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/mesh__mrm__skin_8cpp-source.html | 484 ++++++++++++++++++++++ 1 file changed, 484 insertions(+) create mode 100644 docs/doxygen/nel/mesh__mrm__skin_8cpp-source.html (limited to 'docs/doxygen/nel/mesh__mrm__skin_8cpp-source.html') diff --git a/docs/doxygen/nel/mesh__mrm__skin_8cpp-source.html b/docs/doxygen/nel/mesh__mrm__skin_8cpp-source.html new file mode 100644 index 00000000..7168bebb --- /dev/null +++ b/docs/doxygen/nel/mesh__mrm__skin_8cpp-source.html @@ -0,0 +1,484 @@ + + + + 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  
+

mesh_mrm_skin.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 "nel/misc/bsphere.h"
+00029 #include "nel/misc/fast_mem.h"
+00030 #include "nel/misc/system_info.h"
+00031 #include "3d/mesh_mrm.h"
+00032 #include "3d/mrm_builder.h"
+00033 #include "3d/mrm_parameters.h"
+00034 #include "3d/mesh_mrm_instance.h"
+00035 #include "3d/scene.h"
+00036 #include "3d/skeleton_model.h"
+00037 #include "3d/stripifier.h"
+00038 #include "3d/matrix_3x4.h"
+00039 #include "3d/raw_skin.h"
+00040 
+00041 
+00042 using namespace NLMISC;
+00043 using namespace std;
+00044 
+00045 
+00046 namespace NL3D 
+00047 {
+00048 
+00049 
+00050 // ***************************************************************************
+00051 // ***************************************************************************
+00052 // CMatrix3x4SSE array correctly aligned
+00053 // ***************************************************************************
+00054 // ***************************************************************************
+00055 
+00056 
+00057 
+00058 // ***************************************************************************
+00059 #define NL3D_SSE_ALIGNEMENT             16
+00060 
+00063 class   CMatrix3x4SSEArray
+00064 {
+00065 private:
+00066         void    *_AllocData;
+00067         void    *_Data;
+00068         uint    _Size;
+00069         uint    _Capacity;
+00070 
+00071 public:
+00072         CMatrix3x4SSEArray()
+00073         {
+00074                 _AllocData= NULL;
+00075                 _Data= NULL;
+00076                 _Size= 0;
+00077                 _Capacity= 0;
+00078         }
+00079         ~CMatrix3x4SSEArray()
+00080         {
+00081                 clear();
+00082         }
+00083         CMatrix3x4SSEArray(const CMatrix3x4SSEArray &other)
+00084         {
+00085                 _AllocData= NULL;
+00086                 _Data= NULL;
+00087                 _Size= 0;
+00088                 _Capacity= 0;
+00089                 *this= other;
+00090         }
+00091         CMatrix3x4SSEArray &operator=(const CMatrix3x4SSEArray &other)
+00092         {
+00093                 if( this == &other)
+00094                         return *this;
+00095                 resize(other.size());
+00096                 // copy data from aligned pointers to aligned pointers.
+00097                 memcpy(_Data, other._Data, size() * sizeof(CMatrix3x4SSE) );
+00098 
+00099                 return *this;
+00100         }
+00101 
+00102 
+00103         CMatrix3x4SSE   *getPtr()
+00104         {
+00105                 return (CMatrix3x4SSE*)_Data;
+00106         }
+00107 
+00108         void    clear()
+00109         {
+00110                 free(_AllocData);
+00111                 _AllocData= NULL;
+00112                 _Data= NULL;
+00113                 _Size= 0;
+00114                 _Capacity= 0;
+00115         }
+00116 
+00117         void    resize(uint n)
+00118         {
+00119                 // reserve ??
+00120                 if(n>_Capacity)
+00121                         reserve( max(2*_Capacity, n));
+00122                 _Size= n;
+00123         }
+00124 
+00125         void    reserve(uint n)
+00126         {
+00127                 if(n==0)
+00128                         clear();
+00129                 else if(n>_Capacity)
+00130                 {
+00131                         // Alloc new data.
+00132                         void    *newAllocData;
+00133                         void    *newData;
+00134 
+00135                         // Alloc for alignement.
+00136                         newAllocData= malloc(n * sizeof(CMatrix3x4SSE) + NL3D_SSE_ALIGNEMENT-1);
+00137                         if(newAllocData==NULL)
+00138                                 throw Exception("SSE Allocation Failed");
+00139 
+00140                         // Align ptr
+00141                         newData= (void*) ( ((uint32)newAllocData+NL3D_SSE_ALIGNEMENT-1) & (~(NL3D_SSE_ALIGNEMENT-1)) );
+00142 
+00143                         // copy valid data from old to new.
+00144                         memcpy(newData, _Data, size() * sizeof(CMatrix3x4SSE) );
+00145 
+00146                         // change ptrs and capacity.
+00147                         _Data= newData;
+00148                         _AllocData= newAllocData;
+00149                         _Capacity= n;
+00150                 }
+00151         }
+00152 
+00153         uint    size() const {return _Size;}
+00154 
+00155 
+00156         CMatrix3x4SSE   &operator[](uint i) {return ((CMatrix3x4SSE*)_Data)[i];}
+00157 };
+00158 
+00159 
+00160 
+00161 // ***************************************************************************
+00162 // ***************************************************************************
+00163 // Matrix manip
+00164 // ***************************************************************************
+00165 // ***************************************************************************
+00166 
+00167 
+00168 // ***************************************************************************
+00169 template <class TMatrixArray>
+00170 inline void     computeBoneMatrixes3x4(TMatrixArray &boneMat3x4, const vector<uint32> &matInfs, const CSkeletonModel *skeleton)
+00171 {
+00172         // For all matrix this lod use.
+00173         for(uint i= 0; i<matInfs.size(); i++)
+00174         {
+00175                 // Get Matrix info.
+00176                 uint    matId= matInfs[i];
+00177                 const CMatrix           &boneMat= skeleton->getActiveBoneSkinMatrix(matId);
+00178 
+00179                 // compute "fast" matrix 3x4.
+00180                 // resize Matrix3x4.
+00181                 if(matId>=boneMat3x4.size())
+00182                 {
+00183                         boneMat3x4.resize(matId+1);
+00184                 }
+00185                 boneMat3x4[matId].set(boneMat);
+00186         }
+00187 }
+00188 
+00189 
+00190 // ***************************************************************************
+00191 // ***************************************************************************
+00192 // Simple (slow) skinning version with position only.
+00193 // ***************************************************************************
+00194 // ***************************************************************************
+00195 
+00196 
+00197 // ***************************************************************************
+00198 void    CMeshMRMGeom::applySkin(CLod &lod, const CSkeletonModel *skeleton)
+00199 {
+00200         nlassert(_Skinned);
+00201         if(_SkinWeights.size()==0)
+00202                 return;
+00203 
+00204         // get vertexPtr.
+00205         //===========================
+00206         uint8           *destVertexPtr= (uint8*)_VBufferFinal.getVertexCoordPointer();
+00207         uint            flags= _VBufferFinal.getVertexFormat();
+00208         sint32          vertexSize= _VBufferFinal.getVertexSize();
+00209         // must have XYZ.
+00210         nlassert(flags & CVertexBuffer::PositionFlag);
+00211 
+00212 
+00213         // compute src array.
+00214         CMesh::CSkinWeight      *srcSkinPtr;
+00215         CVector                         *srcVertexPtr;
+00216         srcSkinPtr= &_SkinWeights[0];
+00217         srcVertexPtr= &_OriginalSkinVertices[0];
+00218 
+00219 
+00220 
+00221         // Compute usefull Matrix for this lod.
+00222         //===========================
+00223         // Those arrays map the array of bones in skeleton.
+00224         static  vector<CMatrix3x4>                      boneMat3x4;
+00225         computeBoneMatrixes3x4(boneMat3x4, lod.MatrixInfluences, skeleton);
+00226 
+00227 
+00228         // apply skinning.
+00229         //===========================
+00230         // assert, code below is written especially for 4 per vertex.
+00231         nlassert(NL3D_MESH_SKINNING_MAX_MATRIX==4);
+00232         for(uint i=0;i<NL3D_MESH_SKINNING_MAX_MATRIX;i++)
+00233         {
+00234                 uint            nInf= lod.InfluencedVertices[i].size();
+00235                 if( nInf==0 )
+00236                         continue;
+00237                 uint32          *infPtr= &(lod.InfluencedVertices[i][0]);
+00238 
+00239                 // apply the skin to the vertices
+00240                 switch(i)
+00241                 {
+00242                 //=========
+00243                 case 0:
+00244                         // Special case for Vertices influenced by one matrix. Just copy result of mul.
+00245                         //  for all InfluencedVertices only.
+00246                         for(;nInf>0;nInf--, infPtr++)
+00247                         {
+00248                                 uint    index= *infPtr;
+00249                                 CMesh::CSkinWeight      *srcSkin= srcSkinPtr + index;
+00250                                 CVector                         *srcVertex= srcVertexPtr + index;
+00251                                 uint8                           *dstVertexVB= destVertexPtr + index * vertexSize;
+00252                                 CVector                         *dstVertex= (CVector*)(dstVertexVB);
+00253 
+00254 
+00255                                 // Vertex.
+00256                                 boneMat3x4[ srcSkin->MatrixId[0] ].mulSetPoint( *srcVertex, *dstVertex);
+00257                         }
+00258                         break;
+00259 
+00260                 //=========
+00261                 case 1:
+00262                         //  for all InfluencedVertices only.
+00263                         for(;nInf>0;nInf--, infPtr++)
+00264                         {
+00265                                 uint    index= *infPtr;
+00266                                 CMesh::CSkinWeight      *srcSkin= srcSkinPtr + index;
+00267                                 CVector                         *srcVertex= srcVertexPtr + index;
+00268                                 uint8                           *dstVertexVB= destVertexPtr + index * vertexSize;
+00269                                 CVector                         *dstVertex= (CVector*)(dstVertexVB);
+00270 
+00271 
+00272                                 // Vertex.
+00273                                 boneMat3x4[ srcSkin->MatrixId[0] ].mulSetPoint( *srcVertex, srcSkin->Weights[0], *dstVertex);
+00274                                 boneMat3x4[ srcSkin->MatrixId[1] ].mulAddPoint( *srcVertex, srcSkin->Weights[1], *dstVertex);
+00275                         }
+00276                         break;
+00277 
+00278                 //=========
+00279                 case 2:
+00280                         //  for all InfluencedVertices only.
+00281                         for(;nInf>0;nInf--, infPtr++)
+00282                         {
+00283                                 uint    index= *infPtr;
+00284                                 CMesh::CSkinWeight      *srcSkin= srcSkinPtr + index;
+00285                                 CVector                         *srcVertex= srcVertexPtr + index;
+00286                                 uint8                           *dstVertexVB= destVertexPtr + index * vertexSize;
+00287                                 CVector                         *dstVertex= (CVector*)(dstVertexVB);
+00288 
+00289 
+00290                                 // Vertex.
+00291                                 boneMat3x4[ srcSkin->MatrixId[0] ].mulSetPoint( *srcVertex, srcSkin->Weights[0], *dstVertex);
+00292                                 boneMat3x4[ srcSkin->MatrixId[1] ].mulAddPoint( *srcVertex, srcSkin->Weights[1], *dstVertex);
+00293                                 boneMat3x4[ srcSkin->MatrixId[2] ].mulAddPoint( *srcVertex, srcSkin->Weights[2], *dstVertex);
+00294                         }
+00295                         break;
+00296 
+00297                 //=========
+00298                 case 3:
+00299                         //  for all InfluencedVertices only.
+00300                         for(;nInf>0;nInf--, infPtr++)
+00301                         {
+00302                                 uint    index= *infPtr;
+00303                                 CMesh::CSkinWeight      *srcSkin= srcSkinPtr + index;
+00304                                 CVector                         *srcVertex= srcVertexPtr + index;
+00305                                 uint8                           *dstVertexVB= destVertexPtr + index * vertexSize;
+00306                                 CVector                         *dstVertex= (CVector*)(dstVertexVB);
+00307 
+00308 
+00309                                 // Vertex.
+00310                                 boneMat3x4[ srcSkin->MatrixId[0] ].mulSetPoint( *srcVertex, srcSkin->Weights[0], *dstVertex);
+00311                                 boneMat3x4[ srcSkin->MatrixId[1] ].mulAddPoint( *srcVertex, srcSkin->Weights[1], *dstVertex);
+00312                                 boneMat3x4[ srcSkin->MatrixId[2] ].mulAddPoint( *srcVertex, srcSkin->Weights[2], *dstVertex);
+00313                                 boneMat3x4[ srcSkin->MatrixId[3] ].mulAddPoint( *srcVertex, srcSkin->Weights[3], *dstVertex);
+00314                         }
+00315                         break;
+00316 
+00317                 }
+00318         }
+00319 }
+00320 
+00321 
+00322 // ***************************************************************************
+00323 // ***************************************************************************
+00324 // Old school Template skinning: SSE or not.
+00325 // ***************************************************************************
+00326 // ***************************************************************************
+00327 
+00328 
+00329 // RawSkin Cache constants
+00330 //===============
+00331 // The number of byte to process per block
+00332 const   uint    NL_BlockByteL1= 4096;
+00333 
+00334 // Number of vertices per block to process with 1 matrix.
+00335 uint    CMeshMRMGeom::NumCacheVertexNormal1= NL_BlockByteL1 / sizeof(CRawVertexNormalSkin1);
+00336 // Number of vertices per block to process with 2 matrix.
+00337 uint    CMeshMRMGeom::NumCacheVertexNormal2= NL_BlockByteL1 / sizeof(CRawVertexNormalSkin2);
+00338 // Number of vertices per block to process with 3/4 matrix.
+00339 uint    CMeshMRMGeom::NumCacheVertexNormal4= NL_BlockByteL1 / sizeof(CRawVertexNormalSkin4);
+00340 
+00341 
+00342 // Old School template: include the same file with define switching
+00343 #undef NL_SKIN_SSE
+00344 #include "mesh_mrm_skin_template.cpp"
+00345 #define NL_SKIN_SSE
+00346 #include "mesh_mrm_skin_template.cpp"
+00347 
+00348 
+00349 
+00350 // ***************************************************************************
+00351 // ***************************************************************************
+00352 // Misc.
+00353 // ***************************************************************************
+00354 // ***************************************************************************
+00355 
+00356 
+00357 
+00358 // ***************************************************************************
+00359 void                            CMeshMRMGeom::fillAGPSkinPart(CLod &lod, IVertexBufferHard *currentVBHard)
+00360 {
+00361         // if VBHard OK
+00362         if(currentVBHard)
+00363         {
+00364                 // lock buffer.
+00365                 uint8           *vertexDst= (uint8*)currentVBHard->lock();
+00366 
+00367                 // do it.
+00368                 fillAGPSkinPartWithVBHardPtr(lod, vertexDst);
+00369 
+00370                 // release
+00371                 currentVBHard->unlock();
+00372         }
+00373 }
+00374 
+00375 
+00376 // ***************************************************************************
+00377 void                            CMeshMRMGeom::fillAGPSkinPartWithVBHardPtr(CLod &lod, uint8 *vertexDst)
+00378 {
+00379         // Fill AGP vertices used by this lod from RAM. (not geomorphed ones).
+00380         if( lod.SkinVertexBlocks.size()>0 )
+00381         {
+00382                 // Get VB info, and lock buffers.
+00383                 uint8           *vertexSrc= (uint8*)_VBufferFinal.getVertexCoordPointer();
+00384                 uint32          vertexSize= _VBufferFinal.getVertexSize();
+00385 
+00386                 // big copy of all vertices and their data.
+00387                 // NB: this not help RAM bandwidth, but this help AGP write combiners.
+00388                 // For the majority of mesh (vertex/normal/uv), this is better (6/10).
+00389 
+00390                 // Also, this is a requirement for MeshMorpher to work, because the MehsMorpher may modify
+00391                 // UV and color
+00392 
+00393 
+00394                 // For all block of vertices.
+00395                 CVertexBlock    *vBlock= &lod.SkinVertexBlocks[0];
+00396                 uint    n= lod.SkinVertexBlocks.size();
+00397 
+00398                 /*
+00399                         It appears that it is not a so good idea to use CFastMem::memcpySSE() here, maybe because
+00400                         data is often already in cache (written by skinning), and maybe because movntq is not usefull here since
+00401                         AGP is already a write-combining memory.
+00402                 */
+00403                 for(;n>0; n--, vBlock++)
+00404                 {
+00405                         // For all vertices of this block, copy it from RAM to VRAM.
+00406                         uint8           *src= vertexSrc + vertexSize * vBlock->VertexStart;
+00407                         uint8           *dst= vertexDst + vertexSize * vBlock->VertexStart;
+00408 
+00409                         memcpy(dst, src, vBlock->NVertices * vertexSize);
+00410                 }
+00411         }
+00412 }
+00413 
+00414 
+00415 
+00416 } // NL3D
+00417 
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1