Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogre/Tools/3dsmaxExport/LEXIExporter/LexiExport/Sources/LexiOgreMeshCompiler.cpp @ 11

Last change on this file since 11 was 6, checked in by anonymous, 18 years ago

=…

File size: 22.7 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of LEXIExporter
4
5Copyright 2006 NDS Limited
6
7Author(s):
8Mark Folkenberg,
9Bo Krohn
10
11This program is free software; you can redistribute it and/or modify it under
12the terms of the GNU Lesser General Public License as published by the Free Software
13Foundation; either version 2 of the License, or (at your option) any later
14version.
15
16This program is distributed in the hope that it will be useful, but WITHOUT
17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
19
20You should have received a copy of the GNU Lesser General Public License along with
21this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22Place - Suite 330, Boston, MA 02111-1307, USA, or go to
23http://www.gnu.org/copyleft/lesser.txt.
24-----------------------------------------------------------------------------
25*/
26
27#include "LexiStdAfx.h"
28#include "LexiOgreMeshCompiler.h"
29#include "OgreDefaultHardwareBufferManager.h"
30#include "LexiExportObject.h"
31
32COgreMeshCompiler::COgreMeshCompiler( CIntermediateMesh* pIntermediateMesh, const CDDObject* pConfig, Ogre::String filename) :
33        m_iBind(0),
34        m_MaxSquaredLength(0.0),
35        m_pOgreMesh(NULL),
36        m_bReindex(false),
37        m_bExportNormals(false),
38        m_bExportColours(false),
39        m_bExportTexUVs(false),
40        m_bExportSkeleton(false),
41        m_iNrVerts(0),
42        m_iNrPoses(0)
43{
44        m_IndexBitType = Ogre::HardwareIndexBuffer::IT_16BIT;
45
46        ReadConfig(pConfig);
47
48        if(m_bReindex)
49                ReindexIntermediateBuffers(pIntermediateMesh);
50
51        /////////////////////////////////////
52        //MessageBox(NULL, "PreOgreMeshCreate","BREAK!",0);
53        /////////////////////////////////////
54
55        CreateOgreMesh(pIntermediateMesh);
56
57        /////////////////////////////////////
58        //MessageBox(NULL, "PreCreateBuffer","BREAK!",0);
59        /////////////////////////////////////
60
61        CreateBuffers(pIntermediateMesh);
62
63        Ogre::LogManager::getSingletonPtr()->logMessage("OgreMeshCompiler: Creating Bounds");
64        // create and register bounding box
65        CreateMeshBounds();
66
67        // ready for serialization!
68}
69
70COgreMeshCompiler::~COgreMeshCompiler()
71{
72        LOGDEBUG "OgreMeshCompiler cleaned..");
73
74        Ogre::MeshManager* pMeshMgr = Ogre::MeshManager::getSingletonPtr();
75        delete m_pOgreMesh->sharedVertexData;
76        pMeshMgr->unloadAll();
77        pMeshMgr->removeAll();
78}
79
80
81void COgreMeshCompiler::ReadConfig( const CDDObject* pConfig )
82{
83        assert(pConfig);
84
85        m_bReindex = pConfig->GetBool("reindexID");
86        m_bExportNormals = pConfig->GetBool("normalsID");
87        m_bExportColours = pConfig->GetBool("vertexColorsID");
88        m_bExportTexUVs = pConfig->GetBool("uvID");
89
90        m_bExportSkeleton = false;
91}
92
93
94void COgreMeshCompiler::ReindexIntermediateBuffers( CIntermediateMesh* pIntermediateMesh )
95{
96        assert(pIntermediateMesh);
97
98        SharedUtilities::fastvector< CMeshArray* > bufferList;
99        bufferList.push_back(pIntermediateMesh->GetArray("position",0));
100
101        CMeshArray* pArray; 
102
103       
104        if(m_bExportNormals)
105        {
106                pArray = pIntermediateMesh->GetArray("normal",0);
107                if (pArray == NULL)
108                        LOGWARNING "No Normals found, ignoring \"export normals\" option.");
109                else
110                        bufferList.push_back(pArray);
111        }
112
113       
114        if(m_bExportColours)
115        {
116                pArray = pIntermediateMesh->GetArray("diffuse",0);
117                if (pArray != NULL)
118                        bufferList.push_back(pArray);
119        }
120
121       
122        if(m_bExportTexUVs)
123        {
124                // check all uv sets
125                for(unsigned int x = 1; x <= 99; x++)
126                {
127                        char temp[32];
128                        sprintf(temp, "uv%i", x);
129                        pArray = pIntermediateMesh->GetArray(temp,0);
130                        if (pArray == NULL)
131                                continue;
132                        else
133                                bufferList.push_back(pArray);
134                }
135        }
136
137        // Prepare bone vertex assignments
138        CIntermediateSkeleton* pISkel = pIntermediateMesh->GetSkeleton();
139        SharedUtilities::fastvector< CMeshArray* > boneBuffer;
140
141        if(pISkel != NULL)
142        {
143                // extract declaration map into individual arrays for reindexing
144                pISkel->ExtractVertexAssignmentsArrays(boneBuffer);
145
146                for(int i=0; i < boneBuffer.size(); i++)
147                {
148                        bufferList.push_back( boneBuffer[i] );
149                }
150        }
151
152        pIntermediateMesh->Reindex( bufferList );
153
154        if(pISkel != NULL)
155        {
156                pISkel->ApplyVertexAssignmentsArrays(boneBuffer);
157                //Clean up
158                for(int i=0; i < boneBuffer.size(); i++)
159                {
160                        delete boneBuffer[i];
161                }
162                boneBuffer.clear();
163        }
164
165}
166
167void COgreMeshCompiler::CreateOgreMesh( CIntermediateMesh* pIntermediateMesh )
168{
169        Ogre::String sMeshName = pIntermediateMesh->getName();
170        Ogre::MeshManager* pMeshMgr = Ogre::MeshManager::getSingletonPtr();
171        Ogre::MeshPtr pOgreMesh = pMeshMgr->getByName(sMeshName);
172
173        if(!pOgreMesh.isNull()) {
174                pMeshMgr->unload(pOgreMesh->getHandle());
175                pMeshMgr->remove(pOgreMesh->getHandle());
176                pOgreMesh.setNull();
177        }
178        pOgreMesh = pMeshMgr->createManual(sMeshName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );
179        m_pOgreMesh = pOgreMesh;
180        m_pOgreMesh->sharedVertexData = new Ogre::VertexData();
181
182        CreateSubMeshes( pIntermediateMesh );
183}
184
185void COgreMeshCompiler::CreateSubMeshes( CIntermediateMesh* pIntermediateMesh )
186{
187        assert(pIntermediateMesh);
188        assert(!m_pOgreMesh.isNull());
189
190        unsigned int iCount = pIntermediateMesh->GetNumMaterials();
191        for (int i = 0; i < iCount; i++)
192        {
193                Ogre::SubMesh* pSubMesh = m_pOgreMesh->createSubMesh();
194                CIntermediateMaterial* mat = pIntermediateMesh->GetMaterial(i);
195                m_lMaterialSubMeshMap.insert( std::pair<CIntermediateMaterial*,Ogre::SubMesh*>(mat,pSubMesh) );
196        }
197}
198
199void COgreMeshCompiler::CreateBuffers( CIntermediateMesh* pIntermediateMesh )
200{
201        assert(pIntermediateMesh);
202        assert(!m_pOgreMesh.isNull());
203
204        /////////////////////////////////////
205        //MessageBox(NULL, "PreVertexBuffer","BREAK!",0);
206        /////////////////////////////////////
207        CreateVertexBuffer(pIntermediateMesh);
208
209        /////////////////////////////////////
210        //MessageBox(NULL, "PreIndexBuffer","BREAK!",0);
211        /////////////////////////////////////
212        CreateIndexBuffer(pIntermediateMesh);
213
214        if(m_bExportNormals)
215        {
216                /////////////////////////////////////
217                //MessageBox(NULL, "PreNormalBuffer","BREAK!",0);
218                /////////////////////////////////////
219                CreateNormalBuffer(pIntermediateMesh);
220        }
221
222        if(m_bExportColours)
223        {
224                /////////////////////////////////////
225                //MessageBox(NULL, "PreDiffuseBuffer","BREAK!",0);
226                /////////////////////////////////////
227                CreateDiffuseBuffer(pIntermediateMesh);
228        }       
229        if (m_bExportTexUVs)
230        {
231                /////////////////////////////////////
232                //MessageBox(NULL, "PreTextureCoordBuffer","BREAK!",0);
233                /////////////////////////////////////
234                CreateTexCoordBuffer(pIntermediateMesh);
235        }
236
237        if( pIntermediateMesh->HasPoseData() )
238        {
239                CreatePoseBuffers(pIntermediateMesh);
240        }
241
242        //"specular"
243        //"boneindex"
244        //"blendweight"
245        //"binormal"
246        //"tangent"
247}
248
249void COgreMeshCompiler::CreateVertexBuffer( CIntermediateMesh* pIntermediateMesh )
250{
251        assert(pIntermediateMesh);
252        CMeshArray* pMeshArray = pIntermediateMesh->GetArray("position",0);
253        if(pMeshArray == NULL)
254                return;
255
256        m_iNrVerts = pMeshArray->Size();
257
258        Ogre::VertexData* vertexData = m_pOgreMesh->sharedVertexData;
259        Ogre::VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
260
261        // allocate the position vertex buffer
262        vertexDecl->addElement(m_iBind, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
263        vertexData->vertexCount = m_iNrVerts;
264
265        {       // DEBUG INFO
266                //Ogre::StringUtil::StrStreamType strStrm;
267                //strStrm << "Export: Vertex Size: " << vertexDecl->getVertexSize(m_iBind) << " | Vertex Count: " << vertexData->vertexCount << " | Buffer Size: " << vertexDecl->getVertexSize(m_iBind)*vertexData->vertexCount;
268                //Ogre::LogManager::getSingletonPtr()->logMessage(strStrm.str());
269        }
270
271        vBuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(m_iBind), vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
272        Ogre::VertexBufferBinding* binding = vertexData->vertexBufferBinding;
273        binding->setBinding(m_iBind, vBuf);
274        const Ogre::VertexElement* posElem = vertexData->vertexDeclaration->getElement(m_iBind);
275        unsigned char* vertex = static_cast<unsigned char*>(vBuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
276        m_iBind++;
277
278
279        // Ok, Let´s fill in the buffer with data  :D
280
281        const Ogre::Vector3* data = (const Ogre::Vector3*)pMeshArray->Data();
282
283        Ogre::Real* pReal;
284        posElem->baseVertexPointerToElement(vertex, &pReal);
285
286        unsigned int j = 0;
287        for(unsigned int i=0; i< m_iNrVerts; i++) {
288
289                Ogre::Vector3 vert = data[i];
290
291                *pReal++ = vert.x;
292                *pReal++ = vert.y;
293                *pReal++ = vert.z;
294
295                // Bounding Sphere radius
296                m_MaxSquaredLength = std::max(m_MaxSquaredLength, vert.squaredLength());
297
298                // update AABB
299                m_AABB.merge( vert );
300        }
301        vBuf->unlock();
302
303        //Ogre::StringUtil::StrStreamType strStrm;
304        //strStrm << "Export: #Vertices: " << iNrVerts;
305        //Ogre::LogManager::getSingletonPtr()->logMessage(strStrm.str());
306       
307}
308
309void COgreMeshCompiler::CreateIndexBuffer( CIntermediateMesh* pIntermediateMesh )
310{
311        assert(pIntermediateMesh);
312
313        const CTriangleArray& triangleArray = pIntermediateMesh->GetTriangles();
314        int iNrTriangles = triangleArray.Size();
315
316        // allocate index buffer for each submesh
317        std::map<CIntermediateMaterial*, Ogre::SubMesh*>::iterator it = m_lMaterialSubMeshMap.begin();
318        while( it != m_lMaterialSubMeshMap.end() )
319        {
320                Ogre::SubMesh* pSubMesh = it->second;
321                CIntermediateMaterial* pMat = it->first;
322
323                std::vector< unsigned int > lMatTriangles;
324                pIntermediateMesh->GetTrianglesUsingMaterial( pMat, lMatTriangles);
325
326                int iNrIndices = lMatTriangles.size() *3;
327                pSubMesh->indexData->indexCount = iNrIndices;
328
329                // We should use a 32bit buffer if the vertex buffer has more than 65536 entries (otherwise we cannot reference them)
330                // From the vertex buffer decleration we know the vertex count:
331
332                m_IndexBitType = Ogre::HardwareIndexBuffer::IT_16BIT;
333                if(m_iNrVerts >= 65536)
334                        m_IndexBitType = Ogre::HardwareIndexBuffer::IT_32BIT;
335
336                pSubMesh->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(m_IndexBitType, pSubMesh->indexData->indexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
337
338                Ogre::HardwareIndexBufferSharedPtr iBuf = pSubMesh->indexData->indexBuffer;
339                pSubMesh->useSharedVertices = true;
340                it++;
341
342                // Ok, Let´s fill in the buffer with data  :D
343
344                // We lock the buffer before adding content
345                if(m_IndexBitType == Ogre::HardwareIndexBuffer::IT_32BIT)
346                {       // 32 Bit Index Buffer
347                        unsigned int* pIndices = static_cast<unsigned int*>(iBuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
348
349                        //Ogre::StringUtil::StrStreamType strStrm3;
350                        //strStrm3 << "Export: #Indices: " << iBuf->getNumIndexes();
351                        //Ogre::LogManager::getSingletonPtr()->logMessage(strStrm3.str());
352
353                        unsigned int j = 0;
354                        for(unsigned int i = 0; i< lMatTriangles.size(); i++) {
355
356                                const CTriangle& face = triangleArray[ lMatTriangles[i] ];
357
358                                // indices
359                                pIndices[j++] = face.m_Vertices[0];
360                                pIndices[j++] = face.m_Vertices[1];
361                                pIndices[j++] = face.m_Vertices[2];
362
363                                SetBoneAssignments(face,pIntermediateMesh);
364
365                                // skeleton
366
367
368                        }
369
370                        // Unlock
371                        iBuf->unlock();
372                }
373                else
374                {       // 16 Bit Index Buffer
375                        unsigned short* pIndices = static_cast<unsigned short*>(iBuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
376
377                        //Ogre::StringUtil::StrStreamType strStrm3;
378                        //strStrm3 << "Export: #Indices: " << iBuf->getNumIndexes();
379                        //Ogre::LogManager::getSingletonPtr()->logMessage(strStrm3.str());
380
381                        unsigned int j = 0;
382                        for(unsigned int i = 0; i< lMatTriangles.size(); i++) {
383
384                                const CTriangle& face = triangleArray[ lMatTriangles[i] ];
385
386                                // indices
387                                pIndices[j++] = face.m_Vertices[0];
388                                pIndices[j++] = face.m_Vertices[1];
389                                pIndices[j++] = face.m_Vertices[2];
390
391
392                                // skeleton
393                                SetBoneAssignments(face,pIntermediateMesh);
394                        }
395
396                        // Unlock
397                        iBuf->unlock();
398                }
399
400                if(pMat != NULL)
401                        pSubMesh->setMaterialName(pMat->GetName().c_str());
402                else
403                        pSubMesh->setMaterialName("NoMaterial");
404        }
405}
406
407void COgreMeshCompiler::SetBoneAssignments( const CTriangle& face, CIntermediateMesh* pIntermediateMesh )
408{
409        CIntermediateSkeleton* pISkel = pIntermediateMesh->GetSkeleton();
410        if(pISkel != NULL) {
411                Ogre::VertexBoneAssignment vertexBoneAssignment;
412
413                for (int w=0; w < 3; w++)
414                {
415                        int vertIndex = face.m_Vertices[w];//startIndex-3+w;
416                        int iBoneCount = pISkel->GetNrOfAssignmentsOnVertex(vertIndex);
417
418                        SVertexBoneData maxBoneData;
419                        maxBoneData.weight = 0;
420                        int maxVertIndex = 0;
421                        for (int i=0; i < iBoneCount; i++)
422                        {
423                                SVertexBoneData boneData;
424                                if(pISkel->GetVertexData(vertIndex,i,boneData))
425                                {
426                                        if(maxBoneData.weight < boneData.weight)
427                                                maxBoneData = boneData;
428
429                                        if(boneData.weight < 0.001f) continue;
430
431                                        vertexBoneAssignment.vertexIndex        = vertIndex;
432                                        vertexBoneAssignment.boneIndex          = boneData.boneIndex;
433                                        vertexBoneAssignment.weight                     = boneData.weight;
434       
435                                        m_pOgreMesh->addBoneAssignment(vertexBoneAssignment);
436                                }
437                        }
438                }
439        }
440}
441
442void COgreMeshCompiler::CreateNormalBuffer( CIntermediateMesh* pIntermediateMesh )
443{
444        assert(pIntermediateMesh);
445
446        CMeshArray* pNormalArray = pIntermediateMesh->GetArray("normal",0);
447        if(pNormalArray == NULL)
448                return;
449
450        int iNrNormals = pNormalArray->Size();
451
452        Ogre::VertexData* vertexData = m_pOgreMesh->sharedVertexData;
453        Ogre::VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
454
455        // normals
456        vertexDecl->addElement(m_iBind, 0, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
457
458        // allocate the normal vertex buffer
459        vertexData->vertexCount = iNrNormals;
460        Ogre::HardwareVertexBufferSharedPtr nBuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(m_iBind), vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
461        Ogre::VertexBufferBinding* binding = vertexData->vertexBufferBinding;
462        binding->setBinding(m_iBind, nBuf);
463        const Ogre::VertexElement* posElem = vertexData->vertexDeclaration->getElement(m_iBind);
464        unsigned char* vertex = static_cast<unsigned char*>(nBuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
465        m_iBind++;
466
467        Ogre::Real* pReal;
468        posElem->baseVertexPointerToElement(vertex, &pReal);
469
470        //Ogre::StringUtil::StrStreamType strStrm3;
471        //strStrm3 << "Export: #Normals2Export: " << iNrNormals;
472        //Ogre::LogManager::getSingletonPtr()->logMessage(strStrm3.str());
473
474        const Ogre::Vector3* data = (const Ogre::Vector3*)pNormalArray->Data();
475
476        int j = 0;
477        for (int i = 0 ; i < iNrNormals; i++)
478        {
479                const Ogre::Vector3& vert = data[i];
480
481                *pReal++ = vert.x;
482                *pReal++ = vert.y;
483                *pReal++ = vert.z;
484        }
485        nBuf->unlock();
486}
487
488void COgreMeshCompiler::CreateDiffuseBuffer( CIntermediateMesh* pIntermediateMesh )
489{
490        assert(pIntermediateMesh);
491
492        CMeshArray* pDiffuseArray = pIntermediateMesh->GetArray("diffuse",0);
493
494        bool bCleanUp = false;
495        if(pDiffuseArray == NULL)
496        {
497                LOGWARNING "No Vertex Colours defined, will export white colors on each vertex!.");
498
499                // Fallback on standard white.
500                unsigned int iVIndex = 0;
501                CVec4Array* pArray = new CVec4Array(m_iNrVerts);
502                bCleanUp = true;
503                for(unsigned int x = 0; x < m_iNrVerts; x++)
504                {
505                        Ogre::Vector4& vColor = (*pArray)[iVIndex++];
506                        vColor.x = 1.0f;
507                        vColor.y = 1.0f;
508                        vColor.z = 1.0f;
509                        vColor.w = 1.0f;
510                }
511                pDiffuseArray = pArray;
512        }
513
514        int iNrVerts = pDiffuseArray->Size();
515
516        Ogre::VertexData* vertexData = m_pOgreMesh->sharedVertexData;
517        Ogre::VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
518
519        // diffuse colours
520        vertexDecl->addElement(m_iBind, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
521
522        // allocate the diffuse vertex buffer
523        vertexData->vertexCount = iNrVerts;
524        int vsize = vertexDecl->getVertexSize(m_iBind);
525        Ogre::HardwareVertexBufferSharedPtr dBuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(m_iBind), vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
526        Ogre::VertexBufferBinding* binding = vertexData->vertexBufferBinding;
527        binding->setBinding(m_iBind, dBuf);
528        const Ogre::VertexElement* diffuseElem = vertexData->vertexDeclaration->getElement(m_iBind);
529        unsigned char* vertex = static_cast<unsigned char*>(dBuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
530        m_iBind++;
531
532        Ogre::ARGB* pReal;
533        diffuseElem->baseVertexPointerToElement(vertex, &pReal);
534
535        //Ogre::StringUtil::StrStreamType strStrm3;
536        //strStrm3 << "Export: #Diffuse2Export: " << iNrVerts;
537        //Ogre::LogManager::getSingletonPtr()->logMessage(strStrm3.str());
538
539        const Ogre::Vector4* data = (const Ogre::Vector4*)pDiffuseArray->Data();
540
541        for (int i = 0 ; i < iNrVerts; i++)
542        {
543                const Ogre::Vector4& vert = data[i];
544
545                *pReal++=       (((unsigned int)(vert.w*255.0))<<24)|
546                                        (((unsigned int)(vert.x*255.0))<<16)|
547                                        (((unsigned int)(vert.y*255.0))<<8)|
548                                        (((unsigned int)(vert.z*255.0)));
549        }
550        dBuf->unlock();
551
552        if(bCleanUp)
553                delete [] pDiffuseArray;
554}
555
556void COgreMeshCompiler::CreateTexCoordBuffer( CIntermediateMesh* pIntermediateMesh )
557{
558        assert(pIntermediateMesh);
559
560
561        unsigned int iUVIndex = 0;
562        for(unsigned int x = 1; x <= 99; x++)
563        {
564                char temp[32];
565                sprintf(temp, "uv%i", x);
566                CMeshArray* pUVArray = pIntermediateMesh->GetArray(temp,0);
567                iUVIndex = x;
568
569                if(pUVArray == NULL)
570                        continue;
571
572                //Ogre::String msg = Ogre::String("Exporting UV Channel: ")+Ogre::String(temp);
573                //Ogre::LogManager::getSingletonPtr()->logMessage(msg);
574
575
576                int iNrUVs = pUVArray->Size();
577
578                Ogre::VertexData* vertexData = m_pOgreMesh->sharedVertexData;
579                Ogre::VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
580
581                // normals
582                vertexDecl->addElement(m_iBind, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES,iUVIndex-1);
583
584                // allocate the position vertex buffer
585                vertexData->vertexCount = iNrUVs;
586                Ogre::HardwareVertexBufferSharedPtr uvBuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(vertexDecl->getVertexSize(m_iBind), vertexData->vertexCount, Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
587                Ogre::VertexBufferBinding* binding = vertexData->vertexBufferBinding;
588                binding->setBinding(m_iBind, uvBuf);
589
590                const Ogre::VertexElement* uvElem = vertexData->vertexDeclaration->getElement(m_iBind);
591                unsigned char* vertex = static_cast<unsigned char*>(uvBuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
592                m_iBind++;
593
594                Ogre::Real* pReal;
595                uvElem->baseVertexPointerToElement(vertex, &pReal);
596
597                const Ogre::Vector2* data = (const Ogre::Vector2*)pUVArray->Data();
598
599                for (int i = 0 ; i < iNrUVs; i++)
600                {
601                        const Ogre::Vector2& vert = data[i];
602                        *pReal++= vert.x;
603                        *pReal++= vert.y;
604                }
605                uvBuf->unlock();
606               
607        }
608}
609
610void COgreMeshCompiler::CreateMeshBounds( void )
611{
612        Ogre::Real width = Ogre::Math::Sqrt(m_MaxSquaredLength);
613        m_pOgreMesh->_setBounds(m_AABB);
614        m_pOgreMesh->_setBoundingSphereRadius(width);
615}
616
617void COgreMeshCompiler::PrintVertexDataToLog( void )
618{
619        Ogre::VertexData* vertexData = m_pOgreMesh->sharedVertexData;
620        Ogre::VertexDeclaration* vertexDecl = vertexData->vertexDeclaration;
621
622        Ogre::Real* pReal;
623        const Ogre::VertexElement* posElem = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
624        Ogre::HardwareVertexBufferSharedPtr vBuf = vertexData->vertexBufferBinding->getBuffer(posElem->getSource());
625        unsigned char* vertex = static_cast<unsigned char*>(vBuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
626
627        for(size_t j = 0; j < vertexData->vertexCount; ++j, vertex += vBuf->getVertexSize())
628        {
629                posElem->baseVertexPointerToElement(vertex, &pReal);
630                Ogre::StringUtil::StrStreamType str;
631                str << "x: " << (*pReal++) << "\ty: " << (*pReal++) << "\tz:" << (*pReal++);
632                Ogre::LogManager::getSingletonPtr()->logMessage( str.str());
633        }
634}
635
636bool COgreMeshCompiler::WriteOgreMesh( const Ogre::String& sFilename )
637{
638        assert(Ogre::MeshManager::getSingletonPtr());
639
640        Ogre::MeshSerializer* pMeshWriter = new Ogre::MeshSerializer();
641        try
642        {       
643                pMeshWriter->exportMesh(m_pOgreMesh.get(), sFilename);
644        }
645        catch (Ogre::Exception& e)
646        {
647                LOGERROR "OgreException: %s", e.getFullDescription().c_str());
648//              MessageBox( NULL, e.getFullDescription().c_str(), "ERROR", MB_ICONERROR);
649                return false;
650        } catch(...)
651        {
652                LOGERROR "Unhandled exception caught in COgreMeshCompiler::WriteOgreMesh()");
653        }
654        delete pMeshWriter;
655
656        //if(m_bExportSkeleton)
657        //      if( !m_pSkeletonCompiler->WriteOgreSkeleton( sFilename+".skeleton") )
658        //              return false;
659
660        return true;
661}
662
663Ogre::MeshPtr COgreMeshCompiler::GetOgreMesh( void )
664{
665        return m_pOgreMesh;
666}
667
668void COgreMeshCompiler::CreatePoseBuffers( CIntermediateMesh* pIntermediateMesh )
669{
670        // Create static pose data
671        unsigned int iPoseCount = pIntermediateMesh->GetPoseCount();
672        for(unsigned int i=0; i<iPoseCount; i++)
673        {
674                Ogre::String poseName;
675                unsigned int iFrame;
676                bool bOptimize;
677                pIntermediateMesh->GetPose(i, poseName, iFrame,bOptimize);
678                iFrame *= GetTicksPerFrame();
679
680                CreatePose(pIntermediateMesh, poseName, iFrame, bOptimize );
681        }
682
683        // Create pose animations
684        unsigned int iPoseAnimCount = pIntermediateMesh->GetPoseAnimCount();
685        for(unsigned int i=0; i<iPoseAnimCount; i++)
686        {
687                Ogre::String animName;
688                unsigned int iStartFrame;
689                unsigned int iEndFrame;
690                float fRate;
691                bool bOptimize;
692                pIntermediateMesh->GetPoseAnimation(i, animName, iStartFrame, iEndFrame, fRate, bOptimize);
693
694                float fps = 1.0 / float(GetFrameRate());
695                float fAnimLength = (iEndFrame - iStartFrame) * fps;
696
697                Ogre::Animation* pAnim = m_pOgreMesh->createAnimation(animName,fAnimLength);
698                Ogre::VertexAnimationTrack* pTrack = pAnim->createVertexTrack(0, Ogre::VAT_POSE);
699
700                float x = iStartFrame;
701                int frameCount = 0;
702                while(x <= iEndFrame)
703                {
704                        float time = (x- iStartFrame)*fps; // local in this animation
705                        Ogre::VertexPoseKeyFrame* pKeyFrame = pTrack->createVertexPoseKeyFrame(time);
706
707                        Ogre::String poseName = animName;
708                        poseName += "_";
709                        poseName += Ogre::StringConverter::toString(frameCount++);
710                        unsigned int poseID = CreatePose(pIntermediateMesh, poseName, x*GetTicksPerFrame(), bOptimize );
711
712                        pKeyFrame->addPoseReference(poseID,1.0f);
713
714                        x += fRate;
715                }
716
717                if(bOptimize)
718                        pAnim->optimise();
719        }
720}
721
722unsigned int COgreMeshCompiler::CreatePose( CIntermediateMesh* pIntermediateMesh, Ogre::String poseName, unsigned int iFrame, bool bOptimize )
723{
724        Ogre::Pose* pPose = m_pOgreMesh->createPose(0 /*shared geometry buffer*/, poseName);
725
726        if(iFrame != 0) // then the pose is the same as the reference, so nothing is needed to be checked
727        {
728                CMeshArray* pVerts = new CVec3Array();
729                CMeshArray* pTmpBuf = pIntermediateMesh->GetArray("position", iFrame);
730                pVerts->Create(pTmpBuf->Size(), pTmpBuf->Data());
731
732                CMeshArray* pOrigVerts = new CVec3Array();
733                pTmpBuf = pIntermediateMesh->GetArray("position", 0);
734                pOrigVerts->Create(pTmpBuf->Size(), pTmpBuf->Data());
735               
736                if(m_bReindex)
737                {
738                                SharedUtilities::fastvector< CMeshArray* > bufferList;
739
740                                bufferList.push_back(pVerts);
741                                bufferList.push_back(pOrigVerts);
742
743                                pIntermediateMesh->PostReindex( bufferList );
744                }
745
746                const Ogre::Vector3* data = (const Ogre::Vector3*)pVerts->Data();
747                const Ogre::Vector3* origData = (const Ogre::Vector3*)pOrigVerts->Data();
748                for(unsigned int j=0; j< pVerts->Size(); j++)
749                {
750                        Ogre::Vector3 vert = data[j];
751                        Ogre::Vector3 origVert = origData[j];
752
753                        vert = vert - origVert;
754
755                        if( !bOptimize )
756                        {
757                                pPose->addVertex(j,vert);
758                        }
759                        else if(vert != Ogre::Vector3::ZERO)
760                                pPose->addVertex(j,vert);
761                }
762
763                delete pOrigVerts;
764                delete pVerts;
765        }
766        else
767        {
768                // ensure the buffer is clean (been known to be polluted right after creation)
769                pPose->clearVertexOffsets();
770        }
771
772        return m_iNrPoses++;
773}
Note: See TracBrowser for help on using the repository browser.