Draw objects on Terrain

I would like to allow my player to draw a road between two points on my (height mapped) terrain.

Can thoughts on how one might go about that? I was thinking a press and drag where the road would dynamically update till you released, but I have no idea how I would draw the road when I had that information (start point, end point) on a height mapped terrain.

Any suggestions would be greatly appreciated,
Thanks,
~Eric

On a unrelated note I saw your signature “~Eric” and thought it was weird a moderator was asking this question, then I realized it was another Eric :smile:

What you can do is split your line into smaller segments and read the height on the terrain for each point on the line and set the point’s y coordinate to that height. The size of the segments might depend on your terrain size and resolution.

I would use beizer curves. Calculate the width of that curve then apply a gradient accross the terrain and fill each segment that way. You can even calculate a bit further out and smooth the terrain back into the road way. Finally, I would take the same beizer and raise it up a hair and build the geometry for the roadway, so that you get the road texture on it, perhaps build the side of the road with it. At this point, you have enough data to build railings and alot of other things.

The only thing that the beizer would not give you is bank. You would calculate that over the course of a certain number of angles. The bigger the angle between a few points, the greater the bank. So even this can be given.

And yep, there is a Asset in the Asset Store that does this in the Editor, not at runtime.

Thanks BigMisterB,
I have been working on an algorithm to get the best route over a terrain and I will use your suggestions to draw a road over it.

Hey guys,
I have that curve (or path) through the terrain, and now I would like to draw the road. I have been looking around and it seems that the best way to do this is to create a new mesh for my road and apply the texture. I have created this class for when I want to create a new road based on such a path…

public class RailroadSegment : MonoBehaviour {
 
   Vector3[] mPath;
   Mesh      mMesh;
   Material  mMat;
   
   void setPath(Vector3 [] path)
   {
      mPath = path;
      
      Vector3[] newVertices;
      Vector2[] newUV;
      int[] newTriangles;
      
      // How do I fill the newVertices, new UV, and newTriangles?

      mMesh = new Mesh();
      GetComponent<MeshFilter>().mesh = mMesh;
      mesh.vertices = newVertices;
      mesh.uv = newUV;
      mesh.triangles = newTriangles;

   }
}

Assuming the width of my “road” is about 1.5 meters (I think a world unit is 1 meter on the terrain), and I already have the texture I want applied to mMat… how would I fill the newVertices, newUV, and newTriangles variables to make this look correct? My brain started build up a triangle strip based on the passed in path, but the math seemed complicated and maybe too expensive?

Any help would be great! :smile:

~Eric

If you’re trying to build triangle strips for performance, you don’t have to worry about that. Just build triangles, and call Mesh.Optimize, it internally converts your triangles to triangle strips. Also I wouldn’t worry about the performance of the mesh building, it’s not something that you’ll do every frame, you will do it only when an update on the mesh data is needed.

After a full day of trial and error setting up the mesh, I finally got it. It involved some cross products, a few loops, and sorting out how to define the triangles, but I got it.

You can see the final result here: http://www.blog.niugnepsoftware.com/?p=13

Thanks for everyone’s help in the matter.

And,did you get the terrain deformation?

I am not deforming the terrain, no. I am not sure I want to… but if I did, do you have suggestions on how to go about that?

You would need to access the terrain’s TerrainData object and move from there. It’s rather complex though, it involves knowing the percentage across the terrain for each spot and quite a few other things. Learning it would be a great benefit to you though.

So after doing all my math, I would just call setHeights? Seems reasonable…

yep, its just each “height” is between 0 and 1, and is scaled by the vertical scale of the terrain. So you do “A LOT” of math