Game Development Community

[Solution] SceneWindow Doesn't Take Into Account Camera Angle

by William Lee Sims · in Torque 2D Professional · 10/29/2013 (4:02 pm) · 2 replies

NOTE: The final code and comments are down below. Ignore the code that follows.

My games need to be able to rotate 180 degrees. When it comes to sending events (mouse, touch, etc.), it looks like the code doesn't take into account the camera angle.

For now, I've modified a couple of functions in SceneWindow.cc:
void SceneWindow::windowToScenePoint( const Vector2& srcPoint, Vector2& dstPoint ) const
{
    // New Conversion Code:
    dstPoint = srcPoint;
    dstPoint.scale( mCameraCurrent.mSceneWindowScale );
    dstPoint.x += mCameraCurrent.mSceneMin.x;
    dstPoint.y = mCameraCurrent.mSceneMax.y - dstPoint.y;
    dstPoint.rotate( 0.5 * (mCameraCurrent.mSceneMin + mCameraCurrent.mSceneMax), mCameraCurrent.mCameraAngle ); 
    // Old Conversion:
    // dstPoint.Set( (srcPoint.x * mCameraCurrent.mSceneWindowScale.x) + mCameraCurrent.mSceneMin.x, mCameraCurrent.mSceneMax.y - (srcPoint.y * mCameraCurrent.mSceneWindowScale.y) );
}

void SceneWindow::sceneToWindowPoint( const Vector2& srcPoint, Vector2& dstPoint ) const
{
    // New Conversion Code:
    dstPoint = srcPoint;
    dstPoint.rotate( 0.5 * (mCameraCurrent.mSceneMin + mCameraCurrent.mSceneMax), -mCameraCurrent.mCameraAngle );
    dstPoint.x = dstPoint.x - mCameraCurrent.mSceneMin.x;
    dstPoint.y = mCameraCurrent.mSceneMax.y - dstPoint.y;
    dstPoint.scale( Vector2( 1.0 / mCameraCurrent.mSceneWindowScale.x, 1.0 / mCameraCurrent.mSceneWindowScale.y ) );
    // Old Conversion:
    // dstPoint.Set( (srcPoint.x - mCameraCurrent.mSceneMin.x) / mCameraCurrent.mSceneWindowScale.x, (mCameraCurrent.mSceneMax.y - srcPoint.y) / mCameraCurrent.mSceneWindowScale.y );
}

I've only tested this code with scenes centered around the origin (0,0) and only with angles in multiples of 180 degrees.

I'll be sitting on this a bit while I test it out more and to make sure I didn't misinterpret something in the code. If anybody has any input or knows more about this problem, I'd love to hear it.

Thanks!

#1
11/01/2013 (2:33 pm)
I've finally got around to testing this with arbitrary scales, angles, and camera positions. The final code looks like this:

//-----------------------------------------------------------------------------

void SceneWindow::windowToScenePoint( const Vector2& srcPoint, Vector2& dstPoint ) const
{
    dstPoint = srcPoint;
    dstPoint.scale( mCameraCurrent.mSceneWindowScale );
    dstPoint.x = dstPoint.x + mCameraCurrent.mSceneMin.x;
    dstPoint.y = mCameraCurrent.mSceneMax.y - dstPoint.y;
    dstPoint.rotate( 0.5 * (mCameraCurrent.mSceneMin + mCameraCurrent.mSceneMax), -mCameraCurrent.mCameraAngle ); 
}

//-----------------------------------------------------------------------------

void SceneWindow::sceneToWindowPoint( const Vector2& srcPoint, Vector2& dstPoint ) const
{
    dstPoint = srcPoint;
    dstPoint.rotate( 0.5 * (mCameraCurrent.mSceneMin + mCameraCurrent.mSceneMax), mCameraCurrent.mCameraAngle );
    dstPoint.x = dstPoint.x - mCameraCurrent.mSceneMin.x;
    dstPoint.y = mCameraCurrent.mSceneMax.y - dstPoint.y;
    dstPoint.scale( Vector2( 1 / mCameraCurrent.mSceneWindowScale.x, 1 / mCameraCurrent.mSceneWindowScale.y ) );
}

One small warning: the SceneWindow.getWindowPoint() function can be off as early as the 5th decimal position when the camera is set to a non-zero angle (based upon observation). This means that a "pixel" position of (2,2) might be returned as (1.99996,1.99996), so make sure you take that into account.

I'll get this added to the development branch as soon as I can.
#2
11/01/2013 (3:24 pm)
Thanks William!