Having problems with materials

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Having problems with materials

Postby Devwave » Sun Dec 21, 2014 7:35 pm

Hello

I created a simple project to test properties like friction and elasticity of materials. My goal is to make a character controller that can jump, fly, etc. based on physics of games like WoW, Perfect World, etc. I'm currently using only the default material.

My problem is with the elasticity. Even when I set it to zero the character keeps bouncing when he falls on the floor and when he walks up mountains (he bounces when I stop walking).

And I have alot of questions about how to make things right in this library: I'm using the velocity to move the character with NewtonBodySetVelocity(body, vel). To simulate the sudden stop of movement when the player stops walking in these games I set the horizontal speed to zero.

I need help.
Thanks.
Devwave
 
Posts: 6
Joined: Tue Nov 11, 2014 11:46 pm

Re: Having problems with materials

Postby AntonSynytsia » Sun Dec 21, 2014 11:54 pm

I would suggest looking in demos sandbox, and see how elasticity is done:

There are various of tutorials in demos sandbox that could help you, even the player controller.

If you haven't so, download latest repository from Github, and try the demos sandbox. You will have to compile it though. The project is located in ...\trunk\applications\demosSandbox\projects\YOUR_DESIRED_PROJECT

The tutorials are in ...\trunk\applications\demosSandbox\sdkDemos\demos\

Particularly, the elasticity tutorial is here: ...\trunk\applications\demosSandbox\sdkDemos\demos\BasicRestitution.cpp

There is also an available pre-compiled DemosSandbox.exe that you can download:
viewtopic.php?f=9&t=8696
AntonSynytsia
 
Posts: 193
Joined: Sat Dec 28, 2013 6:36 pm

Re: Having problems with materials

Postby JoeJ » Mon Dec 22, 2014 4:44 pm

Maybe the problems come from setting velocity.
It should be better to add a force instead, so Newton can calculate the velocity dependent on other influnces (collisions).

Here's a code snippet from mine:

Code: Select all
float mass, Ixx, Iyy, Izz; BodyGetMassMatrix (playerBody, mass, Ixx, Iyy, Izz);
      sMat4 matrix;      BodyGetMatrix(playerBody, matrix);
      sVec3 curLinvel;   BodyGetVelocity (playerBody, curLinvel);
      pos = matrix[3];
      
      sVec3 l = targetLinVel; // this is what you have
      l -= curLinvel;
      l -= gravityDir.Dot (l) * gravityDir; // no force at grav direction
      if (jump) l += gravityDir * 15.0;
      sVec3 force = 0.3 * l * (mass / timestep);
      force.SmoothLimitLength2(mass * 400.0); // just something that prevents huge forces
// now store force and apply later in force torque callback


Edit: To keep the player (capsule) upright i use a 'look at' joint, which works well. I guess that's the same as Newtons UpVector joint. Also I control orientation with a torque, but i'd ignore any orientation control until the positioning works.
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Having problems with materials

Postby Devwave » Wed Dec 24, 2014 1:36 pm

Thanks.
I got to implement the movement by force, but the restitution issue still continues.
Even when I set restitution to 0 the player bounces after hitting the floor having only the gravity as acting force.
What I expected in this case was to have a perfectly inelastic collision. The elasticity is working for other values but I really wanted a perfectly inelastic collision.
My basic setup is:
- A character made with a convex hull collision of a 3D modelled bounding box;
- Up vector joint on the character;
- The floor is a body made of a non-self-intersecting tree collision with mass 0.
- World update with fixed timestep of 1 / 60.
What could be the reason for this?
Devwave
 
Posts: 6
Joined: Tue Nov 11, 2014 11:46 pm

Re: Having problems with materials

Postby JoeJ » Thu Dec 25, 2014 2:54 pm

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
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 3 guests