//----------------------------------------------------------------------------- // Torque Game Engine // Copyright (C) GarageGames.com, Inc. //----------------------------------------------------------------------------- #ifndef _FLUID_H_ #define _FLUID_H_ //============================================================================== // TO DO LIST //============================================================================== // - ARB support? // - Optimize the fog given water is horizontal // - New fog system // - Attempt to reject fully fogged low LOD blocks //============================================================================== // - Designate specular map? // - Turn off specular? (for lava) //============================================================================== //============================================================================== // ASSUMPTIONS: // - A single repetition of the terrain (or a "rep") is 256x256 squares. // - A terrain square is 8 meters on a side. // - The fluid can NOT be rotated on any axis. // - The "anchor point" for the fluid can be on any discrete square corner. // - The size of the fluid is constrained to be either a multiple of 4 or 8 // squares. //============================================================================== // DISCUSSION: // - If the overall size of the fluid is less than a quarter of a terrain rep, // then the fluid will use a "double resolution" mode. Thus, when the fluid // is sufficiently small, it gets more detailed. // - The fluid renders blocks in one of two sizes, LOW and HIGH. // - Blocks are 8 squares in normal (LOW) resolution mode, and 4 in high (LOW). // - A quad tree is used to quickly cull down to the blocks. // - Reject and accept masks are used by the quad tree. //============================================================================== //============================================================================== // INCLUDES //============================================================================== #ifndef _TYPES_H_ #include "platform/types.h" #endif #ifndef _PLATFORM_H_ #include "platform/platform.h" #endif #ifndef _GTEXMANAGER_H_ #include "dgl/gTexManager.h" #endif #ifndef _MMATH_H_ #include "math/mMath.h" #endif #include "core/color.h" //============================================================================== // DEFINES //============================================================================== #define s32 S32 #define u32 U32 #define s16 S16 #define u16 U16 #define s8 S8 #define u8 U8 #define byte U8 #define f32 F32 #define PI (3.141592653589793238462643f) #define SECONDS ((f32)(Sim::getCurrentTime()) * 0.001f) #define MALLOC dMalloc #define REALLOC dRealloc #define FREE dFree #define MEMSET dMemset #define TWO_PI (PI * 2.0f) #define FMOD(a,b) (f32)mFmod( a, b ) #define LENGTH3(a,b,c) (f32)mSqrt( (a)*(a) + (b)*(b) + (c)*(c) ) #define SINE(a) (float)mSin( a ) #define COSINE(a) (float)mCos( a ) #define ASSERT(exp) //============================================================================== // TYPES //============================================================================== // // Order for [4] element arrays... // // 2----3 Y // | | | // | | | // 0----1 0----X // //============================================================================== class fluid { //------------------------------------------------------------------------------ // Public Types // public: typedef f32 compute_fog_fn( f32 DeltaZ, f32 D ); //------------------------------------------------------------------------------ // Public Functions // public: fluid ( void ); ~fluid (); // // Render (in FluidRender.cc): // void Render ( bool& EyeSubmerged ); // // Setup per frame (in FluidSupport.cc): // void SetEyePosition ( f32 X, f32 Y, f32 Z ) { m_Eye.set( X, Y, Z ); } void SetFrustrumPlanes ( f32* pFrustrumPlanes ); // // Setup at initialization (in FluidSupport.cc): // void SetInfo ( f32& X0, f32& Y0, f32& SizeX, f32& SizeY, f32 SurfaceZ, f32 WaveAmplitude, f32& Opacity, f32& EnvMapIntensity, s32 RemoveWetEdges, bool UseDepthMap, f32 TessellationSurface, f32 TessellationShore, f32 SurfaceParallax, f32 FlowAngle, f32 FlowRate, f32 DistortGridScale, f32 DistortMagnitude, f32 DistortTime, ColorF SpecColor, F32 SpecPower, bool tiling, u32 terrainSize, u32 terrainBlockSize); void SetTerrainData ( u16* pTerrainData ); void SetTextures ( TextureHandle Base, TextureHandle EnvMapOverTexture, TextureHandle EnvMapUnderTexture, TextureHandle ShoreTexture, TextureHandle DepthTexture, TextureHandle ShoreDepthTexture, TextureHandle SpecMaskTexture ); // MM: Added Various Textures. void SetLightMapTexture ( TextureHandle LightMapTexture ); void SetFogParameters ( f32 R, f32 G, f32 B, f32 VisibleDistance ); void SetFogFn ( compute_fog_fn* pFogFn ); // // Run time interrogation (in FluidSupport.cc): // s32 IsFluidAtXY ( f32 X, f32 Y ) const; //------------------------------------------------------------------------------ // Private Types // private: struct plane { f32 A, B, C, D; }; struct rgba { f32 R, G, B, A; }; struct xyz { f32 X, Y, Z; }; struct uv { f32 U, V; }; struct node { s32 Level; s32 MaskIndexX, MaskIndexY; s32 BlockX0, BlockY0; // World Block f32 X0, Y0; // World Position f32 X1, Y1; // World Position byte ClipBits[4]; }; struct block { f32 X0, Y0; f32 X1, Y1; f32 Distance[4]; // Distance from eye f32 LOD [4]; // Level of detail }; // Rendering phases: // Phase 1 - Base texture (two passes of cross faded textures) // Phase 2 - Shadow map // Phase 3 - Environment map / Specular // Phase 4 - Fog struct vertex { Point3F XYZ; // All phases - Position // rgba RGBA1a; // Phase 1a - Base alpha, first pass (MM: Removed) // rgba RGBA1b; // Phase 1b - Base alpha, second pass (MM: Removed) uv UV1; // Phase 1 - MM: Base UV. uv UV2; // Phase 2 - MM: Shoreline UV. rgba RGBA3; // Phase 3 - MM: EnvMap Colour/Alpha. uv UV3; // Phase 3 - EnvMap UV rgba RGBA4; // Phase 4 - Fog Color/Alpha uv UV4; // Test - MM: Depth Alpha Map. ColorF SPECULAR; }; //------------------------------------------------------------------------------ // Private Variables // public: bool mTile; s32 m_SquareX0, m_SquareY0; // Anchor in terrain squares s32 m_SquaresInX, m_SquaresInY; // Number of squares in fluid region private: f32 m_DepthTexelX, m_DepthTexelY; // MM: Added Depth Texel X/Y. s32 m_BlocksInX, m_BlocksInY; // Number of blocks in fluid region f32 m_SurfaceZ; // Altitude of fluid surface s32 m_RemoveWetEdges; // Dry fill all edges of the fluid block s32 m_HighResMode; // Blocks are 4x4 (high res) or 8x8 squares (normal) plane m_Plane[6]; // Frustrum clip planes: 0=T 1=B 2=L 3=R 4=N 5=F Point3F m_Eye; f32 m_Seconds; f32 m_BaseSeconds; rgba m_FogColor; f32 m_VisibleDistance; f32 m_Opacity; f32 m_EnvMapIntensity; // MM: Added Over/Under Env Texture Support. f32 m_WaveAmplitude; f32 m_WaveFactor; u16* m_pTerrain; // 256x256 data for the terrain bool m_UseDepthMap; // MM: Use Depth Map Flag? F32 m_TessellationSurface; // MM: Tessellation Surface. F32 m_TessellationShore; // MM: Tessellation Shore. F32 m_SurfaceParallax; // MM: Surface Parallax. F32 m_FlowAngle; // MM: Flow Angle. F32 m_FlowRate; // MM: Flow Rate. F32 m_FlowMagnitudeS; // MM: Flow Magnitude S. F32 m_FlowMagnitudeT; // MM: Flow Magnitude T. F32 m_DistortGridScale; // MM: Distort Grid Scale. F32 m_DistortMagnitude; // MM: Distort Magnitude. F32 m_DistortTime; // MM: Distort Time. ColorF m_SpecColor; F32 m_SpecPower; U32 m_TerrainSize; U32 m_TerrainBlockSize; U32 m_TerrainBlockShift; TextureHandle m_BaseTexture; TextureHandle m_EnvMapOverTexture; // MM: Added Over/Under Env Texture Support. TextureHandle m_EnvMapUnderTexture; // MM: Added Over/Under Env Texture Support. TextureHandle m_LightMapTexture; TextureHandle m_ShoreTexture; // MM: Added Shore Texture. TextureHandle m_DepthTexture; // MM: Added Depth Texture. TextureHandle m_ShoreDepthTexture; // MM: Added Shore-Depth Texture. TextureHandle m_SpecMaskTex; f32 m_Step[5]; // [0] = 0 // [1] = 1/4 block step // [2] = 1/2 block step // [3] = 3/4 block step // [4] = 1 block step compute_fog_fn* m_pFogFn; // Bit masks to trivially accept or reject the progressive levels for the // quad tree recursion. No need for an accept mask at the highest level // since it is just the exact opposite of the reject mask at that level. static s32 m_MaskOffset[6]; // Offset for given level into masks. byte m_RejectMask[ 1 + 1 + 2 + 8 + 32 + 128 ]; byte m_AcceptMask[ 1 + 1 + 2 + 8 + 32 ]; // // Shared among instances of fluid. // static vertex* m_pVertex; static s32 m_VAllocated; static s32 m_VUsed; static s16* m_pIndex; static s16* m_pINext; static s16 m_IOffset; static s32 m_IAllocated; static s32 m_IUsed; static s32 m_Instances; // // Debug variables. // public: s32 m_ShowWire; s32 m_ShowNodes; s32 m_ShowBlocks; s32 m_ShowBaseA; s32 m_ShowBaseB; s32 m_ShowLightMap; s32 m_ShowEnvMap; s32 m_ShowFog; //------------------------------------------------------------------------------ // Private Functions // private: inline F32 DISTANCE( F32 x, F32 y, F32 z ) { return( LENGTH3( (x)-m_Eye.x, (y)-m_Eye.y, (z)-m_Eye.z ) ); } // // Functions in FluidSupport.cc: // s32 GetAcceptBit ( s32 Level, s32 IndexX, s32 IndexY ) const; s32 GetRejectBit ( s32 Level, s32 IndexX, s32 IndexY ) const; void SetAcceptBit ( s32 Level, s32 IndexX, s32 IndexY, s32 Value ); void SetRejectBit ( s32 Level, s32 IndexX, s32 IndexY, s32 Value ); void BuildLowerMasks ( void ); void RebuildMasks ( void ); void FloodFill ( u8* pGrid, s32 x, s32 y, s32 SizeX, s32 SizeY ); // // Functions in FluidQuadTree.cc // void RunQuadTree ( bool& EyeSubmerged ); f32 ComputeLOD ( f32 Distance ); byte ComputeClipBits ( f32 X, f32 Y, f32 Z ); void ProcessNode ( node& Node ); void ProcessBlock ( block& Block ); void ProcessBlockLODHigh ( block& Block ); void ProcessBlockLODMorph ( block& Block ); void ProcessBlockLODTrans ( block& Block ); void ProcessBlockLODLow ( block& Block ); void SetupVert ( f32 X, f32 Y, f32 Distance, vertex* pV ); void InterpolateVerts ( vertex* pV0, vertex* pV1, vertex* pV2, vertex* pV3, vertex* pV4, f32 LOD0, f32 LOD4 ); void InterpolateVert ( vertex* pV0, vertex* pV1, vertex* pV2, f32 LOD ); void ReleaseVertexMemory ( void ); vertex* AcquireVertices ( s32 Count ); void AddTriangleIndices ( s16 I1, s16 I2, s16 I3 ); void CalcVertSpecular (); }; //============================================================================== #endif // FLUID_HPP //==============================================================================