The material system in Newton is a bilateral, meaning that the body properties are per pairwise interactions, this have the advantage that it lead to more realistic simulation but is have the disadvantage that it requieres more work to set it up.
However this method is more powerful and it is the prefer method for more seriuos or larger projects
Most physic systems implement the unilateral material approach. In this system material properties are assigned to the rigid body and not to pair of rigid bodies. This method has the advantage that is simple to get it going. However does not always lead to realistic simulations.
One way to implement unilateral material system in Newton is as followes:
-Create a data structure to store the material properties
- Code: Select all
Struct MyAppMaterial
{
float m_restitution,
float m_static frition;
float m_keinetic_frition;
//other material members
...
...
};
Store a material or a reference to a material with the each application graphics object controlled by a rigid body.
also declare three static material callbacks on the base class of your visual body
and three virtual funtions to be called from the static materila functions for eact body. The follwing pseudo code shows this.
- Code: Select all
Struct ApplicationObject
{
// applicatiopn data
...
...
MyAppMaterial m_refMaterial;
private:
// collision method
static ApplicationObject* m_obj0;
static ApplicationObject* m_obj1;
static NewtonBody* m_savedBody0;
static NewtonBody* m_savedBody1;
virtual int OnAABBOverlap (const NewtonBody* me, const NewtonBody* otherbody, const NewtonMaterial* material) = 0;
virtual int OnContactCollision (const NewtonBody* me, const NewtonBody* otherbody, const NewtonMaterial* material) = 0;
virtual void OnContactCollisionEnd (const NewtonMaterial* material) = 0;
// callback material integace to phsyics
static int OnAABBOverlap (const NewtonMaterial* material, const NewtonBody* body0, const NewtonBody* body1)
{
ApplicationObject* obj0;
ApplicationObject* obj1;
m_savedBody0 = body0;
m_savedBody1 = body1;
m_obj0 = NewtonGetUserData (body0);
m_obj1 = NewtonGetUserData (body1);
return obj0->OnAABBOverlap (bodu0, body1, material) ||
obj1->OnAABBOverlap (body1, body0, material);
}
static int OnContactCollision (const NewtonMaterial* material, const NewtonBody* body0, const NewtonBody* body1);
{
return obj0->OnContactCollision (body0, body1, material) ||
obj1->OnContactCollision (body1, body0, material);
}
static void OnContactCollisionEnd (const NewtonMaterial* material)
{
obj0->OnContactCollisionEnd (material);
obj1->OnContactCollisionEnd (material);
}
}
};
Set the three static material callbacks for the default-default material pairs.
When creating rigid bodies leave the material ID set to the default, that way all callback will be directed to the default-default material pair.
At this point the callback will have two materials and a policy will have to be establish to determine which material will provide the dominant friction, restitiuion.
Many solution can be applied, for example the friction could be set to the highest of the two material or to the average or to the median, or any other method.