void tContact::_newtonContactProcess(const NewtonJoint * contactJoint, dFloat timeStep, int threadIndex) { Vec3 contactPosit, contactNormal; float contactBestSpeed = 0.5f; tContact * mtl = NULL; const NewtonBody * body0 = NewtonJointGetBody0(contactJoint); void * contact = NewtonContactJointGetFirstContact (contactJoint); while (contact) { float contactNormalSpeed; NewtonMaterial * material; // get the material for this contact; material = NewtonContactGetMaterial (contact); contactNormalSpeed = NewtonMaterialGetContactNormalSpeed (material); if (contactNormalSpeed > contactBestSpeed){ contactBestSpeed = contactNormalSpeed; contactBestSpeed = contactNormalSpeed; NewtonMaterialGetContactPositionAndNormal(material, &contactPosit.x, &contactNormal[0]); mtl = (tContact *)NewtonMaterialGetMaterialPairUserData(material); } contact = NewtonContactJointGetNextContact (contactJoint, contact); } if (mtl) mtl->OnContactProcess(&contactPosit, &contactNormal); }
static void UserContactRestitution (const NewtonJoint* contactJoint, dFloat timestep, int threadIndex) { dFloat Ixx; dFloat Iyy; dFloat Izz; dFloat mass; NewtonBody* body; NewtonBody* body0; NewtonBody* body1; // call the basic call back GenericContactProcess (contactJoint, timestep, threadIndex); body0 = NewtonJointGetBody0(contactJoint); body1 = NewtonJointGetBody1(contactJoint); body = body0; NewtonBodyGetMassMatrix (body, &mass, &Ixx, &Iyy, &Izz); if (mass == 0.0f) { body = body1; } NewtonCollision* const collision = NewtonBodyGetCollision(body); void* userData = NewtonCollisionGetUserData (collision); dFloat restitution = *((float*)&userData); for (void* contact = NewtonContactJointGetFirstContact (contactJoint); contact; contact = NewtonContactJointGetNextContact (contactJoint, contact)) { NewtonMaterial* const material = NewtonContactGetMaterial (contact); NewtonMaterialSetContactElasticity (material, restitution); } }
void GenericContactProcessCompatible(const void* const newtonContactJoint, float64 timestep, int threadIndex) { con_assert(newtonContactJoint != nullptr, "zero pointer") NewtonBody* body0 = NewtonJointGetBody0(static_cast<const NewtonJoint*>(newtonContactJoint)); NewtonBody* body1 = NewtonJointGetBody1(static_cast<const NewtonJoint*>(newtonContactJoint)); con_assert(body0 != nullptr && body1 != nullptr, "zero pointers") if (body0 != nullptr && body1 != nullptr) { iPhysicsBody* physicsBody0 = static_cast<iPhysicsBody*>(NewtonBodyGetUserData(static_cast<const NewtonBody*>(body0))); iPhysicsBody* physicsBody1 = static_cast<iPhysicsBody*>(NewtonBodyGetUserData(static_cast<const NewtonBody*>(body1))); con_assert(physicsBody0 != nullptr && physicsBody1 != nullptr, "zero pointers"); void* contact = NewtonContactJointGetFirstContact(static_cast<const NewtonJoint*>(newtonContactJoint)); NewtonMaterial* materialCombo = NewtonContactGetMaterial(contact); iPhysicsMaterialCombo* physicsMaterialCombo = static_cast<iPhysicsMaterialCombo*>(NewtonMaterialGetMaterialPairUserData(materialCombo)); if (physicsMaterialCombo != nullptr && physicsBody0 != nullptr && physicsBody1 != nullptr) { physicsMaterialCombo->contact(physicsBody0, physicsBody1); } } }
VALUE MSNewton::Bodies::get_force_in_between(VALUE self, VALUE v_body1, VALUE v_body2) { const NewtonBody* body1 = Util::value_to_body(v_body1); const NewtonBody* body2 = Util::value_to_body(v_body2); Util::validate_two_bodies(body1, body2); dVector net_force(0.0f, 0.0f, 0.0f); for (NewtonJoint* joint = NewtonBodyGetFirstContactJoint(body1); joint; joint = NewtonBodyGetNextContactJoint(body1, joint)) { if (NewtonJointGetBody0(joint) == body2 || NewtonJointGetBody1(joint) == body2) { for (void* contact = NewtonContactJointGetFirstContact(joint); contact; contact = NewtonContactJointGetNextContact(joint, contact)) { NewtonMaterial* material = NewtonContactGetMaterial(contact); dVector force; NewtonMaterialGetContactForce(material, body1, &force[0]); net_force += force; } } } const NewtonWorld* world = NewtonBodyGetWorld(body1); WorldData* world_data = (WorldData*)NewtonWorldGetUserData(world); //BodyData* body1_data = (BodyData*)NewtonBodyGetUserData(body1); //BodyData* body2_data = (BodyData*)NewtonBodyGetUserData(body2); /*if (world_data->gravity_enabled && (body1_data->gravity_enabled || body2_data->gravity_enabled)) { for (int i = 0; i < 3; ++i) net_force[i] *= world_data->inverse_scale; }*/ return Util::vector_to_value(net_force, world_data->inverse_scale4); }
dNewtonCollision* dNewtonContactMaterial::GetShape0 (const void* const contact) { NewtonBody* const body = NewtonJointGetBody0 ((NewtonJoint*)m_materialHandle); NewtonMaterial* const material = NewtonContactGetMaterial (contact); NewtonCollision* const collision = NewtonMaterialGetBodyCollidingShape (material, body); return (dNewtonCollision*)NewtonCollisionGetUserData(collision); }
void GenericContactProcess (const NewtonJoint* contactJoint, dFloat timestep, int threadIndex) { int isHightField; NewtonBody* body; NewtonCollision* collision; NewtonCollisionInfoRecord info; isHightField = 1; body = NewtonJointGetBody0 (contactJoint); collision = NewtonBodyGetCollision(body); NewtonCollisionGetInfo(collision, &info); if (info.m_collisionType != SERIALIZE_ID_HEIGHTFIELD) { body = NewtonJointGetBody1 (contactJoint); collision = NewtonBodyGetCollision(body); NewtonCollisionGetInfo(collision, &info); isHightField = (info.m_collisionType == SERIALIZE_ID_HEIGHTFIELD); } #define HOLE_IN_TERRAIN 10 if (isHightField) { void* nextContact; for (void* contact = NewtonContactJointGetFirstContact (contactJoint); contact; contact = nextContact) { int faceID; NewtonMaterial* material; nextContact = NewtonContactJointGetNextContact (contactJoint, contact); material = NewtonContactGetMaterial (contact); faceID = NewtonMaterialGetContactFaceAttribute (material); if (faceID == HOLE_INTERRAIN) { NewtonContactJointRemoveContact (contactJoint, contact); } } } }
static void PhysicsNewton_CollisionPuckSurfaceCB(const NewtonJoint *pContactJoint,dFloat fTimeStep,int ThreadIndex) { dVector Position(0.0f); // Get pointer to body NewtonBody* body = NewtonJointGetBody0(pContactJoint); dFloat mass, Ixx, Iyy, Izz; NewtonBodyGetMass(body, &mass, &Ixx, &Iyy, &Izz); if (mass == 0.0f) { body = NewtonJointGetBody1(pContactJoint); } dVector tableDir(0.0f, 0.0f, 1.0f, 0.0f); // Test to see if it is the friction calculation that is causing the side force // With this the Puck must go straight because it will be frictionless, the net force should not change direction for (void* contact = NewtonContactJointGetFirstContact (pContactJoint); contact; contact = NewtonContactJointGetNextContact (pContactJoint, contact)) { NewtonMaterial* const material = NewtonContactGetMaterial (contact); NewtonMaterialContactRotateTangentDirections(material, &tableDir[0]); // this the wrong way to make a friction less contact // NewtonMaterialSetContactFrictionCoef (material, 0.0f, 0.0f, 0); // NewtonMaterialSetContactFrictionCoef (material, 0.0f, 0.0f, 1); //This is the correct way to make a friction less contact // NewtonMaterialSetContactFrictionState (material, 0, 0); // NewtonMaterialSetContactFrictionState (material, 0, 1); } }
void GetForceOnStaticBody (NewtonBody* body, NewtonBody* staticBody) { for (NewtonJoint* joint = NewtonBodyGetFirstContactJoint (body); joint; joint = NewtonBodyGetNextContactJoint (body, joint)) { NewtonBody* body0; NewtonBody* body1; body0 = NewtonJointGetBody0(joint); body1 = NewtonJointGetBody1(joint); if ((body0 == staticBody) || (body1 == staticBody)) { for (void* contact = NewtonContactJointGetFirstContact (joint); contact; contact = NewtonContactJointGetNextContact (joint, contact)) { float forceMag; dVector point; dVector normal; NewtonMaterial* material; material = NewtonContactGetMaterial (contact); NewtonMaterialGetContactForce (material, &forceMag); NewtonMaterialGetContactPositionAndNormal (material, &point.m_x, &normal.m_x); dVector force (normal.Scale (-forceMag)); // do wherever you want withteh force } } } }
static void MagneticField (const NewtonJoint* contactJoint, dFloat timestep, int threadIndex) { dFloat magnetStregnth; const NewtonBody* body0; const NewtonBody* body1; const NewtonBody* magneticField; const NewtonBody* magneticPiece; body0 = NewtonJointGetBody0 (contactJoint); body1 = NewtonJointGetBody1 (contactJoint); // get the magnetic field body magneticPiece = body0; magneticField = body1; if (NewtonCollisionIsTriggerVolume (NewtonBodyGetCollision(body0))) { magneticPiece = body1; magneticField = body0; } _ASSERTE (NewtonCollisionIsTriggerVolume (NewtonBodyGetCollision(magneticField))); // calculate the magnetic force field dMatrix center; dMatrix location; NewtonBodyGetMatrix (magneticField, ¢er[0][0]); NewtonBodyGetMatrix (magneticPiece, &location[0][0]); Magnet* magnet; magnet = (Magnet*)NewtonBodyGetUserData(magneticField); magnetStregnth = magnet->m_magnetStregnth; // calculate the magnetic force; dFloat den; dVector force (center.m_posit - location.m_posit); den = force % force; den = magnetStregnth / (den * dSqrt (den) + 0.1f); force = force.Scale (den); // because we are modifiing one of the bodies membber in the call back, there uis a chace that // another materail can be operations on the same object at the same time of aother thread // therfore we need to make the assigmnet in a critical section. NewtonWorldCriticalSectionLock (NewtonBodyGetWorld (magneticPiece)); // add the magner force NewtonBodyAddForce (magneticPiece, &force[0]); force = force.Scale (-1.0f); NewtonBodyAddForce (magnet->m_magneticCore, &force[0]); // also if the body is sleeping fore it to wake up for this frame NewtonBodySetFreezeState (magneticPiece, 0); NewtonBodySetFreezeState (magnet->m_magneticCore, 0); // unlock the critical section NewtonWorldCriticalSectionUnlock (NewtonBodyGetWorld (magneticPiece)); }
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 CustomTriggerManager::UpdateTrigger (CustomTriggerController* const controller) { NewtonBody* const triggerBody = controller->GetBody(); dTree<NewtonBody*,NewtonBody*>& manifest = controller->m_manifest; for (NewtonJoint* joint = NewtonBodyGetFirstContactJoint (triggerBody); joint; joint = NewtonBodyGetNextContactJoint (triggerBody, joint)) { int isActive = NewtonJointIsActive (joint); NewtonBody* const body0 = NewtonJointGetBody0(joint); NewtonBody* const body1 = NewtonJointGetBody1(joint); NewtonBody* const passangerBody = (body0 != triggerBody) ? body0 : body1; if (isActive) { dTree<NewtonBody*,NewtonBody*>::dTreeNode* const passengerNode = manifest.Find (passangerBody); if (passengerNode) { EventCallback (controller, m_inTrigger, passangerBody); } else { CustomScopeLock lock (&m_lock); manifest.Insert (passangerBody, passangerBody); EventCallback (controller, m_enterTrigger, passangerBody); } } else { dTree<NewtonBody*,NewtonBody*>::dTreeNode* const passengerNode = manifest.Find (passangerBody); if (passengerNode) { EventCallback (controller, m_exitTrigger, passangerBody); CustomScopeLock lock (&m_lock); manifest.Remove (passengerNode); } } } }
static void OnGettingTheCollisionSubShapeFromMaterialCallback (const NewtonJoint* const contactJoint, dFloat timestep, int threadIndex) { NewtonBody* const body0 = NewtonJointGetBody0(contactJoint); GetCollisionSubShape(contactJoint, body0); NewtonBody* const body1 = NewtonJointGetBody1(contactJoint); GetCollisionSubShape(contactJoint, body1); }
// return the collision joint, if the body collide NewtonJoint* CheckIfBodiesCollide (NewtonBody* const body0, NewtonBody* const body1) { for (NewtonJoint* joint = NewtonBodyGetFirstContactJoint (body0); joint; joint = NewtonBodyGetNextContactJoint (body0, joint)) { if ((NewtonJointGetBody0(joint) == body1) || (NewtonJointGetBody1(joint) == body1)) { return joint; } } return NULL; }
dVector ForceBetweenBody (NewtonBody* const body0, NewtonBody* const body1) { dVector reactionforce (0.0f); for (NewtonJoint* joint = NewtonBodyGetFirstContactJoint(body0); joint; joint = NewtonBodyGetNextContactJoint(body0, joint)) { if (NewtonJointIsActive(joint) && (NewtonJointGetBody0(joint) == body0) || (NewtonJointGetBody0(joint) == body1)) { for (void* contact = NewtonContactJointGetFirstContact (joint); contact; contact = NewtonContactJointGetNextContact (joint, contact)) { dVector point(0.0f); dVector normal(0.0f); dVector contactForce(0.0f); NewtonMaterial* const material = NewtonContactGetMaterial (contact); NewtonMaterialGetContactPositionAndNormal (material, body0, &point.m_x, &normal.m_x); NewtonMaterialGetContactForce(material, body0, &contactForce[0]); reactionforce += contactForce; } break; } } return reactionforce; }
void dNewton::OnContactProcess (const NewtonJoint* const contactJoint, dFloat timestep, int threadIndex) { NewtonBody* const body = NewtonJointGetBody0 (contactJoint); dNewton* const world = (dNewton*) NewtonWorldGetUserData(NewtonBodyGetWorld (body)); // for (void* contact = NewtonContactJointGetFirstContact (contactJoint); contact; contact = NewtonContactJointGetNextContact (contactJoint, contact)) { // NewtonMaterial* const material = NewtonContactGetMaterial (contact); // NewtonMaterialSetContactFrictionCoef (material, 1.0f, 1.0f, 0); // NewtonMaterialSetContactFrictionCoef (material, 1.0f, 1.0f, 1); // } dNewtonContactMaterial contactMaterial ((void*)contactJoint); world->OnContactProcess (&contactMaterial, timestep, threadIndex); }
void GetContactOnBody (NewtonBody* const body) { for (NewtonJoint* joint = NewtonBodyGetFirstContactJoint (body); joint; joint = NewtonBodyGetNextContactJoint (body, joint)) { NewtonBody* const body0 = NewtonJointGetBody0(joint); NewtonBody* const body1 = NewtonJointGetBody1(joint); for (void* contact = NewtonContactJointGetFirstContact (joint); contact; contact = NewtonContactJointGetNextContact (joint, contact)) { NewtonMaterial* material = NewtonContactGetMaterial (contact); //dFloat forceMag; dVector point; dVector normal; //NewtonMaterialGetContactForce (material, &forceMag); NewtonMaterialGetContactPositionAndNormal (material, body1, &point.m_x, &normal.m_x); NewtonMaterialGetContactPositionAndNormal (material, body0, &point.m_x, &normal.m_x); // do whatever you want with the force } } }
//to get the collision points void HandlecollisionPoints (NewtonJoint* const contactjoint) { NewtonBody* const body0 = NewtonJointGetBody0(contactjoint); NewtonBody* const body1 = NewtonJointGetBody1(contactjoint); for (void* contact = NewtonContactJointGetFirstContact (contactjoint); contact; contact = NewtonContactJointGetNextContact (contactjoint, contact)) { NewtonMaterial* material = NewtonContactGetMaterial (contact); // do whatever you want here //dFloat forceMag; dVector point; dVector normal; //NewtonMaterialGetContactForce (material, &forceMag); NewtonMaterialGetContactPositionAndNormal (material, body0, &point.m_x, &normal.m_x); NewtonMaterialGetContactPositionAndNormal (material, body1, &point.m_x, &normal.m_x); // do whatever you want with the force } }
static void GenericContactProcess (const NewtonJoint* contactJoint, dFloat timestep, int threadIndex) { dFloat contactBestSpeed; dVector contactPosit; SoundEffect* bestSound; bestSound = NULL; contactBestSpeed = 0.5f; NewtonBody* const body0 = NewtonJointGetBody0(contactJoint); for (void* contact = NewtonContactJointGetFirstContact (contactJoint); contact; contact = NewtonContactJointGetNextContact (contactJoint, contact)) { dFloat contactNormalSpeed; NewtonMaterial* material; // get the material for this contact; material = NewtonContactGetMaterial (contact); contactNormalSpeed = NewtonMaterialGetContactNormalSpeed (material); if (contactNormalSpeed > contactBestSpeed){ dVector normal; contactBestSpeed = contactNormalSpeed; NewtonMaterialGetContactPositionAndNormal (material, body0, &contactPosit[0], &normal[0]); bestSound = (SoundEffect *)NewtonMaterialGetMaterialPairUserData (material); } } // now that we found we can play then if (bestSound) { // calculate the volume; dFloat volume; dFloat dist2; dVector eyePoint (GetCameraEyePoint() - contactPosit); dist2 = eyePoint % eyePoint; if (dist2 < (MAX_SOUND_DISTANCE * MAX_SOUND_DISTANCE)) { volume = 1.0f; if (dist2 > (MIN_SOUND_DISTANCE * MIN_SOUND_DISTANCE)) { volume = 1.0f - (dSqrt (dist2) - MIN_SOUND_DISTANCE) / (MAX_SOUND_DISTANCE - MIN_SOUND_DISTANCE); } bestSound->m_manager->Play(bestSound->m_sound, volume, 0); } } }
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 applyCarCollisionForce(const NewtonJoint* contact, dFloat timestep, int threadIndex) { void * userData1 = NewtonBodyGetUserData(NewtonJointGetBody0(contact)); void * userData2 = NewtonBodyGetUserData(NewtonJointGetBody1(contact)); if(userData1 == 0 || userData2 == 0) { return; } Car * car1 = (Car *)userData1; Car * car2 = (Car *)userData2; NewtonJoint * carContact = (NewtonJoint *) NewtonContactJointGetFirstContact(contact); do { dFloat collisionSpeed = NewtonMaterialGetContactNormalSpeed( NewtonContactGetMaterial(carContact) ); collisionSpeed = dAbs(collisionSpeed); if(collisionSpeed > 3) { car1->applyDamagePoints(collisionSpeed); car2->applyDamagePoints(collisionSpeed); break; } carContact = (NewtonJoint *) NewtonContactJointGetNextContact(contact, carContact); } while(carContact); }
static void UserContactRestitution (const NewtonJoint* contactJoint, dFloat timestep, int threadIndex) { // call the basic call back GenericContactProcess (contactJoint, timestep, threadIndex); const NewtonBody* const body0 = NewtonJointGetBody0(contactJoint); const NewtonBody* const body1 = NewtonJointGetBody1(contactJoint); //now core 3.14 can have per collision user data const NewtonCollision* const collision0 = NewtonBodyGetCollision(body0); const NewtonCollision* const collision1 = NewtonBodyGetCollision(body1); NewtonCollisionMaterial material0; NewtonCollisionMaterial material1; NewtonCollisionGetMaterial(collision0, &material0); NewtonCollisionGetMaterial(collision1, &material1); dAssert((material0.m_userId == 1) || (material1.m_userId == 1)); dFloat restitution = dMax(material0.m_userParam[0], material1.m_userParam[0]); for (void* contact = NewtonContactJointGetFirstContact (contactJoint); contact; contact = NewtonContactJointGetNextContact (contactJoint, contact)) { NewtonMaterial* const material = NewtonContactGetMaterial (contact); NewtonMaterialSetContactElasticity (material, restitution); } }
void PhysWorld3D::ProcessContact(const NewtonJoint* const contactJoint, float timestep, int threadIndex) { RigidBody3D* bodyA = static_cast<RigidBody3D*>(NewtonBodyGetUserData(NewtonJointGetBody0(contactJoint))); RigidBody3D* bodyB = static_cast<RigidBody3D*>(NewtonBodyGetUserData(NewtonJointGetBody1(contactJoint))); assert(bodyA && bodyB); using ContactJoint = void*; // Query all joints first, to prevent removing a joint from the list while iterating on it StackVector<ContactJoint> contacts = NazaraStackVector(ContactJoint, NewtonContactJointGetContactCount(contactJoint)); for (ContactJoint contact = NewtonContactJointGetFirstContact(contactJoint); contact; contact = NewtonContactJointGetNextContact(contactJoint, contact)) contacts.push_back(contact); for (ContactJoint contact : contacts) { NewtonMaterial* material = NewtonContactGetMaterial(contact); Callback* callbackData = static_cast<Callback*>(NewtonMaterialGetMaterialPairUserData(material)); assert(callbackData); assert(callbackData->collisionCallback); if (!callbackData->collisionCallback(*bodyA, *bodyB)) NewtonContactJointRemoveContact(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); } }
dNewtonBody* dNewtonContactMaterial::GetBody0 () const { NewtonBody* const body = NewtonJointGetBody0 ((NewtonJoint*)m_materialHandle); return (dNewtonBody*) NewtonBodyGetUserData (body); }
void cPhysicsMaterialNewton::ProcessContactCallback(const NewtonJoint* apJoint, float afTimeStep, int alThreadIndex) { cPhysicsContactData ContactData; int lContactNum = 0; iPhysicsBody * pContactBody1 = (iPhysicsBody*) NewtonBodyGetUserData(NewtonJointGetBody0(apJoint)); iPhysicsBody * pContactBody2 = (iPhysicsBody*) NewtonBodyGetUserData(NewtonJointGetBody1(apJoint)); for (void* pContact = NewtonContactJointGetFirstContact(apJoint); pContact; pContact = NewtonContactJointGetNextContact(apJoint, pContact)) { NewtonMaterial* pMaterial = NewtonContactGetMaterial(pContact); //Log(" Process contact between body '%s' and '%s'.\n",pContactBody1->GetName().c_str(), // pContactBody2->GetName().c_str()); //Normal speed float fNormSpeed = NewtonMaterialGetContactNormalSpeed(pMaterial); if (ContactData.mfMaxContactNormalSpeed < fNormSpeed) ContactData.mfMaxContactNormalSpeed = fNormSpeed; //Tangent speed float fTanSpeed0 = NewtonMaterialGetContactTangentSpeed(pMaterial, 0); float fTanSpeed1 = NewtonMaterialGetContactTangentSpeed(pMaterial, 1); if(std::abs(ContactData.mfMaxContactTangentSpeed) < std::abs(fTanSpeed0)) ContactData.mfMaxContactTangentSpeed = fTanSpeed0; if(std::abs(ContactData.mfMaxContactTangentSpeed) < std::abs(fTanSpeed1)) ContactData.mfMaxContactTangentSpeed = fTanSpeed1; //Force cVector3f vForce; NewtonMaterialGetContactForce(pMaterial,vForce.v); ContactData.mvForce += vForce; //Position and normal cVector3f vPos, vNormal; NewtonMaterialGetContactPositionAndNormal(pMaterial,vPos.v, vNormal.v); ContactData.mvContactNormal += vNormal; ContactData.mvContactPosition += vPos; //Log(" Norm: %f Tan0: %f Tan1: %f\n",fNormSpeed, fTanSpeed0, fTanSpeed1); //Log("Force: %s step %f\n", vForce.ToString().c_str(), afTimestep); if(pContactBody1->GetWorld()->GetSaveContactPoints()) { cCollidePoint collidePoint; collidePoint.mfDepth = 1; NewtonMaterialGetContactPositionAndNormal (pMaterial, collidePoint.mvPoint.v, collidePoint.mvNormal.v); pContactBody1->GetWorld()->GetContactPoints()->push_back(collidePoint); } lContactNum++; } //Log("--- End contact between body '%s' and '%s'.\n",mpContactBody1->GetName().c_str(), // mpContactBody2->GetName().c_str()); if(lContactNum <= 0) return; iPhysicsMaterial *pMaterial1 = pContactBody1->GetMaterial(); iPhysicsMaterial *pMaterial2 = pContactBody2->GetMaterial(); ContactData.mvContactNormal = ContactData.mvContactNormal / (float)lContactNum; ContactData.mvContactPosition = ContactData.mvContactPosition / (float)lContactNum; pMaterial1->GetSurfaceData()->CreateImpactEffect(ContactData.mfMaxContactNormalSpeed, ContactData.mvContactPosition, lContactNum,pMaterial2->GetSurfaceData()); int lPrio1 = pMaterial1->GetSurfaceData()->GetPriority(); int lPrio2 = pMaterial2->GetSurfaceData()->GetPriority(); if(lPrio1 >= lPrio2) { if(std::abs(ContactData.mfMaxContactNormalSpeed) > 0) pMaterial1->GetSurfaceData()->OnImpact(ContactData.mfMaxContactNormalSpeed, ContactData.mvContactPosition, lContactNum,pContactBody1); if(std::abs(ContactData.mfMaxContactTangentSpeed) > 0) pMaterial1->GetSurfaceData()->OnSlide(ContactData.mfMaxContactTangentSpeed, ContactData.mvContactPosition, lContactNum,pContactBody1,pContactBody2); } if(lPrio2 >= lPrio1 && pMaterial2 != pMaterial1) { if(std::abs(ContactData.mfMaxContactNormalSpeed) > 0) pMaterial2->GetSurfaceData()->OnImpact(ContactData.mfMaxContactNormalSpeed, ContactData.mvContactPosition, lContactNum,pContactBody2); if(std::abs(ContactData.mfMaxContactTangentSpeed) > 0) pMaterial2->GetSurfaceData()->OnSlide(ContactData.mfMaxContactTangentSpeed, ContactData.mvContactPosition, lContactNum,pContactBody2,pContactBody1); } pContactBody1->OnCollide(pContactBody2,&ContactData); pContactBody2->OnCollide(pContactBody1,&ContactData); }
void GenericContactProcess (const NewtonJoint* contactJoint, dFloat timestep, int threadIndex) { #if 0 dFloat speed0; dFloat speed1; SpecialEffectStruct* currectEffect; // get the pointer to the special effect structure currectEffect = (SpecialEffectStruct *)NewtonMaterialGetMaterialPairUserData (material); // save the contact information NewtonMaterialGetContactPositionAndNormal (material, &currectEffect->m_position.m_x, &currectEffect->m_normal.m_x); NewtonMaterialGetContactTangentDirections (material, &currectEffect->m_tangentDir0.m_x, &currectEffect->m_tangentDir1.m_x); // Get the maximum normal speed of this impact. this can be used for positioning collision sound speed0 = NewtonMaterialGetContactNormalSpeed (material); if (speed0 > currectEffect->m_contactMaxNormalSpeed) { // save the position of the contact (for 3d sound of particles effects) currectEffect->m_contactMaxNormalSpeed = speed0; } // get the maximum of the two sliding contact speed speed0 = NewtonMaterialGetContactTangentSpeed (material, 0); speed1 = NewtonMaterialGetContactTangentSpeed (material, 1); if (speed1 > speed0) { speed0 = speed1; } // Get the maximum tangent speed of this contact. this can be used for particles(sparks) of playing scratch sounds if (speed0 > currectEffect->m_contactMaxTangentSpeed) { // save the position of the contact (for 3d sound of particles effects) currectEffect->m_contactMaxTangentSpeed = speed0; } #endif // read the table direction // dVector dir (tableDir); // dVector updir (TableDir); // NewtonBody* const body = NewtonJointGetBody0(contactJoint); // for (void* contact = NewtonContactJointGetFirstContact (contactJoint); contact; contact = NewtonContactJointGetNextContact (contactJoint, contact)) { // dFloat speed; // dVector point; // dVector normal; // dVector dir0; // dVector dir1; // dVector force; // NewtonMaterial* material; // // material = NewtonContactGetMaterial (contact); // NewtonMaterialGetContactPositionAndNormal (material, body, &point.m_x, &normal.m_x); // // // if the normal is vertical is large the say 40 degrees // if (fabsf (normal % upDir) > 0.7f) { // // rotate the normal to be aligned with the table direction // NewtonMaterialContactRotateTangentDirections (material, dir); // } // } NewtonBody* const body = NewtonJointGetBody0(contactJoint); for (void* contact = NewtonContactJointGetFirstContact (contactJoint); contact; contact = NewtonContactJointGetNextContact (contactJoint, contact)) { dVector point; dVector normal; dVector dir0; dVector dir1; dVector force; NewtonMaterial* const material = NewtonContactGetMaterial (contact); NewtonMaterialGetContactForce (material, body, &force.m_x); NewtonMaterialGetContactPositionAndNormal (material, body, &point.m_x, &normal.m_x); NewtonMaterialGetContactTangentDirections (material, body, &dir0.m_x, &dir1.m_x); //dFloat speed = NewtonMaterialGetContactNormalSpeed(material); //speed = NewtonMaterialGetContactNormalSpeed(material); // play sound base of the contact speed. // } }