Changeset View
Changeset View
Standalone View
Standalone View
extern/bullet2/src/BulletCollision/Gimpact/btContactProcessing.cpp
| Show All 21 Lines | |||||
| #define MAX_COINCIDENT 8 | #define MAX_COINCIDENT 8 | ||||
| struct CONTACT_KEY_TOKEN | struct CONTACT_KEY_TOKEN | ||||
| { | { | ||||
| unsigned int m_key; | unsigned int m_key; | ||||
| int m_value; | int m_value; | ||||
| CONTACT_KEY_TOKEN() | CONTACT_KEY_TOKEN() | ||||
| { | { | ||||
| } | } | ||||
| CONTACT_KEY_TOKEN(unsigned int key,int token) | CONTACT_KEY_TOKEN(unsigned int key, int token) | ||||
| { | { | ||||
| m_key = key; | m_key = key; | ||||
| m_value = token; | m_value = token; | ||||
| } | } | ||||
| CONTACT_KEY_TOKEN(const CONTACT_KEY_TOKEN& rtoken) | CONTACT_KEY_TOKEN(const CONTACT_KEY_TOKEN& rtoken) | ||||
| { | { | ||||
| m_key = rtoken.m_key; | m_key = rtoken.m_key; | ||||
| m_value = rtoken.m_value; | m_value = rtoken.m_value; | ||||
| } | } | ||||
| inline bool operator <(const CONTACT_KEY_TOKEN& other) const | inline bool operator<(const CONTACT_KEY_TOKEN& other) const | ||||
| { | { | ||||
| return (m_key < other.m_key); | return (m_key < other.m_key); | ||||
| } | } | ||||
| inline bool operator >(const CONTACT_KEY_TOKEN& other) const | inline bool operator>(const CONTACT_KEY_TOKEN& other) const | ||||
| { | { | ||||
| return (m_key > other.m_key); | return (m_key > other.m_key); | ||||
| } | } | ||||
| }; | }; | ||||
| class CONTACT_KEY_TOKEN_COMP | class CONTACT_KEY_TOKEN_COMP | ||||
| { | { | ||||
| public: | public: | ||||
| bool operator() ( const CONTACT_KEY_TOKEN& a, const CONTACT_KEY_TOKEN& b ) const | bool operator()(const CONTACT_KEY_TOKEN& a, const CONTACT_KEY_TOKEN& b) const | ||||
| { | { | ||||
| return ( a < b ); | return (a < b); | ||||
| } | } | ||||
| }; | }; | ||||
| void btContactArray::merge_contacts( | void btContactArray::merge_contacts( | ||||
| const btContactArray & contacts, bool normal_contact_average) | const btContactArray& contacts, bool normal_contact_average) | ||||
| { | { | ||||
| clear(); | clear(); | ||||
| int i; | int i; | ||||
| if(contacts.size()==0) return; | if (contacts.size() == 0) return; | ||||
| if(contacts.size()==1) | if (contacts.size() == 1) | ||||
| { | { | ||||
| push_back(contacts[0]); | push_back(contacts[0]); | ||||
| return; | return; | ||||
| } | } | ||||
| btAlignedObjectArray<CONTACT_KEY_TOKEN> keycontacts; | btAlignedObjectArray<CONTACT_KEY_TOKEN> keycontacts; | ||||
| keycontacts.reserve(contacts.size()); | keycontacts.reserve(contacts.size()); | ||||
| //fill key contacts | //fill key contacts | ||||
| for ( i = 0;i<contacts.size() ;i++ ) | for (i = 0; i < contacts.size(); i++) | ||||
| { | { | ||||
| keycontacts.push_back(CONTACT_KEY_TOKEN(contacts[i].calc_key_contact(),i)); | keycontacts.push_back(CONTACT_KEY_TOKEN(contacts[i].calc_key_contact(), i)); | ||||
| } | } | ||||
| //sort keys | //sort keys | ||||
| keycontacts.quickSort(CONTACT_KEY_TOKEN_COMP()); | keycontacts.quickSort(CONTACT_KEY_TOKEN_COMP()); | ||||
| // Merge contacts | // Merge contacts | ||||
| int coincident_count=0; | int coincident_count = 0; | ||||
| btVector3 coincident_normals[MAX_COINCIDENT]; | btVector3 coincident_normals[MAX_COINCIDENT]; | ||||
| unsigned int last_key = keycontacts[0].m_key; | unsigned int last_key = keycontacts[0].m_key; | ||||
| unsigned int key = 0; | unsigned int key = 0; | ||||
| push_back(contacts[keycontacts[0].m_value]); | push_back(contacts[keycontacts[0].m_value]); | ||||
| GIM_CONTACT * pcontact = &(*this)[0]; | GIM_CONTACT* pcontact = &(*this)[0]; | ||||
| for( i=1;i<keycontacts.size();i++) | for (i = 1; i < keycontacts.size(); i++) | ||||
| { | { | ||||
| key = keycontacts[i].m_key; | key = keycontacts[i].m_key; | ||||
| const GIM_CONTACT * scontact = &contacts[keycontacts[i].m_value]; | const GIM_CONTACT* scontact = &contacts[keycontacts[i].m_value]; | ||||
| if(last_key == key)//same points | if (last_key == key) //same points | ||||
| { | { | ||||
| //merge contact | //merge contact | ||||
| if(pcontact->m_depth - CONTACT_DIFF_EPSILON > scontact->m_depth)//) | if (pcontact->m_depth - CONTACT_DIFF_EPSILON > scontact->m_depth) //) | ||||
| { | { | ||||
| *pcontact = *scontact; | *pcontact = *scontact; | ||||
| coincident_count = 0; | coincident_count = 0; | ||||
| } | } | ||||
| else if(normal_contact_average) | else if (normal_contact_average) | ||||
| { | { | ||||
| if(btFabs(pcontact->m_depth - scontact->m_depth)<CONTACT_DIFF_EPSILON) | if (btFabs(pcontact->m_depth - scontact->m_depth) < CONTACT_DIFF_EPSILON) | ||||
| { | { | ||||
| if(coincident_count<MAX_COINCIDENT) | if (coincident_count < MAX_COINCIDENT) | ||||
| { | { | ||||
| coincident_normals[coincident_count] = scontact->m_normal; | coincident_normals[coincident_count] = scontact->m_normal; | ||||
| coincident_count++; | coincident_count++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| {//add new contact | { //add new contact | ||||
| if(normal_contact_average && coincident_count>0) | if (normal_contact_average && coincident_count > 0) | ||||
| { | { | ||||
| pcontact->interpolate_normals(coincident_normals,coincident_count); | pcontact->interpolate_normals(coincident_normals, coincident_count); | ||||
| coincident_count = 0; | coincident_count = 0; | ||||
| } | } | ||||
| push_back(*scontact); | push_back(*scontact); | ||||
| pcontact = &(*this)[this->size()-1]; | pcontact = &(*this)[this->size() - 1]; | ||||
| } | } | ||||
| last_key = key; | last_key = key; | ||||
| } | } | ||||
| } | } | ||||
| void btContactArray::merge_contacts_unique(const btContactArray & contacts) | void btContactArray::merge_contacts_unique(const btContactArray& contacts) | ||||
| { | { | ||||
| clear(); | clear(); | ||||
| if(contacts.size()==0) return; | if (contacts.size() == 0) return; | ||||
| if(contacts.size()==1) | if (contacts.size() == 1) | ||||
| { | { | ||||
| push_back(contacts[0]); | push_back(contacts[0]); | ||||
| return; | return; | ||||
| } | } | ||||
| GIM_CONTACT average_contact = contacts[0]; | GIM_CONTACT average_contact = contacts[0]; | ||||
| for (int i=1;i<contacts.size() ;i++ ) | for (int i = 1; i < contacts.size(); i++) | ||||
| { | { | ||||
| average_contact.m_point += contacts[i].m_point; | average_contact.m_point += contacts[i].m_point; | ||||
| average_contact.m_normal += contacts[i].m_normal * contacts[i].m_depth; | average_contact.m_normal += contacts[i].m_normal * contacts[i].m_depth; | ||||
| } | } | ||||
| //divide | //divide | ||||
| btScalar divide_average = 1.0f/((btScalar)contacts.size()); | btScalar divide_average = 1.0f / ((btScalar)contacts.size()); | ||||
| average_contact.m_point *= divide_average; | average_contact.m_point *= divide_average; | ||||
| average_contact.m_normal *= divide_average; | average_contact.m_normal *= divide_average; | ||||
| average_contact.m_depth = average_contact.m_normal.length(); | average_contact.m_depth = average_contact.m_normal.length(); | ||||
| average_contact.m_normal /= average_contact.m_depth; | average_contact.m_normal /= average_contact.m_depth; | ||||
| } | } | ||||