From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/ps__shockwave_8cpp-source.html | 547 ++++++++++++++++++++++++ 1 file changed, 547 insertions(+) create mode 100644 docs/doxygen/nel/ps__shockwave_8cpp-source.html (limited to 'docs/doxygen/nel/ps__shockwave_8cpp-source.html') diff --git a/docs/doxygen/nel/ps__shockwave_8cpp-source.html b/docs/doxygen/nel/ps__shockwave_8cpp-source.html new file mode 100644 index 00000000..e88b9430 --- /dev/null +++ b/docs/doxygen/nel/ps__shockwave_8cpp-source.html @@ -0,0 +1,547 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# Home   # nevrax.com   
+ + + + +
Nevrax
+ + + + + + + + + + +
+ + +
+ Nevrax.org
+ + + + + + + +
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
+
+ + +
+ + +
+Docs + +
+  + + + + + +
Documentation 
+ +
+Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  
+

ps_shockwave.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2001 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NEL.
+00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+00024  */
+00025 
+00026 #include "std3d.h"
+00027 
+00028 #include "3d/ps_macro.h"
+00029 #include "3d/ps_shockwave.h"
+00030 #include "3d/driver.h"
+00031 #include "3d/texture_grouped.h"
+00032 #include "3d/ps_iterator.h"
+00033 #include "3d/particle_system.h"
+00034 
+00035 
+00036 namespace NL3D 
+00037 {                                                          
+00038 
+00040 // constant definition   //
+00042 
+00043 // max number of shockwave to be processed at once
+00044 static const uint ShockWaveBufSize = 128; 
+00045 
+00046 // the number of vertices we want in a vertex buffer
+00047 static const uint NumVertsInBuffer = 8 * ShockWaveBufSize;
+00048 
+00049 
+00050 CPSShockWave::TPBMap CPSShockWave::_PBMap; // the primitive blocks
+00051 CPSShockWave::TVBMap CPSShockWave::_VBMap; // vb ith unanimated texture
+00052 CPSShockWave::TVBMap CPSShockWave::_AnimTexVBMap; // vb ith unanimated texture
+00053 CPSShockWave::TVBMap CPSShockWave::_ColoredVBMap; // vb ith unanimated texture
+00054 CPSShockWave::TVBMap CPSShockWave::_ColoredAnimTexVBMap; // vb ith unanimated texture
+00056 // CPSShockWave implementation //
+00058 
+00059 
+00065 class CPSShockWaveHelper
+00066 {
+00067 public:
+00068         template <class T>      
+00069         static void drawShockWave(T posIt, CPSShockWave &s, uint size, uint32 srcStep)
+00070         {
+00071                 PARTICLES_CHECK_MEM;
+00072                 nlassert(s._Owner);
+00073 
+00074                 // get / build the vertex buffer and the primitive block
+00075                 CVertexBuffer *vb;
+00076                 CPrimitiveBlock *pb;
+00077                 s.getVBnPB(vb, pb);
+00078 
+00079                 const uint32 vSize = vb->getVertexSize();
+00080                 IDriver *driver = s.getDriver();
+00081                 s._Owner->incrementNbDrawnParticles(size); // for benchmark purpose     
+00082                 s.setupDriverModelMatrix();
+00083                 const uint numShockWaveToDealWith = std::min(ShockWaveBufSize, s.getNumShockWavesInVB());
+00084                 driver->activeVertexBuffer(*vb);        
+00085 
+00086                 static CPlaneBasis planeBasis[ShockWaveBufSize];
+00087                 float       sizes[ShockWaveBufSize];
+00088                 float       angles[ShockWaveBufSize];
+00089                 
+00090                 uint leftToDo  = size, toProcess;
+00091                 T endIt;
+00092                 uint8 *currVertex;
+00093                 uint k ;
+00094 
+00095                 const float angleStep = 256.f / s._NbSeg;
+00096                 float currAngle;
+00097 
+00098                 CPlaneBasis *ptCurrBasis;
+00099                 uint32  ptCurrBasisIncrement = s._PlaneBasisScheme ? 1 : 0;
+00100 
+00101                 float *ptCurrSize;
+00102                 uint32 ptCurrSizeIncrement = s._SizeScheme ? 1 : 0;
+00103 
+00104                 float *ptCurrAngle;
+00105                 uint32 ptCurrAngleIncrement = s._Angle2DScheme ? 1 : 0;
+00106 
+00107                 CVector radVect, innerVect;
+00108                 float radiusRatio;
+00109 
+00110                 do
+00111                 {
+00112                         currVertex = (uint8 *) vb->getVertexCoordPointer();
+00113                         toProcess = leftToDo > numShockWaveToDealWith ? numShockWaveToDealWith : leftToDo;
+00114                         endIt = posIt + toProcess;
+00115                         if (s._SizeScheme)
+00116                         {
+00117                                 ptCurrSize  = (float *) (s._SizeScheme->make(s._Owner, size - leftToDo, (void *) sizes, sizeof(float), toProcess, true, srcStep));                      
+00118                         }
+00119                         else
+00120                         {
+00121                                 ptCurrSize = &s._ParticleSize;
+00122                         }
+00123 
+00124                         if (s._PlaneBasisScheme)
+00125                         {
+00126                                 ptCurrBasis  = (CPlaneBasis *) (s._PlaneBasisScheme->make(s._Owner, size - leftToDo, (void *) planeBasis, sizeof(CPlaneBasis), toProcess, true, srcStep));                      
+00127                         }
+00128                         else
+00129                         {
+00130                                 ptCurrBasis = &s._PlaneBasis;
+00131                         }
+00132 
+00133                         if (s._Angle2DScheme)
+00134                         {
+00135                                 ptCurrAngle  = (float *) (s._Angle2DScheme->make(s._Owner, size - leftToDo, (void *) angles, sizeof(float), toProcess, true, srcStep));                 
+00136                         }
+00137                         else
+00138                         {
+00139                                 ptCurrAngle = &s._Angle2D;
+00140                         }
+00141                         
+00142 
+00143                         s.updateVbColNUVForRender(size - leftToDo, toProcess, srcStep, *vb);
+00144                         do
+00145                         {                       
+00146                                 currAngle = *ptCurrAngle;
+00147                                 if (fabsf(*ptCurrSize) > 10E-6)
+00148                                 {
+00149                                         radiusRatio = (*ptCurrSize - s._RadiusCut) / *ptCurrSize;
+00150                                 }
+00151                                 else
+00152                                 {
+00153                                         radiusRatio = 0.f;
+00154                                 }
+00155 
+00156                                 for (k = 0; k <= s._NbSeg; ++k)
+00157                                 {
+00158                                         radVect = *ptCurrSize * (CPSUtil::getCos((sint32) currAngle) * ptCurrBasis->X + CPSUtil::getSin((sint32) currAngle) * ptCurrBasis->Y);
+00159                                         innerVect = radiusRatio * radVect;
+00160                                         CHECK_VERTEX_BUFFER(*vb, currVertex);
+00161                                         * (CVector *) currVertex = *posIt + radVect;
+00162                                         currVertex += vSize;
+00163                                         CHECK_VERTEX_BUFFER(*vb, currVertex);
+00164                                         * (CVector *) currVertex = *posIt + innerVect;
+00165                                         currVertex += vSize;
+00166                                         currAngle += angleStep;                         
+00167                                 }
+00168                                 
+00169                                 ++posIt;
+00170                                 ptCurrBasis +=  ptCurrBasisIncrement;
+00171                                 ptCurrSize  +=  ptCurrSizeIncrement;
+00172                                 ptCurrAngle  +=  ptCurrAngleIncrement;
+00173                         }
+00174                         while (posIt != endIt);                 
+00175 
+00176                         pb->setNumQuad(toProcess * s._NbSeg);
+00177                         driver->render(*pb, s._Mat);
+00178                         leftToDo -= toProcess;          
+00179                 }
+00180                 while (leftToDo);
+00181                 PARTICLES_CHECK_MEM;
+00182         }
+00183 };
+00184 
+00186 CPSShockWave::CPSShockWave(uint nbSeg, float radiusCut, CSmartPtr<ITexture> tex) 
+00187                 :  _NbSeg(nbSeg)
+00188                    , _RadiusCut(radiusCut)
+00189                    , _UFactor(1.f)
+00190 
+00191 {
+00192         nlassert(nbSeg > 2 && nbSeg <= 64);
+00193         setTexture(tex);
+00194         init();
+00195         _Name = std::string("ShockWave");
+00196 }
+00197 
+00199 uint32 CPSShockWave::getMaxNumFaces(void) const
+00200 {
+00201         nlassert(_Owner);
+00202         return (_Owner->getMaxSize() * _NbSeg) << 1 ;
+00203 }
+00204 
+00206 bool CPSShockWave::hasTransparentFaces(void)
+00207 {
+00208         return getBlendingMode() != CPSMaterial::alphaTest ;
+00209 }
+00210 
+00212 bool CPSShockWave::hasOpaqueFaces(void)
+00213 {
+00214         return !hasTransparentFaces();
+00215 }
+00216 
+00218 void CPSShockWave::setNbSegs(uint nbSeg)
+00219 {
+00220         nlassert(nbSeg > 2 && nbSeg <= 64);
+00221         _NbSeg = nbSeg;
+00222         if (_Owner)
+00223         {
+00224                 resize(_Owner->getMaxSize());
+00225                 notifyOwnerMaxNumFacesChanged();
+00226         }
+00227 }
+00228 
+00230 void CPSShockWave::setRadiusCut(float radiusCut)
+00231 {
+00232         _RadiusCut = radiusCut; 
+00233         if (_Owner)
+00234         {
+00235                 resize(_Owner->getMaxSize());
+00236         }
+00237 }
+00238 
+00240 void    CPSShockWave::setUFactor(float value)
+00241 {
+00242         nlassert(_Owner); // must be attached to an owner before to call this method
+00243         _UFactor = value;
+00244         resize(_Owner->getSize()); // resize also recomputes the UVs..
+00245 }
+00246 
+00248 void CPSShockWave::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
+00249 {       
+00250         sint ver  = f.serialVersion(2);
+00251         CPSParticle::serial(f);
+00252         CPSColoredParticle::serialColorScheme(f);
+00253         CPSSizedParticle::serialSizeScheme(f);
+00254         CPSTexturedParticle::serialTextureScheme(f);
+00255         CPSRotated3DPlaneParticle::serialPlaneBasisScheme(f);
+00256         CPSRotated2DParticle::serialAngle2DScheme(f);
+00257         serialMaterial(f);
+00258         f.serial(_NbSeg, _RadiusCut);
+00259         if (ver > 1)
+00260         {
+00261                 f.serial(_UFactor);
+00262         }
+00263         init(); 
+00264 }
+00265 
+00267 inline void CPSShockWave::setupUFactor()
+00268 {       
+00269         if (_UFactor != 1.f)
+00270         {
+00271                 _Mat.enableUserTexMat(0);
+00272                 CMatrix texMat;
+00273                 texMat.setRot(_UFactor  * NLMISC::CVector::I,
+00274                                           NLMISC::CVector::J,
+00275                                           NLMISC::CVector::K
+00276                                          );
+00277                 _Mat.setUserTexMat(0, texMat);
+00278         }
+00279         else
+00280         {
+00281                 _Mat.enableUserTexMat(0, false);
+00282         }       
+00283 }
+00284 
+00286 void CPSShockWave::draw(bool opaque)
+00287 {
+00288         PARTICLES_CHECK_MEM;    
+00289         if (!_Owner->getSize()) return; 
+00290 
+00291         uint32 step;
+00292         uint   numToProcess;
+00293         computeSrcStep(step, numToProcess);     
+00294         if (!numToProcess) return;
+00295 
+00296 
+00297         
+00299         CParticleSystem &ps = *(_Owner->getOwner());
+00301         if (_ColorScheme != NULL && ps.getColorAttenuationScheme() != NULL)
+00302         {               
+00303                 CPSMaterial::forceModulateConstantColor(true, ps.getGlobalColor());             
+00304         }
+00305         else
+00306         {
+00307                 forceModulateConstantColor(false);
+00308                 if (!ps.getColorAttenuationScheme())
+00309                 {
+00310                         _Mat.setColor(_Color);
+00311                 }
+00312                 else
+00313                 {
+00314                         NLMISC::CRGBA col;
+00315                         col.modulateFromColor(ps.getGlobalColor(), _Color);
+00316                         _Mat.setColor(col);
+00317                 }
+00318         }
+00320 
+00321         setupUFactor();
+00322         
+00323         if (step == (1 << 16))
+00324         {
+00325                 CPSShockWaveHelper::drawShockWave(_Owner->getPos().begin(),                                
+00326                                                                                   *this,
+00327                                                                                   numToProcess,
+00328                                                                                   step
+00329                                                                                  );
+00330         }
+00331         else
+00332         {               
+00333                 CPSShockWaveHelper::drawShockWave(TIteratorVectStep1616(_Owner->getPos().begin(), 0, step),                                
+00334                                                                                   *this,
+00335                                                                                   numToProcess,
+00336                                                                                   step
+00337                                                                                  );
+00338         }
+00339         
+00340         PARTICLES_CHECK_MEM;
+00341 }
+00342 
+00344 bool CPSShockWave::completeBBox(NLMISC::CAABBox &box) const
+00345 {
+00346         // TODO : implement this
+00347         return false;
+00348 }
+00349 
+00351 void CPSShockWave::init(void)
+00352 {
+00353         _Mat.setLighting(false);        
+00354         _Mat.setZFunc(CMaterial::less);
+00355         _Mat.setDoubleSided(true);
+00356         updateMatAndVbForColor();
+00357         updateMatAndVbForTexture();
+00358 }
+00359 
+00361 void CPSShockWave::updateVbColNUVForRender(uint32 startIndex, uint32 size, uint32 srcStep, CVertexBuffer &vb)
+00362 {
+00363         nlassert(_Owner);
+00364         if (!size) return;
+00365         if (_ColorScheme)
+00366         {
+00367                 // compute the colors, each color is replicated n times...
+00368                 _ColorScheme->makeN(_Owner, startIndex, vb.getColorPointer(), vb.getVertexSize(), size, (_NbSeg + 1) << 1, srcStep);
+00369         }
+00370 
+00371         if (_TexGroup) // if it has a constant texture we are sure it has been setupped before...
+00372         {       
+00373                 sint32 textureIndex[ShockWaveBufSize];
+00374                 const uint32 stride = vb.getVertexSize(), stride2 = stride << 1;
+00375                 uint8 *currUV = (uint8 *) vb.getTexCoordPointer();                              
+00376                 uint k;         
+00377 
+00378                 uint32 currIndexIncr;
+00379                 const sint32 *currIndex;                
+00380 
+00381                 if (_TextureIndexScheme)
+00382                 {
+00383                         currIndex  = (sint32 *) (_TextureIndexScheme->make(_Owner, startIndex, textureIndex, sizeof(sint32), size, true, srcStep));                     
+00384                         currIndexIncr = 1;
+00385                 }
+00386                 else
+00387                 {       
+00388                         currIndex = &_TextureIndex;
+00389                         currIndexIncr = 0;
+00390                 }
+00391                 
+00392                 while (size--)
+00393                 {
+00394                         // for now, we don't make texture index wrapping
+00395                         const CTextureGrouped::TFourUV &uvGroup = _TexGroup->getUVQuad((uint32) *currIndex);
+00396 
+00397                         k = _NbSeg + 1;
+00398 
+00399                         for (k = 0; k <= _NbSeg; ++k)
+00400                         {
+00401                                 
+00402                                 *(CUV *) currUV = uvGroup.uv0 + CUV(k * _UFactor, 0);
+00403                                 *(CUV *) (currUV + stride) = uvGroup.uv3 + CUV(k * _UFactor, 0);                                
+00404                                 // point the next quad
+00405                                 currUV += stride2;
+00406                         }
+00407                         while (--k);
+00408 
+00409                         currIndex += currIndexIncr;
+00410                 }               
+00411         }       
+00412 }
+00413 
+00415 void CPSShockWave::updateMatAndVbForColor(void)
+00416 {       
+00417 
+00418         if (_Owner)
+00419         {
+00420                 resize(_Owner->getMaxSize());
+00421         }       
+00422 }
+00423 
+00425 void CPSShockWave::updateMatAndVbForTexture(void)
+00426 {
+00427         _Mat.setTexture(0, _TexGroup ? (ITexture *) _TexGroup : (ITexture *) _Tex);     
+00428 }
+00429 
+00431 void CPSShockWave::newElement(CPSLocated *emitterLocated, uint32 emitterIndex)
+00432 {
+00433         newColorElement(emitterLocated, emitterIndex);
+00434         newTextureIndexElement(emitterLocated, emitterIndex);
+00435         newSizeElement(emitterLocated, emitterIndex);
+00436         newAngle2DElement(emitterLocated, emitterIndex);
+00437 }
+00438 
+00440 void CPSShockWave::deleteElement(uint32 index)
+00441 {
+00442         deleteColorElement(index);
+00443         deleteTextureIndexElement(index);
+00444         deleteSizeElement(index);
+00445         deleteAngle2DElement(index);
+00446 }
+00447 
+00449 void CPSShockWave::resize(uint32 aSize)
+00450 {
+00451         nlassert(aSize < (1 << 16));
+00452         resizeColor(aSize);
+00453         resizeTextureIndex(aSize);
+00454         resizeSize(aSize);
+00455         resizeAngle2D(aSize);   
+00456 }
+00457 
+00459 void CPSShockWave::getVBnPB(CVertexBuffer *&retVb, CPrimitiveBlock *&retPb)
+00460 {
+00461         TVBMap &vbMap = _ColorScheme == NULL  ? (_TexGroup == NULL ?  _VBMap : _AnimTexVBMap)
+00462                                                                                   : (_TexGroup == NULL ?  _ColoredVBMap : _ColoredAnimTexVBMap);
+00463 
+00464 
+00465         TVBMap::iterator vbIt = vbMap.find(_NbSeg);
+00466         if (vbIt != vbMap.end())
+00467         {
+00468                 retVb = &(vbIt->second);
+00469                 TPBMap::iterator pbIt = _PBMap.find(_NbSeg);
+00470                 nlassert(pbIt != _PBMap.end());
+00471                 retPb = &(pbIt->second);
+00472         }
+00473         else // we need to create the vb
+00474         {               
+00475                 // create an entry (we setup the primitive block at the same time, this could be avoided, but doesn't make much difference)             
+00476                 CVertexBuffer &vb = vbMap[_NbSeg]; // create a vb
+00477                 CPrimitiveBlock &pb = _PBMap[_NbSeg]; // eventually create a pb
+00478                 const uint32 size = getNumShockWavesInVB();
+00479                 vb.setVertexFormat(CVertexBuffer::PositionFlag |
+00480                                                    CVertexBuffer::TexCoord0Flag |
+00481                                                    (_ColorScheme != NULL ?  CVertexBuffer::PrimaryColorFlag : 0) 
+00482                                                   );    
+00483                 vb.setNumVertices((size * (_NbSeg + 1)) << 1 );         
+00484                 pb.reserveQuad(size * _NbSeg);
+00485                 for (uint32 k = 0; k < size; ++k)
+00486                 {
+00487                         for (uint32 l = 0; l < _NbSeg; ++l)
+00488                         {       
+00489                                 const uint32 index = ((k * (_NbSeg + 1)) + l) << 1;                                             
+00490                                 pb.setQuad(l + (k * _NbSeg) , index , index + 2, index + 3, index + 1);                 
+00491                                 vb.setTexCoord(index, 0, CUV((float) l, 0));
+00492                                 vb.setTexCoord(index + 1, 0, CUV((float) l, 1));                        
+00493                         }
+00494                         const uint32 index = ((k * (_NbSeg + 1)) + _NbSeg) << 1;
+00495                         vb.setTexCoord(index, 0, CUV((float) _NbSeg, 0));
+00496                         vb.setTexCoord(index + 1, 0, CUV((float) _NbSeg, 1));                   
+00497                 }
+00498                 retVb = &vb;
+00499                 retPb = &pb;
+00500         }
+00501 }
+00502 
+00504 uint CPSShockWave::getNumShockWavesInVB() const
+00505 {
+00506         const uint numRib = NumVertsInBuffer / ((_NbSeg + 1) << 1);
+00507         return std::max(1u, numRib);
+00508 }
+00509 
+00510 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1