# RayPicking Landscape

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

## Recommended Posts

Hi all! I've got my Pick code working fine to determine whether or not a mesh has been selected from the viewport. The problem I have is trying to trace a ray when the view matrix changes. Ie. I can trace a ray to the landscape fine when the camera is looking at the origin in worldspace (0,0,0) but not when it is looking anywhere else. I've had a big search around the net, but cannot find an answer, and I'm sure it comes down to my bad maths (matrix) skills ! Here's my Pick code. The first part does the mesh picking, and if that fails, it trys to find the x,z coords of the ray where y=0 (for the landscape) I'm using C# and Directx9
private void Pick(int x, int y)
{

Vector3 s = Vector3.Unproject(new Vector3(x, y, 0),
device.Viewport,
device.Transform.Projection,
device.Transform.View,
Matrix.Translation(player1.pos));

Vector3 d = Vector3.Unproject(new Vector3(x, y, 1),
device.Viewport,
device.Transform.Projection,
device.Transform.View,
Matrix.Translation(player1.pos));

Vector3 rPosition = s;
Vector3 rDirection = Vector3.Normalize(d-s);

bIsMeshHit = mesh.Intersect(rPosition, rDirection, out hitInfo);

if (bIsMeshHit)
{
Console.WriteLine(hitInfo);
}
else
{
s = Vector3.Unproject(new Vector3(x, y, 0),
device.Viewport,
device.Transform.Projection,
device.Transform.View,
device.Transform.World);

d = Vector3.Unproject(new Vector3(x, y, 1),
device.Viewport,
device.Transform.Projection,
device.Transform.View,
device.Transform.World);

rPosition = s;
rDirection = Vector3.Normalize(d-s);

//Do landscape...
Vector3 normCamPos = cp_Camera.cp_Position;
Vector3 CamDist = cp_Camera.cp_LookAt - cp_Camera.cp_Position;

normCamPos.Normalize();

float m;
float xd;
float zd;

m = - (normCamPos.Y / rDirection.Y) ;

xd = (normCamPos.X + (m * rDirection.X)) * CamDist.Length();
zd = (normCamPos.Z + (m * rDirection.Z)) * CamDist.Length();

Console.WriteLine("m: " + m);
Console.WriteLine("xd: " + xd);
Console.WriteLine("zd: " + zd);

player1.WalkTo(new Vector3(xd, 0, zd));
}
}


I would be extremely grateful if someone could point out where I am going wrong. As a side note, I was wondering whether a landscape built out of vertex/index buffers is a good way to go for a clickable-terrian based engine, or should I just use a mesh for the landscape ? Much thanks in advance!

##### Share on other sites
Solved.

I found out what I was doing was normalising the camera position, then multiplying the outputed x value by the distance the camera was from the source.

Looking back at it, I don't know what sparked me to do it that way, as it works fine just using the camera position itself as an offset, without having to mess around with normalising or multiplying anything!

I hope this has helped a few people out with their picking code :)

edit:
(here's the changed code...)

//Do landscape...Vector3 normCamPos = cp_Camera.cp_Position;Vector3 CamDist = cp_Camera.cp_LookAt - cp_Camera.cp_Position;float m;float xd;float zd;m = - (normCamPos.Y / rDirection.Y) ;xd = (normCamPos.X + (m * rDirection.X));zd = (normCamPos.Z + (m * rDirection.Z));

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 13
• 9
• 9
• 15
• 14
• ### Forum Statistics

• Total Topics
634070
• Total Posts
3015330
×