Horde3D

Next-Generation Graphics Engine
It is currently 25.11.2024, 17:54

All times are UTC + 1 hour




Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: 02.09.2008, 16:48 
Offline

Joined: 15.06.2008, 11:21
Posts: 166
Location: Germany
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?


Top
 Profile  
Reply with quote  
PostPosted: 02.09.2008, 18:31 
Offline

Joined: 21.08.2008, 11:44
Posts: 354
Good idea :idea:
Is it possible to deliver physic attributes (friction, mass, ...) during this process too :?: [Blender->.fbx->FBX converter->.dae]


Top
 Profile  
Reply with quote  
PostPosted: 02.09.2008, 19:30 
Offline

Joined: 15.06.2008, 11:21
Posts: 166
Location: Germany
Small addition to solve some problems with unnamed animation nodes in the XML (the FBX converter creates those, and the spec says it's optional):
Code:
diff --git a/Horde3D/Source/ColladaConverter/daeLibAnimations.h b/Horde3D/Source/ColladaConverter/daeLibAnimations.h
index 5322f6f..6342e9d 100644
--- a/Horde3D/Source/ColladaConverter/daeLibAnimations.h
+++ b/Horde3D/Source/ColladaConverter/daeLibAnimations.h
@@ -100,10 +100,21 @@ struct DaeAnimation
    }

 

 

-   bool parse( const XMLNode &animNode, unsigned int &maxFrameCount, float &maxAnimTime )

+   bool parse( const XMLNode &animNode, unsigned int &maxFrameCount, float &maxAnimTime, std::string parentid = "" )

    {

       id = animNode.getAttribute( "id", "" );

-      if( id == "" ) return false;

+      if( id == "" )
+      {
+         if( parentid != "" )
+         {
+            id = parentid;
+         }
+         else
+         {
+            log( "Warning: Animation without id!\n" );
+            return false;
+         }
+      }

       

       // Sources

       int nodeItr1 = 0;

@@ -248,7 +259,7 @@ struct DaeAnimation
       while( !node1.isEmpty() )

       {

          DaeAnimation *anim = new DaeAnimation();

-         if( anim->parse( node1, maxFrameCount, maxAnimTime ) ) children.push_back( anim );

+         if( anim->parse( node1, maxFrameCount, maxAnimTime, id ) ) children.push_back( anim );

          else delete anim;

 

          node1 = animNode.getChildNode( "animation", ++nodeItr1 );



EDIT: Argh. phpBB somehow adds empty lines in there, no idea where they came from -.-


Top
 Profile  
Reply with quote  
PostPosted: 02.09.2008, 21:18 
Offline
Tool Developer

Joined: 13.11.2007, 11:07
Posts: 1150
Location: Germany
First, big thanks that you're working on that,... it is something very important to increase better compatibility with different exporters.

Quote:
the advantage with this is that animations are supported. They cannot be loaded yet though, I'll work on this

If I understand it right, the second patch does not solve this problem already, does it? If you find a fully working solution that does not have any big bugs left, we definitely will add it to the official SVN (and of course would be very thankfull :-) ).

Setting the eof property on the SVN would be something very usefull, but I can't find any possibility to change this on the SourceForge SVN.
Does anyone know if it is possible to configure this on the SourceForge project admin pages? Since I normally only work under windows I hadn't these problems before.


Top
 Profile  
Reply with quote  
PostPosted: 02.09.2008, 21:42 
Offline

Joined: 15.06.2008, 11:21
Posts: 166
Location: Germany
Quote:
If I understand it right, the second patch does not solve this problem already, does it? If you find a fully working solution that does not have any big bugs left, we definitely will add it to the official SVN (and of course would be very thankfull :-) ).

I've still got some problems with bones being attached to the wrong vertices (or vertex groups being attached to the wrong vertices, no idea what's going on there).

Quote:
Setting the eof property on the SVN would be something very usefull, but I can't find any possibility to change this on the SourceForge SVN.

It's actually a per-file option, and like that has to be set on the clients so that it gets applied for new files. Existing files can be set like this (for every svn repo) from the commandline:
Code:
svn propset svn:eol-style=native File1 File2 ...

or something like that, I didn't do that for quite some time now, there is a way to automatically set that as an option in the config file, here is mine:
Last lines of my ~/.subversion/config:
Quote:
enable-auto-props = yes
[auto-props]
*.c = svn:eol-style=native
*.cpp = svn:eol-style=native
*.h = svn:eol-style=native
*.dsp = svn:eol-style=CRLF
*.dsw = svn:eol-style=CRLF
*.sh = svn:eol-style=native;svn:executable
*.txt = svn:eol-style=native
*.png = svn:mime-type=image/png
*.jpg = svn:mime-type=image/jpeg
Makefile = svn:eol-style=native
*.ini = svn:eol-style=native
*.lua = svn:eol-style=native
*.hpp = svn:eol-style=native
*.mat = svn:eol-style=native
*.eff = svn:eol-style=native
*.ps = svn:eol-style=native
*.vs = svn:eol-style=native
*.xml = svn:eol-style=native

(this applies for all SVN files you add on *your* computer)


Top
 Profile  
Reply with quote  
PostPosted: 03.09.2008, 17:58 
Offline

Joined: 15.06.2008, 11:21
Posts: 166
Location: Germany
Seems that the FBX converter creates broken vertex weight lists:
.fbx:
Quote:
Indexes: 20,21,22,23,24,25,26,27
Weights: 1.00000000,1.00000000,1.00000000,1.00000000,1.00000000,1.00000000,1.00000000,1.00000000

.dae:
Quote:
<vertex_weights count="8">
<input semantic="JOINT" offset="0" source="#CubeController-Joints"/>
<input semantic="WEIGHT" offset="1" source="#CubeController-Weights"/>
<vcount>1 1 1 1 1 1 1 1</vcount>
<v>0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8</v>
</vertex_weights>


The converter of course interprets this as the first 8 vertices, and I think this interpretation is even correct as there is no other information about this in the file.

Anybody can help me with this issue? Preferrably in IRC or ICQ so that quick questions are possible?

I am currently thinking about starting to write a new converter which should support various model formats, anybody wants to help? -.-


Top
 Profile  
Reply with quote  
PostPosted: 03.09.2008, 18:51 
Offline
Tool Developer

Joined: 13.11.2007, 11:07
Posts: 1150
Location: Germany
Maybe it is also possible to create more direct exporters instead of doing several conversion steps. I think the Blender Exporter is not that far away from being usable. As far as I had a look at it, I think the only thing that has to be handled more generic is the way of parsing the Armatures, since in Blender the hierarchy of objects and armatures can be quite flexible and the exporter currently expects a very specific set-up. But we had already exported some complex models with morph targets and bone animations successfully. But when we tested the exporter with some other models it didn't create acceptable results in all cases.
Sadly I currently have absolutely no time to look at it and the student that developed it is doing some other things now.


Top
 Profile  
Reply with quote  
PostPosted: 06.09.2008, 16:48 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
phoenix64 wrote:
I am currently thinking about starting to write a new converter which should support various model formats, anybody wants to help? -.-

A converter for fbx could be quite handy. I was already considering to support the FBX ascii format since it looks relatively easy to handle and many tools support it but I won't have a chance to do that in the next time.

Also thanks for your patch. This could be a great first contribution for the soon to be started community branch.


Top
 Profile  
Reply with quote  
PostPosted: 06.09.2008, 16:57 
Offline

Joined: 22.11.2007, 17:05
Posts: 707
Location: Boston, MA
marciano wrote:
phoenix64 wrote:
I am currently thinking about starting to write a new converter which should support various model formats, anybody wants to help? -.-

A converter for fbx could be quite handy. I was already considering to support the FBX ascii format since it looks relatively easy to handle and many tools support it but I won't have a chance to do that in the next time.
On the other hand, the FBX->Collada converter works seamlessly in my experience, so it might be better to fix the ColladaConverter to read that style of Collada ;)

_________________
Tristam MacDonald - [swiftcoding]


Top
 Profile  
Reply with quote  
PostPosted: 06.09.2008, 17:16 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
swiftcoder wrote:
marciano wrote:
phoenix64 wrote:
I am currently thinking about starting to write a new converter which should support various model formats, anybody wants to help? -.-

A converter for fbx could be quite handy. I was already considering to support the FBX ascii format since it looks relatively easy to handle and many tools support it but I won't have a chance to do that in the next time.
On the other hand, the FBX->Collada converter works seamlessly in my experience, so it might be better to fix the ColladaConverter to read that style of Collada ;)

That we should also do of course, although I think it's not so much any more that is not supported by ColladaConv (mainly keyframe based (non-sampled) animations which are a bit ugly ;)).

The downside of using FBX -> Collada converter is that the production pipeline for artists becomes tedious since there are so many steps involved. Quick gameplay and asset iteration is an important feature that we should have in mind.


Top
 Profile  
Reply with quote  
PostPosted: 06.09.2008, 17:40 
Offline

Joined: 15.06.2008, 11:21
Posts: 166
Location: Germany
The actual problem with that converter is that I think its output is broken, everything else would work and can be automated.

For now I use the blender exporter, now that I got it to work, it works great, which is why I actually won't be the one to start such a converter project (I will help though!)

EDIT: Btw, any news on that community repo thing?


Top
 Profile  
Reply with quote  
PostPosted: 06.09.2008, 17:51 
Offline
Tool Developer

Joined: 13.11.2007, 11:07
Posts: 1150
Location: Germany
Give us a few minutes :-)


Top
 Profile  
Reply with quote  
PostPosted: 06.09.2008, 22:51 
Offline

Joined: 15.06.2008, 11:21
Posts: 166
Location: Germany
Anybody can test these patches with his existing Collada files and maybe with some Collada models made out of quads to see whether this works for other peoples and doesn't cause any regressions? Then it could go into community svn.


Top
 Profile  
Reply with quote  
PostPosted: 14.09.2008, 22:57 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
Did you already try out the patch with a few models?


Top
 Profile  
Reply with quote  
PostPosted: 15.09.2008, 18:27 
Offline

Joined: 15.06.2008, 11:21
Posts: 166
Location: Germany
Nope, and I'd like to see this tested with the other exporters, not only with blender. I'll test it with blender now.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 9 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group