integrationExample.cpp
Go to the documentation of this file.
1 
7 /*
8 * Copyright 2006 Sony Computer Entertainment Inc.
9 *
10 * Licensed under the MIT Open Source License, for details please see license.txt or the website
11 * http://www.opensource.org/licenses/mit-license.php
12 *
13 */
14 // The DOM used to provide an "integration library", which was a mechanism for
15 // converting the DOM's representation of a Collada model to the user's representation.
16 // The integration classes were very clumsy and not particularly useful, so they
17 // were removed in December 07. In their place, setUserData and getUserData methods
18 // were added to the daeElement class. This program shows how you might write a Collada
19 // importer using these new methods instead of the integration classes.
20 //
21 // Our model structure consists of nodes, meshes, and materials. We create them by
22 // converting from domNode, domGeometry, and domMaterial, respectively. We'll
23 // demonstrate how you can write an importer to traverse the Collada DOM element
24 // hierarchy and attach our model representation structures to the dom* classes.
25 
26 #include <list>
27 #include <vector>
28 #include <iostream>
29 #include <dae.h>
30 #include <dom/domMaterial.h>
31 #include <dom/domGeometry.h>
32 #include <dom/domNode.h>
33 #include <dom/domCOLLADA.h>
34 #include "domTest.h"
35 
36 using namespace std;
37 
38 #define Check(val) if (!(val)) throw exception();
39 
40 
41 // Our material structure, which we create by converting a domMaterial object
42 class Material {
43 public:
44  vector<float> diffuseColor;
46  // ... and lots of other parameters
47 
48  Material(domMaterial& mtl) {
49  // Grab the <effect> from the <material> and initalize the parameters
50  }
51 };
52 
53 
54 // Our mesh structure, which we create by converting a domGeometry object
55 class Mesh {
56 public:
58  // Vertex info, etc
59 
60  Mesh(domGeometry& geom) {
61  // Parse the <geometry> element, extract vertex data, etc
62  }
63 };
64 
65 
66 // Our node structure, which we create by converting a domNode object
67 class Node {
68 public:
69  list<Mesh*> meshes;
70  list<Node*> childNodes;
71 
72  // This is defined later to work around a circular dependency on the lookup function
73  Node(domNode& node);
74 };
75 
76 
77 // This function checks to see if a user data object has already been attached to
78 // the DOM object. If so, that object is casted from void* to the appropriate type
79 // and returned, otherwise the object is created and attached to the DOM object
80 // via the setUserData method.
81 template<typename MyType, typename DomType>
82 MyType& lookup(DomType& domObject) {
83  if (!domObject.getUserData())
84  domObject.setUserData(new MyType(domObject));
85  return *(MyType*)(domObject.getUserData());
86 }
87 
88 // This function traverses all the DOM objects of a particular type and frees
89 // destroys the associated user data object.
90 template<typename MyType, typename DomType>
91 void freeConversionObjects(DAE& dae) {
92  vector<daeElement*> elts = dae.getDatabase()->typeLookup(DomType::ID());
93  for (size_t i = 0; i < elts.size(); i++)
94  delete (MyType*)elts[i]->getUserData();
95 }
96 
97 
98 Node::Node(domNode& node) {
99  // Recursively convert all child nodes. First iterate over the <node> elements.
100  for (size_t i = 0; i < node.getNode_array().getCount(); i++)
101  childNodes.push_back(&lookup<Node, domNode>(*node.getNode_array()[i]));
102 
103  // Then iterate over the <instance_node> elements.
104  for (size_t i = 0; i < node.getInstance_node_array().getCount(); i++) {
105  domNode* child = daeSafeCast<domNode>(
106  node.getInstance_node_array()[i]->getUrl().getElement());
107  Check(child);
108  childNodes.push_back(&lookup<Node, domNode>(*child));
109  }
110 
111  // Iterate over all the <instance_geometry> elements
112  for (size_t i = 0; i < node.getInstance_geometry_array().getCount(); i++) {
113  domInstance_geometry* instanceGeom = node.getInstance_geometry_array()[i];
114  domGeometry* geom = daeSafeCast<domGeometry>(instanceGeom->getUrl().getElement());
115  Check(geom);
116 
117  // Lookup the material that we should apply to the <geometry>. In a real app
118  // we'd need to worry about having multiple <instance_material>s, but in this
119  // test let's just convert the first <instance_material> we find.
120  domInstance_material* instanceMtl = daeSafeCast<domInstance_material>(
121  instanceGeom->getDescendant("instance_material"));
122  Check(instanceMtl);
123  domMaterial* mtl = daeSafeCast<domMaterial>(instanceMtl->getTarget().getElement());
124  Check(mtl);
125  Material& convertedMtl = lookup<Material, domMaterial>(*mtl);
126 
127  // Now convert the geometry, add the result to our list of meshes, and assign
128  // the mesh a material.
129  meshes.push_back(&lookup<Mesh, domGeometry>(*geom));
130  meshes.back()->mtl = &convertedMtl;
131  }
132 }
133 
134 
135 void convertModel(domCOLLADA& root) {
136  // We need to convert the model from the DOM's representation to our internal representation.
137  // First find a <visual_scene> to load. In a real app we would look for and load all
138  // the <visual_scene>s in a document, but for this app we just convert the first
139  // <visual_scene> we find.
140  domVisual_scene* visualScene = daeSafeCast<domVisual_scene>(root.getDescendant("visual_scene"));
141  Check(visualScene);
142 
143  // Now covert all the <node>s in the <visual_scene>. This is a recursive process,
144  // so any child nodes will also be converted.
145  domNode_Array& nodes = visualScene->getNode_array();
146  for (size_t i = 0; i < nodes.getCount(); i++)
147  lookup<Node, domNode>(*nodes[i]);
148 }
149 
150 
151 DefineTest(integration) {
152  // Load a document from disk
153  string file = lookupTestFile("cube.dae");
154  DAE dae;
155  domCOLLADA* root = dae.open(file);
156  CheckResult(root);
157 
158  // Do the conversion. The conversion process throws an exception on error, so
159  // we'll include a try/catch handler.
160  try {
161  convertModel(*root);
162  }
163  catch (const exception&) {
164  return testResult(false);
165  }
166 
167  // Don't forget to destroy the objects we created during the conversion process
168  freeConversionObjects<Node, domNode>(dae);
169  freeConversionObjects<Mesh, domGeometry>(dae);
170  freeConversionObjects<Material, domMaterial>(dae);
171 
172  return testResult(true);
173 }
vector< float > diffuseColor
list< Mesh * > meshes
list< Node * > childNodes
void convertModel(domCOLLADA &root)
Mesh(domGeometry &geom)
Material(domMaterial &mtl)
This is a blank file. has nothing in it. I may have migrated it to the cpp.
Node(domNode &node)
MyType & lookup(DomType &domObject)
string diffuseTexture
void freeConversionObjects(DAE &dae)
DefineTest(integration)
#define Check(val)
Material * mtl
string lookupTestFile(const string &fileName)
Definition: domTest.cpp:95


wrapper_collada
Author(s): Miguel Oliveira
autogenerated on Mon Mar 2 2015 01:33:01