tge/engine/game/fx/precipitation.h
2017-04-17 06:17:10 -06:00

188 lines
7.2 KiB
C++
Executable File

//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#ifndef _PRECIPITATION_H_
#define _PRECIPITATION_H_
#include "game/gameBase.h"
#include "audio/audioDataBlock.h"
//--------------------------------------------------------------------------
/// Precipitation datablock.
class PrecipitationData : public GameBaseData {
typedef GameBaseData Parent;
public:
AudioProfile* soundProfile;
S32 soundProfileId; ///< Ambient sound
StringTableEntry mDropName; ///< Texture filename for raindrop
StringTableEntry mSplashName; ///< Texture filename for splash
F32 mDropSize; ///< Droplet billboard size
F32 mSplashSize; ///< Splash billboard size
bool mUseTrueBillboards; ///< True to use true billboards, false for axis-aligned billboards
S32 mSplashMS; ///< How long in milliseconds a splash will last
PrecipitationData();
DECLARE_CONOBJECT(PrecipitationData);
bool onAdd();
static void initPersistFields();
virtual void packData(BitStream* stream);
virtual void unpackData(BitStream* stream);
};
DECLARE_CONSOLETYPE(PrecipitationData)
struct Raindrop
{
F32 velocity; ///< How fast the drop is falling downwards
Point3F position; ///< Position of the drop
Point3F renderPosition; ///< Interpolated render-position of the drop
F32 time; ///< Time into the turbulence function
F32 mass; ///< Mass of drop used for how much turbulence/wind effects the drop
U32 texCoordIndex; ///< Which piece of the material will be used
bool toRender; ///< Don't want to render all drops, just the ones that pass a few tests
bool valid; ///< Drop becomes invalid after hitting something. Just keep updating
///< the position of it, but don't render until it hits the bottom
///< of the renderbox and respawns
Point3F hitPos; ///< Point at which the drop will collide with something
Raindrop *nextSplashDrop; ///< Linked list cruft for easily adding/removing stuff from the splash list
Raindrop *prevSplashDrop; ///< Same as next but previous!
SimTime animStartTime; ///< Animation time tracker
U32 splashIndex; ///< Texture index for which frame of the splash to render
U32 hitType; ///< What kind of object the drop will hit
Raindrop* next; ///< linked list cruft
Raindrop()
: velocity( 0.0f ),
time( 0.0f ),
mass( 1.0f ),
texCoordIndex( 0 ),
toRender( false ),
valid( true ),
hitPos( 0.0f, 0.0f, 0.0f ),
nextSplashDrop( NULL ),
prevSplashDrop( NULL ),
animStartTime( 0 ),
splashIndex( 0 ),
hitType( 0 ),
next( NULL )
{
}
};
//--------------------------------------------------------------------------
class Precipitation : public GameBase
{
private:
typedef GameBase Parent;
PrecipitationData* mDataBlock;
const static U32 csmDropsPerSide; ///< How many drops are on a side of the material texture
const static F32 csmDropsPerSideF; ///< How many drops are on a side of the material texture
const static U32 csmFramesPerSide; ///< How many frames are on a side of a splash animation
const static F32 csmFramesPerSideF; ///< How many frames are on a side of a splash animation
Raindrop *mDropHead; ///< Drop linked list head
Raindrop *mSplashHead; ///< Splash linked list head
Point2F *texCoords; ///< texture coords for rain texture
Point2F *splashCoords; ///< texture coordinates for splash texture
AUDIOHANDLE mAudioHandle; ///< Ambient sound handle
TextureHandle mDropHandle; ///< Texture handle for raindrop
TextureHandle mSplashHandle; ///< Texture handle for splash
//console exposed variables
S32 mNumDrops; ///< Number of drops in the scene
F32 mPercentage; ///< Server-side set var (NOT exposed to console)
///< which controls how many drops are present [0,1]
F32 mMinSpeed; ///< Minimum downward speed of drops
F32 mMaxSpeed; ///< Maximum downward speed of drops
F32 mMinMass; ///< Minimum mass of drops
F32 mMaxMass; ///< Maximum mass of drops
F32 mBoxWidth; ///< How far away in the x and y directions drops will render
F32 mBoxHeight; ///< How high drops will render
F32 mMaxTurbulence; ///< Coefficient to sin/cos for adding turbulence
F32 mTurbulenceSpeed; ///< How fast the turbulence wraps in a circle
bool mUseTurbulence; ///< Whether to use turbulence or not (MAY EFFECT PERFORMANCE)
bool mRotateWithCamVel; ///< Rotate the drops relative to the camera velocity
///< This is useful for "streak" type drops
bool mDoCollision; ///< Whether or not to do collision
struct
{
bool valid;
U32 startTime;
U32 totalTime;
F32 startPct;
F32 endPct;
} mStormData;
//other functions...
void processTick(const Move*);
void interpolateTick(F32 delta);
VectorF getWindVelocity();
void fillDropList(); ///< Adds/removes drops from the list to have the right # of drops
void killDropList(); ///< Deletes the entire drop list
void spawnDrop(Raindrop *drop); ///< Fills drop info with random velocity, x/y positions, and mass
void spawnNewDrop(Raindrop *drop); ///< Same as spawnDrop except also does z position
void findDropCutoff(Raindrop *drop); ///< Casts a ray to see if/when a drop will collide
inline void wrapDrop(Raindrop *drop, Box3F &box); ///< Wraps a drop within the specified box
void createSplash(Raindrop *drop); ///< Adds a drop to the splash list
void destroySplash(Raindrop *drop); ///< Removes a drop from the splash list
protected:
bool onAdd();
void onRemove();
// Rendering
bool prepRenderImage(SceneState*, const U32, const U32, const bool);
void renderObject(SceneState*, SceneRenderImage*);
void renderPrecip(SceneState *state);
void renderSplashes(SceneState *state);
public:
Precipitation();
~Precipitation();
void inspectPostApply();
enum
{
DataMask = Parent::NextFreeMask << 0,
PercentageMask = Parent::NextFreeMask << 1,
StormMask = Parent::NextFreeMask << 2,
NextFreeMask = Parent::NextFreeMask << 3
};
bool onNewDataBlock(GameBaseData* dptr);
DECLARE_CONOBJECT(Precipitation);
static void initPersistFields();
U32 packUpdate(NetConnection*, U32 mask, BitStream* stream);
void unpackUpdate(NetConnection*, BitStream* stream);
void setPercentage(F32 pct);
void modifyStorm(F32 pct, U32 ms);
};
#endif // PRECIPITATION_H_