Initial commit
This commit is contained in:
237
Torque/SDK/engine/game/fx/precipitation.h
Normal file
237
Torque/SDK/engine/game/fx/precipitation.h
Normal file
@@ -0,0 +1,237 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Torque Game Engine
|
||||
// Copyright (C) GarageGames.com, Inc.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _PRECIPITATION_H_
|
||||
#define _PRECIPITATION_H_
|
||||
|
||||
#include "game/gameBase.h"
|
||||
#include "audio/audioDataBlock.h"
|
||||
|
||||
/// How many drops are on a side of the material texture
|
||||
#define DROPS_PER_SIDE 4
|
||||
/// How many frames are on a side of a splash animation
|
||||
#define FRAMES_PER_SIDE 2
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
/// 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;
|
||||
time = 0;
|
||||
mass = 1;
|
||||
texCoordIndex = 0;
|
||||
next = NULL;
|
||||
toRender = false;
|
||||
valid = true;
|
||||
nextSplashDrop = NULL;
|
||||
prevSplashDrop = NULL;
|
||||
animStartTime = 0;
|
||||
splashIndex = 0;
|
||||
hitType = 0;
|
||||
hitPos = Point3F(0,0,0);
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
class Precipitation : public GameBase
|
||||
{
|
||||
private:
|
||||
|
||||
typedef GameBase Parent;
|
||||
PrecipitationData* mDataBlock;
|
||||
|
||||
Raindrop *mDropHead; ///< Drop linked list head
|
||||
Raindrop *mSplashHead; ///< Splash linked list head
|
||||
Point2F texCoords[4 * DROPS_PER_SIDE*DROPS_PER_SIDE]; ///< texture coords for rain texture
|
||||
Point2F splashCoords[4 * FRAMES_PER_SIDE*FRAMES_PER_SIDE]; ///< 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);
|
||||
};
|
||||
|
||||
inline void Precipitation::wrapDrop(Raindrop *drop, Box3F &box)
|
||||
{
|
||||
bool recalcCutoff = false;
|
||||
//could probably be slightly optimized to get rid of the while loops
|
||||
if (drop->position.x < box.min.x)
|
||||
{
|
||||
while (drop->position.x < box.min.x)
|
||||
drop->position.x += mBoxWidth;
|
||||
recalcCutoff = true;
|
||||
}
|
||||
else if (drop->position.x > box.max.x)
|
||||
{
|
||||
while (drop->position.x > box.max.x)
|
||||
drop->position.x -= mBoxWidth;
|
||||
recalcCutoff = true;
|
||||
}
|
||||
|
||||
if (drop->position.y < box.min.y)
|
||||
{
|
||||
while (drop->position.y < box.min.y)
|
||||
drop->position.y += mBoxWidth;
|
||||
recalcCutoff = true;
|
||||
}
|
||||
else if (drop->position.y > box.max.y)
|
||||
{
|
||||
while (drop->position.y > box.max.y)
|
||||
drop->position.y -= mBoxWidth;
|
||||
recalcCutoff = true;
|
||||
}
|
||||
|
||||
if (drop->position.z < box.min.z)
|
||||
{
|
||||
spawnDrop(drop);
|
||||
drop->position.x += box.min.x;
|
||||
drop->position.y += box.min.y;
|
||||
while (drop->position.z < box.min.z)
|
||||
drop->position.z += mBoxHeight;
|
||||
recalcCutoff = true;
|
||||
}
|
||||
else if (drop->position.z > box.max.z)
|
||||
{
|
||||
while (drop->position.z > box.max.z)
|
||||
drop->position.z -= mBoxHeight;
|
||||
recalcCutoff = true;
|
||||
}
|
||||
|
||||
if(recalcCutoff)
|
||||
findDropCutoff(drop);
|
||||
}
|
||||
|
||||
#endif // PRECIPITATION_H_
|
||||
|
||||
Reference in New Issue
Block a user