Initial implementation of the converted from .obj and .dae file to the renderscript file format. Change-Id: I47f4ecf0fb68515914b660dd3d548afa1920d79c
203 lines
7.9 KiB
C++
203 lines
7.9 KiB
C++
/*
|
|
* Copyright 2006 Sony Computer Entertainment Inc.
|
|
*
|
|
* Licensed under the MIT Open Source License, for details please see license.txt or the website
|
|
* http://www.opensource.org/licenses/mit-license.php
|
|
*
|
|
*/
|
|
|
|
#include "ColladaConditioner.h"
|
|
unsigned int ColladaConditioner::getMaxOffset( domInputLocalOffset_Array &input_array ) {
|
|
|
|
unsigned int maxOffset = 0;
|
|
for ( unsigned int i = 0; i < input_array.getCount(); i++ ) {
|
|
if ( input_array[i]->getOffset() > maxOffset ) {
|
|
maxOffset = (unsigned int)input_array[i]->getOffset();
|
|
}
|
|
}
|
|
return maxOffset;
|
|
}
|
|
|
|
void ColladaConditioner::createTrianglesFromPolylist( domMesh *thisMesh, domPolylist *thisPolylist ) {
|
|
|
|
// Create a new <triangles> inside the mesh that has the same material as the <polylist>
|
|
domTriangles *thisTriangles = (domTriangles *)thisMesh->createAndPlace("triangles");
|
|
//thisTriangles->setCount( 0 );
|
|
unsigned int triangles = 0;
|
|
thisTriangles->setMaterial(thisPolylist->getMaterial());
|
|
domP* p_triangles = (domP*)thisTriangles->createAndPlace("p");
|
|
|
|
// Give the new <triangles> the same <_dae> and <parameters> as the old <polylist>
|
|
for(int i=0; i<(int)(thisPolylist->getInput_array().getCount()); i++) {
|
|
|
|
thisTriangles->placeElement( thisPolylist->getInput_array()[i]->clone() );
|
|
}
|
|
|
|
// Get the number of inputs and primitives for the polygons array
|
|
int numberOfInputs = (int)getMaxOffset(thisPolylist->getInput_array()) + 1;
|
|
int numberOfPrimitives = (int)(thisPolylist->getVcount()->getValue().getCount());
|
|
|
|
unsigned int offset = 0;
|
|
|
|
// Triangulate all the primitives, this generates all the triangles in a single <p> element
|
|
for(int j = 0; j < numberOfPrimitives; j++) {
|
|
|
|
int triangleCount = (int)thisPolylist->getVcount()->getValue()[j] -2;
|
|
// Write out the primitives as triangles, just fan using the first element as the base
|
|
int idx = numberOfInputs;
|
|
for(int k = 0; k < triangleCount; k++) {
|
|
// First vertex
|
|
for(int l = 0; l < numberOfInputs; l++) {
|
|
|
|
p_triangles->getValue().append(thisPolylist->getP()->getValue()[offset + l]);
|
|
}
|
|
// Second vertex
|
|
for(int l = 0; l < numberOfInputs; l++) {
|
|
|
|
p_triangles->getValue().append(thisPolylist->getP()->getValue()[offset + idx + l]);
|
|
}
|
|
// Third vertex
|
|
idx += numberOfInputs;
|
|
for(int l = 0; l < numberOfInputs; l++) {
|
|
|
|
p_triangles->getValue().append(thisPolylist->getP()->getValue()[offset + idx + l]);
|
|
}
|
|
triangles++;
|
|
}
|
|
offset += (unsigned int)thisPolylist->getVcount()->getValue()[j] * numberOfInputs;
|
|
}
|
|
thisTriangles->setCount( triangles );
|
|
|
|
}
|
|
|
|
void ColladaConditioner::createTrianglesFromPolygons( domMesh *thisMesh, domPolygons *thisPolygons ) {
|
|
|
|
// Create a new <triangles> inside the mesh that has the same material as the <polygons>
|
|
domTriangles *thisTriangles = (domTriangles *)thisMesh->createAndPlace("triangles");
|
|
thisTriangles->setCount( 0 );
|
|
thisTriangles->setMaterial(thisPolygons->getMaterial());
|
|
domP* p_triangles = (domP*)thisTriangles->createAndPlace("p");
|
|
|
|
// Give the new <triangles> the same <_dae> and <parameters> as the old <polygons>
|
|
for(int i=0; i<(int)(thisPolygons->getInput_array().getCount()); i++) {
|
|
|
|
thisTriangles->placeElement( thisPolygons->getInput_array()[i]->clone() );
|
|
}
|
|
|
|
// Get the number of inputs and primitives for the polygons array
|
|
int numberOfInputs = (int)getMaxOffset(thisPolygons->getInput_array()) +1;
|
|
int numberOfPrimitives = (int)(thisPolygons->getP_array().getCount());
|
|
|
|
// Triangulate all the primitives, this generates all the triangles in a single <p> element
|
|
for(int j = 0; j < numberOfPrimitives; j++) {
|
|
|
|
// Check the polygons for consistancy (some exported files have had the wrong number of indices)
|
|
domP * thisPrimitive = thisPolygons->getP_array()[j];
|
|
int elementCount = (int)(thisPrimitive->getValue().getCount());
|
|
// Skip the invalid primitive
|
|
if((elementCount % numberOfInputs) != 0) {
|
|
continue;
|
|
} else {
|
|
int triangleCount = (elementCount/numberOfInputs)-2;
|
|
// Write out the primitives as triangles, just fan using the first element as the base
|
|
int idx = numberOfInputs;
|
|
for(int k = 0; k < triangleCount; k++) {
|
|
// First vertex
|
|
for(int l = 0; l < numberOfInputs; l++) {
|
|
|
|
p_triangles->getValue().append(thisPrimitive->getValue()[l]);
|
|
}
|
|
// Second vertex
|
|
for(int l = 0; l < numberOfInputs; l++) {
|
|
|
|
p_triangles->getValue().append(thisPrimitive->getValue()[idx + l]);
|
|
}
|
|
// Third vertex
|
|
idx += numberOfInputs;
|
|
for(int l = 0; l < numberOfInputs; l++) {
|
|
|
|
p_triangles->getValue().append(thisPrimitive->getValue()[idx + l]);
|
|
}
|
|
thisTriangles->setCount(thisTriangles->getCount()+1);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
bool ColladaConditioner::triangulate(DAE *dae) {
|
|
|
|
int error = 0;
|
|
|
|
// How many geometry elements are there?
|
|
int geometryElementCount = (int)(dae->getDatabase()->getElementCount(NULL, "geometry" ));
|
|
|
|
for(int currentGeometry = 0; currentGeometry < geometryElementCount; currentGeometry++) {
|
|
|
|
// Find the next geometry element
|
|
domGeometry *thisGeometry;
|
|
// error = _dae->getDatabase()->getElement((daeElement**)&thisGeometry,currentGeometry, NULL, "geometry");
|
|
daeElement * element = 0;
|
|
error = dae->getDatabase()->getElement(&element,currentGeometry, NULL, "geometry");
|
|
thisGeometry = (domGeometry *) element;
|
|
|
|
// Get the mesh out of the geometry
|
|
domMesh *thisMesh = thisGeometry->getMesh();
|
|
|
|
if (thisMesh == NULL){
|
|
continue;
|
|
}
|
|
|
|
// Loop over all the polygon elements
|
|
for(int currentPolygons = 0; currentPolygons < (int)(thisMesh->getPolygons_array().getCount()); currentPolygons++) {
|
|
|
|
// Get the polygons out of the mesh
|
|
// Always get index 0 because every pass through this loop deletes the <polygons> element as it finishes with it
|
|
domPolygons *thisPolygons = thisMesh->getPolygons_array()[currentPolygons];
|
|
createTrianglesFromPolygons( thisMesh, thisPolygons );
|
|
}
|
|
while (thisMesh->getPolygons_array().getCount() > 0) {
|
|
|
|
domPolygons *thisPolygons = thisMesh->getPolygons_array().get(0);
|
|
// Remove the polygons from the mesh
|
|
thisMesh->removeChildElement(thisPolygons);
|
|
}
|
|
int polylistElementCount = (int)(thisMesh->getPolylist_array().getCount());
|
|
for(int currentPolylist = 0; currentPolylist < polylistElementCount; currentPolylist++) {
|
|
|
|
// Get the polylist out of the mesh
|
|
// Always get index 0 because every pass through this loop deletes the <polygons> element as it finishes with it
|
|
domPolylist *thisPolylist = thisMesh->getPolylist_array()[currentPolylist];
|
|
createTrianglesFromPolylist( thisMesh, thisPolylist );
|
|
}
|
|
while (thisMesh->getPolylist_array().getCount() > 0) {
|
|
|
|
domPolylist *thisPolylist = thisMesh->getPolylist_array().get(0);
|
|
// Remove the polylist from the mesh
|
|
thisMesh->removeChildElement(thisPolylist);
|
|
}
|
|
}
|
|
return (error == 0);
|
|
}
|
|
|
|
bool ColladaConditioner::triangulate(const char *inputFile) {
|
|
|
|
DAE dae;
|
|
bool convertSuceeded = true;
|
|
domCOLLADA* root = dae.open(inputFile);
|
|
|
|
if (!root) {
|
|
printf("Failed to read file %s.\n", inputFile);
|
|
return false;
|
|
}
|
|
|
|
convertSuceeded = triangulate(&dae);
|
|
|
|
dae.writeAll();
|
|
if(!convertSuceeded) {
|
|
printf("Encountered errors\n");
|
|
}
|
|
|
|
return convertSuceeded;
|
|
} |