XFuParticleSystem.cpp Source File

Main Page Class Hierarchy Alphabetical List Compound List File List Compound Members File Members Related Pages

# XFuParticleSystem.cpp

Go to the documentation of this file.

    00001 /*! \file
    00002  * X-Forge Util <br>
    00003  * Copyright 2000-2003 Fathammer Ltd
    00004  *
    00005  * \brief Particle system utility
    00006  *
    00007  * $Id: XFuParticleSystem.cpp,v 1.15.2.1 2003/12/02 14:34:18 mikko Exp $
    00008  * $Date: 2003/12/02 14:34:18 $
    00009  * $Revision: 1.15.2.1 $
    00010  */
    00011 #include <xfcore/XFcCore.h>
    00012 #include <xfcore/XFcGLTextureFromFile.h>
    00013 #include <xfutil/XFuParticleSystem.h>
    00014
    00015 //
    00016 // somewhat long-term TODO:
    00017 // - Get rid of fixed point dependency (compile time or otherwise)
    00018 // - multiple particle system support
    00019 // - lots of other fixes and additions
    00020
    00021 #ifndef PI
    00022 #define PI 3.1415926535897932384626433832795f
    00023 #endif
    00024 #define PS_VERSIONTAG 0x03005350
    00025
    00026 void XFuParticleSystem::PSSeed(INT32 v)
    00027 {
    00028     INT32 s = v & 31;
    00029     INT32 t = v ^ 0x14951C57;
    00030     mRandSeed2 = (t >> s) + (t << (32 - s));
    00031     s = (v >> 5) & 31;
    00032     t = v ^ 0x6C691B25;
    00033     mRandSeed1 = (t >> s) + (t << (32 - s));
    00034 }
    00035
    00036
    00037 // Sol's rol'n'xor noise function
    00038 INT32 XFuParticleSystem::PSRand()
    00039 {
    00040     INT32 v = mRandSeed1;
    00041     mRandSeed1 = ((v >> 13) + (v << (32 - 13)));
    00042     v = mRandSeed2 ^ 0x51549515;
    00043     mRandSeed2 = mRandSeed1 ^ mRandSeed2;
    00044     mRandSeed1 = v;
    00045     return mRandSeed1;
    00046 }
    00047
    00048
    00049 INT32 XFuParticleSystem::PSRandInPlace(INT32 aSeed)
    00050 {
    00051     INT32 randseed1, randseed2;
    00052     INT32 s = aSeed & 31;
    00053     INT32 t = aSeed ^ 0x14951C57;
    00054     randseed2 = (t >> s) + (t << (32 - s));
    00055     s = (aSeed >> 5) & 31;
    00056     t = aSeed ^ 0x6C691B25;
    00057     aSeed = (t >> s) + (t << (32 - s));
    00058     randseed1 = ((aSeed >> 13) + (aSeed << (32 - 13)));
    00059     aSeed = randseed2 ^ 0x51549515;
    00060     randseed2 = randseed1 ^ randseed2;
    00061     randseed1 = aSeed;
    00062     return randseed1 & 0x7fff;
    00063 }
    00064
    00065
    00066 XFuParticleSystem::XFuParticleSystem()
    00067 {
    00068     mFrames = 0;
    00069     mFrame = NULL;
    00070     mParticle = NULL;
    00071     mTexture = NULL;
    00072     mCurrentTick = 0;
    00073     mViewScale = 1;
    00074     mSharedTextures = 0;
    00075     PSSeed(0xf00ba517);
    00076 }
    00077
    00078
    00079 void XFuParticleSystem::restart()
    00080 {
    00081     mStartTick = XFcCore::getTick(); // TODO: this should be replaced with a parameter
    00082     mLastTick = 0;
    00083     mActive = 0;
    00084     mPeakActive = 0;
    00085     mEmitQueue = 0;
    00086     mEmitted = 0;
    00087     INT32 i;
    00088     for (i = 0; i < mMaxVisible; i++)
    00089         mParticle[i].mAge = -1;
    00090     for (i = 0; i < mPreTick; i++)
    00091         tickOnce(REALi(1000) / mDesiredFPS);
    00092 }
    00093
    00094
    00095 void XFuParticleSystem::setMaxVisible(INT32 aValue)
    00096 {
    00097     if (mParticle != NULL)
    00098         delete[] mParticle;
    00099     mParticle = new struct Particle[aValue];
    00100     mMaxVisible = aValue;
    00101     restart();
    00102 }
    00103
    00104
    00105 XFuParticleSystem::~XFuParticleSystem()
    00106 {
    00107     if (mFrames > 0)
    00108     {
    00109         INT32 i;
    00110         for (i = 0; i < mFrames; i++)
    00111         {
    00112             if (!mSharedTextures)
    00113                 delete mFrame[i];
    00114             delete[] mTexture[i];
    00115         }
    00116         delete[] mFrame;
    00117         delete[] mTexture;
    00118     }
    00119     if (mParticle != NULL)
    00120         delete[] mParticle;
    00121 }
    00122
    00123
    00124 // TODO: get rid of fixed point dependency (at compile time, or always)
    00125 XFcFixed XFuNoiseController::noise(INT32 aTick, XFuParticleSystem *ps)
    00126 {
    00127     if (mType == 0) return 0; // no noise
    00128     XFcFixed t;// = REAL(tick);
    00129     t.setValue(aTick << (XFCFIXED_SHIFT - 10));
    00130
    00131     // If noise period is zero, consider it completely random:
    00132     if (mPeriod == 0)
    00133     {
    00134         XFcFixed r;
    00135         r.setValue(((ps->PSRand() & 8191) - 4096) << (XFCFIXED_SHIFT - 12));
    00136         return r * mValue;
    00137     }
    00138
    00139     t = t / mPeriod;
    00140     INT32 v;
    00141
    00142     switch (mType)
    00143     {
    00144     case 1: // sin
    00145         return XFcMath::sinFast((t * PI) * 2) * mValue;
    00146     case 2: // cos
    00147         return XFcMath::cosFast((t * PI) * 2) * mValue;
    00148     case 3: // triangle1
    00149         v = ((((t.getValue() >> (XFCFIXED_SHIFT - 12)) & 4095) - 2048) << 2);
    00150         if (v < 0) v = -v;
    00151         v -= 4096;
    00152         t.setValue(v);
    00153         return t * mValue;
    00154     case 4: // triangle2
    00155         v = (((((t.getValue() >> (XFCFIXED_SHIFT - 12)) + 1024) & 4095) - 2048) << 2);
    00156         if (v < 0) v = -v;
    00157         v -= 4096;
    00158         t.setValue(v);
    00159         return t * mValue;
    00160     case 5: // random
    00161         {
    00162             // please note that the PSRand() noise function has been
    00163             // tailored so that this would work:
    00164             int d = t.getValue() >> (XFCFIXED_SHIFT - 12);
    00165             int s = d >> 12;
    00166             d &= 4095;
    00167             int id = 4096 - d;
    00168             int r1 = ((ps->PSRandInPlace(s)) * id) >> 14; // 16384
    00169             int r2 = ((ps->PSRandInPlace(s+1)) * d) >> 14;
    00170             t.setValue((r1 + r2 - 4096) << (XFCFIXED_SHIFT - 12));
    00171             return t * mValue;
    00172         }
    00173     }
    00174     return 0;
    00175 }
    00176
    00177
    00178 void XFuParticleSystem::render(XFcGL * aGL)
    00179 {
    00180     INT32 cullmode, alphablend, srcblend, tgtblend, shademode, perspcorr;
    00181     // save current GL modes: (note: texture NOT saved)
    00182     aGL->getStateI(XFCGLRS_CULLING, cullmode);
    00183     aGL->getStateI(XFCGLRS_ALPHABLEND, alphablend);
    00184     aGL->getStateI(XFCGLRS_SRCBLEND, srcblend);
    00185     aGL->getStateI(XFCGLRS_TGTBLEND, tgtblend);
    00186     aGL->getStateI(XFCGLRS_SHADING, shademode);
    00187     aGL->getStateI(XFCGLRS_PERSPECTIVECORRECTION, perspcorr);
    00188     // and then set some:
    00189     XFcMatrix4 rot;
    00190     aGL->setStateI(XFCGLRS_CULLING, XFCGLCULL_NONE);
    00191     aGL->setStateI(XFCGLRS_ALPHABLEND, 1);
    00192     aGL->setStateI(XFCGLRS_SHADING, XFCGLSHADE_MATTE);
    00193     aGL->setStateI(XFCGLRS_PERSPECTIVECORRECTION, 0);
    00194
    00195     switch (mAlphaMode)
    00196     {
    00197     case 0: //none:
    00198         aGL->setStateI(XFCGLRS_SRCBLEND, XFCBLEND_ONE);
    00199         aGL->setStateI(XFCGLRS_TGTBLEND, XFCBLEND_ZERO);
    00200         aGL->setStateI(XFCGLRS_ALPHABLEND, 0);
    00201         break;
    00202     case 1: //add
    00203         aGL->setStateI(XFCGLRS_SRCBLEND, XFCBLEND_ONE);
    00204         aGL->setStateI(XFCGLRS_TGTBLEND, XFCBLEND_ONE);
    00205         break;
    00206     case 2: //alpha:
    00207         aGL->setStateI(XFCGLRS_SRCBLEND, XFCBLEND_SRCALPHA);
    00208         aGL->setStateI(XFCGLRS_TGTBLEND, XFCBLEND_INVSRCALPHA);
    00209         break;
    00210     case 3: //mul: Does not work (fillers not implemented)
    00211         aGL->setStateI(XFCGLRS_SRCBLEND, XFCBLEND_ZERO);
    00212         aGL->setStateI(XFCGLRS_TGTBLEND, XFCBLEND_SRCCOLOR);
    00213         break;
    00214     case 4: //invmul
    00215         aGL->setStateI(XFCGLRS_SRCBLEND, XFCBLEND_ZERO);
    00216         aGL->setStateI(XFCGLRS_TGTBLEND, XFCBLEND_INVSRCCOLOR);
    00217         break;
    00218     }
    00219
    00220     if (mFrames == 0)
    00221         aGL->setTexture(NULL);
    00222
    00223     INT32 i;
    00224     for (i = 0; i < mMaxVisible; i++)
    00225     {
    00226         if (mParticle[i].mAge !=  - 1)
    00227         {
    00228             XFcFixed deltaAge = mParticle[i].mAge / mParticle[i].mMaxAge;
    00229
    00230             if (mFrames != 0)
    00231             {
    00232                 // find current animation frame and select the texture:
    00233                 INT32 texture = deltaAge * mFrames + mFrames * mFrameVariation.noise(mCurrentTick, this);
    00234                 if (texture < 0) texture = 0;
    00235                 if (texture >= mFrames) texture = mFrames - 1;
    00236                 aGL->setTexture(mFrame[texture]);
    00237             }
    00238
    00239             XFcFixed size = mParticleSizeStart + deltaAge * (mParticleSizeEnd - mParticleSizeStart);
    00240             size += mParticleSizeVariation.noise(mCurrentTick, this);
    00241             size = size * mSizeScale * mViewScale;
    00242
    00243             XFcFixed alpha = mAlphaStart + deltaAge * (mAlphaEnd - mAlphaStart);
    00244             alpha += mAlphaVariation.noise(mCurrentTick, this) * 255;
    00245             INT32 finalAlpha = alpha;
    00246             if (finalAlpha > 255) finalAlpha = 255;
    00247             if (finalAlpha < 0) finalAlpha = 0;
    00248             finalAlpha <<= 24;
    00249
    00250             XFcMath::matrixIdentity(rot);
    00251             if (mParticle[i].mAngle != REALi(0))
    00252             {
    00253                 REAL cosVal = XFcMath::cosFast(mParticle[i].mAngle);
    00254                 REAL sinVal = XFcMath::sinFast(mParticle[i].mAngle);
    00255                 rot.m[0][0] = cosVal;
    00256                 rot.m[0][1] = sinVal;
    00257                 rot.m[1][0] = -sinVal;
    00258                 rot.m[1][1] = cosVal;
    00259             }
    00260
    00261             // draw sprite:
    00262             aGL->drawSprite3dBillboard(mParticle[i].mX * mSizeScale, mParticle[i].mY * mSizeScale, mParticle[i].mZ * mSizeScale, size, size, 0, 0, 1, 1, &rot, 0xffffff | finalAlpha);
    00263         }
    00264     }
    00265     // restore changed GL states:
    00266     aGL->setStateI(XFCGLRS_CULLING,cullmode);
    00267     aGL->setStateI(XFCGLRS_ALPHABLEND,alphablend);
    00268     aGL->setStateI(XFCGLRS_SRCBLEND,srcblend);
    00269     aGL->setStateI(XFCGLRS_TGTBLEND,tgtblend);
    00270     aGL->setStateI(XFCGLRS_SHADING,shademode);
    00271     aGL->setStateI(XFCGLRS_PERSPECTIVECORRECTION, perspcorr);
    00272 }
    00273
    00274
    00275 void XFuParticleSystem::newParticle(struct Particle &aParticle)
    00276 {
    00277     aParticle.mAge = 0;
    00278     aParticle.mMaxAge = mMaxAge - ((int)((mAgeVariation.noise(mCurrentTick, this) + mAgeVariation.mValue) * REALi(mMaxAge)));
    00279     if (aParticle.mMaxAge == 0)
    00280         aParticle.mMaxAge = 1;
    00281     aParticle.mX = aParticle.mY = aParticle.mZ = 0;
    00282     if (mEmitterSize[0] != 0)
    00283     {
    00284         aParticle.mX = ((PSRand() - 16384) * mEmitterSize[0]) / REALi(16384);
    00285     }
    00286     if (mEmitterSize[1] != 0)
    00287     {
    00288         aParticle.mY = ((PSRand() - 16384) * mEmitterSize[1]) / REALi(16384);
    00289     }
    00290     if (mEmitterSize[2] != 0)
    00291     {
    00292         aParticle.mZ=((PSRand() - 16384) * mEmitterSize[2]) / REALi(16384);
    00293     }
    00294     aParticle.mUniqueSeed = (PSRand() & 0x7fff);
    00295     aParticle.mXi = (mLaunchVelocity[0] + mLaunchVelocityVar[0].noise(mCurrentTick, this));
    00296     aParticle.mYi = (mLaunchVelocity[1] + mLaunchVelocityVar[1].noise(mCurrentTick, this));
    00297     aParticle.mZi = (mLaunchVelocity[2] + mLaunchVelocityVar[2].noise(mCurrentTick, this));
    00298
    00299     aParticle.mAngle = mRotationNoise.noise(mCurrentTick, this) * PI;
    00300     aParticle.mBaseRotation = mRotation;
    00301 }
    00302
    00303 void XFuParticleSystem::tickOnce(XFcFixed aTimeSlice)
    00304 {
    00305     XFcFixed time = aTimeSlice / 100;
    00306     mCurrentTick += aTimeSlice;
    00307     mEmitQueue += XFcFixed(aTimeSlice * mLaunchRate) / 1000;
    00308     INT32 newones = (INT32)(mEmitQueue - mEmitted);
    00309     if (newones > mMaxVisible * 2) mEmitQueue -= (newones - mMaxVisible * 2);
    00310
    00311     INT32 i;
    00312     for (i = 0; i < mMaxVisible; i++)
    00313     {
    00314         if (mParticle[i].mAge != -1)
    00315         {
    00316             mParticle[i].mAge += aTimeSlice;
    00317             if (mParticle[i].mAge >= mParticle[i].mMaxAge)
    00318             {
    00319                 mParticle[i].mAge = -1;
    00320                 mActive--;
    00321             }
    00322         }
    00323         if (mParticle[i].mAge == -1 && newones > 0 && (mMaxTotal == 0 || mMaxTotal > mEmitted))
    00324         {
    00325             newParticle(mParticle[i]);
    00326             mEmitted++;
    00327             newones--;
    00328             mActive++;
    00329             if (mPeakActive < mActive) mPeakActive = mActive;
    00330         }
    00331         if (mParticle[i].mAge !=  - 1)
    00332         {
    00333             XFcFixed difx = mWeight[0] + mNoise[0].noise(mCurrentTick + mParticle[i].mUniqueSeed, this) + -mParticle[i].mXi * (1 - mDamping[0]);
    00334             XFcFixed dify = mWeight[1] + mNoise[1].noise(mCurrentTick + mParticle[i].mUniqueSeed, this) + -mParticle[i].mYi * (1 - mDamping[1]);
    00335             XFcFixed difz = mWeight[2] + mNoise[2].noise(mCurrentTick + mParticle[i].mUniqueSeed, this) + -mParticle[i].mZi * (1 - mDamping[2]);
    00336
    00337             mParticle[i].mX += mParticle[i].mXi * time + (difx / 2) * time * time;
    00338             mParticle[i].mY += mParticle[i].mYi * time + (dify / 2) * time * time;
    00339             mParticle[i].mZ += mParticle[i].mZi * time + (difz / 2) * time * time;
    00340
    00341             mParticle[i].mXi += difx * time;
    00342             mParticle[i].mYi += dify * time;
    00343             mParticle[i].mZi += difz * time;
    00344
    00345             if (mAABB[0]!=0 && XFcMath::abs(mParticle[i].mX) > mAABB[0])
    00346             {
    00347                 if ((mParticle[i].mX < 0 && mFlags & XFUPSF_COLLIDER_XMIN) || (mParticle[i].mX > 0 && mFlags & XFUPSF_COLLIDER_XMAX))
    00348                 {
    00349                     mParticle[i].mXi = -mParticle[i].mXi;
    00350                     if (mParticle[i].mX < 0)
    00351                         mParticle[i].mX = -mAABB[0];
    00352                     else
    00353                         mParticle[i].mX = mAABB[0];
    00354
    00355                 }
    00356                 else
    00357                 {
    00358                     mParticle[i].mAge = -1;
    00359                     mActive--;
    00360                 }
    00361             }
    00362             if (mAABB[1] != 0 && XFcMath::abs(mParticle[i].mY) > mAABB[1])
    00363             {
    00364                 if ((mParticle[i].mY < 0 && mFlags & XFUPSF_COLLIDER_YMIN) || (mParticle[i].mY > 0 && mFlags & XFUPSF_COLLIDER_YMAX))
    00365                 {
    00366                     mParticle[i].mYi = -mParticle[i].mYi;
    00367                     if (mParticle[i].mY < 0)
    00368                         mParticle[i].mY = -mAABB[1];
    00369                     else
    00370                         mParticle[i].mY = mAABB[1];
    00371
    00372                 }
    00373                 else
    00374                 {
    00375                     mParticle[i].mAge = -1;
    00376                     mActive--;
    00377                 }
    00378             }
    00379             if (mAABB[2] != 0 && XFcMath::abs(mParticle[i].mZ) > mAABB[2])
    00380             {
    00381                 if ((mParticle[i].mZ < 0 && mFlags & XFUPSF_COLLIDER_ZMIN) || (mParticle[i].mZ > 0 && mFlags & XFUPSF_COLLIDER_ZMAX))
    00382                 {
    00383                     mParticle[i].mZi = -mParticle[i].mZi;
    00384                     if (mParticle[i].mZ < 0)
    00385                         mParticle[i].mZ = -mAABB[2];
    00386                     else
    00387                         mParticle[i].mZ = mAABB[2];
    00388
    00389                 }
    00390                 else
    00391                 {
    00392                     mParticle[i].mAge = -1;
    00393                     mActive--;
    00394                 }
    00395             }
    00396             mParticle[i].mAngle += time * (mParticle[i].mBaseRotation + mRotationVariation.noise(mCurrentTick+mParticle[i].mUniqueSeed, this));
    00397         }
    00398     }
    00399 }
    00400
    00401
    00402
    00403 void XFuParticleSystem::tick(XFcFixed aTime)
    00404 {
    00405     XFcFixed currenttick = aTime;
    00406
    00407     XFcFixed deltatick = currenttick - mLastTick;
    00408
    00409     if (deltatick > 500 || deltatick < 0)
    00410     {
    00411         // if over 500ms, (2 fps), assume we have slept for a while and don't even try to keep up
    00412         // (these particle systems tend to blow up under 4fps in any case)
    00413         deltatick = 0;
    00414         mLastTick = currenttick;
    00415     }
    00416
    00417     deltatick = mTimeScale * deltatick;
    00418
    00419     XFcFixed frametime = deltatick;
    00420
    00421     if (mDesiredFPS != 0)
    00422         frametime = (REALi(1000) / mDesiredFPS);
    00423
    00424     if (mDesiredFPS != 0 && deltatick < frametime) return;
    00425
    00426     // accuracy problem here - round-offs of last tick are ignored
    00427     mLastTick = currenttick;
    00428
    00429     INT32 loops = 1;
    00430
    00431     if (mFlags & XFUPSF_FORCEITERATIONS)
    00432     {
    00433         loops = (INT32)(deltatick / frametime);
    00434         deltatick = frametime;
    00435         if (loops < 0) loops = 1;
    00436     }
    00437
    00438
    00439     for (; loops; --loops)
    00440     {
    00441         tickOnce(deltatick);
    00442     }
    00443 }
    00444
    00445
    00446 void XFuNoiseController::write(XFcFile * aFile)
    00447 {
    00448     aFile->writeINT32(mType);
    00449     aFile->writeFLOAT32(mPeriod);
    00450     aFile->writeFLOAT32(mValue);
    00451 }
    00452
    00453 void XFuNoiseController::read(XFcFile * aFile)
    00454 {
    00455     mType = aFile->readINT32();
    00456     mPeriod = aFile->readFLOAT32();
    00457     mValue = aFile->readFLOAT32();
    00458 }
    00459
    00460
    00461 void XFuParticleSystem::save(const CHAR *fname)
    00462 {
    00463     XFcFile * f;
    00464     f = XFcFile::open(fname,"wb");
    00465     INT32 tag = PS_VERSIONTAG; // 'PR__' where __ is 00 03
    00466     f->writeINT32(tag);
    00467     f->writeINT32(mFlags);
    00468     f->writeFLOAT32(mLaunchVelocity[0]);
    00469     f->writeFLOAT32(mLaunchVelocity[1]);
    00470     f->writeFLOAT32(mLaunchVelocity[2]);
    00471     mLaunchVelocityVar[0].write(f);
    00472     mLaunchVelocityVar[1].write(f);
    00473     mLaunchVelocityVar[2].write(f);
    00474     f->writeFLOAT32(mDamping[0]);
    00475     f->writeFLOAT32(mDamping[1]);
    00476     f->writeFLOAT32(mDamping[2]);
    00477     f->writeFLOAT32(mWeight[0]);
    00478     f->writeFLOAT32(mWeight[1]);
    00479     f->writeFLOAT32(mWeight[2]);
    00480     mNoise[0].write(f);
    00481     mNoise[1].write(f);
    00482     mNoise[2].write(f);
    00483     f->writeFLOAT32(mLaunchRate);
    00484     f->writeINT32(mMaxAge);
    00485     mAgeVariation.write(f);
    00486     f->writeINT32(mMaxTotal);
    00487     f->writeINT32(mMaxVisible);
    00488     f->writeFLOAT32(mSizeScale);
    00489     f->writeFLOAT32(mTimeScale);
    00490     f->writeFLOAT32(mDesiredFPS);
    00491     f->writeINT32(mAlphaMode);
    00492     f->writeFLOAT32(mAlphaStart);
    00493     f->writeFLOAT32(mAlphaEnd);
    00494     mAlphaVariation.write(f);
    00495     f->writeFLOAT32(mParticleSizeStart);
    00496     f->writeFLOAT32(mParticleSizeEnd);
    00497     mParticleSizeVariation.write(f);
    00498     f->writeFLOAT32(mRotation);
    00499     mRotationVariation.write(f);
    00500     mRotationNoise.write(f);
    00501     mFrameVariation.write(f);
    00502     f->writeFLOAT32(mEmitterSize[0]);
    00503     f->writeFLOAT32(mEmitterSize[1]);
    00504     f->writeFLOAT32(mEmitterSize[2]);
    00505     f->writeFLOAT32(mAABB[0]);
    00506     f->writeFLOAT32(mAABB[1]);
    00507     f->writeFLOAT32(mAABB[2]);
    00508     f->writeINT32(mPreTick);
    00509
    00510     // filenames are encoded as thus: "filename1|filename2|filename3||" <- two |:s end the string
    00511
    00512     INT32 i;
    00513     for (i = 0; i < mFrames; i++)
    00514     {
    00515         CHAR * t = mTexture[i];
    00516         while (*t != 0)
    00517         {
    00518             f->putChar(*t);
    00519             t++;
    00520         }
    00521         f->putChar('|');
    00522     }
    00523     f->putChar('|');
    00524     f->putChar('|');
    00525
    00526     f->close();
    00527 }
    00528
    00529
    00530
    00531 void XFuParticleSystem::load(const char *fname)
    00532 {
    00533     XFcFile *f = XFcFile::open(fname, "rb");
    00534     load(f);
    00535     f->close();
    00536 }
    00537
    00538 void XFuParticleSystem::load(XFcFile *f)
    00539 {
    00540     if (f == NULL) return;
    00541     // load ps3
    00542     int tag = f->readINT32();
    00543     if (tag != PS_VERSIONTAG)
    00544     {
    00545         // different version
    00546     }
    00547     mFlags = f->readINT32();
    00548     mLaunchVelocity[0] = f->readFLOAT32();
    00549     mLaunchVelocity[1] = f->readFLOAT32();
    00550     mLaunchVelocity[2] = f->readFLOAT32();
    00551     mLaunchVelocityVar[0].read(f);
    00552     mLaunchVelocityVar[1].read(f);
    00553     mLaunchVelocityVar[2].read(f);
    00554     mDamping[0] = f->readFLOAT32();
    00555     mDamping[1] = f->readFLOAT32();
    00556     mDamping[2] = f->readFLOAT32();
    00557     mWeight[0] = f->readFLOAT32();
    00558     mWeight[1] = f->readFLOAT32();
    00559     mWeight[2] = f->readFLOAT32();
    00560     mNoise[0].read(f);
    00561     mNoise[1].read(f);
    00562     mNoise[2].read(f);
    00563     mLaunchRate = f->readFLOAT32();
    00564     mMaxAge = f->readINT32();
    00565     mAgeVariation.read(f);
    00566     mMaxTotal = f->readINT32();
    00567     mMaxVisible = f->readINT32();
    00568     mSizeScale = f->readFLOAT32();
    00569     mTimeScale = f->readFLOAT32();
    00570     mDesiredFPS = f->readFLOAT32();
    00571     mAlphaMode = f->readINT32();
    00572     mAlphaStart = f->readFLOAT32();
    00573     mAlphaEnd = f->readFLOAT32();
    00574     mAlphaVariation.read(f);
    00575     mParticleSizeStart = f->readFLOAT32();
    00576     mParticleSizeEnd = f->readFLOAT32();
    00577     mParticleSizeVariation.read(f);
    00578     mRotation = f->readFLOAT32();
    00579     mRotationVariation.read(f);
    00580     mRotationNoise.read(f);
    00581     mFrameVariation.read(f);
    00582     mEmitterSize[0] = f->readFLOAT32();
    00583     mEmitterSize[1] = f->readFLOAT32();
    00584     mEmitterSize[2] = f->readFLOAT32();
    00585     mAABB[0] = f->readFLOAT32();
    00586     mAABB[1] = f->readFLOAT32();
    00587     mAABB[2] = f->readFLOAT32();
    00588     mPreTick = f->readINT32();
    00589
    00590     if (mFrame != NULL)
    00591     {
    00592         INT32 i;
    00593         for (i = 0; i < mFrames; i++)
    00594             delete mFrame[i];
    00595         delete[] mFrame;
    00596     }
    00597     mFrames = 0;
    00598     mFrame = NULL;
    00599     CHAR ** temp;
    00600     CHAR * tempstr;
    00601     temp = new CHAR*[256];
    00602     tempstr = new CHAR[256];
    00603     INT32 inchar = f->getChar();
    00604     INT32 idx=0;
    00605     while (inchar != EOF)
    00606     {
    00607         if (inchar == '|' && idx == 0)
    00608         {
    00609             inchar = EOF;
    00610         }
    00611         else
    00612         {
    00613             if (inchar == '|')
    00614             {
    00615                 tempstr[idx] = 0;
    00616                 temp[mFrames] = XFcStringToolkit::copy(tempstr);
    00617                 idx = 0;
    00618                 mFrames++;
    00619             }
    00620             else
    00621             {
    00622                 tempstr[idx] = (CHAR)inchar;
    00623                 idx++;
    00624             }
    00625             inchar = f->getChar();
    00626         }
    00627     }
    00628     delete[] tempstr;
    00629
    00630     if (mFrames > 0)
    00631     {
    00632         mTexture = new CHAR*[mFrames];
    00633         INT i;
    00634         for (i = 0; i < mFrames; i++)
    00635             mTexture[i] = temp[i];
    00636     }
    00637     else
    00638     {
    00639         mTexture = NULL;
    00640     }
    00641     delete[] temp;
    00642
    00643     if (mSizeScale == 0) mSizeScale = 1;
    00644     setMaxVisible(mMaxVisible); // calls restart()
    00645 }
    00646
    00647
    00648 void XFuParticleSystem::loadTextures(const CHAR *aFilenamePrefix)
    00649 {
    00650     mFrame = new XFcGLTexture *[mFrames];
    00651     INT32 i;
    00652     for (i = 0; i < mFrames; i++)
    00653     {
    00654         mFrame[i] = NULL;
    00655     }
    00656
    00657     for (i = 0; i < mFrames; i++)
    00658     {
    00659         if (aFilenamePrefix == NULL)
    00660             mFrame[i] = XFcGLTextureFromFile::create(mTexture[i]);
    00661         else
    00662         {
    00663             CHAR *filename = XFcStringToolkit::concat(aFilenamePrefix, mTexture[i]);
    00664             mFrame[i] = XFcGLTextureFromFile::create(filename);
    00665             delete[] filename;
    00666         }
    00667     }
    00668 }
    00669

|  | X-Forge Documentation Confidential Copyright © 2002-2003 Fathammer |  | Documentation generated with doxygen by Dimitri van Heesch