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

Started by
15 comments, last by ProgrammingNerd 18 years, 7 months ago
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!....
.
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.

Niko Suni

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 :)
die or be died...i think
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...
.
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].m_vec3Translation;<br>		newPoly.verts[<span class="cpp-number">2</span>] = verticies[indicies].m_vec3Translation;<br>		m_pQTree-&gt;addPoly(newPoly);<br>	}<br><br>	<span class="cpp-comment">// Finally lets clean up the memory</span><br>	<span class="cpp-keyword">delete</span> [] fileAsText;<br>	<br>	<span class="cpp-comment">// Everything went great</span><br>	<span class="cpp-keyword">return</span> MPERR_OK;<br>}<br><br><br></pre></div><!–ENDSCRIPT–><br><br>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.<br><br>Matt Hughson
__________________________________[ Website ] [ Résumé ] [ [email=contact[at]matthughson[dot]com]Contact[/email] ][ Have I been Helpful? Hook me up! ]
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....
.
Need the plane from 3 points try this function

D3DXPLANE* WINAPI D3DXPlaneFromPoints
( D3DXPLANE *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2,
CONST D3DXVECTOR3 *pV3);
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!
.
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
Can you give some explanation and/or code showing OptimizeInplace() usage?
Thanks...
.

This topic is closed to new replies.

Advertisement