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
00032
00033
00034
00037 #ifndef FCL_BROAD_PHASE_SPATIAL_HASH_H
00038 #define FCL_BROAD_PHASE_SPATIAL_HASH_H
00039
00040 #include "fcl/broadphase/broadphase.h"
00041 #include "fcl/broadphase/hash.h"
00042 #include "fcl/BV/AABB.h"
00043 #include <list>
00044 #include <map>
00045
00046 namespace fcl
00047 {
00048
00050 struct SpatialHash
00051 {
00052 SpatialHash(const AABB& scene_limit_, FCL_REAL cell_size_) : cell_size(cell_size_),
00053 scene_limit(scene_limit_)
00054 {
00055 width[0] = std::ceil(scene_limit.width() / cell_size);
00056 width[1] = std::ceil(scene_limit.height() / cell_size);
00057 width[2] = std::ceil(scene_limit.depth() / cell_size);
00058 }
00059
00060 std::vector<unsigned int> operator() (const AABB& aabb) const
00061 {
00062 int min_x = std::floor((aabb.min_[0] - scene_limit.min_[0]) / cell_size);
00063 int max_x = std::ceil((aabb.max_[0] - scene_limit.min_[0]) / cell_size);
00064 int min_y = std::floor((aabb.min_[1] - scene_limit.min_[1]) / cell_size);
00065 int max_y = std::ceil((aabb.max_[1] - scene_limit.min_[1]) / cell_size);
00066 int min_z = std::floor((aabb.min_[2] - scene_limit.min_[2]) / cell_size);
00067 int max_z = std::ceil((aabb.max_[2] - scene_limit.min_[2]) / cell_size);
00068
00069 std::vector<unsigned int> keys((max_x - min_x) * (max_y - min_y) * (max_z - min_z));
00070 int id = 0;
00071 for(int x = min_x; x < max_x; ++x)
00072 {
00073 for(int y = min_y; y < max_y; ++y)
00074 {
00075 for(int z = min_z; z < max_z; ++z)
00076 {
00077 keys[id++] = x + y * width[0] + z * width[0] * width[1];
00078 }
00079 }
00080 }
00081 return keys;
00082 }
00083
00084 private:
00085
00086 FCL_REAL cell_size;
00087 AABB scene_limit;
00088 unsigned int width[3];
00089 };
00090
00092 template<typename HashTable = SimpleHashTable<AABB, CollisionObject*, SpatialHash> >
00093 class SpatialHashingCollisionManager : public BroadPhaseCollisionManager
00094 {
00095 public:
00096 SpatialHashingCollisionManager(FCL_REAL cell_size, const Vec3f& scene_min, const Vec3f& scene_max, unsigned int default_table_size = 1000) : scene_limit(AABB(scene_min, scene_max)),
00097 hash_table(new HashTable(SpatialHash(scene_limit, cell_size)))
00098 {
00099 hash_table->init(default_table_size);
00100 }
00101
00102 ~SpatialHashingCollisionManager()
00103 {
00104 delete hash_table;
00105 }
00106
00108 void registerObject(CollisionObject* obj);
00109
00111 void unregisterObject(CollisionObject* obj);
00112
00114 void setup();
00115
00117 void update();
00118
00120 void update(CollisionObject* updated_obj);
00121
00123 void update(const std::vector<CollisionObject*>& updated_objs);
00124
00126 void clear();
00127
00129 void getObjects(std::vector<CollisionObject*>& objs) const;
00130
00132 void collide(CollisionObject* obj, void* cdata, CollisionCallBack callback) const;
00133
00135 void distance(CollisionObject* obj, void* cdata, DistanceCallBack callback) const;
00136
00138 void collide(void* cdata, CollisionCallBack callback) const;
00139
00141 void distance(void* cdata, DistanceCallBack callback) const;
00142
00144 void collide(BroadPhaseCollisionManager* other_manager, void* cdata, CollisionCallBack callback) const;
00145
00147 void distance(BroadPhaseCollisionManager* other_manager, void* cdata, DistanceCallBack callback) const;
00148
00150 bool empty() const;
00151
00153 size_t size() const;
00154
00156 static void computeBound(std::vector<CollisionObject*>& objs, Vec3f& l, Vec3f& u)
00157 {
00158 AABB bound;
00159 for(unsigned int i = 0; i < objs.size(); ++i)
00160 bound += objs[i]->getAABB();
00161
00162 l = bound.min_;
00163 u = bound.max_;
00164 }
00165
00166 protected:
00167
00169 bool collide_(CollisionObject* obj, void* cdata, CollisionCallBack callback) const;
00170
00172 bool distance_(CollisionObject* obj, void* cdata, DistanceCallBack callback, FCL_REAL& min_dist) const;
00173
00174
00176 std::list<CollisionObject*> objs;
00177
00179 std::list<CollisionObject*> objs_outside_scene_limit;
00180
00182 AABB scene_limit;
00183
00185 std::map<CollisionObject*, AABB> obj_aabb_map;
00186
00188 HashTable* hash_table;
00189
00190 };
00191
00192
00193 }
00194
00195 #include "fcl/broadphase/broadphase_spatialhash.hxx"
00196
00197
00198 #endif