Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

swiftcollisiondetector.cpp

Go to the documentation of this file.
00001 /*
00002     Sheep - A Rigid Body Dynamics Engine
00003     Copyright (C) 2001-2004 Francois Beaune
00004     Contact: http://toxicengine.sourceforge.net/
00005 
00006     This file is part of Sheep.
00007 
00008     Sheep is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     Sheep is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016     GNU General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License
00019     along with Sheep; if not, write to the Free Software
00020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 */
00022 
00023 #include "swiftcollisiondetector.h" // include first
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 //#include <iostream>
00033 
00034 using namespace sheep;
00035 
00036 void SWIFTCollisionDetector::Insert(RigidObject *object) {
00037     assert(object);
00038 
00039     // Make sure this object has not already been inserted.
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     //!\todo Use iterators.
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     //!\todo Use iterators.
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;  // initialized to prevent a compiler warning
00075 
00076     const bool result = m_scene->Add_Object(
00077         vertices, faces,
00078         nv, nf,
00079         object_id,      // passed by reference
00080         false,          //!\todo Replace by object->GetBody()->IsFixed()
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     // Make sure this object has been previously inserted.
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     //!\todo Remove (this is no more necessary).
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,        // passed by reference
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;        // index in m_oids[] and m_feature_types[]
00156     int fid_idx = 0;        // index in m_feature_ids[]
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 //          std::cout << "feature_type: " << m_feature_types[oid_idx-1] << std::endl;
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         // Only keep contact data for pairs of disjoint objects.
00203         if(m_distances[i] >= 0.0)
00204             contacts->push_back(c);
00205     }
00206 }

Generated on Tue May 11 01:31:52 2004 for toxic by doxygen 1.3.6