Jump to content
  • Advertisement
Sign in to follow this  
R3v3n

Problem with moving model over terrain [terrain picking]

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

Hi all,
im writing a engine for my RTS game and i have problem with terrain picking. When i pick my model and click on terrain my model goes not in place when i have click. I found solution on this forum still dosent work.

This is my code for moving model in direct spot:
public float GetExactHeightAt(float xCoord, float zCoord)
{
bool invalid = xCoord < 0;
invalid |= zCoord < 0;
invalid |= xCoord >= heights.GetLength(0) - 1;
invalid |= zCoord >= heights.GetLength(1) - 1;
if (invalid)
return 10;

int xLower = (int)xCoord;
int xHigher = xLower + 1;
float xRelative = (xCoord - xLower) / ((float)xHigher - (float)xLower);
int zLower = (int)zCoord;
int zHigher = zLower + 1;
float zRelative = (zCoord - zLower) / ((float)zHigher - (float)zLower);
float heightLxLz = heights[xLower, zLower];
float heightLxHz = heights[xLower, zHigher];
float heightHxLz = heights[xHigher, zLower];
float heightHxHz = heights[xHigher, zHigher];
bool cameraAboveLowerTriangle = (xRelative + zRelative < 1);
float finalHeight;
if (cameraAboveLowerTriangle)
{
finalHeight = heightLxLz;
finalHeight += zRelative * (heightLxHz - heightLxLz);
finalHeight += xRelative * (heightHxLz - heightLxLz);
}
else
{
finalHeight = heightHxHz;
finalHeight += (1.0f - zRelative) * (heightHxLz - heightHxHz);
finalHeight += (1.0f - xRelative) * (heightLxHz - heightHxHz);
}
return finalHeight;
}


public Ray LinearSearch(Ray ray)
{
ray.Direction /= 50.0f;
Vector3 nextPoint = ray.Position + ray.Direction;
float heightAtNextPoint = GetExactHeightAt(nextPoint.X, nextPoint.Z);
while (heightAtNextPoint < nextPoint.Y)
{
ray.Position = nextPoint;
nextPoint = ray.Position + ray.Direction;
heightAtNextPoint = GetExactHeightAt(nextPoint.X, -nextPoint.Z);
}
return ray;
}


public Vector3 BinarySearch(Ray ray)
{
float accuracy = 0.01f;
float heightAtStartingPoint = GetExactHeightAt(ray.Position.X, -ray.Position.Z);
float currentError = ray.Position.Y - heightAtStartingPoint;
int counter = 0;
while (currentError > accuracy)
{
ray.Direction /= 2.0f;
Vector3 nextPoint = ray.Position + ray.Direction;
float heightAtNextPoint = GetExactHeightAt(nextPoint.X, -nextPoint.Z);
if (nextPoint.Y > heightAtNextPoint)
{
ray.Position = nextPoint;
currentError = ray.Position.Y - heightAtNextPoint;
}
if (counter++ == 1000) break;
}
return ray.Position;
}


public Ray CalculateCursorRayOn3DWorld(Matrix view,Matrix projection)
{
Vector3 nearSource = new Vector3(Position, 0f);
Vector3 farSource = new Vector3(Position, 1f);
Vector3 nearPoint = graphics.Viewport.Unproject(nearSource, projection, view, Matrix.Identity);
Vector3 farPoint = graphics.Viewport.Unproject(farSource, projection, view, Matrix.Identity);
Vector3 direction = farPoint - nearPoint;
//direction.Normalize();
return new Ray(nearPoint,direction);
}
public Ray ClipRay(Ray ray, float highest, float lowest)
{
Vector3 oldStartPoint = ray.Position;
float factorH = -(oldStartPoint.Y - highest) / ray.Direction.Y;
Vector3 pointA = oldStartPoint + factorH * ray.Direction;
float factorL = -(oldStartPoint.Y - lowest) / ray.Direction.Y;
Vector3 pointB = oldStartPoint + factorL * ray.Direction;
Vector3 newDirection = pointB - pointA;
return new Ray(pointA, newDirection);
}


This is my terrain code:
public Terrain(Texture2D map, Texture2D rTexture, Texture2D bTexture, Texture2D gTexture, Texture2D weightMap, float cellSize, float height, Texture2D baseTexture, float textureTiling, Vector3 lightDirection, GraphicsDevice graphicsDevice, ContentManager content)
{
this.map = map;
this.width = map.Width;
this.length = map.Height;
this.height = height;
this.cellSize = cellSize;
this.graphicsDevice = graphicsDevice;
this.baseTexture = baseTexture;
this.textureTiling = textureTiling;
this.lightDirection = lightDirection;
this.effect = content.Load<Effect>("Effects/TerrainEffect");
this.detailTexture = content.Load<Texture2D>("Textures/Terrain/noise");
this.rTexture = rTexture;
this.bTexture = bTexture;
this.gTexture = gTexture;
this.weightMap = weightMap;
this.detailDistance = 2500;
this.detailTextureTiling = 100;
nVertices = width * length;
nIndices = (width - 1) * (length - 1) * 6;
vertexBuffer = new VertexBuffer(graphicsDevice, typeof(VertexPositionNormalTexture), nVertices, BufferUsage.WriteOnly);
indexBuffer = new IndexBuffer(graphicsDevice, IndexElementSize.ThirtyTwoBits, nIndices, BufferUsage.WriteOnly);
GetHeights();
CreateVertices();
CreateIndices();
GetNormals();
vertexBuffer.SetData<VertexPositionNormalTexture>(vertices);
indexBuffer.SetData<int>(indices);
}
private void GetHeights()
{
Color[] heightMapData = new Color[width * length];
map.GetData<Color>(heightMapData);
heights = new float[width, length];
for(int x = 0; x < width; x++)
for (int y = 0; y < length; y++)
{
float amt = heightMapData[y * width + x].R;
amt /= 255.0f;
heights[x, y] = amt * height;
}
}
private void CreateVertices()
{
vertices = new VertexPositionNormalTexture[nVertices];
Vector3 offsetToCenter = -new Vector3(((float)width/2f)*cellSize,0,((float)length/2f)*cellSize);
for (int x = 0; x < width; x++)
for (int y = 0; y < length; y++)
{
this.position = new Vector3(x * cellSize, heights[x, y], y * cellSize) +offsetToCenter;
Vector2 uv = new Vector2((float)x / width, (float)y / length);
vertices[y * width + x] = new VertexPositionNormalTexture(position, new Vector3(0,0,0), uv);
}


}
private void CreateIndices()
{
indices = new int[nIndices];
int i = 0;
for(int x=0;x<width-1;x++)
for (int z = 0; z < length - 1; z++)
{
int upperLeft = z * width + x;
int upperRight = upperLeft + 1;
int lowerLeft = upperLeft + width;
int lowerRight = lowerLeft + 1;
indices[i++] = upperLeft;
indices[i++] = upperRight;
indices[i++] = lowerLeft;
indices[i++] = lowerLeft;
indices[i++] = upperRight;
indices[i++] = lowerRight;
}
}
{
private void GetNormals()
{

for (int i = 0; i < nIndices; i += 3)
{
Vector3 v1 = vertices[indices].Position;
Vector3 v2 = vertices[indices[i+1]].Position;
Vector3 v3 = vertices[indices[i+2]].Position;
Vector3 normal = Vector3.Cross(v1 - v3, v2 - v3);
normal.Normalize();
vertices[indices].Normal += normal;
vertices[indices[i+1]].Normal += normal;
vertices[indices[i+2]].Normal += normal;
}
for (int i = 0; i < nVertices; i++)
vertices.Normal.Normalize();

}
public void Draw(Matrix view,Matrix projection)
{
RasterizerState rs = new RasterizerState();
rs.FillMode = FillMode.WireFrame;
graphicsDevice.RasterizerState = rs;

effect.Parameters["View"].SetValue(view);
effect.Parameters["Projection"].SetValue(projection);
effect.Parameters["World"].SetValue(Matrix.Identity);
effect.Parameters["RTexture"].SetValue(bTexture);
effect.Parameters["GTexture"].SetValue(rTexture);
effect.Parameters["BTexture"].SetValue(baseTexture);
effect.Parameters["WeightMap"].SetValue(weightMap);
effect.Parameters["BaseTexture"].SetValue(gTexture);
effect.Parameters["TextureTiling"].SetValue(textureTiling);
effect.Parameters["LightDirection"].SetValue(lightDirection);
effect.Parameters["DetailTexture"].SetValue(detailTexture);
effect.Parameters["DetailDistance"].SetValue(detailDistance);
effect.Parameters["DetailTextureTiling"].SetValue(detailTextureTiling);
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
graphicsDevice.SetVertexBuffer(vertexBuffer);
graphicsDevice.Indices = indexBuffer;
graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertices.Length, 0, nIndices/3);

}
graphicsDevice.SetVertexBuffer(null);
graphicsDevice.Indices = null;
}
}


Method GetExactHeightAt always return 10, so i repleced it with the method located in sample HeightmapCollisionSample_4_0, but that change nothing. Looks like the Ray give bad position to method GetExactHeightAt. I will be grateful for help.

Share this post


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

  • Advertisement
×

Important Information

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

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!