Jump to content

  • Log In with Google      Sign In   
  • Create Account

Big G the same at various screen sizes....


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
16 replies to this topic

#1 MARS_999   Members   -  Reputation: 1297

Like
0Likes
Like

Posted 14 April 2013 - 04:17 PM

I am using Box2D for my physics, and I am calculating magnetism on objects. What I have noticed now is when I change the screen size the objects take longer to attract to each other vs. a small screen size, which makes logical sense as the distance is less.

 

So how can I take this formula and make it use the same BIG G constant and be screen size independent?

 

Thanks!!

 

 

const float BIG_G = .2f;

b2Vec2 pk = b2->GetWorldCenter();
float mk = b2->GetMass();
b2Vec2 delta = pk - pi;
float r = delta.Length();
float force = BIG_G * mi * mk / (r*r);
delta.Normalize();

Edited by MARS_999, 14 April 2013 - 04:18 PM.


Sponsor:

#2 irreversible   Crossbones+   -  Reputation: 1410

Like
0Likes
Like

Posted 14 April 2013 - 11:39 PM

edit: I'm not really sure what you mean by screen size in your post. I'm assuming the physical screen size and/or screen resolution in my reply

The big secret to keeping a constant size of stuff on the screen is adapting your code to current DPI (dots per inch). Unfortunately, if you're on Windows (a blind assumption here), you cannot rely on built-in DPI functionality to give you accurate DPI measurements (I found absolutely no correlation between the generic 96 dpi returned by Windows and reality). Therefore the only tuly reliable way is to query the physical dimensions of the screen, eg in millimeters (you can do that in any OS, but it's most involved in Windows*) and divide them by the current resolution to get PPI (points/pixels per inch). You can then use this to scale your object to a device-inpendent constant size on any display at any resolution.

 

* I know of exactly one instance of someone having come up with the code to get the physical display size in millimeters on Windows (link above) and that's more than a  hundred lines of code


Edited by irreversible, 14 April 2013 - 11:40 PM.


#3 SimonForsman   Crossbones+   -  Reputation: 6324

Like
0Likes
Like

Posted 15 April 2013 - 02:37 AM

edit: I'm not really sure what you mean by screen size in your post. I'm assuming the physical screen size and/or screen resolution in my reply

The big secret to keeping a constant size of stuff on the screen is adapting your code to current DPI (dots per inch). Unfortunately, if you're on Windows (a blind assumption here), you cannot rely on built-in DPI functionality to give you accurate DPI measurements (I found absolutely no correlation between the generic 96 dpi returned by Windows and reality). Therefore the only tuly reliable way is to query the physical dimensions of the screen, eg in millimeters (you can do that in any OS, but it's most involved in Windows*) and divide them by the current resolution to get PPI (points/pixels per inch). You can then use this to scale your object to a device-inpendent constant size on any display at any resolution.

 

* I know of exactly one instance of someone having come up with the code to get the physical display size in millimeters on Windows (link above) and that's more than a  hundred lines of code

 

I think he is just talking about resolution and that he is making objects larger and placing them further apart when the resolution is increased(so that things look roughly the same). Thus objects that are 100px from eachother at 640x480 becomes 200px from eachother at 1280x920 which causes his magnetism force to be weaker.

 

The solution, as always is to separate rendering and logic.

Always run the logic at a fixed resolution (He doesn't have to measure distances in pixels then either)


I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!

#4 MARS_999   Members   -  Reputation: 1297

Like
0Likes
Like

Posted 15 April 2013 - 03:17 AM

edit: I'm not really sure what you mean by screen size in your post. I'm assuming the physical screen size and/or screen resolution in my reply
The big secret to keeping a constant size of stuff on the screen is adapting your code to current DPI (dots per inch). Unfortunately, if you're on Windows (a blind assumption here), you cannot rely on built-in DPI functionality to give you accurate DPI measurements (I found absolutely no correlation between the generic 96 dpi returned by Windows and reality). Therefore the only tuly reliable way is to query the physical dimensions of the screen, eg in millimeters (you can do that in any OS, but it's most involved in Windows*) and divide them by the current resolution to get PPI (points/pixels per inch). You can then use this to scale your object to a device-inpendent constant size on any display at any resolution.
 
* I know of exactly one instance of someone having come up with the code to get the physical display size in millimeters on Windows (link above) and that's more than a  hundred lines of code

 
I think he is just talking about resolution and that he is making objects larger and placing them further apart when the resolution is increased(so that things look roughly the same). Thus objects that are 100px from eachother at 640x480 becomes 200px from eachother at 1280x920 which causes his magnetism force to be weaker.
 
The solution, as always is to separate rendering and logic.
Always run the logic at a fixed resolution (He doesn't have to measure distances in pixels then either)

I am not sure how to do this....meaning separate the two, as box2d is where I get the objects positions from....

#5 SimonForsman   Crossbones+   -  Reputation: 6324

Like
0Likes
Like

Posted 15 April 2013 - 03:26 AM

 

edit: I'm not really sure what you mean by screen size in your post. I'm assuming the physical screen size and/or screen resolution in my reply
The big secret to keeping a constant size of stuff on the screen is adapting your code to current DPI (dots per inch). Unfortunately, if you're on Windows (a blind assumption here), you cannot rely on built-in DPI functionality to give you accurate DPI measurements (I found absolutely no correlation between the generic 96 dpi returned by Windows and reality). Therefore the only tuly reliable way is to query the physical dimensions of the screen, eg in millimeters (you can do that in any OS, but it's most involved in Windows*) and divide them by the current resolution to get PPI (points/pixels per inch). You can then use this to scale your object to a device-inpendent constant size on any display at any resolution.
 
* I know of exactly one instance of someone having come up with the code to get the physical display size in millimeters on Windows (link above) and that's more than a  hundred lines of code

 
I think he is just talking about resolution and that he is making objects larger and placing them further apart when the resolution is increased(so that things look roughly the same). Thus objects that are 100px from eachother at 640x480 becomes 200px from eachother at 1280x920 which causes his magnetism force to be weaker.
 
The solution, as always is to separate rendering and logic.
Always run the logic at a fixed resolution (He doesn't have to measure distances in pixels then either)

I am not sure how to do this....meaning separate the two, as box2d is where I get the objects positions from....

 

scale your positions etc to suit the current resolution after you get them from box2d, not before you give them to box2d.

 

If you use a 3D API and orthographic projection you can simply set the projection matrix based on the box2d resolution rather than the screen resolution.


Edited by SimonForsman, 15 April 2013 - 03:32 AM.

I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!

#6 MARS_999   Members   -  Reputation: 1297

Like
0Likes
Like

Posted 15 April 2013 - 06:48 PM

 

 

edit: I'm not really sure what you mean by screen size in your post. I'm assuming the physical screen size and/or screen resolution in my reply
The big secret to keeping a constant size of stuff on the screen is adapting your code to current DPI (dots per inch). Unfortunately, if you're on Windows (a blind assumption here), you cannot rely on built-in DPI functionality to give you accurate DPI measurements (I found absolutely no correlation between the generic 96 dpi returned by Windows and reality). Therefore the only tuly reliable way is to query the physical dimensions of the screen, eg in millimeters (you can do that in any OS, but it's most involved in Windows*) and divide them by the current resolution to get PPI (points/pixels per inch). You can then use this to scale your object to a device-inpendent constant size on any display at any resolution.
 
* I know of exactly one instance of someone having come up with the code to get the physical display size in millimeters on Windows (link above) and that's more than a  hundred lines of code

 
I think he is just talking about resolution and that he is making objects larger and placing them further apart when the resolution is increased(so that things look roughly the same). Thus objects that are 100px from eachother at 640x480 becomes 200px from eachother at 1280x920 which causes his magnetism force to be weaker.
 
The solution, as always is to separate rendering and logic.
Always run the logic at a fixed resolution (He doesn't have to measure distances in pixels then either)

I am not sure how to do this....meaning separate the two, as box2d is where I get the objects positions from....

 

scale your positions etc to suit the current resolution after you get them from box2d, not before you give them to box2d.

 

If you use a 3D API and orthographic projection you can simply set the projection matrix based on the box2d resolution rather than the screen resolution.

Ok so how would you go about scaling when you have many different screen resolutions...

 

e.g. 1024x768 or 1920x1080 and plug that into this equation

 

float force = BIG_G * mi * mk / (r*r);

 

thanks!



#7 MARS_999   Members   -  Reputation: 1297

Like
0Likes
Like

Posted 16 April 2013 - 02:11 AM

float scaleFactor = 800.0f / config.screenSize.Width;
            force *= scaleFactor;

 

as you can see I am at least trying to figure this out, but that code doesn't work either...

 

Thanks



#8 Olof Hedman   Crossbones+   -  Reputation: 2956

Like
0Likes
Like

Posted 16 April 2013 - 02:44 AM

You are going about it backwards, you shouldn't scale the force. 

 

Your box2d world does not have to care about screen resolution at all.  

You could let the height of the world be 1.0f, and the width equal to the aspect ratio.

 

Then in your rendering code, you just get the position from box2D, multiply the position with you screen resolution, and use that to position the object.



#9 SimonForsman   Crossbones+   -  Reputation: 6324

Like
1Likes
Like

Posted 16 April 2013 - 02:44 AM

float scaleFactor = 800.0f / config.screenSize.Width;
            force *= scaleFactor;

 

as you can see I am at least trying to figure this out, but that code doesn't work either...

 

Thanks

 

Don't scale the forces (This is game logic, it should be 100% independent of the visual represenation), scale the rendering. (or just make the viewable area of the world larger)

 

So , if you want objects to appear the same size regardless of resolution (only higher detail at higher resolutions) you scale the rendering. (having high res sprites that you scale down for lower resolutions give the best result (allthough upscaling with filtering isn't completely worthless)

 

If you want objects to be smaller (and fit more of them on screen) at higher resolutions you don't scale anything, you just render a larger area

 

You cannot cleanly scale from a 4:3 resolution to a 16:9 resolution, when the aspect ratio changes you have 3 options:

1) Add a border (This is best for games where the full scene should be visible all the time, such as tetris, pong, etc)

2) Expand/contract the viewable area horizontally (good option for platformers etc where a wider resolution simply lets the player see further right/left)

3) Stretch the visuals (not recommended since its ugly)

 

So, lets say our simulation runs in a 2D world that is "800x600"(You can use anything for the size of your world, olofs suggestion is good for a game where everything is visible anyway (for large world games you could use 1 unit = 1 meter or something instead) and we want all of it to be on screen all the time. (a game like tetris for example).

we got a 20x20 object at position 40,50 , if we render at 800x600 this is easy enough.

 

if we scale the resolution to 1600x1200 we got a simple 2x scale and render a 40x40 object at 80,100. (This works better if you got high resolution sprites that you scale down for low resolutions, or better yet, vector art (you can rasterize that when the user selects a resolution for the first time)

 

If we do something a bit trickier and go for 1920x1080 we get a bit of a problem: the horizontal scale then is 2.4 and the vertical is 1.8

Since stretching is ugly we use a left-right border and the 1.8 scale (we could also use the 2.4 scale and cut off the top and bottom portions, but then we'd lose information)

 

800*1.8 = 1440

(1920 - 1440) / 2 = 240 (so we get a 240px border on each side)

 

then we render that 20x20 object as 36x36 at position x=240 + 40*1.8 , y=50*1.8

 

if we use sprites that are, lets say 80x80 for those 20x20 objects we can scale quite nicely even to very high resolutions, we could also provide hand-scaled sprites for various lower resolutions if automatic downscaling doesn't give nice enough results.

 

If the game world is scrollable it gets even easier, then we can have a game world that is, say 5000x5000 units and we just show as much of it on screen as we can centered around the player. (Higher resolutions = smaller units and more of the world visible at once), or we could combine the approaches and both scale and scroll (to keep things from getting horribly tiny at high resolutions).


Edited by SimonForsman, 16 April 2013 - 02:50 AM.

I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!

#10 MARS_999   Members   -  Reputation: 1297

Like
0Likes
Like

Posted 16 April 2013 - 04:00 AM

I don't think I need to scale the size of the objects. ... I need to keep the force constant between screen resolutions as the distance varies and on larger screens objects tske to long to start attracting

#11 Olof Hedman   Crossbones+   -  Reputation: 2956

Like
0Likes
Like

Posted 16 April 2013 - 04:13 AM

I don't think I need to scale the size of the objects. ... I need to keep the force constant between screen resolutions as the distance varies and on larger screens objects tske to long to start attracting

 

But it only varies if you mix in screen resolution in your physics calculations.

Stop doing that, and the problem will go away.

We are trying to tell you that your physics calculations does not need to know about screen resolution, and trying to force it to will only complicate your code.

Separate it.

Physics should live in its own little virtual world where everything is constant.

 

Then in your rendering code, you can simply chose a view that shows the objects in the world you want to show (maybe there are even more of them then will fit on screen)

 

Object A and Object B will always be X units apart, in the physics code, no matter if they are shown in opposite corners, or both in the same corner of the screen, and will always behave as expected in relation to each other.



#12 MARS_999   Members   -  Reputation: 1297

Like
0Likes
Like

Posted 17 April 2013 - 01:35 AM

Sigh, I guess I am just to dense to make this happen people... but I have tried and this is what I am using now. LIke I said when I change the screen resolution from 1024x768 to 1920x1080 the objects take to long to move as the magnetism is weakened. I am not using the screen size in this code, I am using box2D GetWorldCenter() and that is it....

 

 

 

for(b2Body* b1 = world->GetBodyList(); b1; b1 = b1->GetNext())    
    {
        void* data1 = b1->GetUserData();
        b2Vec2 pi = b1->GetWorldCenter();
        float mi = b1->GetMass();
        for(b2Body* b2 =world->GetBodyList(); b2; b2 = b2->GetNext())
        {
            void* data2 = b2->GetUserData();
            if(b1 == b2 || !data1 || !data2 )
                continue;                
            b2Vec2 pk = b2->GetWorldCenter();
            float mk = b2->GetMass();
            b2Vec2 delta = pk - pi;
            float r = delta.Length();
            float force = BIG_G * mi * mk / (r*r);
            delta.Normalize();
            b1->ApplyForce( force * delta, pi);
            b2->ApplyForce(-force * delta, pk);
        }
    }


#13 SimonForsman   Crossbones+   -  Reputation: 6324

Like
0Likes
Like

Posted 17 April 2013 - 02:47 AM

Sigh, I guess I am just to dense to make this happen people... but I have tried and this is what I am using now. LIke I said when I change the screen resolution from 1024x768 to 1920x1080 the objects take to long to move as the magnetism is weakened. I am not using the screen size in this code, I am using box2D GetWorldCenter() and that is it....

 

 

 

 

for(b2Body* b1 = world->GetBodyList(); b1; b1 = b1->GetNext())    
    {
        void* data1 = b1->GetUserData();
        b2Vec2 pi = b1->GetWorldCenter();
        float mi = b1->GetMass();
        for(b2Body* b2 =world->GetBodyList(); b2; b2 = b2->GetNext())
        {
            void* data2 = b2->GetUserData();
            if(b1 == b2 || !data1 || !data2 )
                continue;                
            b2Vec2 pk = b2->GetWorldCenter();
            float mk = b2->GetMass();
            b2Vec2 delta = pk - pi;
            float r = delta.Length();
            float force = BIG_G * mi * mk / (r*r);
            delta.Normalize();
            b1->ApplyForce( force * delta, pi);
            b2->ApplyForce(-force * delta, pk);
        }
    }

 

How do you initialize Box2D ?


I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!

#14 MARS_999   Members   -  Reputation: 1297

Like
0Likes
Like

Posted 17 April 2013 - 08:25 AM

I will post it tonight....

#15 MARS_999   Members   -  Reputation: 1297

Like
0Likes
Like

Posted 17 April 2013 - 05:07 PM

NX::App* p = NX::App::Get();
    
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    bodyDef.position.Set(posX, posY);

    KillBody();
    
    body = p->GetWorld()->CreateBody(&bodyDef);

    b2PolygonShape dynamicBox;
    dynamicBox.SetAsBox(sizeX, sizeY);

    b2FixtureDef fixtureDef;
    fixtureDef.shape = &dynamicBox;

    // Set the box density to be non-zero, so it will be dynamic.
    fixtureDef.density = 1.0f;

    // Override the default friction.
    fixtureDef.friction = 0.3f;

    // Add the shape to the body.
    body->CreateFixture(&fixtureDef);

    body->SetUserData(this);


#16 Olof Hedman   Crossbones+   -  Reputation: 2956

Like
0Likes
Like

Posted 18 April 2013 - 03:52 AM

I think your problem is where you place your objects in the world.

 

You seem to use screen coordinates to place them.

 

Decoupling physics from graphics means you have to both convert input (from a mouse etc) to physics world coordinates, and then you need to convert back from physics to screen coordinates in rendering.



#17 MARS_999   Members   -  Reputation: 1297

Like
0Likes
Like

Posted 18 April 2013 - 05:05 PM

b2Vec2 position = body->GetPosition();

 

I get the positions form Box2d so the coordinates should be done in physics terms...

 

then I use that variable to draw the object


Edited by MARS_999, 18 April 2013 - 05:06 PM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS