Add screen->world and world->screen functions for 2D; add extended camera2D example (#947)
This commit is contained in:
parent
37bb8e9554
commit
97101d1003
3 changed files with 324 additions and 22 deletions
59
src/core.c
59
src/core.c
|
@ -1250,28 +1250,7 @@ void BeginMode2D(Camera2D camera)
|
|||
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
|
||||
rlMultMatrixf(MatrixToFloat(screenScaling)); // Apply screen scaling if required
|
||||
|
||||
// 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.offset.y, 0.0f);
|
||||
|
||||
Matrix matTransform = MatrixMultiply(MatrixMultiply(matOrigin, MatrixMultiply(matScale, matRotation)), matTranslation);
|
||||
|
||||
rlMultMatrixf(MatrixToFloat(matTransform)); // Apply transformation to modelview
|
||||
rlMultMatrixf(MatrixToFloat(GetCamera2DMatrix(camera))); // Apply transformation to modelview
|
||||
}
|
||||
|
||||
// Ends 2D mode with custom camera
|
||||
|
@ -1502,6 +1481,42 @@ Matrix GetCameraMatrix(Camera camera)
|
|||
return MatrixLookAt(camera.position, camera.target, camera.up);
|
||||
}
|
||||
|
||||
|
||||
Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera) {
|
||||
Matrix m = MatrixInvert(GetCamera2DMatrix(camera));
|
||||
Vector3 transform = Vector3Transform((Vector3){position.x, position.y, 0}, m);
|
||||
return (Vector2){transform.x, transform.y};
|
||||
}
|
||||
|
||||
Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera) {
|
||||
Matrix m = GetCamera2DMatrix(camera);
|
||||
Vector3 transform = Vector3Transform((Vector3){position.x, position.y, 0}, m);
|
||||
return (Vector2){transform.x, transform.y};
|
||||
}
|
||||
|
||||
Matrix GetCamera2DMatrix(Camera2D camera) {
|
||||
// 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.offset.y, 0.0f);
|
||||
Matrix matTransform = MatrixMultiply(MatrixMultiply(matOrigin, MatrixMultiply(matScale, matRotation)), matTranslation);
|
||||
return matTransform;
|
||||
}
|
||||
|
||||
// Set target FPS (maximum)
|
||||
void SetTargetFPS(int fps)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue