accessing mesh data (sorta continued)

Started by
7 comments, last by Muhammad Haggag 19 years, 7 months ago
A little while ago i had posted asking help on accessing verticies in a mesh, but i seem to have that going without bugs... Now a new problem arises. I get a simple face index from the D3DXINTERSECT function telling me the polygon number of which i hit with my ray. So i take the face index (which im pretty sure is working correctly) and use the following code:
D3DXVECTOR3 *pVertList;

m_pMesh->LockVertexBuffer(D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK, (BYTE**)&pVertList);

intersectO.v1 = pVertList[dwFace * 3];
intersectO.v2 = pVertList[dwFace * 3 + 1];
intersectO.v3 = pVertList[dwFace * 3 + 2];

m_pMesh->UnlockVertexBuffer();


now when i display the verticy information i recieve it turns out to be some really screwed up figures... i render a polygon that is pure white with the 3 verticies i get and it seems to be completely randomly placed, so i think that how i get my vertex information from the mesh is screwed up some how. Another thing, the figures that display when i run the program range from something like this: 0.#DS3X12.00 to: 2000000000000000000000000000000.0000 one i saw was 2 thousand trillion trillion trillion...... no joke... any ideas? *ponder Chris
Bow before me... for i am l33t!
Advertisement
Are you checking the range of dwFace with the number of vertices in the mesh? Make sure it's more or equal to 0 and less than the number of vertices / 3.

I can't see anything wrong in the code that you posted. Are there any other fragments that mess with intersectO besides printing out the values?
If your mesh's FVF is anything besides D3DFVF_XYZ, this won't work. You should get the size of each mesh vertex and do something like:

BYTE* pVertList;[lock]pVertList += vertSize * dwFace * 3;intersectO.v1 = *static_cast<D3DXVECTOR3*>(pVertList);pVertList += vertSize;intersectO.v2 = *static_cast<D3DXVECTOR3*>(pVertList);pVertList += vertSize;intersectO.v3 = *static_cast<D3DXVECTOR3*>(pVertList);


You get the idea.

Well you were right, my mesh does not support just xyz, now i tried using a vertex buffer:

struct vertex_test{
float x,y,z;
float nx,ny,nz;
DWORD Diffuse;
DWORD Ambient;
DWORD Specular;
DWORD Emissive;
float tx, ty;
};

But it still seems to be rather confused, i notice that some of the verticies that i get do corrilate to some of the verticies shown, but they dont seem to corrilate polygon wise (one will come out of the crate corner while one will go to one of the grid polygons on the ground)

How would i be able to get the size of the vertex type that the mesh is using so that i could compare it to the vertex structure i have created? I am using the mesh class from "The Zen of d3d game programming". I tried to find out but it uses materials and stuff so im not quite sure where to go from now to find out.


Thanks for all your help so far, its been really helpful



Chris
Bow before me... for i am l33t!
Quote:Original post by Pirosan
How would i be able to get the size of the vertex type that the mesh is using so that i could compare it to the vertex structure i have created? I am using the mesh class from "The Zen of d3d game programming". I tried to find out but it uses materials and stuff so im not quite sure where to go from now to find out.


The author of the book must have declared a standard vertex type somewhere. Try looking for that. If his mesh class is using the ID3DXMesh interface to manage the mesh, then you can get the size of a vertex by calling ID3DXMesh::GetFVF(), which will tell you the FVF codes being used, then use that returned DWORD to calculate the size.

DWORD fvf = p_pMesh->GetFVF();DWORD size = 0;if( fvf & D3DFVF_XYZ ) size += 12else if( fvf & D3DFVF_XYZRHW ) size += 16if( fvf & D3DFVF_NORMAL ) size += 12if( fvf & D3DFVF_DIFFUSE ) size += 4if( fvf & D3DFVF_SPECULAR ) size += 4if( fvf & D3DFVF_TEX1 ) size += 8

[size=2]aliak.net
Quote:Original post by IFooBar
If his mesh class is using the ID3DXMesh interface to manage the mesh, then you can get the size of a vertex by calling ID3DXMesh::GetFVF(), which will tell you the FVF codes being used, then use that returned DWORD to calculate the size.

DWORD fvf = p_pMesh->GetFVF();DWORD size = 0;if( fvf & D3DFVF_XYZ ) size += 12else if( fvf & D3DFVF_XYZRHW ) size += 16if( fvf & D3DFVF_NORMAL ) size += 12if( fvf & D3DFVF_DIFFUSE ) size += 4if( fvf & D3DFVF_SPECULAR ) size += 4if( fvf & D3DFVF_TEX1 ) size += 8

Rather than manually calculating the vertex size, one should use D3DX to do it. The final code might look like:
BYTE* vertices;m_mesh->LockVertexBuffer(D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK, &vertices);UINT stride = D3DXGetFVFVertexSize(m_mesh->GetFVF());// Seek to the first vertex of the given facevertices += stride * dwFace * 3;intersectO.v1 = *static_cast<D3DXVECTOR3*>(vertices);vertices += stride;intersectO.v2 = *static_cast<D3DXVECTOR3*>(vertices);vertices += stride;intersectO.v3 = *static_cast<D3DXVECTOR3*>(vertices);mesh->UnlockVertexBuffer();

Coder, i attempted using your idea for now and got an error saying:

'static_cast' : cannot convert from 'unsigned char *' to 'struct D3DXVECTOR3 *'

Is there something missing in that code?


EDIT: wow... i fount out that the mesh information contained the xyz, the normals and the texture coordinates (it uses materials for diffuse and texture and stuff) and i set the vertex buffer to the correct settings... so i get a polygon that is linked to some REAL vertex coordinates in my simple grid world (for debugging)... but there is only one problem now. It may snap to some real world verticies, yet it seems to be random verticies on the grid, making the polygon not match any polygons i have in the level....

*PONDER >.< ;;


Chris

[Edited by - Pirosan on September 17, 2004 12:39:13 AM]
Bow before me... for i am l33t!
well... the more i do the odder it gets... i took my face index number and cast it as int and seemed to get a FEW polygons to light up... not in the right place though and there are still screwups... ah i dont know whats going on!!!!

ill put in my whole collision function and the needed structures:

return structure (returns a -1 upon failiur to hit anything or the distance to that polygon including the xyz coordinates of said polygon)
struct intersect{	float dist;	D3DXVECTOR3 v1, v2, v3;};/////and here is my simple vertex buffer!struct vert{float x,y,z;float nx,ny,nz;};

function:
ntersect OsMesh::checkCollide(D3DXVECTOR3 pRayPos, D3DXVECTOR3 pRayDir){BOOL bHit;DWORD dwFace;float fBary1, fBary2, fDist;D3DXIntersect(m_pMesh, &pRayPos, &pRayDir, &bHit, &dwFace, &fBary1, &fBary2, &fDist, NULL, NULL);struct intersect intersectO;//	fvf = m_pMesh->GetFVF();vert *pVertList;if(bHit){m_pMesh->LockVertexBuffer(D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK, (BYTE**)&pVertList);int f = (int)(dwFace);intersectO.v1.x = pVertList[f * 3].x;intersectO.v1.y = pVertList[f * 3].y;intersectO.v1.z = pVertList[f * 3].z;intersectO.v2.x = pVertList[f * 3 + 1].x;intersectO.v2.y = pVertList[f * 3 + 1].y;intersectO.v2.z = pVertList[f * 3 + 1].z;intersectO.v3.x = pVertList[f * 3 + 2].x;intersectO.v3.y = pVertList[f * 3 + 2].y;intersectO.v3.z = pVertList[f * 3 + 2].z;m_pMesh->UnlockVertexBuffer();}if(bHit){	intersectO.dist = fDist;	g_mDist = fDist;}else{	intersectO.dist = -1;}return intersectO;}
Bow before me... for i am l33t!
Quote:Original post by Pirosan
Coder, i attempted using your idea for now and got an error saying:

'static_cast' : cannot convert from 'unsigned char *' to 'struct D3DXVECTOR3 *'

Is there something missing in that code?

Pardon me, I was mistaken. Use a reinterpret_cast instead of the static_cast.

This topic is closed to new replies.

Advertisement