From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- .../nel/lod__character__manager_8cpp-source.html | 926 +++++++++++++++++++++ 1 file changed, 926 insertions(+) create mode 100644 docs/doxygen/nel/lod__character__manager_8cpp-source.html (limited to 'docs/doxygen/nel/lod__character__manager_8cpp-source.html') diff --git a/docs/doxygen/nel/lod__character__manager_8cpp-source.html b/docs/doxygen/nel/lod__character__manager_8cpp-source.html new file mode 100644 index 00000000..65ac3401 --- /dev/null +++ b/docs/doxygen/nel/lod__character__manager_8cpp-source.html @@ -0,0 +1,926 @@ + + + + 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  
+

lod_character_manager.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2000-2002 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 "nel/misc/common.h"
+00029 #include "3d/lod_character_manager.h"
+00030 #include "3d/lod_character_shape.h"
+00031 #include "3d/lod_character_shape_bank.h"
+00032 #include "3d/lod_character_instance.h"
+00033 #include "nel/misc/hierarchical_timer.h"
+00034 #include "3d/fast_floor.h"
+00035 #include "3d/lod_character_texture.h"
+00036 #include "nel/misc/file.h"
+00037 
+00038 
+00039 using   namespace std;
+00040 using   namespace NLMISC;
+00041 
+00042 namespace NL3D 
+00043 {
+00044 
+00045 
+00046 H_AUTO_DECL ( NL3D_CharacterLod_Render )
+00047 
+00048 
+00049 // ***************************************************************************
+00050 // Dest is without Normal because precomputed
+00051 #define NL3D_CLOD_VERTEX_FORMAT (CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag | CVertexBuffer::PrimaryColorFlag)
+00052 #define NL3D_CLOD_VERTEX_SIZE   24
+00053 #define NL3D_CLOD_UV_OFF                12
+00054 #define NL3D_CLOD_COLOR_OFF             20
+00055 
+00056 // size (in block) of the big texture.
+00057 #define NL3D_CLOD_TEXT_NLOD_WIDTH       16
+00058 #define NL3D_CLOD_TEXT_NLOD_HEIGHT      16
+00059 #define NL3D_CLOD_TEXT_NUM_IDS          NL3D_CLOD_TEXT_NLOD_WIDTH*NL3D_CLOD_TEXT_NLOD_HEIGHT
+00060 #define NL3D_CLOD_BIGTEXT_WIDTH         NL3D_CLOD_TEXT_NLOD_WIDTH*NL3D_CLOD_TEXT_WIDTH
+00061 #define NL3D_CLOD_BIGTEXT_HEIGHT        NL3D_CLOD_TEXT_NLOD_HEIGHT*NL3D_CLOD_TEXT_HEIGHT
+00062 
+00063 // Default texture color. Alpha must be 255
+00064 #define NL3D_CLOD_DEFAULT_TEXCOLOR      CRGBA(255,255,255,255)
+00065 
+00066 
+00067 // ***************************************************************************
+00068 CLodCharacterManager::CLodCharacterManager()
+00069 {
+00070         _Driver= NULL;
+00071         _MaxNumVertices= 3000;
+00072         _Rendering= false;
+00073 
+00074         // Setup the format of render
+00075         _VBuffer.setVertexFormat(NL3D_CLOD_VERTEX_FORMAT);
+00076 
+00077         // NB: addRenderCharacterKey() loop hardCoded for Vertex+UV+Normal+Color only.
+00078         nlassert( NL3D_CLOD_UV_OFF == _VBuffer.getTexCoordOff());
+00079         nlassert( NL3D_CLOD_COLOR_OFF == _VBuffer.getColorOff());
+00080 
+00081         // setup the texture.
+00082         _BigTexture= new CTextureBlank;
+00083         // The texture always reside in memory... This take 1Mo of RAM. (16*32*16*32 * 4)
+00084         // NB: this is simplier like that, and this is not a problem, since only 1 or 2 Mo are allocated :o)
+00085         _BigTexture->setReleasable(false);
+00086         // create the bitmap.
+00087         _BigTexture->resize(NL3D_CLOD_BIGTEXT_WIDTH, NL3D_CLOD_BIGTEXT_HEIGHT, CBitmap::RGBA);
+00088         // Format of texture, 16 bits and no mipmaps.
+00089         _BigTexture->setUploadFormat(ITexture::RGB565);
+00090         _BigTexture->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff);
+00091         _BigTexture->setWrapS(ITexture::Clamp);
+00092         _BigTexture->setWrapT(ITexture::Clamp);
+00093 
+00094         // Alloc free Ids
+00095         _FreeIds.resize(NL3D_CLOD_TEXT_NUM_IDS);
+00096         for(uint i=0;i<_FreeIds.size();i++)
+00097         {
+00098                 _FreeIds[i]= i;
+00099         }
+00100 
+00101         // setup the material
+00102         _Material.initUnlit();
+00103         _Material.setAlphaTest(true);
+00104         _Material.setDoubleSided(true);
+00105         _Material.setTexture(0, _BigTexture);
+00106 
+00107         // setup for lighting, Default for Ryzom setup
+00108         _LightCorrectionMatrix.rotateZ((float)Pi/2);
+00109         _LightCorrectionMatrix.invert();
+00110 }
+00111 
+00112 
+00113 // ***************************************************************************
+00114 CLodCharacterManager::~CLodCharacterManager()
+00115 {
+00116         reset();
+00117 }
+00118 
+00119 // ***************************************************************************
+00120 void                    CLodCharacterManager::reset()
+00121 {
+00122         // delete shapeBanks.
+00123         for(uint i=0;i<_ShapeBankArray.size();i++)
+00124         {
+00125                 if(_ShapeBankArray[i])
+00126                         delete _ShapeBankArray[i];
+00127         }
+00128 
+00129         // clears containers
+00130         contReset(_ShapeBankArray);
+00131         contReset(_ShapeMap);
+00132 
+00133         // reset render part.
+00134         deleteVertexBuffer();
+00135         _Driver= NULL;
+00136 }
+00137 
+00138 // ***************************************************************************
+00139 uint32                  CLodCharacterManager::createShapeBank()
+00140 {
+00141         // search a free entry
+00142         for(uint i=0;i<_ShapeBankArray.size();i++)
+00143         {
+00144                 // if ree, use it.
+00145                 if(_ShapeBankArray[i]==NULL)
+00146                 {
+00147                         _ShapeBankArray[i]= new CLodCharacterShapeBank;
+00148                         return i;
+00149                 }
+00150         }
+00151 
+00152         // no free entrey, resize array.
+00153         _ShapeBankArray.push_back(new CLodCharacterShapeBank);
+00154         return _ShapeBankArray.size()-1;
+00155 }
+00156 
+00157 // ***************************************************************************
+00158 const CLodCharacterShapeBank    *CLodCharacterManager::getShapeBank(uint32 bankId) const
+00159 {
+00160         if(bankId>=_ShapeBankArray.size())
+00161                 return NULL;
+00162         else
+00163                 return _ShapeBankArray[bankId];
+00164 }
+00165 
+00166 // ***************************************************************************
+00167 CLodCharacterShapeBank  *CLodCharacterManager::getShapeBank(uint32 bankId)
+00168 {
+00169         if(bankId>=_ShapeBankArray.size())
+00170                 return NULL;
+00171         else
+00172                 return _ShapeBankArray[bankId];
+00173 }
+00174 
+00175 // ***************************************************************************
+00176 void                    CLodCharacterManager::deleteShapeBank(uint32 bankId)
+00177 {
+00178         if(bankId>=_ShapeBankArray.size())
+00179         {
+00180                 if(_ShapeBankArray[bankId])
+00181                 {
+00182                         delete _ShapeBankArray[bankId];
+00183                         _ShapeBankArray[bankId]= NULL;
+00184                 }
+00185         }
+00186 }
+00187 
+00188 // ***************************************************************************
+00189 sint32                  CLodCharacterManager::getShapeIdByName(const std::string &name) const
+00190 {
+00191         CstItStrIdMap   it= _ShapeMap.find(name);
+00192         if(it==_ShapeMap.end())
+00193                 return -1;
+00194         else
+00195                 return it->second;
+00196 }
+00197 
+00198 // ***************************************************************************
+00199 const CLodCharacterShape        *CLodCharacterManager::getShape(uint32 shapeId) const
+00200 {
+00201         // split the id
+00202         uint    bankId= shapeId >> 16;
+00203         uint    shapeInBankId= shapeId &0xFFFF;
+00204 
+00205         // if valid bankId
+00206         const CLodCharacterShapeBank    *shapeBank= getShapeBank(bankId);
+00207         if(shapeBank)
+00208         {
+00209                 // return the shape from the bank
+00210                 return shapeBank->getShape(shapeInBankId);
+00211         }
+00212         else
+00213                 return NULL;
+00214 }
+00215 
+00216 // ***************************************************************************
+00217 bool                    CLodCharacterManager::compile()
+00218 {
+00219         bool    error= false;
+00220 
+00221         // clear the map
+00222         contReset(_ShapeMap);
+00223 
+00224         // build the map
+00225         for(uint i=0; i<_ShapeBankArray.size(); i++)
+00226         {
+00227                 if(_ShapeBankArray[i])
+00228                 {
+00229                         // Parse all Shapes
+00230                         for(uint j=0; j<_ShapeBankArray[i]->getNumShapes(); j++)
+00231                         {
+00232                                 // build the shape Id
+00233                                 uint    shapeId= (i<<16) + j;
+00234 
+00235                                 // get the shape
+00236                                 const CLodCharacterShape        *shape= _ShapeBankArray[i]->getShape(j);
+00237                                 if(shape)
+00238                                 {
+00239                                         const string &name= shape->getName();
+00240                                         ItStrIdMap      it= _ShapeMap.find(name);
+00241                                         if(it == _ShapeMap.end())
+00242                                                 // insert the id in the map
+00243                                                 _ShapeMap.insert(make_pair(name, shapeId));
+00244                                         else
+00245                                         {
+00246                                                 error= true;
+00247                                                 nlwarning("Found a Character Lod with same name in the manager: %s", name.c_str());
+00248                                         }
+00249                                 }
+00250                         }
+00251                 }
+00252         }
+00253 
+00254         return error;
+00255 }
+00256 
+00257 // ***************************************************************************
+00258 // ***************************************************************************
+00259 // Render
+00260 // ***************************************************************************
+00261 // ***************************************************************************
+00262 
+00263 
+00264 // ***************************************************************************
+00265 void                    CLodCharacterManager::setMaxVertex(uint32 maxVertex)
+00266 {
+00267         // we must not be beewteen beginRender() and endRender()
+00268         nlassert(!isRendering());
+00269         _MaxNumVertices= maxVertex;
+00270 }
+00271 
+00272 // ***************************************************************************
+00273 void                    CLodCharacterManager::deleteVertexBuffer()
+00274 {
+00275         // test (refptr) if the object still exist in memory.
+00276         if(_VBHard!=NULL)
+00277         {
+00278                 // A vbufferhard should still exist only if driver still exist.
+00279                 nlassert(_Driver!=NULL);
+00280 
+00281                 // must unlock VBhard before. ATI: No need to update any vertices.
+00282                 _VBHard->unlock(0,0);
+00283 
+00284                 // delete it from driver.
+00285                 _Driver->deleteVertexBufferHard(_VBHard);
+00286                 _VBHard= NULL;
+00287         }
+00288 
+00289         // delete the soft one.
+00290         _VBuffer.deleteAllVertices();
+00291 }
+00292 
+00293 
+00294 // ***************************************************************************
+00295 void                    CLodCharacterManager::beginRender(IDriver *driver, const CVector &managerPos)
+00296 {
+00297         H_AUTO_USE ( NL3D_CharacterLod_Render )
+00298 
+00299         // we must not be beewteen beginRender() and endRender()
+00300         nlassert(!isRendering());
+00301 
+00302         // Reset render
+00303         //=================
+00304         _CurrentVertexId=0;
+00305         _CurrentTriId= 0;
+00306 
+00307         // update Driver.
+00308         //=================
+00309         nlassert(driver);
+00310 
+00311         // test change of driver.
+00312         nlassert(driver);
+00313         if( _Driver==NULL || driver!=_Driver )
+00314         {
+00315                 // must restart build of VB.
+00316                 deleteVertexBuffer();
+00317                 _Driver= driver;
+00318                 _VBHardOk= _Driver->supportVertexBufferHard();
+00319         }
+00320 
+00321         // If the vbhard exist, but size is different from cur max size, reset.
+00322         if(_VBHard && _VBHard->getNumVertices()!=_MaxNumVertices)
+00323                 deleteVertexBuffer();
+00324 
+00325         // If VBHard is possible, and if not already allocated, try to create it.
+00326         if(_VBHardOk && _VBHard==NULL)
+00327         {
+00328                 _VBHard= driver->createVertexBufferHard(_VBuffer.getVertexFormat(), _VBuffer.getValueTypePointer(), 
+00329                         _MaxNumVertices, IDriver::VBHardAGP);
+00330         }
+00331 
+00332         // Last try to create a std VertexBuffer if the VBHard does not exist.
+00333         if(_VBHard==NULL)
+00334         {
+00335                 // just resize the std VB.
+00336                 _VBuffer.setNumVertices(_MaxNumVertices);
+00337         }
+00338 
+00339         // prepare for render.
+00340         //=================
+00341 
+00342         // Lock Buffer.
+00343         if(_VBHard)
+00344         {
+00345                 _VertexData= (uint8*)_VBHard->lock();
+00346                 _VertexSize= _VBHard->getVertexSize();
+00347         }
+00348         else
+00349         {
+00350                 _VertexData= (uint8*)_VBuffer.getVertexCoordPointer();
+00351                 _VertexSize= _VBuffer.getVertexSize();
+00352         }
+00353         // NB: addRenderCharacterKey() loop hardCoded for Vertex+UV+Normal+Color only.
+00354         nlassert( _VertexSize == NL3D_CLOD_VERTEX_SIZE );       // Vector + Normal + UV + RGBA
+00355 
+00356 
+00357         // Alloc a minimum of primitives (2*vertices), to avoid as possible reallocation in addRenderCharacterKey
+00358         if(_Triangles.size()<_MaxNumVertices * 2)
+00359                 _Triangles.resize(_MaxNumVertices * 2);
+00360 
+00361         // Local manager matrix
+00362         _ManagerMatrixPos= managerPos;
+00363 
+00364         // Ok, start rendering
+00365         _Rendering= true;
+00366 }
+00367 
+00368 
+00369 // ***************************************************************************
+00370 static inline CRGBA     computeLodLighting(const CVector &lightObjectSpace, const CVector &normalPtr, CRGBA ambient, CRGBA diffuse)
+00371 {
+00372         // \todo yoyo: TODO_OPTIMIZE
+00373         float   f= lightObjectSpace * normalPtr;
+00374         f= max(0.f,f);
+00375         sint    f8= OptFastFloor(f*255);
+00376         CRGBA   lightRes;
+00377         lightRes.modulateFromuiRGBOnly(diffuse, f8);
+00378         lightRes.addRGBOnly(lightRes, ambient);
+00379         return lightRes;
+00380 }
+00381 
+00382 
+00383 // ***************************************************************************
+00384 bool                    CLodCharacterManager::addRenderCharacterKey(CLodCharacterInstance &instance, const CMatrix &worldMatrix, 
+00385         CRGBA ambient, CRGBA diffuse, const CVector &lightDir)
+00386 {
+00387         H_AUTO_USE ( NL3D_CharacterLod_Render )
+00388 
+00389         nlassert(_Driver);
+00390         // we must be beewteen beginRender() and endRender()
+00391         nlassert(isRendering());
+00392 
+00393         CVector         unPackScaleFactor;
+00394         uint            numVertices;
+00395 
+00396         // Get the Shape and current key.
+00397         //=============
+00398 
+00399         // get the shape
+00400         const CLodCharacterShape        *clod= getShape(instance.ShapeId);
+00401         // if not found quit, return true
+00402         if(!clod)
+00403                 return true;
+00404 
+00405         // get UV/Normal array. NULL => error
+00406         const CVector   *normalPtr= clod->getNormals();
+00407         // get UV of the instance
+00408         const CUV               *uvPtr= instance.getUVs();
+00409         // uvPtr is NULL means that initInstance() has not been called!!
+00410         nlassert(normalPtr && uvPtr);
+00411 
+00412         // get the anim key
+00413         const CLodCharacterShape::CVector3s             *vertPtr;
+00414         vertPtr= clod->getAnimKey(instance.AnimId, instance.AnimTime, instance.WrapMode, unPackScaleFactor);
+00415         // if not found quit, return true
+00416         if(!vertPtr)
+00417                 return true;
+00418         // get num verts
+00419         numVertices= clod->getNumVertices();
+00420 
+00421         // empty shape??
+00422         if(numVertices==0)
+00423                 return true;
+00424 
+00425         // If too many vertices, quit, returning false.
+00426         if(_CurrentVertexId+numVertices > _MaxNumVertices)
+00427                 return false;
+00428 
+00429         // verify colors.
+00430         bool    vertexColor= instance.VertexColors.size() == numVertices;
+00431         // if error, take white as global color.
+00432 
+00433 
+00434         // Transform and Add vertices.
+00435         //=============
+00436 
+00437         // Get matrix pos.
+00438         CVector         matPos= worldMatrix.getPos();
+00439         // compute in manager space.
+00440         matPos -= _ManagerMatrixPos;
+00441         // Get rotation line vectors
+00442         float   a00= worldMatrix.get()[0]; float        a01= worldMatrix.get()[4]; float        a02= worldMatrix.get()[8]; 
+00443         float   a10= worldMatrix.get()[1]; float        a11= worldMatrix.get()[5]; float        a12= worldMatrix.get()[9]; 
+00444         float   a20= worldMatrix.get()[2]; float        a21= worldMatrix.get()[6]; float        a22= worldMatrix.get()[10];
+00445 
+00446         // get the light in object space.
+00447         CVector         lightObjectSpace;
+00448         // Multiply light dir with transpose of worldMatrix. This may be not exact (not uniform scale) but sufficient.
+00449         lightObjectSpace.x= a00 * lightDir.x + a10 * lightDir.y + a20 * lightDir.z;
+00450         lightObjectSpace.y= a01 * lightDir.x + a11 * lightDir.y + a21 * lightDir.z;
+00451         lightObjectSpace.z= a02 * lightDir.x + a12 * lightDir.y + a22 * lightDir.z;
+00452         // animation User correction
+00453         lightObjectSpace= _LightCorrectionMatrix.mulVector(lightObjectSpace);
+00454         // normalize, and neg for Dot Product.
+00455         lightObjectSpace.normalize();
+00456         lightObjectSpace= -lightObjectSpace;
+00457 
+00458         // multiply matrix with scale factor for Pos.
+00459         a00*= unPackScaleFactor.x; a01*= unPackScaleFactor.y; a02*= unPackScaleFactor.z; 
+00460         a10*= unPackScaleFactor.x; a11*= unPackScaleFactor.y; a12*= unPackScaleFactor.z; 
+00461         a20*= unPackScaleFactor.x; a21*= unPackScaleFactor.y; a22*= unPackScaleFactor.z; 
+00462 
+00463 
+00464         // get dst Array.
+00465         uint8   *dstPtr;
+00466         dstPtr= _VertexData + _CurrentVertexId * _VertexSize;
+00467 
+00468         // 2 modes, with or without per vertexColor
+00469         if(vertexColor)
+00470         {
+00471                 // get color array
+00472                 const CRGBA             *colorPtr= &instance.VertexColors[0];
+00473                 for(;numVertices>0;numVertices--)
+00474                 {
+00475                         // NB: order is important for AGP filling optimisation
+00476                         // transform vertex, and store.
+00477                         CVector         *dstVector= (CVector*)dstPtr;
+00478                         dstVector->x= a00 * vertPtr->x + a01 * vertPtr->y + a02 * vertPtr->z + matPos.x;
+00479                         dstVector->y= a10 * vertPtr->x + a11 * vertPtr->y + a12 * vertPtr->z + matPos.y;
+00480                         dstVector->z= a20 * vertPtr->x + a21 * vertPtr->y + a22 * vertPtr->z + matPos.z;
+00481                         // Copy UV
+00482                         *(CUV*)(dstPtr + NL3D_CLOD_UV_OFF)= *uvPtr;
+00483 
+00484                         // Compute Lighting.
+00485                         CRGBA   lightRes= computeLodLighting(lightObjectSpace, *normalPtr, ambient, diffuse);
+00486                         // modulate color and store.
+00487                         ((CRGBA*)(dstPtr + NL3D_CLOD_COLOR_OFF))->modulateFromColorRGBOnly(*colorPtr, lightRes);
+00488                         // Copy Alpha.
+00489                         ((CRGBA*)(dstPtr + NL3D_CLOD_COLOR_OFF))->A= colorPtr->A;
+00490 
+00491                         // next
+00492                         vertPtr++;
+00493                         uvPtr++;
+00494                         normalPtr++;
+00495                         colorPtr++;
+00496                         dstPtr+= NL3D_CLOD_VERTEX_SIZE;
+00497                 }
+00498         }
+00499         else
+00500         {
+00501                 for(;numVertices>0;numVertices--)
+00502                 {
+00503                         // NB: order is important for AGP filling optimisation
+00504                         // transform vertex, and store.
+00505                         CVector         *dstVector= (CVector*)dstPtr;
+00506                         dstVector->x= a00 * vertPtr->x + a01 * vertPtr->y + a02 * vertPtr->z + matPos.x;
+00507                         dstVector->y= a10 * vertPtr->x + a11 * vertPtr->y + a12 * vertPtr->z + matPos.y;
+00508                         dstVector->z= a20 * vertPtr->x + a21 * vertPtr->y + a22 * vertPtr->z + matPos.z;
+00509                         // Copy UV
+00510                         *(CUV*)(dstPtr + NL3D_CLOD_UV_OFF)= *uvPtr;
+00511 
+00512                         // Compute Lighting.
+00513                         CRGBA   lightRes= computeLodLighting(lightObjectSpace, *normalPtr, ambient, diffuse);
+00514                         lightRes.A= 255;
+00515                         // store global color
+00516                         *(CRGBA*)(dstPtr + NL3D_CLOD_COLOR_OFF)= lightRes;
+00517 
+00518                         // next
+00519                         vertPtr++;
+00520                         uvPtr++;
+00521                         normalPtr++;
+00522                         dstPtr+= NL3D_CLOD_VERTEX_SIZE;
+00523                 }
+00524         }
+00525 
+00526 
+00527         // Add Primitives.
+00528         //=============
+00529 
+00530         // get number of tri indexes
+00531         uint    numTriIdxs= clod->getNumTriangles() * 3;
+00532 
+00533         // realloc tris if needed.
+00534         if(_CurrentTriId+numTriIdxs > _Triangles.size())
+00535         {
+00536                 _Triangles.resize(_CurrentTriId+numTriIdxs);
+00537         }
+00538 
+00539         // reindex and copy tris
+00540         const uint32    *srcIdx= clod->getTriangleArray();
+00541         uint32                  *dstIdx= &_Triangles[_CurrentTriId];
+00542         for(;numTriIdxs>0;numTriIdxs--, srcIdx++, dstIdx++)
+00543         {
+00544                 *dstIdx= *srcIdx + _CurrentVertexId;
+00545         }
+00546 
+00547 
+00548         // Next
+00549         //=============
+00550 
+00551         // Inc Vertex count.
+00552         _CurrentVertexId+= clod->getNumVertices();
+00553         // Inc Prim count.
+00554         _CurrentTriId+= clod->getNumTriangles() * 3;
+00555 
+00556 
+00557         // key added
+00558         return true;
+00559 }
+00560 
+00561 // ***************************************************************************
+00562 void                    CLodCharacterManager::endRender()
+00563 {
+00564         H_AUTO_USE ( NL3D_CharacterLod_Render )
+00565 
+00566         nlassert(_Driver);
+00567         // we must be beewteen beginRender() and endRender()
+00568         nlassert(isRendering());
+00569 
+00570         // UnLock Buffer.
+00571         if(_VBHard)
+00572         {
+00573                 // ATI: copy only used vertices.
+00574                 _VBHard->unlock(0, _CurrentVertexId);
+00575         }
+00576 
+00577         // Render the VBuffer and the primitives.
+00578         if(_CurrentTriId>0)
+00579         {
+00580                 // setup matrix.
+00581                 CMatrix         managerMatrix; 
+00582                 managerMatrix.setPos(_ManagerMatrixPos);
+00583                 _Driver->setupModelMatrix(managerMatrix);
+00584 
+00585                 // active VB
+00586                 if(_VBHard)
+00587                         _Driver->activeVertexBufferHard(_VBHard);
+00588                 else
+00589                         _Driver->activeVertexBuffer(_VBuffer);
+00590 
+00591                 // render triangles
+00592                 _Driver->renderTriangles(_Material, &_Triangles[0], _CurrentTriId/3);
+00593         }
+00594 
+00595         // Ok, end rendering
+00596         _Rendering= false;
+00597 }
+00598 
+00599 // ***************************************************************************
+00600 void                    CLodCharacterManager::setupNormalCorrectionMatrix(const CMatrix &normalMatrix)
+00601 {
+00602         _LightCorrectionMatrix= normalMatrix;
+00603         _LightCorrectionMatrix.setPos(CVector::Null);
+00604         _LightCorrectionMatrix.invert();
+00605 }
+00606 
+00607 
+00608 // ***************************************************************************
+00609 // ***************************************************************************
+00610 // Texturing.
+00611 // ***************************************************************************
+00612 // ***************************************************************************
+00613 
+00614 
+00615 // ***************************************************************************
+00616 CLodCharacterTmpBitmap::CLodCharacterTmpBitmap()
+00617 {
+00618         reset();
+00619 }
+00620 
+00621 // ***************************************************************************
+00622 void                    CLodCharacterTmpBitmap::reset()
+00623 {
+00624         // setup a 1*1 bitmap
+00625         _Bitmap.resize(1);
+00626         _Bitmap[0]= CRGBA::Black;
+00627         _WidthPower=0;
+00628         _UShift= 8;
+00629         _VShift= 8;
+00630 }
+00631 
+00632 // ***************************************************************************
+00633 void                    CLodCharacterTmpBitmap::build(const NLMISC::CBitmap &bmpIn)
+00634 {
+00635         uint    width= bmpIn.getWidth();
+00636         uint    height= bmpIn.getHeight();
+00637         nlassert(width>0 && width<=256);
+00638         nlassert(height>0 && height<=256);
+00639 
+00640         // resize bitmap.
+00641         _Bitmap.resize(width*height);
+00642         _WidthPower= getPowerOf2(width);
+00643         // compute shift
+00644         _UShift= 8-getPowerOf2(width);
+00645         _VShift= 8-getPowerOf2(height);
+00646 
+00647         // convert the bitmap.
+00648         CBitmap         bmp= bmpIn;
+00649         bmp.convertToType(CBitmap::RGBA);
+00650         CRGBA   *src= (CRGBA*)&bmp.getPixels()[0];
+00651         CRGBA   *dst= _Bitmap.getPtr();
+00652         for(sint nPix= width*height;nPix>0;nPix--, src++, dst++)
+00653         {
+00654                 *dst= *src;
+00655         }
+00656 }
+00657 
+00658 // ***************************************************************************
+00659 void                    CLodCharacterTmpBitmap::build(CRGBA col)
+00660 {
+00661         // setup a 1*1 bitmap and set it with col
+00662         reset();
+00663         _Bitmap[0]= col;
+00664 }
+00665 
+00666 
+00667 // ***************************************************************************
+00668 void                    CLodCharacterManager::initInstance(CLodCharacterInstance &instance)
+00669 {
+00670         // first release in (maybe) other manager.
+00671         if(instance._Owner)
+00672                 instance._Owner->releaseInstance(instance);
+00673 
+00674         // get the shape
+00675         const CLodCharacterShape        *clod= getShape(instance.ShapeId);
+00676         // if not found quit
+00677         if(!clod)
+00678                 return;
+00679         // get Uvs.
+00680         const CUV       *uvSrc= clod->getUVs();
+00681         nlassert(uvSrc);
+00682 
+00683 
+00684         // Ok, init header
+00685         instance._Owner= this;
+00686         instance._UVs.resize(clod->getNumVertices());
+00687 
+00688         // allocate an id. If cannot, then fill Uvs with 0 => filled with Black. (see endTextureCompute() why).
+00689         if(_FreeIds.empty())
+00690         {
+00691                 // set a "Not enough memory" id
+00692                 instance._TextureId= NL3D_CLOD_TEXT_NUM_IDS;
+00693                 CUV             uv(0,0);
+00694                 fill(instance._UVs.begin(), instance._UVs.end(), uv);
+00695         }
+00696         // else OK, can instanciate the Uvs.
+00697         else
+00698         {
+00699                 // get the id.
+00700                 instance._TextureId= _FreeIds.back();
+00701                 _FreeIds.pop_back();
+00702                 // get the x/y.
+00703                 uint    xId= instance._TextureId % NL3D_CLOD_TEXT_NLOD_WIDTH;
+00704                 uint    yId= instance._TextureId / NL3D_CLOD_TEXT_NLOD_WIDTH;
+00705                 // compute the scale/bias to apply to Uvs.
+00706                 float   scaleU= 1.0f / NL3D_CLOD_TEXT_NLOD_WIDTH;
+00707                 float   scaleV= 1.0f / NL3D_CLOD_TEXT_NLOD_HEIGHT;
+00708                 float   biasU= (float)xId / NL3D_CLOD_TEXT_NLOD_WIDTH;
+00709                 float   biasV= (float)yId / NL3D_CLOD_TEXT_NLOD_HEIGHT;
+00710                 // apply it to each UVs.
+00711                 CUV             *uvDst= &instance._UVs[0];
+00712                 for(uint i=0; i<instance._UVs.size();i++)
+00713                 {
+00714                         uvDst[i].U= biasU + uvSrc[i].U*scaleU;
+00715                         uvDst[i].V= biasV + uvSrc[i].V*scaleV;
+00716                 }
+00717         }
+00718 }
+00719 
+00720 // ***************************************************************************
+00721 void                    CLodCharacterManager::releaseInstance(CLodCharacterInstance &instance)
+00722 {
+00723         if(instance._Owner==NULL)
+00724                 return;
+00725         nlassert(this==instance._Owner);
+00726 
+00727         // if the id is not a "Not enough memory" id, release it.
+00728         if(instance._TextureId>=0 && instance._TextureId<NL3D_CLOD_TEXT_NUM_IDS)
+00729                 _FreeIds.push_back(instance._TextureId);
+00730 
+00731         // reset the instance
+00732         instance._Owner= NULL;
+00733         instance._TextureId= -1;
+00734         contReset(instance._UVs);
+00735 }
+00736 
+00737 
+00738 // ***************************************************************************
+00739 CRGBA                   *CLodCharacterManager::getTextureInstance(CLodCharacterInstance &instance)
+00740 {
+00741         nlassert(instance._Owner==this);
+00742         nlassert(instance._TextureId!=-1);
+00743         // if the texture id is a "not enough memory", quit.
+00744         if(instance._TextureId==NL3D_CLOD_TEXT_NUM_IDS)
+00745                 return NULL;
+00746 
+00747         // get the x/y.
+00748         uint    xId= instance._TextureId % NL3D_CLOD_TEXT_NLOD_WIDTH;
+00749         uint    yId= instance._TextureId / NL3D_CLOD_TEXT_NLOD_WIDTH;
+00750 
+00751         // get the ptr on the correct pixel.
+00752         CRGBA   *pix= (CRGBA*)&_BigTexture->getPixels(0)[0];
+00753         return pix + yId*NL3D_CLOD_TEXT_HEIGHT*NL3D_CLOD_BIGTEXT_WIDTH + xId*NL3D_CLOD_TEXT_WIDTH;
+00754 }
+00755 
+00756 
+00757 // ***************************************************************************
+00758 bool                    CLodCharacterManager::startTextureCompute(CLodCharacterInstance &instance)
+00759 {
+00760         CRGBA   *dst= getTextureInstance(instance);
+00761         if(!dst)
+00762                 return false;
+00763 
+00764         // erase the texture with 0,0,0,255. Alpha is actually the min "Quality" part of the CTUVQ.
+00765         CRGBA   col= NL3D_CLOD_DEFAULT_TEXCOLOR;
+00766         for(uint y=0;y<NL3D_CLOD_TEXT_HEIGHT;y++)
+00767         {
+00768                 // erase the line
+00769                 for(uint x=0;x<NL3D_CLOD_TEXT_WIDTH;x++)
+00770                         dst[x]= col;
+00771                 // Next line
+00772                 dst+= NL3D_CLOD_BIGTEXT_WIDTH;
+00773         }
+00774 
+00775         return true;
+00776 }
+00777 
+00778 // ***************************************************************************
+00779 void                    CLodCharacterManager::addTextureCompute(CLodCharacterInstance &instance, const CLodCharacterTexture &lodTexture)
+00780 {
+00781         CRGBA   *dst= getTextureInstance(instance);
+00782         if(!dst)
+00783                 return;
+00784 
+00785         // get lookup ptr.
+00786         nlassert(lodTexture.Texture.size()==NL3D_CLOD_TEXT_SIZE);
+00787         const CLodCharacterTexture::CTUVQ               *lookUpPtr= &lodTexture.Texture[0];
+00788 
+00789         // apply the lodTexture, taking only better quality (ie nearer 0)
+00790         for(uint y=0;y<NL3D_CLOD_TEXT_HEIGHT;y++)
+00791         {
+00792                 // erase the line
+00793                 for(uint x=0;x<NL3D_CLOD_TEXT_WIDTH;x++)
+00794                 {
+00795                         CLodCharacterTexture::CTUVQ             lut= *lookUpPtr;
+00796                         // if this quality is better than the one stored
+00797                         if(lut.Q<dst[x].A)
+00798                         {
+00799                                 // get what texture to read, and read the pixel.
+00800                                 CRGBA   col= _TmpBitmaps[lut.T].getPixel(lut.U, lut.V);
+00801                                 // set quality.
+00802                                 col.A= lut.Q;
+00803                                 // set in dest
+00804                                 dst[x]= col;
+00805                         }
+00806 
+00807                         // next lookup
+00808                         lookUpPtr++;
+00809                 }
+00810                 // Next line
+00811                 dst+= NL3D_CLOD_BIGTEXT_WIDTH;
+00812         }
+00813 }
+00814 
+00815 // ***************************************************************************
+00816 void                    CLodCharacterManager::endTextureCompute(CLodCharacterInstance &instance, uint numBmpToReset)
+00817 {
+00818         CRGBA   *dst= getTextureInstance(instance);
+00819         if(!dst)
+00820                 return;
+00821 
+00822         // reset All Alpha values to 255 => no AlphaTest problems
+00823         for(uint y=0;y<NL3D_CLOD_TEXT_HEIGHT;y++)
+00824         {
+00825                 // erase the line
+00826                 for(uint x=0;x<NL3D_CLOD_TEXT_WIDTH;x++)
+00827                 {
+00828                         dst[x].A= 255;
+00829                 }
+00830                 // Next line
+00831                 dst+= NL3D_CLOD_BIGTEXT_WIDTH;
+00832         }
+00833 
+00834         // If the id == 0 then must reset the 0,0 Pixel to black. for the "Not Enough memory" case in initInstance().
+00835         if(instance._TextureId==0)
+00836                 *(CRGBA*)&_BigTexture->getPixels(0)[0]= NL3D_CLOD_DEFAULT_TEXCOLOR;
+00837 
+00838         // get the x/y.
+00839         uint    xId= instance._TextureId % NL3D_CLOD_TEXT_NLOD_WIDTH;
+00840         uint    yId= instance._TextureId / NL3D_CLOD_TEXT_NLOD_WIDTH;
+00841         // touch the texture for Driver update.
+00842         _BigTexture->touchRect(
+00843                 CRect(xId*NL3D_CLOD_TEXT_WIDTH, yId*NL3D_CLOD_TEXT_HEIGHT, NL3D_CLOD_TEXT_WIDTH, NL3D_CLOD_TEXT_HEIGHT) );
+00844 
+00845         // reset tmpBitmaps / free memory.
+00846         for(uint i=0; i<numBmpToReset; i++)
+00847         {
+00848                 _TmpBitmaps[i].reset();
+00849         }
+00850 
+00851         // TestYoyo
+00852         /*NLMISC::COFile        f("tam.tga");
+00853         _BigTexture->writeTGA(f,32);*/
+00854 }
+00855 
+00856 
+00857 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1