2
Copyright (c) 2008-2009 NetAllied Systems GmbH
4
This file is part of COLLADAMax.
6
Portions of the code are:
7
Copyright (c) 2005-2007 Feeling Software Inc.
8
Copyright (c) 2005-2007 Sony Computer Entertainment America
10
Based on the 3dsMax COLLADASW Tools:
11
Copyright (c) 2005-2006 Autodesk Media Entertainment
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
19
#include "COLLADAMaxStableHeaders.h"
21
#include "COLLADAMaxControllerExporter.h"
22
#include "COLLADAMaxDocumentExporter.h"
23
#include "COLLADAMaxExportSceneGraph.h"
31
const String ExportSceneGraph::HELPER_GEOMETRY_ID_SUFFIX ="-helper_geometry";
32
const String ExportSceneGraph::JOINT_SID_BASE_NAME = "joint";
34
ExportSceneGraph::ExportSceneGraph ( INode * iNode, const COLLADASW::URI& maxFileUri, DocumentExporter const& documentExporter, COLLADABU::IDList& xRefExportFileNames )
35
: mExportSelection ( false ),
37
mMaxFileUri(maxFileUri),
38
mDocumentExporter(documentExporter),
39
mXRefExportFileNames(xRefExportFileNames),
40
mRootExportNode ( 0 ),
43
if ( mMaxFileUri.getScheme().empty() )
44
mMaxFileUri.setScheme(COLLADASW::URI::SCHEME_FILE);
48
//---------------------------------------------------------------
49
ExportSceneGraph::~ExportSceneGraph()
51
for ( INodeXRefSceneGraphListMap::iterator i = mINodeXRefSceneGraphListMap.begin(); i != mINodeXRefSceneGraphListMap.end(); ++i )
53
for ( XRefSceneGraphList::iterator j = i->second.begin(); j != i->second.end(); ++j )
55
delete j->exportSceneGraph;
61
//---------------------------------------------------------------
62
bool ExportSceneGraph::create ( bool exportSelection )
64
mExportSelection = exportSelection;
66
if ( mRootExportNode )
67
delete mRootExportNode;
70
mRootExportNode = create ( mRootNode, 0, isNotEmpty );
72
findReferencedObjects(mRootExportNode);
74
bool shouldExportXRefedFiles = mDocumentExporter.getOptions().getIncludeXRefs();
75
bool shouldAddInstanceNodesForXRefs = true;
77
int xRefFileCount = mRootNode->GetXRefFileCount();
79
for ( int i = 0; i < xRefFileCount; ++i)
81
#ifdef MAX_2010_OR_NEWER
82
if ( mRootNode->GetXRefFlags(i) & XREF_DISABLED )
88
#ifdef MAX_2010_OR_NEWER
90
std::string XRefFileNameString = COLLADABU::StringUtils::wideString2utf8String(mRootNode->GetXRefFile(i).GetFileName().data());
91
const char* XRefFileName = XRefFileNameString.c_str();
93
const char* XRefFileName = mRootNode->GetXRefFile(i).GetFileName().data();
96
const char* XRefFileName = mRootNode->GetXRefFileName(i).data();
98
COLLADASW::URI uri(COLLADASW::URI::nativePathToUri(NativeString(XRefFileName)));
100
XRefSceneGraph xRefScene;
101
xRefScene.exportFileBaseName = mXRefExportFileNames.addId(uri.getPathFileBase(), false);
102
xRefScene.exportSceneGraph = new ExportSceneGraph(mRootNode->GetXRefTree(i), uri, mDocumentExporter, mXRefExportFileNames);
104
INode* xRefParent = mRootNode->GetXRefParent(i);
106
if ( shouldAddInstanceNodesForXRefs )
108
auto& xRefSceneGraphList = mINodeXRefSceneGraphListMap[xRefParent ? xRefParent : mRootNode];
109
xRefSceneGraphList.push_back(xRefScene);
114
if ( shouldExportXRefedFiles )
116
if ( xRefScene.exportSceneGraph->create(false) )
123
if ( shouldAddInstanceNodesForXRefs )
125
xRefScene.exportSceneGraph->create(true);
133
//---------------------------------------------------------------
134
ExportNode * ExportSceneGraph::create ( INode *iNode, ExportNode* parent, bool& isInVisualScene)
137
ExportNode * exportNode = new ExportNode ( iNode, parent );
139
isInVisualScene = isNodeInVisualScene(iNode);
141
int numberOfChildren = iNode->NumberOfChildren();
143
for ( int i = 0; i < numberOfChildren; ++i )
145
INode * child = iNode->GetChildNode ( i );
146
bool isChildInVisualScene;
147
ExportNode * childExportNode = create ( child, exportNode, isChildInVisualScene );
149
exportNode->add( childExportNode );
151
if ( isChildInVisualScene )
152
isInVisualScene = true;
155
exportNode->setId ( mNodeIdList.addId ( NativeString(iNode->GetName()) ) );
156
mINodeExportNodeMap[iNode] = exportNode;
157
exportNode->createControllerList();
158
//createBones(exportNode);
159
exportNode->setIsInVisualScene(isInVisualScene);
165
void ExportSceneGraph::createBones(INode *iNode, ExportNode* exportNode, bool& isInVisualScene)
167
if ( !exportNode->getType() == ExportNode::MESH )
170
ControllerList* controllers = exportNode->getControllerList();
171
size_t controllerCount = controllers->getControllerCount();
172
for ( size_t i = 0; i < controllerCount; ++i)
174
Controller* controller = controllers->getReferencedJoints()
181
//---------------------------------------------------------------
182
bool ExportSceneGraph::isNodeInVisualScene ( INode * iNode )
184
return ! ( mExportSelection && !iNode->Selected() ) && !iNode->IsHidden();
188
//---------------------------------------------------------------
189
COLLADASW::String ExportSceneGraph::createJointSid()
191
return JOINT_SID_BASE_NAME + COLLADASW::Utils::toString(mBoneCount++);
194
//---------------------------------------------------------------
195
ExportNode * ExportSceneGraph::getExportNode( INode* iNode ) const
197
INodeExportNodeMap::const_iterator it = mINodeExportNodeMap.find(iNode);
199
if ( it != mINodeExportNodeMap.end() )
205
//---------------------------------------------------------------
206
const ExportSceneGraph::XRefSceneGraphList* ExportSceneGraph::getXRefSceneGraphList(INode* node) const
208
auto i = mINodeXRefSceneGraphListMap.find(node);
210
if ( i == mINodeXRefSceneGraphListMap.cend() )
218
const ExportSceneGraph::XRefSceneGraphList ExportSceneGraph::findAllXRefScenes() const
220
std::set<const XRefSceneGraph*> set;
222
for ( auto i = mINodeXRefSceneGraphListMap.cbegin(); i != mINodeXRefSceneGraphListMap.cend(); ++ i )
224
for ( XRefSceneGraphList::const_iterator j = i->second.cbegin(); j != i->second.cend(); ++j )
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.
234
ExportSceneGraph::XRefSceneGraphList result;
236
for ( auto i = set.cbegin(); i != set.cend(); ++i )
238
result.push_back(**i);
244
//---------------------------------------------------------------
245
void ExportSceneGraph::findReferencedObjects( ExportNode* exportNode )
247
if ( exportNode->hasControllers() )
249
ControllerList* controllerList = exportNode->getControllerList();
251
size_t controllerCount = controllerList->getControllerCount();
253
for ( size_t j = 0; j < controllerCount; ++j)
255
Controller* controller = controllerList->getController(j);
257
if ( controller->getType() != Controller::MORPH )
260
MorphController* morphController = (MorphController*)controller;
262
MorphR3* morpher = morphController->getMorph();
264
size_t channelBankCount = morpher->chanBank.size();
265
for ( size_t i = 0; i<channelBankCount; ++i)
267
morphChannel& channel = morpher->chanBank[i];
269
if (!channel.mActive || channel.mNumPoints == 0)
272
INode* targetINode = channel.mConnection;
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);
285
ExportNode* targetExportNode = getExportNode(targetINode);
286
targetExportNode->setIsReferenced(true);
293
size_t numberOfChildren = exportNode->getNumberOfChildren();
295
for ( size_t i = 0; i < numberOfChildren; ++i )
296
findReferencedObjects(exportNode->getChild(i));
300
//---------------------------------------------------------------
301
String ExportSceneGraph::getMorphControllerHelperId( const MorphControllerHelperGeometry& morphControllerHelperGeometry )
303
String id = morphControllerHelperGeometry.controllerId;
304
id += HELPER_GEOMETRY_ID_SUFFIX;
305
id += COLLADASW::Utils::toString(morphControllerHelperGeometry.channelBankindex);
308
id += COLLADABU::StringUtils::wideString2utf8String(morphControllerHelperGeometry.morphController->getMorph()->chanBank[morphControllerHelperGeometry.channelBankindex].mName.data());
310
id += morphControllerHelperGeometry.morphController->getMorph()->chanBank[morphControllerHelperGeometry.channelBankindex].mName;
315
//---------------------------------------------------------------
316
bool MorphControllerHelperGeometry::operator<( const MorphControllerHelperGeometry& rhs ) const
318
if ( exportNode < rhs.exportNode)
321
if ( exportNode > rhs.exportNode)
324
if ( morphController < rhs.morphController)
327
if ( morphController > rhs.morphController)
330
if ( channelBankindex < rhs.channelBankindex)
333
if ( channelBankindex > rhs.channelBankindex)