// this callback is called for every contact between the two bodies int Physics::genericContactProcess( const NewtonMaterial* p_material, const NewtonContact* p_contact ) { float speed0; float speed1; osg::Vec3f normal; // get the maximun normal speed of this impact. speed0 = NewtonMaterialGetContactNormalSpeed( p_material, p_contact ); if ( speed0 > s_colStruct->_contactMaxNormalSpeed ) { // save the position of the contact ( e.g. for 3d sound for particle effects ) s_colStruct->_contactMaxNormalSpeed = speed0; NewtonMaterialGetContactPositionAndNormal( p_material, &s_colStruct->_position._v[ 0 ], &normal._v[ 0 ] ); } // get the maximun of the two sliding contact speeds speed0 = NewtonMaterialGetContactTangentSpeed( p_material, p_contact, 0 ); speed1 = NewtonMaterialGetContactTangentSpeed( p_material, p_contact, 1 ); if ( speed1 > speed0 ) speed0 = speed1; // get the maximun tangent speed of this contact. this can be used e.g. for particles(sparks) or playing scratch sounds if ( speed0 > s_colStruct->_contactMaxTangentSpeed ) { // save the position of the contact (for 3d sound or particle effects) s_colStruct->_contactMaxTangentSpeed = speed0; NewtonMaterialGetContactPositionAndNormal( p_material, &s_colStruct->_position._v[ 0 ], &normal._v[ 0 ] ); } // return one to tell Newton we want to accept this contact return 1; }
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. // } }
dFloat Material::GetContactTangentSpeed ( const NewtonContact* contactlHandle, int index) { return NewtonMaterialGetContactTangentSpeed( m_material, contactlHandle, index ); }
virtual Math::Real getContactTangentSpeed(bool _primary = true) const { return NewtonMaterialGetContactTangentSpeed(m_pMaterial, m_pContact, _primary ? 0 : 1); }