groundcover requested augs

1) fadescale- allows an enduser to reduce drawdistance for groundcover via $pref::GroundCover::fadeScale
2) adds minslope, conformtonormal, and min/max rotations along the x and y axies
This commit is contained in:
AzaezelX 2020-06-13 12:18:41 -05:00
parent 341c7eeee1
commit 7c9d2f3ca2
2 changed files with 72 additions and 5 deletions

View file

@ -316,7 +316,7 @@ U32 GroundCoverCell::renderShapes( const TSRenderState &rdata,
camVector = inst.point - state->getDiffuseCameraPosition();
dist = getMax( camVector.len(), 0.01f );
worldMat.set( EulerF(0, 0, inst.rotation), inst.point );
worldMat.set( EulerF(inst.normal.x, inst.normal.y, inst.rotation), inst.point );
// TSShapeInstance::render() uses the
// world matrix for the RenderInst.
@ -423,6 +423,7 @@ U32 GroundCover::smStatRenderedBillboards = 0;
U32 GroundCover::smStatRenderedBatches = 0;
U32 GroundCover::smStatRenderedShapes = 0;
F32 GroundCover::smDensityScale = 1.0f;
F32 GroundCover::smFadeScale = 1.0f;
ConsoleDocClass( GroundCover,
"@brief Covers the ground in a field of objects (IE: Grass, Flowers, etc)."
@ -494,8 +495,15 @@ GroundCover::GroundCover()
mWindScale[i] = 1.0f;
mMinSlope[i] = 0.0f;
mMaxSlope[i] = 0.0f;
mConformToNormal[i] = false;
mMinRotX[i] = 0.0f;
mMaxRotX[i] = 0.0f;
mMinRotY[i] = 0.0f;
mMaxRotY[i] = 0.0f;
mMinElevation[i] = -99999.0f;
mMaxElevation[i] = 99999.0f;
@ -566,8 +574,16 @@ void GroundCover::initPersistFields()
addField( "windScale", TypeF32, Offset( mWindScale, GroundCover ), MAX_COVERTYPES, "The wind effect scale." );
addField( "minSlope", TypeF32, Offset(mMinSlope, GroundCover), MAX_COVERTYPES, "The minimum slope angle in degrees for placement.");
addField( "maxSlope", TypeF32, Offset( mMaxSlope, GroundCover ), MAX_COVERTYPES, "The maximum slope angle in degrees for placement." );
addField("conformToNormal",TypeBool, Offset(mConformToNormal, GroundCover), MAX_COVERTYPES, "Use the terrain's slope for angle");
addField("minRotX", TypeF32, Offset(mMinRotX, GroundCover), MAX_COVERTYPES, "minumum amount of rotation along the X axis to add");
addField("maxRotX", TypeF32, Offset(mMaxRotX, GroundCover), MAX_COVERTYPES, "maximum amount of rotation along the X axis to add");
addField("minRotY", TypeF32, Offset(mMinRotY, GroundCover), MAX_COVERTYPES, "minumum amount of rotation along the Y axis to add");
addField("maxRotY", TypeF32, Offset(mMaxRotY, GroundCover), MAX_COVERTYPES, "maximum amount of rotation along the Y axis to add");
addField( "minElevation", TypeF32, Offset( mMinElevation, GroundCover ), MAX_COVERTYPES, "The minimum world space elevation for placement." );
addField( "maxElevation", TypeF32, Offset( mMaxElevation, GroundCover ), MAX_COVERTYPES, "The maximum world space elevation for placement." );
@ -613,6 +629,8 @@ void GroundCover::consoleInit()
{
Con::addVariable( "$pref::GroundCover::densityScale", TypeF32, &smDensityScale, "A global LOD scalar which can reduce the overall density of placed GroundCover.\n"
"@ingroup Foliage\n");
Con::addVariable("$pref::GroundCover::fadeScale", TypeF32, &smFadeScale, "A global fade scalar which can reduce the overall rendered distance of placed GroundCover.\n"
"@ingroup Foliage\n");
Con::addVariable( "$GroundCover::renderedCells", TypeS32, &smStatRenderedCells, "Stat for number of rendered cells.\n"
"@ingroup Foliage\n");
@ -720,7 +738,13 @@ U32 GroundCover::packUpdate( NetConnection *connection, U32 mask, BitStream *str
stream->write( mSizeExponent[i] );
stream->write( mWindScale[i] );
stream->write( mMinSlope[i] );
stream->write( mMaxSlope[i] );
stream->writeFlag(mConformToNormal[i]);
stream->write(mMinRotX[i]);
stream->write(mMaxRotX[i]);
stream->write(mMinRotY[i]);
stream->write(mMaxRotY[i]);
stream->write( mMinElevation[i] );
stream->write( mMaxElevation[i] );
@ -785,7 +809,13 @@ void GroundCover::unpackUpdate( NetConnection *connection, BitStream *stream )
stream->read( &mSizeExponent[i] );
stream->read( &mWindScale[i] );
stream->read( &mMinSlope[i] );
stream->read( &mMaxSlope[i] );
mConformToNormal[i] = stream->readFlag();
stream->read(&mMinRotX[i]);
stream->read(&mMaxRotX[i]);
stream->read(&mMinRotY[i]);
stream->read(&mMaxRotY[i]);
stream->read( &mMinElevation[i] );
stream->read( &mMaxElevation[i] );
@ -1142,7 +1172,14 @@ GroundCoverCell* GroundCover::_generateCell( const Point2I& index,
F32 flipBB = -1.0f;
// Precompute a few other type specific values.
const bool typeConformToNormal = mConformToNormal[type];
const F32 typeMinRotX = (mMaxRotX[type] > mMinRotX[type]) ? mMinRotX[type] : mMaxRotX[type];
const F32 typeMaxRotX = (mMaxRotX[type] > mMinRotX[type]) ? mMaxRotX[type] : mMinRotX[type];
const F32 typeMinRotY = (mMaxRotY[type] > mMinRotY[type]) ? mMinRotY[type] : mMaxRotY[type];
const F32 typeMaxRotY = (mMaxRotY[type] > mMinRotY[type]) ? mMaxRotY[type] : mMinRotY[type];
const F32 typeSizeRange = mSizeMax[type] - mSizeMin[type];
const F32 typeMinSlope = mMinSlope[type];
const F32 typeMaxSlope = mMaxSlope[type];
const F32 typeMaxElevation = mMaxElevation[type];
const F32 typeMinElevation = mMinElevation[type];
@ -1253,11 +1290,22 @@ GroundCoverCell* GroundCover::_generateCell( const Point2I& index,
continue;
}
if (!mIsZero(typeMinSlope))
{
if (mAcos(normal.z) < mDegToRad(typeMinSlope))
continue;
}
point.set( cp.x, cp.y, h );
p.point = point;
p.rotation = rotation;
p.normal = normal;
if (!typeConformToNormal)
{
p.normal.y = 0;
p.normal.x = 0;
}
p.normal.x += rand.randF(typeMinRotX, typeMaxRotX);
p.normal.y += rand.randF(typeMinRotY, typeMaxRotY);
// Grab the terrain lightmap color at this position.
//
// TODO: Can't we remove this test? The terrain
@ -1562,7 +1610,8 @@ void GroundCover::prepRenderImage( SceneRenderState *state )
F32 screenScale = state->getWorldToScreenScale().y / state->getViewport().extent.y;
// Set the far distance for billboards.
mCuller.setFarDist( mRadius * screenScale );
F32 radius = mRadius * smFadeScale;
mCuller.setFarDist(radius * screenScale );
F32 cullScale = 1.0f;
if ( state->isReflectPass() )
@ -1571,7 +1620,7 @@ void GroundCover::prepRenderImage( SceneRenderState *state )
// Setup our shader const data.
// Must be done prior to submitting our render instance.
mShaderConstData.fadeInfo.set( mFadeRadius * cullScale * screenScale, mRadius * cullScale * screenScale );
mShaderConstData.fadeInfo.set( mFadeRadius * smFadeScale * cullScale * screenScale, radius * cullScale * screenScale );
const F32 simTime = Sim::getCurrentTime() * 0.001f;
@ -1649,7 +1698,7 @@ void GroundCover::prepRenderImage( SceneRenderState *state )
rdata.setLightQuery( &query );
// TODO: Add a special fade out for DTS?
mCuller.setFarDist( mShapeCullRadius );
mCuller.setFarDist( mShapeCullRadius*smFadeScale);
for ( S32 i = 0; i < mCellGrid.size(); i++ )
{

View file

@ -151,6 +151,13 @@ public:
/// Returns the current quality scale... see above.
static F32 getQualityScale() { return smDensityScale; }
/// Sets the global ground cover fade scalar which controls
/// the percentage of the maximum designed distance to display cover.
/// Returns the actual value set.
static F32 setFadeScale(F32 scale) { return smFadeScale = mClampF(scale, 0.0f, 1.0f); }
/// Returns the current fade scale... see above.
static F32 getFadeScale() { return smFadeScale; }
protected:
enum MaskBits
@ -255,6 +262,7 @@ protected:
/// down. It scales both rendering cost and placement
/// CPU performance.
static F32 smDensityScale;
static F32 smFadeScale;
String mMaterialName;
Material *mMaterial;
@ -282,9 +290,19 @@ protected:
/// The wind effect scale.
F32 mWindScale[MAX_COVERTYPES];
/// The maximum slope angle in degrees for placement.
F32 mMinSlope[MAX_COVERTYPES];
/// The maximum slope angle in degrees for placement.
F32 mMaxSlope[MAX_COVERTYPES];
/// conform the x/y rotations to gorund normal
bool mConformToNormal[MAX_COVERTYPES];
F32 mMinRotX[MAX_COVERTYPES];
F32 mMaxRotX[MAX_COVERTYPES];
F32 mMinRotY[MAX_COVERTYPES];
F32 mMaxRotY[MAX_COVERTYPES];
/// The minimum world space elevation for placement.
F32 mMinElevation[MAX_COVERTYPES];