//----------------------------------------------------------------------------- // Copyright (c) 2012 GarageGames, LLC // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- #ifndef _GROUNDCOVER_H_ #define _GROUNDCOVER_H_ #ifndef _SCENEOBJECT_H_ #include "scene/sceneObject.h" #endif #ifndef _MATHUTIL_FRUSTUM_H_ #include "math/util/frustum.h" #endif #ifndef _GFXTEXTUREHANDLE_H_ #include "gfx/gfxTextureHandle.h" #endif #ifndef _GFX_GFXPRIMITIVEBUFFER_H_ #include "gfx/gfxPrimitiveBuffer.h" #endif #ifndef _RENDERPASSMANAGER_H_ #include "renderInstance/renderPassManager.h" #endif #ifndef _MATTEXTURETARGET_H_ #include "materials/matTextureTarget.h" #endif #ifndef _SHADERFEATURE_H_ #include "shaderGen/shaderFeature.h" #endif #include "T3D/assets/ShapeAsset.h" class TerrainBlock; class GroundCoverCell; class TSShapeInstance; class Material; class MaterialParameters; class MaterialParameterHandle; /// #define MAX_COVERTYPES 8 GFXDeclareVertexFormat( GCVertex ) { Point3F point; Point3F normal; // .rgb = ambient // .a = corner index GFXVertexColor ambient; // .x = size x // .y = size y // .z = type // .w = wind amplitude Point4F params; }; struct GroundCoverShaderConstData { Point2F fadeInfo; Point3F gustInfo; Point2F turbInfo; Point3F camRight; Point3F camUp; }; class GroundCover; class GroundCoverShaderConstHandles : public ShaderFeatureConstHandles { public: GroundCoverShaderConstHandles(); virtual void init( GFXShader *shader ); virtual void setConsts( SceneRenderState *state, const SceneData &sgData, GFXShaderConstBuffer *buffer ); GroundCover *mGroundCover; GFXShaderConstHandle *mTypeRectsSC; GFXShaderConstHandle *mFadeSC; GFXShaderConstHandle *mWindDirSC; GFXShaderConstHandle *mGustInfoSC; GFXShaderConstHandle *mTurbInfoSC; GFXShaderConstHandle *mCamRightSC; GFXShaderConstHandle *mCamUpSC; }; class GroundCover : public SceneObject { friend class GroundCoverShaderConstHandles; friend class GroundCoverCell; typedef SceneObject Parent; public: GroundCover(); ~GroundCover(); DECLARE_CONOBJECT(GroundCover); static void consoleInit(); static void initPersistFields(); bool onAdd(); void onRemove(); void inspectPostApply(); // Network U32 packUpdate( NetConnection *, U32 mask, BitStream *stream ); void unpackUpdate( NetConnection *, BitStream *stream ); // Rendering void prepRenderImage( SceneRenderState *state ); // Editor void onTerrainUpdated( U32 flags, TerrainBlock *tblock, const Point2I& min, const Point2I& max ); // Misc const GroundCoverShaderConstData& getShaderConstData() const { return mShaderConstData; } /// Sets the global ground cover LOD scalar which controls /// the percentage of the maximum designed cover to put down. /// It scales both rendering cost and placement CPU performance. /// Returns the actual value set. static F32 setQualityScale( F32 scale ) { return smDensityScale = mClampF( scale, 0.0f, 1.0f ); } /// 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 { TerrainBlockMask = Parent::NextFreeMask << 0, NextFreeMask = Parent::NextFreeMask << 1 }; MaterialParameters *mMatParams; MaterialParameterHandle *mTypeRectsParam; MaterialParameterHandle *mFadeParams; MaterialParameterHandle *mWindDirParam; MaterialParameterHandle *mGustInfoParam; MaterialParameterHandle *mTurbInfoParam; MaterialParameterHandle *mCamRightParam; MaterialParameterHandle *mCamUpParam; /// This RNG seed is saved and sent to clients /// for generating the same cover. S32 mRandomSeed; /// This is the outer generation radius from /// the current camera position. F32 mRadius; // Offset along the Z axis to render the ground cover. F32 mZOffset; /// This is less than or equal to mRadius and /// defines when fading of cover elements begins. F32 mFadeRadius; /// This is the distance at which DTS elements are /// completely culled out. F32 mShapeCullRadius; /// Whether shapes rendered by the GroundCover should cast shadows. bool mShapesCastShadows; /// This is used to scale the various culling radii /// when rendering a reflection... typically for water. F32 mReflectRadiusScale; /// This is the number of cells per axis in the grid. U32 mGridSize; typedef Vector CellVector; /// This is the allocator for GridCell chunks. CellVector mAllocCellList; CellVector mFreeCellList; /// This is the grid of active cells. CellVector mCellGrid; /// This is a scratch grid used while updating /// the cell grid. CellVector mScratchGrid; /// This is the index to the first grid cell. Point2I mGridIndex; /// The maximum amount of cover elements to include in /// the grid at any one time. The actual amount may be /// less than this based on randomization. S32 mMaxPlacement; /// Used to detect changes in cell placement count from /// the global quality scale so we can regen the cells. S32 mLastPlacementCount; /// Used for culling cells to update and render. Frustum mCuller; /// Debug parameter for displaying the grid cells. bool mDebugRenderCells; /// Debug parameter for turning off billboard rendering. bool mDebugNoBillboards; /// Debug parameter for turning off shape rendering. bool mDebugNoShapes; /// Debug parameter for locking the culling frustum which /// will freeze the cover generation. bool mDebugLockFrustum; /// Stat for number of rendered cells. static U32 smStatRenderedCells; /// Stat for number of rendered billboards. static U32 smStatRenderedBillboards; /// Stat for number of rendered billboard batches. static U32 smStatRenderedBatches; /// Stat for number of rendered shapes. static U32 smStatRenderedShapes; /// The global ground cover LOD scalar which controls /// the percentage of the maximum amount of cover to put /// down. It scales both rendering cost and placement /// CPU performance. static F32 smDensityScale; static F32 smFadeScale; BaseMatInstance* mMaterialInst; DECLARE_MATERIALASSET(GroundCover, Material); DECLARE_ASSET_NET_SETGET(GroundCover, Material, InitialUpdateMask); GroundCoverShaderConstData mShaderConstData; /// This is the maximum amout of degrees the billboard will /// tilt down to match the camera. F32 mMaxBillboardTiltAngle; /// The probability of one cover type verses another. F32 mProbability[MAX_COVERTYPES]; /// The minimum random size for each cover type. F32 mSizeMin[MAX_COVERTYPES]; /// The maximum random size of this cover type. F32 mSizeMax[MAX_COVERTYPES]; /// An exponent used to bias between the minimum /// and maximum random sizes. F32 mSizeExponent[MAX_COVERTYPES]; /// 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]; /// The maximum world space elevation for placement. F32 mMaxElevation[MAX_COVERTYPES]; /// Terrain material assetId to limit coverage to, or /// left empty to cover entire terrain. StringTableEntry mLayer[MAX_COVERTYPES]; /// Inverts the data layer test making the /// layer an exclusion mask. bool mInvertLayer[MAX_COVERTYPES]; /// The minimum amount of elements in a clump. S32 mMinClumpCount[MAX_COVERTYPES]; /// The maximum amount of elements in a clump. S32 mMaxClumpCount[MAX_COVERTYPES]; /// An exponent used to bias between the minimum /// and maximum clump counts for a particular clump. F32 mClumpCountExponent[MAX_COVERTYPES]; /// The maximum clump radius. F32 mClumpRadius[MAX_COVERTYPES]; /// This is a cached array of billboard aspect scales /// used to avoid some calculations when generating cells. F32 mBillboardAspectScales[MAX_COVERTYPES]; RectF mBillboardRects[MAX_COVERTYPES]; /// The cover shape filenames. DECLARE_SHAPEASSET_ARRAY(GroundCover, Shape, MAX_COVERTYPES); DECLARE_ASSET_ARRAY_NET_SETGET(GroundCover, Shape, -1); /// The cover shape instances. TSShapeInstance* mShapeInstances[MAX_COVERTYPES]; /// This is the same as mProbability, but normalized for use /// during the cover placement process. F32 mNormalizedProbability[MAX_COVERTYPES]; /// A shared primitive buffer setup for drawing the maximum amount /// of billboards you could possibly have in a single cell. GFXPrimitiveBufferHandle mPrimBuffer; /// The length in meters between peaks in the wind gust. F32 mWindGustLength; /// Controls how often the wind gust peaks per second. F32 mWindGustFrequency; /// The maximum distance in meters that the peak wind /// gust will displace an element. F32 mWindGustStrength; /// The direction of the wind. Point2F mWindDirection; /// Controls the overall rapidity of the wind turbulence. F32 mWindTurbulenceFrequency; /// The maximum distance in meters that the turbulence can /// displace a ground cover element. F32 mWindTurbulenceStrength; void _initMaterial(); bool _initShader(); void _initShapes(); void _deleteShapes(); /// Called when GroundCover parameters are changed and /// things need to be reinitialized to continue. void _initialize( U32 cellCount, U32 cellPlacementCount ); /// Updates the cover grid by removing cells that /// have fallen outside of mRadius and adding new /// ones that have come into view. void _updateCoverGrid( const Frustum &culler ); /// Clears the cell grid, moves all the allocated cells to /// the free list, and deletes excess free cells. void _freeCells(); /// Clears the cell grid and deletes all the free cells. void _deleteCells(); /// Returns a cell to the free list. void _recycleCell( GroundCoverCell* cell ); /// Generates a new cell using the recycle list when possible. GroundCoverCell* _generateCell( const Point2I& index, const Box3F& bounds, U32 placementCount, S32 randSeed ); void _debugRender( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ); }; #endif // _GROUNDCOVER_H_