~ubuntu-branches/ubuntu/wily/opencollada/wily-proposed

« back to all changes in this revision

Viewing changes to dae23ds/src/DAE23dsWriter.cpp

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2015-05-14 17:23:27 UTC
  • Revision ID: package-import@ubuntu.com-20150514172327-f862u8envms01fra
Tags: upstream-0.1.0~20140703.ddf8f47+dfsg1
ImportĀ upstreamĀ versionĀ 0.1.0~20140703.ddf8f47+dfsg1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Copyright (c) 2009 NetAllied Systems GmbH
 
3
 
 
4
    This file is part of dae23ds.
 
5
        
 
6
    Licensed under the MIT Open Source License, 
 
7
    for details please see LICENSE file or the website
 
8
    http://www.opensource.org/licenses/mit-license.php
 
9
*/
 
10
 
 
11
#include "DAE23dsStableHeaders.h"
 
12
#include "DAE23dsWriter.h"
 
13
#include "DAE23dsMeshWriter.h"
 
14
#include "DAE23dsMeshHandler.h"
 
15
#include "DAE23dsMeshLengthCalculator.h"
 
16
#include "DAE23dsSceneGraphWriter.h"
 
17
#include "DAE23dsSceneGraphHandler.h"
 
18
#include "DAE23dsMaterialsLengthCalculator.h"
 
19
#include "DAE23dsMaterialsWriter.h"
 
20
 
 
21
#include "COLLADASaxFWLLoader.h"
 
22
 
 
23
#include "COLLADAFWRoot.h"
 
24
#include "COLLADAFWGeometry.h"
 
25
#include "COLLADAFWNode.h"
 
26
#include "COLLADAFWVisualScene.h"
 
27
#include "COLLADAFWInstanceGeometry.h"
 
28
 
 
29
 
 
30
#include "CommonFWriteBufferFlusher.h"
 
31
#include "CommonCharacterBuffer.h"
 
32
 
 
33
namespace DAE23ds
 
34
{
 
35
 
 
36
        static size_t FLUSHERBUFFERSIZE = 1024*1024*4;
 
37
        static size_t BUFFERSIZE = 1024*1024*2;
 
38
 
 
39
        static const size_t RESERVED_OBJECTIDS_COUNT = 0;
 
40
        static const size_t RESERVED_MATERIALNUMBERS_COUNT = 1;
 
41
 
 
42
 
 
43
        //--------------------------------------------------------------------
 
44
        bool Writer::InstanceGeometryInfo::operator<( const InstanceGeometryInfo& rhs ) const
 
45
        {
 
46
                if (fwInstanceGeometry < rhs.fwInstanceGeometry)
 
47
                        return true;
 
48
                if (fwInstanceGeometry > rhs.fwInstanceGeometry)
 
49
                        return false;
 
50
 
 
51
                return false;
 
52
        }
 
53
 
 
54
        //--------------------------------------------------------------------
 
55
        bool Writer::InstanceGeometryIdentifier::operator<( const InstanceGeometryIdentifier& rhs ) const
 
56
        {
 
57
                if (fwInstanceGeometry < rhs.fwInstanceGeometry)
 
58
                        return true;
 
59
                if (fwInstanceGeometry > rhs.fwInstanceGeometry)
 
60
                        return false;
 
61
 
 
62
                if (instanceNumber < rhs.instanceNumber)
 
63
                        return true;
 
64
                if (instanceNumber > rhs.instanceNumber)
 
65
                        return false;
 
66
 
 
67
                return false;
 
68
        }
 
69
 
 
70
        //--------------------------------------------------------------------
 
71
        Writer::Writer( const COLLADABU::URI& inputFile, const COLLADABU::URI& outputFile, bool applyTransformationsToMeshes )
 
72
                : mInputFile(inputFile)
 
73
                , mOutputFile(outputFile)
 
74
                , mApplyTransformationsToMeshes(applyTransformationsToMeshes)
 
75
                , mBuffer(0)
 
76
                , mCurrentRun(SCENEGRAPH_RUN)
 
77
                , mVisualScene(0)
 
78
                , mGeometryMaterialBindingFileNameMap(compare)
 
79
                , mObjectAndMaterialBlockLength(0)
 
80
                , mNextObjectId( RESERVED_OBJECTIDS_COUNT )
 
81
                , mNextMaterialNumber( RESERVED_MATERIALNUMBERS_COUNT )
 
82
        {
 
83
        }
 
84
 
 
85
        //--------------------------------------------------------------------
 
86
        Writer::~Writer()
 
87
        {
 
88
                delete mVisualScene;
 
89
        }
 
90
 
 
91
        //--------------------------------------------------------------------
 
92
        void Writer::reportError( const String& method, const String& message, Severity severity )
 
93
        {
 
94
                switch ( severity )
 
95
                {
 
96
                case SEVERITY_INFORMATION:
 
97
                        std::cout << "Information"; 
 
98
                        break;
 
99
                case SEVERITY_WARNING:
 
100
                        std::cout << "Warning"; 
 
101
                        break;
 
102
                case _SEVERITY_ERROR:
 
103
                        std::cout << "Error"; 
 
104
                        break;
 
105
                }
 
106
                if ( !method.empty() )
 
107
                        std::cout << " in " << method;
 
108
                std::cout << ": ";
 
109
                std::cout << message << std::endl;
 
110
        }
 
111
 
 
112
        //--------------------------------------------------------------------
 
113
        bool Writer::write()
 
114
        {
 
115
                COLLADASaxFWL::Loader loader;
 
116
                COLLADAFW::Root root(&loader, this);
 
117
 
 
118
                Common::FWriteBufferFlusher bufferFlusher( getOutputFile().toNativePath().c_str(), FLUSHERBUFFERSIZE );
 
119
                Common::Buffer buffer( BUFFERSIZE, &bufferFlusher);
 
120
 
 
121
                mBuffer = &buffer;
 
122
 
 
123
                // Load scene graph 
 
124
                loader.setObjectFlags(   COLLADASaxFWL::Loader::ASSET_FLAG 
 
125
                                                           | COLLADASaxFWL::Loader::EFFECT_FLAG
 
126
                                                           | COLLADASaxFWL::Loader::MATERIAL_FLAG
 
127
                                                           | COLLADASaxFWL::Loader::LIBRARY_NODES_FLAG
 
128
                                                           | COLLADASaxFWL::Loader::VISUAL_SCENES_FLAG
 
129
                                                           | COLLADASaxFWL::Loader::SCENE_FLAG
 
130
                                                           | COLLADASaxFWL::Loader::GEOMETRY_FLAG);
 
131
                if ( !root.loadDocument(mInputFile.toNativePath()) )
 
132
                        return false;
 
133
 
 
134
                createUniqueIdNodeMap();
 
135
 
 
136
                SceneGraphHandler sceneGraphHandler(this, mVisualScene, mLibraryNodesList);
 
137
                sceneGraphHandler.handle();
 
138
 
 
139
                calculateMaterialsBlockLength();
 
140
                calculateMeshesLength();
 
141
 
 
142
                writeHeader( sceneGraphHandler.getScenegraphLength() );
 
143
                writeMaterialsBlocks();
 
144
 
 
145
                // load and write geometries
 
146
                mCurrentRun = GEOMETRY_RUN;
 
147
                if ( !root.loadDocument(mInputFile.toNativePath()) )
 
148
                        return false;
 
149
 
 
150
                SceneGraphWriter sceneGraphWriter(this, mVisualScene, mLibraryNodesList);
 
151
                sceneGraphWriter.write( sceneGraphHandler.getScenegraphLength() );
 
152
 
 
153
                return true;
 
154
        }
 
155
 
 
156
        //--------------------------------------------------------------------
 
157
        void Writer::calculateMeshesLength()
 
158
        {
 
159
                MeshDataMap::const_iterator it = mMeshDataMap.begin();
 
160
                for ( ; it != mMeshDataMap.end(); ++it)
 
161
                {
 
162
                        const MeshData& meshData = it->second;
 
163
                        MeshLengthCalculator meshLengthCalculator( this, meshData );
 
164
                        meshLengthCalculator.handle();
 
165
                }
 
166
        }
 
167
 
 
168
        //--------------------------------------------------------------------
 
169
        void Writer::calculateMaterialsBlockLength()
 
170
        {
 
171
                MaterialsLengthCalculator materialsLengthCalculator(this);
 
172
                materialsLengthCalculator.calculate();
 
173
        }
 
174
 
 
175
        //--------------------------------------------------------------------
 
176
        void Writer::writeMaterialsBlocks()
 
177
        {
 
178
                MaterialsWriter materialsWriter(this);
 
179
                materialsWriter.write();
 
180
        }
 
181
 
 
182
        //------------------------------
 
183
        void Writer::createUniqueIdNodeMap( COLLADAFW::Node* node )
 
184
        {
 
185
                mUniqueIdNodeMap[node->getUniqueId()] = node;
 
186
                createUniqueIdNodeMap( node->getChildNodes() );
 
187
        }
 
188
 
 
189
        //------------------------------
 
190
        void Writer::createUniqueIdNodeMap( const COLLADAFW::NodePointerArray& nodes )
 
191
        {
 
192
                for ( size_t i = 0, cout = nodes.getCount(); i < cout; ++i)
 
193
                {
 
194
                        COLLADAFW::Node* node = nodes[i];
 
195
                        createUniqueIdNodeMap( node );
 
196
                }
 
197
        }
 
198
 
 
199
        //------------------------------
 
200
        void Writer::createUniqueIdNodeMap()
 
201
        {
 
202
                createUniqueIdNodeMap( mVisualScene->getRootNodes() );
 
203
                Writer::LibraryNodesList::const_iterator it = mLibraryNodesList.begin();
 
204
                for ( ; it != mLibraryNodesList.end(); ++it )
 
205
                {
 
206
                        const COLLADAFW::LibraryNodes& libraryNodes = *it;
 
207
                        createUniqueIdNodeMap( libraryNodes.getNodes() );
 
208
                }
 
209
        }
 
210
 
 
211
 
 
212
        //--------------------------------------------------------------------
 
213
        void Writer::cancel( const String& errorMessage )
 
214
        {
 
215
        }
 
216
 
 
217
        //--------------------------------------------------------------------
 
218
        void Writer::start()
 
219
        {
 
220
        }
 
221
 
 
222
        //--------------------------------------------------------------------
 
223
        void Writer::finish()
 
224
        {
 
225
        }
 
226
 
 
227
        //--------------------------------------------------------------------
 
228
        bool Writer::writeGlobalAsset( const COLLADAFW::FileInfo* asset )
 
229
        {
 
230
                if ( mCurrentRun != SCENEGRAPH_RUN )
 
231
                        return true;
 
232
                return true;
 
233
        }
 
234
 
 
235
        //--------------------------------------------------------------------
 
236
        bool Writer::writeVisualScene( const COLLADAFW::VisualScene* visualScene )
 
237
        {
 
238
                if ( mCurrentRun != SCENEGRAPH_RUN )
 
239
                        return true;
 
240
                mVisualScene = new COLLADAFW::VisualScene(*visualScene);
 
241
                return true;
 
242
        }
 
243
 
 
244
        //--------------------------------------------------------------------
 
245
        bool Writer::writeLibraryNodes( const COLLADAFW::LibraryNodes* libraryNodes )
 
246
        {
 
247
                if ( mCurrentRun != SCENEGRAPH_RUN )
 
248
                        return true;
 
249
                mLibraryNodesList.push_back(*libraryNodes);
 
250
                return true;
 
251
        }
 
252
 
 
253
        //--------------------------------------------------------------------
 
254
        bool Writer::writeGeometry( const COLLADAFW::Geometry* geometry )
 
255
        {
 
256
                if ( geometry->getType() != COLLADAFW::Geometry::GEO_TYPE_MESH )
 
257
                        return true;
 
258
 
 
259
                switch ( mCurrentRun )
 
260
                {
 
261
                case SCENEGRAPH_RUN:
 
262
                        {
 
263
                                MeshHandler meshHandler( this, (COLLADAFW::Mesh*)geometry );
 
264
                                return meshHandler.handle();
 
265
                                break;
 
266
                        }
 
267
                case GEOMETRY_RUN:
 
268
                        {
 
269
                                MeshWriter meshWriter( this, (COLLADAFW::Mesh*)geometry );
 
270
                                return meshWriter.handle();
 
271
                                break;
 
272
                        }
 
273
                default:
 
274
                        return true;
 
275
                }
 
276
        }
 
277
 
 
278
        //--------------------------------------------------------------------
 
279
        bool Writer::writeMaterial( const COLLADAFW::Material* material )
 
280
        {
 
281
                if ( mCurrentRun != SCENEGRAPH_RUN )
 
282
                        return true;
 
283
                mUniqueIdFWMaterialMap.insert(std::make_pair(material->getUniqueId(),*material ));
 
284
                return true;
 
285
        }
 
286
 
 
287
        //--------------------------------------------------------------------
 
288
        bool Writer::writeEffect( const COLLADAFW::Effect* effect )
 
289
        {
 
290
                if ( mCurrentRun != SCENEGRAPH_RUN )
 
291
                        return true;
 
292
                mUniqueIdFWEffectMap.insert(std::make_pair(effect->getUniqueId(),*effect ));
 
293
                return true;
 
294
        }
 
295
 
 
296
        //--------------------------------------------------------------------
 
297
        bool Writer::writeCamera( const COLLADAFW::Camera* camera )
 
298
        {
 
299
                if ( mCurrentRun != SCENEGRAPH_RUN )
 
300
                        return true;
 
301
                return true;
 
302
        }
 
303
 
 
304
        //--------------------------------------------------------------------
 
305
        bool Writer::writeImage( const COLLADAFW::Image* image )
 
306
        {
 
307
                if ( mCurrentRun != SCENEGRAPH_RUN )
 
308
                        return true;
 
309
                mUniqueIdFWImageMap.insert(std::make_pair(image->getUniqueId(),*image ));
 
310
                return true;
 
311
        }
 
312
 
 
313
        //--------------------------------------------------------------------
 
314
        bool Writer::writeLight( const COLLADAFW::Light* light )
 
315
        {
 
316
                if ( mCurrentRun != SCENEGRAPH_RUN )
 
317
                        return true;
 
318
                return true;
 
319
        }
 
320
 
 
321
        //--------------------------------------------------------------------
 
322
        bool Writer::writeAnimation( const COLLADAFW::Animation* animation )
 
323
        {
 
324
                return true;
 
325
        }
 
326
 
 
327
        //--------------------------------------------------------------------
 
328
        bool Writer::writeAnimationList( const COLLADAFW::AnimationList* animationList )
 
329
        {
 
330
                return true;
 
331
        }
 
332
 
 
333
        //--------------------------------------------------------------------
 
334
        void Writer::fillMaterialBindingMap(const GeometryMaterialBinding& materialBinding)
 
335
        {
 
336
                const COLLADAFW::MaterialBindingArray& fwBindings = materialBinding.fwInstanceGeometry->getMaterialBindings();
 
337
                size_t fwBindingCount = fwBindings.getCount();
 
338
                
 
339
                if ( fwBindingCount == materialBinding.bindingMap.size() )
 
340
                {
 
341
                        //both container have already equal size. Nothing to do
 
342
                        return;
 
343
                }
 
344
 
 
345
                for ( size_t i = 0; i< fwBindingCount; ++i)
 
346
                {
 
347
                        const COLLADAFW::MaterialBinding& fwBinding = fwBindings[i];
 
348
                        materialBinding.bindingMap.insert(std::make_pair(fwBinding.getMaterialId(), fwBinding.getReferencedMaterial()));
 
349
                }
 
350
        }
 
351
 
 
352
        //--------------------------------------------------------------------
 
353
        bool Writer::compare( const GeometryMaterialBinding& lhs, const GeometryMaterialBinding& rhs )
 
354
        {
 
355
                const COLLADAFW::UniqueId& lhsGeometryUniqueId = lhs.fwInstanceGeometry->getInstanciatedObjectId();
 
356
                const COLLADAFW::UniqueId& rhsGeometryUniqueId = rhs.fwInstanceGeometry->getInstanciatedObjectId();
 
357
                
 
358
                if ( lhsGeometryUniqueId < rhsGeometryUniqueId )
 
359
                        return true;
 
360
 
 
361
                if ( lhsGeometryUniqueId > rhsGeometryUniqueId )
 
362
                        return false;
 
363
 
 
364
                const COLLADAFW::MaterialBindingArray& lhsFwBinding = lhs.fwInstanceGeometry->getMaterialBindings();
 
365
                const COLLADAFW::MaterialBindingArray& rhsFwBinding = rhs.fwInstanceGeometry->getMaterialBindings();
 
366
 
 
367
                if ( lhsFwBinding.getCount() < rhsFwBinding.getCount() )
 
368
                        return true;
 
369
 
 
370
                if ( lhsFwBinding.getCount() > rhsFwBinding.getCount() )
 
371
                        return false;
 
372
 
 
373
                fillMaterialBindingMap(lhs);
 
374
                fillMaterialBindingMap(rhs);
 
375
 
 
376
                const MaterialBindingMap& lhsBindingMap = lhs.bindingMap;
 
377
                const MaterialBindingMap& rhsBindingMap = rhs.bindingMap;
 
378
 
 
379
                assert(lhsBindingMap.size() == rhsBindingMap.size());
 
380
 
 
381
                MaterialBindingMap::const_iterator lhsIt = lhsBindingMap.begin();
 
382
                MaterialBindingMap::const_iterator rhsIt = rhsBindingMap.begin();
 
383
 
 
384
                for ( ; lhsIt != lhsBindingMap.end(); ++lhsIt, ++rhsIt)
 
385
                {
 
386
                        if ( lhsIt->first < rhsIt->first )
 
387
                                return true;
 
388
 
 
389
                        if ( lhsIt->first > rhsIt->first )
 
390
                                return false;
 
391
 
 
392
                        if ( lhsIt->second < rhsIt->second )
 
393
                                return true;
 
394
 
 
395
                        if ( lhsIt->second > rhsIt->second )
 
396
                                return false;
 
397
                }
 
398
 
 
399
                return false;
 
400
        }
 
401
 
 
402
        //--------------------------------------------------------------------
 
403
        bool Writer::writeHeader( ChunkLength sceneGraphLength )
 
404
        {
 
405
                // triangle mesh 
 
406
                //plus material blocks
 
407
                //plus plus empty chunk
 
408
                ChunkLength edit3DSLength = mObjectAndMaterialBlockLength + EMPTY_CHUNK_LENGTH ;
 
409
 
 
410
                // add mesh version size
 
411
                edit3DSLength += MESH_VERSION_CHUNK_LENGTH;
 
412
 
 
413
                // add EDIT_MASTERSCALE version length
 
414
                edit3DSLength += EDIT_MASTERSCALE_CHUNK_LENGTH;
 
415
 
 
416
 
 
417
                // edit 3ds plus empty chunk
 
418
                ChunkLength mainLength = edit3DSLength + EMPTY_CHUNK_LENGTH;
 
419
 
 
420
                // add M3D3DS_VERSION version length and scene graph length
 
421
                mainLength += M3D_VERSION_CHUNK_LENGTH+ sceneGraphLength;
 
422
 
 
423
 
 
424
                //  write header
 
425
 
 
426
                //Main chunk
 
427
                mBuffer->copyToBuffer(MAIN3DS);
 
428
                mBuffer->copyToBuffer(mainLength);
 
429
 
 
430
 
 
431
                // M3D_VERSION version
 
432
                mBuffer->copyToBuffer(M3D3DS_VERSION);
 
433
                mBuffer->copyToBuffer(M3D_VERSION_CHUNK_LENGTH);
 
434
                mBuffer->copyToBuffer(M3D_VERSION);
 
435
 
 
436
                //3d editor chunk
 
437
                mBuffer->copyToBuffer(EDIT3DS);
 
438
                mBuffer->copyToBuffer(edit3DSLength);
 
439
 
 
440
                // mesh version
 
441
                mBuffer->copyToBuffer(MESH3DS_VERSION);
 
442
                mBuffer->copyToBuffer(MESH_VERSION_CHUNK_LENGTH);
 
443
                mBuffer->copyToBuffer(MESH_VERSION);
 
444
 
 
445
                // master scale
 
446
                mBuffer->copyToBuffer(EDIT_MASTERSCALE);
 
447
                mBuffer->copyToBuffer(EDIT_MASTERSCALE_CHUNK_LENGTH);
 
448
                mBuffer->copyToBuffer((float)1);
 
449
 
 
450
                return true;
 
451
        }
 
452
 
 
453
        //--------------------------------------------------------------------
 
454
        ChunkLength Writer::getObjectNameLength()
 
455
        {
 
456
                return OBJECT_NAME_LENGTH;
 
457
        }
 
458
 
 
459
        //--------------------------------------------------------------------
 
460
        ChunkLength Writer::getMaterialNameLength()
 
461
        {
 
462
                return OBJECT_NAME_LENGTH;
 
463
        }
 
464
 
 
465
        //--------------------------------------------------------------------
 
466
        template<class NumberType, char prefix>
 
467
        const char* Writer::calculateNameFromNumber( const NumberType& number)
 
468
        {
 
469
                // we do not support to big meshes here
 
470
                assert(number < 100000);
 
471
                static char buffer[OBJECT_NAME_LENGTH];
 
472
                char* p = buffer;
 
473
                *(p++) = prefix;
 
474
                if ( number < 1000000) *(p++) = '0';
 
475
                if ( number < 100000) *(p++) = '0';
 
476
                if ( number < 10000) *(p++) = '0';
 
477
                if ( number < 100) *(p++) = '0';
 
478
                if ( number < 10) *(p++) = '0';
 
479
                p += Common::itoa( number, p, 10);
 
480
                return buffer;
 
481
 
 
482
        }
 
483
 
 
484
 
 
485
        //--------------------------------------------------------------------
 
486
        const char* Writer::calculateMaterialNameFromMaterialNumer( const MaterialNumber& materialNumber)
 
487
        {
 
488
                return calculateNameFromNumber<MaterialNumber, 'M'>(materialNumber);
 
489
        }
 
490
 
 
491
        //--------------------------------------------------------------------
 
492
        const char* Writer::calculateObjectNameFromObjectId( const ObjectId& objectId)
 
493
        {
 
494
                return calculateNameFromNumber<ObjectId, 'G'>(objectId);
 
495
        }
 
496
                
 
497
} // namespace DAE23ds