Jump to content
  • Advertisement
Sign in to follow this  
xissburg

hmm...I wanna get the vertex positions yet!!! :P

This topic is 4818 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello...this is the 3rd time I'm asking it here!heh...the answers I got was not sufficient but, thanks for who answered me...I think it will be the last time I will be asking it here....heh... :) Well, I've developped a 'walk on terrain system'(heheh).Its a first person simulator where you can walk on a 'noised' terrain.Depending of the triangle you are on, you climb or get down.Resuming, I used the plane formula to do it. Now, the problem: the terrain was modelled in 3dsmax and then exported to '.x'.I loaded it into the application through D3DXLoadMeshFromX().Since I need the triangles vertices positions to calculate the triangles normals vectors, I need to copy all the positions of each vertex by hand!!Its a heavy and intense job!!!Look at 3dsmax and the go to VC++ and type number by number....hmm...think about a large terrain with many triangles?!?I would take more time to copy all the vertices positions values than to develop all the application base code!!!!Damn! So what I wanna know is how can I take all the vertices positions automatically through code.This way, I will be able to load any terrain into my application without problems...please help me!!Please write a bit of code....PLEASE give me a good explanation.... :)....:) Uffs...Thats all....Thanks for all!....

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by xissburg
Since I need the triangles vertices positions to calculate the triangles normals vectors, I need to copy all the positions of each vertex by hand!!Its a heavy and intense job!!!Look at 3dsmax and the go to VC++ and type number by number....hmm...think about a large terrain with many triangles?!?I would take more time to copy all the vertices positions values than to develop all the application base code!!!!Damn!

So what I wanna know is how can I take all the vertices positions automatically through code.


Have you heard about the concept of "loops"? [grin]

Seriously, once you find the algorithm for calculating normals for a single triangle, you can apply that algorithm to any number of triangles by using a simple loop that goes through all of them.

The actual algorithm is also easy, and readily available in 'net. To recap:

n = |p2-p0| x |p1-p0|

where p0...p2 are the points of the triangle, "x" is the cross product and anything inside "|"s are normalized.

Share this post


Link to post
Share on other sites
um,

unless i have horribly misinterpreted your question, figuring out how to export the normals from Max is somewhat irrelevant.

you can get at the geometry in the ID3DXMesh object, just there's a couple of snafus involved with doing it.

problem 1: its indexed. you have to understand the index buffer and the vertex buffer.

problem 2: you have no idea (just after loading) what vertex format the mesh will be using internally.

so, the solution i've used for a year or so:

1. use CloneMeshFVF with D3DFVF_XYZ to make a 'minimal' mesh with just positions.
2. lock the index and vertex buffers
3. loop through the indices, using 3 at a time.
4. lookup the vertex positions for those indices (sometimes it helps if you define something like

struct foobarVertex { float x; float y; float z; };

)

5. that's one of the triangles. if you go through all the indices, you'll get all your triangles out. what you do with them after that is your business.

6. after you're done, unlock the IB and VB, and release the positions-only mesh

i use this method to get geometry into my physics library, it works quite nicely.

if you need vertex normals too, you can do that...they tend to be in the mesh. you'll need to adjust your structure to contain normals :),... and then read them out with the positions as you iterate through.

if face normals are what you want, use the formula Niko suggested to calculate them... vertex normals can look better though, as you can tweak them in MAX :)

hope this is useful :)

Share this post


Link to post
Share on other sites
Hey thank you men.

Well, I wanna just the positions of the vertex.The normals are calculated through the cross product into the application.

Qatal, I've understood your method.I have already heard about this method but, I would like to see a bit of code!! Can you or anyone show it for me?!? You'll make me happy so!! :) ....heh....

Thanks...

Share this post


Link to post
Share on other sites
I wrote an x file parser for doing exactly that before. It basically just goes through an X File and gets all the vertex information. It then sends those poly's to a quad tree class for use with terrain clamping.

Couple things:

1) X file must be in ASCII format
2) This is part of a much larger system, so if you have questions about what any of the function calls do, let me know.
3) Mesh must be triangulated before export to x file


//////////////////////////////////////////////////////////////////////////
// Function: loadTerrain
//
// Purpose: Loads terrain from a .X file
//////////////////////////////////////////////////////////////////////////
MPRESULT CTerrainManager::loadTerrain(char* a_pcTerrainFile)
{
// Singletons
CLoadscreen* pLodSrn = CLoadscreen::getInstance();

// Open the file for reading
HANDLE file = CreateFile(a_pcTerrainFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

// Now we need to find out how big the actual file is
// We allow one byte for the NULL terminator
DWORD fileSize = GetFileSize(file, NULL) + 1;

// This character array will store the entire file contents
char *fileAsText = new char[fileSize];

// Start with a NULL string so we don't have any garbage to screw things up
memset(fileAsText, 0, fileSize);

// ReadFile needs a DWORD as one of the parameters
DWORD bytesRead;

// Read the file into our string for the amount of bytes taken from GetFileSize
ReadFile(file, fileAsText, fileSize - 1, &bytesRead, NULL);

// If you create a handle, you have to close it as well
CloseHandle(file);


// The will hold the bounding volumes for the mesh as a whole
// These values will be used to set up the quad tree
// We start the at the highest and lowest values they can store so that the
// first position we come across over writes them
float minX, minZ, maxX, maxZ;
minX = minZ = FLT_MAX;
maxX = maxZ = FLT_MIN;


// At this point we have loaded the file and can start parsing it

// We'll start by finding the chunck of data containing the mesh
char* placeHolder = strstr(fileAsText, "Mesh ");

// We then want to skip to the end of that line
placeHolder = strstr(placeHolder, "\n");

// And now their are 4 characters before we get to the data
placeHolder += 4;

// We are now sitting right infront of the number of verts, so lets read them in!
sscanf(placeHolder, "%d;", &vertexCount);

// We then want to skip to the end of that line
placeHolder = strstr(placeHolder, "\n");

// And now their are 4 characters before we get to the next data
placeHolder += 4;

// With all the proper counters set up we can now allocate some memory to
// store the verts and indicies
verticies = new CCustomVertexDefault[vertexCount];

// Let start with a clean slate and memset out vertex array
memset(verticies, 0, sizeof(CCustomVertexDefault) * vertexCount);

// Reset the loading screen task
pLodSrn->setNewTask("Loading Terrain Verts");

// Now that we have the vertex count we can loop through and load the vert data
for(int i = 0; i < vertexCount; i++)
{
// The vertex data looks something like this:
// -50.000000;-0.000000;50.000000;,
// Line after line of coordinates, so lets read them in

// Start by creating some temp variables to make reading in the data a little
// easier
float x, y, z;

// Now read into those temp variables
sscanf(placeHolder, "%f;%f;%f;,", &x, &y, &z);

// Now copy that data into the real verticies
verticies.m_vec3Translation.x = x;
verticies.m_vec3Translation.y = y;
verticies.m_vec3Translation.z = z;

verticies.m_vec3Normal.y = 1.0f;

// Lets check if we have extended the bounds at all
if(x < minX)
minX = x;
if(x > maxX)
maxX = x;
if(z < minZ)
minZ = z;
if(z > maxZ)
maxZ = z;

// We then want to skip to the end of that line
placeHolder = strstr(placeHolder, "\n");

// And now their are 4 characters before we get to the next data
placeHolder += 4;
}

// Awesome! So at this point we have all the verts loaded in an we're even left
// with our place holder point right at the start of the index data! Lets load it.

// Like the verts, the first thing we need to do is find out how many there are
// In this case though, it is telling us how many primitives their are
sscanf(placeHolder, "%d", &primativeCount);

// With that in mind though, its a simple calculation to get the number of
// indicies
indexCount = primativeCount * 3;

// We then want to skip to the end of that line
placeHolder = strstr(placeHolder, "\n");

// And now their are 6 characters before we get to the data
placeHolder += 6;

// With the number of indicies know to us we can allocate some memory
indicies = new WORD[indexCount];

// Reset the loading screen task
pLodSrn->setNewTask("Loading Terrain Indicies");

// Now we just fly through the data loading in the indicies
for(i = 0; i < indexCount; )
{
// A line of data for indices looks like this:
// 3;0,1,11;,
// But since we skipped 6 characters this time we are right after the '3;'
// We do this because all the 3 is for is to tell us how many indicies are
// on this line (3 means we are using triangles too). But since the entire model
// is the same (in this sense), it says 3 everytime, so lets just skip over it

// Once again lets create some temp variables
int a, b, c;

// And lets read the data into those variables
sscanf(placeHolder, "%d,%d,%d", &a, &b, &c);

// Now we need to cycle through and store these indicies
indicies = a;
i++;
indicies = b;
i++;
indicies = c;
i++;

// We then want to skip to the end of that line
placeHolder = strstr(placeHolder, "\n");

// And now their are 6 characters before we get to the data
placeHolder += 6;
}

// Now we can create our quad tree
boxf bounds;
bounds.min.x = minX;
bounds.min.z = minZ;
bounds.max.x = maxX;
bounds.max.z = MaxZ;

m_pQTree = new quad_tree(bounds);

// Reset the loading screen task
pLodSrn->setNewTask("Populating Quad Tree");

for(i = 0; i < indexCount; i += 3)
{
polygon newPoly;
newPoly.verts[0] = verticies[indicies].m_vec3Translation;
newPoly.verts[1] = verticies[indicies[i + 1]].m_vec3Translation;
newPoly.verts[2] = verticies[indicies[i + 2]].m_vec3Translation;
m_pQTree->addPoly(newPoly);
}

// Finally lets clean up the memory
delete [] fileAsText;

// Everything went great
return MPERR_OK;
}




If you open up an x file in note pad, you can follow along with all the pointer arithmetic. It's a little ugly, but quite simple at its core.

Matt Hughson

Share this post


Link to post
Share on other sites
Hey thanks for everyone!...I finally got the vertex positions from my D3DXMESH!!!:)

But....there's another problem now...:(

Well, I have the all the vertex positions but, as I already said before, I will calc the triangles normals and I need to know which vertex is connected to another vertex...and so on...I need to know what are the index of the vertex which form the triangle0, triangle1, etc...I have the following structure to hold the triangles properties:


struct TRIANGLE
{
D3DXVECTOR3 v0;
D3DXVECTOR3 v1;
D3DXVECTOR3 v2;
D3DXVECTOR3 N;
float d;
};


v0, v1 and v2 are the triangle's vertex positions, N is the triangle's normal vector and d is the constant of the triangle used in the plane formula(ax+by+cz+d=0).N and d will be calculated after the vertex positions be found.

I've tried many algorithms but none of them worked correctly...PLEASE HELP ME AGAIN MAN!!!

Thanks for all....

Share this post


Link to post
Share on other sites
Isn't it!!!

I wanna get the vertex index of the vertices which forms the triangle0, triangle1, triangle2....

I wanna know which vertex is connected to which vertex.For example v1 is connected to v5 which is connected to v19 which is conneced to v1.It forms a triangle!

Please understand me!

Share this post


Link to post
Share on other sites
Several functions can create an adjacency table, which shows what vertices are connected to which ones. ID3DXMesh::OptimizeInplace can do this.

Syntax:

HRESULT OptimizeInplace(
DWORD Flags,
CONST DWORD *pAdjacencyIn,
DWORD *pAdjacencyOut,
DWORD *pFaceRemap,
LPD3DXBUFFER *ppVertexRemap
);



Hope this helps,
ProgrammingNerd

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!