Horde3D

Next-Generation Graphics Engine
It is currently 16.04.2024, 05:27

All times are UTC + 1 hour




Post new topic Reply to topic  [ 13 posts ] 
Author Message
PostPosted: 20.07.2010, 18:52 
Offline

Joined: 16.05.2009, 12:43
Posts: 207
Hey all.

So I'm in the final phase of implementing the core features for my engine before I start back in on the AI stuff. The last thing I really have to implement is getting the meshes baked into a physx representation.

Now I'm already doing that, but there are issues with the way that horde represents vertex and triangle index data. Let me explain a bit.

Physx in order to cook a mesh, requires raw vertex position data + n vertices AND raw triangle index data + n triangles

The problem is that horde doesnt actually use just the vertex positions as indices within the triangle data does it. It uses (as far as I can tell) three vertices per triangle as you would expect, but these vertices can be duplicated such that the normals can be different. Thing is that physx wants a SINGLE vertex, rather than one per triangle with different normal. So for instance its able to cook out a flat quad, because its got the same normals. But it cant cook out a box, because each side of the box has its own set of normals and verts.

So my question is: Whats the best way to just get the position array, rather than the vertex array per vertex+normal triangle index? I would prefer to get it via the render interface if possible, but otherwise I'll have to hack ColladaConv to store raw vertex positions + raw triangles.

Any ideas?


Top
 Profile  
Reply with quote  
PostPosted: 21.07.2010, 02:03 
Offline

Joined: 08.11.2006, 03:10
Posts: 384
Location: Australia
It shouldn't be too hard to take a Horde index/vertex buffer, and then strip out the 'duplicated' vertices. I would approach it something like below (this probably isn't the most efficient, but it should work, i think :wink: )
Code:
deadIndices = new set

# remap indices to remove duplicate positions
for each vertex as V,I              # that's POSITION,INDEX
  for each other vertex as O,J
    if dist(V, O) < epsillon then
      deadIndices.insert( J )
      for each index as K
        if K == J then
          K := I

# This part might not be needed, it just saves space:

# now actually remove the duplicated data...
sort deadIndices in descending order
for each deadIndices as D
  vertex.remove( D )

#...and shift down indices to match
for each index as I
  for each deadIndices as D
    assert( I != D )
    if I > D then
      --I


Top
 Profile  
Reply with quote  
PostPosted: 21.07.2010, 08:35 
Offline

Joined: 16.05.2009, 12:43
Posts: 207
Hmm, maybe I'm looking at this wrong. Maybe the vertex stream isnt just vertices. Maybe its vertex + normal + tangent?

Maybe I just need to change the stride?

Weirdly enough, the navmesh generator just takes this all in its stride. But feeding the same info to physx just comes back with broken geometry. I'll have to investigate further.


Top
 Profile  
Reply with quote  
PostPosted: 21.07.2010, 09:50 
Offline

Joined: 16.05.2009, 12:43
Posts: 207
So to be clear what my problem is.. let me outline something.

I've attached the planebox dae and scene files so you can see what I mean.

If you look in the DEA for the box mesh. There are 8 vertices (as you would expect for a box). If you look at the corresponding scene.xml you have vertstart at 4 and end at 27. Clearly 24 verts is different than 8! So it makes sense that there are 24 verts if you have 6 sides each with 4 verts. But I dont see any of that in the DAE file. So its likely something thats being done in colladaconv. My question is how do I get the original 8 verts?


Attachments:
planebox.DAE.xml [12.36 KiB]
Downloaded 834 times
planebox.scene.xml [520 Bytes]
Downloaded 637 times
Top
 Profile  
Reply with quote  
PostPosted: 21.07.2010, 10:34 
Offline

Joined: 15.02.2009, 02:13
Posts: 161
Location: Sydney Australia
Hi zoombapup,

This might or might not be the case, but try setting the normals to all smooth on the mesh so it isn't solid or has sharp edges.

_________________
-Alex
Website


Top
 Profile  
Reply with quote  
PostPosted: 21.07.2010, 11:03 
Offline

Joined: 16.05.2009, 12:43
Posts: 207
I did think it might be the mesh, but looking at the DAE file, it seems like the issue is on the horde side. The DAE file clearly shows proper vertex positions and triangle indices.


Top
 Profile  
Reply with quote  
PostPosted: 21.07.2010, 13:05 
Offline

Joined: 15.02.2009, 02:13
Posts: 161
Location: Sydney Australia
Hi zoombapup,

The collada format might specify the verts correctly but internally collada converter might split the mesh up based on the hard edges so they do render as hard edges, because as far as I know I don't think opengl can specify the difference between hard edges and smooth edges, it needs to be split up at the vertex level and this would explain why you have 24 verts instead of 8, each face has its own unique 4 verts.

_________________
-Alex
Website


Top
 Profile  
Reply with quote  
PostPosted: 21.07.2010, 13:47 
Offline

Joined: 16.05.2009, 12:43
Posts: 207
Yeah, I think youre right there. So I guess my best bet is to add physx cooking into colladaconverter before it does that split. That way I can grab the raw vertex positions+triangles and spit them out to a physx baked version (I guess it kind of makes sense to do that anyway, but for some reason it felt a bit bad doing that).


Top
 Profile  
Reply with quote  
PostPosted: 22.07.2010, 07:47 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
Hi,

the position stream is not interleaved with other data. ColladaConv does split vertices if they have different normals or tex coords, as this is required for rendering. For a physics proxy mesh (without render material), you could try to disable texture coordinates and just use one smoothing group, so that normals for a single vertex point into the same direction. Then ColladaConv might not split the vertices.

Otherwise, as DarkAngel points out, it should not be too hard to reconstruct an index buffer with merged positions, either at load time or in ColladaConv. The second index buffer might even make it officially into ColladaConv one day, as it is more friendly to the post-transform vertex cache for shadow map rendering or a z pass.


Top
 Profile  
Reply with quote  
PostPosted: 22.07.2010, 08:20 
Offline

Joined: 08.11.2006, 03:10
Posts: 384
Location: Australia
zoombapup wrote:
So I guess my best bet is to add physx cooking into colladaconverter before it does that split.
The only thing I'd worry about is that in some cases, a model might be exported with some "splits" already in it (e.g. an artist has two verts at the same position and hasn't welded them). I'd probably still run something like my above algorithm to make it completely bullet proof (seeing this is a tool you'll be giving to artists, who will want it to "just work(TM)").
marciano wrote:
The second index buffer might even make it officially into ColladaConv one day, as it is more friendly to the post-transform vertex cache for shadow map rendering or a z pass.
I've never heard of using a second index buffer for z-only passes -- that's a cool idea!


Top
 Profile  
Reply with quote  
PostPosted: 22.07.2010, 09:38 
Offline

Joined: 16.05.2009, 12:43
Posts: 207
DarkAngel wrote:
zoombapup wrote:
So I guess my best bet is to add physx cooking into colladaconverter before it does that split.
The only thing I'd worry about is that in some cases, a model might be exported with some "splits" already in it (e.g. an artist has two verts at the same position and hasn't welded them). I'd probably still run something like my above algorithm to make it completely bullet proof (seeing this is a tool you'll be giving to artists, who will want it to "just work(TM)").
marciano wrote:
The second index buffer might even make it officially into ColladaConv one day, as it is more friendly to the post-transform vertex cache for shadow map rendering or a z pass.
I've never heard of using a second index buffer for z-only passes -- that's a cool idea!


Only me on this project. So I can assume if it doesnt work, the artist (me) knows whats wrong. :)


Top
 Profile  
Reply with quote  
PostPosted: 22.07.2010, 14:30 
Offline

Joined: 16.05.2009, 12:43
Posts: 207
Actually Marciano, if you can give me some pointers as to where in colladaconv it actually does the splitting that would be good. I'm thinking its converter::processMeshes where I need to grab the raw triangle indices and vertex positions but I'm not quite understanding what youre doing there. I assume its basically taking the collada data and converting it into a bunch of output buffers to be saved in the geometry file?

So where does it do the actual splitting for normals? Or does it do that when it loads the collada scene?


Top
 Profile  
Reply with quote  
PostPosted: 22.07.2010, 22:32 
Offline
Engine Developer

Joined: 10.09.2006, 15:52
Posts: 1217
In Collada, the corner of a primitive (e.g. triangle) is not a single vertex index but rather a tuple of indices, one for position, normal, tex coords, etc. Technically, ColladaConv does not split but rather merge these indices. It loops over all index tuples and checks if a vertex with this data already exists. If that's the case, it reuses it, otherwise it creates a new entry in the vertex array. This is done in the for loop below the comment "// Try to find vertex". For performance reasons, we don't loop over the whole list of vertices but only the ones that have the same position index as our tuple.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 8 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