Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogre/Tools/3dsmaxExport/LEXIExporter/LexiExport/Sources/LexiIntermediateMesh.cpp @ 45

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

=…

File size: 10.5 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 "LexiIntermediateAPI.h"
29
30//
31
32const Ogre::String& CIntermediateMesh::getMovableType(void) const
33{
34        static Ogre::String sTypeName = "CIntermediateMesh";
35        return sTypeName;
36}
37
38const Ogre::AxisAlignedBox& CIntermediateMesh::getBoundingBox(void) const
39{
40        static Ogre::AxisAlignedBox aab;
41        return aab;
42}
43
44Ogre::Real CIntermediateMesh::getBoundingRadius(void) const
45{
46        return 0.0f;
47}
48
49void CIntermediateMesh::_updateRenderQueue(Ogre::RenderQueue* queue)
50{
51}
52
53///////////////////////////////////////////////////////////
54
55CIntermediateMesh::CIntermediateMesh(unsigned int iNumTriangles, unsigned int iNodeID) : MovableObject(GetNodeFromID(iNodeID)->GetName())
56{
57        m_iNodeID = iNodeID;
58        m_bIsCollapsed = false;
59
60        m_Triangles.Create(iNumTriangles);
61        m_iNumTriangles = iNumTriangles;
62        m_pISkeleton = NULL;
63
64        m_pIndexTable = NULL;
65        m_pPickIndexTable = NULL;
66        m_iIndexCount = 0;
67
68}
69
70CIntermediateMesh::~CIntermediateMesh()
71{
72        for(ArrayMap::iterator it = m_Arrays.begin(); it != m_Arrays.end(); it++)
73        {
74                MeshArray* pArray = it->second;
75                delete pArray->m_pArray;
76                delete pArray;
77        }
78        m_Arrays.clear();
79
80        delete [] m_pIndexTable;
81        delete [] m_pPickIndexTable;
82}
83
84//
85
86unsigned int CIntermediateMesh::GetNumTriangles() const
87{
88        return m_iNumTriangles;
89}
90
91//
92
93CTriangle& CIntermediateMesh::GetTriangle(unsigned int iIndex)
94{
95        return m_Triangles[iIndex];
96}
97
98const CTriangle& CIntermediateMesh::GetTriangle(unsigned int iIndex) const
99{
100        return m_Triangles[iIndex];
101}
102
103//
104
105CTriangleArray& CIntermediateMesh::GetTriangles()
106{
107        return m_Triangles;
108}
109
110const CTriangleArray& CIntermediateMesh::GetTriangles() const
111{
112        return m_Triangles;
113}
114
115void CIntermediateMesh::SetSkeleton( CIntermediateSkeleton* pSkel )
116{
117        m_pISkeleton = pSkel;
118}
119
120CIntermediateSkeleton* CIntermediateMesh::GetSkeleton( void )
121{
122        return m_pISkeleton;
123}
124
125//
126bool CIntermediateMesh::AddPose(Ogre::String name, unsigned int frame, bool bOptimize)
127{
128        std::map<Ogre::String, PoseData>::const_iterator it = m_lPoseList.find(name);
129
130        if(it == m_lPoseList.end() )
131        {
132                PoseData newData;
133                newData.m_bOptimize = bOptimize;
134                newData.m_iTime = frame;
135                newData.m_sPoseName = name;
136                m_lPoseList.insert( std::pair<Ogre::String, PoseData>(name,newData) );
137                return true;
138        }
139
140        return false;
141}
142
143bool CIntermediateMesh::HasPoseData( void )
144{
145        if( (m_lPoseList.size() != 0) || (m_lPoseAnims.size() != 0))
146                return true;
147        return false;
148}
149
150unsigned int CIntermediateMesh::GetPoseCount( void )
151{
152        return m_lPoseList.size();
153}
154
155bool CIntermediateMesh::GetPose(unsigned int index, Ogre::String& poseName, unsigned int& frameRef, bool& optimize )
156{
157        if( index < m_lPoseList.size() )
158        {
159                std::map< Ogre::String, PoseData>::iterator it = m_lPoseList.begin();
160
161                while(index > 0)
162                {
163                        index--;
164                        it ++;
165                }
166                poseName = it->second.m_sPoseName;
167                frameRef = it->second.m_iTime;
168                optimize = it->second.m_bOptimize;
169                return true;
170        }
171
172        return false;
173}
174
175bool CIntermediateMesh::AddPoseAnimation(const char* pszAnimName, unsigned int iStartFrame, unsigned int iEndFrame, float fRate, bool bOptimize)
176{
177        std::map<Ogre::String, PoseAnimData>::const_iterator it = m_lPoseAnims.find(pszAnimName);
178
179        if(it == m_lPoseAnims.end() )
180        {
181                PoseData newData;
182                newData.m_bOptimize = bOptimize;
183                newData.m_iTime = 0;
184                newData.m_sPoseName = "";
185
186                PoseAnimData newAnimData;
187                newAnimData.m_poseData = newData;
188                newAnimData.m_sAnimName = pszAnimName;
189                newAnimData.m_iStartFrame = iStartFrame;
190                newAnimData.m_iEndFrame = iEndFrame;
191                newAnimData.m_fSampleRate = fRate;
192
193                m_lPoseAnims.insert( std::pair<Ogre::String, PoseAnimData>(pszAnimName,newAnimData) );
194                return true;
195        }
196
197        return false;
198}
199
200unsigned int CIntermediateMesh::GetPoseAnimCount( void )
201{
202        return m_lPoseAnims.size();
203}
204
205bool CIntermediateMesh::GetPoseAnimation(unsigned int index, Ogre::String& poseName, unsigned int& iStartFrame, unsigned int& iEndFrame, float& fRate, bool& bOptimize)
206{
207        if( index < m_lPoseAnims.size() )
208        {
209                std::map<Ogre::String, PoseAnimData>::const_iterator it = m_lPoseAnims.begin();
210
211                while(index > 0)
212                {
213                        index--;
214                        it ++;
215                }
216                poseName = it->second.m_sAnimName;
217                iStartFrame = it->second.m_iStartFrame;
218                iEndFrame = it->second.m_iEndFrame;
219                bOptimize = it->second.m_poseData.m_bOptimize;
220                fRate = it->second.m_fSampleRate;
221                return true;
222        }
223
224        return false;
225}
226//
227
228void CIntermediateMesh::ForceCreateArray(const char* pszName)
229{
230        unsigned int iNumVertices = m_iNumTriangles * 3;
231
232        CMeshArray* pArray = NULL;
233        if(!stricmp(pszName, "position") || !stricmp(pszName, "normal"))
234        {
235                pArray = new CVec3Array(iNumVertices);
236        }
237        else if(!stricmp(pszName, "diffuse") || !stricmp(pszName, "specular"))
238        {
239                pArray = new CVec4Array(iNumVertices);
240        }
241        else
242        {
243                char temp[16];
244
245                for(unsigned int x = 1; x <= 99; x++)
246                {
247                        sprintf(temp, "uv%i", x);
248                        if(!stricmp(pszName, temp))
249                        {
250                                pArray = new CVec2Array(iNumVertices);
251                                break;
252                        }
253                }
254        }
255
256        if(pArray) pArray->Zero();
257
258        MeshArray* pMA = new MeshArray;
259        pMA->m_iTime = 0;
260        pMA->m_pArray = pArray;
261        m_Arrays.insert(ArrayMap::value_type(pszName, pMA));
262}
263
264//
265
266CMeshArray* CIntermediateMesh::GetArray(const char* pszName, TimeValue iTime)
267{
268        ArrayMap::iterator it = m_Arrays.find(pszName);
269        if(it != m_Arrays.end())
270        {
271                const MeshArray* pMA = it->second;
272                if(pMA->m_iTime == iTime) return pMA->m_pArray;
273
274                delete pMA->m_pArray;
275                delete pMA;
276                m_Arrays.erase(it);
277        }
278
279        CMeshArray* pArray = CIntermediateBuilder::Get()->BuildMeshArray(m_iNodeID, pszName, iTime);
280
281        MeshArray* pMA = new MeshArray;
282        pMA->m_iTime = iTime;
283        pMA->m_pArray = pArray;
284        m_Arrays.insert(ArrayMap::value_type(pszName, pMA));
285
286        return pArray;
287}
288
289bool CIntermediateMesh::IsCollapsed( void )
290{
291        return m_bIsCollapsed;
292}
293
294//
295
296unsigned int CIntermediateMesh::GetNumMaterials() const
297{
298        return m_Materials.size();
299}
300
301CIntermediateMaterial* CIntermediateMesh::GetMaterial(unsigned int iIndex) const
302{
303        return m_Materials[iIndex];
304}
305
306//
307
308static fastvector<CMeshArray*> _CmpList;
309static unsigned int _iCmpListSize;
310
311class vertexcmp {
312
313        public:
314
315                bool operator () (const unsigned int& a, const unsigned int& b) const
316                {
317                        for(unsigned int x = 0; x < _iCmpListSize; x++)
318                        {
319                                CMeshArray* pArray = _CmpList[x];
320                                int r = memcmp(pArray->Data(a), pArray->Data(b), pArray->ElementSize());
321                                if(r < 0) return true;
322                                else if(r > 0) return false;
323                        }
324
325                        return false;
326                }
327
328};
329
330typedef std::map<unsigned int, unsigned int, vertexcmp> vertexmap;
331
332//
333
334void CIntermediateMesh::Reindex(const fastvector<CMeshArray*>& ArrayList)
335{
336        _iCmpListSize = ArrayList.size();
337        if(!_iCmpListSize) return;
338
339        // We assume the first element contains exactly all verticies
340        unsigned int iNumVertices = ArrayList[0]->Size();
341        if(!iNumVertices) return;
342
343        _CmpList = ArrayList;
344
345        if(m_pIndexTable != NULL)
346                delete [] m_pIndexTable;
347        if(m_pPickIndexTable != NULL)
348                delete [] m_pPickIndexTable;
349
350
351        m_pIndexTable = new unsigned int[iNumVertices];
352        m_pPickIndexTable = new unsigned int[iNumVertices];
353
354        //
355
356        vertexmap crcmap;
357        m_iIndexCount = 0;
358
359        for(unsigned int x = 0; x < iNumVertices; x++)
360        {
361                vertexmap::iterator it = crcmap.find(x);
362                if(it != crcmap.end())
363                {
364                        m_pIndexTable[x] = it->second;
365                }
366                else
367                {
368                        m_pIndexTable[x] = m_iIndexCount;
369                        m_pPickIndexTable[m_iIndexCount++] = x;
370                        crcmap.insert(vertexmap::value_type(x, crcmap.size()));
371                }
372        }
373
374        // Keep only the buffer entries which are to be used together with the new indices.
375
376        for(unsigned int x = 0; x < _iCmpListSize; x++)
377        {
378                CMeshArray* pArray = _CmpList[x];
379
380                unsigned int iElemSize = pArray->ElementSize();
381                unsigned char* pTarget = new unsigned char[m_iIndexCount * iElemSize];
382
383                for(unsigned int y = 0; y < m_iIndexCount; y++)
384                {
385                        memcpy(pTarget + (y * iElemSize), pArray->Data(m_pPickIndexTable[y]), iElemSize);
386                }
387
388                pArray->Create(m_iIndexCount, pTarget);
389                delete []pTarget;
390        }
391
392        //
393
394        for(unsigned int x = 0; x < m_iNumTriangles; x++)
395        {
396                CTriangle& tri = m_Triangles[x];
397                unsigned int& t1 = tri.m_Vertices[0];
398                unsigned int& t2 = tri.m_Vertices[1];
399                unsigned int& t3 = tri.m_Vertices[2];
400
401//              if(m_pISkeleton) m_pISkeleton->PrepareReindexChange(t1, m_pIndexTable[t1]);
402                t1 = m_pIndexTable[t1];
403
404//              if(m_pISkeleton) m_pISkeleton->PrepareReindexChange(t2, m_pIndexTable[t2]);
405                t2 = m_pIndexTable[t2];
406
407//              if(m_pISkeleton) m_pISkeleton->PrepareReindexChange(t3, m_pIndexTable[t3]);
408                t3 = m_pIndexTable[t3];
409        }
410
411        //
412
413        //delete []pIndexTable;
414        //delete []pPickIndexTable;
415
416        //if(m_pISkeleton) m_pISkeleton->ApplyReindexChanges();
417       
418}
419
420void CIntermediateMesh::PostReindex(const fastvector<CMeshArray*>& ArrayList)
421{       
422        for(unsigned int x = 0; x < ArrayList.size(); x++)
423        {
424                CMeshArray* pArray = ArrayList[x];
425
426                unsigned int iElemSize = pArray->ElementSize();
427                unsigned char* pTarget = new unsigned char[m_iIndexCount * iElemSize];
428
429                for(unsigned int y = 0; y < m_iIndexCount; y++)
430                {
431                        memcpy(pTarget + (y * iElemSize), pArray->Data(m_pPickIndexTable[y]), iElemSize);
432                }
433
434                pArray->Create(m_iIndexCount, pTarget);
435                delete []pTarget;
436        }
437}
438
439//
440
441void CIntermediateMesh::GetTrianglesUsingMaterial(CIntermediateMaterial* pMaterial, std::vector<unsigned int>& Triangles) const
442{
443        Triangles.clear();
444
445        for(unsigned int x = 0; x < m_iNumTriangles; x++)
446        {
447                const CTriangle& tri = m_Triangles[x];
448                if(tri.m_pMaterial == pMaterial) Triangles.push_back(x);
449        } 
450}
451
452void CIntermediateMesh::BuildMaterialList( void )
453{
454        m_Materials.clear();
455
456        for(unsigned int x = 0; x < m_iNumTriangles; x++)
457        {
458                CIntermediateMaterial* pMat = m_Triangles[x].m_pMaterial;
459
460                bool bMatExists = false;
461                for ( int i =0; i < m_Materials.size(); i++)
462                {
463                        if(m_Materials[i] == pMat)
464                                bMatExists = true;
465                }
466                if(!bMatExists)
467                        m_Materials.push_back(pMat);
468        } 
469}
470
471//
472
Note: See TracBrowser for help on using the repository browser.