|
@@ -24,6 +24,7 @@
|
|
|
// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
|
|
|
// Copyright (C) 2015 Faust Logic, Inc.
|
|
|
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|
|
|
+
|
|
|
#include "particle.h"
|
|
|
#include "console/consoleTypes.h"
|
|
|
#include "console/typeValidators.h"
|
|
@@ -77,6 +78,8 @@ static const F32 sgDefaultSpinSpeed = 1.f;
|
|
|
static const F32 sgDefaultSpinRandomMin = 0.f;
|
|
|
static const F32 sgDefaultSpinRandomMax = 0.f;
|
|
|
|
|
|
+static const F32 sgDefaultSpinBias = 1.0f;
|
|
|
+static const F32 sgDefaultSizeBias = 1.0f;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
// Constructor
|
|
@@ -107,9 +110,9 @@ ParticleData::ParticleData()
|
|
|
}
|
|
|
|
|
|
times[0] = 0.0f;
|
|
|
- times[1] = 0.33f;
|
|
|
- times[2] = 0.66f;
|
|
|
- times[3] = 1.0f;
|
|
|
+ times[1] = 1.0f;
|
|
|
+ for (i = 2; i < PDC_NUM_KEYS; i++)
|
|
|
+ times[i] = -1.0f;
|
|
|
|
|
|
texCoords[0].set(0.0,0.0); // texture coords at 4 corners
|
|
|
texCoords[1].set(0.0,1.0); // of particle quad
|
|
@@ -120,18 +123,20 @@ ParticleData::ParticleData()
|
|
|
animTexUVs = NULL; // array of tile vertex UVs
|
|
|
textureName = NULL; // texture filename
|
|
|
textureHandle = NULL; // loaded texture handle
|
|
|
+ textureExtName = NULL;
|
|
|
+ textureExtHandle = NULL;
|
|
|
+ constrain_pos = false;
|
|
|
+ start_angle = 0.0f;
|
|
|
+ angle_variance = 0.0f;
|
|
|
+ sizeBias = sgDefaultSizeBias;
|
|
|
+ spinBias = sgDefaultSpinBias;
|
|
|
+ randomizeSpinDir = false;
|
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
// Destructor
|
|
|
//-----------------------------------------------------------------------------
|
|
|
-ParticleData::~ParticleData()
|
|
|
-{
|
|
|
- if (animTexUVs)
|
|
|
- {
|
|
|
- delete [] animTexUVs;
|
|
|
- }
|
|
|
-}
|
|
|
+
|
|
|
|
|
|
FRangeValidator dragCoefFValidator(0.f, 5.f);
|
|
|
FRangeValidator gravCoefFValidator(-10.f, 10.f);
|
|
@@ -219,6 +224,15 @@ void ParticleData::initPersistFields()
|
|
|
"@brief Time keys used with the colors and sizes keyframes.\n\n"
|
|
|
"Values are from 0.0 (particle creation) to 1.0 (end of lifespace)." );
|
|
|
|
|
|
+ addGroup("AFX");
|
|
|
+ addField("textureExtName", TypeFilename, Offset(textureExtName, ParticleData));
|
|
|
+ addField("constrainPos", TypeBool, Offset(constrain_pos, ParticleData));
|
|
|
+ addField("angle", TypeF32, Offset(start_angle, ParticleData));
|
|
|
+ addField("angleVariance", TypeF32, Offset(angle_variance, ParticleData));
|
|
|
+ addField("sizeBias", TypeF32, Offset(sizeBias, ParticleData));
|
|
|
+ addField("spinBias", TypeF32, Offset(spinBias, ParticleData));
|
|
|
+ addField("randomizeSpinDir", TypeBool, Offset(randomizeSpinDir, ParticleData));
|
|
|
+ endGroup("AFX");
|
|
|
Parent::initPersistFields();
|
|
|
}
|
|
|
|
|
@@ -248,18 +262,22 @@ void ParticleData::packData(BitStream* stream)
|
|
|
stream->writeInt((S32)(spinRandomMin + 1000), 11);
|
|
|
stream->writeInt((S32)(spinRandomMax + 1000), 11);
|
|
|
}
|
|
|
+ if(stream->writeFlag(spinBias != sgDefaultSpinBias))
|
|
|
+ stream->write(spinBias);
|
|
|
+ stream->writeFlag(randomizeSpinDir);
|
|
|
stream->writeFlag(useInvAlpha);
|
|
|
|
|
|
S32 i, count;
|
|
|
|
|
|
// see how many frames there are:
|
|
|
- for(count = 0; count < 3; count++)
|
|
|
+ for(count = 0; count < ParticleData::PDC_NUM_KEYS-1; count++)
|
|
|
if(times[count] >= 1)
|
|
|
break;
|
|
|
|
|
|
count++;
|
|
|
|
|
|
- stream->writeInt(count-1, 2);
|
|
|
+ // An extra bit is needed for 8 keys.
|
|
|
+ stream->writeInt(count-1, 3);
|
|
|
|
|
|
for( i=0; i<count; i++ )
|
|
|
{
|
|
@@ -267,7 +285,8 @@ void ParticleData::packData(BitStream* stream)
|
|
|
stream->writeFloat( colors[i].green, 7);
|
|
|
stream->writeFloat( colors[i].blue, 7);
|
|
|
stream->writeFloat( colors[i].alpha, 7);
|
|
|
- stream->writeFloat( sizes[i]/MaxParticleSize, 14);
|
|
|
+ // AFX bits raised from 14 to 16 to allow larger sizes
|
|
|
+ stream->writeFloat( sizes[i]/MaxParticleSize, 16);
|
|
|
stream->writeFloat( times[i], 8);
|
|
|
}
|
|
|
|
|
@@ -284,6 +303,13 @@ void ParticleData::packData(BitStream* stream)
|
|
|
mathWrite(*stream, animTexTiling);
|
|
|
stream->writeInt(framesPerSec, 8);
|
|
|
}
|
|
|
+ if (stream->writeFlag(textureExtName && textureExtName[0]))
|
|
|
+ stream->writeString(textureExtName);
|
|
|
+ stream->writeFlag(constrain_pos);
|
|
|
+ stream->writeFloat(start_angle/360.0f, 11);
|
|
|
+ stream->writeFloat(angle_variance/180.0f, 10);
|
|
|
+ if(stream->writeFlag(sizeBias != sgDefaultSizeBias))
|
|
|
+ stream->write(sizeBias);
|
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
@@ -327,17 +353,24 @@ void ParticleData::unpackData(BitStream* stream)
|
|
|
spinRandomMax = sgDefaultSpinRandomMax;
|
|
|
}
|
|
|
|
|
|
+ if(stream->readFlag())
|
|
|
+ stream->read(&spinBias);
|
|
|
+ else
|
|
|
+ spinBias = sgDefaultSpinBias;
|
|
|
+ randomizeSpinDir = stream->readFlag();
|
|
|
useInvAlpha = stream->readFlag();
|
|
|
|
|
|
S32 i;
|
|
|
- S32 count = stream->readInt(2) + 1;
|
|
|
+ // An extra bit is needed for 8 keys.
|
|
|
+ S32 count = stream->readInt(3) + 1;
|
|
|
for(i = 0;i < count; i++)
|
|
|
{
|
|
|
colors[i].red = stream->readFloat(7);
|
|
|
colors[i].green = stream->readFloat(7);
|
|
|
colors[i].blue = stream->readFloat(7);
|
|
|
colors[i].alpha = stream->readFloat(7);
|
|
|
- sizes[i] = stream->readFloat(14) * MaxParticleSize;
|
|
|
+ // AFX bits raised from 14 to 16 to allow larger sizes
|
|
|
+ sizes[i] = stream->readFloat(16) * MaxParticleSize;
|
|
|
times[i] = stream->readFloat(8);
|
|
|
}
|
|
|
textureName = (stream->readFlag()) ? stream->readSTString() : 0;
|
|
@@ -351,6 +384,14 @@ void ParticleData::unpackData(BitStream* stream)
|
|
|
mathRead(*stream, &animTexTiling);
|
|
|
framesPerSec = stream->readInt(8);
|
|
|
}
|
|
|
+ textureExtName = (stream->readFlag()) ? stream->readSTString() : 0;
|
|
|
+ constrain_pos = stream->readFlag();
|
|
|
+ start_angle = 360.0f*stream->readFloat(11);
|
|
|
+ angle_variance = 180.0f*stream->readFloat(10);
|
|
|
+ if(stream->readFlag())
|
|
|
+ stream->read(&sizeBias);
|
|
|
+ else
|
|
|
+ sizeBias = sgDefaultSizeBias;
|
|
|
}
|
|
|
|
|
|
bool ParticleData::protectedSetSizes( void *object, const char *index, const char *data)
|
|
@@ -432,11 +473,33 @@ bool ParticleData::onAdd()
|
|
|
}
|
|
|
|
|
|
times[0] = 0.0f;
|
|
|
- for (U32 i = 1; i < 4; i++) {
|
|
|
- if (times[i] < times[i-1]) {
|
|
|
- Con::warnf(ConsoleLogEntry::General, "ParticleData(%s) times[%d] < times[%d]", getName(), i, i-1);
|
|
|
- times[i] = times[i-1];
|
|
|
- }
|
|
|
+ for (U32 i = 1; i < PDC_NUM_KEYS; i++)
|
|
|
+ {
|
|
|
+ if (times[i] < 0.0f)
|
|
|
+ break;
|
|
|
+ if (times[i] < times[i-1])
|
|
|
+ {
|
|
|
+ Con::warnf(ConsoleLogEntry::General, "ParticleData(%s) times[%d] < times[%d]", getName(), i, i-1);
|
|
|
+ times[i] = times[i-1];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ times[0] = 0.0f;
|
|
|
+
|
|
|
+ U32 last_idx = 0;
|
|
|
+ for (U32 i = 1; i < PDC_NUM_KEYS; i++)
|
|
|
+ {
|
|
|
+ if (times[i] < 0.0f)
|
|
|
+ break;
|
|
|
+ else
|
|
|
+ last_idx = i;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (U32 i = last_idx+1; i < PDC_NUM_KEYS; i++)
|
|
|
+ {
|
|
|
+ times[i] = times[last_idx];
|
|
|
+ colors[i] = colors[last_idx];
|
|
|
+ sizes[i] = sizes[last_idx];
|
|
|
}
|
|
|
|
|
|
// Here we validate parameters
|
|
@@ -475,6 +538,10 @@ bool ParticleData::onAdd()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ start_angle = mFmod(start_angle, 360.0f);
|
|
|
+ if (start_angle < 0.0f)
|
|
|
+ start_angle += 360.0f;
|
|
|
+ angle_variance = mClampF(angle_variance, -180.0f, 180.0f);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -500,6 +567,15 @@ bool ParticleData::preload(bool server, String &errorStr)
|
|
|
error = true;
|
|
|
}
|
|
|
}
|
|
|
+ if (textureExtName && textureExtName[0])
|
|
|
+ {
|
|
|
+ textureExtHandle = GFXTexHandle(textureExtName, &GFXStaticTextureSRGBProfile, avar("%s() - textureExtHandle (line %d)", __FUNCTION__, __LINE__));
|
|
|
+ if (!textureExtHandle)
|
|
|
+ {
|
|
|
+ errorStr = String::ToString("Missing particle texture: %s", textureName);
|
|
|
+ error = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
if (animateTexture)
|
|
|
{
|
|
@@ -611,6 +687,11 @@ void ParticleData::initializeParticle(Particle* init, const Point3F& inheritVelo
|
|
|
|
|
|
// assign spin amount
|
|
|
init->spinSpeed = spinSpeed * gRandGen.randF( spinRandomMin, spinRandomMax );
|
|
|
+ // apply spin bias
|
|
|
+ init->spinSpeed *= spinBias;
|
|
|
+ // randomize spin direction
|
|
|
+ if (randomizeSpinDir && (gRandGen.randI( 0, 1 ) == 1))
|
|
|
+ init->spinSpeed = -init->spinSpeed;
|
|
|
}
|
|
|
|
|
|
bool ParticleData::reload(char errorBuffer[256])
|