Game Development Community

Coverting world coord to screen coord with moving / rotating camera

by rwillis · in Torque X 2D · 02/07/2009 (9:34 am) · 1 replies

I've attached the camera to the player object and need to find a way to convert any location in the world to GUI coordinates even though the camera can (obviously) be rotated any way. The previous implementations of converting world to screen on this forum assume, unless i'm mistaken, that the camera has a rotation of zero and is at 0,0 in world space. Anyone come up with an implementation that can convert world to screen with a moving camera?

#1
02/07/2009 (8:51 pm)
I figured out a way to convert world coordinates to GUI coordinates when the camera is mounted to an object which can be rotated and is not always at position {0,0}:

public Vector2 ConvertPosFromWorldUnitsToGUIUnits(Vector2 worldPos)
        {
            float distanceFromCameraToWorldPos;
            float distanceXFromCameraToWorldPos;
            float worldXForGUI;
            float worldYForGUI;

            double angle;
            double angleOne;
            double angleTwo;
            
            float percentAcrossX;
            float percentAcrossY;

            distanceFromCameraToWorldPos = Vector2.Distance(worldPos, Camera.Position);
            distanceXFromCameraToWorldPos = Math.Abs(Camera.Position.X - worldPos.X);
            angleTwo = Math.Acos(distanceXFromCameraToWorldPos / distanceFromCameraToWorldPos);
  
            //Top Left Quad
            if (worldPos.X < Camera.Position.X && worldPos.Y < Camera.Position.Y)
            {
                angleOne = (360 - Camera.Rotation) * (Math.PI / 180);
                angle = angleOne + angleTwo;

                worldXForGUI = (float)Math.Cos(angle) * distanceFromCameraToWorldPos;
                worldYForGUI = (float)Math.Sin(angle) * distanceFromCameraToWorldPos;

                percentAcrossX = ((Camera.Extent.X / 2) - worldXForGUI) / Camera.Extent.X;
                percentAcrossY = ((Camera.Extent.Y / 2) - worldYForGUI) / Camera.Extent.Y;
            }
            //Bottom Left Quad
            else if (worldPos.X < Camera.Position.X && worldPos.Y >= Camera.Position.Y)
            {
                angleOne = Camera.Rotation * (Math.PI / 180);
                angle = angleOne + angleTwo;

                worldXForGUI = (float)Math.Cos(angle) * distanceFromCameraToWorldPos;
                worldYForGUI = (float)Math.Sin(angle) * distanceFromCameraToWorldPos;

                percentAcrossX = ((Camera.Extent.X / 2) - worldXForGUI) / Camera.Extent.X;
                percentAcrossY = ((Camera.Extent.Y / 2) + worldYForGUI) / Camera.Extent.Y;
            }
            //Top Right Quad
            else if (worldPos.X >= Camera.Position.X && worldPos.Y < Camera.Position.Y)
            {
                angleOne = Camera.Rotation * (Math.PI / 180);
                angle = angleOne + angleTwo;

                worldXForGUI = (float)Math.Cos(angle) * distanceFromCameraToWorldPos;
                worldYForGUI = (float)Math.Sin(angle) * distanceFromCameraToWorldPos;

                percentAcrossX = ((Camera.Extent.X / 2) + worldXForGUI) / Camera.Extent.X;
                percentAcrossY = ((Camera.Extent.Y / 2) - worldYForGUI) / Camera.Extent.Y;
            }
            //Bottom Right Quad
            else if (worldPos.X >= Camera.Position.X && worldPos.Y >= Camera.Position.Y)
            {
                angleOne = (360 - Camera.Rotation) * (Math.PI / 180);
                angle = angleOne + angleTwo;

                worldXForGUI = (float)Math.Cos(angle) * distanceFromCameraToWorldPos;
                worldYForGUI = (float)Math.Sin(angle) * distanceFromCameraToWorldPos;

                percentAcrossX = ((Camera.Extent.X / 2) + worldXForGUI) / Camera.Extent.X;
                percentAcrossY = ((Camera.Extent.Y / 2) + worldYForGUI) / Camera.Extent.Y;
            }
            else
            {
                //Not supposed to happen
                angleOne = (360 - Camera.Rotation) * (Math.PI / 180);
                angle = angleOne + angleTwo;

                worldXForGUI = (float)Math.Cos(angle) * distanceFromCameraToWorldPos;
                worldYForGUI = (float)Math.Sin(angle) * distanceFromCameraToWorldPos;

                percentAcrossX = ((Camera.Extent.X / 2) - worldXForGUI) / Camera.Extent.X;
                percentAcrossY = ((Camera.Extent.Y / 2) - worldYForGUI) / Camera.Extent.Y;
            }

            return new Vector2(GUICanvas.Instance.Bounds.Width * percentAcrossX, GUICanvas.Instance.Bounds.Height * percentAcrossY) ;
}