[GOOD NEWS! READ PLEASE] How to generate adjacency?

Started by
34 comments, last by XVincentX 15 years, 9 months ago
Hello! I'm trying to implement a Shadow Volume example. I'm not using .x file format but a class containing Index and Vertex Buffer. Now, even if i try to set D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ and triangleadj in the Geometry Shader input, the silohuette detecting does not works. I read on internet that adjaceny must be generated and inserted in the index buffer, but how? How to understant the adjacency from an existing vertex-index buffer? Thank you! [Edited by - XVincentX on June 30, 2008 9:24:50 AM]
Advertisement
Don't know about DX10... and I may be telling you something you already know, but:

int iFaces = pMeshToPrep->GetNumFaces();DWORD* adjInfo = new DWORD[iFaces *3];pMeshToPrep->GenerateAdjacency(00.0000125f, adjInfo);


Edit-
Sorry just re-read your post, Yeah I don't know how to explicitly attach or insert that info into a mesh :/
Infact; i need to get them without using D3DX Mesh interface, i've got only vertex and index buffer.

Noone knows how?
Quote:I read on internet that adjaceny must be generated and inserted in the index buffer

Could you post a link to that info? It's not clear what "inserting" something into an index buffer means. It may be that, by looking at it, others may get an idea of what is intended and be able to provide you with recommendations.

In general, determining adjacency is not a trivial algorithm. Even if you come up with an algorithm, making it efficient could be difficult as it requires the comparison of multiple face vertices with vertices of other faces, easily resulting in 100's (if not 1000's) of vector comparisons.

A general outline (just off the top of my head):

Set up an array of DWORDs of size 3*numFaces (3 DWORDs per face). Set all values in the array to 0xffffffff.

for each face: compare the 3 sets of 2 vertices (each forming the line on one side of the face) in order with all sets of vertices for all other faces of a higher number.

For each comparison: If set "n" (n=0,1 or 2) from the first face IS sufficiently close (you must decide "how close" is "close") to a set from the second face, store the number of the second face in the array at position "n" for the first face. If the comparison is valid (the vertex sets are "close"), store the number of the first face in the appropriate position for the adjacency of the second face.

NOTE: this will not work if a vertex position is common to more than 3 faces.


[Edited by - Buckeye on June 27, 2008 2:55:18 PM]

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Sure!

My goal it's to have in the geometry shader 3 primitive vertices and 3 vertices of adiacency.
In this way, i will be able to... bla bla bla bla...

I've got Vertex and Index buffer, and so i tried to search in D3D documentation. I found this, in ID3DX10Mesh

Generate a list of mesh edges, as well as a list of faces that share each edge.HRESULT GenerateAdjacencyAndPointReps(  FLOAT Epsilon);


But there is also this other function:

Adds adjacency data to the mesh's index buffer. When the mesh is to be sent to a geometry shader that takes adjacency data, it is neccessary for the mesh's index buffer to contain adjacency data.HRESULT GenerateGSAdjacency();


So i think that the right way to generate adjacency for geometry shader using, it's to add the right indices in the index buffer.
So for each primitive i should have got 6 indices...

From D3D10 FAQ, there is also this:

Quote:
How does D3D10 know how to generate adjacency indices for my mesh? Or, why does D3D10 not render correctly when I specify that the geometry shader needs adjacency information.

The adjacency information is not created by D3D10, but by the application. Adjacency indices are generated by the application and must contain six indices per primitive; of the six, the odd numbered indices are the edge adjacent vertices. ID3DX10Mesh::GenerateAdjacencyAndPointsReps can be used to generate this data.

Quote:Original post by Buckeye
In general, determining adjacency is not a trivial algorithm. Even if you come up with an algorithm, making it efficient could be difficult as it requires the comparison of multiple face vertices with vertices of other faces, easily resulting in 100's (if not 1000's) of vector comparisons.


Urgh!!!
mmm, and then how can Microsoft Implementation be so quick?
Okay. See my previous (edited) post for a possible algorithm.

From the description, it appears that the interleaved indices for a single face are:

1. index of the first vertex.
2. index of the face (or 0xffffffff if no other face is adjacent <-- guessing) that shares the current face's vertex 0 and vertex 1.
3. index of the second vertex.
4. index of the face that shares the current face's vertex 1 and 2.
5. index of the third vertex.
6. index of the face that shares the current face's vertex 2 and vertex 0.

Quote:the odd numbered indices are the edge adjacent vertices

Sorry. I'm not sure, in this context, what "edge adjacent vertices" could mean other than the index of a face that shares that edge.

By the way, the "epsilon" mentioned in the GenerateAdjacency call is some small number that you supply that determines "how close" one vertex position must be to another to be considered "the same position."

EDIT: if you implement an algorithm and it's at all possible, generate a mesh and the index buffer described and compare your result with DX10's.

EDIT2: with regard to speed, you should, in general, only have to generate the adjacency info once, unless you rearrange your mesh often. By the way, how do you know that the DX10 algorithm is fast? [smile]

EDIT3: note, also, if you implement such an algorithm, you have to pay careful attention to the order of comparision with the second face vertices. I.e., if you're comparing v0 and v1 of the first face (the first of the three sets to compare), you'll compare them to the three sets (v1,v0), (v2,v1), (v0,v2) of the second face because the edge direction reverses on each edge.

[Edited by - Buckeye on June 27, 2008 2:22:07 PM]

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

mmm, i found another thing interesting.
Take a look in this page of Direct3D10 Doc

direct3D10->programming guide->pipeline stage->input assembler stage->getting started->primitive topologies, and look for TriangleList with adjacency.

I thought...mabye i have just to order indices in that way, to have adjacency...or not?
Okay. In the ShadowVolume10 Sample on msdn (I don't have the DX10 docs), it has a diagram that shows that, indeed, the interleaved index is the vertex index for the non-coincident vertex of an adjacent face. That makes sense for an indexed mesh (or array of vertices) which share vertices, one of two types of indexed meshes. In my previous post, I was considering a mesh that may contain triangles comprised of vertices that are not shared with any other face.

It appears that it would not work for a mesh comprised of faces which do not share vertices.

Is your setup (vertices and indices) strictly comprised of shared vertices to form adjacent faces?

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Yes, i use Indexed Mesh, and all shares vertices.
Simple example here -> http://xvincentx.netsons.org/programBlog/wp-content/v2ydbb6tmp.jpg

I'm sorry if i did not specify this particular, i thought it was implicit

Ok, now how have i to proceed?

This topic is closed to new replies.

Advertisement