Sign in to follow this  
winifix

Struggling with WorldToScreen in C#

Recommended Posts

Hi Fellow Programmers,

I am hitting my head against a wall trying to convert the below c++ method to c# using SlimDX, any help would be appreciated.

Vector2 World::WorldToScreen (const Vector3& Position, float AspectRatio) noexcept
{
    D3DXMATRIX Projection;
    D3DXMATRIX View;
    D3DXMATRIX World;

    D3DXMatrixPerspectiveFovRH(&Projection, GetFieldOfView() * 0.6f, AspectRatio, 0.0f, 1.0f);

    auto CameraPosition = GetCameraPosition();
    auto Matrix = GetCameraMatrix();

    D3DXVECTOR3 Eye (CameraPosition.X, CameraPosition.Y, CameraPosition.Z);
    D3DXVECTOR3 LookAt (CameraPosition.X + Matrix[0][0], CameraPosition.Y + Matrix[0][1], CameraPosition.Z + Matrix[0][2]);
    D3DXVECTOR3 Up (0.0f, 0.0f, 1.0f);

    D3DXMatrixLookAtRH(&View, &Eye, &LookAt, &Up);
    D3DXMatrixIdentity(&World);

    D3DVIEWPORT9 Viewport = { 0, 0, 1, 1, 0, 0 };
    D3DXVECTOR3 WorldPosition (Position.X, Position.Y, Position.Z);

    D3DXVECTOR3 ScreenPosition;
    D3DXVec3Project(&ScreenPosition, &WorldPosition, &Viewport, &Projection, &View, &World);

    return { ScreenPosition.x, ScreenPosition.y };
}

Currently, I have managed to port the below.

public static Vector2 WorldToScreen(float x, float y, float z)
{
	//D3DXMATRIX Projection;
	//D3DXMATRIX View;
	//D3DXMATRIX World;

	SlimDX.Matrix Projection;
	SlimDX.Matrix View;
	SlimDX.Matrix World;

	var aspectRatio = (float)WindowHelper.WindowWidth / (float)WindowHelper.WindowHeight;

	//D3DXMatrixPerspectiveFovRH(&Projection, GetFieldOfView() * 0.6f, AspectRatio, 0.0f, 1.0f);
	Projection = SlimDX.Matrix.PerspectiveFovRH(FOV * 0.6f, aspectRatio, 0f, 0f);

	//D3DXVECTOR3 Eye (CameraPosition.X, CameraPosition.Y, CameraPosition.Z);
	//D3DXVECTOR3 LookAt (CameraPosition.X + Matrix[0][0], CameraPosition.Y + Matrix[0][1], CameraPosition.Z + Matrix[0][2]);
	//D3DXVECTOR3 Up (0.0f, 0.0f, 1.0f);

	Vector3 eye = new Vector3(X, Y, Z);
	Vector3 lookAt = new Vector3(X + Matrix[0, 0], Y + Matrix[0, 1], Z + Matrix[0, 2]);
	Vector3 up = new Vector3(0f, 0f, 1f);

	//D3DXMatrixLookAtRH(&View, &Eye, &LookAt, &Up);
	//D3DXMatrixIdentity(&World);

	SlimDX.Matrix.LookAtRH(eye, lookAt, up);
	World = SlimDX.Matrix.Identity;

	//D3DVIEWPORT9 Viewport = { 0, 0, 1, 1, 0, 0 };
	//D3DXVECTOR3 WorldPosition (Position.X, Position.Y, Position.Z);
	Viewport Viewport = new Viewport(0, 0, 1, 1, 0, 0);
	SlimDX.Vector3 WorldPosition = new Vector3(x, y, z);

	// D3DXVECTOR3 ScreenPosition;
	// D3DXVec3Project(&ScreenPosition, &WorldPosition, &Viewport, &Projection, &View, &World);

	SlimDX.Vector3 ScreenPosition = ????
	return new Vector2(ScreenPosition.X, ScreenPosition.Y);
}

What is the SlimDX equivalent of "D3DXVec3Project(&ScreenPosition, &WorldPosition, &Viewport, &Projection, &View, &World);"

or what alternative methods can be used keep in mind i am in 3rd person view with Camera behind player, not in 1st person view so the below method does not work

Vector2 WorldSpaceToScreenSpace(Vector3 worldSpacePos)
{
    Vector4 clipSpacePos = Vector4.Transform(new Vector4(worldSpacePos, 1.0f), viewProjMatrix);
    Vector2 screenSpacePos;
    screenSpacePos.x = (clipSpacePos.x / clipSpacePos.w) * 0.5f + 0.5f;
    screenSpacePos.y = 1.0f - ((clipSpacePos.y / clipSpacePos.w) * 0.5f + 0.5f);
    screenSpacePos.x *= viewPortWidth;
    screenSpacePos.y *= viewPortHeight;
    return screenSpacePos;
}

 

 

Edited by winifix

Share this post


Link to post
Share on other sites

thanks alot guys, got it mostly working

 

        public static Vector2 WorldToScreen(float x, float y, float z)
        {
            var Projection = Matrix.PerspectiveFovRH(FOV*0.6f, Aspect, NearClip, FarClip);

            var eye = new Vector3(X, Y, Z);
            var lookAt = new Vector3(X + Matrix[0, 0], Y + Matrix[0, 1], Z + Matrix[0, 2]);
            var up = new Vector3(0f, 0f, 1f);

            var View = Matrix.LookAtRH(eye, lookAt, up);
            var World = Matrix.Identity;

            var WorldPosition = new Vector3(x, y, z);

            var ScreenPosition = Vector3.Project(WorldPosition, 0f, 0f, 1920f, 1080f, NearClip, FarClip, World*View*Projection);
            return new Vector2(ScreenPosition.X, ScreenPosition.Y);
        }

its still not perfect - this is still my issue

https://www.youtube.com/watch?v=ApxjB6KRpPo


Below are the sample values input and output.
[20:58:00] Camera X: -6435.304
[20:58:00] Camera Y: 662.7703
[20:58:00] Camera Z: 392.2399
[20:58:00] Camera NearClip: 0.1
[20:58:00] Camera FarClip: 777
[20:58:00] Camera FOV: 1.570796
[20:58:00] X = 603.3526, Y = 632.2842

 

Edited by winifix

Share this post


Link to post
Share on other sites

Edit found the fix

 

public static Vector2 WorldToScreen(float x, float y, float z)
{
    var Projection = Matrix.PerspectiveFovRH(FOV * 0.5f, Aspect, NearClip, FarClip);

    var eye = new Vector3(X, Y, Z);
    var lookAt = new Vector3(X + Matrix[0, 0], Y + Matrix[0, 1], Z + Matrix[0, 2]);
    var up = new Vector3(0f, 0f, 1f);

    var View = Matrix.LookAtRH(eye, lookAt, up);
    var World = Matrix.Identity;

    var WorldPosition = new Vector3(x, y, z);

    var ScreenPosition = Vector3.Project(WorldPosition, 0f, 0f, WindowHelper.WindowWidth, WindowHelper.WindowHeight, NearClip, FarClip, World*View*Projection);
    return new Vector2(ScreenPosition.X, ScreenPosition.Y-20f);
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this