I don't not know how newtons material system is supposed to work by default,
also i can't verify if inelasic collisions work as expected for me (i use them for ragdoll bodies).
ATI forced me to remove OpenGL immediate mode and i have not yet updated physics stuff, so it's broken at the moment for me.
However - two things may eventually help...
1. Restitution is dependent on both materials involved in a collision and newton allows the user to select the proper value from a table for example, but it's up to the user to implement this.
Code fragment below is how i did this, but i did not care if there is a 'automatic' and thus faster way to do it. There should be - in fact i do not use Newton material at all, i just overwrite it by replacing it with my values in a callback that is called for every contact, set up with:
NewtonMaterialSetCollisionCallback (world, defMatID, defMatID, this, GenericOnAABBOverlap, GenericContactProcess);
Maybe you wanna play around with something like that to see if you could fix it his way.
The callback is interesting because you could also modify contact velocity for things like treadmills etc.
I assume you set softness for the default material and use it for all bodies, thus it should work already, but it may be worth to try out.
2. Maybe the up vector joint corrects the orientation very stiff and thus with large torque, causing the bouncy behaviour.
Does bouncing also happen to non player bodies without the joint?
You could try to reduce the joints max friction (== max force / torque),
or replace it entirely with a torque based method - i could help here...
Using capsule instead box should also limit this effect.
- Code: Select all
static void GenericContactProcess (const NewtonJoint* contactJoint, dFloat timestep, int threadIndex)
{
const NewtonBody* body0 = NewtonJointGetBody0(contactJoint);
const NewtonBody* body1 = NewtonJointGetBody1(contactJoint);
NewtonWorld *world = NewtonBodyGetWorld (body0);
int defMatId = NewtonMaterialGetDefaultGroupID (world);
PhysicsWorld *pworld = (PhysicsWorld*) NewtonMaterialGetUserData (world, defMatId, defMatId);
// get my data...
BodyData *data0 = (BodyData*) BodyGetUserData ((Body*)body0);
BodyData *data1 = (BodyData*) BodyGetUserData ((Body*)body1);
Material &mat0 = pworld->materials[data0->materialIndex];
Material &mat1 = pworld->materials[data1->materialIndex];
// do some simple average or min value over both materials
float staticFriction = min(mat0.staticFriction, mat1.staticFriction);
float dynamicFriction = min(mat0.dynamicFriction, mat1.dynamicFriction);
float restitution = (mat0.restitution + mat1.restitution) * 0.5f;
// overwrite anything with those values...
for (void* contact = NewtonContactJointGetFirstContact (contactJoint); contact;
contact = NewtonContactJointGetNextContact (contactJoint, contact))
{
NewtonMaterial* material = NewtonContactGetMaterial (contact);
NewtonMaterialSetContactFrictionCoef (material, staticFriction, dynamicFriction, 0);
NewtonMaterialSetContactFrictionCoef (material, staticFriction, dynamicFriction, 1);
NewtonMaterialSetContactElasticity (material, restitution); // 1 = bounce forever