Jump to content
  • Advertisement
Sign in to follow this  
Heartt

RayPicking Landscape

This topic is 4876 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! 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 this post


Link to post
Share on other sites
Advertisement
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));

Share this post


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

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!