In my program I have an input and an output. The input is a 2D position that can range from (0,0) to (240,360). My output is a 3D world generated in XNA.
However, I haven't been able to figure out how to translate the points from the 2D grid to the 3D. I want to be able to translate the points so that (0,0) results in XNA showing the point in the work at the top left corner of what the camera can see. Likewise, I want the point of (240,360) to appear in the bottom right corner of what the camera can see. The Z value will be zero (it'll change, but that's out of the scope of this question).
How can I figure out where the corners of my camera's vision is? Here's how I draw my objects in the 3D world.
Vector3 camPos = new Vector3(0.0f, 0.0f, 500.0f);
Matrix view = Matrix.CreateLookAt(camPos, Vector3.Zero, Vector3.Up);
Matrix proj = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, Graphi开发者_如何学运维csDevice.DisplayMode.AspectRatio, 1, 10000);
Matrix ballWorld = Matrix.Identity;
//rotate it so that it is always facing foward
ballWorld.Forward = direction;
ballWorld.Up = Vector3.Up;
ballWorld.Right = Vector3.Cross(direction, Vector3.Up);
foreach (SphereObject so in blobs) {
Matrix sphereWorld = ballWorld;
sphereWorld *= Matrix.CreateTranslation(so.Position);
sphereWorld *= Matrix.CreateScale(so.Scale);
so.SphereModel.Draw(sphereWorld, view, proj);
}
And here's where I get the points from the 2D plane and create the SphereObject
public void CreateNewBlob(System.Drawing.Point p) {
Random rand = new Random();
SphereObject so = new SphereObject(model, new Vector3(p.X, p.Y, 0));
so.SetColor(new Color((float)rand.NextDouble(), (float)rand.NextDouble(), (float)rand.NextDouble()));
blobs.Add(so);
}
Are you sure you don't want to use a orthographic projection?
What about mapping the 2D point onto the viewport, then unprojecting a ray from this point, and using it to find the farthest visible point on the ray based on the far clipping plane?
float farplane = 1000;
Matrix proj = Matrix.CreateLookAt(Vector3.Zero, Vector3.Forward, Vector3.Up);
Matrix view = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, this.GraphicsDevice.Viewport.AspectRatio, 1, farplane);
Vector2 Coord = new Vector2(10,10); //between 0,0 and 240,360
Coord.X = Coord.X * (GraphicsDevice.Viewport.Width / 240);
Coord.Y = Coord.Y * (GraphicsDevice.Viewport.Height / 360);
Ray r = ProjectRayFromPointOnScreen((int)Coord.X, (int)Coord.Y, proj, view);
Vector3 ballpos = r.Position + (r.Direction *= (farplane - 1)); //Move just inside the far plane so its not clipped by accident
public Ray ProjectRayFromPointOnScreen(int x, int y, Matrix ProjectionMatrix, Matrix ViewMatrix)
{
Vector3 nearsource = new Vector3(x, y, 0);
Vector3 farsource = new Vector3(x, y, 1);
/* The Unproject method: http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.viewport.unproject.aspx */
GraphicsDevice graphics = this.GraphicsDevice;
Vector3 startpoint = graphics.Viewport.Unproject(nearsource,
ProjectionMatrix,
ViewMatrix,
Matrix.Identity);
Vector3 endpoint = graphics.Viewport.Unproject(farsource,
ProjectionMatrix,
ViewMatrix,
Matrix.Identity);
Vector3 direction = endpoint - startpoint;
direction.Normalize();
Ray r = new Ray(startpoint, direction);
return r;
}
This appears to work, though im not sure exactly what effect you are trying to achieve in your app. Good luck!
精彩评论