From d8b8c0f3fc8ab3872c65bcfefd258bd6ad4ece51 Mon Sep 17 00:00:00 2001 From: arvyy Date: Fri, 16 Aug 2019 17:09:50 +0300 Subject: [PATCH] change Camera2D behavior (#945) --- examples/core/core_2d_camera.c | 6 ++---- src/core.c | 17 +++++++++++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/examples/core/core_2d_camera.c b/examples/core/core_2d_camera.c index 81f580ad..ba432f46 100644 --- a/examples/core/core_2d_camera.c +++ b/examples/core/core_2d_camera.c @@ -42,7 +42,7 @@ int main(void) Camera2D camera = { 0 }; camera.target = (Vector2){ player.x + 20, player.y + 20 }; - camera.offset = (Vector2){ 0, 0 }; + camera.offset = (Vector2){ screenWidth / 2, screenHeight / 2 }; camera.rotation = 0.0f; camera.zoom = 1.0f; @@ -57,12 +57,10 @@ int main(void) if (IsKeyDown(KEY_RIGHT)) { player.x += 2; // Player movement - camera.offset.x -= 2; // Camera displacement with player movement } else if (IsKeyDown(KEY_LEFT)) { player.x -= 2; // Player movement - camera.offset.x += 2; // Camera displacement with player movement } // Camera target follows player @@ -135,4 +133,4 @@ int main(void) //-------------------------------------------------------------------------------------- return 0; -} \ No newline at end of file +} diff --git a/src/core.c b/src/core.c index ac0ddd29..81bed607 100644 --- a/src/core.c +++ b/src/core.c @@ -1251,11 +1251,24 @@ void BeginMode2D(Camera2D camera) rlLoadIdentity(); // Reset current matrix (MODELVIEW) rlMultMatrixf(MatrixToFloat(screenScaling)); // Apply screen scaling if required - // Camera rotation and scaling is always relative to target + //The camera in world-space is set by + //1. Move it to target + //2. Rotate by -rotation and scale by (1/zoom) + // When setting higher scale, it's more intuitive for the world to become bigger (= camera become smaller), + // not for the camera getting bigger, hence the invert. Same deal with rotation. + //3. Move it by (-offset); + // Offset defines target transform relative to screen, but since we're effectively "moving" screen (camera) + // we need to do it into opposite direction (inverse transform) + // + //Having camera transform in world-space, inverse of it gives the modelview transform. + //Since (A*B*C)' = C'*B'*A', the modelview is + //1. Move to offset + //2. Rotate and Scale + //3. Move by -target Matrix matOrigin = MatrixTranslate(-camera.target.x, -camera.target.y, 0.0f); Matrix matRotation = MatrixRotate((Vector3){ 0.0f, 0.0f, 1.0f }, camera.rotation*DEG2RAD); Matrix matScale = MatrixScale(camera.zoom, camera.zoom, 1.0f); - Matrix matTranslation = MatrixTranslate(camera.offset.x + camera.target.x, camera.offset.y + camera.target.y, 0.0f); + Matrix matTranslation = MatrixTranslate(camera.offset.x, camera.offset.y, 0.0f); Matrix matTransform = MatrixMultiply(MatrixMultiply(matOrigin, MatrixMultiply(matScale, matRotation)), matTranslation);