MADEAPPS / newton-dynamics

Newton Dynamics is an integrated solution for real time simulation of physics environments.
http://www.newtondynamics.com
Other
942 stars 182 forks source link

Scaled-down collisions bounce forever? #6

Closed DashW closed 10 years ago

DashW commented 10 years ago

Sorry for not posting this on the newtondynamics.com forums, but I registered weeks ago and my account was never activated.

When I try to scale an existing convex hull collision down to 0.02 of its normal size, it seems to just keep bouncing forever, but when I create the convex hull at the correct size, it works as expected.

This works:

    for(unsigned i = 0; i < vertexBuffer->GetLength(); ++i)
    {
        vertexBuffer->Get(i).position *= 0.02f;
    }

    collision = NewtonCreateConvexHull(
        physicsWorld->newtonWorld,
        vertexBuffer->GetLength(),
        (float*)vertexBuffer->GetData(),
        vertexBuffer->GetElementSize(),
        0.0f, 0, (float*)&offsetMatrix);

This doesn't:

    collision = NewtonCreateConvexHull(
        physicsWorld->newtonWorld,
        vertexBuffer->GetLength(),
        (float*)vertexBuffer->GetData(),
        vertexBuffer->GetElementSize(),
        0.0f, 0, (float*)&offsetMatrix);

    NewtonCollisionSetScale(collision, 0.02f, 0.02f, 0.02f);

I need this to be able to scale collisions dynamically, so that 'growing' an object pushes other objects out of the way in real-time.

For the moment, I've introduced a hack workaround that multiplies the softness of a contact by the scale factors of both bodies in the contact callback. This helps fix the bouncing, but the affected bodies still vibrate for several seconds before they come to rest.

I'm using the latest version from the Google Code repository, r1679 (Jul 28th)

AntonSynytsia commented 10 years ago

Maybe you need to recalculate body inertia...

DashW commented 10 years ago

Already doing that, the inertial matrix and center of mass are okay.

MannyClicks commented 10 years ago

I'm using the latest version from the Google Code repository, r1679 (Jul 28th)

Make sure to use the github repository, the Google Code repo is defunct and not up to date.

JulioJerez commented 10 years ago

first what is you user name? so that I can activate the account?

Julio

DashW commented 10 years ago

@JulioJerez - I've registered as DashW

Make sure to use the github repository, the Google Code repo is defunct and not up to date.

@Manny-MADE - I'll try that now, I wasn't aware of the GitHub repo until today.

JulioJerez commented 10 years ago

your account is active now.

On Thu, Aug 14, 2014 at 7:56 AM, Richard Copperwaite < notifications@github.com> wrote:

@JulioJerez https://github.com/JulioJerez - I've registered as DashW

Make sure to use the github repository, the Google Code repo is defunct and not up to date.

@Manny-MADE https://github.com/Manny-MADE - I'll try that now, honestly I wasn't aware of the GitHub repo until today.

— Reply to this email directly or view it on GitHub https://github.com/MADEAPPS/newton-dynamics/issues/6#issuecomment-52194022 .

DashW commented 10 years ago

Thanks!

I've just upgraded to latest from GitHub master, and the issue is still happening.

I'm using NewtonConvexCollisionCalculateInertialMatrix to recompute the inertia and center of mass after scaling, not sure if that's of any use.

AntonSynytsia commented 10 years ago

Juleo, I wondered about that too. Scaled up collisions also act improperly. Do I have to do anything else after calling NewtonCollisionSetScale, such as recalculating mass, or its done automatically?

JulioJerez commented 10 years ago

no you do not have to do anything, do you have a test. scale should work fine, I use for the player controller and for the vehicle tires. you should call NewtonBodySetInertia after you scale a body.

AntonSynytsia commented 10 years ago

serialized_world_scaled_body.bin

Try moving small box, and you'll see it behave abnormally.

I think I noticed the problem. The centre of mass is quite improper. I encountered many problems with offseted centre of mass of small bodies. For some reason small connvex bodies don't have proper centre of mass, but do have proper collision.

Maybe improper centre of mass is created due to the purpose that my wrapper doesn't work properly. Juleo, can you create a small body in Sandbox of 1.0 x 0.5 x 0.5 inches convex body and see if it has propper centre of mass. If it does then there is some improper implementation in my engine, (maybe floating range is too small); otherwise it could be an issue in newton.

JulioJerez commented 10 years ago

I though I replied to this before, but maybe I was no clear.

you are scaling the collision shape using function NewtonCollisionSetScale (collision, scaleX, scaleY, scaleZ);

That will only scale the collision but leave everything else untouched if your collsion shape is attached to a body, and you want to make sure every thing is updated. this is why you see the CG skewered to a corner.

you need to call the functions to set the Mass matrix, and CG again. If you just want every thing to scale proportionally with the scale, they is a util function tat does everything for you

void NewtonBodySetCollisionScale (const NewtonBody* const bodyPtr, dFloat scaleX, dFloat scaleY, dFloat scaleZ)

It will scale the collision, set the Center of mass and Mass matrix and update the broad phase appropriately.

Note: playing the serialized I noticed they was a bug in the function and I fix it. please sync again and try. I did not tested, but I believe it will work.

The center of mass not part of the collision is part of the body and by deful will be at 0, 0, 0. how are you setting it?

On Sun, Aug 17, 2014 at 11:04 AM, Anton notifications@github.com wrote:

serialized_world_scaled_body.bin https://googledrive.com/host/0B3qg8f4WrNdHdHVyLVFuaHRjOTA/serialized_world_scaled_body.bin

Try moving small box, and you'll see it behave abnormally.

I think I noticed the problem. The centre of mass is quite improper. I encountered many problems with offseted centre of mass of small bodies. For some reason small connvex bodies don't have proper centre of mass, but do have proper collision.

Maybe improper centre of mass is created due to the purpose that my wrapper doesn't work properly. Juleo, can you create a small body in Sandbox of 1.0 x 0.5 x 0.5 inches convex body and see if it has propper centre of mass. If it does then there is some impropper implementation in my engine, (maybe floating range is too small); otherwise it could be an issue in newton.

— Reply to this email directly or view it on GitHub https://github.com/MADEAPPS/newton-dynamics/issues/6#issuecomment-52429679 .

AntonSynytsia commented 10 years ago

Juleo, I understand the concept. Thanks for clarifying. I did the scaling part by calling NewtonCollisionSetScale, and then NewtonBodySetMassProperties, which is about the same as NewtonBodySetCollisionScale.

Lets leave the scaling part out of discussion for now. What bothers me is the way small bodies work. Can you create a box in a sandbox of 0.03 x 0.01 x 0.01 meters using NewtonCreateConvexHull. And then call NewtonCreateDynamicBody, consequently call NewtonBodySetMassProperties to calculate all inertia, centre of mass, and set mass. As of result you will notice centre of mass is improper. And thats the point I was trying to make. Don't use NewtonCreateBox as it will have proper centre of mass - we're testing NewtonCreateConvexHull.

So the pseudo code will look like this.

pts = [ [0,0,0], [0,0,0.01], [0.01,0,0.01],  [0.01,0,0], [0,0.03,0], [0,0.03,0.01], [0.01, 0.03,0], [0.01,0.03,0.01] ]
col = NewtonCreateConvexHull(world, 8, pts, 12, 0.0, 0, nil)
body = NewtonCreateDynamicBody(world, col, matrix)
NewtonBodySetMassProperties(body, 1.0, col)
JulioJerez commented 10 years ago

ah ok, that's a different problem.

Convex hulls mass data is calculated by an algorithm based on the Theorem called Green and Divergence http://en.wikipedia.org/wiki/Green's_theorem http://en.wikipedia.org/wiki/Divergence_theorem The let you calculate volume by calculation Ares, and calculate ares by calculation perimeter

The problem is that with floating point accuracy the calculation lose lost of significant digit of pressition. so I put a limit as to how small a volume result is because if it is too small the the numerical errors are probably the dominnt factor on the calculation and the result will be incorrect anyway.

Tha value is control by define

define DG_MAX_MIN_VOLUME dgFloat32 (1.0e-6f)

witch was set to 1.0e-4.

with that value the origin was devided by 100. because the volume was 100 time smaller. I set to 1.0e-6 and the calculate value is spot on

m_centerOfMass x=0.0049999999 y=0.015000001 z=0.0049999999 w=2.9999999e-006 dgVector

I check that fix with that valeu at 1.0e-6 I do not comment you make any smaller, and body of 0.01 unit in lenegh is in fact really small.

for the level of accuracy double precision is required. Any reason why you need such small objects?

On Mon, Aug 18, 2014 at 2:35 PM, Anton notifications@github.com wrote:

Juleo, I understand the concept. Thanks for clarifying. I did the scaling part by calling NewtonCollisionSetScale, and then NewtonBodySetMassProperties, which is about the same as NewtonBodySetCollisionScale.

Lets leave the scaling part out of discussion for now. What bothers me is the way small bodies work. Can you create a box in a sandbox of 0.03 x 0.01 x 0.01 meters using NewtonCreateConvexHull. And then call NewtonCreateDynamicBody, consequently call NewtonBodySetMassProperties to calculate all inertia, centre of mass, and set mass. As of result you will notice centre of mass is improper. And thats the point I was trying to make. Don't use NewtonCreateBox as it will have proper centre of mass - we're testing NewtonCreateConvexHull.

So the pseudo code will look like this.

pts = [ [0,0,0], [0,0,0.01], [0.01,0,0.01], [0.01,0,0], [0,0.03,0], [0,0.03,0.01], [0.01, 0.03,0], [0.01,0.03,0.01] ] col = NewtonCreateConvexHull(world, 8, pts, 12, 0.0, 0, nil) body = NewtonCreateDynamicBody(world, col, matrix) NewtonBodySetMassProperties(body, 1.0, col)

— Reply to this email directly or view it on GitHub https://github.com/MADEAPPS/newton-dynamics/issues/6#issuecomment-52558750 .

AntonSynytsia commented 10 years ago

Juleo, I'm not going to use such small objects, but when it comes to writing an engine wrapper, which will allow people to simulate their drawn models, I had to verify that such small objects are no good for simulation. Who knows? Maybe this could have been a bug.

Thanks for noting the Green and Divergence Theorem. I might need it someday.

Just so I know, to compile double precision, I have to

define _NEWTON_USE_DOUBLE in Newton.h ? or what file?

And then reduce/increase some min max definite values, right?

Anyway, thanks for making the min volume 100 times smaller, and for help :)

AntonSynytsia commented 10 years ago

Back to the topic now.

There was once an issue in Newton where convex bodies bounced on tree collisions : http://newtondynamics.com/forum/viewtopic.php?f=12&t=8650&p=55632#p55632. I can verify that this is fixed in Newton 3.13.

JulioJerez commented 10 years ago

Just remember that an object of size (0.01 x 0.01 x 0.01) we are talking of a body the size of a small dice, in general game do no deal with convex hull that size. the size could reduced be safely reduced another 1000 times and that will make a volume (0.001 x 0.001 x 0.001) which know is a very minuscule object to be a convex HULL.

did that change make a difference?

On Mon, Aug 18, 2014 at 5:33 PM, Anton notifications@github.com wrote:

Juleo, I'm not going to use such small objects, but when it comes to writing an engine wrapper, which will allow people to simulate their drawn models, I had to verify that such small objects are no good for simulation. Who knows? Maybe this could have been a bug.

Thanks for noting the Green and Divergence Theorem. I might need it someday.

Just so I know, to compile double precision, I have to

define _NEWTON_USE_DOUBLE in Newton.h ? or what file?

And then reduce/increase some min max definite values, right?

Anyway, thanks for making the min volume 100 times smaller, and for help :)

— Reply to this email directly or view it on GitHub https://github.com/MADEAPPS/newton-dynamics/issues/6#issuecomment-52575906 .

AntonSynytsia commented 10 years ago

Yes Juleo, small objects have proper centre of mass now. Although they go to sleep too soon. Its like they are in some intense fluid. As well, they penetrate a little too much when it comes to contacts. I think this is normal though. Such small objects shouldn't be handled anyway.

Here is an example in case your interested: serialized_world.bin

JulioJerez commented 10 years ago

The default penetration is 1/128 of a unit. that about 0.0075, you object is 0.01 is width so the penetration will be about 50% of the object size.

But the engine also support that by setting the skin width. you can se the skin with to the default penetration and the body will be almost flush with the ground, no withstanding numerical errors.

Julio

AntonSynytsia commented 10 years ago

Got it, THanks

AntonSynytsia commented 10 years ago

And how about the minimum value that lets the bodies go to sleep? Do you know what constant may it be,if any? I'm willing to reduce it too.

I suspect there is a minimum force. Any lower force will tell the body to go to sleep.

JulioJerez commented 10 years ago

That's no controllable in Newton. In Newton bodies go to sleep when the velocity and acceleration is zero.

you can control whether you want a body never go to sleep, or you can wake them up on each frame. But auto sleep is actually a physic principle http://en.wikipedia.org/wiki/Mechanical_equilibrium

Newton use the condition of force equal zero and velocity equal zero. That equilibrium is call static indifferent, there are other types which are more complex like dynamic equilibrium that can be supported, but not one has shown interest so it is no completed.

Dynamics equilibrium can for example make a body go to sleep if it is on top of another body that is moving with constant velocity, or a connotative acceleration.

This will be for example a space station, of a large ship in the ocean.

why do you want to manipulate the sleep?

AntonSynytsia commented 10 years ago

I don't want to manipulate sleep, but it seems small bodies go to sleep to soon.

Oh wait, disabling auto sleep still doesn't force such small bodies to lie flat or flat out on the floor. Its like they are in very stiff environment. Maybe its due to the fact that penetration is too deep.

AntonSynytsia commented 10 years ago

Ok, I noticed that the contact joints are generated too early (for small objects). In the picture below you can see that 4 contacts are generated even though only two corners are in contact with the floor. contact joints generated too early Is there such thing as minimum contact joint distance? Is it controllable? (In this example the auto-sleep is disabled)

JulioJerez commented 10 years ago

can you save a serialized file?

On Tue, Aug 19, 2014 at 11:48 AM, Anton notifications@github.com wrote:

Ok, I noticed that the contact joints are generated too early (for small objects). In the picture below you can see that 4 contacts are generated even though only two corners are in contact with the floor. [image: contact joints generated too early] https://cloud.githubusercontent.com/assets/2840847/3971191/696a86d0-27d1-11e4-8977-e035bf06627a.png Is there such thing as minimum contact joint distance? Is it controllable?

— Reply to this email directly or view it on GitHub https://github.com/MADEAPPS/newton-dynamics/issues/6#issuecomment-52680818 .

AntonSynytsia commented 10 years ago

serialized_world.bin

JulioJerez commented 10 years ago

I just played the demo and I see the problem, this is related to the contacts tolerance. It look really bad. It required some new coding to resolve it, but I will do it because it really looks bad. I am working on fixing it.

AntonSynytsia commented 10 years ago

Thank you

JulioJerez commented 10 years ago

Ok try this again. See if it is better. It was a very big change.

JulioJerez commented 10 years ago

Oh I forget you need to set the contact merge Tolerance by calling this functions void NewtonSetContactMergeTolerance (const NewtonWorld* const newtonWorld, dFloat tolerance); The default is 0.05 and will make you scene fail, but setting to 0.001 and it should work.

AntonSynytsia commented 10 years ago

Thanks, it does seem to behave way better than before.

I also had to reduce DG_RESTING_CONTACT_PENETRATION and DG_IMPULSIVE_CONTACT_PENETRATION to prevent penetration because on my appliation the update rate is constant 1/60.0 of a second, which is not always good when it comes to handling such small objects.

JulioJerez commented 10 years ago

I would not change those constant, It is better to set the collsion thickness by setting in in the material void NewtonMaterialSetSurfaceThickness (const NewtonWorld* const newtonWorld, int id0, int id1, dFloat thickness); changing those constant Newton may lead to instability.

Also why do you use such small objects? those object are not even centimeters. In the serialized demo the small boxes were 0.0067 in width, that's less that 7 milimiter, it is very hard to simulate such small object at iterative rate. The smallest velocity translate to large displace relative to eh body size.

AntonSynytsia commented 10 years ago

Oh, right, NewtonMaterialSetSurfaceThickness does the trick.