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__ribbon_8cpp-source.html | 1099 ++++++++++++++++++++++++++ 1 file changed, 1099 insertions(+) create mode 100644 docs/doxygen/nel/ps__ribbon_8cpp-source.html (limited to 'docs/doxygen/nel/ps__ribbon_8cpp-source.html') diff --git a/docs/doxygen/nel/ps__ribbon_8cpp-source.html b/docs/doxygen/nel/ps__ribbon_8cpp-source.html new file mode 100644 index 00000000..ed0b9629 --- /dev/null +++ b/docs/doxygen/nel/ps__ribbon_8cpp-source.html @@ -0,0 +1,1099 @@ + + + + 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_ribbon.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_ribbon.h"
+00029 #include "3d/ps_macro.h"
+00030 #include "3d/particle_system.h"
+00031 #include "3d/driver.h"
+00032 #include "3d/ps_util.h"
+00033 #include "3d/texture_mem.h"
+00034 #include "nel/misc/matrix.h"
+00035 
+00036 namespace NL3D 
+00037 {
+00038 
+00039 static NLMISC::CRGBA GradientB2W[] = {NLMISC::CRGBA(0, 0, 0, 0), NLMISC::CRGBA(255, 255, 255, 255) };
+00040 
+00042 static ITexture *CreateGradientTexture()
+00043 {
+00044         std::auto_ptr<CTextureMem> tex(new CTextureMem((uint8 *) &GradientB2W,
+00045                                                                                                    sizeof(GradientB2W),
+00046                                                                                                    false, /* dont delete */
+00047                                                                                                    false, /* not a file */
+00048                                                                                                    2, 1)
+00049                                                                   );
+00050         tex->setWrapS(ITexture::Clamp);
+00051         tex->setShareName("#GradBW");
+00052         return tex.release();
+00053 }
+00054 
+00055 
+00057 // ribbon implementation //
+00059 
+00060         // predifined shapes
+00061 const NLMISC::CVector CPSRibbon::Triangle[] = 
+00062 { 
+00063         NLMISC::CVector(0, 1, 0),
+00064         NLMISC::CVector(1, -1, 0),
+00065         NLMISC::CVector(-1, -1, 0),                                                              
+00066 };
+00067 
+00068 const NLMISC::CVector CPSRibbon::Losange[] = 
+00069 { 
+00070         NLMISC::CVector(0, 1.f, 0),
+00071         NLMISC::CVector(1.f, 0, 0),
+00072         NLMISC::CVector(0, -1.f, 0),
+00073         NLMISC::CVector(-1.f, 0, 0)
+00074 };
+00075 
+00076 const NLMISC::CVector  CPSRibbon::HeightSides[] = 
+00077 {  
+00078         NLMISC::CVector(-0.5f, 1, 0),
+00079         NLMISC::CVector(0.5f, 1, 0),
+00080         NLMISC::CVector(1, 0.5f, 0),
+00081         NLMISC::CVector(1, -0.5f, 0),
+00082         NLMISC::CVector(0.5f, -1, 0),
+00083         NLMISC::CVector(-0.5f, -1, 0),
+00084         NLMISC::CVector(-1, -0.5f, 0),
+00085         NLMISC::CVector(-1, 0.5f, 0) 
+00086 };
+00087 
+00088 
+00089 const NLMISC::CVector CPSRibbon::Pentagram[] = 
+00090 { 
+00091         NLMISC::CVector(0, 1, 0),
+00092         NLMISC::CVector(1, -1, 0),
+00093         NLMISC::CVector(-1, 0, 0),
+00094         NLMISC::CVector(1, 0, 0),
+00095         NLMISC::CVector(-1, -1, 0)
+00096 };
+00097 
+00098 const uint CPSRibbon::NbVerticesInTriangle = sizeof(CPSRibbon::Triangle) / sizeof(CVector);
+00099 const uint CPSRibbon::NbVerticesInLosange = sizeof(Losange) / sizeof(CVector);
+00100 const uint CPSRibbon::NbVerticesInHeightSide = sizeof(CPSRibbon::HeightSides) / sizeof(CVector);
+00101 const uint CPSRibbon::NbVerticesInPentagram = sizeof(CPSRibbon::Pentagram) / sizeof(CVector);
+00102 
+00103 
+00104 CPSRibbon::TVBMap                       CPSRibbon::_VBMap;                           // index / vertex buffers with no color
+00105 CPSRibbon::TVBMap                       CPSRibbon::_FadedVBMap;                  // index / vertex buffers for constant color with fading
+00106 CPSRibbon::TVBMap                       CPSRibbon::_ColoredVBMap;                // index / vertex buffer + colors
+00107 CPSRibbon::TVBMap                       CPSRibbon::_FadedColoredVBMap;   // index / vertex buffer + faded colors
+00108 
+00109 CPSRibbon::TVBMap                       CPSRibbon::_TexVBMap;                       // index / vertex buffers with no color + texture
+00110 CPSRibbon::TVBMap                       CPSRibbon::_TexFadedVBMap;              // index / vertex buffers for constant color with fading + texture
+00111 CPSRibbon::TVBMap                       CPSRibbon::_TexColoredVBMap;            // index / vertex buffer + colors + texture
+00112 CPSRibbon::TVBMap                       CPSRibbon::_TexFadedColoredVBMap;   // index / vertex buffer + faded colors + texture
+00113 
+00114 
+00115 struct CDummy2DAngle : CPSRotated2DParticle
+00116 {
+00117         CPSLocated *getAngle2DOwner(void) { return NULL; }
+00118 };
+00119 
+00121 void CPSRibbon::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
+00122 {
+00123         sint ver = f.serialVersion(2);
+00124         if (ver == 1)
+00125         {
+00126                 nlassert(f.isReading());
+00127 
+00130                 sint ver2 = f.serialVersion(2);
+00131 
+00132                 // here is CPSLocatedBindable::serial(f)
+00133                 sint ver3 = f.serialVersion(4);
+00134                 f.serialPtr(_Owner);
+00135                 if (ver3 > 1) f.serialEnum(_LOD);
+00136                 if (ver3 > 2) f.serial(_Name);
+00137                 if (ver3 > 3) 
+00138                 {
+00139                         if (f.isReading())
+00140                         {
+00141                                 uint32 id;
+00142                                 f.serial(id);
+00143                                 setExternID(id);
+00144                         }
+00145                         else
+00146                         {
+00147                                 f.serial(_ExternID);
+00148                         }
+00149                 }
+00150 
+00151                 if (ver2 >= 2)
+00152                 {
+00153                         bool bDisableAutoLOD;
+00154                         f.serial(bDisableAutoLOD);
+00155                         disableAutoLOD(bDisableAutoLOD);
+00156                 }
+00157 
+00158                 uint32 tailNbSegs;
+00159                 bool   colorFading;
+00160                 bool   systemBasisEnabled;
+00161                 bool   drEnabled; // dying ribbons, not supported in this version
+00162 
+00163                 CPSColoredParticle::serialColorScheme(f);
+00164                 CPSSizedParticle::serialSizeScheme(f);
+00165 
+00166                 // we dont use the 2d angle anymore...serial a dummy one
+00167                 {                       
+00168                          CDummy2DAngle _Dummy2DAngle;
+00169                         _Dummy2DAngle.serialAngle2DScheme(f); 
+00170                 }
+00171 
+00172                 f.serial(colorFading, systemBasisEnabled);
+00173                 serialMaterial(f);
+00174 
+00175                 f.serial(drEnabled);                            
+00176                 f.serial(tailNbSegs);
+00177                 ITexture *tex;
+00178                 f.serialPolyPtr(tex);
+00179                 _Tex = tex;
+00180                 if (_Tex != NULL)
+00181                 {
+00182                         f.serial(_UFactor, _VFactor) ;
+00183                 }
+00184 
+00185                 // shape serialization  
+00186                 f.serialCont(_Shape);
+00187                 
+00188                 
+00189                 _NbSegs = tailNbSegs >> 1;
+00190                 if (_NbSegs < 1) _NbSegs = 2;
+00191                 setInterpolationMode(Linear);
+00192 
+00193                 nlassert(_Owner);
+00194                 resize(_Owner->getMaxSize());
+00195                 initDateVect();         
+00196                 resetFromOwner();       
+00197         }       
+00198 
+00199 
+00200         if (ver >= 2)
+00201         {
+00202                 CPSRibbonBase::serial(f);
+00203                 CPSColoredParticle::serialColorScheme(f);
+00204                 CPSSizedParticle::serialSizeScheme(f);
+00205                 CPSMaterial::serialMaterial(f);
+00206                 f.serialCont(_Shape);
+00207                 bool colorFading = _ColorFading;
+00208                 f.serial(colorFading);  
+00209                 _ColorFading = colorFading;
+00210                 uint32 tailNbSegs = _NbSegs;
+00211                 f.serial(tailNbSegs);           
+00212                 if (f.isReading())
+00213                 {
+00214                         setTailNbSeg(_NbSegs);
+00215                         touch();
+00216                 }
+00217                 ITexture *tex = _Tex;
+00218                 f.serialPolyPtr(tex);
+00219                 _Tex = tex;
+00220                 if (_Tex != NULL)
+00221                 {
+00222                         f.serial(_UFactor, _VFactor) ;
+00223                 }
+00224         }
+00225 
+00226 }
+00227 
+00228 
+00229 //=======================================================       
+00230 CPSRibbon::CPSRibbon() : _UFactor(1.f),
+00231                                                  _VFactor(1.f),
+00232                                                  _ColorFading(true),
+00233                                                  _GlobalColor(false),
+00234                                                  _Touch(true)
+00235 {
+00236         setInterpolationMode(Linear);
+00237         setSegDuration(0.06f);
+00238         _Name = std::string("Ribbon");
+00239         setShape(Triangle, NbVerticesInTriangle);
+00240         _Mat.setDoubleSided(true);
+00241 }
+00242 
+00243 
+00244 //=======================================================       
+00245 CPSRibbon::~CPSRibbon()
+00246 {
+00247 }
+00248 
+00249 
+00250 //==========================================================================    
+00251 inline uint CPSRibbon::getNumVerticesInSlice() const
+00252 {
+00253         return _Shape.size() + (_Tex == NULL ? 0 : 1);
+00254 }
+00255 
+00256 
+00257 
+00258 
+00259 
+00260 //=======================================================       
+00261 void CPSRibbon::step(TPSProcessPass pass, TAnimationTime ellapsedTime, TAnimationTime realEt)
+00262 {       
+00263         if (pass == PSMotion)
+00264         {       
+00265                 if (!_Parametric)
+00266                 {
+00267                         updateGlobals();
+00268                 }
+00269         }
+00270         else
+00271         if (
+00272                 (pass == PSBlendRender && hasTransparentFaces())
+00273                 || (pass == PSSolidRender && hasOpaqueFaces())
+00274                 )
+00275         {
+00276                 uint32 step;
+00277                 uint   numToProcess;
+00278                 computeSrcStep(step, numToProcess);     
+00279                 if (!numToProcess) return;
+00280                 
+00282                 CParticleSystem &ps = *(_Owner->getOwner());    
+00283                 _Mat.setColor(ps.getGlobalColor());
+00284                 
+00289                 displayRibbons(numToProcess, step);
+00290 
+00291         }
+00292         else 
+00293         if (pass == PSToolRender) // edition mode only
+00294         {                       
+00295                 //showTool();
+00296         }       
+00297 }
+00298 
+00299 
+00300 //=======================================================       
+00301 void CPSRibbon::newElement(CPSLocated *emitterLocated, uint32 emitterIndex)
+00302 {
+00303         CPSRibbonBase::newElement(emitterLocated, emitterIndex);
+00304         newColorElement(emitterLocated, emitterIndex);
+00305         newSizeElement(emitterLocated, emitterIndex);
+00306 }
+00307 
+00308 
+00309 //=======================================================       
+00310 void CPSRibbon::deleteElement(uint32 index)
+00311 {
+00312         CPSRibbonBase::deleteElement(index);
+00313         deleteColorElement(index);      
+00314         deleteSizeElement(index);       
+00315 }
+00316 
+00317 
+00318 //=======================================================       
+00319 void CPSRibbon::resize(uint32 size)
+00320 {
+00321         nlassert(size < (1 << 16));
+00322         CPSRibbonBase::resize(size);    
+00323         resizeColor(size);
+00324         resizeSize(size);
+00325 }
+00326 
+00327 //=======================================================       
+00328 void CPSRibbon::updateMatAndVbForColor(void)
+00329 {
+00330         touch();
+00331 }
+00332 
+00333 
+00335 // Create the start slice of a ribbon (all vertices at the same pos)
+00336 static inline uint8 *BuildRibbonFirstSlice(const NLMISC::CVector &pos,
+00337                                                                                    uint  numVerts,
+00338                                                                                    uint8 *dest,
+00339                                                                                    uint  vertexSize
+00340                                                                               )
+00341 {       
+00342         do
+00343         {
+00344                 * (NLMISC::CVector *) dest = pos;
+00345                 dest += vertexSize;
+00346         }
+00347         while (--numVerts);
+00348         return dest;
+00349 }
+00350 
+00351 
+00353 // This compute one slice of a ribbon, and return the next vertex to be filled
+00354 static inline uint8 *ComputeRibbonSlice(const NLMISC::CVector &prev,
+00355                                                                             const NLMISC::CVector &next,                                                                         
+00356                                                                             const NLMISC::CVector *shape,
+00357                                                                             uint  numVerts,
+00358                                                                             uint8 *dest,
+00359                                                                             uint  vertexSize,
+00360                                                                                 float size
+00361                                                                            )
+00362 {       
+00363         // compute a basis from the next and previous position.
+00364         // (not optimized for now, but not widely used, either...)      
+00365         static NLMISC::CMatrix m;
+00366         m.setPos(next);
+00367         CPSUtil::buildSchmidtBasis(next - prev, m);
+00368         m.scale(size);
+00369         
+00370         const NLMISC::CVector *shapeEnd = shape + numVerts;
+00371         do
+00372         {
+00373                 *(NLMISC::CVector *) dest = m * (*shape);
+00374                 ++shape;
+00375                 dest += vertexSize;
+00376         }
+00377         while (shape != shapeEnd);
+00378         return dest;
+00379 }
+00380 
+00381 
+00382 
+00384 // This is used to compute a ribbon mesh from its curve and its base shape.
+00385 // This is for untextured versions (no need to duplicate the last vertex of each slice)
+00386 static inline uint8 *ComputeUntexturedRibbonMesh(uint8 *destVb,
+00387                                                                                              uint  vertexSize,
+00388                                                                                              const NLMISC::CVector *curve,
+00389                                                                                              const NLMISC::CVector *shape,
+00390                                                                                              uint  numSegs,
+00391                                                                                                  uint  numVerticesInShape,
+00392                                                                                                  float sizeIncrement,
+00393                                                                                                  float size
+00394                                                                                                 )
+00395 {                                       
+00396         do
+00397         {
+00398                 destVb = ComputeRibbonSlice(curve[1],
+00399                                                                     curve[0],
+00400                                                                         shape,
+00401                                                                         numVerticesInShape,
+00402                                                                         destVb,
+00403                                                                         vertexSize,
+00404                                                                         size);
+00405                 ++ curve;
+00406                 size -= sizeIncrement;
+00407         }
+00408         while (--numSegs);
+00409         return BuildRibbonFirstSlice(curve[0], numVerticesInShape, destVb, vertexSize);                 
+00410 }
+00411 
+00413 // This is used to compute a ribbon mesh from its curve and its base shape.
+00414 // (Textured Version)
+00415 static inline uint8 *ComputeTexturedRibbonMesh(uint8 *destVb,
+00416                                                                                            uint  vertexSize,
+00417                                                                                            const NLMISC::CVector *curve,
+00418                                                                                            const NLMISC::CVector *shape,
+00419                                                                                            uint  numSegs,
+00420                                                                                            uint  numVerticesInShape,
+00421                                                                                            float sizeIncrement,
+00422                                                                                            float size
+00423                                                                                           )
+00424 {       
+00425                         
+00426         do
+00427         {
+00428                 uint8 *nextDestVb = ComputeRibbonSlice(curve[1],
+00429                                                                                            curve[0],
+00430                                                                                            shape,
+00431                                                                                            numVerticesInShape,
+00432                                                                                            destVb,
+00433                                                                                            vertexSize,
+00434                                                                                            size
+00435                                                                                           );
+00436                 // duplicate last vertex ( equal first)
+00437                 * (NLMISC::CVector *) nextDestVb = * (NLMISC::CVector *) destVb;
+00438                 destVb = nextDestVb + vertexSize;
+00439                 //
+00440                 ++ curve;
+00441                 size -= sizeIncrement;
+00442         }
+00443         while (--numSegs);
+00444         return BuildRibbonFirstSlice(curve[0], numVerticesInShape + 1, destVb, vertexSize);     
+00445 }
+00446 
+00447 //==========================================================================    
+00448 void CPSRibbon::displayRibbons(uint32 nbRibbons, uint32 srcStep)
+00449 {       
+00450         if (!nbRibbons) return;
+00451         nlassert(_Owner);       
+00452         CPSRibbonBase::updateLOD();
+00453         if (_UsedNbSegs < 2) return;
+00454         const float date = _Owner->getOwner()->getSystemDate();
+00455         uint8                                           *currVert;
+00456         CVBnPB                                          &VBnPB = getVBnPB(); // get the appropriate vb (built it if needed)
+00457         CVertexBuffer                           &VB = VBnPB.VB;
+00458         CPrimitiveBlock                         &PB = VBnPB.PB;
+00459         const uint32                            vertexSize  = VB.getVertexSize();
+00460         uint                                            colorOffset=0;  
+00461         
+00462         IDriver *drv = this->getDriver();
+00463         setupDriverModelMatrix();
+00464         drv->activeVertexBuffer(VB);
+00465         _Owner->incrementNbDrawnParticles(nbRibbons); // for benchmark purpose          
+00466         const uint numRibbonBatch = getNumRibbonsInVB(); // number of ribons to process at once         
+00467         if (_UsedNbSegs == 0) return;   
+00469         // Material setup //
+00471                 CParticleSystem &ps = *(_Owner->getOwner());
+00472                 bool useGlobalColor = ps.getColorAttenuationScheme() != NULL;
+00473                 if (useGlobalColor != _GlobalColor)
+00474                 {
+00475                         touch();
+00476                 }
+00477                 updateMaterial();
+00478                 setupGlobalColor();
+00479                 //
+00480                 if (_ColorScheme)
+00481                 {
+00482                         colorOffset = VB.getColorOff(); 
+00483                 }       
+00485         // Compute ribbons //
+00487                 const uint numVerticesInSlice = getNumVerticesInSlice();
+00488                 const uint numVerticesInShape = _Shape.size();
+00489                 //
+00490                 static std::vector<float> sizes;
+00491                 static std::vector<NLMISC::CVector> ribbonPos;  // this is where the position of each ribbon slice center i stored
+00492                 ribbonPos.resize(_UsedNbSegs + 1); // make sure we have enough room
+00493                 sizes.resize(numRibbonBatch);
+00494                 
+00495                 //
+00496                 uint toProcess;
+00497                 uint ribbonIndex = 0; // index of the first ribbon in the batch being processed 
+00498                 uint32 fpRibbonIndex = 0; // fixed point index in source
+00499                 do
+00500                 {
+00501                         toProcess = std::min((uint) (nbRibbons - ribbonIndex) , numRibbonBatch);
+00502                         currVert = (uint8 *) VB.getVertexCoordPointer();
+00503                                 
+00505                         const float     *ptCurrSize;
+00506                         uint32  ptCurrSizeIncrement;
+00507                         if (_SizeScheme)
+00508                         {                       
+00509                                 ptCurrSize = (float *) _SizeScheme->make(this->_Owner, ribbonIndex, &sizes[0], sizeof(float), toProcess, true, srcStep);                        
+00510                                 ptCurrSizeIncrement = 1;
+00511                         }
+00512                         else
+00513                         {
+00514                                 ptCurrSize = &_ParticleSize;
+00515                                 ptCurrSizeIncrement = 0;
+00516                         }
+00517 
+00519                         if (_ColorScheme)
+00520                         {                       
+00521                                 _ColorScheme->makeN(this->_Owner, ribbonIndex, currVert + colorOffset, vertexSize, toProcess, numVerticesInSlice * (_UsedNbSegs + 1), srcStep);                 
+00522                         }                       
+00523                         uint k = toProcess;     
+00525                         // interpolate and project points the result is directly setup in the vertex buffer //
+00527                         if (!_Parametric)
+00528                         {
+00530                                 // INCREMENTAL CASE //
+00532                                 if (_Tex != NULL) // textured case
+00533                                 {
+00534                                         do
+00535                                         {
+00536                                                 const float ribbonSizeIncrement = *ptCurrSize / (float) _UsedNbSegs;
+00537                                                 ptCurrSize += ptCurrSizeIncrement;
+00538                                                 // the parent class has a method to get the ribbons positions
+00539                                                 computeRibbon((uint) (fpRibbonIndex >> 16), &ribbonPos[0], sizeof(NLMISC::CVector));
+00540                                                 currVert = ComputeTexturedRibbonMesh(currVert,
+00541                                                                                                                          vertexSize,
+00542                                                                                                                          &ribbonPos[0],
+00543                                                                                                                          &_Shape[0],
+00544                                                                                                                          _UsedNbSegs,
+00545                                                                                                                          numVerticesInShape,
+00546                                                                                                                          ribbonSizeIncrement,
+00547                                                                                                                          *ptCurrSize
+00548                                                                                                                         );
+00549                                                 fpRibbonIndex += srcStep;
+00550                                         }
+00551                                         while (--k);
+00552                                 }
+00553                                 else // untextured case
+00554                                 {
+00555                                         do
+00556                                         {
+00557                                                 const float ribbonSizeIncrement = *ptCurrSize / (float) _UsedNbSegs;
+00558                                                 ptCurrSize += ptCurrSizeIncrement;
+00559                                                 // the parent class has a method to get the ribbons positions
+00560                                                 computeRibbon((uint) (fpRibbonIndex >> 16), &ribbonPos[0], sizeof(NLMISC::CVector));
+00561                                                 currVert = ComputeUntexturedRibbonMesh(currVert,
+00562                                                                                                                            vertexSize,
+00563                                                                                                                            &ribbonPos[0],
+00564                                                                                                                            &_Shape[0],
+00565                                                                                                                            _UsedNbSegs,
+00566                                                                                                                            numVerticesInShape,
+00567                                                                                                                            ribbonSizeIncrement,
+00568                                                                                                                            *ptCurrSize
+00569                                                                                                                           );
+00570                                                 fpRibbonIndex += srcStep;
+00571                                         }
+00572                                         while (--k);    
+00573                                 }
+00574                         }
+00575                         else
+00576                         {
+00578                                 // PARAMETRIC  CASE //
+00580                                 if (_Tex != NULL) // textured case
+00581                                 {
+00582                                         do
+00583                                         {
+00584                                                 const float ribbonSizeIncrement = *ptCurrSize / (float) _UsedNbSegs;
+00585                                                 ptCurrSize += ptCurrSizeIncrement;
+00586                                                 _Owner->integrateSingle(date - _UsedSegDuration * (_UsedNbSegs + 1),
+00587                                                                                                 _UsedSegDuration,
+00588                                                                                                 _UsedNbSegs + 1,
+00589                                                                                                 (uint) (fpRibbonIndex >> 16),
+00590                                                                                                 &ribbonPos[0]);
+00591 
+00592                                                 currVert = ComputeTexturedRibbonMesh(currVert,
+00593                                                                                                                          vertexSize,
+00594                                                                                                                          &ribbonPos[0],
+00595                                                                                                                          &_Shape[0],
+00596                                                                                                                          _UsedNbSegs,
+00597                                                                                                                          numVerticesInShape,
+00598                                                                                                                          ribbonSizeIncrement,
+00599                                                                                                                          *ptCurrSize
+00600                                                                                                                     );
+00601                                                 fpRibbonIndex += srcStep;
+00602                                         }
+00603                                         while (--k);
+00604                                 }
+00605                                 else // untextured case
+00606                                 {
+00607                                         do
+00608                                         {
+00609                                                 const float ribbonSizeIncrement = *ptCurrSize / (float) _UsedNbSegs;
+00610                                                 ptCurrSize += ptCurrSizeIncrement;
+00611                                                 _Owner->integrateSingle(date - _UsedSegDuration * (_UsedNbSegs + 1),
+00612                                                                                                 _UsedSegDuration,
+00613                                                                                                 _UsedNbSegs + 1,
+00614                                                                                                 (uint) (fpRibbonIndex >> 16),
+00615                                                                                                 &ribbonPos[0]);
+00616 
+00617                                                 currVert = ComputeUntexturedRibbonMesh(currVert,
+00618                                                                                                                            vertexSize,
+00619                                                                                                                            &ribbonPos[0],
+00620                                                                                                                            &_Shape[0],
+00621                                                                                                                            _UsedNbSegs,
+00622                                                                                                                            numVerticesInShape,
+00623                                                                                                                            ribbonSizeIncrement,
+00624                                                                                                                            *ptCurrSize
+00625                                                                                                                           );                            
+00626                                                 fpRibbonIndex += srcStep;
+00627                                         }
+00628                                         while (--k);
+00629                                 }                                                       
+00630                         }                       
+00631                         // display the result
+00632                         PB.setNumTri((numVerticesInShape * _UsedNbSegs * toProcess) << 1);                      
+00633                         drv->render(PB, _Mat);
+00634                         ribbonIndex += toProcess;               
+00635                 }
+00636                 while (ribbonIndex != nbRibbons);
+00637                 
+00638 }       
+00639 
+00640 //==========================================================================    
+00641 bool CPSRibbon::hasTransparentFaces(void)
+00642 {
+00643         return getBlendingMode() != CPSMaterial::alphaTest ;
+00644 }
+00645 
+00646 
+00647 //==========================================================================    
+00648 bool CPSRibbon::hasOpaqueFaces(void)
+00649 {
+00650         return !hasTransparentFaces();
+00651 }
+00652 
+00653 //==========================================================================    
+00654 uint32 CPSRibbon::getMaxNumFaces(void) const
+00655 {
+00656         nlassert(_Owner);
+00657         return _Owner->getMaxSize() * _NbSegs;  
+00658 }
+00659 
+00660 //==========================================================================    
+00661 CPSRibbon::CVBnPB &CPSRibbon::getVBnPB()
+00662 {
+00663         static TVBMap * const vbMaps[] =
+00664         {
+00666                 &_VBMap,                
+00667                 &_FadedVBMap,        
+00668                 &_ColoredVBMap,  
+00669                 &_FadedColoredVBMap,
+00671                 &_TexVBMap,             
+00672                 &_TexFadedVBMap,             
+00673                 &_TexColoredVBMap,  
+00674                 &_TexFadedColoredVBMap
+00675         };
+00676 
+00678         TVBMap &map = *vbMaps[ (_Tex != NULL                     ? (1 << 2) : 0)  | // set bit 2 if textured
+00679                                                    (_ColorScheme != NULL  ? (1 << 1) : 0)  | // set bit 1 if per ribbon color
+00680                                                    (_ColorFading                         ? 1 : 0)                  // set bit 0 if color fading
+00681                                                  ];
+00682 
+00683         const uint numVerticesInSlice = getNumVerticesInSlice(); 
+00684         const uint numVerticesInShape = _Shape.size();
+00685 
+00686 
+00687         // The number of slice is encoded in the upper word of the vb index
+00688         // The number of vertices per slices is encoded in the lower word
+00689         uint VBnPDIndex = ((_UsedNbSegs + 1) << 16) | numVerticesInSlice;
+00690         TVBMap::iterator it = map.find(VBnPDIndex);
+00691         if (it != map.end())
+00692         {
+00693                 return it->second;
+00694         }
+00695         else    // must create this vb, with few different size, it is still interseting, though they are only destroyed at exit
+00696         {
+00697                 const uint numRibbonInVB = getNumRibbonsInVB();
+00698                 CVBnPB &VBnPB = map[VBnPDIndex]; // make an entry
+00699 
+00703                 CVertexBuffer &vb = VBnPB.VB;
+00704                 vb.setVertexFormat(CVertexBuffer::PositionFlag  | /* alway need position */
+00705                                                    (_ColorScheme || _ColorFading ? CVertexBuffer::PrimaryColorFlag : 0) | /* need a color ? */
+00706                                                    ((_ColorScheme && _ColorFading) ||  _Tex != NULL ? CVertexBuffer::TexCoord0Flag : 0) | /* need texture coordinates ? */
+00707                                                    (_Tex != NULL && _ColorScheme && _ColorFading ? CVertexBuffer::TexCoord1Flag : 0) /* need 2nd texture coordinates ? */
+00708                                                   );
+00709                 vb.setNumVertices((_UsedNbSegs + 1) * numRibbonInVB * numVerticesInSlice); // 1 seg = 1 line + terminal vertices
+00710 
+00711                 // set the primitive block size
+00712                 CPrimitiveBlock &pb = VBnPB.PB;
+00713                 pb.setNumTri((_UsedNbSegs * numRibbonInVB * _Shape.size()) << 1);
+00715                 uint vbIndex = 0;
+00716                 uint pbIndex = 0; 
+00717                 uint i, k, l;
+00718                 for (i = 0; i < numRibbonInVB; ++i)
+00719                 {
+00720                         for (k = 0; k < (_UsedNbSegs + 1); ++k)
+00721                         {
+00722 
+00724                                 if (k != _UsedNbSegs) 
+00725                                 {       
+00726                                         uint vIndex = vbIndex;
+00727                                         for (l = 0; l < (numVerticesInShape - 1); ++l) 
+00728                                         {                                                                                                                                                       
+00729                                                 pb.setTri(pbIndex ++, vIndex, vIndex + numVerticesInSlice, vIndex + numVerticesInSlice + 1);
+00730                                                 pb.setTri(pbIndex ++, vIndex, vIndex + numVerticesInSlice + 1, vIndex + 1);
+00731                                                 ++ vIndex;
+00732                                         }       
+00733                                         
+00735                                         uint nextVertexIndex = (numVerticesInShape == numVerticesInSlice) ?     vIndex + 1 - numVerticesInShape // no texture -> we loop 
+00736                                                                                    : vIndex + 1; // a texture is used : use onemore vertex                                                                              
+00737                                         pb.setTri(pbIndex ++, vIndex, vIndex + numVerticesInSlice, nextVertexIndex + numVerticesInSlice);
+00738                                         pb.setTri(pbIndex ++, vIndex, nextVertexIndex + numVerticesInSlice, nextVertexIndex);
+00739 
+00740                                 }
+00741 
+00743                                 for (l = 0; l < numVerticesInSlice; ++l) 
+00744                                 {
+00745                                         nlassert(vbIndex < vb.getNumVertices());
+00747                                         if (_Tex != NULL)
+00748                                         {                                               
+00749                                                 vb.setTexCoord(vbIndex,
+00750                                                                            _ColorScheme && _ColorFading ? 1 : 0,                // must we use the second texture coord ? (when 1st one used by the gradient texture : we can't encode it in the diffuse as it encodes each ribbon color)
+00751                                                                            (float) k / _UsedNbSegs,                               // u
+00752                                                                            1.f - (l / (float) numVerticesInShape) // v
+00753                                                                           );                                            
+00754                                         }
+00755 
+00757                                         if (_ColorFading)
+00758                                         {
+00759                                                 // If not per ribbon color, we can encode it in the diffuse
+00760                                                 if (_ColorScheme == NULL)
+00761                                                 {
+00762                                                         uint8 intensity = (uint8) (255 * (1.f - ((float) k / _UsedNbSegs)));
+00763                                                         NLMISC::CRGBA col(intensity, intensity, intensity, intensity);
+00764                                                         vb.setColor(vbIndex, col);                                              
+00765                                                 }
+00766                                                 else // encode it in the first texture
+00767                                                 {
+00768                                                         vb.setTexCoord(vbIndex, 0, 0.5f - 0.5f * ((float) k / _UsedNbSegs), 0);
+00769                                                 }
+00770                                         }
+00771                                         ++ vbIndex;
+00772                                 }
+00773                                 
+00774                         }
+00775                 }
+00776                 return VBnPB;
+00777         }
+00778 }
+00779 
+00780 //==========================================================================    
+00781 uint    CPSRibbon::getNumRibbonsInVB() const
+00782 {
+00783         const uint numVerticesInSlice = getNumVerticesInSlice(); 
+00784         const uint vertexInVB = 512;    
+00785         return std::max(1u, (uint) (vertexInVB / (numVerticesInSlice * (_UsedNbSegs + 1))));
+00786 }
+00787 
+00788 
+00789 //==========================================================================    
+00790 inline void     CPSRibbon::updateUntexturedMaterial()
+00791 {
+00793         // UNTEXTURED RIBBON //
+00795 
+00796         static NLMISC::CRefPtr<ITexture> ptGradTexture;
+00797 
+00798         CParticleSystem &ps = *(_Owner->getOwner());
+00799         if (_ColorScheme)
+00800         {       // PER RIBBON COLOR
+00801                 if (ps.getColorAttenuationScheme())
+00802                 {
+00803                         if (_ColorFading) // global color + fading + per ribbon color
+00804                         {
+00805                                 // the first stage is used to get fading * global color
+00806                                 // the second stage multiply the result by the diffuse colot
+00807                                 if (ptGradTexture == NULL) // have we got a gradient texture ?
+00808                                 {
+00809                                         ptGradTexture = CreateGradientTexture();
+00810                                 }
+00811                                 _Mat.setTexture(0, ptGradTexture);
+00812                                 CPSMaterial::forceTexturedMaterialStages(2); // use constant color 0 * diffuse, 1 stage needed
+00813                                 SetupModulatedStage(_Mat, 0, CMaterial::Texture, CMaterial::Constant);
+00814                                 SetupModulatedStage(_Mat, 1, CMaterial::Previous, CMaterial::Diffuse);
+00815                         }
+00816                         else // per ribbon color with global color 
+00817                         {
+00818                                 CPSMaterial::forceTexturedMaterialStages(1); // use constant color 0 * diffuse, 1 stage needed
+00819                                 SetupModulatedStage(_Mat, 0, CMaterial::Diffuse, CMaterial::Constant);
+00820                         }
+00821                 }
+00822                 else
+00823                 {       
+00824                         if (_ColorFading) // per ribbon color, no fading
+00825                         {                               
+00826                                 if (ptGradTexture == NULL) // have we got a gradient texture ?
+00827                                 {
+00828                                         ptGradTexture = CreateGradientTexture();
+00829                                 }
+00830                                 _Mat.setTexture(0, ptGradTexture);
+00831                                 CPSMaterial::forceTexturedMaterialStages(1);
+00832                                 SetupModulatedStage(_Mat, 0, CMaterial::Texture, CMaterial::Diffuse);
+00833                         }
+00834                         else // per color ribbon with no fading, and no global color
+00835                         {
+00836                                 CPSMaterial::forceTexturedMaterialStages(0); // no texture use constant diffuse only
+00837                         }
+00838                 }
+00839         }
+00840         else // GLOBAL COLOR
+00841         {               
+00842                 if (_ColorFading)
+00843                 {                                                               
+00844                         CPSMaterial::forceTexturedMaterialStages(1); // use constant color 0 * diffuse, 1 stage needed                          
+00845                         SetupModulatedStage(_Mat, 0, CMaterial::Diffuse, CMaterial::Constant);
+00846                 }
+00847                 else // color attenuation, no fading : 
+00848                 {
+00849                         CPSMaterial::forceTexturedMaterialStages(0); // no texture use constant diffuse only                            
+00850                 }               
+00851         }
+00852         _Touch = false;
+00853 }
+00854 
+00855 //==========================================================================    
+00856 inline void     CPSRibbon::updateTexturedMaterial()
+00857 {
+00859         // TEXTURED RIBBON //
+00861 
+00862         static NLMISC::CRefPtr<ITexture> ptGradTexture;
+00863         CParticleSystem &ps = *(_Owner->getOwner());
+00864         if (_ColorScheme)
+00865         {       // PER RIBBON COLOR
+00866                 if (ps.getColorAttenuationScheme())
+00867                 {
+00868                         if (_ColorFading) // global color + fading + per ribbon color
+00869                         {                               
+00870                                 if (ptGradTexture == NULL) // have we got a gradient texture ?
+00871                                 {
+00872                                         ptGradTexture = CreateGradientTexture(); // create it
+00873                                 }
+00875                                 _Mat.setTexture(0, ptGradTexture);
+00876                                 _Mat.setTexture(1, _Tex);
+00877                                 CPSMaterial::forceTexturedMaterialStages(3); // use constant color 0 * diffuse, 1 stage needed                          
+00878                                 SetupModulatedStage(_Mat, 0, CMaterial::Texture, CMaterial::Diffuse);
+00879                                 SetupModulatedStage(_Mat, 1, CMaterial::Texture, CMaterial::Previous);
+00880                                 SetupModulatedStage(_Mat, 2, CMaterial::Previous, CMaterial::Constant);                         
+00881                         }
+00882                         else // per ribbon color with global color 
+00883                         {
+00884                                 _Mat.setTexture(0, _Tex);
+00885                                 CPSMaterial::forceTexturedMaterialStages(2); // use constant color 0 * diffuse, 1 stage needed                          
+00886                                 SetupModulatedStage(_Mat, 0, CMaterial::Texture, CMaterial::Diffuse);
+00887                                 SetupModulatedStage(_Mat, 1, CMaterial::Previous, CMaterial::Constant);                 
+00888                         }
+00889                 }
+00890                 else
+00891                 {       
+00892                         if (_ColorFading) // per ribbon color, fading : 2 textures needed
+00893                         {                               
+00894                                 if (ptGradTexture == NULL) // have we got a gradient texture ?
+00895                                 {
+00896                                         ptGradTexture = CreateGradientTexture(); // create it
+00897                                 }
+00898                                 _Mat.setTexture(0, ptGradTexture);
+00899                                 _Mat.setTexture(1, _Tex);
+00900                                 CPSMaterial::forceTexturedMaterialStages(2); 
+00901                                 SetupModulatedStage(_Mat, 0, CMaterial::Texture, CMaterial::Diffuse); // texture * ribbon color
+00902                                 SetupModulatedStage(_Mat, 1, CMaterial::Texture, CMaterial::Previous);  // * gradient
+00903                         }
+00904                         else // per color ribbon with no fading, and no global color
+00905                         {
+00906                                 _Mat.setTexture(0, _Tex);
+00907                                 CPSMaterial::forceTexturedMaterialStages(1); // no texture use constant diffuse only
+00908                                 SetupModulatedStage(_Mat, 0, CMaterial::Texture, CMaterial::Diffuse);                           
+00909                         }
+00910                 }
+00911         }
+00912         else // GLOBAL COLOR
+00913         {
+00914                 
+00915                 if (_ColorFading) // gradient is encoded in diffuse
+00916                 {
+00917                         _Mat.setTexture(0, _Tex);
+00918                         CPSMaterial::forceTexturedMaterialStages(2); // use constant color 0 * diffuse, 1 stage needed                          
+00919                         SetupModulatedStage(_Mat, 0, CMaterial::Texture, CMaterial::Diffuse);
+00920                         SetupModulatedStage(_Mat, 1, CMaterial::Previous, CMaterial::Constant);                 
+00921                 }
+00922                 else // constant color
+00923                 {
+00924                         _Mat.setTexture(0, _Tex);
+00925                         CPSMaterial::forceTexturedMaterialStages(1); // no texture use constant diffuse only                                                    
+00926                         SetupModulatedStage(_Mat, 0, CMaterial::Texture, CMaterial::Diffuse);   
+00927                 }               
+00928         }
+00929         _Touch = false;
+00930 }
+00931 
+00932 //==========================================================================    
+00933 void    CPSRibbon::updateMaterial()
+00934 {
+00935         if (!_Touch) return;
+00936         if (_Tex != NULL) 
+00937         {
+00938                 updateTexturedMaterial();
+00939                 setupTextureMatrix();
+00940         }
+00941         else
+00942         {
+00943                 updateUntexturedMaterial();
+00944         }
+00945 }
+00946 
+00947 
+00948 
+00949 //==========================================================================    
+00950 inline void     CPSRibbon::setupUntexturedGlobalColor()
+00951 {       
+00953         CParticleSystem &ps = *(_Owner->getOwner());    
+00954         if (_ColorScheme)
+00955         {       
+00956                 _Mat.texConstantColor(0, ps.getGlobalColor());                                  
+00957         }
+00958         else // GLOBAL COLOR with / without fading
+00959         {
+00960                 if (ps.getColorAttenuationScheme())
+00961                 {                       
+00962                         NLMISC::CRGBA col;
+00963                         col.modulateFromColor(ps.getGlobalColor(), _Color);
+00964                         if (_ColorFading)
+00965                         {                                                               
+00966                                 _Mat.texConstantColor(0, col);                          
+00967                         }
+00968                         else // color attenuation, no fading : 
+00969                         {                                                       
+00970                                 _Mat.setColor(col);
+00971                         }
+00972                 }
+00973                 else
+00974                 {
+00975                         if (_ColorFading)
+00976                         {
+00977                                 _Mat.texConstantColor(0, _Color);                               
+00978                         }
+00979                         else // constant color
+00980                         {
+00981                                 _Mat.setColor(_Color);
+00982                         }
+00983                 }
+00984         }
+00985 }
+00986 
+00987 //==========================================================================    
+00988 inline void     CPSRibbon::setupTexturedGlobalColor()
+00989 {       
+00991         CParticleSystem &ps = *(_Owner->getOwner());    
+00992         if (_ColorScheme)
+00993         {       
+00994                 if (ps.getColorAttenuationScheme() && _ColorFading)
+00995                 {
+00996                         _Mat.texConstantColor(2, ps.getGlobalColor());
+00997                 }
+00998                 else
+00999                 {
+01000                         _Mat.texConstantColor(1, ps.getGlobalColor());
+01001                 }                               
+01002         }
+01003         else // GLOBAL COLOR with / without fading
+01004         {
+01005                 if (ps.getColorAttenuationScheme())
+01006                 {                       
+01007                         NLMISC::CRGBA col;
+01008                         col.modulateFromColor(ps.getGlobalColor(), _Color);
+01009                         if (_ColorFading)
+01010                         {                                                               
+01011                                 _Mat.texConstantColor(1, col);                          
+01012                         }
+01013                         else // color attenuation, no fading : 
+01014                         {                                                       
+01015                                 _Mat.setColor(col);
+01016                         }
+01017                 }
+01018                 else
+01019                 {
+01020                         if (_ColorFading)
+01021                         {
+01022                                 _Mat.texConstantColor(1, _Color);                               
+01023                         }
+01024                         else // constant color
+01025                         {
+01026                                 _Mat.setColor(_Color);
+01027                         }
+01028                 }
+01029         }
+01030 }
+01031 
+01032 
+01033 //==========================================================================    
+01034 void    CPSRibbon::setupGlobalColor()
+01035 {
+01036         if (_Tex != NULL) setupTexturedGlobalColor();
+01037                 else setupUntexturedGlobalColor();
+01038 }
+01039 
+01040 //==========================================================================    
+01041 void CPSRibbon::setupTextureMatrix()
+01042 {
+01043         uint stage = (_ColorScheme != NULL && _ColorFading == true) ? 1 : 0;    
+01044         if (_UFactor != 1.f || _VFactor != 1.f)
+01045         {
+01046                 _Mat.enableUserTexMat(stage);
+01047                 CMatrix texMat;
+01048                 texMat.setRot(_UFactor  * NLMISC::CVector::I,
+01049                                           _VFactor  * NLMISC::CVector::J,
+01050                                           NLMISC::CVector::K
+01051                                          );
+01052                 _Mat.setUserTexMat(stage, texMat);
+01053         }
+01054         else
+01055         {
+01056                 _Mat.enableUserTexMat(stage, false);
+01057         }
+01058         _Mat.enableUserTexMat(1 - stage, false);
+01059 }
+01060 
+01061 //==========================================================================    
+01063 void CPSRibbon::setShape(const CVector *shape, uint32 nbPointsInShape)
+01064 {
+01065         nlassert(nbPointsInShape >= 3);         
+01066         _Shape.resize(nbPointsInShape);
+01067         std::copy(shape, shape + nbPointsInShape, _Shape.begin());      
+01068 }
+01069 
+01071 void CPSRibbon::getShape(CVector *shape) const
+01072 {
+01073         std::copy(_Shape.begin(), _Shape.end(), shape);
+01074 }
+01075 
+01076 
+01077 
+01078 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1