Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "gim_contact.h"
00032
00033 #define MAX_COINCIDENT 8
00034
00035 void gim_contact_array::merge_contacts(
00036 const gim_contact_array & contacts, bool normal_contact_average)
00037 {
00038 clear();
00039
00040 if(contacts.size()==1)
00041 {
00042 push_back(contacts.back());
00043 return;
00044 }
00045
00046 gim_array<GIM_RSORT_TOKEN> keycontacts(contacts.size());
00047 keycontacts.resize(contacts.size(),false);
00048
00049
00050
00051 GUINT i;
00052
00053 for (i = 0;i<contacts.size() ;i++ )
00054 {
00055 keycontacts[i].m_key = contacts[i].calc_key_contact();
00056 keycontacts[i].m_value = i;
00057 }
00058
00059
00060 gim_heap_sort(keycontacts.pointer(),keycontacts.size(),GIM_RSORT_TOKEN_COMPARATOR());
00061
00062
00063
00064 GUINT coincident_count=0;
00065 btVector3 coincident_normals[MAX_COINCIDENT];
00066
00067 GUINT last_key = keycontacts[0].m_key;
00068 GUINT key = 0;
00069
00070 push_back(contacts[keycontacts[0].m_value]);
00071 GIM_CONTACT * pcontact = &back();
00072
00073
00074
00075 for( i=1;i<keycontacts.size();i++)
00076 {
00077 key = keycontacts[i].m_key;
00078 const GIM_CONTACT * scontact = &contacts[keycontacts[i].m_value];
00079
00080 if(last_key == key)
00081 {
00082
00083 if(pcontact->m_depth - CONTACT_DIFF_EPSILON > scontact->m_depth)
00084 {
00085 *pcontact = *scontact;
00086 coincident_count = 0;
00087 }
00088 else if(normal_contact_average)
00089 {
00090 if(btFabs(pcontact->m_depth - scontact->m_depth)<CONTACT_DIFF_EPSILON)
00091 {
00092 if(coincident_count<MAX_COINCIDENT)
00093 {
00094 coincident_normals[coincident_count] = scontact->m_normal;
00095 coincident_count++;
00096 }
00097 }
00098 }
00099 }
00100 else
00101 {
00102
00103 if(normal_contact_average && coincident_count>0)
00104 {
00105 pcontact->interpolate_normals(coincident_normals,coincident_count);
00106 coincident_count = 0;
00107 }
00108
00109 push_back(*scontact);
00110 pcontact = &back();
00111 }
00112 last_key = key;
00113 }
00114 }
00115
00116 void gim_contact_array::merge_contacts_unique(const gim_contact_array & contacts)
00117 {
00118 clear();
00119
00120 if(contacts.size()==1)
00121 {
00122 push_back(contacts.back());
00123 return;
00124 }
00125
00126 GIM_CONTACT average_contact = contacts.back();
00127
00128 for (GUINT i=1;i<contacts.size() ;i++ )
00129 {
00130 average_contact.m_point += contacts[i].m_point;
00131 average_contact.m_normal += contacts[i].m_normal * contacts[i].m_depth;
00132 }
00133
00134
00135 GREAL divide_average = 1.0f/((GREAL)contacts.size());
00136
00137 average_contact.m_point *= divide_average;
00138
00139 average_contact.m_normal *= divide_average;
00140
00141 average_contact.m_depth = average_contact.m_normal.length();
00142
00143 average_contact.m_normal /= average_contact.m_depth;
00144
00145 }
00146