Sign in to follow this  
Bru

3 is bigger than 9/3

Recommended Posts

hey there, i would like to discuss about a strange problem i am having with the directX api. i have a mesh. now i got the vertex list from its vertex buffer. tryed to use Mesh->GetNumFaces() in the loop that creates the vertex list, and use Mesh->GetNumVertices()/3 in another loop that checks collision with 3 vertices at a time. ofc my whole collision system seem to be buggy, but after hours of debugging i found out that one of the things that may cause it is that GetNumFaces brings a bigger result by about 100 than GetNumberVertices/3, which seems damn odd to me. correct me if i am wrong, a face is a triangle? a triangle has 3 vertices? 3 vertices are one triangle? then how comes the results are not equal?

Share this post


Link to post
Share on other sites
You could have a triangle strip or fan, which wouldn't be 3 vertices per triangle - although I think I heard that ID3DXMesh only uses triangle lists (I don't use ID3DXMesh).

The likely cause is that the index buffer references multiple vertices. You'll want to get the index buffer too, and see how many indices are in it.

Share this post


Link to post
Share on other sites
Quote:
Original post by Evil Steve
You could have a triangle strip or fan, which wouldn't be 3 vertices per triangle - although I think I heard that ID3DXMesh only uses triangle lists (I don't use ID3DXMesh).

The likely cause is that the index buffer references multiple vertices. You'll want to get the index buffer too, and see how many indices are in it.


oh i see, this makes sense. this might also be the reason why my collision function seems to a bit while checking collision.
thanks :) i'll rate you as helpfull

Share this post


Link to post
Share on other sites
I haven't worked with the DX mesh, but I think that it's possible that the mesh gets optimized, this means that the number of vertices is not numberOfFaces*3.

Share this post


Link to post
Share on other sites
Quote:
Original post by Waterwalker
Hi,

usually one vertex is shared or referenced by multiple adjacent triangles. getNumIndices()/3 is what you are looking for.

regards


unfortunately there's no such method in ID3DXMesh

Share this post


Link to post
Share on other sites
Quote:
Original post by Bru
Quote:
Original post by Waterwalker
Hi,

usually one vertex is shared or referenced by multiple adjacent triangles. getNumIndices()/3 is what you are looking for.

regards


unfortunately there's no such method in ID3DXMesh
You can always use GetIndexBuffer() - although I suspect there's a cleaner way:

UINT GetNumIndicesInMesh(ID3DXBaseMesh* pMesh)
{
// Get the index buffer
LPDIRECT3DINDEXBUFFER9 pIB;
HRESULT hResult = pMesh->GetIndexBuffer(&pIB);
if(FAILED(hResult))
return 0;

// Get the buffer description
D3DINDEXBUFFER_DESC desc;
hResult = pIB->GetDesc(&desc);
pIB->Release();
if(FAILED(hResult))
return 0;

if(desc.Format == D3DFMT_INDEX16)
return desc.Size / 2;
else if(desc.Format == D3DFMT_INDEX32)
return desc.Size / 4;

// Unknown format
return 0;
}




EDIT: Actually, if ID3DXMesh only uses indexed triangle lists, then the number of indices is implicitly the number of faces times 3. Although you could use the above code to verify that if you really want.

Share this post


Link to post
Share on other sites
Quote:
Original post by Evil Steve
Quote:
Original post by Bru
Quote:
Original post by Waterwalker
Hi,

usually one vertex is shared or referenced by multiple adjacent triangles. getNumIndices()/3 is what you are looking for.

regards


unfortunately there's no such method in ID3DXMesh
You can always use GetIndexBuffer() - although I suspect there's a cleaner way:
*** Source Snippet Removed ***

EDIT: Actually, if ID3DXMesh only uses indexed triangle lists, then the number of indices is implicitly the number of faces times 3. Although you could use the above code to verify that if you really want.


thanks i'll try that :)
i hope its ok if i'll use this thread for another question, better ask it here than open another thread and be getting my user rating raped even more.
the thing is i have my collision function that recives vertex as D3DXVCTOR3*.
now i pass it a vertex list(which seems to be completly fine when i checked it) in a loop, and sometimes it seems like the third parameter which is the third vertex arrives as ???? instead of a number, and this kills my calculations.
now i didnt bring any code since its a bit alot, but if i'll know what might cause the parameter to sometimes become ???? i might be able to fix it.
so what might screw it?

Share this post


Link to post
Share on other sites
If I get you right you lock the vertex buffer and reinterpret the data pointer provided by the lock as pointer to a D3DXVECTOR3 array. Note that each vertex of the mesh does not only contain a position but other attributes such as normals or texture coordinates as well.

Hence GetNumBytesPerVertex() tells you how many bytes each vertex of the mesh has. Usually the first 3*sizeof(float) bytes of each vertex are the vertex' position which you could interpret as D3DXVECTOR3. If you want to loop through your vertices use the pointer from the data lock and for each iteration add GetNumBytesPerVertex() to the pointer. Then you can use the pointer reinterpreted to D3DXVECTOR3*.

Share this post


Link to post
Share on other sites
Quote:
Original post by Bru
the thing is i have my collision function that recives vertex as D3DXVCTOR3*.
now i pass it a vertex list(which seems to be completly fine when i checked it) in a loop, and sometimes it seems like the third parameter which is the third vertex arrives as ???? instead of a number, and this kills my calculations.
now i didnt bring any code since its a bit alot, but if i'll know what might cause the parameter to sometimes become ???? i might be able to fix it.
so what might screw it?
If you mean it shows up as "????" in the watch window, that means that it's an invalid value, usually because you have an invalid pointer. Check that you're not reading past the end of the vertex buffer - you can get the number og bytes in the vertex buffer from a GetDesc() call on the vertex buffer, and you can add that on to the address returned from locking the buffer to tell you where the end is.

Share this post


Link to post
Share on other sites
Quote:
Original post by Evil Steve
Quote:
Original post by Bru
the thing is i have my collision function that recives vertex as D3DXVCTOR3*.
now i pass it a vertex list(which seems to be completly fine when i checked it) in a loop, and sometimes it seems like the third parameter which is the third vertex arrives as ???? instead of a number, and this kills my calculations.
now i didnt bring any code since its a bit alot, but if i'll know what might cause the parameter to sometimes become ???? i might be able to fix it.
so what might screw it?
If you mean it shows up as "????" in the watch window, that means that it's an invalid value, usually because you have an invalid pointer. Check that you're not reading past the end of the vertex buffer - you can get the number og bytes in the vertex buffer from a GetDesc() call on the vertex buffer, and you can add that on to the address returned from locking the buffer to tell you where the end is.

i think i dont? i have this code i found and twaked a little.

VerticesNum = new D3DXVECTOR3[Mesh->GetNumVertices()/3];

DWORD stride = D3DXGetFVFVertexSize(Mesh->GetFVF());
BYTE* vbptr = NULL;Mesh->LockVertexBuffer(0, (LPVOID*)&vbptr);
for(DWORD i = 0; i < Mesh->GetNumVertices()/3;i++){
D3DXVECTOR3* pos = (D3DXVECTOR3*)vbptr;
VerticesNum[i].x = pos->x;
VerticesNum[i].y = pos->y;
VerticesNum[i].z = pos->z;
vbptr += stride;

}

Mesh->UnlockVertexBuffer();

i thought it does a good job making a vertex list out of the vertex buffer. does it not? should i have used the functions you guys mentioned?

Share this post


Link to post
Share on other sites
This piece of code looks ok except that you should not divide the vertex count by 3. A mesh has n vertices and you want to loop through all n vertices. Using your code you would only copy the first thrid of vertices from the mesh.

Is this really the code that shows up as ??? in the debugger? I would think there is another piece of code in your source that loops through this array using another counter (numTris for example) and hence accesses invalid memory areas.

Share this post


Link to post
Share on other sites
Quote:
Original post by Waterwalker
This piece of code looks ok except that you should not divide the vertex count by 3. A mesh has n vertices and you want to loop through all n vertices. Using your code you would only copy the first thrid of vertices from the mesh.

Is this really the code that shows up as ??? in the debugger? I would think there is another piece of code in your source that loops through this array using another counter (numTris for example) and hence accesses invalid memory areas.

when i first got that piece of code i didnt devide the loop by 3. the thing is that i had to do it with the array in the first line, and if i didnt do that i got an exception because that the array is full and i am still trying to fill it with information.
and yes, that's not the code that brings ???. should i post it too?
also, that function that sometimes brings question marks as the third parameter doesnt do it in the end of the list. it can give me question marks,when i pass 3 vertices that are in the middle of the list.

Share this post


Link to post
Share on other sites
The correct way to copy the vertices' positions from the vertex buffer could look like this (I did not compile but you get the idea)

D3DXVECTOR3 *vertices = new D3DXVECTOR3[Mesh->GetNumVertices()];
DWORD stride = Mesh->GetNumBytesPerVertex();
BYTE* vbptr = NULL;

Mesh->LockVertexBuffer(0, (LPVOID*)&vbptr);
D3DXVECTOR3 *pos = vertices;

for (DWORD i = 0; i < Mesh->GetNumVertices(); i++)
{
memcpy(pos, vbptr, sizeof(D3DXVECTOR3));
vbptr += stride;
pos++;
}


After that you can run through the array vertices with your debugger and check the values. They should be alright. If something goes wrong in another place then its most likely the wrong count you use to access the array.

Share this post


Link to post
Share on other sites
Quote:
Original post by Waterwalker
The correct way to copy the vertices' positions from the vertex buffer could look like this (I did not compile but you get the idea)

D3DXVECTOR3 *vertices = new D3DXVECTOR3[Mesh->GetNumVertices()];
DWORD stride = Mesh->GetNumBytesPerVertex();
BYTE* vbptr = NULL;

Mesh->LockVertexBuffer(0, (LPVOID*)&vbptr);
D3DXVECTOR3 *pos = vertices;

for (DWORD i = 0; i < Mesh->GetNumVertices(); i++)
{
memcpy(pos, vbptr, sizeof(D3DXVECTOR3));
vbptr += stride;
pos++;
}


After that you can run through the array vertices with your debugger and check the values. They should be alright. If something goes wrong in another place then its most likely the wrong count you use to access the array.


ahh thanks that seemed to have helped alot :)
though it seems like my collision function sometimes finds collision when i am moving toward the collision object, sometimes not, and sometimes it find it when i am not moving toward it. but i belive i should be able to solve that myself and i'll check that tommorow.
thanks :)

Share this post


Link to post
Share on other sites
No problem. You seem(ed) to be confused by vertices, indices, and triangles. I hope that is clearer now. Collision detection can be quite hard to get it right but you should dig through some tutorials about that first using google to find some stuff ;)

Share this post


Link to post
Share on other sites
Quote:
Original post by Waterwalker
No problem. You seem(ed) to be confused by vertices, indices, and triangles. I hope that is clearer now. Collision detection can be quite hard to get it right but you should dig through some tutorials about that first using google to find some stuff ;)

thanks :) tbh i found that a bit hard for me to read long articles and i dont know why. maybe they are just too long or doesnt explain the subject good enough, or think i am a math genious or because english is not my first language(i do understand everything i read, but you know it can be such a headach to read an article that is not in your M language).

Share this post


Link to post
Share on other sites
wow, i tryed to also get the indices data from the index buffer but my attempt didnt go very well. tryed to do it the same way waterwalker posted here but it didnt work, i seem to be getting exceptions when i try to get the indices data.
i thought it would work the same way but it seems like not.
is it diffrent?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this