This makes ColladaConv work together with Autodesk FBX converter which makes Blender->.fbx->FBX converter->.dae possible to be used (the advantage with this is that animations are supported. They cannot be loaded yet though, I'll work on this).
Code:
diff --git a/Horde3D/Source/ColladaConverter/converter.cpp b/Horde3D/Source/ColladaConverter/converter.cpp
index f3c8163..bea761a 100644
--- a/Horde3D/Source/ColladaConverter/converter.cpp
+++ b/Horde3D/Source/ColladaConverter/converter.cpp
@@ -505,8 +505,8 @@ void Converter::processMeshes( ColladaDocument &doc, bool optimize )
v.storedNormal = iTriGroup.getNormal( normIndex );
// Skinning
- if( skin != 0x0 )
- {
+ if( skin != 0x0 && v.daePosIndex < skin->vertWeights.size() )
+ {
DaeVertWeights vertWeights = skin->vertWeights[v.daePosIndex];
// Sort weights if necessary
diff --git a/Horde3D/Source/ColladaConverter/daeLibGeometries.h b/Horde3D/Source/ColladaConverter/daeLibGeometries.h
index 2724b80..958afe6 100644
--- a/Horde3D/Source/ColladaConverter/daeLibGeometries.h
+++ b/Horde3D/Source/ColladaConverter/daeLibGeometries.h
@@ -98,17 +98,13 @@ struct DaeTriGroup
normSource = 0x0;
texSource[0] = 0x0; texSource[1] = 0x0; texSource[2] = 0x0; texSource[3] = 0x0;
}
-
-
- bool parse( const XMLNode &trianglesNode )
- {
- int vertexOffset = 0, normOffset = -1, texCoordOffset[4] = { -1, -1, -1, -1 };
- unsigned int numInputs = 0;
-
+
+ int getBaseChannel( const XMLNode &node )
+ {
// Find the base mapping channel with the lowest set-id
int baseChannel = 999999;
int nodeItr1 = 0;
- XMLNode node1 = trianglesNode.getChildNode( "input", nodeItr1 );
+ XMLNode node1 = node.getChildNode( "input", nodeItr1 );
while( !node1.isEmpty() )
{
if( strcmp( node1.getAttribute( "semantic", "" ), "TEXCOORD" ) == 0 )
@@ -124,12 +120,15 @@ struct DaeTriGroup
break;
}
}
- node1 = trianglesNode.getChildNode( "input", ++nodeItr1 );
- }
-
- // Parse data
- nodeItr1 = 0;
- node1 = trianglesNode.getChildNode( "input", nodeItr1 );
+ node1 = node.getChildNode( "input", ++nodeItr1 );
+ }
+ return baseChannel;
+ }
+
+ void readOffsets( const XMLNode &node, int baseChannel, unsigned int &numInputs, int &vertexOffset, int &normOffset, int texCoordOffset[4] )
+ {
+ int nodeItr1 = 0;
+ XMLNode node1 = node.getChildNode( "input", nodeItr1 );
while( !node1.isEmpty() )
{
++numInputs;
@@ -163,15 +162,26 @@ struct DaeTriGroup
removeGate( normSourceId );
}
- node1 = trianglesNode.getChildNode( "input", ++nodeItr1 );
+ node1 = node.getChildNode( "input", ++nodeItr1 );
}
+ }
+
+ bool parse( const XMLNode &trianglesNode )
+ {
+ int vertexOffset = 0, normOffset = -1, texCoordOffset[4] = { -1, -1, -1, -1 };
+ unsigned int numInputs = 0;
+
+ int baseChannel = getBaseChannel( trianglesNode );
+
+ // Parse data
+ readOffsets( trianglesNode, baseChannel, numInputs, vertexOffset, normOffset, texCoordOffset );
if( vSourceId == "" ) return false;
matId = trianglesNode.getAttribute( "material", "" );
int count = atoi( trianglesNode.getAttribute( "count", "0" ) ) * 3;
- node1 = trianglesNode.getChildNode( "p" );
+ XMLNode node1 = trianglesNode.getChildNode( "p" );
unsigned int pos = 0;
char *s = (char *)node1.getText();
@@ -205,7 +215,88 @@ struct DaeTriGroup
return true;
}
+
+ // Parses a polygon section and converts it to triangles
+ bool parsePolygons( const XMLNode &trianglesNode )
+ {
+ int vertexOffset = 0, normOffset = -1, texCoordOffset[4] = { -1, -1, -1, -1 };
+ unsigned int numInputs = 0;
+
+ int baseChannel = getBaseChannel( trianglesNode );
+
+ // Parse data
+ readOffsets( trianglesNode, baseChannel, numInputs, vertexOffset, normOffset, texCoordOffset );
+
+ if( vSourceId == "" ) return false;
+ matId = trianglesNode.getAttribute( "material", "" );
+
+ int count = atoi( trianglesNode.getAttribute( "count", "0" ) ) * 3;
+
+ int nodeItr1 = 0;
+ XMLNode node1 = trianglesNode.getChildNode( "p", nodeItr1 );
+ while( !node1.isEmpty() )
+ {
+ char *s = (char *)node1.getText();
+ if( s == 0x0 ) return false;
+
+ unsigned int pos = 0;
+ unsigned int ui;
+
+ IndexEntry indexEntry;
+
+ int j = 0;
+
+ // Store first and last index to add more than one triangle using them
+ int i = 0;
+ IndexEntry firstindex;
+ IndexEntry lastindex;
+
+
+ while (parseUInt(s, pos, ui))
+ {
+ // No else-if since offset sharing is possible
+ if( j == vertexOffset )
+ indexEntry.posIndex = ui;
+ if( j == normOffset )
+ indexEntry.normIndex = (int)ui;
+ if( j == texCoordOffset[0] )
+ indexEntry.texIndex[0] = (int)ui;
+ if( j == texCoordOffset[1] )
+ indexEntry.texIndex[1] = (int)ui;
+ if( j == texCoordOffset[2] )
+ indexEntry.texIndex[2] = (int)ui;
+ if( j == texCoordOffset[3] )
+ indexEntry.texIndex[3] = (int)ui;
+
+ j++;
+ if (j == numInputs)
+ {
+ if( i == 0 )
+ {
+ firstindex = indexEntry;
+ }
+ else
+ {
+ if( i > 2 )
+ {
+ // Begin new triangle
+ indices.push_back( firstindex );
+ indices.push_back( lastindex );
+ }
+ lastindex = indexEntry;
+ }
+ indices.push_back( indexEntry );
+ i++;
+ j = 0;
+ }
+ }
+
+ node1 = trianglesNode.getChildNode( "p", ++nodeItr1 );
+ }
+
+ return true;
+ }
Vec3f getPos( int posIndex )
{
@@ -328,7 +419,8 @@ struct DaeGeometry
node2 = node1.getChildNode( "vertices", ++nodeItr2 );
}
-
+
+ // Parse triangles
nodeItr2 = 0;
node2 = node1.getChildNode( "triangles", nodeItr2 );
while( !node2.isEmpty() )
@@ -355,9 +447,36 @@ struct DaeGeometry
node2 = node1.getChildNode( "triangles", ++nodeItr2 );
}
+
+ // Parse polygons
+ nodeItr2 = 0;
+ node2 = node1.getChildNode( "polygons", nodeItr2 );
+ while( !node2.isEmpty() )
+ {
+ triGroups.push_back( DaeTriGroup() );
+ if( triGroups[triGroups.size() - 1].parsePolygons( node2 ) )
+ {
+ DaeTriGroup &triGroup = triGroups[triGroups.size() - 1];
+
+ triGroup.vSource = findVSource( triGroup.vSourceId );
+ triGroup.normSource = findSource( triGroup.normSourceId );
+ triGroup.texSource[0] = findSource( triGroup.texSourceId[0] );
+ triGroup.texSource[1] = findSource( triGroup.texSourceId[1] );
+ triGroup.texSource[2] = findSource( triGroup.texSourceId[2] );
+ triGroup.texSource[3] = findSource( triGroup.texSourceId[3] );
- if( !node1.getChildNode( "polygons" ).isEmpty() )
- log( "Warning: Ingnoring non-triangle data in mesh '" + id + "'" );
+ if( triGroup.vSource == 0x0 )
+ {
+ log( "Warning: Mesh '" + id + "' has no vertex coordinates and is ignored" );
+ triGroups.pop_back();
+ }
+ }
+ else triGroups.pop_back();
+
+ node2 = node1.getChildNode( "polygons", ++nodeItr2 );
+ }
+
+ // Unsupported geometry types
if( !node1.getChildNode( "polylist" ).isEmpty() )
log( "Warning: Ingnoring non-triangle data in mesh '" + id + "'" );
if( !node1.getChildNode( "trifans" ).isEmpty() )
diff --git a/Horde3D/Source/ColladaConverter/daeLibVisualScenes.h b/Horde3D/Source/ColladaConverter/daeLibVisualScenes.h
index 5723fc8..f9e12ad 100644
--- a/Horde3D/Source/ColladaConverter/daeLibVisualScenes.h
+++ b/Horde3D/Source/ColladaConverter/daeLibVisualScenes.h
@@ -66,9 +66,18 @@ struct DaeNode
id = nodeNode.getAttribute( "id", "" );
if( id == "" ) return false;
name = nodeNode.getAttribute( "name", "" );
- sid = nodeNode.getAttribute( "sid", "" );
+ sid = nodeNode.getAttribute( "sid", "" );
- if( strcmp( nodeNode.getAttribute( "type", "" ), "JOINT" ) == 0 ) joint = true;
+ if( strcmp( nodeNode.getAttribute( "type", "" ), "JOINT" ) == 0 )
+ {
+ if( sid == "" )
+ {
+ // At least the Autodesk FBX converter does not fill this attribute, still we depend on it
+ // (The specs say it's optional after all)
+ sid = id;
+ }
+ joint = true;
+ }
else joint = false;
// Parse transformations
As always, some EOL-changes in there. Can anybody set the SVN to eol-style=native plz? -.-
And any chance to get this into SVN? Anything that should be changed before?