static void UserContactFriction (const NewtonJoint* contactJoint, dFloat timestep, int threadIndex) { dFloat Ixx; dFloat Iyy; dFloat Izz; dFloat mass; // call the basic call back GenericContactProcess (contactJoint, timestep, threadIndex); const NewtonBody* const body0 = NewtonJointGetBody0(contactJoint); const NewtonBody* const body1 = NewtonJointGetBody1(contactJoint); const NewtonBody* body = body0; NewtonBodyGetMass (body, &mass, &Ixx, &Iyy, &Izz); if (mass == 0.0f) { body = body1; } //now core 300 can have per collision user data NewtonCollision* const collision = NewtonBodyGetCollision(body); void* userData = NewtonCollisionGetUserData (collision); dFloat frictionValue = *((dFloat*)&userData); for (void* contact = NewtonContactJointGetFirstContact (contactJoint); contact; contact = NewtonContactJointGetNextContact (contactJoint, contact)) { NewtonMaterial* const material = NewtonContactGetMaterial (contact); NewtonMaterialSetContactFrictionCoef (material, frictionValue + 0.1f, frictionValue, 0); NewtonMaterialSetContactFrictionCoef (material, frictionValue + 0.1f, frictionValue, 1); } }
void PhysicsWorld::onContactCallback(const NewtonJoint* contactJoint, F32 timestep, int threadIndex) { const NewtonBody* body0 = NewtonJointGetBody0(contactJoint); const NewtonBody* body1 = NewtonJointGetBody1(contactJoint); F32 friction0 = 0.01; F32 elasticity0 = 0.001; F32 friction1 = friction0; F32 elasticity1 = elasticity0; void* userData = NewtonBodyGetUserData(body0); if(userData) { friction0 = static_cast<PhysicsBody*>(userData)->getFriction(); elasticity0 = static_cast<PhysicsBody*>(userData)->getElasticity(); } userData = NewtonBodyGetUserData(body1); if(userData) { friction1 = static_cast<PhysicsBody*>(userData)->getFriction(); elasticity1 = static_cast<PhysicsBody*>(userData)->getElasticity(); } F32 friction = friction0 + friction1; F32 elasticity = elasticity0 + elasticity1; void* contact = NewtonContactJointGetFirstContact(contactJoint); while(contact) { NewtonMaterial* material = NewtonContactGetMaterial(contact); NewtonMaterialSetContactFrictionCoef(material, friction + 0.1, friction, 0); NewtonMaterialSetContactFrictionCoef(material, friction + 0.1, friction, 1); NewtonMaterialSetContactElasticity(material, elasticity); contact = NewtonContactJointGetNextContact(contactJoint, contact); } }
void ApplyTracktionForce (dFloat timestep, const NewtonBody* track) { dVector veloc; dVector omega; dMatrix matrix; NewtonBodyGetOmega(m_body0, &omega[0]); NewtonBodyGetVelocity(m_body0, &veloc[0]); NewtonBodyGetMatrix (m_body0, &matrix[0][0]); // itetate over the contact list and condition each contact direction anc contact acclerations for (NewtonJoint* contactJoint = NewtonBodyGetFirstContactJoint (track); contactJoint; contactJoint = NewtonBodyGetNextContactJoint (track, contactJoint)) { _ASSERTE ((NewtonJointGetBody0 (contactJoint) == track) || (NewtonJointGetBody1 (contactJoint) == track)); #ifdef REMOVE_REDUNDAT_CONTACT int contactCount; contactCount = NewtonContactJointGetContactCount(contactJoint); if (contactCount > 2) { // project the contact to the bounday of the conve hull o fteh trhread foot ptint dFloat maxDist; dFloat minDist; void* minContact; void* maxContact; dMatrix matrix; minContact = NULL; maxContact = NULL; NewtonBodyGetMatrix (track, &matrix[0][0]); maxDist = -1.0e10f; minDist = -1.0e10f; //find the best two contacts and remove all others for (void* contact = NewtonContactJointGetFirstContact (contactJoint); contact; contact = NewtonContactJointGetNextContact (contactJoint, contact)) { dFloat dist; dVector point; dVector normal; NewtonMaterial* material; material = NewtonContactGetMaterial (contact); NewtonMaterialGetContactPositionAndNormal(material, &point[0], &normal[0]); dist = matrix.m_front % point; if (dist > maxDist) { maxDist = dist; maxContact = contact; } if (-dist > minDist) { minDist = -dist; minContact = contact; } } // now delete all reduntact contacts void* nextContact; NewtonWorld* world; world = NewtonBodyGetWorld (track); NewtonWorldCriticalSectionLock(world); for (void* contact = NewtonContactJointGetFirstContact (contactJoint); contact; contact = nextContact) { nextContact = NewtonContactJointGetNextContact (contactJoint, contact); if (!((contact == minContact) || (contact == maxContact))) { NewtonContactJointRemoveContact (contactJoint, contact); } } NewtonWorldCriticalSectionUnlock(world); } #endif for (void* contact = NewtonContactJointGetFirstContact (contactJoint); contact; contact = NewtonContactJointGetNextContact (contactJoint, contact)) { dFloat speed; dFloat accel; dVector point; dVector normal; dVector dir0; dVector dir1; NewtonMaterial* material; material = NewtonContactGetMaterial (contact); NewtonMaterialContactRotateTangentDirections (material, &matrix.m_front[0]); NewtonMaterialGetContactPositionAndNormal(material, &point[0], &normal[0]); NewtonMaterialGetContactTangentDirections (material, &dir0[0], &dir1[0]); dVector posit (point - matrix.m_posit); veloc += omega * posit; speed = veloc % dir0; // accel = m_accel - 0.1f * speed + (((posit % m_matrix.m_right) > 0.0f) ? m_turnAccel : - m_turnAccel); accel = m_veloc + (((posit % matrix.m_right) > 0.0f) ? m_turnVeloc : - m_turnVeloc); accel = (accel - speed) * 0.5f / timestep; // NewtonMaterialSetContactStaticFrictionCoef (material, 1.0f, 0); // NewtonMaterialSetContactKineticFrictionCoef (material, 1.0f, 0); NewtonMaterialSetContactFrictionCoef (material, 1.0f, 1.0f, 0); // NewtonMaterialSetContactStaticFrictionCoef (material, 0.5f, 1); // NewtonMaterialSetContactKineticFrictionCoef (material, 0.5f, 1); NewtonMaterialSetContactFrictionCoef (material, 0.5f, 0.5f, 1); NewtonMaterialSetContactTangentAcceleration (material, accel, 0); } // for debug purpose show the contact ShowJointContacts (contactJoint); } }
void dNewtonContactMaterial::SetContactFrictionCoef (const void* const contact, dFloat staticFrictionCoef, dFloat kineticFrictionCoef, int index) { NewtonMaterial* const material = NewtonContactGetMaterial (contact); NewtonMaterialSetContactFrictionCoef (material, staticFrictionCoef, kineticFrictionCoef, index); }