gremlin/libs/spark/src/Core/SPK_Model.cpp
2011-01-05 23:02:10 +01:00

300 lines
8.4 KiB
C++

//////////////////////////////////////////////////////////////////////////////////
// SPARK particle engine //
// Copyright (C) 2008-2009 - Julien Fryer - julienfryer@gmail.com //
// //
// This software is provided 'as-is', without any express or implied //
// warranty. In no event will the authors be held liable for any damages //
// arising from the use of this software. //
// //
// Permission is granted to anyone to use this software for any purpose, //
// including commercial applications, and to alter it and redistribute it //
// freely, subject to the following restrictions: //
// //
// 1. The origin of this software must not be misrepresented; you must not //
// claim that you wrote the original software. If you use this software //
// in a product, an acknowledgment in the product documentation would be //
// appreciated but is not required. //
// 2. Altered source versions must be plainly marked as such, and must not be //
// misrepresented as being the original software. //
// 3. This notice may not be removed or altered from any source distribution. //
//////////////////////////////////////////////////////////////////////////////////
#include "Core/SPK_Model.h"
#include "Core/SPK_Interpolator.h"
namespace SPK
{
const float Model::DEFAULT_VALUES[NB_PARAMS] =
{
1.0f, // RED
1.0f, // GREEN
1.0f, // BLUE
1.0f, // ALPHA
1.0f, // SIZE
1.0f, // MASS
0.0f, // ANGLE
0.0f, // TEXTURE_INDEX
0.0f, // ROTATION_SPEED
0.0f, // CUSTOM_0
0.0f, // CUSTOM_1
0.0f, // CUSTOM_2
};
Model::Model(int enableFlag,int mutableFlag,int randomFlag,int interpolatedFlag) :
Registerable(),
lifeTimeMin(1.0f),
lifeTimeMax(1.0f),
immortal(false),
paramsSize(0),
nbEnableParams(0),
nbMutableParams(0),
nbRandomParams(0),
nbInterpolatedParams(0)
{
enableFlag |= FLAG_RED | FLAG_GREEN | FLAG_BLUE; // Adds the color parameters to the enable flag
this->enableFlag = enableFlag & ((1 << (NB_PARAMS + 1)) - 1); // masks the enable flag with the existing parameters
this->interpolatedFlag = interpolatedFlag & this->enableFlag; // masks the interpolated flag with the enable flag
this->mutableFlag = mutableFlag & this->enableFlag; // masks the mutable flag with the enable flag
this->mutableFlag &= ~this->interpolatedFlag; // a param cannot be both interpolated and mutable
this->randomFlag = randomFlag & this->enableFlag; // masks the random flag with the enable flag
this->randomFlag &= ~this->interpolatedFlag; // a param cannot be both interpolated and random
int particleEnableParamsSize = 0;
int particleMutableParamsSize = 0;
for (size_t i = 0; i < NB_PARAMS; ++i)
{
ModelParam param = static_cast<ModelParam>(i);
int paramSize = 0;
if (isEnabled(param))
{
++nbEnableParams;
if (!isInterpolated(param))
{
interpolators[i] = NULL;
paramSize = 1;
if (isMutable(param))
{
paramSize = 2;
++nbMutableParams;
}
if (isRandom(param))
{
paramSize <<= 1;
++nbRandomParams;
}
}
else
{
interpolators[i] = new Interpolator(); // Creates the interpolator
++nbInterpolatedParams;
}
}
else
interpolators[i] = NULL;
particleEnableIndices[i] = particleEnableParamsSize;
particleMutableIndices[i] = particleMutableParamsSize;
particleEnableParamsSize += isEnabled(param) >> i;
particleMutableParamsSize += isMutable(param) >> i;
indices[i] = paramsSize;
paramsSize += paramSize;
}
// creates the array of params for this model
if (paramsSize > 0)
{
params = new float[paramsSize];
unsigned int currentParamIndex = 0;
unsigned int currentIndex = 0;
while (currentIndex < paramsSize)
{
unsigned int nbValues = getNbValues(static_cast<ModelParam>(currentParamIndex));
for (size_t i = 0; i < nbValues; ++i)
params[currentIndex + i] = DEFAULT_VALUES[currentParamIndex];
++currentParamIndex;
currentIndex += nbValues;
}
}
else
params = NULL;
if (nbEnableParams > 0)
{
enableParams = new int[nbEnableParams];
size_t index = 0;
for (size_t i = 0; i < NB_PARAMS; ++i)
if (isEnabled(static_cast<ModelParam>(i)))
enableParams[index++] = i;
}
else
enableParams = NULL;
if (nbMutableParams > 0)
{
mutableParams = new int[nbMutableParams];
size_t index = 0;
for (size_t i = 0; i < NB_PARAMS; ++i)
if (isMutable(static_cast<ModelParam>(i)))
mutableParams[index++] = i;
}
else
mutableParams = NULL;
if (nbInterpolatedParams > 0)
{
interpolatedParams = new int[nbInterpolatedParams];
size_t index = 0;
for (size_t i = 0; i < NB_PARAMS; ++i)
if (isInterpolated(static_cast<ModelParam>(i)))
interpolatedParams[index++] = i;
}
else
interpolatedParams = NULL;
}
Model::Model(const Model& model) :
Registerable(model),
lifeTimeMin(model.lifeTimeMin),
lifeTimeMax(model.lifeTimeMax),
immortal(model.immortal),
paramsSize(model.paramsSize),
nbEnableParams(model.nbEnableParams),
nbMutableParams(model.nbMutableParams),
nbRandomParams(model.nbRandomParams),
nbInterpolatedParams(model.nbInterpolatedParams),
enableFlag(model.enableFlag),
mutableFlag(model.mutableFlag),
randomFlag(model.randomFlag),
interpolatedFlag(model.interpolatedFlag),
params(NULL),
enableParams(NULL),
mutableParams(NULL),
interpolatedParams(NULL)
{
if (paramsSize > 0)
{
params = new float[paramsSize];
for (size_t i = 0; i < paramsSize; ++i)
params[i] = model.params[i];
}
if (nbEnableParams > 0)
{
enableParams = new int[nbEnableParams];
for (size_t i = 0; i < nbEnableParams; ++i)
enableParams[i] = model.enableParams[i];
}
if (nbMutableParams > 0)
{
mutableParams = new int[nbMutableParams];
for (size_t i = 0; i < nbMutableParams; ++i)
mutableParams[i] = model.mutableParams[i];
}
if (nbInterpolatedParams > 0)
{
interpolatedParams = new int[nbMutableParams];
for (size_t i = 0; i < nbInterpolatedParams; ++i)
interpolatedParams[i] = model.interpolatedParams[i];
}
for (size_t i = 0; i < NB_PARAMS; ++i)
{
indices[i] = model.indices[i];
particleEnableIndices[i] = model.particleEnableIndices[i];
particleMutableIndices[i] = model.particleMutableIndices[i];
if (model.interpolators[i] != NULL)
interpolators[i] = new Interpolator(*model.interpolators[i]);
else
interpolators[i] = NULL;
}
}
Model::~Model()
{
delete[] enableParams;
delete[] mutableParams;
delete[] interpolatedParams;
delete[] params;
for (size_t i = 0; i < NB_PARAMS; ++i)
delete interpolators[i];
}
bool Model::setParam(ModelParam type,float startMin,float startMax,float endMin,float endMax)
{
// if the given param doesnt have 4 values, return
if (getNbValues(type) != 4)
return false;
// Sets the values at the right position in params
float* ptr = params + indices[type];
*ptr++ = startMin;
*ptr++ = startMax;
*ptr++ = endMin;
*ptr = endMax;
return true;
}
bool Model::setParam(ModelParam type,float value0,float value1)
{
// if the given param doesnt have 2 values, return
if (getNbValues(type) != 2)
return false;
// Sets the values at the right position in params
float* ptr = params + indices[type];
*ptr++ = value0;
*ptr = value1;
return true;
}
bool Model::setParam(ModelParam type,float value)
{
// if the given param doesnt have 1 value, return
if (getNbValues(type) != 1)
return false;
// Sets the value at the right position in params
params[indices[type]] = value;
return true;
}
float Model::getParamValue(ModelParam type,size_t index) const
{
unsigned int nbValues = getNbValues(type);
if (index < nbValues)
return params[indices[type] + index];
return DEFAULT_VALUES[type];
}
unsigned int Model::getNbValues(ModelParam type) const
{
int value = 1 << type;
if (!(enableFlag & value) || (interpolatedFlag & value))
return 0;
if (!(mutableFlag & value) && !(randomFlag & value))
return 1;
if ((mutableFlag & value) && (randomFlag & value))
return 4;
return 2;
}
float Model::getDefaultValue(ModelParam param)
{
return DEFAULT_VALUES[param];
}
}