libgdx / box2dlights

Fork of box2dlights by Kalle Hamalainen
Apache License 2.0
255 stars 82 forks source link

Convert box2d body position from meters to pixels #74

Closed Honguito98 closed 9 years ago

Honguito98 commented 9 years ago

This solves know problems with attachToBody() method in this class. Box2d always handles meters, instead pixels:

According to Box2D manual:

Caution

Box2D is tuned for MKS units. Keep the size of moving objects roughly between 0.1 and 10 meters.
You'll need to use some scaling system when you render your environment and actors.
The Box2D testbed does this by using an OpenGL viewport transform. DO NOT USE PIXELS.
davebaol commented 9 years ago

Why on earth 2 pull requests? This PR clearly depends on #75, so they should be just 1.

Honguito98 commented 9 years ago

Sorry for that! I new to github system.

rinold commented 9 years ago

Sorry, but currently I don't understand why you need converting the start position to pixels. And what are the "known" problems with attach to body method?

I don't reject the thing that I missed something, but the box2dlights is completely working in the box2d world coordinates, and scaling the start vector to pixels, seems to me, will break the other dependent methods, like contains() and etc. which uses the start.x/y values.

UPD. I don't know all details, but this looks like for me that you are passing the combined matrix in pixel coords, instead of box2d world coords and then you are trying to fix it here by converting the bodies positions to pixels.. However, this is just a suggestion and I might be wrong.

Honguito98 commented 9 years ago

The 'know' problems are:

For example: http://badlogicgames.com/forum/viewtopic.php?f=11&t=5610#p26860 I've seen the solution: scale the camera, but I my case, I need to handle pixels only (because I do several calculations with pixels).

Ok, I've seen on some code examples using a constant for convert pixels to box2d coordinates and vice-versa (like this: http://www.gamefromscratch.com/post/2014/09/10/LibGDX-Tutorial-13-Physics-with-Box2D-Part-2-Force-Impulses-and-Torque.aspx).

Some users try to scale just the body position, instead deal with the camera. An optional field variable can be used, so, these divided values will scale to meters:

    // Where BOX2D_WORLD_SCALE is actually PIXEL_TO_METERS
    start.x = vec.x * RayHandler.BOX2D_WORLD_SCALE + dX;
    start.y = vec.y * RayHandler.BOX2D_WORLD_SCALE + dY;
piotr-j commented 9 years ago

Or you could use a camera with proper scale, like you probably should. We can't guard against all possible mistakes. It should be documented of course.

Honguito98 commented 9 years ago

Ok, I got it, I created a new matrix for store the camera.combined, then scale to box2d and finally apply this matrix to box2dlights:

float PIXELS_TO_METERS_MUL = 100;
float PIXELS_TO_METERS_DIV = .01f;
    box2dLightsMt
        .set(camera.combined)
        .scale(PIXELS_TO_METERS_MUL, PIXELS_TO_METERS_MUL, 0)
    ;

    rayHandler.setCombinedMatrix(
        box2dLightsMt,
        camera.position.x * PIXELS_TO_METERS_DIV,
        camera.position.y * PIXELS_TO_METERS_DIV,
        1280 * PIXELS_TO_METERS_DIV,
        800 * PIXELS_TO_METERS_DIV

    );

Yeah, sorry for my mistake, please cancel my PR (or commits).