• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright 2006 Sony Computer Entertainment Inc.
3 *
4 * Licensed under the MIT Open Source License, for details please see license.txt or the website
5 * http://www.opensource.org/licenses/mit-license.php
6 *
7 */
8 
9 #include "ColladaConditioner.h"
getMaxOffset(domInputLocalOffset_Array & input_array)10 unsigned int ColladaConditioner::getMaxOffset( domInputLocalOffset_Array &input_array ) {
11 
12     unsigned int maxOffset = 0;
13     for ( unsigned int i = 0; i < input_array.getCount(); i++ ) {
14         if ( input_array[i]->getOffset() > maxOffset ) {
15             maxOffset = (unsigned int)input_array[i]->getOffset();
16         }
17     }
18     return maxOffset;
19 }
20 
createTrianglesFromPolylist(domMesh * thisMesh,domPolylist * thisPolylist)21 void ColladaConditioner::createTrianglesFromPolylist( domMesh *thisMesh, domPolylist *thisPolylist ) {
22 
23     // Create a new <triangles> inside the mesh that has the same material as the <polylist>
24     domTriangles *thisTriangles = (domTriangles *)thisMesh->createAndPlace("triangles");
25     //thisTriangles->setCount( 0 );
26     unsigned int triangles = 0;
27     thisTriangles->setMaterial(thisPolylist->getMaterial());
28     domP* p_triangles = (domP*)thisTriangles->createAndPlace("p");
29 
30     // Give the new <triangles> the same <_dae> and <parameters> as the old <polylist>
31     for(int i=0; i<(int)(thisPolylist->getInput_array().getCount()); i++) {
32 
33         thisTriangles->placeElement( thisPolylist->getInput_array()[i]->clone() );
34     }
35 
36     // Get the number of inputs and primitives for the polygons array
37     int numberOfInputs = (int)getMaxOffset(thisPolylist->getInput_array()) + 1;
38     int numberOfPrimitives = (int)(thisPolylist->getVcount()->getValue().getCount());
39 
40     unsigned int offset = 0;
41 
42     // Triangulate all the primitives, this generates all the triangles in a single <p> element
43     for(int j = 0; j < numberOfPrimitives; j++) {
44 
45         int triangleCount = (int)thisPolylist->getVcount()->getValue()[j] -2;
46         // Write out the primitives as triangles, just fan using the first element as the base
47         int idx = numberOfInputs;
48         for(int k = 0; k < triangleCount; k++) {
49             // First vertex
50             for(int l = 0; l < numberOfInputs; l++) {
51 
52                 p_triangles->getValue().append(thisPolylist->getP()->getValue()[offset + l]);
53             }
54             // Second vertex
55             for(int l = 0; l < numberOfInputs; l++) {
56 
57                 p_triangles->getValue().append(thisPolylist->getP()->getValue()[offset + idx + l]);
58             }
59             // Third vertex
60             idx += numberOfInputs;
61             for(int l = 0; l < numberOfInputs; l++) {
62 
63                 p_triangles->getValue().append(thisPolylist->getP()->getValue()[offset + idx + l]);
64             }
65             triangles++;
66         }
67         offset += (unsigned int)thisPolylist->getVcount()->getValue()[j] * numberOfInputs;
68     }
69     thisTriangles->setCount( triangles );
70 
71 }
72 
createTrianglesFromPolygons(domMesh * thisMesh,domPolygons * thisPolygons)73 void ColladaConditioner::createTrianglesFromPolygons( domMesh *thisMesh, domPolygons *thisPolygons ) {
74 
75     // Create a new <triangles> inside the mesh that has the same material as the <polygons>
76     domTriangles *thisTriangles = (domTriangles *)thisMesh->createAndPlace("triangles");
77     thisTriangles->setCount( 0 );
78     thisTriangles->setMaterial(thisPolygons->getMaterial());
79     domP* p_triangles = (domP*)thisTriangles->createAndPlace("p");
80 
81     // Give the new <triangles> the same <_dae> and <parameters> as the old <polygons>
82     for(int i=0; i<(int)(thisPolygons->getInput_array().getCount()); i++) {
83 
84         thisTriangles->placeElement( thisPolygons->getInput_array()[i]->clone() );
85     }
86 
87     // Get the number of inputs and primitives for the polygons array
88     int numberOfInputs = (int)getMaxOffset(thisPolygons->getInput_array()) +1;
89     int numberOfPrimitives = (int)(thisPolygons->getP_array().getCount());
90 
91     // Triangulate all the primitives, this generates all the triangles in a single <p> element
92     for(int j = 0; j < numberOfPrimitives; j++) {
93 
94         // Check the polygons for consistancy (some exported files have had the wrong number of indices)
95         domP * thisPrimitive = thisPolygons->getP_array()[j];
96         int elementCount = (int)(thisPrimitive->getValue().getCount());
97         // Skip the invalid primitive
98         if((elementCount % numberOfInputs) != 0) {
99             continue;
100         } else {
101             int triangleCount = (elementCount/numberOfInputs)-2;
102             // Write out the primitives as triangles, just fan using the first element as the base
103             int idx = numberOfInputs;
104             for(int k = 0; k < triangleCount; k++) {
105                 // First vertex
106                 for(int l = 0; l < numberOfInputs; l++) {
107 
108                     p_triangles->getValue().append(thisPrimitive->getValue()[l]);
109                 }
110                 // Second vertex
111                 for(int l = 0; l < numberOfInputs; l++) {
112 
113                     p_triangles->getValue().append(thisPrimitive->getValue()[idx + l]);
114                 }
115                 // Third vertex
116                 idx += numberOfInputs;
117                 for(int l = 0; l < numberOfInputs; l++) {
118 
119                     p_triangles->getValue().append(thisPrimitive->getValue()[idx + l]);
120                 }
121                 thisTriangles->setCount(thisTriangles->getCount()+1);
122             }
123         }
124     }
125 
126 }
127 
128 
triangulate(DAE * dae)129 bool ColladaConditioner::triangulate(DAE *dae) {
130 
131     int error = 0;
132 
133     // How many geometry elements are there?
134     int geometryElementCount = (int)(dae->getDatabase()->getElementCount(NULL, "geometry" ));
135 
136     for(int currentGeometry = 0; currentGeometry < geometryElementCount; currentGeometry++) {
137 
138         // Find the next geometry element
139         domGeometry *thisGeometry;
140         //      error = _dae->getDatabase()->getElement((daeElement**)&thisGeometry,currentGeometry, NULL, "geometry");
141         daeElement * element = 0;
142         error = dae->getDatabase()->getElement(&element,currentGeometry, NULL, "geometry");
143         thisGeometry = (domGeometry *) element;
144 
145         // Get the mesh out of the geometry
146         domMesh *thisMesh = thisGeometry->getMesh();
147 
148         if (thisMesh == NULL){
149             continue;
150         }
151 
152         // Loop over all the polygon elements
153         for(int currentPolygons = 0; currentPolygons < (int)(thisMesh->getPolygons_array().getCount()); currentPolygons++) {
154 
155             // Get the polygons out of the mesh
156             // Always get index 0 because every pass through this loop deletes the <polygons> element as it finishes with it
157             domPolygons *thisPolygons = thisMesh->getPolygons_array()[currentPolygons];
158             createTrianglesFromPolygons( thisMesh, thisPolygons );
159         }
160         while (thisMesh->getPolygons_array().getCount() > 0) {
161 
162             domPolygons *thisPolygons = thisMesh->getPolygons_array().get(0);
163             // Remove the polygons from the mesh
164             thisMesh->removeChildElement(thisPolygons);
165         }
166         int polylistElementCount = (int)(thisMesh->getPolylist_array().getCount());
167         for(int currentPolylist = 0; currentPolylist < polylistElementCount; currentPolylist++) {
168 
169             // Get the polylist out of the mesh
170             // Always get index 0 because every pass through this loop deletes the <polygons> element as it finishes with it
171             domPolylist *thisPolylist = thisMesh->getPolylist_array()[currentPolylist];
172             createTrianglesFromPolylist( thisMesh, thisPolylist );
173         }
174         while (thisMesh->getPolylist_array().getCount() > 0) {
175 
176             domPolylist *thisPolylist = thisMesh->getPolylist_array().get(0);
177             // Remove the polylist from the mesh
178             thisMesh->removeChildElement(thisPolylist);
179         }
180     }
181     return (error == 0);
182 }
183 
triangulate(const char * inputFile)184 bool ColladaConditioner::triangulate(const char *inputFile) {
185 
186     DAE dae;
187     bool convertSuceeded = true;
188     domCOLLADA* root = dae.open(inputFile);
189 
190     if (!root) {
191         printf("Failed to read file %s.\n", inputFile);
192         return false;
193     }
194 
195     convertSuceeded = triangulate(&dae);
196 
197     dae.writeAll();
198     if(!convertSuceeded) {
199         printf("Encountered errors\n");
200     }
201 
202     return convertSuceeded;
203 }
204 
stripGeometry(DAE * dae)205 bool ColladaConditioner::stripGeometry(DAE *dae) {
206     bool convertSuceeded = true;
207     int geometryElementCount = (int)(dae->getDatabase()->getElementCount(NULL,
208                                                                          "library_geometries" ));
209 
210     for(int currentGeometry = 0; currentGeometry < geometryElementCount; currentGeometry++) {
211 
212         daeElement * element = 0;
213         int error = dae->getDatabase()->getElement(&element, currentGeometry,
214                                                    NULL, "library_geometries");
215         daeBool removed = daeElement::removeFromParent(element);
216         convertSuceeded = convertSuceeded && removed;
217     }
218     return convertSuceeded;
219 }
220 
stripGeometry(const char * inputFile)221 bool ColladaConditioner::stripGeometry(const char *inputFile) {
222     DAE dae;
223     bool convertSuceeded = true;
224     domCOLLADA* root = dae.open(inputFile);
225 
226     if (!root) {
227         printf("Failed to read file %s.\n", inputFile);
228         return false;
229     }
230 
231     stripGeometry(&dae);
232 
233     dae.writeAll();
234     if(!convertSuceeded) {
235         printf("Encountered errors\n");
236     }
237 
238     return convertSuceeded;
239 }
240