node.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002  * \file
00003  *
00004  * $Id:$
00005  *
00006  * Copyright (C) Brno University of Technology (BUT)
00007  *
00008  * This file is part of software developed by dcgm-robotics@FIT group.
00009  *
00010  * Author: Jan Gorig (xgorig01@stud.fit.vutbr.cz)
00011  * Supervised by: Michal Spanel (spanel@fit.vutbr.cz)
00012  * Date: 12/04/2012
00013  *
00014  * This file is free software: you can redistribute it and/or modify
00015  * it under the terms of the GNU Lesser General Public License as published by
00016  * the Free Software Foundation, either version 3 of the License, or
00017  * (at your option) any later version.
00018  *
00019  * This file is distributed in the hope that it will be useful,
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  * GNU Lesser General Public License for more details.
00023  *
00024  * You should have received a copy of the GNU Lesser General Public License
00025  * along with this file.  If not, see <http://www.gnu.org/licenses/>.
00026  */
00027 
00028 #include <cstdio>
00029 #include <srs_env_model/but_server/objtree/node.h>
00030 
00031 namespace objtree
00032 {
00033 
00040 Node::Node(unsigned char place, Node *parent)
00041 {
00042     m_place = place;
00043     m_parent = parent;
00044 
00045     if(m_parent != NULL)
00046     {
00047         //Update neighbor pointers in neighbors
00048         for(unsigned char neighbor = 0; neighbor < NEIGHBORS; neighbor++)
00049         {
00050             m_neighbors[neighbor] = computeNeighbor(neighbor);
00051 
00052             if(m_neighbors[neighbor] != NULL)
00053             {
00054                 m_neighbors[neighbor]->m_neighbors[reverseNeighborId(neighbor)] = this;
00055             }
00056         }
00057     }
00058     else
00059     {
00060         //Root node hasn't got any neighbors
00061         for(unsigned char neighbor = 0; neighbor < NEIGHBORS; neighbor++)
00062         {
00063             m_neighbors[neighbor] = NULL;
00064         }
00065     }
00066 
00067     for(unsigned char i = 0; i < CHILDREN; i++)
00068     {
00069         m_children[i] = NULL;
00070     }
00071 }
00072 
00076 Node::~Node()
00077 {
00078     //Nullify all neighbor pointers to this node
00079     for(unsigned char neighbor = 0; neighbor < NEIGHBORS; neighbor++)
00080     {
00081         if(m_neighbors[neighbor] != NULL)
00082         {
00083             m_neighbors[neighbor]->m_neighbors[reverseNeighborId(neighbor)] = NULL;
00084         }
00085     }
00086 
00087     //Delete all children
00088     for(unsigned char place = 0; place < CHILDREN; place++)
00089     {
00090         if(m_children[place]) delete m_children[place];
00091     }
00092 
00093     //Delete all objects
00094     for(std::list<Object*>::iterator i = m_objects.begin(); i != m_objects.end(); i++)
00095     {
00096         (*i)->removeNode(this);
00097         delete *i;
00098     }
00099 }
00100 
00105 Node* Node::parent()
00106 {
00107     return m_parent;
00108 }
00109 
00116 Node* Node::child(unsigned char place, bool createNew)
00117 {
00118     if(!m_children[place] && createNew)
00119     {
00120         m_children[place] = new Node(place, this);
00121     }
00122 
00123     return m_children[place];
00124 }
00125 
00131 Node* Node::neighbor(unsigned char dir)
00132 {
00133     return m_neighbors[dir];
00134 }
00135 
00140 const std::list<Object*>& Node::objects() const
00141 {
00142     return m_objects;
00143 }
00144 
00149 void Node::add(Object* object)
00150 {
00151     m_objects.push_back(object);
00152     object->newNode(this);
00153 }
00154 
00162 Box& Node::getChildBox(unsigned char place, Box &childBox, const Box &parentBox)
00163 {
00164     childBox = parentBox;
00165 
00166     childBox.w/=2.0f;
00167     childBox.h/=2.0f;
00168     childBox.d/=2.0f;
00169 
00170     switch(place)
00171     {
00172         case 0:
00173             break;
00174         case 1:
00175             childBox.x+=childBox.w;
00176             break;
00177         case 2:
00178             childBox.y+=childBox.h;
00179             break;
00180         case 3:
00181             childBox.x+=childBox.w;
00182             childBox.y+=childBox.h;
00183             break;
00184         case 4:
00185             childBox.z+=childBox.d;
00186             break;
00187         case 5:
00188             childBox.x+=childBox.w;
00189             childBox.z+=childBox.d;
00190             break;
00191         case 6:
00192             childBox.y+=childBox.h;
00193             childBox.z+=childBox.d;
00194             break;
00195         case 7:
00196             childBox.x+=childBox.w;
00197             childBox.y+=childBox.h;
00198             childBox.z+=childBox.d;
00199             break;
00200     }
00201 
00202     return childBox;
00203 }
00204 
00211 Node* Node::parentNeighborChild(unsigned char parentNeighbor, unsigned char child)
00212 {
00213     if(m_parent->m_neighbors[parentNeighbor] != NULL)
00214     {
00215         return m_parent->m_neighbors[parentNeighbor]->m_children[child];
00216     }
00217 
00218     return NULL;
00219 }
00220 
00221 /*
00222  * Neighbors ids (from top view)
00223  * Top part:  Middle part:  Bottom part:
00224  *  6  7  8     14 15 16      23 24 25
00225  *  3  4  5     12    13      20 21 22
00226  *  0  1  2      9 10 11      17 18 19
00227  *
00228  * Node children ids (from top view)
00229  * Top part:  Bottom part:
00230  *   2  3         6  7
00231  *   0  1         4  5
00232  *
00233  * Temporary ids (from top view)
00234  * 12 13 14 15  28 29 30 31  44 45 46 47  60 61 62 63
00235  *  8  9 10 11  24 25 26 27  40 41 42 43  56 57 58 59
00236  *  4  5  6  7  20 21 22 23  36 37 38 39  52 53 54 55
00237  *  0  1  2  3  16 17 18 19  32 33 34 35  48 49 50 51
00238  */
00239 
00246 Node* Node::computeNeighbor(unsigned char dir)
00247 {
00248    if(dir >= 13) dir++;
00249 
00250    unsigned char x = m_place%2+1;
00251    unsigned char y = (m_place%4)/2+1;
00252    unsigned char z = m_place/4+1;
00253 
00254    x -= dir%3 == 0;
00255    x += (dir+1)%3 == 0;
00256 
00257    y -= dir%9 <= 2;
00258    y += dir%9 >= 6;
00259 
00260    z -= dir <= 8;
00261    z += dir >= 18;
00262 
00263    unsigned char child = 1-x%2;
00264    if(y%2 == 0) child += 2;
00265    if(z%2 == 0) child += 4;
00266 
00267    x -= x >= 2;
00268    y -= y >= 2;
00269    z -= z >= 2;
00270 
00271    unsigned char parent = z*9+y*3+x;
00272 
00273    if(parent == 13) return m_parent->m_children[child];
00274    if(parent > 13) parent--;
00275 
00276    return parentNeighborChild(parent, child);
00277 }
00278 
00284 unsigned char Node::reverseNeighborId(unsigned char dir)
00285 {
00286     return 25-dir;
00287 }
00288 
00294 void Node::removeObject(Object *object)
00295 {
00296     m_objects.remove(object);
00297 
00298     if(m_objects.size() == 0)
00299     {
00300         m_parent->m_children[m_place] = NULL;
00301         m_parent->deleteIfEmpty();
00302         delete this;
00303     }
00304 }
00305 
00309 void Node::deleteIfEmpty()
00310 {
00311     //We don't want to delete root node
00312     if(m_parent == NULL)
00313     {
00314         return;
00315     }
00316 
00317     for(unsigned char child = 0; child < CHILDREN; child++)
00318     {
00319         if(m_children[child] != NULL)
00320         {
00321             return;
00322         }
00323     }
00324 
00325     if(m_objects.size() != 0)
00326     {
00327         return;
00328     }
00329 
00330     m_parent->m_children[m_place] = NULL;
00331     m_parent->deleteIfEmpty();
00332     delete this;
00333 }
00334 
00335 }


srs_env_model
Author(s): Vit Stancl (stancl@fit.vutbr.cz), Tomas Lokaj, Jan Gorig, Michal Spanel (spanel@fit.vutbr.cz)
autogenerated on Sun Jan 5 2014 11:50:48