Hello. I want to draw some 2D user interface stuff where some of my 3D objects are positioned.
3D camera stuff is beyond me, but I did find some code here: Transforming a 3D position to a screen (2D) position
This ALMOST works, as you can see from the screenshots. The red bar should be drawn on the center of the two characters (see the blue lines I drew to show where). I thought it might have something to do with Orthographic projection, but I tried changing it to Perspective and the results were similar.
Here’s that function to get a Point from a 3d Position
/// <summary> /// Transforming a 3D position to a 2D position /// </summary> /// <param name="vec">3D Position</param> /// <param name="viewMatrix">View Matrix</param> /// <param name="projMatrix">Projection Matrix</param> /// <param name="Width">Screen Width</param> /// <param name="Height">Screen Height</param> /// <returns></returns> public Point GetProjectPoint(Vector3 vec)//, Matrix viewMatrix, Matrix projMatrix, int Width, int Height) { int width = ScreenWidth; int height = ScreenHeight; Matrix mat = Matrix.Identity * View * Projection; Vector4 v4 = Vector4.Transform(vec, mat); return new Point((int)((v4.X / v4.W + 1) * (width / 2)), (int)((1 - v4.Y / v4.W) * (height / 2))); }
//Properties public Matrix Projection { get; protected set; }
public float Zoom { get { return zoom; } set { zoom = value; UpdateLookAt(); //any time the position changes, it calls update look at References.textureEffect.Parameters["MatrixTransform"].SetValue(View * Projection); // References.flatEffect.Parameters["MatrixTransform"].SetValue(ViewFlat * Projection); } } public Vector3 Position { get { return cameraPosition; } set { cameraPosition = value; UpdateLookAt(); //any time the position changes, it calls update look at cameraFacing = CameraFacing(); References.textureEffect.Parameters["MatrixTransform"].SetValue(View * Projection); // References.flatEffect.Parameters["MatrixTransform"].SetValue(ViewFlat * Projection); if (Ortho) ThreeDRoom.UpdateCameraRotation(); } } public Vector3 Rotation { get { return cameraRotation; } set { cameraRotation = value; UpdateLookAt(); //any time the rotation changes, it calls update look at References.textureEffect.Parameters["MatrixTransform"].SetValue(View * Projection); if (Ortho) ThreeDRoom.UpdateCameraRotation(); } } public Matrix View //Defines entire view of camera. Where it's located, it's target and the up vector. Essentially creating a transform with forward, up, and relative camera position. { //view and projection needed for camera's orientation in 3D space. get { return Matrix.CreateLookAt(cameraPosition, cameraLookAt, Vector3.Up) * Matrix.CreateScale(Zoom,Zoom,Zoom); } }
//Constructor public _3DCamera(Game game, Vector3 position, Vector3 rotation, float speed) // : base(game) { cameraSpeed = speed; //set up projection matrix //Orthographic project = 2D, Perspective = 3D if(Ortho) { Projection = Matrix.CreateOrthographic(10, 10, 0.0f, 4000.0f); } else { Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, game.GraphicsDevice.Viewport.AspectRatio, 0.05f, 4000.0f); } //Set camera position and rotation MoveTo(position, rotation); prevMouseState = Mouse.GetState(); }