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) |
|
||||||||||||||||||||||||||||
|
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 }
|
1.3.6