• Advertisement
Sign in to follow this  

Place a mesh over a terrain mesh

This topic is 4323 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

First of all sorry for my bad English, I'm Italian. I'm a very beginner with Directx. I try to make a very simple game engine. I try to do this with managed DirectX I have a mesh that represent a terrain and a mesh that represent a person. The mesh of the person can rotate and move in the space but I want that this mesh follow the terrain height. To do this I hope that the simple way was to use the Intersect method of the Mesh object (terrain) and use the Dist property to adjust the Y position of the person mesh, but I'm not able to make this work. Is this really the better way ? My terrain mesh have the follow world transformation :
_worldMatrix = Matrix.Scaling(_scale, _scale, _scale);
_worldMatrix *= Matrix.Translation(-_position);
_device.Transform.World = _worldMatrix;

where _scale = 1.0f; and _position = new Vector3(0.0f, -4570.0f, 0.0f); My person mesh (load from tiny.x) have this world transformation :
_worldMatrix = Matrix.Scaling(_scale, _scale, _scale);
_worldMatrix *= Matrix.RotationY( -m_fFacing );
_worldMatrix *= Matrix.Translation(-_position);
_device.Transform.World = _worldMatrix;

where _scale = 0.005f; and initial m_fFacing = 0.0f; and initial _position = new Vector3(0.0f, -20.0f, 0.0f); Ok, now reading some sample on the forum I create the method to calculate the distance from my person mesh and the terrain mesh :
float retVal = 0.0f;
IntersectInformation intersectInfo = new IntersectInformation();

//Get the inverted world matrix of the terrain mesh
Matrix terrainWorldInverted = Matrix.Invert(_terrain.WorldMatrix);
//Generate a new matrix
Matrix ray = _person.WorldMatrix * terrainWorldInverted;
//Set the origin of the ray
_rayOrigin = new Vector3(ray.M31, ray.M32, ray.M33);    // Why this ?
//Set the direction of the ray
_rayDirection = new Vector3(ray.M41, ray.M42, ray.M43); // Why this ?
//Test the intersection and return the distance
if (_terrain.MeshObject.Intersect(_rayOrigin, _rayDirection, out intersectInfo)){
	retVal = intersectInfo.Dist;
}else if (_terrain.MeshObject.Intersect(_rayOrigin, -_rayDirection, out intersectInfo)){
	retVal = intersectInfo.Dist;
}

But this don't work. I have some question about this function : 1) Is the ray origin correct ? Why this origin is not _position of the person mesh ? 2) Is the ray direction correct ? I think that this direction have to be new Vector3(0.0f, -1.0f, 0.0f) or not ? 3) When I have the correct distance how I can adjust the position of the person mesh ? I have just to apply a new Matrix.Translation(0.0f, retVal, 0.0f) to the world transformation of the person ? Please help me out, I'm very confused ! If this is not the right way to do this, please tell me the correct way. Many thanks. [Edited by - DanieleMig on April 21, 2006 6:17:25 AM]

Share this post


Link to post
Share on other sites
Advertisement
You might edit your post and put the code in [ source ][ /source ] or < pre >< /pre > tags (without the spaces). This will make your post easier to read, and people might be more likely to respond.

Share this post


Link to post
Share on other sites
Well, I can`t help you with those Intersection functions that you use, but I would like to advise you to consider changing the DirectX Mesh representation of the terrain to regular heightmap with Vertex/Index Buffers. There are plenty resources regarding heightmaps all over the net. And you`ll get a direct control over how your terrain is stored/manipulated/optimized/textured/LODed. Believe me, it takes just 1 afternoon to write the basic heightmap renderer (without any lighting/normals, Index Buffers).
EDIT: You see ? It took you 5 days and you`re still stuck at the same problem. With heightmap (that would take you just one afternoon to write), it would already be solved long ago.

If you had your terrain as a regular heightmap, your problem could be solved like this (as I did it long time ago):
1. Heightmap has a resolution of RxR vertices. Spacing between them is, say, 10.0f.
2. At any time you know real X,Z position of your character (point P). According to this position you can find out on which triangle you are standing (X/Spacing gives you Column of the heightmap, Z/Spacing gives you Row of the Heightmap). Deciding whether it`s the right or left triangle of that quad should be easy.
3. Since you know the triangle over which you`re staying, you also know all of its 3 coordinates (A,B,C). To find out the Y-pos of the position, we must first calculate the YPos of the point Q1 that would be on the edge of given triangle (either top or bottom - depending on whether it`s left or right triangle of the quad) but with same Xpos.
Let`s consider (as an example), that our point P is on left triangle of the quad with points A,B,C where AC is hypothenus. Then DeltaY1 = B.ypos-C.ypos; Pct1 = Distance (B,Q1) / Distance (B,C); Q1.ypos = B.ypos + Pct1 * DeltaY1.
So, with this calculation we received the Ypos of the point P, IF the ypos of point A and B would be the same. Since, this is not generaly the case, we must make the same calculations for point Q2 that would be on edge BA.
So: DeltaY2 = B.ypos-A.ypos; Pct2 = Distance (B,Q2) / Distance (B,A); Q2.ypos = B.ypos + Pct2 * DeltaY2.

Now, the Y-position of your point P is : P.ypos = B.ypos + (Q1.ypos - B.ypos) + (Q2.ypos - B.ypos)

Now, I might have missed some absolute values or stuff like that, but that`s easy to debug when you`ll have all your points in Watch window. Simply, we must first take into account the slope of BC and then the slope of BA by percentage of distance of point Q1/Q2 on given edge. Just draw it on paper, and you`ll see it immediatelly.

Share this post


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

  • Advertisement