Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

=…

File size: 11.1 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
32CIntermediateSkeleton::CIntermediateSkeleton()
33{
34}
35
36CIntermediateSkeleton::~CIntermediateSkeleton()
37{
38        clear();
39}
40
41//
42
43void CIntermediateSkeleton::clear()
44{
45        unsigned int iCount = m_BoneList.size();
46        for(unsigned int x = 0; x < iCount; x++)
47        {
48                CIntermediateBone* pBone = m_BoneList[x];
49                delete pBone;
50        }
51        m_BoneList.clear();
52        m_RootBoneList.clear();
53        m_BoneNameList.clear();
54        m_VertexBoneData.clear();
55}
56
57//
58
59void CIntermediateSkeleton::SetFPS(float fFPS)
60{
61        m_fFPS = fFPS;
62}
63
64float CIntermediateSkeleton::GetFPS() const
65{
66        return m_fFPS;
67}
68
69//
70
71unsigned int CIntermediateSkeleton::GetBoneCount() const
72{
73        return m_BoneList.size();
74}
75
76CIntermediateBone* CIntermediateSkeleton::GetBone(unsigned int iBone)
77{
78        return m_BoneList[iBone];
79}
80
81const CIntermediateBone* CIntermediateSkeleton::GetBone(unsigned int iBone) const
82{
83        return m_BoneList[iBone];
84}
85
86std::string CIntermediateSkeleton::GetBoneName(unsigned int iBone) const
87{
88        return m_BoneList[iBone]->GetName();
89}
90
91CIntermediateBone* CIntermediateSkeleton::GetBoneByName( const char* pszName ) const
92{
93        std::map<std::string, CIntermediateBone*>::const_iterator iter = m_BoneNameList.find( pszName );
94        if(iter != m_BoneNameList.end())
95                return iter->second;
96        else
97                return NULL;
98}
99
100CIntermediateBone* CIntermediateSkeleton::GetBoneByIndex( int index ) const
101{
102        std::map<int, CIntermediateBone*>::const_iterator iter = m_IndexedBoneList.find( index );
103        if(iter != m_IndexedBoneList.end())
104                return iter->second;
105        else
106                return NULL;
107}
108
109void CIntermediateSkeleton::AddBone(CIntermediateBone* pBone, const char* pszName)
110{
111        m_BoneList.push_back(pBone);
112        //m_BoneNameList.push_back(pszName);
113        m_BoneNameList.insert( std::pair<std::string, CIntermediateBone*>(pBone->GetName(),pBone) );
114        m_BoneHandles.insert( std::pair<ULONG, CIntermediateBone*>(pBone->GetHandle(), pBone));
115}
116
117bool CIntermediateSkeleton::AssembleBones( void )
118{
119        if(m_BoneList.empty())
120                PopulateBoneHandleMap();
121        if(m_BoneList.empty())
122                return false; // still nothing to process
123
124        std::vector<CIntermediateBone*>::iterator iter = m_BoneList.begin();
125
126        while (iter != m_BoneList.end())
127        {
128                RecursiveAssembleBones(*iter);
129                iter++;
130        }
131
132        return true;
133}
134
135bool CIntermediateSkeleton::RecursiveAssembleBones( CIntermediateBone* pIBone )
136{
137        ULONG parentHandle = pIBone->GetParentHandle();
138
139        CIntermediateBone* parent = FindBone( parentHandle );
140        if(parent)
141                parent->AddBone( pIBone );
142
143        return true;
144}
145
146void CIntermediateSkeleton::PopulateBoneHandleMap( void )
147{
148        std::vector<CIntermediateBone*>::iterator iter = m_BoneList.begin();
149
150        while (iter != m_BoneList.end())
151        {
152                RecursivePopulateBoneHandleMap(*iter);
153                iter++;
154        }
155}
156
157void CIntermediateSkeleton::BuildIndexedBoneList( void )
158{
159        std::vector<CIntermediateBone*>::iterator iter = m_BoneList.begin();
160
161        while (iter != m_BoneList.end())
162        {
163                m_IndexedBoneList.insert( std::pair<int, CIntermediateBone*>( (*iter)->GetIndex(), *iter));
164                iter++;
165        }
166}
167
168void CIntermediateSkeleton::RecursivePopulateBoneHandleMap( CIntermediateBone* pIBone )
169{
170        m_BoneHandles.insert( std::pair<ULONG, CIntermediateBone*>(pIBone->GetHandle(), pIBone));
171
172        for (int i = 0; i < pIBone->GetBoneCount(); i++)
173        {
174                RecursivePopulateBoneHandleMap(pIBone->GetBone(i));
175        }
176}
177
178CIntermediateBone* CIntermediateSkeleton::FindBone( ULONG handle )
179{
180        std::map<ULONG,CIntermediateBone*>::iterator iter = m_BoneHandles.find( handle );
181
182        if(iter != m_BoneHandles.end())
183                return iter->second;
184
185        return NULL;
186}
187
188int CIntermediateSkeleton::GetNrOfAssignmentsOnVertex( int idx )
189{
190        std::map< int, std::vector<SVertexBoneData> >::iterator iter = m_VertexBoneData.find( idx );
191
192        if( iter != m_VertexBoneData.end() )
193        {
194                return iter->second.size();
195        }
196
197        return 0;
198}
199
200void CIntermediateSkeleton::TrimVertexAssignments( int iMaxAssignments )
201{
202       
203        std::map< int, std::vector<SVertexBoneData> >::iterator iter = m_VertexBoneData.begin();
204
205        // throw the lowest weighted away
206        while( iter != m_VertexBoneData.end() )
207        {
208                if(iter->second.size() >= iMaxAssignments)
209                {
210                        LOGWARNING "Too Many Vertex Bone assignments (max: %i).. ignoring the lowest weights..", iMaxAssignments);
211
212
213                        sort(iter->second.begin(), iter->second.end() );
214
215                        int popCount = iter->second.size() - iMaxAssignments;
216                        while(popCount != 0)
217                        {
218                                iter->second.pop_back();
219                                popCount--;
220                        }
221
222                }
223                iter++;
224        }
225       
226}
227
228void CIntermediateSkeleton::NormalizeVertexAssignments( void )
229{
230        std::map< int, std::vector<SVertexBoneData> >::iterator iter = m_VertexBoneData.begin();
231
232        // normalize
233        while( iter != m_VertexBoneData.end() )
234        {
235                std::vector<SVertexBoneData>::iterator it = iter->second.begin();
236                std::vector<SVertexBoneData>::iterator iend = iter->second.end();
237
238                float fTotal=0;
239                for(; it != iend; ++it) {
240                        SVertexBoneData& vertexBoneData = (*it);
241                        fTotal+=vertexBoneData.weight;         
242                }
243
244                if( (fTotal!=0) && (fTotal!=1) ) {
245                        it = iter->second.begin();
246                        for(; it != iend; ++it) {
247                                SVertexBoneData& vertexBoneData = (*it);
248                                vertexBoneData.weight/=fTotal;
249                        }       
250                }
251                iter++;
252        }
253}
254
255bool CIntermediateSkeleton::GetVertexData( int idx, int assignmentNr, SVertexBoneData& returnVal )
256{
257        std::map< int, std::vector<SVertexBoneData> >::iterator iter = m_VertexBoneData.find( idx );
258
259        if( iter != m_VertexBoneData.end() )
260        {
261                if(     iter->second[assignmentNr].bRead != true )
262                {
263                        returnVal.boneIndex = iter->second[assignmentNr].boneIndex;
264                        returnVal.weight = iter->second[assignmentNr].weight;
265                        iter->second[assignmentNr].bRead = true;
266                        return true;
267                }
268        }
269
270        return false;
271}
272
273bool CIntermediateSkeleton::AddVertexData( int idx, SVertexBoneData vertexData )
274{
275        std::map< int, std::vector<SVertexBoneData> >::iterator iter = m_VertexBoneData.find( idx );
276
277        if( iter != m_VertexBoneData.end() )
278        {
279                iter->second.push_back(vertexData);
280                return true;
281        }
282        else
283        {
284                std::vector<SVertexBoneData> newlist;
285                newlist.push_back(vertexData);
286                m_VertexBoneData.insert( std::pair<int, std::vector<SVertexBoneData>>(idx,newlist) );
287                return true;
288        }
289
290        return false;
291}
292
293typedef std::map< int, std::vector<SVertexBoneData> > vertexMap;
294typedef CTMeshArray<SVertexBoneData> CDataArray;
295
296void CIntermediateSkeleton::ExtractVertexAssignmentsArrays( SharedUtilities::fastvector< CMeshArray* > &bufferList )
297{
298        short MAX_BONE_INDEX = 3;
299        //short boneNr = 0;
300        unsigned int iIndexCount = m_VertexBoneData.size();
301
302        CDataArray* pArray;
303
304        for(int i=0; i < MAX_BONE_INDEX; i++)
305        {
306                pArray = new CDataArray(iIndexCount);
307               
308                vertexMap::const_iterator it = m_VertexBoneData.begin();
309
310                for(int j=0; j < iIndexCount; j++)
311                {
312                        std::vector<SVertexBoneData> curList = it->second;
313                        SVertexBoneData curData;
314
315                        if( i < curList.size())
316                                curData = curList[i];
317                        else
318                        {
319                                curData.boneIndex = 0xFFFFFFFF;
320                                curData.weight = 0xFFFFFFFF;
321                        }
322
323                        (*pArray)[j] = curData;
324                        it++;
325                }
326                bufferList.push_back(pArray);
327        }
328}
329
330/** Apply new assignments based on the arrays given.
331        The new arrays must fit the original index count.
332*/
333bool CIntermediateSkeleton::ApplyVertexAssignmentsArrays( SharedUtilities::fastvector< CMeshArray* > &bufferList )
334{
335        short MAX_BONE_INDEX = 3;
336        CDataArray* pArray;
337
338        if(bufferList.size()> MAX_BONE_INDEX)
339                return false;
340
341        m_VertexBoneData.clear();
342
343        for(int i=0; i < bufferList.size(); i++)
344        {
345                pArray = dynamic_cast<CDataArray*>(bufferList[i]);
346
347                for(int j=0; j < pArray->Size(); j++)
348                {
349                        SVertexBoneData curData = (*pArray)[j];
350                        if(curData.boneIndex != 0xFFFFFFFF)
351                                AddVertexData(j,curData);
352                }
353        }
354        return true;
355}
356/*
357bool CIntermediateSkeleton::PrepareReindexChange( int oldIndex, int newIndex )
358{
359        std::map< int, std::vector<SVertexBoneData> >::iterator iter = m_VertexBoneData.find( oldIndex );
360
361        if( iter != m_VertexBoneData.end() )
362        {
363                std::map< int, std::vector<SVertexBoneData> >::iterator iter2 = m_ReindexVertexBoneData.find( newIndex );
364                if( iter2 != m_ReindexVertexBoneData.end() )
365                {
366                        // we already have a record on this index.. so we append
367                        // NO! WE DON`T
368                        //while(!iter->second.empty())
369                        //{
370                        //      iter2->second.push_back(iter->second.back());
371                        //      iter->second.pop_back();
372                        //}
373                        //return true;
374                }
375                else
376                {
377                        m_ReindexVertexBoneData.insert( std::pair<int, std::vector<SVertexBoneData>>(newIndex,iter->second) );
378                        return true;
379                }
380        }
381
382        return false;
383}
384
385bool CIntermediateSkeleton::ApplyReindexChanges( void )
386{
387        m_VertexBoneData.clear();
388        m_VertexBoneData = m_ReindexVertexBoneData;
389        m_ReindexVertexBoneData.clear();
390        return true;
391}
392*/
393void CIntermediateSkeleton::MarkBoneAsRoot( CIntermediateBone* pIBone )
394{
395        m_RootBoneList.push_back( pIBone );
396}
397
398const std::vector<CIntermediateBone*>& CIntermediateSkeleton::GetRootBones( void ) const
399{
400        return m_RootBoneList;
401}
402
403
404std::string CIntermediateSkeleton::ToString( void )
405{
406        std::stringstream str;
407        str << "\n";
408        print( str, m_RootBoneList.front() );
409
410        print( str, m_RootBoneList.front(), 0 ); // obsolete since multiple animation support added
411
412        return str.str();
413}
414
415void CIntermediateSkeleton::print( std::stringstream& output, CIntermediateBone* pBone, int indent)
416{
417        for (int i=0; i <= indent; i++)
418                output << "\t";
419
420        output << pBone->GetName() << "(" << pBone->GetHandle() << ")" << "[" << pBone->GetIndex() << "]" << "\n";
421
422        for (int j = 0; j < pBone->GetBoneCount(); j++)
423                print(output, pBone->GetBone(j), indent+1);
424}
425
426void CIntermediateSkeleton::printAnimationData( std::stringstream& output, CIntermediateBone* pBone, int indent)
427{
428        for (int i=0; i <= indent; i++)
429                output << "\t";
430
431        output << pBone->GetName() << "(" << pBone->GetHandle() << ")" << "[" << pBone->GetIndex() << "]" << "\n";
432       
433        //Ogre::Vector3 vPos, vScale;
434        //float fTimeInSecs;
435        //Ogre::Quaternion qOri;
436
437        //for (int j =0; j < pBone->GetFrameCount(); j++)
438        //{
439        //      pBone->GetFrame(j, fTimeInSecs, vPos, qOri, vScale);
440
441        //      for (int i=0; i <= indent; i++) output << "\t";
442        //      output << "Frame: " << j << "\t" << " time:" << Ogre::StringConverter::toString(fTimeInSecs)
443        //              << "\t" << "(" << Ogre::StringConverter::toString(vPos) << ")"
444        //              << "\t" << "(" << Ogre::StringConverter::toString(qOri) << ")"
445        //              << "\t" << "(" << Ogre::StringConverter::toString(vScale) << ")" << "\n";
446        //}
447        //output << "\t" << "\n";
448
449        //for (int j = 0; j < pBone->GetBoneCount(); j++)
450        //      printAnimationData(output, pBone->GetBone(j), indent+1);
451}
452
453
454//
455
Note: See TracBrowser for help on using the repository browser.