1 /*
2 Copyright (C) 2005-2007 Feeling Software Inc.
3 Portions of the code are:
4 Copyright (C) 2005-2007 Sony Computer Entertainment America
5
6 MIT License: http://www.opensource.org/licenses/mit-license.php
7 */
8 /*
9 Based on the FS Import classes:
10 Copyright (C) 2005-2006 Feeling Software Inc
11 Copyright (C) 2005-2006 Autodesk Media Entertainment
12 MIT License: http://www.opensource.org/licenses/mit-license.php
13 */
14
15 #include "StdAfx.h"
16 #include "FCDocument/FCDocument.h"
17 #include "FCDocument/FCDAnimated.h"
18 #include "FCDocument/FCDAnimation.h"
19 #include "FCDocument/FCDAnimationChannel.h"
20 #include "FCDocument/FCDAnimationClip.h"
21 #include "FCDocument/FCDAnimationCurve.h"
22 #include "FCDocument/FCDAsset.h"
23 #include "FCDocument/FCDCamera.h"
24 #include "FCDocument/FCDController.h"
25 #include "FCDocument/FCDEffect.h"
26 #include "FCDocument/FCDEmitter.h"
27 #include "FCDocument/FCDEntityReference.h"
28 #include "FCDocument/FCDExternalReferenceManager.h"
29 #include "FCDocument/FCDExtra.h"
30 #include "FCDocument/FCDForceField.h"
31 #include "FCDocument/FCDGeometry.h"
32 #include "FCDocument/FCDImage.h"
33 #include "FCDocument/FCDLight.h"
34 #include "FCDocument/FCDLibrary.h"
35 #include "FCDocument/FCDMaterial.h"
36 #include "FCDocument/FCDPlaceHolder.h"
37 #include "FCDocument/FCDPhysicsMaterial.h"
38 #include "FCDocument/FCDPhysicsModel.h"
39 #include "FCDocument/FCDPhysicsScene.h"
40 #include "FCDocument/FCDSceneNode.h"
41 #include "FCDocument/FCDTexture.h"
42 #include "FCDocument/FCDVersion.h"
43 #include "FUtils/FUFileManager.h"
44 #include "FUtils/FUUniqueStringMap.h"
45 #include "FUtils/FUDaeSyntax.h"
46
47 //
48 // FCDocument
49 //
50
51 ImplementObjectType(FCDocument);
52
53 ImplementParameterObject(FCDocument, FCDEntityReference, visualSceneRoot, new FCDEntityReference(parent->GetDocument(), NULL));
54 ImplementParameterObject(FCDocument, FCDEntityReference, physicsSceneRoots, new FCDEntityReference(parent->GetDocument(), NULL));
55 ImplementParameterObject(FCDocument, FCDAsset, asset, new FCDAsset(parent->GetDocument()));
56 ImplementParameterObject(FCDocument, FCDExtra, extra, new FCDExtra(parent->GetDocument(), parent));
57 ImplementParameterObject(FCDocument, FCDAnimationLibrary, animationLibrary, new FCDAnimationLibrary(parent->GetDocument()));
58 ImplementParameterObject(FCDocument, FCDAnimationClipLibrary, animationClipLibrary, new FCDAnimationClipLibrary(parent->GetDocument()));
59 ImplementParameterObject(FCDocument, FCDCameraLibrary, cameraLibrary, new FCDCameraLibrary(parent->GetDocument()));
60 ImplementParameterObject(FCDocument, FCDControllerLibrary, controllerLibrary, new FCDControllerLibrary(parent->GetDocument()));
61 ImplementParameterObject(FCDocument, FCDEffectLibrary, effectLibrary, new FCDEffectLibrary(parent->GetDocument()));
62 ImplementParameterObject(FCDocument, FCDForceFieldLibrary, forceFieldLibrary, new FCDForceFieldLibrary(parent->GetDocument()));
63 ImplementParameterObject(FCDocument, FCDGeometryLibrary, geometryLibrary, new FCDGeometryLibrary(parent->GetDocument()));
64 ImplementParameterObject(FCDocument, FCDImageLibrary, imageLibrary, new FCDImageLibrary(parent->GetDocument()));
65 ImplementParameterObject(FCDocument, FCDLightLibrary, lightLibrary, new FCDLightLibrary(parent->GetDocument()));
66 ImplementParameterObject(FCDocument, FCDMaterialLibrary, materialLibrary, new FCDMaterialLibrary(parent->GetDocument()));
67 ImplementParameterObject(FCDocument, FCDPhysicsModelLibrary, physicsModelLibrary, new FCDPhysicsModelLibrary(parent->GetDocument()));
68 ImplementParameterObject(FCDocument, FCDPhysicsMaterialLibrary, physicsMaterialLibrary, new FCDPhysicsMaterialLibrary(parent->GetDocument()));
69 ImplementParameterObject(FCDocument, FCDPhysicsSceneLibrary, physicsSceneLibrary, new FCDPhysicsSceneLibrary(parent->GetDocument()));
70 ImplementParameterObject(FCDocument, FCDVisualSceneNodeLibrary, visualSceneLibrary, new FCDVisualSceneNodeLibrary(parent->GetDocument()));
71 ImplementParameterObject(FCDocument, FCDEmitterLibrary, emitterLibrary, new FCDEmitterLibrary(parent->GetDocument()));
72
FCDocument()73 FCDocument::FCDocument()
74 : FCDObject(this)
75 , fileManager(NULL), version(NULL), uniqueNameMap(NULL)
76 , InitializeParameterNoArg(visualSceneRoot)
77 , InitializeParameterNoArg(physicsSceneRoots)
78 , InitializeParameterNoArg(asset)
79 , InitializeParameterNoArg(extra)
80 , hasStartTime(false), hasEndTime(false)
81 , InitializeParameter(startTime, 0.0f)
82 , InitializeParameter(endTime, 0.0f)
83 , InitializeParameterNoArg(animationLibrary)
84 , InitializeParameterNoArg(animationClipLibrary)
85 , InitializeParameterNoArg(cameraLibrary)
86 , InitializeParameterNoArg(controllerLibrary)
87 , InitializeParameterNoArg(effectLibrary)
88 , InitializeParameterNoArg(forceFieldLibrary)
89 , InitializeParameterNoArg(geometryLibrary)
90 , InitializeParameterNoArg(imageLibrary)
91 , InitializeParameterNoArg(lightLibrary)
92 , InitializeParameterNoArg(materialLibrary)
93 , InitializeParameterNoArg(physicsModelLibrary)
94 , InitializeParameterNoArg(physicsMaterialLibrary)
95 , InitializeParameterNoArg(physicsSceneLibrary)
96 , InitializeParameterNoArg(visualSceneLibrary)
97 , InitializeParameterNoArg(emitterLibrary)
98 {
99 fileManager = new FUFileManager();
100 version = new FCDVersion(DAE_SCHEMA_VERSION);
101 uniqueNameMap = new FUSUniqueStringMap();
102
103 asset = new FCDAsset(this);
104 externalReferenceManager = new FCDExternalReferenceManager(this);
105 extra = new FCDExtra(this, this);
106 visualSceneRoot = new FCDEntityReference(this, NULL);
107
108 animationLibrary = new FCDAnimationLibrary(this);
109 animationClipLibrary = new FCDAnimationClipLibrary(this);
110 cameraLibrary = new FCDCameraLibrary(this);
111 controllerLibrary = new FCDControllerLibrary(this);
112 emitterLibrary = new FCDEmitterLibrary(this);
113 forceFieldLibrary = new FCDForceFieldLibrary(this);
114 effectLibrary = new FCDEffectLibrary(this);
115 geometryLibrary = new FCDGeometryLibrary(this);
116 imageLibrary = new FCDImageLibrary(this);
117 lightLibrary = new FCDLightLibrary(this);
118 materialLibrary = new FCDMaterialLibrary(this);
119 visualSceneLibrary = new FCDVisualSceneNodeLibrary(this);
120 physicsMaterialLibrary = new FCDPhysicsMaterialLibrary(this);
121 physicsModelLibrary = new FCDPhysicsModelLibrary(this);
122 physicsSceneLibrary = new FCDPhysicsSceneLibrary(this);
123 }
124
~FCDocument()125 FCDocument::~FCDocument()
126 {
127 // Release the external references to and from this document
128 // before all clearing the entities.
129 FUTrackable::Detach();
130
131 externalReferenceManager = NULL;
132
133 // Release the libraries and the asset
134 animationLibrary = NULL;
135 animationClipLibrary = NULL;
136 cameraLibrary = NULL;
137 controllerLibrary = NULL;
138 effectLibrary = NULL;
139 emitterLibrary = NULL;
140 forceFieldLibrary = NULL;
141 geometryLibrary = NULL;
142 imageLibrary = NULL;
143 lightLibrary = NULL;
144 materialLibrary = NULL;
145 visualSceneLibrary = NULL;
146 physicsMaterialLibrary = NULL;
147 physicsModelLibrary = NULL;
148 physicsSceneLibrary = NULL;
149 asset = NULL;
150
151 // Must be released last
152 CLEAR_POINTER_VECTOR(layers);
153 while (!animatedValues.empty()) { animatedValues.begin()->first->Release(); }
154 // animatedValueMap.clear();
155
156 SAFE_DELETE(fileManager);
157 SAFE_DELETE(uniqueNameMap);
158 SAFE_DELETE(version);
159 }
160
GetVisualSceneInstance() const161 const FCDSceneNode* FCDocument::GetVisualSceneInstance() const
162 {
163 if (visualSceneRoot == NULL) return NULL;
164 const FCDEntity* entity = visualSceneRoot->GetEntity();
165 if (entity != NULL && entity->HasType(FCDSceneNode::GetClassType())) return (const FCDSceneNode*) entity;
166 else return NULL;
167 }
168
GetPhysicsSceneInstance(size_t index) const169 const FCDPhysicsScene* FCDocument::GetPhysicsSceneInstance(size_t index) const
170 {
171 if (index == 0 && physicsSceneRoots.empty()) return NULL;
172 FUAssert(index < physicsSceneRoots.size(), return NULL);
173 const FCDEntity* entity = physicsSceneRoots[index]->GetEntity();
174 if (entity != NULL && entity->HasType(FCDPhysicsScene::GetClassType())) return (const FCDPhysicsScene*) entity;
175 else return NULL;
176 }
177
AddPhysicsSceneInstanceReference()178 FCDEntityReference* FCDocument::AddPhysicsSceneInstanceReference()
179 {
180 physicsSceneRoots.push_back(new FCDEntityReference(this, (FCDObjectWithId*) NULL));
181 return physicsSceneRoots.back();
182 }
183
AddPhysicsSceneInstance(FCDPhysicsScene * scene)184 void FCDocument::AddPhysicsSceneInstance(FCDPhysicsScene* scene)
185 {
186 FCDEntityReference* reference = AddPhysicsSceneInstanceReference();
187 reference->SetEntity(scene);
188 }
189
190 // Adds an entity layer to the document.
AddLayer()191 FCDLayer* FCDocument::AddLayer()
192 {
193 FCDLayer* layer = new FCDLayer();
194 layers.push_back(layer);
195 return layer;
196 }
197
198 // Releases an entity layer from the document.
ReleaseLayer(FCDLayer * layer)199 void FCDocument::ReleaseLayer(FCDLayer* layer)
200 {
201 layers.release(layer);
202 }
203
204 // Search for a specific COLLADA library items with a given COLLADA id.
FindAnimation(const fm::string & daeId)205 FCDAnimation* FCDocument::FindAnimation(const fm::string& daeId) { return animationLibrary->FindDaeId(daeId); }
FindAnimationClip(const fm::string & daeId)206 FCDAnimationClip* FCDocument::FindAnimationClip(const fm::string& daeId) { return animationClipLibrary->FindDaeId(daeId); }
FindCamera(const fm::string & daeId)207 FCDCamera* FCDocument::FindCamera(const fm::string& daeId) { return cameraLibrary->FindDaeId(daeId); }
FindController(const fm::string & daeId)208 FCDController* FCDocument::FindController(const fm::string& daeId) { return controllerLibrary->FindDaeId(daeId); }
FindEffect(const fm::string & daeId)209 FCDEffect* FCDocument::FindEffect(const fm::string& daeId) { return effectLibrary->FindDaeId(daeId); }
FindEmitter(const fm::string & daeId)210 FCDEmitter* FCDocument::FindEmitter(const fm::string& daeId) { return emitterLibrary->FindDaeId(daeId); }
FindForceField(const fm::string & daeId)211 FCDForceField* FCDocument::FindForceField(const fm::string& daeId) { return forceFieldLibrary->FindDaeId(daeId); }
FindGeometry(const fm::string & daeId)212 FCDGeometry* FCDocument::FindGeometry(const fm::string& daeId) { return geometryLibrary->FindDaeId(daeId); }
FindImage(const fm::string & daeId)213 FCDImage* FCDocument::FindImage(const fm::string& daeId) { return imageLibrary->FindDaeId(daeId); }
FindLayer(const fm::string & name)214 FCDLayer* FCDocument::FindLayer(const fm::string& name) { for (FCDLayerList::iterator itL = layers.begin(); itL != layers.end(); ++itL) { if ((*itL)->name == name) return *itL; } return NULL; }
FindLight(const fm::string & daeId)215 FCDLight* FCDocument::FindLight(const fm::string& daeId) { return lightLibrary->FindDaeId(daeId); }
FindMaterial(const fm::string & daeId)216 FCDMaterial* FCDocument::FindMaterial(const fm::string& daeId) { return materialLibrary->FindDaeId(daeId); }
FindVisualScene(const fm::string & daeId)217 FCDSceneNode* FCDocument::FindVisualScene(const fm::string& daeId) { return visualSceneLibrary->FindDaeId(daeId); }
FindPhysicsScene(const fm::string & daeId)218 FCDPhysicsScene* FCDocument::FindPhysicsScene(const fm::string& daeId) { return physicsSceneLibrary->FindDaeId(daeId); }
FindPhysicsMaterial(const fm::string & daeId)219 FCDPhysicsMaterial* FCDocument::FindPhysicsMaterial(const fm::string& daeId) { return physicsMaterialLibrary->FindDaeId(daeId); }
FindPhysicsModel(const fm::string & daeId)220 FCDPhysicsModel* FCDocument::FindPhysicsModel(const fm::string& daeId) { return physicsModelLibrary->FindDaeId(daeId); }
FindSceneNode(const char * daeId) const221 const FCDSceneNode* FCDocument::FindSceneNode(const char* daeId) const { return visualSceneLibrary->FindDaeId(daeId); }
FindEntity(const fm::string & daeId)222 FCDEntity* FCDocument::FindEntity(const fm::string& daeId)
223 {
224 #define CHECK_LIB(libraryName) { \
225 FCDEntity* e = libraryName->FindDaeId(daeId); \
226 if (e != NULL) return e; }
227
228 CHECK_LIB(animationLibrary);
229 CHECK_LIB(animationClipLibrary);
230 CHECK_LIB(cameraLibrary);
231 CHECK_LIB(controllerLibrary);
232 CHECK_LIB(effectLibrary);
233 CHECK_LIB(emitterLibrary);
234 CHECK_LIB(forceFieldLibrary);
235 CHECK_LIB(geometryLibrary);
236 CHECK_LIB(imageLibrary);
237 CHECK_LIB(lightLibrary);
238 CHECK_LIB(materialLibrary);
239 CHECK_LIB(visualSceneLibrary);
240 CHECK_LIB(physicsSceneLibrary);
241 CHECK_LIB(physicsMaterialLibrary);
242 CHECK_LIB(physicsModelLibrary);
243 #undef CHECK_LIB
244
245 return NULL;
246 }
247
248 // Add an animated value to the list
RegisterAnimatedValue(FCDAnimated * animated)249 void FCDocument::RegisterAnimatedValue(FCDAnimated* animated)
250 {
251 // Look for a duplicate in order to avoid memory loss
252 //if (animated->GetValueCount() == 0 || FindAnimatedValue(animated->GetValue(0)) != NULL)
253 if (animated->GetValueCount() == 0)
254 {
255 SAFE_RELEASE(animated);
256 return;
257 }
258
259 // List the new animated value
260 animatedValues.insert(animated, animated);
261
262 //// Also add to the map the individual values for easy retrieval
263 //size_t count = animated->GetValueCount();
264 //for (size_t i = 0; i < count; ++i)
265 //{
266 // const float* value = animated->GetValue(i);
267 // animatedValueMap.insert(value, animated);
268 //}
269 }
270
271 // Unregisters an animated value of the document.
UnregisterAnimatedValue(FCDAnimated * animated)272 void FCDocument::UnregisterAnimatedValue(FCDAnimated* animated)
273 {
274 if (animated != NULL)
275 {
276 // Intentionally search from the end:
277 // - In the destructor of the document, we delete from the end.
278 // - In animation exporters, we add to the end and are likely to delete right away.
279 FCDAnimatedSet::iterator it = animatedValues.find(animated);
280 if (it != animatedValues.end())
281 {
282 animatedValues.erase(it);
283
284 //// Also remove to the map the individual values contained
285 //size_t count = animated->GetValueCount();
286 //for (size_t i = 0; i < count; ++i)
287 //{
288 // const float* value = animated->GetValue(i);
289 // FCDAnimatedValueMap::iterator itV = animatedValueMap.find(value);
290 // if (itV != animatedValueMap.end() && (*itV).second == animated)
291 // {
292 // animatedValueMap.erase(itV);
293 // }
294 //}
295 }
296 }
297 }
298 //
299 //// Retrieve an animated value, given a value pointer
300 //const FCDAnimated* FCDocument::FindAnimatedValue(const float* ptr) const
301 //{
302 // FCDAnimatedValueMap::const_iterator it = animatedValueMap.find(ptr);
303 // return (it != animatedValueMap.end()) ? (*it).second : NULL;
304 //}
305 //
306 //// Retrieve an animated float value for a given fully qualified target
307 //const float* FCDocument::FindAnimatedTarget(const fm::string& fullyQualifiedTarget)
308 //{
309 // if (fullyQualifiedTarget.empty()) return NULL;
310 // fm::string target = (fullyQualifiedTarget[0] == '#') ? fullyQualifiedTarget.substr(1) : fullyQualifiedTarget;
311 // fm::string pointer, qualifier;
312 // FUStringConversion::SplitTarget(target, pointer, qualifier);
313 //
314 // // Find the pointer
315 // FCDAnimated* animatedValue = NULL;
316 // for (FCDAnimatedSet::iterator itA = animatedValues.begin(); itA != animatedValues.end(); ++itA)
317 // {
318 // FCDAnimated* animated = (*itA).first;
319 // if (animated->GetTargetPointer() == pointer) { animatedValue = animated; break; }
320 // }
321 // if (animatedValue == NULL) return NULL;
322 //
323 // // Return the qualified value
324 // size_t index = animatedValue->FindQualifier(qualifier);
325 // if (index == size_t(-1)) return NULL;
326 // return animatedValue->GetValue(index);
327 //}
328 //
329 //// Returns whether a given value pointer is animated
330 //bool FCDocument::IsValueAnimated(const float* ptr) const
331 //{
332 // const FCDAnimated* animated = FindAnimatedValue(ptr);
333 // return (animated != NULL) ? animated->HasCurve() : false;
334 //}
335
336 // Insert new library elements
AddVisualScene()337 FCDSceneNode* FCDocument::AddVisualScene()
338 {
339 FCDSceneNode* visualScene = visualSceneLibrary->AddEntity();
340 if (visualSceneRoot->GetEntity() == NULL) visualSceneRoot->SetEntity(visualScene);
341 return visualScene;
342 }
AddPhysicsScene()343 FCDPhysicsScene* FCDocument::AddPhysicsScene()
344 {
345 FCDPhysicsScene* physicsScene = physicsSceneLibrary->AddEntity();
346 AddPhysicsSceneInstance(physicsScene);
347 return physicsScene;
348 }
349
SetFileUrl(const fstring & filename)350 void FCDocument::SetFileUrl(const fstring& filename)
351 {
352 fileManager->PopRootFile();
353 fileUrl = GetFileManager()->GetCurrentUri().MakeAbsolute(filename);
354 fileManager->PushRootFile(fileUrl);
355 }
356
SetCurrentTime(float time)357 void FCDocument::SetCurrentTime(float time)
358 {
359 for (FCDAnimatedSet::iterator itA = animatedValues.begin(); itA != animatedValues.end(); ++itA)
360 {
361 FCDAnimated* animated = (*itA).first;
362 animated->Evaluate(time);
363 }
364
365 // We must evaluate all our child documents as well!
366 for (size_t i = 0; i < externalReferenceManager->GetPlaceHolderCount(); i++)
367 {
368 FCDPlaceHolder* placeHolder = externalReferenceManager->GetPlaceHolder(i);
369 if (placeHolder->IsTargetLoaded()) placeHolder->GetTarget()->SetCurrentTime(time);
370 }
371 }
372
373 // More linker-tricking for DLL support.
CreateLibraryFunctions(FCDocument * doc)374 extern bool CreateLibraryFunctions(FCDocument* doc)
375 {
376 doc->GetForceFieldLibrary()->GetEntityCount();
377 doc->GetForceFieldLibrary()->GetEntity(0);
378 doc->GetImageLibrary()->GetEntityCount();
379 doc->GetImageLibrary()->GetEntity(0);
380 doc->GetPhysicsMaterialLibrary()->GetEntityCount();
381 doc->GetPhysicsMaterialLibrary()->GetEntity(0);
382 doc->GetPhysicsModelLibrary()->GetEntityCount();
383 doc->GetPhysicsModelLibrary()->GetEntity(0);
384 return true;
385 }
386