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

« back to all changes in this revision

Viewing changes to COLLADAMax/src/COLLADAMaxExportSceneGraph.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) 2008-2009 NetAllied Systems GmbH
 
3
 
 
4
        This file is part of COLLADAMax.
 
5
 
 
6
    Portions of the code are:
 
7
    Copyright (c) 2005-2007 Feeling Software Inc.
 
8
    Copyright (c) 2005-2007 Sony Computer Entertainment America
 
9
    
 
10
    Based on the 3dsMax COLLADASW Tools:
 
11
    Copyright (c) 2005-2006 Autodesk Media Entertainment
 
12
        
 
13
    Licensed under the MIT Open Source License, 
 
14
    for details please see LICENSE file or the website
 
15
    http://www.opensource.org/licenses/mit-license.php
 
16
*/
 
17
 
 
18
 
 
19
#include "COLLADAMaxStableHeaders.h"
 
20
 
 
21
#include "COLLADAMaxControllerExporter.h"
 
22
#include "COLLADAMaxDocumentExporter.h"
 
23
#include "COLLADAMaxExportSceneGraph.h"
 
24
 
 
25
#include <sstream>
 
26
#include <iostream>
 
27
 
 
28
namespace COLLADAMax
 
29
{
 
30
 
 
31
        const String ExportSceneGraph::HELPER_GEOMETRY_ID_SUFFIX ="-helper_geometry";
 
32
        const String ExportSceneGraph::JOINT_SID_BASE_NAME = "joint";
 
33
 
 
34
        ExportSceneGraph::ExportSceneGraph ( INode * iNode, const COLLADASW::URI& maxFileUri, DocumentExporter const& documentExporter, COLLADABU::IDList& xRefExportFileNames )
 
35
            : mExportSelection ( false ),
 
36
            mRootNode ( iNode ),
 
37
                        mMaxFileUri(maxFileUri),
 
38
            mDocumentExporter(documentExporter),
 
39
                        mXRefExportFileNames(xRefExportFileNames),
 
40
            mRootExportNode ( 0 ),
 
41
                        mBoneCount(0)
 
42
    {
 
43
                if ( mMaxFileUri.getScheme().empty() )
 
44
                        mMaxFileUri.setScheme(COLLADASW::URI::SCHEME_FILE);
 
45
        }
 
46
 
 
47
 
 
48
        //---------------------------------------------------------------
 
49
        ExportSceneGraph::~ExportSceneGraph()
 
50
        {
 
51
        for ( INodeXRefSceneGraphListMap::iterator i = mINodeXRefSceneGraphListMap.begin(); i != mINodeXRefSceneGraphListMap.end(); ++i )
 
52
        {
 
53
            for ( XRefSceneGraphList::iterator j = i->second.begin(); j != i->second.end(); ++j )
 
54
            {
 
55
                            delete j->exportSceneGraph;
 
56
            }
 
57
        }
 
58
        }
 
59
 
 
60
 
 
61
    //---------------------------------------------------------------
 
62
    bool ExportSceneGraph::create ( bool exportSelection )
 
63
    {
 
64
        mExportSelection = exportSelection;
 
65
 
 
66
        if ( mRootExportNode )
 
67
            delete mRootExportNode;
 
68
 
 
69
                bool isNotEmpty;
 
70
                mRootExportNode = create ( mRootNode, 0, isNotEmpty );
 
71
 
 
72
                findReferencedObjects(mRootExportNode);
 
73
 
 
74
        bool shouldExportXRefedFiles = mDocumentExporter.getOptions().getIncludeXRefs();
 
75
        bool shouldAddInstanceNodesForXRefs = true;
 
76
 
 
77
                int xRefFileCount = mRootNode->GetXRefFileCount();
 
78
 
 
79
                for ( int i = 0; i < xRefFileCount; ++i)
 
80
                {
 
81
#ifdef MAX_2010_OR_NEWER
 
82
            if ( mRootNode->GetXRefFlags(i) & XREF_DISABLED )
 
83
            {
 
84
                continue;
 
85
            }
 
86
#endif
 
87
 
 
88
#ifdef MAX_2010_OR_NEWER
 
89
 #ifdef UNICODE
 
90
            std::string XRefFileNameString = COLLADABU::StringUtils::wideString2utf8String(mRootNode->GetXRefFile(i).GetFileName().data());
 
91
            const char* XRefFileName = XRefFileNameString.c_str();
 
92
 #else
 
93
                        const char* XRefFileName = mRootNode->GetXRefFile(i).GetFileName().data();
 
94
 #endif
 
95
#else
 
96
                        const char* XRefFileName = mRootNode->GetXRefFileName(i).data();
 
97
#endif
 
98
                        COLLADASW::URI uri(COLLADASW::URI::nativePathToUri(NativeString(XRefFileName)));
 
99
            
 
100
                        XRefSceneGraph xRefScene;
 
101
                        xRefScene.exportFileBaseName = mXRefExportFileNames.addId(uri.getPathFileBase(), false);
 
102
            xRefScene.exportSceneGraph = new ExportSceneGraph(mRootNode->GetXRefTree(i), uri, mDocumentExporter, mXRefExportFileNames);
 
103
 
 
104
            INode* xRefParent = mRootNode->GetXRefParent(i);
 
105
 
 
106
            if ( shouldAddInstanceNodesForXRefs )
 
107
            {
 
108
                auto& xRefSceneGraphList = mINodeXRefSceneGraphListMap[xRefParent ? xRefParent : mRootNode];
 
109
                xRefSceneGraphList.push_back(xRefScene);
 
110
 
 
111
                                isNotEmpty = true;
 
112
            }
 
113
 
 
114
            if ( shouldExportXRefedFiles )
 
115
            {
 
116
                            if ( xRefScene.exportSceneGraph->create(false) )
 
117
                            {
 
118
                                    isNotEmpty = true;
 
119
                            }
 
120
            }
 
121
            else
 
122
            {
 
123
                if ( shouldAddInstanceNodesForXRefs )
 
124
                {
 
125
                    xRefScene.exportSceneGraph->create(true);
 
126
                }
 
127
            }
 
128
                }
 
129
 
 
130
        return isNotEmpty;
 
131
    }
 
132
 
 
133
    //---------------------------------------------------------------
 
134
    ExportNode * ExportSceneGraph::create ( INode *iNode, ExportNode* parent, bool& isInVisualScene)
 
135
    {
 
136
 
 
137
        ExportNode * exportNode = new ExportNode ( iNode, parent );
 
138
 
 
139
                isInVisualScene = isNodeInVisualScene(iNode);
 
140
 
 
141
        int numberOfChildren = iNode->NumberOfChildren();
 
142
 
 
143
        for ( int i = 0; i < numberOfChildren; ++i )
 
144
        {
 
145
            INode * child = iNode->GetChildNode ( i );
 
146
                        bool isChildInVisualScene;
 
147
            ExportNode * childExportNode = create ( child, exportNode, isChildInVisualScene );
 
148
 
 
149
                        exportNode->add( childExportNode );
 
150
 
 
151
            if ( isChildInVisualScene )
 
152
               isInVisualScene = true;
 
153
        }
 
154
 
 
155
                exportNode->setId ( mNodeIdList.addId ( NativeString(iNode->GetName()) ) );
 
156
                mINodeExportNodeMap[iNode] = exportNode;
 
157
                exportNode->createControllerList();
 
158
                //createBones(exportNode);
 
159
                exportNode->setIsInVisualScene(isInVisualScene);
 
160
 
 
161
                return exportNode;
 
162
    }
 
163
 
 
164
        /*
 
165
        void ExportSceneGraph::createBones(INode *iNode, ExportNode* exportNode, bool& isInVisualScene)
 
166
        {
 
167
                if ( !exportNode->getType() == ExportNode::MESH )
 
168
                        return;
 
169
 
 
170
                ControllerList* controllers = exportNode->getControllerList();
 
171
                size_t controllerCount = controllers->getControllerCount();
 
172
                for ( size_t i = 0; i < controllerCount; ++i)
 
173
                {
 
174
                        Controller* controller = controllers->getReferencedJoints()
 
175
                }
 
176
 
 
177
                
 
178
                
 
179
        }
 
180
*/
 
181
    //---------------------------------------------------------------
 
182
    bool ExportSceneGraph::isNodeInVisualScene ( INode * iNode )
 
183
    {
 
184
        return ! ( mExportSelection && !iNode->Selected() ) && !iNode->IsHidden();
 
185
 
 
186
    }
 
187
 
 
188
        //---------------------------------------------------------------
 
189
        COLLADASW::String ExportSceneGraph::createJointSid()
 
190
        {
 
191
                return JOINT_SID_BASE_NAME + COLLADASW::Utils::toString(mBoneCount++);
 
192
        }
 
193
 
 
194
        //---------------------------------------------------------------
 
195
        ExportNode * ExportSceneGraph::getExportNode( INode* iNode ) const
 
196
        {
 
197
                INodeExportNodeMap::const_iterator it = mINodeExportNodeMap.find(iNode);
 
198
 
 
199
                if ( it != mINodeExportNodeMap.end() )
 
200
                        return it->second;
 
201
                else
 
202
                        return 0;
 
203
        }
 
204
 
 
205
    //---------------------------------------------------------------
 
206
    const ExportSceneGraph::XRefSceneGraphList* ExportSceneGraph::getXRefSceneGraphList(INode* node) const
 
207
    {
 
208
        auto i = mINodeXRefSceneGraphListMap.find(node);
 
209
 
 
210
        if ( i == mINodeXRefSceneGraphListMap.cend() )
 
211
        {
 
212
            return NULL;
 
213
        }
 
214
 
 
215
        return &i->second;
 
216
    }
 
217
 
 
218
    const ExportSceneGraph::XRefSceneGraphList ExportSceneGraph::findAllXRefScenes() const
 
219
    {
 
220
        std::set<const XRefSceneGraph*> set;
 
221
 
 
222
        for ( auto i = mINodeXRefSceneGraphListMap.cbegin(); i != mINodeXRefSceneGraphListMap.cend(); ++ i )
 
223
        {
 
224
            for ( XRefSceneGraphList::const_iterator j = i->second.cbegin(); j != i->second.cend(); ++j )
 
225
            {
 
226
                set.insert(&*j);
 
227
            }
 
228
        }
 
229
 
 
230
        //double copying... could have been evaded by changing return type
 
231
        //but I do not want to create/force new conventions... anyway it should
 
232
        //not be a big problem since it is, at most, called once per scene.
 
233
 
 
234
        ExportSceneGraph::XRefSceneGraphList result;
 
235
 
 
236
        for ( auto i = set.cbegin(); i != set.cend(); ++i )
 
237
        {
 
238
            result.push_back(**i);
 
239
        }
 
240
 
 
241
        return result;
 
242
    }
 
243
 
 
244
        //---------------------------------------------------------------
 
245
        void ExportSceneGraph::findReferencedObjects( ExportNode* exportNode )
 
246
        {
 
247
                if ( exportNode->hasControllers() )
 
248
                {
 
249
                        ControllerList* controllerList = exportNode->getControllerList();
 
250
 
 
251
                        size_t controllerCount = controllerList->getControllerCount();
 
252
 
 
253
                        for ( size_t j = 0; j < controllerCount; ++j)
 
254
                        {
 
255
                                Controller* controller = controllerList->getController(j);
 
256
 
 
257
                                if ( controller->getType() != Controller::MORPH )
 
258
                                        continue;
 
259
 
 
260
                                MorphController* morphController = (MorphController*)controller;
 
261
 
 
262
                                MorphR3* morpher = morphController->getMorph();
 
263
 
 
264
                                size_t channelBankCount = morpher->chanBank.size();
 
265
                                for ( size_t i = 0; i<channelBankCount; ++i)
 
266
                                {
 
267
                                        morphChannel& channel = morpher->chanBank[i];
 
268
 
 
269
                                        if (!channel.mActive || channel.mNumPoints == 0) 
 
270
                                                continue;
 
271
 
 
272
                                        INode* targetINode = channel.mConnection;
 
273
 
 
274
                                        if ( !targetINode )
 
275
                                        {
 
276
                                                MorphControllerHelperGeometry morphControllerHelperGeometry;
 
277
                                                morphControllerHelperGeometry.exportNode = exportNode;
 
278
                                                morphControllerHelperGeometry.morphController = morphController;
 
279
                                                morphControllerHelperGeometry.controllerId = ControllerExporter::getControllerId(*exportNode, controllerCount - j, controllerList->getController(j)->getType());
 
280
                                                morphControllerHelperGeometry.channelBankindex = i;
 
281
                                                mMorphControllerHelperGeometryList.push_back(morphControllerHelperGeometry);
 
282
                                        }
 
283
                                        else
 
284
                                        {
 
285
                                                ExportNode* targetExportNode = getExportNode(targetINode);
 
286
                                                targetExportNode->setIsReferenced(true);
 
287
                                        }
 
288
                                }
 
289
 
 
290
                        }
 
291
                }
 
292
 
 
293
                size_t numberOfChildren = exportNode->getNumberOfChildren();
 
294
 
 
295
                for ( size_t i = 0; i < numberOfChildren; ++i )
 
296
                        findReferencedObjects(exportNode->getChild(i));
 
297
 
 
298
        }
 
299
 
 
300
        //---------------------------------------------------------------
 
301
        String ExportSceneGraph::getMorphControllerHelperId( const MorphControllerHelperGeometry& morphControllerHelperGeometry )
 
302
        {
 
303
                String id = morphControllerHelperGeometry.controllerId;
 
304
                id += HELPER_GEOMETRY_ID_SUFFIX;
 
305
                id += COLLADASW::Utils::toString(morphControllerHelperGeometry.channelBankindex);
 
306
                id += "-";
 
307
#ifdef UNICODE
 
308
        id += COLLADABU::StringUtils::wideString2utf8String(morphControllerHelperGeometry.morphController->getMorph()->chanBank[morphControllerHelperGeometry.channelBankindex].mName.data());
 
309
#else
 
310
                id += morphControllerHelperGeometry.morphController->getMorph()->chanBank[morphControllerHelperGeometry.channelBankindex].mName;
 
311
#endif
 
312
                return id;
 
313
        }
 
314
 
 
315
        //---------------------------------------------------------------
 
316
        bool MorphControllerHelperGeometry::operator<( const MorphControllerHelperGeometry& rhs ) const
 
317
        {
 
318
                if ( exportNode < rhs.exportNode)
 
319
                        return true;
 
320
 
 
321
                if ( exportNode > rhs.exportNode)
 
322
                        return false;
 
323
 
 
324
                if ( morphController < rhs.morphController)
 
325
                        return true;
 
326
 
 
327
                if ( morphController > rhs.morphController)
 
328
                        return false;
 
329
 
 
330
                if ( channelBankindex < rhs.channelBankindex)
 
331
                        return true;
 
332
 
 
333
                if ( channelBankindex > rhs.channelBankindex)
 
334
                        return false;
 
335
 
 
336
                return false;
 
337
        }
 
338
}