source: OGRE/trunk/ogrenew/Tools/dotXSIConverter/src/Exporter.cpp @ 657

Revision 657, 23.2 KB checked in by mattausch, 19 years ago (diff)

added ogre dependencies and patched ogre sources

Line 
1#include "Exporter.h"
2#include <iostream>
3#include <string>
4#include "stdafx.h"
5#include "SemanticLayer.h"
6#include "OgreException.h"
7#include "OgreLogManager.h"
8#include "OgreMeshManager.h"
9#include "OgreSkeletonManager.h"
10#include "OgreAnimation.h"
11#include "OgreAnimationTrack.h"
12#include "OgreKeyFrame.h"
13#include "OgreMesh.h"
14#include "OgreSubMesh.h"
15#include "OgreSkeleton.h"
16#include "OgreBone.h"
17#include "OgreDefaultHardwareBufferManager.h"
18#include "OgreMeshSerializer.h"
19#include "OgreSkeletonSerializer.h"
20#include "OgrePrerequisites.h"
21#include "OgreVector2.h"
22#include "OgreVector3.h"
23#include "OgreVector3.h"
24#include "OgreColourValue.h"
25
26using namespace Ogre;
27
28//----------------------- GLOBALS FOR SINGLETONS -------------
29LogManager* logMgr;
30ResourceGroupManager* rgm;
31MeshManager* meshMgr;
32DefaultHardwareBufferManager* hardwareBufMgr;
33SkeletonManager* skelMgr;
34
35//------------------------------------------------------------
36Exporter::UniqueVertex::UniqueVertex()
37    : initialized(false), position(Ogre::Vector3::ZERO), normal(Ogre::Vector3::ZERO), color(0),
38    nextIndex(0)
39{
40    for (int i = 0; i < OGRE_MAX_TEXTURE_COORD_SETS; ++i)
41        uv[i] = Ogre::Vector2::ZERO;
42}
43
44//------------------------------------------------------------
45bool Exporter::UniqueVertex::operator ==(const UniqueVertex& rhs) const
46{
47    bool ret = position == rhs.position &&
48        normal == rhs.normal &&
49        color == rhs.color;
50    if (!ret) return ret;
51    for (int i = 0; i < OGRE_MAX_TEXTURE_COORD_SETS && ret; ++i)
52    {
53        ret = ret && (uv[i] == rhs.uv[i]);
54    }
55    return ret;
56}
57
58//------------------------------------------------------------
59Exporter::Exporter(CSLModel * Root)
60{
61    // Initialize Exporter object instance variables
62    this->SceneRoot = Root;
63    boneCount = 0;
64}
65
66//------------------------------------------------------------
67Exporter::~Exporter()
68{
69}
70
71//------------------------------------------------------------
72void Exporter::exportMesh(std::string fileName, std::string skelName)
73{
74    // Construct mesh
75    MeshPtr pMesh = MeshManager::getSingleton().createManual(fileName, ResourceGroupManager::
76        DEFAULT_RESOURCE_GROUP_NAME);
77    pMesh->setSkeletonName(skelName);
78
79    // We'll assume we want to export the entire scene
80    exportCSLModel(pMesh.getPointer(), SceneRoot);
81    MeshSerializer serializer;
82    serializer.exportMesh(pMesh.getPointer(), fileName);
83}
84
85//--------------------------------------------------------------------------
86void Exporter::exportCSLModel(Mesh* pMesh, CSLModel* XSIModel)
87{
88    if (XSIModel->GetPrimitiveType() == CSLTemplate::SI_MESH)
89        exportSubMesh(pMesh, (CSLMesh *) XSIModel->Primitive());
90       
91    CSLModel* *l_childrenList = XSIModel->GetChildrenList();
92
93    // Loop through all children
94    for (int i = 0; i < XSIModel->GetChildrenCount(); i++ )
95    {
96        exportCSLModel (pMesh, l_childrenList[i]);
97    }
98}
99
100//-------------------------------------------------------------------------
101void Exporter::exportSubMesh(Mesh *pMesh, CSLMesh* XSIMesh)
102{
103    SubMesh* sm = 0;
104    sm = pMesh->createSubMesh(XSIMesh->GetName());
105       
106    // HACK:  No materials exporter yet, I hard coded this, wrong as hell, but did it anyway
107    // For now, I'm just creating the materials file manually.
108    sm->setMaterialName("Examples/Woman");
109    CSLTriangleList** triangles = XSIMesh->TriangleLists();
110
111    // Assume only one triangle list for now
112    CSLTriangleList* triArray = triangles[0];
113    std::cout << "Number of triangles: " << triArray->GetTriangleCount() << "\n";
114    CSIBCVector3D* srcPosArray = XSIMesh->Shape()->GetVertexListPtr();
115    std::cout << "Number of vertices: " << XSIMesh->Shape()->GetVertexCount() << "\n";
116    CSIBCVector3D* srcNormArray = XSIMesh->Shape()->GetNormalListPtr();
117    std::cout << "Number of normals: " << XSIMesh->Shape()->GetNormalCount() << "\n";
118    CSLShape_35 * uv = ((CSLShape_35 *) XSIMesh->Shape());
119    size_t numUVs = uv->UVCoordArrays()[0]->GetUVCoordCount();
120    std::cout << "Number of UVs: " << numUVs << "\n";
121
122    // For now, assume only one set of UV's
123    CSIBCVector2D* uvValueArray = ((CSLShape_35 *) XSIMesh->Shape())->UVCoordArrays()[0]->GetUVCoordListPtr();
124
125    // Check for colors
126    bool hasVertexColors = false;
127    if (XSIMesh->Shape()->GetColorCount() > 0)
128        hasVertexColors = true;
129
130    // Never use shared geometry
131    sm->useSharedVertices = false;
132    sm->vertexData = new VertexData();
133
134    // Always do triangle list
135    sm->indexData->indexCount = static_cast<size_t>(triArray->GetTriangleCount() * 3);
136
137    // Identify the unique vertices, write to a temp index buffer
138    startPolygonMesh(XSIMesh->Shape()->GetVertexCount(), triArray->GetTriangleCount() * 3);
139
140    // Iterate through all the triangles
141    // There will often be less positions than normals and UV's
142    for (long t = 0; t < triArray->GetTriangleCount(); ++t)
143    {
144        for (int p = 0; p < 3; ++p)
145        {
146            UniqueVertex vertex;
147            CSIBCVector3D pos = srcPosArray[triArray->GetVertexIndicesPtr()[t*3+p]];
148            CSIBCVector3D norm = srcNormArray[triArray->GetNormalIndicesPtr()[t*3+p]];
149            CSIBCVector2D uv = uvValueArray[triArray->GetUVIndicesPtr(0)[t*3+p]];
150            vertex.position = Vector3(pos.GetX(), pos.GetY(), pos.GetZ());
151            vertex.normal = Vector3(norm.GetX(), norm.GetY(), norm.GetZ());
152
153            // We are assuming 1 UV -- in our files, number of UV's = number of Normals
154            vertex.uv[0] = Vector2(uv.GetX(), (1 - uv.GetY()));
155                                               
156            if (hasVertexColors)
157                vertex.color = triArray->GetColorIndicesPtr()[t*3+p];
158            size_t index = createOrRetrieveUniqueVertex(triArray->GetVertexIndicesPtr()[t*3+p], vertex);
159            mIndices.push_back(index);
160        }
161    }
162    delete [] uvValueArray;
163
164    // Now bake final geometry
165    sm->vertexData->vertexCount = mUniqueVertices.size();
166
167    // Determine index size
168    bool use32BitIndexes = false;
169    if (mUniqueVertices.size() > 65536)
170        use32BitIndexes = true;
171    sm->indexData->indexBuffer =
172        HardwareBufferManager::getSingleton().createIndexBuffer(
173        use32BitIndexes ? HardwareIndexBuffer::IT_32BIT : HardwareIndexBuffer::IT_16BIT,
174        triArray->GetTriangleCount() * 3, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
175    if (use32BitIndexes)
176    {
177        uint32* pIdx = static_cast<uint32*>(
178            sm->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD));
179        writeIndexes(pIdx);
180        sm->indexData->indexBuffer->unlock();
181    }
182    else
183    {
184        uint16* pIdx = static_cast<uint16*>(
185            sm->indexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD));
186        writeIndexes(pIdx);
187        sm->indexData->indexBuffer->unlock();
188    }
189
190    // Define vertex declaration
191    unsigned buf = 0;
192    size_t offset = 0;
193    sm->vertexData->vertexDeclaration->addElement(buf, offset, VET_FLOAT3, VES_POSITION);
194    offset += VertexElement::getTypeSize(VET_FLOAT3);
195    sm->vertexData->vertexDeclaration->addElement(buf, offset, VET_FLOAT3, VES_NORMAL);
196    offset += VertexElement::getTypeSize(VET_FLOAT3);
197    // TODO:  Split Vertex Data if animated
198       
199    if (hasVertexColors)
200    {
201        sm->vertexData->vertexDeclaration->addElement(buf, offset, VET_COLOUR, VES_DIFFUSE);
202        offset += VertexElement::getTypeSize(VET_COLOUR);
203    }
204
205    // Again, assume only 1 uv
206    sm->vertexData->vertexDeclaration->addElement(buf, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES);
207    offset += VertexElement::getTypeSize(VET_FLOAT2);
208
209    // Create and fill buffer(s)
210    for (unsigned short b = 0; b <= sm->vertexData->vertexDeclaration->getMaxSource(); ++b)
211    {
212        createVertexBuffer(sm->vertexData, b);
213    }
214
215    // Bounds definitions
216    Real squaredRadius = 0.0f;
217    Vector3 min, max;
218    bool first = true;
219    for (long i = 0; i < XSIMesh->Shape()->GetVertexCount(); ++i)
220    {
221        Vector3 position = Vector3(srcPosArray[i].GetX(), srcPosArray[i].GetY(), srcPosArray[i].GetZ());
222        if (first)
223        {
224            squaredRadius = position.squaredLength();
225            min = max = position;
226            first = false;
227        }
228        else
229        {
230            squaredRadius = std::max(squaredRadius, position.squaredLength());
231            min.makeFloor(position);
232            max.makeCeil(position);
233        }
234    }
235    AxisAlignedBox box;
236    box.setExtents(min, max);
237    box.merge(pMesh->getBounds());
238    pMesh->_setBounds(box);
239    pMesh->_setBoundingSphereRadius(std::max(pMesh->getBoundingSphereRadius(),
240        Math::Sqrt(squaredRadius)));
241       
242    // Get Envelope list for this submesh
243    CSLEnvelope** envelopes = XSIMesh->ParentModel()->GetEnvelopeList();
244    CSLEnvelope* env = 0;
245    int boneIdx;
246    bool done;
247    int index;
248    VertexBoneAssignment vertAssign;
249    for (int e = 0; e < XSIMesh->ParentModel()->GetEnvelopeCount(); ++e)
250    {
251        env = envelopes[e];
252        for (int g = 0; g < boneCount; ++g)
253        {
254            if (boneArray[g] == env->GetDeformer()->GetName())
255                boneIdx = g;
256            else
257                continue;
258            break;
259        }
260               
261        SLVertexWeight* wtList = env->GetVertexWeightListPtr();
262               
263        // Go through all collocated vertices, assigning the same weights to each.
264        // All the dotXSI files I've seen normalize the weights to 100, so for now
265        // I'm just dividing by 100.  TODO:  Insert code to handle normalization
266        // just in case.
267        for (int h = 0; h < env->GetVertexWeightCount(); ++h)
268        {
269            vertAssign.boneIndex = boneIdx;
270            vertAssign.vertexIndex = index = (int) wtList[h].m_fVertexIndex;
271            vertAssign.weight = (Real) (wtList[h].m_fWeight / 100);
272            done = false;
273            while (!done)
274            {
275                sm->addBoneAssignment(vertAssign);
276                if (mUniqueVertices[index].nextIndex)
277                    vertAssign.vertexIndex = index = mUniqueVertices[index].nextIndex;
278                else
279                    done = true;
280            }
281        }
282    }
283       
284    // Last step here is to reorganise the vertex buffers
285    VertexDeclaration* newDecl =
286        sm->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(true);
287    BufferUsageList bufferUsages;
288    for (size_t u = 0; u <= newDecl->getMaxSource(); ++u)
289        bufferUsages.push_back(HardwareBuffer::HBU_STATIC_WRITE_ONLY);
290    sm->vertexData->reorganiseBuffers(newDecl, bufferUsages);
291}                       
292
293//-----------------------------------------------------------------------------
294template <typename T>
295void Exporter::writeIndexes(T* buf)
296{
297    IndexList::const_iterator i, iend;
298    iend = mIndices.end();
299    for (i = mIndices.begin(); i != iend; ++i)
300    {
301        *buf++ = static_cast<T>(*i);
302    }
303}
304
305//-----------------------------------------------------------------------------
306void Exporter::createVertexBuffer(VertexData* vd, unsigned short bufIdx)
307{
308    HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
309        vd->vertexDeclaration->getVertexSize(bufIdx),
310        vd->vertexCount,
311        HardwareBuffer::HBU_STATIC_WRITE_ONLY);
312    vd->vertexBufferBinding->setBinding(bufIdx, vbuf);
313    size_t vertexSize = vd->vertexDeclaration->getVertexSize(bufIdx);
314
315    char* pBase = static_cast<char*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
316
317    VertexDeclaration::VertexElementList elems = vd->vertexDeclaration->findElementsBySource(bufIdx);
318    VertexDeclaration::VertexElementList::iterator ei, eiend;
319    eiend = elems.end();
320    float* pFloat;
321    RGBA* pRGBA;
322
323    Exporter::UniqueVertexList::iterator srci = mUniqueVertices.begin();
324
325    for (size_t v = 0; v < vd->vertexCount; ++v, ++srci)
326    {
327        for (ei = elems.begin(); ei != eiend; ++ei)
328        {
329            VertexElement& elem = *ei;
330            switch(elem.getSemantic())
331            {
332            case VES_POSITION:
333                elem.baseVertexPointerToElement(pBase, &pFloat);
334                *pFloat++ = srci->position.x;
335                *pFloat++ = srci->position.y;
336                *pFloat++ = srci->position.z;
337                break;
338            case VES_NORMAL:
339                elem.baseVertexPointerToElement(pBase, &pFloat);
340                *pFloat++ = srci->normal.x;
341                *pFloat++ = srci->normal.y;
342                *pFloat++ = srci->normal.z;
343                break;
344            case VES_DIFFUSE:
345                elem.baseVertexPointerToElement(pBase, &pRGBA);
346                *pRGBA = srci->color;
347                break;
348            case VES_TEXTURE_COORDINATES:
349                elem.baseVertexPointerToElement(pBase, &pFloat);
350                *pFloat++ = srci->uv[elem.getIndex()].x;
351                *pFloat++ = srci->uv[elem.getIndex()].y;
352                break;
353            }
354        }
355        pBase += vertexSize;
356    }
357    vbuf->unlock();
358}
359
360//----------------------------------------------------------------------
361void Exporter::startPolygonMesh(size_t count, size_t indexCount)
362{
363    mUniqueVertices.clear();
364    mUniqueVertices.resize(count);
365    mIndices.clear();
366    mIndices.reserve(indexCount); // intentionally reserved, not resized
367}
368
369//----------------------------------------------------------------------
370size_t Exporter::createOrRetrieveUniqueVertex(size_t originalPositionIndex, const UniqueVertex& vertex)
371{
372    UniqueVertex& orig = mUniqueVertices[originalPositionIndex];
373
374    if (!orig.initialized)
375    {
376        orig = vertex;
377        orig.initialized = true;
378        return originalPositionIndex;
379    }
380    else if (orig == vertex)
381    {
382        return originalPositionIndex;
383    }
384    else
385    {
386        // no match, go to next or create new
387        if (orig.nextIndex)
388        {
389            // cascade
390            return createOrRetrieveUniqueVertex(orig.nextIndex, vertex);
391        }
392        else
393        {
394            // get new index
395            size_t newindex = mUniqueVertices.size();
396            orig.nextIndex = newindex;
397            // create new (NB invalidates 'orig' reference)
398            mUniqueVertices.push_back(vertex);
399            // set initialised
400            mUniqueVertices[newindex].initialized = true;
401
402            return newindex;
403        }
404    }
405}
406
407//------------------------------------------------------------------------------
408void Exporter::exportBones(std::string fileName)
409{               
410    // Construct skeleton
411    SkeletonPtr pSkel = SkeletonManager::getSingleton().create( fileName, ResourceGroupManager::
412        DEFAULT_RESOURCE_GROUP_NAME, true);
413               
414    // Recursively traverse the bone tree       
415    root = false;
416    recurseBones(pSkel.getPointer(), SceneRoot);
417       
418    // Export animations
419    exportAnim(pSkel.getPointer(), SceneRoot);
420
421    // Call serializer to write .skeleton file
422    SkeletonSerializer serializer;
423    serializer.exportSkeleton(pSkel.getPointer(), fileName);
424}
425
426//-----------------------------------------------------------------
427void Exporter::recurseBones(Skeleton* pSkel, CSLModel* XSIModel)
428{
429    CSIBCVector3D vec3d;
430               
431    // A plethora of logical expressions to ensure that the root null and
432    // its children are the only ones that will enter this if block.  Eliminates
433    // any extraneous nulls not related to the skeleton.
434
435    if ((XSIModel->GetPrimitiveType() == CSLTemplate::SI_NULL_OBJECT) &&
436        ((XSIModel->ParentModel()->GetPrimitiveType() == CSLTemplate::SI_NULL_OBJECT) || (!root)))
437    {
438        boneArray[boneCount] = XSIModel->GetName();
439        Bone* ogreBone = pSkel->createBone(XSIModel->GetName(), boneCount);
440        root = true;
441        vec3d = XSIModel->Transform()->GetScale();
442        ogreBone->setScale(vec3d.GetX(), vec3d.GetY(), vec3d.GetZ());
443        vec3d = XSIModel->Transform()->GetTranslation();
444        Vector3 bonePos(vec3d.GetX(), vec3d.GetY(), vec3d.GetZ());
445        ogreBone->setPosition(bonePos);
446               
447        // Yes, we are converting Euler angles to quaternions, at risk of gimbal lock.
448        // This is because XSI doesn't export quaternions, except through the animation
449        // mixer and action FCurves.  It's possible to get a 3x3 Rotation matrix, which
450        // might be a better choice for conversion to quaternion.
451        vec3d = XSIModel->Transform()->GetEulerRotation();
452        Ogre::Quaternion qx, qy, qz, qfinal;
453        qx.FromAngleAxis(Ogre::Degree(vec3d.GetX()), Ogre::Vector3::UNIT_X);
454        qy.FromAngleAxis(Ogre::Degree(vec3d.GetY()), Ogre::Vector3::UNIT_Y);
455        qz.FromAngleAxis(Ogre::Degree(vec3d.GetZ()), Ogre::Vector3::UNIT_Z);
456
457        // Assume rotate by x then y then z
458        qfinal = qz * qy * qx;
459        ogreBone->setOrientation(qfinal);
460        ++boneCount;
461                       
462        if ((boneCount > 1) && (XSIModel->ParentModel()->GetPrimitiveType() == CSLTemplate::SI_NULL_OBJECT))
463        {
464            pSkel->getBone(XSIModel->ParentModel()->GetName())->addChild(ogreBone);
465        }
466    }                   
467                       
468    CSLModel* *l_childrenList = XSIModel->GetChildrenList();
469
470    // Loop through all children
471    for (int i = 0; i < XSIModel->GetChildrenCount(); i++ )
472    {
473        recurseBones (pSkel, l_childrenList[i]);
474    }
475}
476
477//------------------------------------------------------------------------------
478
479void Exporter::exportAnim(Skeleton* pSkel, CSLModel* XSIModel)
480{
481    CSLTransform* initial;
482    CSLTransform* keyfr = 0;
483    CSIBCMatrix4x4 initmat, invinitmat, keyfmat, newmat;
484       
485    // Timing conversions from XSI frames to OGRE time in seconds
486    float frameRate = XSIModel->Scene()->SceneInfo()->GetFrameRate();
487    float lengthInFrames = XSIModel->Scene()->SceneInfo()->GetEnd() -
488        XSIModel->Scene()->SceneInfo()->GetStart();
489    float realTime = lengthInFrames / frameRate;
490       
491    // HACK:  You'd want to assign the correct name to your particular animation.
492    Animation *ogreanim =
493        pSkel->createAnimation("Jump", realTime );
494    int i, numKeys;
495   
496    // Go to each bone and create the animation tracks
497    for (i = 0; i < boneCount; ++i)
498    {
499        Bone* ogrebone = pSkel->getBone(boneArray[i]);
500        CSLModel* XSIbone = XSIModel->Scene()->FindModelRecursively((char *) boneArray[i].c_str(), XSIModel);
501        if ((i == 0) || (XSIbone->ParentModel()->GetPrimitiveType() == CSLTemplate::SI_NULL_OBJECT))
502        {
503            // Create animation tracks for a bone
504            AnimationTrack *ogretrack = ogreanim->createTrack(i, ogrebone);
505            numKeys = XSIbone->Transform()->FCurves()[0]->GetKeyCount();
506            CSLLinearKey* scalx = XSIbone->Transform()->GetSpecificFCurve(CSLTemplate::SI_SCALING_X)->GetLinearKeyListPtr();
507            CSLLinearKey* scaly = XSIbone->Transform()->GetSpecificFCurve(CSLTemplate::SI_SCALING_Y)->GetLinearKeyListPtr();
508            CSLLinearKey* scalz = XSIbone->Transform()->GetSpecificFCurve(CSLTemplate::SI_SCALING_Z)->GetLinearKeyListPtr();
509            CSLLinearKey* rotx = XSIbone->Transform()->GetSpecificFCurve(CSLTemplate::SI_ROTATION_X)->GetLinearKeyListPtr();
510            CSLLinearKey* roty = XSIbone->Transform()->GetSpecificFCurve(CSLTemplate::SI_ROTATION_Y)->GetLinearKeyListPtr();
511            CSLLinearKey* rotz = XSIbone->Transform()->GetSpecificFCurve(CSLTemplate::SI_ROTATION_Z)->GetLinearKeyListPtr();
512            CSLLinearKey* tranx = XSIbone->Transform()->GetSpecificFCurve(CSLTemplate::SI_TRANSLATION_X)->GetLinearKeyListPtr();
513            CSLLinearKey* trany = XSIbone->Transform()->GetSpecificFCurve(CSLTemplate::SI_TRANSLATION_Y)->GetLinearKeyListPtr();
514            CSLLinearKey* tranz = XSIbone->Transform()->GetSpecificFCurve(CSLTemplate::SI_TRANSLATION_Z)->GetLinearKeyListPtr();
515                               
516            // Set up the bind pose matrix and take inverse
517            initial = XSIbone->Transform();
518            initial->ComputeLocalMatrix();
519            initmat = initial->GetMatrix();
520            initmat.GetInverse(invinitmat);
521                       
522            for (int currKeyIdx = 0; currKeyIdx < numKeys; ++currKeyIdx)
523            {
524                // Create keyframe
525                // Adjust for start time, and for the fact that frames are numbered from 1
526                float frameTime = scalx[currKeyIdx].m_fTime - XSIModel->Scene()->SceneInfo()->GetStart();
527                realTime = frameTime / frameRate;
528                KeyFrame *ogrekey = ogretrack->createKeyFrame(realTime);
529                keyfr = XSIbone->Transform();
530                keyfr->SetScale(CSIBCVector3D(scalx[currKeyIdx].m_fValue, scaly[currKeyIdx].m_fValue, scalz[currKeyIdx].m_fValue));
531                keyfr->SetEulerRotation(CSIBCVector3D(rotx[currKeyIdx].m_fValue, roty[currKeyIdx].m_fValue, rotz[currKeyIdx].m_fValue));
532                keyfr->SetTranslation(CSIBCVector3D(tranx[currKeyIdx].m_fValue, trany[currKeyIdx].m_fValue, tranz[currKeyIdx].m_fValue));
533                keyfr->ComputeLocalMatrix();
534                keyfmat = keyfr->GetMatrix();
535                               
536                // Inverse bind pose matrix * keyframe transformation matrix
537                invinitmat.Multiply(keyfmat, newmat);
538                CSIBCVector3D kfSca, kfRot, kfPos;
539                newmat.GetTransforms(kfSca, kfRot, kfPos);
540                Vector3 kSca(kfSca.GetX(), kfSca.GetY(), kfSca.GetZ());
541                Vector3 kPos(kfPos.GetX(), kfPos.GetY(), kfPos.GetZ());
542                Quaternion qx, qy, qz, kfQ;
543                ogrekey->setScale(kSca);
544                ogrekey->setTranslate(kPos);
545                qx.FromAngleAxis(Ogre::Radian(kfRot.GetX()), Vector3::UNIT_X);
546                qy.FromAngleAxis(Ogre::Radian(kfRot.GetY()), Vector3::UNIT_Y);
547                qz.FromAngleAxis(Ogre::Radian(kfRot.GetZ()), Vector3::UNIT_Z);
548                kfQ = qz * qy * qx;
549                ogrekey->setRotation(kfQ);
550            }
551        }
552    }
553}
554
555//------------------------------------------------------------------------------
556int main(int argc, char *argv[])
557{
558    // Validate command line arguments
559    if (argc != 3) {
560        std::cout << "XSI Ogre Exporter should be invoked in the format: \n";
561        std::cout << "exporter <XSI File> <OGRE Mesh/Skeleton File>\n";
562        std::cout << "Ex:  exporter example.xsi example\n";
563        return (0);
564    }
565       
566    // Ogre Singletons
567    logMgr = new LogManager();
568    logMgr->createLog("XSIOgreExport");
569    rgm = new ResourceGroupManager();
570    meshMgr = new MeshManager();
571    hardwareBufMgr = new DefaultHardwareBufferManager();
572    skelMgr = new SkeletonManager();
573
574    // Initialize dotXSI Scene
575    CSLScene Scene;
576    std::string fn(argv[2]);
577    std::string meshFileName = fn + ".mesh";
578    std::string skelFileName = fn + ".skeleton";
579       
580    // Continue if valid dotXSI file, end gracefully if not
581    if (Scene.Open(argv[1]) == SI_SUCCESS)
582    {   
583        Scene.Read();
584        Exporter * e = new Exporter(Scene.Root());
585        e->exportBones(skelFileName);
586        e->exportMesh(meshFileName, skelFileName);   
587        delete e;
588        Scene.Close();
589    }
590    else
591        std::cout << "Error opening file " << argv[1] << ".  Please check for validity.\n";
592
593    // Get rid of Ogre Singletons
594    delete skelMgr;
595    delete meshMgr;
596    delete hardwareBufMgr;
597    delete rgm;
598    delete logMgr;
599    return (0);
600}
Note: See TracBrowser for help on using the repository browser.