mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-19 20:19:50 +02:00
Fixed particles for Prey.
This commit is contained in:
+393
-117
@@ -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
|
idDeclParticle::ParseParametric
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
void idDeclParticle::ParseParametric( idLexer &src, idParticleParm *parm ) {
|
void idDeclParticle::ParseParametric(idLexer& src, idParticleParm* parm) {
|
||||||
idToken token;
|
idToken token;
|
||||||
|
|
||||||
parm->table = NULL;
|
parm->table = NULL;
|
||||||
parm->from = parm->to = 0.0f;
|
parm->from = 0.0f;
|
||||||
|
parm->to = 0.0f;
|
||||||
|
|
||||||
if ( !src.ReadToken( &token ) ) {
|
#ifdef PREY
|
||||||
src.Error( "not enough parameters" );
|
parm->randomp = 0.0f;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// First token can be:
|
||||||
|
// 10
|
||||||
|
// -10
|
||||||
|
// table sometable
|
||||||
|
//
|
||||||
|
if (!src.ReadToken(&token)) {
|
||||||
|
src.Error("missing particle parm");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( token.IsNumeric() ) {
|
if (!token.Cmp("-")) {
|
||||||
// can have a to + 2nd parm
|
idToken token2;
|
||||||
parm->from = parm->to = atof( token );
|
|
||||||
if ( src.ReadToken( &token ) ) {
|
if (!src.ReadToken(&token2)) {
|
||||||
if ( !token.Icmp( "to" ) ) {
|
src.Error("no number after minus sign");
|
||||||
if ( !src.ReadToken( &token ) ) {
|
return;
|
||||||
src.Error( "missing second parameter" );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
parm->to = atof( token );
|
|
||||||
} else {
|
|
||||||
src.UnreadToken( &token );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// table
|
token = "-" + token2;
|
||||||
parm->table = static_cast<const idDeclTable *>( declManager->FindType( DECL_TABLE, token, false ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
token.StripQuotes();
|
||||||
|
|
||||||
|
if (!token.Icmp("table")) {
|
||||||
|
if (!src.ReadToken(&token)) {
|
||||||
|
src.Error("missing table name");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
token.StripQuotes();
|
||||||
|
|
||||||
|
parm->table = static_cast<const idDeclTable*>(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
|
idDeclParticle::ParseParticleStage
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
idParticleStage *idDeclParticle::ParseParticleStage( idLexer &src ) {
|
idParticleStage* idDeclParticle::ParseParticleStage(idLexer& src) {
|
||||||
idToken token;
|
idToken token;
|
||||||
|
|
||||||
idParticleStage *stage = new idParticleStage;
|
idParticleStage* stage = new idParticleStage;
|
||||||
stage->Default();
|
stage->Default();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if ( src.HadError() ) {
|
if (src.HadError()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( !src.ReadToken( &token ) ) {
|
if (!src.ReadToken(&token)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "}" ) ) {
|
if (!token.Icmp("}")) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "material" ) ) {
|
if (!token.Icmp("material")) {
|
||||||
src.ReadToken( &token );
|
src.ReadToken(&token);
|
||||||
stage->material = declManager->FindMaterial( token.c_str() );
|
stage->material = declManager->FindMaterial(token.c_str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "count" ) ) {
|
if (!token.Icmp("count")) {
|
||||||
stage->totalParticles = src.ParseInt();
|
stage->totalParticles = src.ParseInt();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "time" ) ) {
|
if (!token.Icmp("time")) {
|
||||||
stage->particleLife = src.ParseFloat();
|
stage->particleLife = src.ParseFloat();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "cycles" ) ) {
|
if (!token.Icmp("cycles")) {
|
||||||
stage->cycles = src.ParseFloat();
|
stage->cycles = src.ParseFloat();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "timeOffset" ) ) {
|
if (!token.Icmp("timeOffset")) {
|
||||||
stage->timeOffset = src.ParseFloat();
|
stage->timeOffset = src.ParseFloat();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "deadTime" ) ) {
|
if (!token.Icmp("deadTime")) {
|
||||||
stage->deadTime = src.ParseFloat();
|
stage->deadTime = src.ParseFloat();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "randomDistribution" ) ) {
|
if (!token.Icmp("randomDistribution")) {
|
||||||
stage->randomDistribution = src.ParseBool();
|
stage->randomDistribution = src.ParseBool();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "bunching" ) ) {
|
if (!token.Icmp("bunching")) {
|
||||||
stage->spawnBunching = src.ParseFloat();
|
stage->spawnBunching = src.ParseFloat();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !token.Icmp( "distribution" ) ) {
|
if (!token.Icmp("distribution")) {
|
||||||
src.ReadToken( &token );
|
src.ReadToken(&token);
|
||||||
if ( !token.Icmp( "rect" ) ) {
|
if (!token.Icmp("rect")) {
|
||||||
stage->distributionType = PDIST_RECT;
|
stage->distributionType = PDIST_RECT;
|
||||||
} else if ( !token.Icmp( "cylinder" ) ) {
|
}
|
||||||
|
else if (!token.Icmp("cylinder")) {
|
||||||
stage->distributionType = PDIST_CYLINDER;
|
stage->distributionType = PDIST_CYLINDER;
|
||||||
} else if ( !token.Icmp( "sphere" ) ) {
|
}
|
||||||
|
else if (!token.Icmp("sphere")) {
|
||||||
stage->distributionType = PDIST_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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !token.Icmp( "direction" ) ) {
|
if (!token.Icmp("direction")) {
|
||||||
src.ReadToken( &token );
|
src.ReadToken(&token);
|
||||||
if ( !token.Icmp( "cone" ) ) {
|
if (!token.Icmp("cone")) {
|
||||||
stage->directionType = PDIR_CONE;
|
stage->directionType = PDIR_CONE;
|
||||||
} else if ( !token.Icmp( "outward" ) ) {
|
}
|
||||||
|
else if (!token.Icmp("outward")) {
|
||||||
stage->directionType = PDIR_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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !token.Icmp( "orientation" ) ) {
|
if (!token.Icmp("orientation")) {
|
||||||
src.ReadToken( &token );
|
src.ReadToken(&token);
|
||||||
if ( !token.Icmp( "view" ) ) {
|
if (!token.Icmp("view")) {
|
||||||
stage->orientation = POR_VIEW;
|
stage->orientation = POR_VIEW;
|
||||||
} else if ( !token.Icmp( "aimed" ) ) {
|
}
|
||||||
|
else if (!token.Icmp("aimed")) {
|
||||||
stage->orientation = POR_AIMED;
|
stage->orientation = POR_AIMED;
|
||||||
} else if ( !token.Icmp( "x" ) ) {
|
}
|
||||||
|
else if (!token.Icmp("x")) {
|
||||||
stage->orientation = POR_X;
|
stage->orientation = POR_X;
|
||||||
} else if ( !token.Icmp( "y" ) ) {
|
}
|
||||||
|
else if (!token.Icmp("y")) {
|
||||||
stage->orientation = POR_Y;
|
stage->orientation = POR_Y;
|
||||||
} else if ( !token.Icmp( "z" ) ) {
|
}
|
||||||
|
else if (!token.Icmp("z")) {
|
||||||
stage->orientation = POR_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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !token.Icmp( "customPath" ) ) {
|
if (!token.Icmp("customPath")) {
|
||||||
src.ReadToken( &token );
|
src.ReadToken(&token);
|
||||||
if ( !token.Icmp( "standard" ) ) {
|
if (!token.Icmp("standard")) {
|
||||||
stage->customPathType = PPATH_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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !token.Icmp( "speed" ) ) {
|
if (!token.Icmp("speed")) {
|
||||||
ParseParametric( src, &stage->speed );
|
ParseParametric(src, &stage->speed);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "rotation" ) ) {
|
if (!token.Icmp("rotation")) {
|
||||||
ParseParametric( src, &stage->rotationSpeed );
|
ParseParametric(src, &stage->rotationSpeed);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "angle" ) ) {
|
if (!token.Icmp("angle")) {
|
||||||
stage->initialAngle = src.ParseFloat();
|
stage->initialAngle = src.ParseFloat();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "entityColor" ) ) {
|
if (!token.Icmp("entityColor")) {
|
||||||
stage->entityColor = src.ParseBool();
|
stage->entityColor = src.ParseBool();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "size" ) ) {
|
if (!token.Icmp("size")) {
|
||||||
ParseParametric( src, &stage->size );
|
ParseParametric(src, &stage->size);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "aspect" ) ) {
|
if (!token.Icmp("aspect")) {
|
||||||
ParseParametric( src, &stage->aspect );
|
ParseParametric(src, &stage->aspect);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "fadeIn" ) ) {
|
if (!token.Icmp("fadeIn")) {
|
||||||
stage->fadeInFraction = src.ParseFloat();
|
stage->fadeInFraction = src.ParseFloat();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "fadeOut" ) ) {
|
if (!token.Icmp("fadeOut")) {
|
||||||
stage->fadeOutFraction = src.ParseFloat();
|
stage->fadeOutFraction = src.ParseFloat();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "fadeIndex" ) ) {
|
if (!token.Icmp("fadeIndex")) {
|
||||||
stage->fadeIndexFraction = src.ParseFloat();
|
stage->fadeIndexFraction = src.ParseFloat();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "color" ) ) {
|
if (!token.Icmp("color")) {
|
||||||
stage->color[0] = src.ParseFloat();
|
stage->color[0] = src.ParseFloat();
|
||||||
stage->color[1] = src.ParseFloat();
|
stage->color[1] = src.ParseFloat();
|
||||||
stage->color[2] = src.ParseFloat();
|
stage->color[2] = src.ParseFloat();
|
||||||
stage->color[3] = src.ParseFloat();
|
stage->color[3] = src.ParseFloat();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "fadeColor" ) ) {
|
if (!token.Icmp("fadeColor")) {
|
||||||
stage->fadeColor[0] = src.ParseFloat();
|
stage->fadeColor[0] = src.ParseFloat();
|
||||||
stage->fadeColor[1] = src.ParseFloat();
|
stage->fadeColor[1] = src.ParseFloat();
|
||||||
stage->fadeColor[2] = src.ParseFloat();
|
stage->fadeColor[2] = src.ParseFloat();
|
||||||
stage->fadeColor[3] = src.ParseFloat();
|
stage->fadeColor[3] = src.ParseFloat();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp("offset" ) ) {
|
if (!token.Icmp("offset")) {
|
||||||
stage->offset[0] = src.ParseFloat();
|
stage->offset[0] = src.ParseFloat();
|
||||||
stage->offset[1] = src.ParseFloat();
|
stage->offset[1] = src.ParseFloat();
|
||||||
stage->offset[2] = src.ParseFloat();
|
stage->offset[2] = src.ParseFloat();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "animationFrames" ) ) {
|
if (!token.Icmp("animationFrames")) {
|
||||||
stage->animationFrames = src.ParseInt();
|
stage->animationFrames = src.ParseInt();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "animationRate" ) ) {
|
if (!token.Icmp("animationRate")) {
|
||||||
stage->animationRate = src.ParseFloat();
|
stage->animationRate = src.ParseFloat();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "boundsExpansion" ) ) {
|
if (!token.Icmp("boundsExpansion")) {
|
||||||
stage->boundsExpansion = src.ParseFloat();
|
stage->boundsExpansion = src.ParseFloat();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !token.Icmp( "gravity" ) ) {
|
if (!token.Icmp("gravity")) {
|
||||||
src.ReadToken( &token );
|
src.ReadToken(&token);
|
||||||
if ( !token.Icmp( "world" ) ) {
|
if (!token.Icmp("world")) {
|
||||||
stage->worldGravity = true;
|
stage->worldGravity = true;
|
||||||
} else {
|
}
|
||||||
src.UnreadToken( &token );
|
else {
|
||||||
|
src.UnreadToken(&token);
|
||||||
}
|
}
|
||||||
stage->gravity = src.ParseFloat();
|
stage->gravity = src.ParseFloat();
|
||||||
continue;
|
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
|
// derive values
|
||||||
stage->cycleMsec = ( stage->particleLife + stage->deadTime ) * 1000;
|
stage->cycleMsec = (stage->particleLife + stage->deadTime) * 1000;
|
||||||
|
|
||||||
return stage;
|
return stage;
|
||||||
}
|
}
|
||||||
@@ -420,62 +633,122 @@ idParticleStage *idDeclParticle::ParseParticleStage( idLexer &src ) {
|
|||||||
idDeclParticle::Parse
|
idDeclParticle::Parse
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
bool idDeclParticle::Parse( const char *text, const int textLength ) {
|
bool idDeclParticle::Parse(const char* text, const int textLength) {
|
||||||
idLexer src;
|
idLexer src;
|
||||||
idToken token;
|
idToken token;
|
||||||
|
|
||||||
src.LoadMemory( text, textLength, GetFileName(), GetLineNum() );
|
src.LoadMemory(text, textLength, GetFileName(), GetLineNum());
|
||||||
src.SetFlags( DECL_LEXER_FLAGS );
|
src.SetFlags(DECL_LEXER_FLAGS);
|
||||||
src.SkipUntilString( "{" );
|
src.SkipUntilString("{");
|
||||||
|
|
||||||
depthHack = 0.0f;
|
depthHack = 0.0f;
|
||||||
|
|
||||||
|
#ifdef PREY
|
||||||
|
bool boundsSpecified = false;
|
||||||
|
bounds.Clear();
|
||||||
|
#endif
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if ( !src.ReadToken( &token ) ) {
|
if (!src.ReadToken(&token)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !token.Icmp( "}" ) ) {
|
if (!token.Icmp("}")) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !token.Icmp( "{" ) ) {
|
if (!token.Icmp("{")) {
|
||||||
idParticleStage *stage = ParseParticleStage( src );
|
idParticleStage* stage = ParseParticleStage(src);
|
||||||
if ( !stage ) {
|
if (!stage) {
|
||||||
src.Warning( "Particle stage parse failed" );
|
src.Warning("Particle stage parse failed");
|
||||||
MakeDefault();
|
MakeDefault();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
stages.Append( stage );
|
stages.Append(stage);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !token.Icmp( "depthHack" ) ) {
|
if (!token.Icmp("depthHack")) {
|
||||||
depthHack = src.ParseFloat();
|
depthHack = src.ParseFloat();
|
||||||
continue;
|
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();
|
MakeDefault();
|
||||||
return false;
|
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
|
// calculate the bounds
|
||||||
//
|
//
|
||||||
bounds.Clear();
|
bounds.Clear();
|
||||||
for( int i = 0; i < stages.Num(); i++ ) {
|
for (int i = 0; i < stages.Num(); i++) {
|
||||||
GetStageBounds( stages[i] );
|
GetStageBounds(stages[i]);
|
||||||
bounds.AddBounds( stages[i]->bounds );
|
bounds.AddBounds(stages[i]->bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( bounds.GetVolume() <= 0.1f ) {
|
if (bounds.GetVolume() <= 0.1f) {
|
||||||
bounds = idBounds( vec3_origin ).Expand( 8.0f );
|
bounds = idBounds(vec3_origin).Expand(8.0f);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
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
|
idDeclParticle::FreeData
|
||||||
@@ -744,6 +1017,9 @@ void idParticleStage::Default() {
|
|||||||
spawnBunching = 1.0f;
|
spawnBunching = 1.0f;
|
||||||
particleLife = 1.5f;
|
particleLife = 1.5f;
|
||||||
timeOffset = 0.0f;
|
timeOffset = 0.0f;
|
||||||
|
#ifdef PREY
|
||||||
|
lowSkippable = false;
|
||||||
|
#endif
|
||||||
deadTime = 0.0f;
|
deadTime = 0.0f;
|
||||||
distributionType = PDIST_RECT;
|
distributionType = PDIST_RECT;
|
||||||
distributionParms[0] = 8.0f;
|
distributionParms[0] = 8.0f;
|
||||||
|
|||||||
@@ -39,14 +39,23 @@ If you have questions concerning this license or the applicable additional terms
|
|||||||
|
|
||||||
class idParticleParm {
|
class idParticleParm {
|
||||||
public:
|
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 from;
|
||||||
float to;
|
float to;
|
||||||
|
#ifdef PREY
|
||||||
float Eval( float frac, idRandom &rand ) const;
|
float randomp; // HUMANHEAD bjk
|
||||||
float Integrate( float frac, idRandom &rand ) const;
|
#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 renderView_s renderView_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const renderEntity_t * renderEnt; // for shaderParms, etc
|
const renderEntity_t* renderEnt; // for shaderParms, etc
|
||||||
const renderView_t * renderView;
|
const renderView_t* renderView;
|
||||||
int index; // particle number in the system
|
int index; // particle number in the system
|
||||||
float frac; // 0.0 to 1.0
|
float frac; // 0.0 to 1.0
|
||||||
idRandom random;
|
idRandom random;
|
||||||
idVec3 origin; // dynamic smoke particles can have individual origins and axis
|
idVec3 origin; // dynamic smoke particles can have individual origins and axis
|
||||||
idMat3 axis;
|
idMat3 axis;
|
||||||
|
|
||||||
|
|
||||||
float age; // in seconds, calculated as fraction * stage->particleLife
|
float age; // in seconds, calculated as fraction * stage->particleLife
|
||||||
idRandom originalRandom; // needed so aimed particles can reset the random for another origin calculation
|
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
|
float animationFrameFrac; // set by ParticleTexCoords, used to make the cross faded version
|
||||||
@@ -103,33 +111,33 @@ typedef struct {
|
|||||||
//
|
//
|
||||||
class idParticleStage {
|
class idParticleStage {
|
||||||
public:
|
public:
|
||||||
idParticleStage( void );
|
idParticleStage(void);
|
||||||
virtual ~idParticleStage( void ) {}
|
virtual ~idParticleStage(void) {}
|
||||||
|
|
||||||
void Default();
|
void Default();
|
||||||
virtual int NumQuadsPerParticle() const; // includes trails and cross faded animations
|
virtual int NumQuadsPerParticle() const; // includes trails and cross faded animations
|
||||||
// returns the number of verts created, which will range from 0 to 4*NumQuadsPerParticle()
|
// 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;
|
void ParticleOrigin(particleGen_t* g, idVec3& origin) const;
|
||||||
int ParticleVerts( particleGen_t *g, const idVec3 origin, idDrawVert *verts ) const;
|
int ParticleVerts(particleGen_t* g, const idVec3 origin, idDrawVert* verts) const;
|
||||||
void ParticleTexCoords( particleGen_t *g, idDrawVert *verts ) const;
|
void ParticleTexCoords(particleGen_t* g, idDrawVert* verts) const;
|
||||||
void ParticleColors( particleGen_t *g, idDrawVert *verts ) const;
|
void ParticleColors(particleGen_t* g, idDrawVert* verts) const;
|
||||||
|
|
||||||
const char * GetCustomPathName();
|
const char* GetCustomPathName();
|
||||||
const char * GetCustomPathDesc();
|
const char* GetCustomPathDesc();
|
||||||
int NumCustomPathParms();
|
int NumCustomPathParms();
|
||||||
void SetCustomPathType( const char *p );
|
void SetCustomPathType(const char* p);
|
||||||
void operator=( const idParticleStage &src );
|
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
|
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
|
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
|
int cycleMsec; // ( particleLife + deadTime ) in msec
|
||||||
|
|
||||||
@@ -137,37 +145,37 @@ public:
|
|||||||
float particleLife; // total seconds of life for each particle
|
float particleLife; // total seconds of life for each particle
|
||||||
float timeOffset; // time offset from system start for the first particle to spawn
|
float timeOffset; // time offset from system start for the first particle to spawn
|
||||||
float deadTime; // time after particleLife before respawning
|
float deadTime; // time after particleLife before respawning
|
||||||
|
|
||||||
//------------------------------- // standard path parms
|
//------------------------------- // standard path parms
|
||||||
|
|
||||||
prtDistribution_t distributionType;
|
prtDistribution_t distributionType;
|
||||||
float distributionParms[4];
|
float distributionParms[4];
|
||||||
|
|
||||||
prtDirection_t directionType;
|
prtDirection_t directionType;
|
||||||
float directionParms[4];
|
float directionParms[4];
|
||||||
|
|
||||||
idParticleParm speed;
|
idParticleParm speed;
|
||||||
float gravity; // can be negative to float up
|
float gravity; // can be negative to float up
|
||||||
bool worldGravity; // apply gravity in world space
|
bool worldGravity; // apply gravity in world space
|
||||||
bool randomDistribution; // randomly orient the quad on emission ( defaults to true )
|
bool randomDistribution; // randomly orient the quad on emission ( defaults to true )
|
||||||
bool entityColor; // force color from render entity ( fadeColor is still valid )
|
bool entityColor; // force color from render entity ( fadeColor is still valid )
|
||||||
|
|
||||||
//------------------------------ // custom path will completely replace the standard path calculations
|
//------------------------------ // custom path will completely replace the standard path calculations
|
||||||
|
|
||||||
prtCustomPth_t customPathType; // use custom C code routines for determining the origin
|
prtCustomPth_t customPathType; // use custom C code routines for determining the origin
|
||||||
float customPathParms[8];
|
float customPathParms[8];
|
||||||
|
|
||||||
//--------------------------------
|
//--------------------------------
|
||||||
|
|
||||||
idVec3 offset; // offset from origin to spawn all particles, also applies to customPath
|
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
|
int animationFrames; // if > 1, subdivide the texture S axis into frames and crossfade
|
||||||
float animationRate; // frames per second
|
float animationRate; // frames per second
|
||||||
|
|
||||||
float initialAngle; // in degrees, random angle is used if zero ( default )
|
float initialAngle; // in degrees, random angle is used if zero ( default )
|
||||||
idParticleParm rotationSpeed; // half the particles will have negative rotation speeds
|
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];
|
float orientationParms[4];
|
||||||
|
|
||||||
idParticleParm size;
|
idParticleParm size;
|
||||||
@@ -185,6 +193,10 @@ public:
|
|||||||
float boundsExpansion; // user tweak to fix poorly calculated bounds
|
float boundsExpansion; // user tweak to fix poorly calculated bounds
|
||||||
|
|
||||||
idBounds bounds; // derived
|
idBounds bounds; // derived
|
||||||
|
|
||||||
|
#ifdef PREY
|
||||||
|
bool lowSkippable; // HUMANHEAD bjk
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -194,25 +206,38 @@ public:
|
|||||||
class idDeclParticle : public idDecl {
|
class idDeclParticle : public idDecl {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual size_t Size( void ) const;
|
virtual size_t Size(void) const;
|
||||||
virtual const char * DefaultDefinition( void ) const;
|
virtual const char* DefaultDefinition(void) const;
|
||||||
virtual bool Parse( const char *text, const int textLength );
|
virtual bool Parse(const char* text, const int textLength);
|
||||||
virtual void FreeData( void );
|
virtual void FreeData(void);
|
||||||
|
|
||||||
bool Save( const char *fileName = NULL );
|
bool Save(const char* fileName = NULL);
|
||||||
|
|
||||||
idList<idParticleStage *>stages;
|
idList<idParticleStage*>stages;
|
||||||
idBounds bounds;
|
idBounds bounds;
|
||||||
float depthHack;
|
float depthHack;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool RebuildTextSource( void );
|
bool RebuildTextSource(void);
|
||||||
void GetStageBounds( idParticleStage *stage );
|
|
||||||
idParticleStage * ParseParticleStage( idLexer &src );
|
#ifdef PREY
|
||||||
void ParseParms( idLexer &src, float *parms, int maxParms );
|
void CalcBounds(void); // HUMANHEAD bjk
|
||||||
void ParseParametric( idLexer &src, idParticleParm *parm );
|
|
||||||
void WriteStage( idFile *f, idParticleStage *stage );
|
# ifdef PARTICLE_BOUNDS
|
||||||
void WriteParticleParm( idFile *f, idParticleParm *parm, const char *name );
|
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__ */
|
#endif /* !__DECLPARTICLE_H__ */
|
||||||
|
|||||||
Reference in New Issue
Block a user