Skip to content

Instantly share code, notes, and snippets.

@lukaspj
Created July 12, 2015 15:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lukaspj/6d8168caf12fc13e7fac to your computer and use it in GitHub Desktop.
Save lukaspj/6d8168caf12fc13e7fac to your computer and use it in GitHub Desktop.
ColorF BillboardRenderer::getParticleColor(Particle const* part)
{
PROFILE_SCOPE(getParticleColor);
AssertFatal(part->totalLifetime > 0, "Particle lifetime must be larger than 0.");
F32 t = F32(part->currentAge) / F32(part->totalLifetime);
AssertFatal(t <= 1.0f, "Out out bounds filter function for particle.");
PROFILE_START(getParticleColor_OUTER);
for (U32 i = 1; i < ParticleSystem::PDC_NUM_KEYS; i++)
{
PROFILE_START(getParticleColor_INNER);
if (getDataBlock()->getTime(i) >= t)
{
F32 firstPart = t - getDataBlock()->getTime(i - 1);
F32 total = getDataBlock()->getTime(i) -
getDataBlock()->getTime(i - 1);
firstPart /= total;
ColorF outCol;
PROFILE_START(getParticleColor_INTERPOLATE);
outCol.interpolate(getDataBlock()->getColor(i - 1), getDataBlock()->getColor(i), firstPart);
PROFILE_END();
PROFILE_END();
PROFILE_END();
return outCol;
}
PROFILE_END();
}
PROFILE_END();
return getDataBlock()->getColor(ParticleSystem::PDC_NUM_KEYS - 1);
}
//-----------------------------------------------------------------------------
// Set up particle for billboard style render
//-----------------------------------------------------------------------------
void BillboardRenderer::setupBillboard(Particle *part,
Point3F *basePts,
const MatrixF &camView,
const ColorF &ambientColor,
ParticleVertexType *lVerts)
{
PROFILE_SCOPE(setupBillboard);
F32 width = getParticleSize(part) * 0.5f;
F32 spinAngle = part->spinSpeed * part->currentAge * ParticleSystem::AgedSpinToRadians;
F32 sy, cy;
mSinCos(spinAngle, sy, cy);
PROFILE_START(setupBillboardLerp);
const F32 ambientLerp = mClampF(getDataBlock()->getAmbientFactor(), 0.0f, 1.0f);
ColorF partCol = mLerp(getParticleColor(part), (getParticleColor(part) * ambientColor), ambientLerp);
PROFILE_END();
// fill four verts, use macro and unroll loop
#define fillVert(){ \
lVerts->point.x = cy * basePts->x - sy * basePts->z; \
lVerts->point.y = 0.0f; \
lVerts->point.z = sy * basePts->x + cy * basePts->z; \
camView.mulV( lVerts->point ); \
lVerts->point *= width; \
lVerts->point += part->pos; \
lVerts->color = partCol; } \
// Here we deal with UVs for animated particle (billboard)
if (getDataBlock()->getAnimateTexture())
{
S32 fm = (S32)(part->currentAge*(1.0 / 1000.0)*getDataBlock()->getFramesPerSec());
U8 fm_tile = getDataBlock()->getAnimTexFrames()[fm % getDataBlock()->getNumFrames()];
S32 uv[4];
uv[0] = fm_tile + fm_tile / getDataBlock()->getAnimTexTiling().x;
uv[1] = uv[0] + (getDataBlock()->getAnimTexTiling().x + 1);
uv[2] = uv[1] + 1;
uv[3] = uv[0] + 1;
fillVert();
// Here and below, we copy UVs from particle datablock's current frame's UVs (billboard)
lVerts->texCoord = getDataBlock()->getAnimTexUVs()[uv[0]];
++lVerts;
++basePts;
fillVert();
lVerts->texCoord = getDataBlock()->getAnimTexUVs()[uv[1]];
++lVerts;
++basePts;
fillVert();
lVerts->texCoord = getDataBlock()->getAnimTexUVs()[uv[2]];
++lVerts;
++basePts;
fillVert();
lVerts->texCoord = getDataBlock()->getAnimTexUVs()[uv[3]];
++lVerts;
++basePts;
return;
}
fillVert();
// Here and below, we copy UVs from particle datablock's texCoords (billboard)
lVerts->texCoord = getDataBlock()->getTexCoords(0);
++lVerts;
++basePts;
fillVert();
lVerts->texCoord = getDataBlock()->getTexCoords(1);
++lVerts;
++basePts;
fillVert();
lVerts->texCoord = getDataBlock()->getTexCoords(2);
++lVerts;
++basePts;
fillVert();
lVerts->texCoord = getDataBlock()->getTexCoords(3);
++lVerts;
++basePts;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment