diff --git a/neo/framework/DeclParticle.cpp b/neo/framework/DeclParticle.cpp index 9850f41c..0ed54b11 100644 --- a/neo/framework/DeclParticle.cpp +++ b/neo/framework/DeclParticle.cpp @@ -171,246 +171,459 @@ void idDeclParticle::ParseParms( idLexer &src, float *parms, int maxParms ) { } } +/* +================ +idDeclParticle::IsParticleStageToken +================ +*/ +static bool IsParticleStageToken(const idToken& token) { + if (!token.Icmp("}")) { + return true; + } + if (!token.Icmp("{")) { + return true; + } + if (!token.Icmp("material")) { + return true; + } + if (!token.Icmp("count")) { + return true; + } + if (!token.Icmp("time")) { + return true; + } + if (!token.Icmp("cycles")) { + return true; + } + if (!token.Icmp("timeOffset")) { + return true; + } + if (!token.Icmp("deadTime")) { + return true; + } + if (!token.Icmp("randomDistribution")) { + return true; + } + if (!token.Icmp("bunching")) { + return true; + } + if (!token.Icmp("distribution")) { + return true; + } + if (!token.Icmp("direction")) { + return true; + } + if (!token.Icmp("orientation")) { + return true; + } + if (!token.Icmp("customPath")) { + return true; + } + if (!token.Icmp("speed")) { + return true; + } + if (!token.Icmp("rotation")) { + return true; + } + if (!token.Icmp("angle")) { + return true; + } + if (!token.Icmp("entityColor")) { + return true; + } + if (!token.Icmp("size")) { + return true; + } + if (!token.Icmp("aspect")) { + return true; + } + if (!token.Icmp("fadeIn")) { + return true; + } + if (!token.Icmp("fadeOut")) { + return true; + } + if (!token.Icmp("fadeIndex")) { + return true; + } + if (!token.Icmp("color")) { + return true; + } + if (!token.Icmp("fadeColor")) { + return true; + } + if (!token.Icmp("offset")) { + return true; + } + if (!token.Icmp("animationFrames")) { + return true; + } + if (!token.Icmp("animationRate")) { + return true; + } + if (!token.Icmp("boundsExpansion")) { + return true; + } + if (!token.Icmp("gravity")) { + return true; + } +#ifdef PREY + if (!token.Icmp("lowSkippable")) { + return true; + } +#endif + + return false; +} + +/* +================ +idDeclParticle::ReadParticleParmFloat +================ +*/ +static bool ReadParticleParmFloat(idLexer& src, float& value) { + idToken token; + + if (!src.ReadToken(&token)) { + src.Error("missing particle parm value"); + return false; + } + + if (!token.Cmp("-")) { + idToken token2; + + if (!src.ReadToken(&token2)) { + src.Error("no number after minus sign"); + return false; + } + + token = "-" + token2; + } + + token.StripQuotes(); + value = atof(token.c_str()); + return true; +} + /* ================ idDeclParticle::ParseParametric ================ */ -void idDeclParticle::ParseParametric( idLexer &src, idParticleParm *parm ) { +void idDeclParticle::ParseParametric(idLexer& src, idParticleParm* parm) { idToken token; parm->table = NULL; - parm->from = parm->to = 0.0f; + parm->from = 0.0f; + parm->to = 0.0f; - if ( !src.ReadToken( &token ) ) { - src.Error( "not enough parameters" ); +#ifdef PREY + parm->randomp = 0.0f; +#endif + + // + // First token can be: + // 10 + // -10 + // table sometable + // + if (!src.ReadToken(&token)) { + src.Error("missing particle parm"); return; } - if ( token.IsNumeric() ) { - // can have a to + 2nd parm - parm->from = parm->to = atof( token ); - if ( src.ReadToken( &token ) ) { - if ( !token.Icmp( "to" ) ) { - if ( !src.ReadToken( &token ) ) { - src.Error( "missing second parameter" ); - return; - } - parm->to = atof( token ); - } else { - src.UnreadToken( &token ); - } + if (!token.Cmp("-")) { + idToken token2; + + if (!src.ReadToken(&token2)) { + src.Error("no number after minus sign"); + return; } - } else { - // table - parm->table = static_cast( declManager->FindType( DECL_TABLE, token, false ) ); + + token = "-" + token2; } -} + token.StripQuotes(); + if (!token.Icmp("table")) { + if (!src.ReadToken(&token)) { + src.Error("missing table name"); + return; + } + + token.StripQuotes(); + + parm->table = static_cast(declManager->FindType(DECL_TABLE, token.c_str(), false)); + parm->from = 0.0f; + parm->to = 1.0f; + } + else { + parm->from = atof(token.c_str()); + parm->to = parm->from; + } + + // + // Prey allows: + // size 1.000 to 2.000 with 0.500 + // and also broken/exported formatting: + // size 1.000 + // with 0.500 + // + while (src.ReadToken(&token)) { + if (IsParticleStageToken(token)) { + src.UnreadToken(&token); + break; + } + + if (!token.Icmp("to")) { + if (!ReadParticleParmFloat(src, parm->to)) { + return; + } + continue; + } + +#ifdef PREY + if (!token.Icmp("with")) { + if (!ReadParticleParmFloat(src, parm->randomp)) { + return; + } + continue; + } +#endif + + // + // If some other token appears, do not eat the rest of the stage. + // Put it back so the normal stage parser can report it correctly. + // + src.UnreadToken(&token); + break; + } +} /* ================ idDeclParticle::ParseParticleStage ================ */ -idParticleStage *idDeclParticle::ParseParticleStage( idLexer &src ) { +idParticleStage* idDeclParticle::ParseParticleStage(idLexer& src) { idToken token; - idParticleStage *stage = new idParticleStage; + idParticleStage* stage = new idParticleStage; stage->Default(); while (1) { - if ( src.HadError() ) { + if (src.HadError()) { break; } - if ( !src.ReadToken( &token ) ) { + if (!src.ReadToken(&token)) { break; } - if ( !token.Icmp( "}" ) ) { + if (!token.Icmp("}")) { break; } - if ( !token.Icmp( "material" ) ) { - src.ReadToken( &token ); - stage->material = declManager->FindMaterial( token.c_str() ); + if (!token.Icmp("material")) { + src.ReadToken(&token); + stage->material = declManager->FindMaterial(token.c_str()); continue; } - if ( !token.Icmp( "count" ) ) { + if (!token.Icmp("count")) { stage->totalParticles = src.ParseInt(); continue; } - if ( !token.Icmp( "time" ) ) { + if (!token.Icmp("time")) { stage->particleLife = src.ParseFloat(); continue; } - if ( !token.Icmp( "cycles" ) ) { + if (!token.Icmp("cycles")) { stage->cycles = src.ParseFloat(); continue; } - if ( !token.Icmp( "timeOffset" ) ) { + if (!token.Icmp("timeOffset")) { stage->timeOffset = src.ParseFloat(); continue; } - if ( !token.Icmp( "deadTime" ) ) { + if (!token.Icmp("deadTime")) { stage->deadTime = src.ParseFloat(); continue; } - if ( !token.Icmp( "randomDistribution" ) ) { + if (!token.Icmp("randomDistribution")) { stage->randomDistribution = src.ParseBool(); continue; } - if ( !token.Icmp( "bunching" ) ) { + if (!token.Icmp("bunching")) { stage->spawnBunching = src.ParseFloat(); continue; } - if ( !token.Icmp( "distribution" ) ) { - src.ReadToken( &token ); - if ( !token.Icmp( "rect" ) ) { + if (!token.Icmp("distribution")) { + src.ReadToken(&token); + if (!token.Icmp("rect")) { stage->distributionType = PDIST_RECT; - } else if ( !token.Icmp( "cylinder" ) ) { + } + else if (!token.Icmp("cylinder")) { stage->distributionType = PDIST_CYLINDER; - } else if ( !token.Icmp( "sphere" ) ) { + } + else if (!token.Icmp("sphere")) { stage->distributionType = PDIST_SPHERE; - } else { - src.Error( "bad distribution type: %s\n", token.c_str() ); } - ParseParms( src, stage->distributionParms, sizeof( stage->distributionParms ) / sizeof( stage->distributionParms[0] ) ); + else { + src.Error("bad distribution type: %s\n", token.c_str()); + } + ParseParms(src, stage->distributionParms, sizeof(stage->distributionParms) / sizeof(stage->distributionParms[0])); continue; } - if ( !token.Icmp( "direction" ) ) { - src.ReadToken( &token ); - if ( !token.Icmp( "cone" ) ) { + if (!token.Icmp("direction")) { + src.ReadToken(&token); + if (!token.Icmp("cone")) { stage->directionType = PDIR_CONE; - } else if ( !token.Icmp( "outward" ) ) { + } + else if (!token.Icmp("outward")) { stage->directionType = PDIR_OUTWARD; - } else { - src.Error( "bad direction type: %s\n", token.c_str() ); } - ParseParms( src, stage->directionParms, sizeof( stage->directionParms ) / sizeof( stage->directionParms[0] ) ); + else { + src.Error("bad direction type: %s\n", token.c_str()); + } + ParseParms(src, stage->directionParms, sizeof(stage->directionParms) / sizeof(stage->directionParms[0])); continue; } - if ( !token.Icmp( "orientation" ) ) { - src.ReadToken( &token ); - if ( !token.Icmp( "view" ) ) { + if (!token.Icmp("orientation")) { + src.ReadToken(&token); + if (!token.Icmp("view")) { stage->orientation = POR_VIEW; - } else if ( !token.Icmp( "aimed" ) ) { + } + else if (!token.Icmp("aimed")) { stage->orientation = POR_AIMED; - } else if ( !token.Icmp( "x" ) ) { + } + else if (!token.Icmp("x")) { stage->orientation = POR_X; - } else if ( !token.Icmp( "y" ) ) { + } + else if (!token.Icmp("y")) { stage->orientation = POR_Y; - } else if ( !token.Icmp( "z" ) ) { + } + else if (!token.Icmp("z")) { stage->orientation = POR_Z; - } else { - src.Error( "bad orientation type: %s\n", token.c_str() ); } - ParseParms( src, stage->orientationParms, sizeof( stage->orientationParms ) / sizeof( stage->orientationParms[0] ) ); + else { + src.Error("bad orientation type: %s\n", token.c_str()); + } + ParseParms(src, stage->orientationParms, sizeof(stage->orientationParms) / sizeof(stage->orientationParms[0])); continue; } - if ( !token.Icmp( "customPath" ) ) { - src.ReadToken( &token ); - if ( !token.Icmp( "standard" ) ) { + if (!token.Icmp("customPath")) { + src.ReadToken(&token); + if (!token.Icmp("standard")) { stage->customPathType = PPATH_STANDARD; - } else if ( !token.Icmp( "helix" ) ) { - stage->customPathType = PPATH_HELIX; - } else if ( !token.Icmp( "flies" ) ) { - stage->customPathType = PPATH_FLIES; - } else if ( !token.Icmp( "spherical" ) ) { - stage->customPathType = PPATH_ORBIT; - } else { - src.Error( "bad path type: %s\n", token.c_str() ); } - ParseParms( src, stage->customPathParms, sizeof( stage->customPathParms ) / sizeof( stage->customPathParms[0] ) ); + else if (!token.Icmp("helix")) { + stage->customPathType = PPATH_HELIX; + } + else if (!token.Icmp("flies")) { + stage->customPathType = PPATH_FLIES; + } + else if (!token.Icmp("spherical")) { + stage->customPathType = PPATH_ORBIT; + } + else { + src.Error("bad path type: %s\n", token.c_str()); + } + ParseParms(src, stage->customPathParms, sizeof(stage->customPathParms) / sizeof(stage->customPathParms[0])); continue; } - if ( !token.Icmp( "speed" ) ) { - ParseParametric( src, &stage->speed ); + if (!token.Icmp("speed")) { + ParseParametric(src, &stage->speed); continue; } - if ( !token.Icmp( "rotation" ) ) { - ParseParametric( src, &stage->rotationSpeed ); + if (!token.Icmp("rotation")) { + ParseParametric(src, &stage->rotationSpeed); continue; } - if ( !token.Icmp( "angle" ) ) { + if (!token.Icmp("angle")) { stage->initialAngle = src.ParseFloat(); continue; } - if ( !token.Icmp( "entityColor" ) ) { + if (!token.Icmp("entityColor")) { stage->entityColor = src.ParseBool(); continue; } - if ( !token.Icmp( "size" ) ) { - ParseParametric( src, &stage->size ); + if (!token.Icmp("size")) { + ParseParametric(src, &stage->size); continue; } - if ( !token.Icmp( "aspect" ) ) { - ParseParametric( src, &stage->aspect ); + if (!token.Icmp("aspect")) { + ParseParametric(src, &stage->aspect); continue; } - if ( !token.Icmp( "fadeIn" ) ) { + if (!token.Icmp("fadeIn")) { stage->fadeInFraction = src.ParseFloat(); continue; } - if ( !token.Icmp( "fadeOut" ) ) { + if (!token.Icmp("fadeOut")) { stage->fadeOutFraction = src.ParseFloat(); continue; } - if ( !token.Icmp( "fadeIndex" ) ) { + if (!token.Icmp("fadeIndex")) { stage->fadeIndexFraction = src.ParseFloat(); continue; } - if ( !token.Icmp( "color" ) ) { + if (!token.Icmp("color")) { stage->color[0] = src.ParseFloat(); stage->color[1] = src.ParseFloat(); stage->color[2] = src.ParseFloat(); stage->color[3] = src.ParseFloat(); continue; } - if ( !token.Icmp( "fadeColor" ) ) { + if (!token.Icmp("fadeColor")) { stage->fadeColor[0] = src.ParseFloat(); stage->fadeColor[1] = src.ParseFloat(); stage->fadeColor[2] = src.ParseFloat(); stage->fadeColor[3] = src.ParseFloat(); continue; } - if ( !token.Icmp("offset" ) ) { + if (!token.Icmp("offset")) { stage->offset[0] = src.ParseFloat(); stage->offset[1] = src.ParseFloat(); stage->offset[2] = src.ParseFloat(); continue; } - if ( !token.Icmp( "animationFrames" ) ) { + if (!token.Icmp("animationFrames")) { stage->animationFrames = src.ParseInt(); continue; } - if ( !token.Icmp( "animationRate" ) ) { + if (!token.Icmp("animationRate")) { stage->animationRate = src.ParseFloat(); continue; } - if ( !token.Icmp( "boundsExpansion" ) ) { + if (!token.Icmp("boundsExpansion")) { stage->boundsExpansion = src.ParseFloat(); continue; } - if ( !token.Icmp( "gravity" ) ) { - src.ReadToken( &token ); - if ( !token.Icmp( "world" ) ) { + if (!token.Icmp("gravity")) { + src.ReadToken(&token); + if (!token.Icmp("world")) { stage->worldGravity = true; - } else { - src.UnreadToken( &token ); + } + else { + src.UnreadToken(&token); } stage->gravity = src.ParseFloat(); continue; } - src.Error( "unknown token %s\n", token.c_str() ); +#ifdef PREY + if (!token.Icmp("lowSkippable")) { + stage->lowSkippable = src.ParseBool(); + continue; + } +#endif + + src.Error("unknown token %s\n", token.c_str()); } // derive values - stage->cycleMsec = ( stage->particleLife + stage->deadTime ) * 1000; + stage->cycleMsec = (stage->particleLife + stage->deadTime) * 1000; return stage; } @@ -420,62 +633,122 @@ idParticleStage *idDeclParticle::ParseParticleStage( idLexer &src ) { idDeclParticle::Parse ================ */ -bool idDeclParticle::Parse( const char *text, const int textLength ) { +bool idDeclParticle::Parse(const char* text, const int textLength) { idLexer src; idToken token; - src.LoadMemory( text, textLength, GetFileName(), GetLineNum() ); - src.SetFlags( DECL_LEXER_FLAGS ); - src.SkipUntilString( "{" ); + src.LoadMemory(text, textLength, GetFileName(), GetLineNum()); + src.SetFlags(DECL_LEXER_FLAGS); + src.SkipUntilString("{"); depthHack = 0.0f; +#ifdef PREY + bool boundsSpecified = false; + bounds.Clear(); +#endif + while (1) { - if ( !src.ReadToken( &token ) ) { + if (!src.ReadToken(&token)) { break; } - if ( !token.Icmp( "}" ) ) { + if (!token.Icmp("}")) { break; } - if ( !token.Icmp( "{" ) ) { - idParticleStage *stage = ParseParticleStage( src ); - if ( !stage ) { - src.Warning( "Particle stage parse failed" ); + if (!token.Icmp("{")) { + idParticleStage* stage = ParseParticleStage(src); + if (!stage) { + src.Warning("Particle stage parse failed"); MakeDefault(); return false; } - stages.Append( stage ); + stages.Append(stage); continue; } - if ( !token.Icmp( "depthHack" ) ) { + if (!token.Icmp("depthHack")) { depthHack = src.ParseFloat(); continue; } - src.Warning( "bad token %s", token.c_str() ); +#ifdef PREY + if (!token.Icmp("bounds")) { + bounds[0][0] = src.ParseFloat(); + bounds[0][1] = src.ParseFloat(); + bounds[0][2] = src.ParseFloat(); + + bounds[1][0] = src.ParseFloat(); + bounds[1][1] = src.ParseFloat(); + bounds[1][2] = src.ParseFloat(); + + boundsSpecified = true; + continue; + } +#endif + + src.Warning("bad token %s", token.c_str()); MakeDefault(); return false; } +#ifdef PREY + // + // Prey declarations may carry explicit bounds. + // If no bounds were present, or the cvar asks for recalculation, + // recalculate them and rebuild the source text with a bounds line. + // + if (!boundsSpecified || cvarSystem->GetCVarBool("r_recalcParticleBounds")) { + CalcBounds(); + RebuildTextSource(); + } +#else // // calculate the bounds // bounds.Clear(); - for( int i = 0; i < stages.Num(); i++ ) { - GetStageBounds( stages[i] ); - bounds.AddBounds( stages[i]->bounds ); + for (int i = 0; i < stages.Num(); i++) { + GetStageBounds(stages[i]); + bounds.AddBounds(stages[i]->bounds); } - if ( bounds.GetVolume() <= 0.1f ) { - bounds = idBounds( vec3_origin ).Expand( 8.0f ); + if (bounds.GetVolume() <= 0.1f) { + bounds = idBounds(vec3_origin).Expand(8.0f); } +#endif return true; } +#ifdef PREY +/* +================ +idDeclParticle::CalcBounds + +HUMANHEAD bjk +================ +*/ +void idDeclParticle::CalcBounds(void) { + bounds.Clear(); + + for (int i = 0; i < stages.Num(); i++) { +#ifdef PARTICLE_BOUNDS + idDrawVert particleVerts[MAX_PARTICLES * 4]; // see note below + GetStageBounds(stages[i], particleVerts); +#else + GetStageBounds(stages[i]); +#endif + + bounds.AddBounds(stages[i]->bounds); + } + + if (bounds.GetVolume() <= 0.1f) { + bounds = idBounds(vec3_origin).Expand(8.0f); + } +} +#endif + /* ================ idDeclParticle::FreeData @@ -744,6 +1017,9 @@ void idParticleStage::Default() { spawnBunching = 1.0f; particleLife = 1.5f; timeOffset = 0.0f; +#ifdef PREY + lowSkippable = false; +#endif deadTime = 0.0f; distributionType = PDIST_RECT; distributionParms[0] = 8.0f; diff --git a/neo/framework/DeclParticle.h b/neo/framework/DeclParticle.h index 4bbdd6e3..1b5d12bb 100644 --- a/neo/framework/DeclParticle.h +++ b/neo/framework/DeclParticle.h @@ -39,14 +39,23 @@ If you have questions concerning this license or the applicable additional terms class idParticleParm { public: - idParticleParm( void ) { table = NULL; from = to = 0.0f; } + idParticleParm(void) { + table = NULL; + from = to = 0.0f; +#ifdef PREY + randomp = 0.0f; +#endif + } - const idDeclTable * table; + const idDeclTable* table; float from; float to; - - float Eval( float frac, idRandom &rand ) const; - float Integrate( float frac, idRandom &rand ) const; +#ifdef PREY + float randomp; // HUMANHEAD bjk +#endif + + float Eval(float frac, idRandom& rand) const; + float Integrate(float frac, idRandom& rand) const; }; @@ -83,15 +92,14 @@ typedef struct renderEntity_s renderEntity_t; typedef struct renderView_s renderView_t; typedef struct { - const renderEntity_t * renderEnt; // for shaderParms, etc - const renderView_t * renderView; + const renderEntity_t* renderEnt; // for shaderParms, etc + const renderView_t* renderView; int index; // particle number in the system float frac; // 0.0 to 1.0 idRandom random; idVec3 origin; // dynamic smoke particles can have individual origins and axis idMat3 axis; - float age; // in seconds, calculated as fraction * stage->particleLife idRandom originalRandom; // needed so aimed particles can reset the random for another origin calculation float animationFrameFrac; // set by ParticleTexCoords, used to make the cross faded version @@ -103,33 +111,33 @@ typedef struct { // class idParticleStage { public: - idParticleStage( void ); - virtual ~idParticleStage( void ) {} + idParticleStage(void); + virtual ~idParticleStage(void) {} void Default(); virtual int NumQuadsPerParticle() const; // includes trails and cross faded animations // returns the number of verts created, which will range from 0 to 4*NumQuadsPerParticle() - virtual int CreateParticle( particleGen_t *g, idDrawVert *verts ) const; + virtual int CreateParticle(particleGen_t* g, idDrawVert* verts) const; - void ParticleOrigin( particleGen_t *g, idVec3 &origin ) const; - int ParticleVerts( particleGen_t *g, const idVec3 origin, idDrawVert *verts ) const; - void ParticleTexCoords( particleGen_t *g, idDrawVert *verts ) const; - void ParticleColors( particleGen_t *g, idDrawVert *verts ) const; + void ParticleOrigin(particleGen_t* g, idVec3& origin) const; + int ParticleVerts(particleGen_t* g, const idVec3 origin, idDrawVert* verts) const; + void ParticleTexCoords(particleGen_t* g, idDrawVert* verts) const; + void ParticleColors(particleGen_t* g, idDrawVert* verts) const; - const char * GetCustomPathName(); - const char * GetCustomPathDesc(); + const char* GetCustomPathName(); + const char* GetCustomPathDesc(); int NumCustomPathParms(); - void SetCustomPathType( const char *p ); - void operator=( const idParticleStage &src ); + void SetCustomPathType(const char* p); + void operator=(const idParticleStage& src); //------------------------------ - const idMaterial * material; + const idMaterial* material; int totalParticles; // total number of particles, although some may be invisible at a given time float cycles; // allows things to oneShot ( 1 cycle ) or run for a set number of cycles - // on a per stage basis + // on a per stage basis int cycleMsec; // ( particleLife + deadTime ) in msec @@ -137,37 +145,37 @@ public: float particleLife; // total seconds of life for each particle float timeOffset; // time offset from system start for the first particle to spawn float deadTime; // time after particleLife before respawning - + //------------------------------- // standard path parms - + prtDistribution_t distributionType; float distributionParms[4]; - + prtDirection_t directionType; float directionParms[4]; - + idParticleParm speed; float gravity; // can be negative to float up bool worldGravity; // apply gravity in world space bool randomDistribution; // randomly orient the quad on emission ( defaults to true ) bool entityColor; // force color from render entity ( fadeColor is still valid ) - + //------------------------------ // custom path will completely replace the standard path calculations - + prtCustomPth_t customPathType; // use custom C code routines for determining the origin float customPathParms[8]; - + //-------------------------------- - + idVec3 offset; // offset from origin to spawn all particles, also applies to customPath - + int animationFrames; // if > 1, subdivide the texture S axis into frames and crossfade float animationRate; // frames per second float initialAngle; // in degrees, random angle is used if zero ( default ) idParticleParm rotationSpeed; // half the particles will have negative rotation speeds - - prtOrientation_t orientation; // view, aimed, or axis fixed + + prtOrientation_t orientation; // view, aimed, or axis fixed float orientationParms[4]; idParticleParm size; @@ -185,6 +193,10 @@ public: float boundsExpansion; // user tweak to fix poorly calculated bounds idBounds bounds; // derived + +#ifdef PREY + bool lowSkippable; // HUMANHEAD bjk +#endif }; @@ -194,25 +206,38 @@ public: class idDeclParticle : public idDecl { public: - virtual size_t Size( void ) const; - virtual const char * DefaultDefinition( void ) const; - virtual bool Parse( const char *text, const int textLength ); - virtual void FreeData( void ); + virtual size_t Size(void) const; + virtual const char* DefaultDefinition(void) const; + virtual bool Parse(const char* text, const int textLength); + virtual void FreeData(void); - bool Save( const char *fileName = NULL ); + bool Save(const char* fileName = NULL); - idListstages; + idListstages; idBounds bounds; float depthHack; private: - bool RebuildTextSource( void ); - void GetStageBounds( idParticleStage *stage ); - idParticleStage * ParseParticleStage( idLexer &src ); - void ParseParms( idLexer &src, float *parms, int maxParms ); - void ParseParametric( idLexer &src, idParticleParm *parm ); - void WriteStage( idFile *f, idParticleStage *stage ); - void WriteParticleParm( idFile *f, idParticleParm *parm, const char *name ); + bool RebuildTextSource(void); + +#ifdef PREY + void CalcBounds(void); // HUMANHEAD bjk + +# ifdef PARTICLE_BOUNDS + void GetStageBounds(idParticleStage* stage, idDrawVert* particleVerts); +# else + void GetStageBounds(idParticleStage* stage); +# endif + +#else + void GetStageBounds(idParticleStage* stage); +#endif + + idParticleStage* ParseParticleStage(idLexer& src); + void ParseParms(idLexer& src, float* parms, int maxParms); + void ParseParametric(idLexer& src, idParticleParm* parm); + void WriteStage(idFile* f, idParticleStage* stage); + void WriteParticleParm(idFile* f, idParticleParm* parm, const char* name); }; #endif /* !__DECLPARTICLE_H__ */