source: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/BBCColladaMeshSerializer.cpp @ 950

Revision 950, 9.2 KB checked in by igarcia, 18 years ago (diff)
Line 
1
2#include "BBCColladaMeshSerializer.h"
3
4namespace BBC {
5
6        ColladaMeshSerializer::ColladaMeshSerializer()
7        {
8        }
9
10        ColladaMeshSerializer::~ColladaMeshSerializer()
11        {
12        }
13
14        void ColladaMeshSerializer::setEntity(EntityPtr entity)
15        {
16                mEntity = entity;
17        }
18
19        EntityPtr ColladaMeshSerializer::getEntity()
20        {
21                return mEntity;
22        }
23
24        void ColladaMeshSerializer::exportMesh(const Ogre::String& fileName, bool mergeSubMeshes = false, bool tangents = false)
25    {
26                Ogre::String outputFileName;
27
28                outputFileName = BBC::Util::getBaseName(fileName) + ".dae";
29
30                mFCDocument = new FCDocument();
31                mFCDocument->AddVisualScene();
32                mFCDVisualSceneNodeLibrary = mFCDocument->GetVisualSceneLibrary();
33                mSceneNode = mFCDocument->GetVisualSceneRoot()->AddChildNode();
34                //mSceneNode->AddTransform(FCDTransform::SCALE, -1);
35                //mSceneNode->AddTransform(FCDTransform::ROTATION, -1);
36                //mSceneNode->AddTransform(FCDTransform::TRANSLATION, -1);     
37                mFCDEntityInstanceList = (const FCDEntityInstanceList&)mSceneNode->GetInstances();
38                mFCDGeometry = mFCDocument->GetGeometryLibrary()->AddEntity();
39                mFCDGeometryMesh = mFCDGeometry->CreateMesh();
40                mFCDGeometryInstance = new FCDGeometryInstance(mFCDocument, mFCDGeometry);
41                mFCDMaterialInstance = new FCDMaterialInstance(mFCDocument, mFCDGeometryInstance);
42                mFCDMaterial = mFCDocument->GetMaterialLibrary()->AddMaterial();
43                mFCDEffect = mFCDocument->GetMaterialLibrary()->AddEffect();
44                mFCDMaterial->SetEffect(mFCDEffect);
45                ((FCDMaterialInstanceList)mFCDGeometryInstance->GetMaterialInstanceList()).push_back(mFCDMaterialInstance);
46                mSceneNode->GetInstances().push_back(mFCDGeometryInstance);
47
48                Ogre::LogManager::getSingleton().logMessage("** Begin Collada Mesh Export **");
49        // Derive the scene root
50
51        // Construct mesh               
52                BBC::MeshPtr pMesh(new BBC::Mesh(Ogre::MeshManager::getSingleton().createManual(outputFileName, outputFileName).getPointer()));
53               
54                Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().load(outputFileName, outputFileName);
55
56                Ogre::LogManager::getSingleton().logMessage("Num.SubEntities:" + Ogre::StringConverter::toString(mEntity->getNumSubEntities()));
57
58                mEntity->setMesh(pMesh);
59
60                buildMesh(pMesh, mergeSubMeshes);       
61
62                save(outputFileName);
63
64                mFloatPositionList.clear();
65
66                mFloatNormalList.clear();
67               
68                mIntPositionIDFaceList.clear();
69
70                for (unsigned int iTexCoordSet = 0; iTexCoordSet < mEntity->getSubEntity(0)->getNumTexCoordSets(); iTexCoordSet++)
71                {
72                        mFloatTexCoordList[iTexCoordSet].clear();
73                }
74       
75                mFloatColorList.clear();
76
77                delete mFCDocument;             
78
79                Ogre::LogManager::getSingleton().logMessage("** Collada Mesh Export Complete **");
80    }
81
82        void ColladaMeshSerializer::exportSubMesh(MeshPtr pMesh, unsigned int iSubEntity)
83        {
84                bool hasVertexColours = mEntity->getSubEntity(iSubEntity)->hasVertexColours();
85                bool hasNormals = mEntity->getSubEntity(iSubEntity)->hasNormals();
86
87                for (unsigned int iVertex = 0; iVertex < mEntity->getSubEntity(iSubEntity)->getNumVertices(); iVertex++)
88                {
89                        Ogre::Vector3 position = mEntity->getSubEntity(iSubEntity)->getPosition(iVertex);
90                        mFloatPositionList.push_back(position[0]);
91                        mFloatPositionList.push_back(position[1]);
92                        mFloatPositionList.push_back(position[2]);
93
94                        if (hasNormals)
95                        {
96                                Ogre::Vector3 normal = mEntity->getSubEntity(iSubEntity)->getNormal(iVertex);
97                                mFloatNormalList.push_back(normal[0]);
98                                mFloatNormalList.push_back(normal[1]);
99                                mFloatNormalList.push_back(normal[2]);
100                        }
101
102                        if (hasVertexColours)
103                        {
104                                Ogre::ColourValue color;
105                                //color.setAsARGB(mEntity->getSubEntity(iSubEntity)->getVertexColour(iVertex) & 0xFF);
106                                color.setAsARGB(mEntity->getSubEntity(iSubEntity)->getVertexColour(iVertex));
107                                mFloatColorList.push_back(color.r);
108                                mFloatColorList.push_back(color.g);
109                                mFloatColorList.push_back(color.b);
110                                mFloatColorList.push_back(color.a);
111                        }
112
113                        for (unsigned int iTexCoordSet = 0; iTexCoordSet < mEntity->getSubEntity(iSubEntity)->getNumTexCoordSets(); iTexCoordSet++)
114                        {
115                                if (mEntity->getSubEntity(iSubEntity)->getTexCoordDimensions(iTexCoordSet) == 2)
116                                {
117                                        Ogre::Vector3 texcoord0 = mEntity->getSubEntity(iSubEntity)->getTexCoord(iVertex, iTexCoordSet);
118                                        mFloatTexCoordList[iTexCoordSet].push_back(texcoord0[0]);
119                                        mFloatTexCoordList[iTexCoordSet].push_back(texcoord0[1]);
120                                }
121                                if (mEntity->getSubEntity(iSubEntity)->getTexCoordDimensions(iTexCoordSet) == 3)
122                                {
123                                        Ogre::Vector3 texcoord0 = mEntity->getSubEntity(iSubEntity)->getTexCoord(iVertex, iTexCoordSet);
124                                        mFloatTexCoordList[iTexCoordSet].push_back(texcoord0[0]);
125                                        mFloatTexCoordList[iTexCoordSet].push_back(texcoord0[1]);
126                                        mFloatTexCoordList[iTexCoordSet].push_back(texcoord0[2]);
127                                }
128                        }
129                }
130
131                if (iSubEntity == 0)
132                {                                               
133                        mFCDGeometryVertexSource = mFCDGeometryMesh->AddVertexSource();
134                }
135               
136                //mFCDGeometryVertexSource = mFCDGeometryMesh->AddSource();
137                mFCDGeometryVertexSource->SetSourceType(FUDaeGeometryInput::POSITION);                 
138                if (iSubEntity == (mEntity->getNumSubEntities() - 1))
139                {
140                        mFCDGeometryVertexSource->SetSourceData(mFloatPositionList, 3, 0, 0);   
141                }
142                mFCDGeometryPolygons = mFCDGeometryMesh->AddPolygons();
143                mFCDGeometryPolygonsInput = mFCDGeometryPolygons->FindInput(mFCDGeometryVertexSource);         
144
145                if (hasNormals)
146                {
147                        if (iSubEntity == 0)
148                        {
149                                mFCDGeometryNormalsSource = mFCDGeometryMesh->AddVertexSource();
150                                //mFCDGeometryNormalsSource = mFCDGeometryMesh->AddSource();
151                        }
152                        mFCDGeometryNormalsSource->SetSourceType(FUDaeGeometryInput::NORMAL);
153                        if (iSubEntity == (mEntity->getNumSubEntities() - 1))
154                        {
155                                mFCDGeometryNormalsSource->SetSourceData(mFloatNormalList, 3, 0, 0);
156                        }
157                        //mFCDGeometryPolygons->AddInput(mFCDGeometryNormalsSource, 0);                 
158                }
159                       
160
161                for (unsigned int iTexCoordSet = 0; iTexCoordSet < mEntity->getSubEntity(iSubEntity)->getNumTexCoordSets(); iTexCoordSet++)
162                {
163                        if (iSubEntity == (mEntity->getNumSubEntities() - 1))
164                        {
165                                //mFCDGeometrySource = mFCDGeometryMesh->AddVertexSource();
166                                mFCDGeometryTexCoordSource = mFCDGeometryMesh->AddSource();
167                                mFCDGeometryTexCoordSource->SetSourceType(FUDaeGeometryInput::TEXCOORD);
168                                mFCDGeometryTexCoordSource->SetSourceData(mFloatTexCoordList[iTexCoordSet], 2, 0, 0);
169                                mFCDGeometryPolygons->AddInput(mFCDGeometryTexCoordSource, 0);
170                        }                               
171                }
172               
173                if (hasVertexColours)
174                {
175                        if (iSubEntity == (mEntity->getNumSubEntities() - 1))
176                        {
177                                //mFCDGeometrySource = mFCDGeometryMesh->AddVertexSource();
178                                mFCDGeometryColorSource = mFCDGeometryMesh->AddSource();
179                                mFCDGeometryColorSource->SetSourceType(FUDaeGeometryInput::COLOR);
180                                mFCDGeometryColorSource->SetSourceData(mFloatColorList, 4, 0, 0);
181                                mFCDGeometryPolygons->AddInput(mFCDGeometryColorSource, 0);     
182                        }                                       
183                }
184
185                iCount = 0;             
186                iSubEntityNextFirstIDFace = 0;
187
188                for (unsigned int iFace = 0; iFace < mEntity->getSubEntity(iSubEntity)->getNumFaces(); iFace++)
189                {                               
190                        Ogre::Vector3 positionIDFace;                           
191                        positionIDFace = mEntity->getSubEntity(iSubEntity)->getFaceVerticesIDs(iFace);
192
193                        mFCDGeometryPolygons->AddFace(3);
194
195                        mFCDGeometryPolygonsInput->indices[iCount] = iSubEntityFirstIDFace + positionIDFace[0];
196                        mFCDGeometryPolygonsInput->indices[iCount+1] = iSubEntityFirstIDFace + positionIDFace[1];
197                        mFCDGeometryPolygonsInput->indices[iCount+2] = iSubEntityFirstIDFace + positionIDFace[2];
198
199                        if (positionIDFace[0] > iSubEntityNextFirstIDFace)
200                        {
201                                iSubEntityNextFirstIDFace = positionIDFace[0] + 1;
202                        }
203
204                        if (positionIDFace[1] > iSubEntityNextFirstIDFace)
205                        {
206                                iSubEntityNextFirstIDFace = positionIDFace[1] + 1;
207                        }
208
209                        if (positionIDFace[2] > iSubEntityNextFirstIDFace)
210                        {
211                                iSubEntityNextFirstIDFace = positionIDFace[2] + 1;
212                        }
213
214                        iCount = iCount + 3;
215                }
216               
217                iSubEntityLastIDFace = iSubEntityFirstIDFace + (iSubEntityNextFirstIDFace - 1);
218                iSubEntityFirstIDFace = iSubEntityLastIDFace + 1;                       
219        }
220
221        void ColladaMeshSerializer::save(Ogre::String filename)
222        {               
223                //mFCDocument->WriteToFile(fstring("test.dae"));
224                // Create a new xml root node from this COLLADA document
225                xmlNode* rootNode = FUXmlWriter::CreateNode(DAE_COLLADA_ELEMENT);
226
227                FUStatus status;
228                status = mFCDocument->WriteDocumentToXML(rootNode);
229                if (status.IsSuccessful())             
230                {
231                        // Create the XML document and write it out to the given filename
232                        xmlDoc* daeDocument = xmlNewDoc(NULL); // NULL implies version 1.0
233                        xmlDocSetRootElement(daeDocument, rootNode);
234
235                        intptr_t bytesWritten = xmlSaveFormatFileEnc(filename.c_str(), daeDocument, "utf-8", 1);
236                        if (bytesWritten < 0)
237                        {
238                                //status.Fail(FS("Unable to write COLLADA document to file '") + filename + FS("'. Verify that the folder exists and the file is writable."), rootNode->line);
239                        }
240                        else if (status.IsSuccessful())
241                        {
242                                //status.AppendString(FC("COLLADA document written successfully."));
243                        }
244                        xmlFreeDoc(daeDocument);
245                }
246                else
247                {
248                        xmlFreeNode(rootNode);
249                }
250
251                // Clean-up
252                xmlCleanupParser();
253        }
254
255        void ColladaMeshSerializer::exportSubMeshes(MeshPtr pMesh)
256        {
257                iCount = 0;
258        iSubEntityFirstIDFace = 0;
259                iSubEntityNextFirstIDFace = 0;
260                iSubEntityLastIDFace = 0;
261
262                for (unsigned int iSubEntity = 0; iSubEntity < mEntity->getNumSubEntities(); iSubEntity++)
263                {
264                        exportSubMesh(pMesh, iSubEntity);
265                }
266    }
267
268        void ColladaMeshSerializer::buildMesh(MeshPtr pMesh, bool mergeSubmeshes)
269        {
270                if (!mergeSubmeshes)
271                {
272                        exportSubMeshes(pMesh);
273                }       
274
275                // TODO
276                if (mergeSubmeshes)
277                {
278                }
279        }
280}
Note: See TracBrowser for help on using the repository browser.