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

Revision 969, 9.4 KB checked in by igarcia, 19 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 hasVertexColors = mEntity->getSubEntity(iSubEntity)->hasVertexColors();
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 (hasVertexColors)
103                        {
104                                Ogre::ColourValue color;
105                                Ogre::RGBA rc = mEntity->getSubEntity(iSubEntity)->getVertexColor(iVertex);
106       
107                                color.b = (rc & 0xFF) / 255.0f;         rc >>= 8;
108                                color.g = (rc & 0xFF) / 255.0f;         rc >>= 8;
109                                color.r = (rc & 0xFF) / 255.0f;         rc >>= 8;
110                                color.a = (rc & 0xFF) / 255.0f;
111
112                                //color.setAsARGB(mEntity->getSubEntity(iSubEntity)->getVertexColor(iVertex));
113                                mFloatColorList.push_back(color.r);
114                                mFloatColorList.push_back(color.g);
115                                mFloatColorList.push_back(color.b);
116                                mFloatColorList.push_back(color.a);
117                        }
118
119                        for (unsigned int iTexCoordSet = 0; iTexCoordSet < mEntity->getSubEntity(iSubEntity)->getNumTexCoordSets(); iTexCoordSet++)
120                        {
121                                if (mEntity->getSubEntity(iSubEntity)->getTexCoordDimensions(iTexCoordSet) == 2)
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                                }
127                                if (mEntity->getSubEntity(iSubEntity)->getTexCoordDimensions(iTexCoordSet) == 3)
128                                {
129                                        Ogre::Vector3 texcoord0 = mEntity->getSubEntity(iSubEntity)->getTexCoord(iVertex, iTexCoordSet);
130                                        mFloatTexCoordList[iTexCoordSet].push_back(texcoord0[0]);
131                                        mFloatTexCoordList[iTexCoordSet].push_back(texcoord0[1]);
132                                        mFloatTexCoordList[iTexCoordSet].push_back(texcoord0[2]);
133                                }
134                        }
135                }
136
137                if (iSubEntity == 0)
138                {                                               
139                        mFCDGeometryVertexSource = mFCDGeometryMesh->AddVertexSource();
140                }
141               
142                //mFCDGeometryVertexSource = mFCDGeometryMesh->AddSource();
143                mFCDGeometryVertexSource->SetSourceType(FUDaeGeometryInput::POSITION);                 
144                if (iSubEntity == (mEntity->getNumSubEntities() - 1))
145                {
146                        mFCDGeometryVertexSource->SetSourceData(mFloatPositionList, 3, 0, 0);   
147                }
148                mFCDGeometryPolygons = mFCDGeometryMesh->AddPolygons();
149                mFCDGeometryPolygonsInput = mFCDGeometryPolygons->FindInput(mFCDGeometryVertexSource);         
150
151                if (hasNormals)
152                {
153                        if (iSubEntity == 0)
154                        {
155                                mFCDGeometryNormalsSource = mFCDGeometryMesh->AddVertexSource();
156                                //mFCDGeometryNormalsSource = mFCDGeometryMesh->AddSource();
157                        }
158                        mFCDGeometryNormalsSource->SetSourceType(FUDaeGeometryInput::NORMAL);
159                        if (iSubEntity == (mEntity->getNumSubEntities() - 1))
160                        {
161                                mFCDGeometryNormalsSource->SetSourceData(mFloatNormalList, 3, 0, 0);
162                        }
163                        //mFCDGeometryPolygons->AddInput(mFCDGeometryNormalsSource, 0);                 
164                }
165                       
166
167                for (unsigned int iTexCoordSet = 0; iTexCoordSet < mEntity->getSubEntity(iSubEntity)->getNumTexCoordSets(); iTexCoordSet++)
168                {
169                        if (iSubEntity == (mEntity->getNumSubEntities() - 1))
170                        {
171                                //mFCDGeometrySource = mFCDGeometryMesh->AddVertexSource();
172                                mFCDGeometryTexCoordSource = mFCDGeometryMesh->AddSource();
173                                mFCDGeometryTexCoordSource->SetSourceType(FUDaeGeometryInput::TEXCOORD);
174                                mFCDGeometryTexCoordSource->SetSourceData(mFloatTexCoordList[iTexCoordSet], 2, 0, 0);
175                                mFCDGeometryPolygons->AddInput(mFCDGeometryTexCoordSource, 0);
176                        }                               
177                }
178               
179                if (hasVertexColors)
180                {
181                        if (iSubEntity == (mEntity->getNumSubEntities() - 1))
182                        {
183                                //mFCDGeometrySource = mFCDGeometryMesh->AddVertexSource();
184                                mFCDGeometryColorSource = mFCDGeometryMesh->AddSource();
185                                mFCDGeometryColorSource->SetSourceType(FUDaeGeometryInput::COLOR);
186                                mFCDGeometryColorSource->SetSourceData(mFloatColorList, 4, 0, 0);
187                                mFCDGeometryPolygons->AddInput(mFCDGeometryColorSource, 0);     
188                        }                                       
189                }
190
191                iCount = 0;             
192                iSubEntityNextFirstIDFace = 0;
193
194                for (unsigned int iFace = 0; iFace < mEntity->getSubEntity(iSubEntity)->getNumFaces(); iFace++)
195                {                               
196                        Ogre::Vector3 positionIDFace;                           
197                        positionIDFace = mEntity->getSubEntity(iSubEntity)->getFaceVerticesIDs(iFace);
198
199                        mFCDGeometryPolygons->AddFace(3);
200
201                        mFCDGeometryPolygonsInput->indices[iCount] = iSubEntityFirstIDFace + positionIDFace[0];
202                        mFCDGeometryPolygonsInput->indices[iCount+1] = iSubEntityFirstIDFace + positionIDFace[1];
203                        mFCDGeometryPolygonsInput->indices[iCount+2] = iSubEntityFirstIDFace + positionIDFace[2];
204
205                        if (positionIDFace[0] > iSubEntityNextFirstIDFace)
206                        {
207                                iSubEntityNextFirstIDFace = positionIDFace[0] + 1;
208                        }
209
210                        if (positionIDFace[1] > iSubEntityNextFirstIDFace)
211                        {
212                                iSubEntityNextFirstIDFace = positionIDFace[1] + 1;
213                        }
214
215                        if (positionIDFace[2] > iSubEntityNextFirstIDFace)
216                        {
217                                iSubEntityNextFirstIDFace = positionIDFace[2] + 1;
218                        }
219
220                        iCount = iCount + 3;
221                }
222               
223                iSubEntityLastIDFace = iSubEntityFirstIDFace + (iSubEntityNextFirstIDFace - 1);
224                iSubEntityFirstIDFace = iSubEntityLastIDFace + 1;                       
225        }
226
227        void ColladaMeshSerializer::save(Ogre::String filename)
228        {               
229                //mFCDocument->WriteToFile(fstring("test.dae"));
230                // Create a new xml root node from this COLLADA document
231                xmlNode* rootNode = FUXmlWriter::CreateNode(DAE_COLLADA_ELEMENT);
232
233                FUStatus status;
234                status = mFCDocument->WriteDocumentToXML(rootNode);
235                if (status.IsSuccessful())             
236                {
237                        // Create the XML document and write it out to the given filename
238                        xmlDoc* daeDocument = xmlNewDoc(NULL); // NULL implies version 1.0
239                        xmlDocSetRootElement(daeDocument, rootNode);
240
241                        intptr_t bytesWritten = xmlSaveFormatFileEnc(filename.c_str(), daeDocument, "utf-8", 1);
242                        if (bytesWritten < 0)
243                        {
244                                //status.Fail(FS("Unable to write COLLADA document to file '") + filename + FS("'. Verify that the folder exists and the file is writable."), rootNode->line);
245                        }
246                        else if (status.IsSuccessful())
247                        {
248                                //status.AppendString(FC("COLLADA document written successfully."));
249                        }
250                        xmlFreeDoc(daeDocument);
251                }
252                else
253                {
254                        xmlFreeNode(rootNode);
255                }
256
257                // Clean-up
258                xmlCleanupParser();
259        }
260
261        void ColladaMeshSerializer::exportSubMeshes(MeshPtr pMesh)
262        {
263                iCount = 0;
264        iSubEntityFirstIDFace = 0;
265                iSubEntityNextFirstIDFace = 0;
266                iSubEntityLastIDFace = 0;
267
268                for (unsigned int iSubEntity = 0; iSubEntity < mEntity->getNumSubEntities(); iSubEntity++)
269                {
270                        exportSubMesh(pMesh, iSubEntity);
271                }
272    }
273
274        void ColladaMeshSerializer::buildMesh(MeshPtr pMesh, bool mergeSubmeshes)
275        {
276                if (!mergeSubmeshes)
277                {
278                        exportSubMeshes(pMesh);
279                }       
280
281                // TODO
282                if (mergeSubmeshes)
283                {
284                }
285        }
286}
Note: See TracBrowser for help on using the repository browser.