00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "swiftcollisiondetector.h"
00024 #include "common/math/matrix3.h"
00025 #include "common/math/quaternion.h"
00026 #include "common/math/vector3.h"
00027 #include "engine/dynamics/rigidbody.h"
00028 #include "engine/simulation/rigidobject.h"
00029 #include "rigidmodel.h"
00030
00031 #include <cassert>
00032
00033
00034 using namespace sheep;
00035
00036 void SWIFTCollisionDetector::Insert(RigidObject *object) {
00037 assert(object);
00038
00039
00040 assert(m_object_to_id.find(object) == m_object_to_id.end());
00041
00042 RigidModel *model = object->GetModel();
00043
00044 const int nv = model->m_vertices.size();
00045 const int nf = model->m_faces.size();
00046
00047 SWIFT_Real *vertices = new SWIFT_Real[3 * nv];
00048 int *faces = new int[3 * nf];
00049 int index = 0;
00050
00051
00052 for(int i = 0; i < nv; ++i) {
00053 const Vector3 &v = model->m_vertices[i];
00054
00055 vertices[++index] = v.m_x;
00056 vertices[++index] = v.m_y;
00057 vertices[++index] = v.m_z;
00058 }
00059
00060 index = 0;
00061
00062
00063 for(int i = 0; i < nf; ++i) {
00064 const RigidModel::Face &f = model->m_faces[i];
00065
00066 faces[++index] = f.m_v0;
00067 faces[++index] = f.m_v1;
00068 faces[++index] = f.m_v2;
00069 }
00070
00071 const int copy_oid = m_model_to_id.find(object->GetModel()) == m_model_to_id.end() ?
00072 DEFAULT_COPY : m_model_to_id[object->GetModel()];
00073
00074 int object_id = 0;
00075
00076 const bool result = m_scene->Add_Object(
00077 vertices, faces,
00078 nv, nf,
00079 object_id,
00080 false,
00081 DEFAULT_ORIENTATION,
00082 DEFAULT_TRANSLATION,
00083 DEFAULT_SCALE,
00084 DEFAULT_BOX_SETTING,
00085 DEFAULT_BOX_ENLARGE_REL,
00086 2.0 * HULL_THICKNESS,
00087 DEFAULT_FACE_VALENCES,
00088 copy_oid);
00089
00090 assert(result);
00091
00092 delete [] faces;
00093 delete [] vertices;
00094
00095 m_id_to_object[object_id] = object;
00096 m_object_to_id[object] = object_id;
00097 }
00098
00099 void SWIFTCollisionDetector::Remove(RigidObject *object) {
00100 assert(object);
00101
00102
00103 assert(m_object_to_id.find(object) != m_object_to_id.end());
00104
00105 const int object_id = m_object_to_id[object];
00106
00107 m_id_to_object.erase(object_id);
00108 m_object_to_id.erase(object);
00109
00110 m_scene->Delete_Object(object_id);
00111 }
00112
00113 void SWIFTCollisionDetector::RefreshTransformations() {
00114 for(object_to_id_map::const_iterator it = m_object_to_id.begin();
00115 it != m_object_to_id.end(); ++it)
00116 {
00117 const RigidBody *body = it->first->GetBody();
00118
00119 SWIFT_Real orientation[9];
00120 SWIFT_Real translation[3];
00121
00122 const Matrix3 m = Matrix3::Rotation(body->GetOrientation());
00123
00124 for(int i = 0; i < 9; i++)
00125 orientation[i] = m[i];
00126
00127 const Vector3 &p = body->GetPosition();
00128
00129 translation[0] = p.m_x;
00130 translation[1] = p.m_y;
00131 translation[2] = p.m_z;
00132
00133 m_scene->Set_Object_Transformation(it->second, orientation, translation);
00134 }
00135
00136
00137 m_scene->Activate();
00138
00139 m_are_disjoint = ! m_scene->Query_Contact_Determination(
00140 false,
00141 2.0 * HULL_THICKNESS,
00142 m_num_pairs,
00143 &m_oids,
00144 &m_distances,
00145 NO_NEAREST_PTS,
00146 NO_NORMALS,
00147 &m_pids,
00148 &m_feature_types,
00149 &m_feature_ids);
00150 }
00151
00152 void SWIFTCollisionDetector::FindContacts(ContactList *contacts) {
00153 assert(contacts);
00154
00155 int oid_idx = 0;
00156 int fid_idx = 0;
00157
00158 for(int i = 0; i < m_num_pairs; ++i) {
00159 Contact c;
00160
00161 c.m_a = m_id_to_object[m_oids[oid_idx]];
00162
00163 switch(m_feature_types[oid_idx++]) {
00164 case SWIFT_VERTEX:
00165 c.m_fa.m_type = Feature::Type::VERTEX;
00166 c.m_fa.m_id0 = m_feature_ids[fid_idx++];
00167 break;
00168 case SWIFT_EDGE:
00169 c.m_fa.m_type = Feature::Type::EDGE;
00170 c.m_fa.m_id0 = m_feature_ids[fid_idx++];
00171 c.m_fa.m_id1 = m_feature_ids[fid_idx++];
00172 break;
00173 case SWIFT_FACE:
00174 c.m_fa.m_type = Feature::Type::FACE;
00175 c.m_fa.m_id0 = m_feature_ids[fid_idx++];
00176 break;
00177 default:
00178
00179 assert(!"Internal failure.");
00180 }
00181
00182 c.m_b = m_id_to_object[m_oids[oid_idx]];
00183
00184 switch(m_feature_types[oid_idx++]) {
00185 case SWIFT_VERTEX:
00186 c.m_fb.m_type = Feature::Type::VERTEX;
00187 c.m_fb.m_id0 = m_feature_ids[fid_idx++];
00188 break;
00189 case SWIFT_EDGE:
00190 c.m_fb.m_type = Feature::Type::EDGE;
00191 c.m_fb.m_id0 = m_feature_ids[fid_idx++];
00192 c.m_fb.m_id1 = m_feature_ids[fid_idx++];
00193 break;
00194 case SWIFT_FACE:
00195 c.m_fb.m_type = Feature::Type::FACE;
00196 c.m_fb.m_id0 = m_feature_ids[fid_idx++];
00197 break;
00198 default:
00199 assert(!"Internal failure.");
00200 }
00201
00202
00203 if(m_distances[i] >= 0.0)
00204 contacts->push_back(c);
00205 }
00206 }