# How to make a ramp on terrain

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

## Recommended Posts

Hello all.
Im trying to make ramps on my terrain, so units and stuff can travel up cliffs.
I have 4 points of the ramp these are the two heigh location on the cliff
and the other to are the low points marking the ramps location on the terrain.

My question is using the four points how would I go about finding all the other vertices that fit within the four selected vertices
and adjust there height to follow a gradient between the heigh points and the low points like a ramp say a 45`

so far I have is the four triangles I just add some height to see thier locations for now.
Any Help would be good thanks.

//Code
[source]
DWORD indexlowpt1 = IX.pSourceindices[lowfaceindex1 * 3];
DWORD indexlowpt2 = IX.pSourceindices[lowfaceindex2 * 3];
//RT = VB.pSourceVertices[index].pos;//(pSourceVertices[index].pos + pSourceVertices[index].pos + pSourceVertices[index].pos) / 3);
DWORD t1 = 0;
DWORD t2 = 0;
//rase the triangle
float h = 1000.0f;
//1 triangle
t1 = IX.pSourceindices[(heighfaceindex1 * 3) + 1];
t2 = IX.pSourceindices[(heighfaceindex1 * 3) + 2];
VB.pSourceVertices[indexheighpt1].pos.y += h;
VB.pSourceVertices[t1].pos.y += h;
VB.pSourceVertices[t2].pos.y += h;

//2 triangle
t1 = IX.pSourceindices[(heighfaceindex2 * 3) + 1];
t2 = IX.pSourceindices[(heighfaceindex2 * 3) + 2];
VB.pSourceVertices[indexheighpt2].pos.y += h;
VB.pSourceVertices[t1].pos.y += h;
VB.pSourceVertices[t2].pos.y += h;

//3 triangle low part
t1 = IX.pSourceindices[(lowfaceindex1 * 3) + 1];
t2 = IX.pSourceindices[(lowfaceindex1 * 3) + 2];
VB.pSourceVertices[indexlowpt1].pos.y = h;
VB.pSourceVertices[t1].pos.y += h;
VB.pSourceVertices[t2].pos.y += h;

//4 triangle low part
t1 = IX.pSourceindices[(lowfaceindex2 * 3) + 1];
t2 = IX.pSourceindices[(lowfaceindex2 * 3) + 2];
VB.pSourceVertices[indexlowpt2].pos.y = h;
VB.pSourceVertices[t1].pos.y += h;
VB.pSourceVertices[t2].pos.y += h;

[/source]

##### Share on other sites
Let me ask you first this: How do you generate terrain? Do you generate it from a height-map?

##### Share on other sites
It can be a height map or a mesh grid

##### Share on other sites
First thing you want to do is to detect which terrain vertices are part of your ramp (by looking from above, if you draw a rectangle that would be your ramp, you need to identify which vertices are affected by your ramp by being in that rectangle and outside, immediately near it. Then you would go through each of them, take their coordinates as input and write a function that returns their height. This function would pickup the ramp's rectangle "corners" to say so and then interpolate across it to find the heights of the vertices. I hope it makes sense.

##### Share on other sites
Is there some way I can find the other vertices based on the four bounding indices I already have.
The mesh is layed out as a grid, or will I have to search the whole vetex array(hope not).
I've tryed google but cant seem to find anything.(Don't know what to search for really).

##### Share on other sites
If you look from "above" the mesh is a grid and should stay like so, as you only change their heights, not their horizontal positions. Looking at this grid from the above, if you draw a rectangle you should be able to find the points using simple trigonometry. You can search the entire array, is not that big, you have to really swap through it once. If after that you find out it runs too slow, you can think of optimizing things, but only then.

##### Share on other sites
Ok. Thank you for your idea here it is I think.

First I find all selected vertices within the polygon boundary,
I then use the 2 top points(the top of the cliff) and the ramps starting point(the tip of the ramp)
to calcualate the angle of the slop, I now create a direction vector that points up the ramp normalized(UpRampDir1)
(UpRampDir1) is used to calculate the line the vertex makes with the ramps direction. I then use this line to create
a distance that is then used to multiply the angle with which will give me the height for this vertex in the right direction.

Well I have it creating ramps based on the four user inputs(mouse selection points).
where it create ramps in all direction but one there is a spot on the terrain based on maybe its direction its faceing
that the ramp always is to steep(I think I can live with that as the editor also has lowering and rising modifiers).

I do have a question but. Is there a way to select a rectangle of verteices based on the four starting indices
(like a look up as you would do with a cell based grid). It is just used in the editor and thats not real time
and I can't see any real slowing down yet, but the map has only 32000 vertices, Im going to have maps that are also 64000 , 128000 not tested yet.

[source]

std::vector<D3DXVECTOR3> boundingpolly;
//1 2 heigh points
//*----*
//| |
//*----*
//4 3 order
//2 1 low points
//build the polygon boundary
boundingpolly.push_back(VB.pSourceVertices[indexheighpt1].pos);
boundingpolly.push_back(VB.pSourceVertices[indexheighpt2].pos);
boundingpolly.push_back(VB.pSourceVertices[indexlowpt1].pos);
boundingpolly.push_back(VB.pSourceVertices[indexlowpt2].pos);
boundingpolly.push_back(VB.pSourceVertices[indexheighpt1].pos);//rap back to start

//we need the 2 direction vectors going up the ramp from the bounding polygon
D3DXVECTOR3 UpRampDir1 = boundingpolly[3] - boundingpolly[0];//takes lowpt2 and heigh pt1 facing down
D3DXVECTOR3 UpRampDir2 = boundingpolly[1] - boundingpolly[2];//takes lowpt1 and heigh pt2

D3DXVECTOR3 RidgeLine = boundingpolly[3] - boundingpolly[2];//2 low side of ramp points facing left

D3DXVec3Normalize(&RidgeLine,
&RidgeLine);

D3DXVec3Normalize(&UpRampDir1,
&UpRampDir1);

D3DXVec3Normalize(&UpRampDir2,
&UpRampDir2);

DWORD amtv = TestMesh->GetVertexCount();

//we need the angle from low point2 to top point 0
//this will be our slope for the ramp
//get the length of the rise(height)
float rise = fabs(boundingpolly[0].y - boundingpolly[3].y);//D3DXVec3Length(&tn);//top poly point
if(rise == 0)
rise = 1.0f;

//get the run now
float run = fabs(boundingpolly[0].x - boundingpolly[3].x);//D3DXVec3Length(&tn);//last selected ramp point low 2
if(run == 0)
run = 1.0f;

float angle = atan(rise/run);//sin((35.0f));
if(angle == 0)
angle = 1;

//I would Like to fix this so I could do a look up based on the 4 starting index we have art the start
//for all vertices see if any are with in the selected four points
for(DWORD ctr = 0; ctr < amtv; ctr++)
{
//see if this vert is in the polygon
int val = PointInPoly(boundingpolly,//std::vector<D3DXVECTOR3> &vertices,
&VB.pSourceVertices[ctr].pos);//D3DXVECTOR3 *point)
if(val == 1)
{
D3DXVECTOR3 p1 = boundingpolly[2];
D3DXVECTOR3 p2 = boundingpolly[3];//second low point
D3DXVECTOR3 p3 = UpRampDir1 * 100000.0f;
D3DXVECTOR3 p4 = VB.pSourceVertices[ctr].pos;//we need the ramp direction up to create the lines end point
//get the distace of the vertex from the ridge line
D3DXVECTOR3 rl = Lineintercept(p1, p2, p3, p4);//low point now

D3DXVECTOR3 totarget = VB.pSourceVertices[ctr].pos - rl;//
//totarget.y =0.0;
//D3DXVec3Normalize(&totarget,
// &totarget);
float dist = D3DXVec3Length(&totarget);

float height = angle * dist;//totarget.y *(D3DXVec3Length(&UpRampDir1) -( D3DXVec3Length(&UpRampDir1) - dist));

//if heigh is grater then the top lower it
if(height > boundingpolly[0].y)
height = boundingpolly[0].y;

VB.pSourceVertices[ctr].pos.y = height;
//ok in side the bounds save it's index
//indicesinbounds.push_back(ctr);
}

}//end all vertices

//--------------------------------------------------------------------------------------------------------
//this will return 1 if the 3d point is inside of the polygon on the same plane
//based on the PNPOLY algo
//the return value is
//---------------------------------------------------------------------------------------------------------
int PointInPoly(std::vector<D3DXVECTOR3> &vertices, D3DXVECTOR3 *point)
{
int i, j, c = 0;
for (i = 0, j = vertices.size() - 1; i < vertices.size(); j = i++)
{
if( ((vertices.z > point->z) != (vertices[j].z > point->z)) &&
(point->x < (vertices[j].x - vertices.x) * (point->z - vertices.z) / (vertices[j].z - vertices.z) + vertices.x) )
c = !c;
}
return c;

}

//----------------------------------------------------------------------------------------------
//this is a 2d intecept
//only using x z, y will be nothing
//----------------------------------------------------------------------------------------------
D3DXVECTOR3 Lineintercept( D3DXVECTOR3 &p1, D3DXVECTOR3 &p2, D3DXVECTOR3 &p3, D3DXVECTOR3 &p4)
{
D3DXVECTOR3 r(1.0f, 0.0f, 1.0f);

//p1-p2 is the first edge.
//p3-p4 is the second edge.

float x1 = p1.x, x2 = p2.x, x3 = p3.x, x4 = p4.x;
float z1 = p1.z, z2 = p2.z, z3 = p3.z, z4 = p4.z;

float d = (x1 - x2) * (z3 - z4) - (z1 - z2) * (x3 - x4);
// If d is zero, there is no intersection
if (d == 0)
return r;

float pre = (x1*z2 - z1*x2), pos = (x3*z4 - z3*x4);
float x = ( pre * (x3 - x4) - (x1 - x2) * pos ) / d;
float z = ( pre * (z3 - z4) - (z1 - z2) * pos ) / d;

/*// Check if the x and y coordinates are within both lines
if ( x < min(x1, x2) || x > max(x1, x2) ||
x < min(x3, x4) || x > max(x3, x4) ) return NULL;
if ( y < min(y1, y2) || y > max(y1, y2) ||
y < min(y3, y4) || y > max(y3, y4) ) return NULL;

cout << "Inter X : " << x << endl;
cout << "Inter Y : " << y << endl;

// Return the point of intersection
r->x = x;
r->y = y;
*/
r.x = x;
r.y = 0.0f;
r.z = z;
return r;
}//end Lineintercept
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////

[/source]

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 19
• 36
• 9
• 16
• 75