/*============================================================================= Name : particle.c Purpose : maintain and render particle systems Created 11/13/1997 by khent Copyright Relic Entertainment, Inc. All rights reserved. =============================================================================*/ #ifndef __PARTICLE_H #define __PARTICLE_H #include "matrix.h" #include "color.h" #include "spaceobj.h" #include "texreg.h" void partFilter(bool on); #ifndef HW_Release #define PART_Debug #define PART_Verbose 1 #else #undef PART_Debug #define PART_Verbose 0 #endif #define PART_NUM_ALTERNATES 128 #define PART_MONOSCALE 0x1 #define PART_ALPHA 0x2 #define PART_WORLDSPACE 0x4 //world space motion updating #define PART_WORLDSPACEVELOCITY 0x8 //if the particle is in worldspace, use it's velocity in local space for heading typedef enum {PART_POINTS, PART_CUBES, PART_LINES, PART_MESH, PART_BILLBOARD} particleType; #define partTypeof(p) ((pointSystem*)(p))->t #define partNumberof(p) ((pointSystem*)(p))->n #define PART_CYLINDER 1 #define PART_SPHERE 2 #define PART_SPECULAR 1 #define PART_STIPPLE 2 #define PART_NODEPTHWRITE 4 #define PART_ADDITIVE 8 #define PART_PSEUDOBILLBOARD 16 #define PART_TRUEBILLBOARD 32 #define PART_XYZSCALE 64 #define PART_NOCOLORSCHEME 0 //particle has no definite color scheme typedef char particleSystem; typedef particleSystem *psysPtr; #define PART_LOOPSTART 1 #define PART_LOOP 2 typedef struct { trhandle tex; //== -1 if end, stay at last frame ubyte uv[2][2]; udword flags; //LOOPSTART = 1, LOOP = 2 } texAnim; typedef struct { meshdata* mesh; //NULL = end of anim udword flags; //LOOPSTART = 1, LOOP = 2 } meshAnim; //generic particle type. //this is way too big typedef struct { //lifespan real32 lifespan; real32 waitspan; //this decs before lifespan //velocity real32 velLOF; real32 velR; real32 deltaVelLOF; real32 deltaVelR; //position vector rvec; vector position; //next to icolor, better for interleaved vertex lists //appearance real32 icolor[4]; real32 deltaColor[4]; real32 scale; real32 deltaScale; bool8 lit; real32 illum; real32 deltaIllum; //line-specifics real32 length; real32 deltaLength; //sprite-specifics trhandle tex; real32 rot; real32 deltaRot; //worldspace particle stuff //render only uses position, so only //creationhelper and updatesystem need this vector wVel; //LOFvel + Rvel vector wAccel; //LOFaccel + Rvel //color bias real32 bias[3]; //animating sprite stuff void* tstruct; real32 rate; bool8 loop; real32 currentFrame; //mesh thingz real32 tumble[3]; real32 deltaTumble[3]; meshdata *mesh; real32 meshRate; void* mstruct; real32 meshFrame; real32 exponent; ubyte colorScheme; //0-7 or PART_NOCOLORSCHEME if none sbyte loopCount; //flags udword flags; } particle; //common params to all particles in a point system typedef struct { particleType t; //common among all particle system types udword flags; bool8 isAlive; //so's this uword n; real32 lastUpdated; //task time it was last updated real32 drag; real32 ang, angDelta; //end of common data } pointSystem; //common params to all particles in a cube system typedef struct { particleType t; udword flags; bool8 isAlive; uword n; real32 lastUpdated; //task time it was last updated real32 drag; real32 ang, angDelta; } cubeSystem; //common params to all particles in a line system typedef struct { particleType t; udword flags; bool8 isAlive; uword n; real32 lastUpdated; //task time it was last updated real32 drag; real32 ang, angDelta; } lineSystem; //common params to all particles in a mesh system typedef struct { particleType t; udword flags; bool8 isAlive; uword n; real32 lastUpdated; //task time it was last updated real32 drag; real32 ang, angDelta; trhandle tex; matrix* partMat; vector partPos; } meshSystem; //common params to all particles in a billboarded texture system typedef struct { particleType t; udword flags; bool8 isAlive; uword n; real32 lastUpdated; //task time it was last updated real32 drag; real32 ang, angDelta; //if a particle's own trhandle == 0, it grabs from the //global setting for the system (right here) trhandle tex; udword uv[2][2]; vector position; vector lofvec; uword slices; matrix* partMat; } billSystem; extern matrix partEffectOwnerSystem; extern vector partEffectOwnerPosition; extern color partEffectColor; extern real32 partNLips; //functions void partStartup(void); void partShutdown(void); void partSetDefaults(); void partRenderSystem(psysPtr psys); bool8 partUpdateSystem(psysPtr psys, real32 dt, vector* velvec); //TRUE if system died, FALSE otherwise psysPtr partCreateSystem(particleType t, udword n); psysPtr partCreateSystemWithDelta(particleType t, udword n, udword delta); psysPtr partCreateSphericalSystem(particleType t, udword n); psysPtr partCreateSphericalSystemWithDelta(particleType t, udword n, udword delta); void partDefaultSystem(ShipPtr ship); udword partHeaderSize(psysPtr psys); //system modifiers void partModifyTumble(psysPtr psys, vector* t); void partModifyDeltaTumble(psysPtr psys, vector* dt); void partModifyExponent(psysPtr psys, real32 exponent); void partModifyDrag(psysPtr psys, real32 d); void partModifyMesh(psysPtr psys, meshdata *mesh); void partModifyLighting(psysPtr psys, bool lit); void partModifyIllum(psysPtr psys, real32 illum); void partModifyDeltaIllum(psysPtr psys, real32 deltaIllum); void partModifyTexture(psysPtr psys, trhandle tex, udword u0, udword v0, udword u1, udword v1); void partModifyScale(psysPtr psys, real32 s); void partModifyDeltaScale(psysPtr psys, real32 d); void partModifyDeltaLength(psysPtr psys, real32 d); void partModifyLifespan(psysPtr psys, real32 l); void partModifyLength(psysPtr psys, real32 l); void partModifyVelLOF(psysPtr psys, real32 v); void partModifyDeltaVelLOF(psysPtr psys, real32 d); void partModifyVelR(psysPtr psys, real32 v); void partModifyDeltaVelR(psysPtr psys, real32 d); void partModifyDeltaColorC(psysPtr psys, color c); void partModifyColorC(psysPtr psys, color c); void partModifyColor(psysPtr psys, real32 r, real32 g, real32 b, real32 a); void partModifyDeltaColor(psysPtr psys, real32 dr, real32 dg, real32 db, real32 da); void partModifyColorBias(psysPtr psys, real32 rb, real32 gb, real32 bb); void partModifyAddColor(psysPtr psys, color c); void partModifyOffsetLOF(psysPtr psys, real32 offset); //for billboard systems void partModifyAnimation(psysPtr psys, void* tstruct); void partModifyFramerate(psysPtr psys, real32 rate); void partModifyLoopFlag(psysPtr psys, bool8 willLoop); void partModifyBillPosition(psysPtr psys, vector* pos); //flag modifiers void partModifySpecular(psysPtr psys, bool spec); void partModifyStipple(psysPtr psys, bool stip); void partModifyNoDepthWrite(psysPtr psys, bool noWrite); void partModifyAdditiveBlends(psysPtr psys, bool add); void partModifyPseudoBillboard(psysPtr psys, bool bill); void partModifyTrueBillboard(psysPtr psys, bool bill); //0 - normal, 1 - additive, 2 - stipple void partModifyAlphaMode(psysPtr psys, udword mode); void partModifyColorScheme(psysPtr psys, sdword colorScheme); //callbacks //delta values are assumed to be + or - the given delta, //unless the given is -ve which implies a strictly -ve delta void partSetIsWorldspace(bool8 isWorldspace); void partSetVelocityInWorldSpace(bool8 isLocalSpace); void partSetWorldVel(vector* worldVel); //these only make sense for billboard systems void partSetAnimation(void* tstruct); void partSetFramerate(real32 rate); void partSetLoopFlag(bool8 willLoop); void partSetStartFrame(udword frame); void partSetCoordSys(matrix* mat); void partSetSlices(udword s); //for circles void partSetPosition(vector *pos); //used by PART_BILLBOARD systems void partSetMeshdata(meshdata *m); //used by PART_MESH systems //used by PART_BILLBOARD systems void partSetTrHandle(trhandle t, udword u0, udword v0, udword u1, udword v1); //PART_MESH systems use this, vals are angles in radians (default 0,0,0) void partSetTumble(real32 x, real32 y, real32 z); void partSetTumbleDist(real32 dx, real32 dy, real32 dz); void partSetDeltaTumble(real32 x, real32 y, real32 z); //rads/s void partSetDeltaTumbleDist(real32 dx, real32 dy, real32 dz); void partSetExponent(real32 exponent); //morphing stuff void partSetMorph(void* mstruct); void partSetMorphFramerate(real32 meshRate); void partSetMorphLoopCount(sdword loopCount); void partSetMeshStartFrame(real32 frame); void partModifyMorph(psysPtr psys, void* mstruct); void partModifyMorphFramerate(psysPtr psys, real32 meshRate); void partSetDrag(real32 n); void partSetXYZScale(real32 x, real32 y, real32 z); void partSetScale(real32 n); //scale refers to linewidth with PART_LINES void partSetScaleDist(real32 d); void partSetDeltaScale(real32 n); void partSetDeltaScaleDist(real32 d); void partSetOffsetLOF(real32 n); //starting offset along lof void partSetOffsetR(real32 n); //starting offset along r void partSetOffsetTheta(real32 n); //ditto void partSetOffsetArray(vector *offsets);//array of offset positions void partSetDeltaLOF(real32 n); //modifies offsetLOF (nothing to do with velocity) void partSetDeltaLOFDist(real32 n); void partSetDeltaR(real32 r, real32 t); void partSetDeltaRDist(real32 r, real32 t); void partSetVelLOF(real32 v); //velocity along lof void partSetVelLOFDist(real32 d); //distribution of vel along lof void partSetVelR(real32 v); //velocity along r void partSetVelRDist(real32 d); //velRDist void partSetDeltaVelLOF(real32 d); //acceleration void partSetDeltaVelLOFDist(real32 d); void partSetDeltaVelR(real32 v); void partSetDeltaVelRDist(real32 v); //angles in radians void partSetAng(real32 a); void partSetAngDist(real32 d); void partSetAngDelta(real32 d); void partSetAngDeltaDist(real32 d); void partSetColorA(real32 r, real32 g, real32 b, real32 a); void partSetColor(real32 r, real32 g, real32 b); void partSetColorDist(real32 r, real32 g, real32 b); void partSetColorADist(real32 r, real32 g, real32 b, real32 a); void partSetDeltaColor(real32 r, real32 g, real32 b); void partSetDeltaColorDist(real32 r, real32 g, real32 b); void partSetDeltaColorA(real32 r, real32 g, real32 b, real32 a); void partSetDeltaColorADist(real32 r, real32 g, real32 b, real32 a); void partSetLighting(bool l); void partSetIllum(real32 n); void partSetIllumDist(real32 n); void partSetDeltaIllum(real32 n); void partSetDeltaIllumDist(real32 n); void partSetLifespan(real32 t); void partSetLifespanDist(real32 d); void partSetWaitspan(real32 t); void partSetWaitspanDist(real32 d); void partSetLength(real32 l); void partSetLengthDist(real32 d); void partSetDeltaLength(real32 d); void partSetDeltaLengthDist(real32 d); void partSetColorBias(real32 rb, real32 gb, real32 bb); void partSetColorBiasDist(real32 drb, real32 dgb, real32 dbb); void partSetSpecular(bool spec); void partSetStipple(bool stip); void partSetNoDepthWrite(bool noWrite); void partSetAdditiveBlends(bool add); void partSetPseudoBillboard(bool bill); void partSetTrueBillboard(bool bill); void partSetAlphaMode(udword mode); //0 - normal, 1 - additive, 2 - stippled void partSetColorScheme(sdword colorScheme); void partCreateCallbackSet(void (*function)(sdword userValue, ubyte *userData), sdword userValue, ubyte *userData); void partMultiplySystemByMatrix(psysPtr psys, matrix *m); void partCircleSolid3(vector* centre, real32 radius, sdword nSlices, color c); #endif