Go to the documentation of this file.00001 #ifndef GIM_CONTACT_H_INCLUDED
00002 #define GIM_CONTACT_H_INCLUDED
00003
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
00032
00033
00034
00035 #include "gim_geometry.h"
00036 #include "gim_radixsort.h"
00037 #include "gim_array.h"
00038
00039
00043 #define NORMAL_CONTACT_AVERAGE 1
00044 #define CONTACT_DIFF_EPSILON 0.00001f
00045
00051 class GIM_CONTACT
00052 {
00053 public:
00054 btVector3 m_point;
00055 btVector3 m_normal;
00056 GREAL m_depth;
00057 GREAL m_distance;
00058 GUINT m_feature1;
00059 GUINT m_feature2;
00060 public:
00061 GIM_CONTACT()
00062 {
00063 }
00064
00065 GIM_CONTACT(const GIM_CONTACT & contact):
00066 m_point(contact.m_point),
00067 m_normal(contact.m_normal),
00068 m_depth(contact.m_depth),
00069 m_feature1(contact.m_feature1),
00070 m_feature2(contact.m_feature2)
00071 {
00072 m_point = contact.m_point;
00073 m_normal = contact.m_normal;
00074 m_depth = contact.m_depth;
00075 m_feature1 = contact.m_feature1;
00076 m_feature2 = contact.m_feature2;
00077 }
00078
00079 GIM_CONTACT(const btVector3 &point,const btVector3 & normal,
00080 GREAL depth, GUINT feature1, GUINT feature2):
00081 m_point(point),
00082 m_normal(normal),
00083 m_depth(depth),
00084 m_feature1(feature1),
00085 m_feature2(feature2)
00086 {
00087 }
00088
00090 SIMD_FORCE_INLINE GUINT calc_key_contact() const
00091 {
00092 GINT _coords[] = {
00093 (GINT)(m_point[0]*1000.0f+1.0f),
00094 (GINT)(m_point[1]*1333.0f),
00095 (GINT)(m_point[2]*2133.0f+3.0f)};
00096 GUINT _hash=0;
00097 GUINT *_uitmp = (GUINT *)(&_coords[0]);
00098 _hash = *_uitmp;
00099 _uitmp++;
00100 _hash += (*_uitmp)<<4;
00101 _uitmp++;
00102 _hash += (*_uitmp)<<8;
00103 return _hash;
00104 }
00105
00106 SIMD_FORCE_INLINE void interpolate_normals( btVector3 * normals,GUINT normal_count)
00107 {
00108 btVector3 vec_sum(m_normal);
00109 for(GUINT i=0;i<normal_count;i++)
00110 {
00111 vec_sum += normals[i];
00112 }
00113
00114 GREAL vec_sum_len = vec_sum.length2();
00115 if(vec_sum_len <CONTACT_DIFF_EPSILON) return;
00116
00117 GIM_INV_SQRT(vec_sum_len,vec_sum_len);
00118
00119 m_normal = vec_sum*vec_sum_len;
00120 }
00121
00122 };
00123
00124
00125 class gim_contact_array:public gim_array<GIM_CONTACT>
00126 {
00127 public:
00128 gim_contact_array():gim_array<GIM_CONTACT>(64)
00129 {
00130 }
00131
00132 SIMD_FORCE_INLINE void push_contact(const btVector3 &point,const btVector3 & normal,
00133 GREAL depth, GUINT feature1, GUINT feature2)
00134 {
00135 push_back_mem();
00136 GIM_CONTACT & newele = back();
00137 newele.m_point = point;
00138 newele.m_normal = normal;
00139 newele.m_depth = depth;
00140 newele.m_feature1 = feature1;
00141 newele.m_feature2 = feature2;
00142 }
00143
00144 SIMD_FORCE_INLINE void push_triangle_contacts(
00145 const GIM_TRIANGLE_CONTACT_DATA & tricontact,
00146 GUINT feature1,GUINT feature2)
00147 {
00148 for(GUINT i = 0;i<tricontact.m_point_count ;i++ )
00149 {
00150 push_back_mem();
00151 GIM_CONTACT & newele = back();
00152 newele.m_point = tricontact.m_points[i];
00153 newele.m_normal = tricontact.m_separating_normal;
00154 newele.m_depth = tricontact.m_penetration_depth;
00155 newele.m_feature1 = feature1;
00156 newele.m_feature2 = feature2;
00157 }
00158 }
00159
00160 void merge_contacts(const gim_contact_array & contacts, bool normal_contact_average = true);
00161 void merge_contacts_unique(const gim_contact_array & contacts);
00162 };
00163
00164 #endif // GIM_CONTACT_H_INCLUDED