2d transformations

edited March 21 in raylib: core
Hi Raysan,

First of all, thank you for this library.

I am a bit confused with the library functions for 2D transformations. I hope you will have the time to read through my doubts.

From your definition for Camera2D in raylib.h (395 - 401) I assumed that setting a 2d camera means that the origin of coordinates is at (camera.offset + camera.target) and rotation and zooming is about camera.target. Lines 729 to 744 in core.c also seem to suggest that.

I am trying to revolve a circle about the center of the screen. So I have the following program:

#include

int main()
{
// Initialization
//--------------------------------------------------------------------------------------
int swidth = 600;
int sheight = 600;

InitWindow(swidth, sheight, "Rotational transformation");

const int revolution_radius = 200;
const int circle_radius = 40;

Camera2D camera;

camera.zoom = 1.0f;
camera.target = (Vector2){swidth/2, sheight/2};
camera.offset = (Vector2){ revolution_radius, 0 };

float revolution_angle = 0.0;

SetTargetFPS(60);
//--------------------------------------------------------------------------------------

// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
camera.rotation = revolution_angle;
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();

ClearBackground(DARKGRAY);

Begin2dMode(camera);

DrawCircle(0, 0, circle_radius, GREEN);

End2dMode();

revolution_angle++;

if (revolution_angle == 360) {
revolution_angle = 0;
}


EndDrawing();
//----------------------------------------------------------------------------------
}

// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------

return 0;
}
The program is not working as it is supposed to. The revolution is not about the center of the screen and the radius of revolution is also not correct.

Can you please help me about what is going wrong ?

Once we have set up a 2d camera the new origin is at camera.offset + camera.target, isn't it ? So the coordinates of your shapes need be given only with respect to this new origin, correct ? Then why is it that in your core_2d_camera.c example you still draw the player rectangle with the old coordinates( line 106 in core_2d_camera.c )?

I have other questions. But I will ask them later. Please answer them at your convenience.

Thanks.

Comments

  • edited March 21
    Hi krishna,

    About Camera2D, consider it as an extra transformation (position, rotation, scale) over all the elements drawn between Begin2dMode() and End2dMode(). For that reason, those elements are drawn not considering Camera2D transformation.

    camera.target defines the point where Camera2D is looking (rotation and zoom origin), the camera.offset is the displacement from target, probably most of the time you want it to be { 0, 0 }.

    Not sure if I clarified it enough... please, let me know if it makes sense...
  • Hi Raysan,

    Yes, I have also understood Camera2D as an extra transformation to what is drawn between Begin2dMode(camera) and End2dMode().

    So if I want to draw a circle of radius 40 at a distance r to the right of the center of the screen, the straightforward way would be

    DrawCircle(screenWidth/2 + r, screenHeight/2, 40, GREEN);

    But can I not draw this same circle at the same place using Camera2D as follows:

    ...
    camera.target = (Vector2){screenWidth/2, screenHeight/2};
    camera.offset = (Vector2) { r, 0};
    camera.rotation = 0.0;
    camera.zoom = 1.0;
    ...

    Begin2dMode(camera);

    DrawCircle(0, 0, 40, GREEN);

    End2dMode();

    Is this not correct ? Is this not what the purpose of Camera2D ?

    Thank you for your time.
  • Hi krishna!

    The 2d camera target is only the point used for rotation and zoom, it does not add and extra displacement over your shapes. You should draw your circle (or any other 2d shape) like if you were drawing in a normal canvas - (0, 0) is the top-left corner.

    In your code, you just draw your circle in the top-left corner of the screen with a displacement (applied by camera) of r.
  • Thank you, Raysan. I am able to do what I intended now.

    But if I want to compose transformations I will have to manually do it using the matrix functions in raymath.h, I guess. Perhaps, when you have the time, you can provide functions to translate the origin and rotate about the origin as in Processing(http://processing.org).
  • Hi krishna, actually, translation and rotation functionality is exposed if using directly rlgl layer (https://github.com/raysan5/raylib/blob/develop/examples/rlgl_standalone.c), check how it is used to draw shapes: https://github.com/raysan5/raylib/blob/develop/src/shapes.c
    You can create your custom shapes drawing implementations using rlgl functions (actually is very close to OpenGL immediate mode coding). ;)
Sign In or Register to comment.