I am trying to figure out how XNA is actually projecting a 3d world space coordinate to screen space.
I decompiled the MonoGame framework and copied the CreateLookAt und CreatePerspectiveFieldOfView methods of Matrix and multiplied thereafter 3 vectors like XNA does:
First multiply each position with world, then multiply resultig new vector4 with view and then the new resulting vector4 finally by projection.
public static Vector2<T> Project(Vector3<T> source, Matrix4x4<T> world, Matrix4x4<T> view, Matrix4x4<T> projection, int width, int height)
{
Vector4<T> worldPosition = world * new Vector4<T>(source.X.ParseToNumeric<T>(), source.Y.ParseToNumeric<T>(), source.Z.ParseToNumeric<T>(), 1);
Vector4<T> viewPosition = view * worldPosition;
Vector4<T> position = projection * viewPosition;
var X = position.X.ParseToNumeric<T>();
var Y = position.Y.ParseToNumeric<T>();
var Z = position.Z.ParseToNumeric<T>();
return new Vector2<T>((X / Z) + width / 2, (Y / Z) + height / 2);
}
Because (0,0,0) would be the center of the screen I added to the corresponding X and Y coordinates width and height divided by 2. Just because it made sense I divided finally the xy components by z.
I used following matrices:
basicEffect.World = Matrix.Identity;
basicEffect.View = Matrix.CreateLookAt(new Vector3(0, 0, 0), new Vector3(0, 0, 1), new Vector3(0, 1, 0));
basicEffect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 0.1f, 1000.0f);
And these points:
vertices[0] = new VertexPositionColor(new Vector3(0, 0, 2), Color.Red);
vertices[1] = new VertexPositionColor(new Vector3(1, 0, 2), Color.Red);
vertices[2] = new VertexPositionColor(new Vector3(0, 1, 2), Color.Red);
Do you know why this happens?