29 #include "../idlib/precompiled.h"
40 {
"cylinder", 4,
"" },
58 {
"standard", 0,
"Standard" },
59 {
"helix", 5,
"sizeX Y Z radialSpeed axialSpeed" },
60 {
"flies", 3,
"radialSpeed axialSpeed size" },
61 {
"orbit", 2,
"radius speed"},
62 {
"drip", 2,
"something something" }
90 memset( &renderEntity, 0,
sizeof( renderEntity ) );
94 memset( &renderView, 0,
sizeof( renderView ) );
106 for (
int i = 0 ;
i < 1000 ;
i++ ) {
110 for (
int inCycleTime = 0 ; inCycleTime < maxMsec ; inCycleTime += 16 ) {
113 if ( inCycleTime + 16 > maxMsec ) {
114 inCycleTime = maxMsec - 1;
118 g.
age = inCycleTime * 0.001f;
132 for (
float f = 0;
f <= 1.0f;
f += 1.0f / 64 ) {
134 float aspect = stage->
aspect.
Eval(
f, steppingRandom );
138 if ( size > maxSize ) {
158 memset( parms, 0, maxParms *
sizeof( *parms ) );
164 if ( count == maxParms ) {
165 src.
Error(
"too many parms on line" );
169 parms[
count] = atof( token );
183 parm->
from = parm->
to = 0.0f;
186 src.
Error(
"not enough parameters" );
192 parm->
from = parm->
to = atof( token );
194 if ( !token.
Icmp(
"to" ) ) {
196 src.
Error(
"missing second parameter" );
199 parm->
to = atof( token );
229 if ( !token.
Icmp(
"}" ) ) {
232 if ( !token.
Icmp(
"material" ) ) {
237 if ( !token.
Icmp(
"count" ) ) {
241 if ( !token.
Icmp(
"time" ) ) {
245 if ( !token.
Icmp(
"cycles" ) ) {
249 if ( !token.
Icmp(
"timeOffset" ) ) {
253 if ( !token.
Icmp(
"deadTime" ) ) {
257 if ( !token.
Icmp(
"randomDistribution" ) ) {
261 if ( !token.
Icmp(
"bunching" ) ) {
266 if ( !token.
Icmp(
"distribution" ) ) {
268 if ( !token.
Icmp(
"rect" ) ) {
270 }
else if ( !token.
Icmp(
"cylinder" ) ) {
272 }
else if ( !token.
Icmp(
"sphere" ) ) {
275 src.
Error(
"bad distribution type: %s\n", token.
c_str() );
281 if ( !token.
Icmp(
"direction" ) ) {
283 if ( !token.
Icmp(
"cone" ) ) {
285 }
else if ( !token.
Icmp(
"outward" ) ) {
288 src.
Error(
"bad direction type: %s\n", token.
c_str() );
294 if ( !token.
Icmp(
"orientation" ) ) {
296 if ( !token.
Icmp(
"view" ) ) {
298 }
else if ( !token.
Icmp(
"aimed" ) ) {
300 }
else if ( !token.
Icmp(
"x" ) ) {
302 }
else if ( !token.
Icmp(
"y" ) ) {
304 }
else if ( !token.
Icmp(
"z" ) ) {
307 src.
Error(
"bad orientation type: %s\n", token.
c_str() );
313 if ( !token.
Icmp(
"customPath" ) ) {
315 if ( !token.
Icmp(
"standard" ) ) {
317 }
else if ( !token.
Icmp(
"helix" ) ) {
319 }
else if ( !token.
Icmp(
"flies" ) ) {
321 }
else if ( !token.
Icmp(
"spherical" ) ) {
324 src.
Error(
"bad path type: %s\n", token.
c_str() );
330 if ( !token.
Icmp(
"speed" ) ) {
334 if ( !token.
Icmp(
"rotation" ) ) {
338 if ( !token.
Icmp(
"angle" ) ) {
342 if ( !token.
Icmp(
"entityColor" ) ) {
346 if ( !token.
Icmp(
"size" ) ) {
350 if ( !token.
Icmp(
"aspect" ) ) {
354 if ( !token.
Icmp(
"fadeIn" ) ) {
358 if ( !token.
Icmp(
"fadeOut" ) ) {
362 if ( !token.
Icmp(
"fadeIndex" ) ) {
366 if ( !token.
Icmp(
"color" ) ) {
373 if ( !token.
Icmp(
"fadeColor" ) ) {
380 if ( !token.
Icmp(
"offset" ) ) {
386 if ( !token.
Icmp(
"animationFrames" ) ) {
390 if ( !token.
Icmp(
"animationRate" ) ) {
394 if ( !token.
Icmp(
"boundsExpansion" ) ) {
398 if ( !token.
Icmp(
"gravity" ) ) {
400 if ( !token.
Icmp(
"world" ) ) {
409 src.
Error(
"unknown token %s\n", token.
c_str() );
438 if ( !token.
Icmp(
"}" ) ) {
442 if ( !token.
Icmp(
"{" ) ) {
445 src.
Warning(
"Particle stage parse failed" );
453 if ( !token.
Icmp(
"depthHack" ) ) {
497 "\t\t" "material\t_default\n"
499 "\t\t" "time\t\t1.0\n"
516 if ( parm->
from == parm->
to ) {
623 "\tGenerated by the Particle Editor.\n"
624 "\tTo use the particle editor, launch the game and type 'editParticles' on the console.\n"
668 return table->TableLookup( frac );
675 common->
Printf(
"idParticleParm::Integrate: can't integrate tables\n" );
678 return (
from + frac * (
to -
from ) * 0.5
f ) * frac;
820 count *= ( 1 + trails );
841 float radiusSqr, angle1, angle2;
858 radiusSqr = origin[0] * origin[0] + origin[1] * origin[1];
861 float f = sqrt( radiusSqr ) / distributionParms[3];
862 float invf = 1.0f /
f;
863 float newRadius = distributionParms[3] + f * ( 1.0f - distributionParms[3] );
864 float rescale = invf * newRadius;
866 origin[0] *= rescale;
867 origin[1] *= rescale;
882 radiusSqr = origin[0] * origin[0] + origin[1] * origin[1] + origin[2] * origin[2];
883 }
while( radiusSqr > 1.0
f );
885 origin.
Set( 1.0
f, 1.0
f, 1.0
f );
894 float f = sqrt( radiusSqr ) / distributionParms[3];
895 float invf = 1.0f /
f;
896 float newRadius = distributionParms[3] + f * ( 1.0f - distributionParms[3] );
897 float rescale = invf * newRadius;
899 origin[0] *= rescale;
900 origin[1] *= rescale;
901 origin[2] *= rescale;
926 float s1, c1, s2, c2;
952 float angle1, angle2, speed1, speed2;
963 origin[1] = s1 * customPathParms[1];
964 origin[2] = g->
random.
RandomFloat() * customPathParms[2] + customPathParms[4] * speed2 * g->
age;
973 float s1, c1, s2, c2;
990 origin[1] = s1 * customPathParms[0];
1001 common->
Error(
"idParticleStage::ParticleOrigin: bad customPathType" );
1016 origin += gra * g->
age * g->
age;
1031 float width = psize;
1032 float height = psize * paspect;
1039 float currentAge = g->
age;
1040 float currentFrac = g->
frac;
1042 idVec3 stepOrigin = origin;
1047 if ( trailTime == 0 ) {
1051 float height = 1.0f / ( 1 + numTrails );
1054 for (
int i = 0 ;
i <= numTrails ;
i++ ) {
1056 g->
age = currentAge - (
i + 1 ) * trailTime / ( numTrails + 1 );
1062 up = stepOrigin - oldOrigin;
1067 up -= ( up * forwardDir ) * forwardDir;
1072 left = up.
Cross( forwardDir );
1075 verts_p[0] = verts[0];
1076 verts_p[1] = verts[1];
1077 verts_p[2] = verts[2];
1078 verts_p[3] = verts[3];
1081 verts_p[0].
xyz = stepOrigin - left;
1082 verts_p[1].
xyz = stepOrigin + left;
1084 verts_p[0].
xyz = stepOrigin - stepLeft;
1085 verts_p[1].
xyz = stepOrigin + stepLeft;
1087 verts_p[2].
xyz = oldOrigin - left;
1088 verts_p[3].
xyz = oldOrigin + left;
1091 verts_p[0].
st[0] = verts[0].
st[0];
1092 verts_p[0].
st[1] =
t;
1094 verts_p[1].
st[0] = verts[1].
st[0];
1095 verts_p[1].
st[1] =
t;
1097 verts_p[2].
st[0] = verts[2].
st[0];
1100 verts_p[3].
st[0] = verts[3].
st[0];
1107 stepOrigin = oldOrigin;
1111 g->
random = currentRandom;
1112 g->
age = currentAge;
1113 g->
frac = currentFrac;
1115 return 4 * (numTrails+1);
1127 if ( g->
index & 1 ) {
1163 idVec3 entityLeft, entityUp;
1168 left = entityLeft * c + entityUp *
s;
1169 up = entityUp * c - entityLeft *
s;
1175 verts[0].
xyz = origin - left + up;
1176 verts[1].
xyz = origin + left + up;
1177 verts[2].
xyz = origin - left - up;
1178 verts[3].
xyz = origin + left - up;
1202 int intFrame = (
int)floatFrame;
1204 s = width * intFrame;
1232 float fadeFraction = 1.0f;
1251 for (
int i = 0 ;
i < 4 ;
i++ ) {
1256 }
else if ( icolor > 255 ) {
1262 verts[3].
color[
i] = icolor;
1291 if ( verts[0].
color[0] == 0 && verts[0].
color[1] == 0 && verts[0].
color[2] == 0 && verts[0].
color[3] == 0 ) {
1308 float iFrac = 1.0f - frac;
1309 for (
int i = 0 ;
i < numVerts ;
i++ ) {
1310 verts[numVerts +
i] = verts[
i];
1312 verts[numVerts +
i].
st[0] +=
width;
1314 verts[numVerts +
i].
color[0] *= frac;
1315 verts[numVerts +
i].
color[1] *= frac;
1316 verts[numVerts +
i].
color[2] *= frac;
1317 verts[numVerts +
i].
color[3] *= frac;
1319 verts[
i].
color[0] *= iFrac;
1320 verts[
i].
color[1] *= iFrac;
1321 verts[
i].
color[2] *= iFrac;
1322 verts[
i].
color[3] *= iFrac;
1325 return numVerts * 2;
int GetLineNum(void) const
float Eval(float frac, idRandom &rand) const
idParticleStage * ParseParticleStage(idLexer &src)
bool AddBounds(const idBounds &a)
float Integrate(float frac, idRandom &rand) const
void ParseParametric(idLexer &src, idParticleParm *parm)
bool ReplaceSourceFileText(void)
idMat3 mat3_identity(idVec3(1, 0, 0), idVec3(0, 1, 0), idVec3(0, 0, 1))
void void bool HadError(void) const
const char * GetFileName(void) const
const int DECL_LEXER_FLAGS
const int CustomParticleCount
idStr & StripQuotes(void)
idMat3 Transpose(void) const
void Set(const float x, const float y, const float z)
GLenum GLsizei GLenum GLenum const GLvoid * table
static float ClampFloat(float min, float max, float value)
const char * GetName(void) const
virtual idDecl * CreateNewDecl(declType_t type, const char *name, const char *fileName)=0
const renderEntity_t * renderEnt
virtual size_t Size(void) const
bool Save(const char *fileName=NULL)
static const float M_DEG2RAD
virtual const idMaterial * FindMaterial(const char *name, bool makeDefault=true)=0
float GetVolume(void) const
float ParseFloat(bool *errorFlag=NULL)
idVec3 Cross(const idVec3 &a) const
virtual bool Parse(const char *text, const int textLength)
int ReadTokenOnLine(idToken *token)
void ParticleOrigin(particleGen_t *g, idVec3 &origin) const
int Icmp(const char *text) const
static float Cos16(float a)
void GetStageBounds(idParticleStage *stage)
idParticleParm rotationSpeed
static float Sin16(float a)
void ParticleColors(particleGen_t *g, idDrawVert *verts) const
const ParticleParmDesc ParticleDistributionDesc[]
bool AddPoint(const idVec3 &v)
void Error(const char *str,...) id_attribute((format(printf
GLuint GLuint GLsizei count
void ParticleTexCoords(particleGen_t *g, idDrawVert *verts) const
void SetCustomPathType(const char *p)
static int FtoiFast(float f)
idVec3 vec3_origin(0.0f, 0.0f, 0.0f)
const char * GetDataPtr(void) const
virtual int CreateParticle(particleGen_t *g, idDrawVert *verts) const
virtual const idDecl * FindType(declType_t type, const char *name, bool makeDefault=true)=0
const renderView_t * renderView
prtDirection_t directionType
prtDistribution_t distributionType
const char * GetCustomPathName()
const idMaterial * material
void DeleteContents(bool clear)
void operator=(const idParticleStage &src)
virtual int WriteFloatString(const char *fmt,...) id_attribute((format(printf
void UnreadToken(const idToken *token)
virtual void Printf(const char *fmt,...) id_attribute((format(printf
float orientationParms[4]
idList< idParticleStage * > stages
static void SinCos16(float a, float &s, float &c)
int LoadMemory(const char *ptr, int length, const char *name, int startLine=1)
idBounds Expand(const float d) const
const char * GetCustomPathDesc()
GLenum GLsizei GLsizei height
prtCustomPth_t customPathType
void SetText(const char *text)
void ProjectVector(const idVec3 &src, idVec3 &dst) const
idDeclManager * declManager
static const float TWO_PI
bool IsNumeric(void) const
int ParticleVerts(particleGen_t *g, const idVec3 origin, idDrawVert *verts) const
int Append(const type &obj)
void void Warning(const char *str,...) id_attribute((format(printf
void ProjectSelfOntoSphere(const float radius)
void ParseParms(idLexer &src, float *parms, int maxParms)
virtual void FreeData(void)
const idDeclTable * table
virtual const char * DefaultDefinition(void) const
float distributionParms[4]
void WriteStage(idFile *f, idParticleStage *stage)
const char * c_str(void) const
int SkipUntilString(const char *string)
idBounds & ExpandSelf(const float d)
prtOrientation_t orientation
virtual void Error(const char *fmt,...) id_attribute((format(printf
bool RebuildTextSource(void)
const ParticleParmDesc ParticleCustomDesc[]
float shaderParms[MAX_ENTITY_SHADER_PARMS]
const ParticleParmDesc ParticleOrientationDesc[]
int ReadToken(idToken *token)
const ParticleParmDesc ParticleDirectionDesc[]
void WriteParticleParm(idFile *f, idParticleParm *parm, const char *name)
virtual int NumQuadsPerParticle() const