Jump to content
  • Advertisement
Sign in to follow this  
winifix

Struggling with WorldToScreen in C#

This topic is 612 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 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
Advertisement

I think you forgot to set the ViewMatrix

SlimDX.Matrix.LookAtRH(eye, lookAt, up);

probably should be

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

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




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
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!