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 #include <cstdio>
00029 #include <srs_env_model/but_server/objtree/octree.h>
00030 #include <srs_env_model/but_server/objtree/filter.h>
00031 #include <srs_env_model/but_server/objtree/node.h>
00032
00033 namespace objtree
00034 {
00035
00041 Octree::Octree(unsigned int maxDepth) :
00042 m_rootSize(0.0f, 0.0f, 0.0f, 16.0f, 16.0f, 16.0f)
00043 {
00044 m_root = new Node;
00045 m_maxId = 0;
00046 m_maxDepth = maxDepth;
00047 }
00048
00055 Octree::Octree(const Box &rootSize, unsigned int maxDepth) :
00056 m_rootSize(rootSize)
00057 {
00058 m_root = new Node;
00059 m_maxId = 0;
00060 m_maxDepth = maxDepth;
00061 }
00062
00066 Octree::~Octree()
00067 {
00068 delete m_root;
00069 }
00070
00074 void Octree::clear()
00075 {
00076 delete m_root;
00077 m_objects.clear();
00078
00079 m_root = new Node;
00080 m_maxId = 0;
00081 }
00082
00088 unsigned int Octree::insertOnFit(Object* object)
00089 {
00090 Node *node = m_root;
00091
00092 Box box(m_rootSize);
00093 Box childBox;
00094
00095 bool fits = true;
00096 unsigned char i;
00097
00098 while(fits)
00099 {
00100 for(i = 0; !(fits = object->fitsIntoBox(Node::getChildBox(i, childBox, box))) && i < Node::CHILDREN; i++);
00101
00102 if(fits)
00103 {
00104 node = node->child(i, true);
00105 box = childBox;
00106 }
00107 }
00108
00109 node->add(object);
00110 m_objects[m_maxId] = object;
00111 object->setId(m_maxId++);
00112
00113 return object->id();
00114 }
00115
00124 unsigned int Octree::insertOnInterfere(Object* object, Node *node, Box box, unsigned int depth)
00125 {
00126 Box childBox;
00127
00128 for(unsigned char i = 0; i < Node::CHILDREN; i++)
00129 {
00130 if(object->interfereWithBox(Node::getChildBox(i, childBox, box)))
00131 {
00132 Node *child = node->child(i, true);
00133
00134 if(depth < m_maxDepth)
00135 {
00136 insertOnInterfere(object, child, childBox, depth+1);
00137 }
00138 else
00139 {
00140 child->add(object);
00141 }
00142 }
00143 }
00144
00145 return object->id();
00146 }
00147
00158 unsigned int Octree::insertUpdateOnInterfere(Object* object, Node *node, Box box, bool &inserted, unsigned int depth)
00159 {
00160 Box childBox;
00161
00162 for(unsigned char i = 0; i < Node::CHILDREN; i++)
00163 {
00164 if(object->interfereWithBox(Node::getChildBox(i, childBox, box)))
00165 {
00166 Node *child = node->child(i, true);
00167
00168 if(depth < m_maxDepth)
00169 {
00170 insertUpdateOnInterfere(object, child, childBox, inserted, depth+1);
00171 }
00172 else
00173 {
00174
00175 Object *similar = NULL;
00176
00177 for(std::list<Object*>::const_iterator j = child->objects().begin(); j != child->objects().end() && !similar; j++)
00178 {
00179 if(*j != object && (*j)->isSimilar(object))
00180 {
00181 similar = *j;
00182 }
00183 }
00184
00185 for(unsigned int n = 0; n < Node::NEIGHBORS && !similar; n++)
00186 {
00187 Node *neighbor = child->neighbor(n);
00188 if(neighbor == NULL)
00189 {
00190 continue;
00191 }
00192
00193 for(std::list<Object*>::const_iterator j = neighbor->objects().begin(); j != neighbor->objects().end() && !similar; j++)
00194 {
00195 if(*j != object && (*j)->isSimilar(object))
00196 {
00197 similar = *j;
00198 }
00199 }
00200 }
00201
00202 child->add(object);
00203
00204
00205 if(similar != NULL)
00206 {
00207
00208 if(!inserted)
00209 {
00210 m_objects[similar->id()] = object;
00211 object->setId(similar->id());
00212 inserted = true;
00213 #if HISTORY_ENABLED
00214 object->takeHistory(similar);
00215 #endif
00216 }
00217
00218 else
00219 {
00220 m_objects.erase(similar->id());
00221 }
00222
00223 delete similar;
00224 }
00225
00226 else
00227 {
00228 if(!inserted)
00229 {
00230 if(!object->hasId())
00231 {
00232 m_objects[m_maxId] = object;
00233 object->setId(m_maxId++);
00234 }
00235 else
00236 {
00237 m_objects[object->id()] = object;
00238 }
00239 }
00240 }
00241 }
00242 }
00243 }
00244
00245 return object->id();
00246 }
00247
00256 Object* Octree::getSimilarObject(const Object *object, Node *node, Box box, unsigned int depth)
00257 {
00258 Box childBox;
00259 Object *similar;
00260
00261 for(unsigned char i = 0; i < Node::CHILDREN; i++)
00262 {
00263 Node *child = node->child(i);
00264
00265 if(!child) continue;
00266
00267 if(object->interfereWithBox(Node::getChildBox(i, childBox, box)))
00268 {
00269 if(depth < m_maxDepth)
00270 {
00271 similar = getSimilarObject(object, child, childBox, depth+1);
00272 if(similar) return similar;
00273 }
00274 else
00275 {
00276 for(std::list<Object*>::const_iterator j = node->objects().begin(); j != node->objects().end(); j++)
00277 {
00278 if(*j != object && (*j)->isSimilar(object))
00279 {
00280 return *j;
00281 }
00282 }
00283
00284 for(unsigned int n = 0; n < Node::NEIGHBORS; n++)
00285 {
00286 Node *neighbor = child->neighbor(n);
00287
00288 if(!neighbor) continue;
00289
00290 for(std::list<Object*>::const_iterator j = neighbor->objects().begin(); j != neighbor->objects().end(); j++)
00291 {
00292 if(*j != object && (*j)->isSimilar(object))
00293 {
00294 return *j;
00295 }
00296 }
00297 }
00298 }
00299 }
00300 }
00301
00302 return NULL;
00303 }
00304
00310 Object* Octree::getSimilarObject(const Object* object)
00311 {
00312 return getSimilarObject(object, m_root, m_rootSize);
00313 }
00314
00320 unsigned int Octree::insert(Object* object)
00321 {
00322 if(!object->hasId())
00323 {
00324 m_objects[m_maxId] = object;
00325 object->setId(m_maxId++);
00326 }
00327 else
00328 {
00329 m_objects[object->id()] = object;
00330 }
00331
00332 return insertOnInterfere(object, m_root, m_rootSize);
00333 }
00334
00341 unsigned int Octree::insertUpdate(Object* object)
00342 {
00343 bool inserted = false;
00344 return insertUpdateOnInterfere(object, m_root, m_rootSize, inserted);
00345 }
00346
00354 unsigned int Octree::insertUpdate2(Object* object)
00355 {
00356 Object *similar = getSimilarObject(object, m_root, m_rootSize);
00357
00358 if(similar)
00359 {
00360 m_objects[similar->id()] = object;
00361 object->setId(similar->id());
00362
00363 delete similar;
00364 }
00365 else
00366 {
00367 m_objects[m_maxId] = object;
00368 object->setId(m_maxId++);
00369 }
00370
00371 return insertOnInterfere(object, m_root, m_rootSize);
00372 }
00373
00381 bool Octree::isPositionFree(float x, float y, float z)
00382 {
00383 Node *node = m_root;
00384
00385 Box box(m_rootSize);
00386
00387 for(;;)
00388 {
00389 unsigned char id = 0;
00390
00391 if(x >= box.x+box.w/2.0f) id += 1;
00392 if(y >= box.y+box.h/2.0f) id += 2;
00393 if(z >= box.z+box.d/2.0f) id += 4;
00394
00395 node = node->child(id);
00396
00397 if(node == NULL)
00398 {
00399 return true;
00400 }
00401
00402 for(std::list<Object*>::const_iterator i = node->objects().begin(); i != node->objects().end(); i++)
00403 {
00404 if((*i)->isPointInside(x, y, z))
00405 {
00406 return false;
00407 }
00408 }
00409
00410 Node::getChildBox(id, box, box);
00411 }
00412 }
00413
00420 void Octree::nodes(std::list<Box> &nodesList, std::set<Object*> &objectList, const Filter *filter)
00421 {
00422 nodes(nodesList, objectList, filter, m_rootSize, m_root);
00423 }
00424
00433 void Octree::nodes(std::list<Box> &nodesList, std::set<Object*> &objectList, const Filter *filter, Box dim, Node *node)
00434 {
00435 if(!filter->filter(dim)) return;
00436
00437 for(std::list<Object*>::const_iterator i = node->objects().begin(); i != node->objects().end(); i++)
00438 {
00439 objectList.insert(*i);
00440 }
00441
00442 nodesList.push_back(dim);
00443
00444 for(unsigned int i = 0; i < Node::CHILDREN; i++)
00445 {
00446 Node *child = node->child(i);
00447
00448 if(child)
00449 {
00450 Box newDim;
00451 Node::getChildBox(i, newDim, dim);
00452 nodes(nodesList, objectList, filter, newDim, child);
00453 }
00454 }
00455 }
00456
00462 void Octree::objects(std::set<Object*> &objectList, const Filter *filter)
00463 {
00464 std::list<Box> nodesList;
00465 nodes(nodesList, objectList, filter, m_rootSize, m_root);
00466 }
00467
00468 const Object* Octree::object(unsigned int id) const
00469 {
00470 std::map<unsigned int, Object*>::const_iterator i = m_objects.find(id);
00471
00472 if(i != m_objects.end()) return i->second;
00473 else return NULL;
00474 }
00475
00481 bool Octree::removeObject(unsigned int id)
00482 {
00483 std::map<unsigned int, Object*>::iterator i = m_objects.find(id);
00484
00485 if(i != m_objects.end())
00486 {
00487 delete i->second;
00488 m_objects.erase(i);
00489
00490 return true;
00491 }
00492 else
00493 {
00494 return false;
00495 }
00496 }
00497
00502 Node* Octree::root() const
00503 {
00504 return m_root;
00505 }
00506
00511 unsigned int Octree::maxId() const
00512 {
00513 return m_maxId;
00514 }
00515
00520 unsigned int Octree::count() const
00521 {
00522 return m_objects.size();
00523 }
00524
00529 const std::map<unsigned int, Object*>& Octree::objectsAll() const
00530 {
00531 return m_objects;
00532 }
00533
00534 }