NL3D::CPSFanLightHelper Class Reference


Detailed Description

====================================================================================

Well, we could have put a method template in CPSFanLight, but some compilers want the definition of the methods in the header, and some compilers don't want friend with function template, so we use a static method template of a friend class instead, which gives us the same result :)

Definition at line 68 of file ps_fan_light.cpp.

Static Public Member Functions

template<class T, class U> void drawFanLight (T posIt, U timeIt, CPSFanLight &f, uint size, uint32 srcStep)


Member Function Documentation

template<class T, class U>
void NL3D::CPSFanLightHelper::drawFanLight posIt,
timeIt,
CPSFanLight f,
uint  size,
uint32  srcStep
[inline, static]
 

Definition at line 72 of file ps_fan_light.cpp.

References NL3D::CPSRotated2DParticle::_Angle2D, NL3D::CPSRotated2DParticle::_Angle2DScheme, NL3D::CPSColoredParticle::_ColorScheme, NL3D::CPSMaterial::_Mat, NL3D::CPSFanLight::_MoveIntensity, NL3D::CPSFanLight::_NbFans, NL3D::CPSLocatedBindable::_Owner, NL3D::CPSSizedParticle::_ParticleSize, NL3D::CPSFanLight::_PhaseSmoothness, NL3D::CPSFanLight::_PhaseSpeed, NL3D::CPSFanLight::_RandomPhaseTab, NL3D::CPSFanLight::_RandomPhaseTabInitialized, NL3D::CPSSizedParticle::_SizeScheme, NL3D::IDriver::activeVertexBuffer(), CHECK_VERTEX_BUFFER, NL3D::CPSLocatedBindable::computeI(), NL3D::CPSLocatedBindable::computeK(), NL3D::FanLightBufSize, NL3D::CVertexBuffer::getColorPointer(), NL3D::CPSLocatedBindable::getDriver(), NL3D::CPSFanLight::getNumFanlightsInVB(), NL3D::CPSFanLight::getVBnIB(), NL3D::CVertexBuffer::getVertexCoordPointer(), NL3D::CVertexBuffer::getVertexSize(), NL3D::CPSLocated::incrementNbDrawnParticles(), NL3D::CPSAttribMaker< float >::make(), NL3D::CPSAttribMaker< CRGBA >::make(), min, nlassert, PARTICLES_CHECK_MEM, NL3D::IDriver::renderTriangles(), NL3D::CPSLocatedBindable::setupDriverModelMatrix(), sint32, size, stride, NL3D::CPSFanLight::TIndexBuffer, uint, uint32, and uint8.

00073         {
00074                 PARTICLES_CHECK_MEM;
00075                 nlassert(f._RandomPhaseTabInitialized);
00076                 //
00077                 f.setupDriverModelMatrix();
00078                 const CVector I = f.computeI();
00079                 const CVector K = f.computeK();         
00080                 //              
00081                 CVertexBuffer *vb;
00082                 CPSFanLight::TIndexBuffer  *ib;
00083                 // get (and build if necessary) the vb and the ib
00084                 f.getVBnIB(vb, ib);
00085                 IDriver *driver = f.getDriver();
00086                 driver->activeVertexBuffer(*vb);
00087                 const uint maxNumFanLightToDealWith = std::min(FanLightBufSize, f.getNumFanlightsInVB());       
00088                 uint8 *randomPhaseTab = &f._RandomPhaseTab[f._PhaseSmoothness][0];
00089                 f._Owner->incrementNbDrawnParticles(size); // for benchmark purpose                     
00090                 float pSizes[FanLightBufSize];
00091                 float pAngles[FanLightBufSize];
00092                 T endPosIt;             
00093 
00094                 sint32 k; // helps to count the fans
00095 
00096                 
00097                  // if so, we need to deal process separatly group of particles                 
00098                 const uint32 stride = vb->getVertexSize();
00099 
00100                 float currentAngle;
00101                 const float angleStep = 256.0f / f._NbFans;     
00102 
00103                 
00104                 float *currentSizePt; // it points either the particle constant size, or a size in a table
00105                 float *currentAnglePt; // it points either the particle constant angle, or an angle in a table
00106 
00107                 
00108                 const uint32 currentSizePtIncrement = f._SizeScheme ? 1 : 0; // increment to get the next size for the size pointer. It is 0 if the size is constant
00109                 const uint32 currentAnglePtIncrement = f._Angle2DScheme ? 1 : 0; // increment to get the next angle for the angle pointer. It is 0 if the size is constant
00110                                 
00111 
00112                 uint leftToDo = size;
00113                 do
00114                 {                               
00115                         uint8 *ptVect = (uint8 *) vb->getVertexCoordPointer();
00116                         uint toProcess = std::min(leftToDo, maxNumFanLightToDealWith);                                                  
00117                         // compute individual colors if needed
00118                         if (f._ColorScheme)
00119                         {
00120                                 // we change the color at each fan light center
00121                                 f._ColorScheme->make(f._Owner, size - leftToDo, vb->getColorPointer(), vb->getVertexSize() * (f._NbFans + 2), toProcess, false, srcStep);
00122                         }
00123                         if (f._SizeScheme)
00124                         {
00125                                 currentSizePt  = (float *) (f._SizeScheme->make(f._Owner, size - leftToDo, pSizes, sizeof(float), toProcess, true, srcStep));
00126                                 currentSizePt = pSizes;
00127                         }
00128                         else
00129                         {
00130                                 currentSizePt = &f._ParticleSize;
00131                         }
00132                         if (f._Angle2DScheme)
00133                         {
00134                                 currentAnglePt = (float *) (f._Angle2DScheme->make(f._Owner, size - leftToDo, pAngles, sizeof(float), toProcess, true, srcStep));                                       
00135                         }
00136                         else
00137                         {
00138                                 currentAnglePt = &f._Angle2D;
00139                         }                       
00140                         //                                                              
00141                         float fSize, firstSize, sizeStepBase=0.0, sizeStep;
00142                         if (f._PhaseSmoothness)
00143                         {
00144                                 sizeStepBase = 1.f / f._PhaseSmoothness;
00145                         }
00146                         endPosIt = posIt + toProcess;
00147                         for (;posIt != endPosIt; ++posIt, ++timeIt)
00148                         {       
00149                                 
00150                                 CHECK_VERTEX_BUFFER(*vb, ptVect);
00151                                 *(CVector *) ptVect = *posIt;                           
00152                                 // the start angle
00153                                 currentAngle = *currentAnglePt;
00154                                 const uint8 phaseAdd = (uint8) (f._PhaseSpeed * (*timeIt));
00155                                 ptVect += stride;
00156                                 const float fanSize = *currentSizePt * 0.5f;
00157                                 const float moveIntensity = f._MoveIntensity * fanSize;                         
00158                                 // compute radius & vect for first fan
00159                                 firstSize  = fanSize + (moveIntensity * CPSUtil::getCos(randomPhaseTab[0] + phaseAdd));
00160                                 *(CVector *) ptVect = (*posIt) + I * firstSize * (CPSUtil::getCos((sint32) currentAngle))
00161                                                                           + K * firstSize * (CPSUtil::getSin((sint32) currentAngle));
00162                                 currentAngle += angleStep;
00163                                 ptVect += stride;
00164                                 fSize = firstSize;
00165                                 // computes other fans
00166                                 const sint32 upperBound = (sint32) (f._NbFans - f._PhaseSmoothness - 1);
00167                                 for (k = 1; k <= upperBound; ++k)
00168                                 {
00169                                         fSize  = fanSize + (moveIntensity * CPSUtil::getCos(randomPhaseTab[k] + phaseAdd));
00170                                         *(CVector *) ptVect = (*posIt) + I * fSize * (CPSUtil::getCos((sint32) currentAngle))
00171                                                                                   + K * fSize * (CPSUtil::getSin((sint32) currentAngle));
00172                                         currentAngle += angleStep;
00173                                         ptVect += stride;
00174                                 }
00175 
00176                                 // interpolate radius, so that the fanlight loops correctly
00177                                 sizeStep = sizeStepBase * (firstSize - fSize);
00178                                 for (; k <= (sint32) (f._NbFans - 1); ++k)
00179                                 {                               
00180                                         *(CVector *) ptVect = (*posIt) + I * fSize * (CPSUtil::getCos((sint32) currentAngle))
00181                                                                                   + K * fSize * (CPSUtil::getSin((sint32) currentAngle));
00182                                         currentAngle += angleStep;
00183                                         ptVect += stride;
00184                                         fSize  += sizeStep;
00185                                 }
00186                                 // last fan
00187                                 *(CVector *) ptVect = (*posIt) + I * firstSize * (CPSUtil::getCos((sint32) *currentAnglePt))
00188                                                                                   + K * firstSize * (CPSUtil::getSin((sint32) *currentAnglePt));
00189                                 ptVect += stride;
00190                                 currentSizePt += currentSizePtIncrement;
00191                                 currentAnglePt += currentAnglePtIncrement;
00192                         }                       
00193                         driver->renderTriangles(f._Mat, &((*ib)[0]), toProcess * f._NbFans);
00194                         leftToDo -= toProcess;
00195                 }               
00196                 while (leftToDo != 0);
00197                 PARTICLES_CHECK_MEM;
00198         }


The documentation for this class was generated from the following file:
Generated on Tue Mar 16 07:13:02 2004 for NeL by doxygen 1.3.6