collisiondetectors/CD_rangesensor/logical.cpp

Go to the documentation of this file.
00001 #pragma warning ( disable : 4786 )
00002 
00003 #include "logical.h"
00004 
00006 //  Octree Logic Components
00008 
00009 inline int white_node( OctreeNode *node)
00010 {
00011   return(node -> color == WHITE);
00012 }
00013 
00014 inline int black_node( OctreeNode *node) 
00015 { 
00016   return(node -> color == BLACK);
00017 } 
00018 
00019 void delete_node( OctreeNode *node)
00020 {
00021   int i;
00022   OctreeNode *father;
00023   if(node == NULL ) return;
00024   father = node->father;
00025   if(father != NULL)
00026   {
00027     for(i =0; i< 8; i++)
00028     {
00029       if(father->son->pointer[i] == node) 
00030       {
00031         father->son->pointer[i] = NULL;
00032         break;
00033       }
00034     } 
00035   }
00036   
00037   if(node->son==NULL) 
00038   {
00039     free(node);
00040   }
00041   else
00042   {
00043     for(i =0; i< 8; i++) 
00044     {
00045       if(node->son != NULL)
00046         delete_node(node->son->pointer[i]);
00047     }
00048     free(node->son);
00049     //node->son= NULL;
00050     free(node);
00051   }
00052   if(father!= NULL)
00053     if( (father->son->pointer[0]==NULL) && (father->son->pointer[1]==NULL) &&
00054       (father->son->pointer[2]==NULL) && (father->son->pointer[3]==NULL) &&
00055       (father->son->pointer[4]==NULL) && (father->son->pointer[5]==NULL) &&
00056       (father->son->pointer[6]==NULL) && (father->son->pointer[7]==NULL) )
00057     {
00058       free(father->son);
00060       father->son = NULL;
00061     }
00062 }
00063 
00064 static char input_bitbucket_place = 0;
00065 static char input_bitbucket_ch = (char)0xAA;
00066 
00067 static char output_bitbucket_place = 0;
00068 static char output_bitbucket_ch = 0;
00069 
00070 void reset_bitbuckets ()
00071 {
00072   input_bitbucket_place = 0;
00073   input_bitbucket_ch = (char)0xAA;
00074   
00075   output_bitbucket_place = 0;
00076   output_bitbucket_ch = 0;
00077 }
00078 
00079 void input_bitbucket (char invalue, bool flush, FILE *fp)
00080 //Saves to disk the invalue of 0x00,0x01,0x03 in 2 byte chunks
00081 //Rules: input (invalue = 0x02, flush = true) when finished with the input
00082 {
00083   
00084   //eliminate everything above the 2 lsb of input data
00085   invalue = (invalue & 0x03); 
00086   
00087   //format is [4][3][2][1] in the 8 bit byte.
00088   //if there is no entry then the space will be occupied by 0x02.
00089   if (input_bitbucket_place == 0)
00090     input_bitbucket_ch = (input_bitbucket_ch & 0xFC) | invalue;
00091   else if (input_bitbucket_place == 2)
00092     input_bitbucket_ch = (input_bitbucket_ch & 0xF3) | (invalue << 2);
00093   else if (input_bitbucket_place == 4)
00094     input_bitbucket_ch = (input_bitbucket_ch & 0xCF) | (invalue << 4);
00095   else if (input_bitbucket_place == 6)
00096     input_bitbucket_ch = (input_bitbucket_ch & 0x3F) | (invalue << 6); 
00097   
00098   //if we have finished defining a character, or time to flush data, write it to disk
00099   //IMPROVE: could store more than a character sized buffer for faster disk access
00100   if ((input_bitbucket_place >= 6) || (flush == true))
00101   {
00102     putc(input_bitbucket_ch,fp);
00103     //printf ("\nbitchar:%x, place=%d",input_bitbucket_ch,input_bitbucket_place);
00104     //reset values to start processing next char
00105     input_bitbucket_place = -2;
00106     input_bitbucket_ch = (char)0xAA;
00107   }
00108   input_bitbucket_place++;
00109   input_bitbucket_place++;
00110 }
00111 
00112 char output_bitbucket (bool &eof_found, FILE *fp)
00113 //Reads from disk the invalue of 0x00,0x01,0x03 in 2 byte chunks
00114 //Rules: look for eof_found == true to find when to quit.
00115 //       if quit, ignore the current character ( == 2 )
00116 {
00117   
00118   char tempout;
00119   
00120   eof_found = false;
00121   //format is [4][3][2][1] in the 8 bit byte.
00122   //if there is no entry then the space will be occupied by 0x02.
00123   //note that on first pass when ch = 0, has no effect on data.
00124   output_bitbucket_ch = output_bitbucket_ch >> 2;
00125   if (output_bitbucket_place == 0)
00126   {
00127     //read target char from file
00128     output_bitbucket_ch = getc(fp);
00129     // Note: we may read in a char value with exactly the value of EOF from the
00130     // binary file, so forget about EOF and look for the 0x02 marker.
00131   } 
00132   output_bitbucket_place++;
00133   output_bitbucket_place++;
00134   //reset counter if reading is at end of the byte
00135   if (output_bitbucket_place >= 8)
00136     output_bitbucket_place = 0;
00137   //printf ("\nbitchar:%x, place=%d",output_bitbucket_ch,output_bitbucket_place);
00138   
00139   //the 2 lsb of the byte are the ones we are interested in now
00140   tempout = output_bitbucket_ch & 0x03;
00141   if (tempout == 0x02)
00142     eof_found=true;
00143   
00144   return (tempout);
00145 }
00146 
00147 OctreeNode* read_node(FILE *tree_structure)
00148 {
00149   char color;
00150   bool temp= false;
00151   
00152   OctreeNode* p;
00153   color = output_bitbucket(temp,tree_structure);
00154   if ( temp == true )
00155     return(NULL);
00156   
00157   p = ( OctreeNode* ) malloc( sizeof( OctreeNode ) );
00158   //p->info_value = 0.0;
00159   //p = new OctreeNode;
00160   p->son = NULL;
00161   if(color == GRAY) {
00162     int i;
00163     i = 1;
00164     p->color = i;
00165     p->son = (struct child_pointer*) malloc(sizeof(struct child_pointer));
00166     
00167     p->son->pointer[0]= read_node(tree_structure);
00168     p->son->pointer[1]= read_node(tree_structure);
00169     p->son->pointer[2]= read_node(tree_structure);
00170     p->son->pointer[3]= read_node(tree_structure);
00171     p->son->pointer[4]= read_node(tree_structure);
00172     p->son->pointer[5]= read_node(tree_structure);
00173     p->son->pointer[6]= read_node(tree_structure);
00174     p->son->pointer[7]= read_node(tree_structure);
00175     p->son->pointer[0]->father =p;
00176     p->son->pointer[1]->father =p;
00177     p->son->pointer[2]->father =p;
00178     p->son->pointer[3]->father =p;
00179     p->son->pointer[4]->father =p;
00180     p->son->pointer[5]->father =p;
00181     p->son->pointer[6]->father =p;
00182     p->son->pointer[7]->father =p;
00183   }
00184   else
00185   {
00186     p->color = color;
00187     p->son = NULL;
00188     
00189   }
00190   return(p);   
00191 }
00192 
00193 void save_node(OctreeNode* node, FILE  *tree_structure)
00194 {
00195   if( node->color == WHITE)
00196   {
00197     input_bitbucket (WHITE,false,tree_structure);
00198   }
00199   if( node->color == BLACK)
00200   {
00201     input_bitbucket (BLACK,false,tree_structure);
00202   }
00203   if( node->color == GRAY)
00204   {
00205     input_bitbucket (GRAY,false,tree_structure);
00206   }
00207   
00208   if(node->son != NULL)
00209   {
00210     save_node(node->son->pointer[0], tree_structure);
00211     save_node(node->son->pointer[1], tree_structure);
00212     save_node(node->son->pointer[2], tree_structure);
00213     save_node(node->son->pointer[3], tree_structure);
00214     save_node(node->son->pointer[4], tree_structure);
00215     save_node(node->son->pointer[5], tree_structure);
00216     save_node(node->son->pointer[6], tree_structure);
00217     save_node(node->son->pointer[7], tree_structure);
00218   }
00219   if ( node->father == NULL )
00220   {
00221     input_bitbucket (2,true,tree_structure);
00222   }
00223   
00224   return;
00225 }
00226 
00227 int volume = 0;
00228 void octree_volume( OctreeNode* node, int level)
00229 {
00230   if(node->father == NULL) volume = 0;
00231   if( node->color == WHITE)
00232   {
00233     volume += (int) pow(2.0, (double) level);
00234   }
00235   
00236   if(node->son != NULL)
00237   {
00238     octree_volume(node->son->pointer[0], level -1);
00239     octree_volume(node->son->pointer[1], level -1);
00240     octree_volume(node->son->pointer[2], level -1);
00241     octree_volume(node->son->pointer[3], level -1);
00242     octree_volume(node->son->pointer[4], level -1);
00243     octree_volume(node->son->pointer[5], level -1);
00244     octree_volume(node->son->pointer[6], level -1);
00245     octree_volume(node->son->pointer[7], level -1);
00246   }
00247 }
00248 
00249 void negative( OctreeNode* node )
00250 {
00251   /*negative an octree , tree root is not changed*/
00252   
00253   if( node->color == WHITE)
00254   {
00255     node->color = BLACK;
00256     return;
00257   }
00258   if( node->color == BLACK)
00259   {
00260     node->color = WHITE;
00261     return;
00262   }
00263   if(node->son != NULL)
00264   {
00265     negative(node->son->pointer[0]);
00266     negative(node->son->pointer[1]);
00267     negative(node->son->pointer[2]);
00268     negative(node->son->pointer[3]);
00269     negative(node->son->pointer[4]);
00270     negative(node->son->pointer[5]);
00271     negative(node->son->pointer[6]);
00272     negative(node->son->pointer[7]);
00273   }
00274   return;
00275 }
00276 
00277 
00278 
00279 
00280 OctreeNode* create_node(char color_node)
00281 {
00282   /*creat a node with specified color */
00283   OctreeNode *q;
00284   //int i;
00285   q = (OctreeNode *)malloc(sizeof(OctreeNode));
00286   if(color_node == GRAY)
00287   {
00288     q->son = (struct child_pointer*) malloc(sizeof(struct child_pointer));
00289     //for(i =0; i< 8; i++) 
00290     //q->son->pointer[i] = NULL;
00291   }
00292   else
00293   {
00294     q->son = NULL;
00295   }
00296   q-> color = color_node;
00297   q->father = NULL;
00298   //q->info_value = 0.0;
00299   return(q);
00300 }
00301 
00302 OctreeNode* copy(OctreeNode *node)
00303 {
00304   /* make a copy of an octree, oringal one is not changed */
00305   OctreeNode *p;
00306   int i;
00307   p = create_node(node->color);
00308   if(node->color==GRAY)
00309   {
00310     for(i=0; i< 8; i++)
00311     {
00312       p->son->pointer[i]= copy(node->son->pointer[i]);
00313       p->son->pointer[i]->father= p;
00314     }
00315   }
00316   return(p);
00317 }
00318 
00319 
00320 
00321 void clean(OctreeNode *node)
00322 {
00323   /* clean nodes with all their child nodes having the same color */
00324   int i;
00325   if(node->color==GRAY)
00326   {
00327     for(i=0; i< 8; i++)   
00328     {
00329       clean(node->son->pointer[i]);
00330     }
00331     if( (node->son->pointer[0]->color== BLACK) && (node->son->pointer[1]->color== BLACK) && 
00332       (node->son->pointer[2]->color== BLACK) && (node->son->pointer[3]->color== BLACK) &&
00333       (node->son->pointer[4]->color== BLACK) && (node->son->pointer[5]->color== BLACK) &&
00334       (node->son->pointer[6]->color== BLACK) && (node->son->pointer[7]->color== BLACK) )
00335     {
00336       for(i=0; i<8; i++)
00337         delete_node(node->son->pointer[i]);
00338       node->color= BLACK;
00339       free(node->son);
00340       node->son = NULL;
00341     }
00342     else if( (node->son->pointer[0]->color== WHITE) && (node->son->pointer[1]->color== WHITE) && 
00343       (node->son->pointer[2]->color== WHITE) && (node->son->pointer[3]->color== WHITE) &&
00344       (node->son->pointer[4]->color== WHITE) && (node->son->pointer[5]->color== WHITE) &&
00345       (node->son->pointer[6]->color== WHITE) && (node->son->pointer[7]->color== WHITE) )
00346     {
00347       for(i=0; i<8; i++)
00348         delete_node(node->son->pointer[i]);
00349       node->color= WHITE;
00350       free(node->son);
00351       node->son = NULL;
00352     }
00353     
00354   }
00355 }
00356 
00357 
00358 
00359 void detach(OctreeNode *node)
00360 {
00361   /* detatch a branch from its tree */
00362   OctreeNode *father;
00363   int i;
00364   
00365   if(node == NULL ) return;
00366   if(node->father == NULL ) return;
00367   father = node->father;
00368   for(i = 0; i< 8; i++)
00369   {
00370     if(father->son->pointer[i] == node) 
00371     {
00372       father->son->pointer[i] = NULL;
00373       break;
00374     }
00375   }
00376   if(father->son != NULL)
00377     if( (father->son->pointer[0]==NULL) && (father->son->pointer[1]==NULL) &&
00378       (father->son->pointer[2]==NULL) && (father->son->pointer[3]==NULL) &&
00379       (father->son->pointer[4]==NULL) && (father->son->pointer[5]==NULL) &&
00380       (father->son->pointer[6]==NULL) && (father->son->pointer[7]==NULL) )
00381     {
00382       free(father->son);
00384       father->son = NULL;
00385     } 
00386 }
00387 
00388 
00389 
00390 int check_node_containment(OctreeNode *node, struct cubic_d *worldsize, 
00391                             vector_d target)
00392 //return values;
00393 //0 contained in black node
00394 //1 contained in white node
00395 //2 don't know (outside of octree box range)
00396 {
00397   struct cubic_d sub_c;
00398   double x_mid, y_mid, z_mid;
00399   int retvalue;
00400     
00401   //failure case is: target point not inside currently considered box
00402   if ( (target.x > worldsize->x1) ||
00403   (target.y > worldsize->y1) ||
00404   (target.z > worldsize->z1) ||
00405   (target.x <= worldsize->x0) ||
00406   (target.y <= worldsize->y0) ||
00407   (target.z <= worldsize->z0) )
00408   {
00409     return 2;
00410   }
00411 
00412   //now we know point is contained
00413   if (node->color==WHITE)
00414   {
00415     //in known free space
00416     return 1;
00417   }
00418 
00419   if (node->color==BLACK)
00420   {
00421     //in unknown space
00422     return 0;
00423   }
00424   
00425   //now we know brick can be subdivided
00426   if (node->color==GRAY)
00427   {
00428     
00429     x_mid = (worldsize->x1 + worldsize->x0)/2.0;
00430     y_mid = (worldsize->y1 + worldsize->y0)/2.0;
00431     z_mid = (worldsize->z1 + worldsize->z0)/2.0;
00432     
00433     sub_c.x0= worldsize->x0;
00434     sub_c.y0= worldsize->y0;
00435     sub_c.z0= worldsize->z0;
00436     sub_c.x1= x_mid;
00437     sub_c.y1= y_mid;
00438     sub_c.z1= z_mid; 
00439     retvalue = check_node_containment(node->son->pointer[0], &sub_c, target);
00440     if (retvalue != 2) 
00441       goto check_node_containment_end;
00442     //sorry about the goto, but I think this is a good way
00443     
00444     sub_c.x0= worldsize->x0;
00445     sub_c.y0= worldsize->y0;
00446     sub_c.z0= z_mid;
00447     sub_c.x1= x_mid;
00448     sub_c.y1= y_mid;
00449     sub_c.z1= worldsize->z1;
00450     retvalue = check_node_containment(node->son->pointer[1], &sub_c, target);
00451     if (retvalue != 2) 
00452       goto check_node_containment_end; 
00453     
00454     sub_c.x0= worldsize->x0;
00455     sub_c.y0= y_mid;
00456     sub_c.z0= worldsize->z0;
00457     sub_c.x1= x_mid;
00458     sub_c.y1= worldsize->y1;
00459     sub_c.z1= z_mid;
00460     retvalue = check_node_containment(node->son->pointer[2], &sub_c, target);
00461     if (retvalue != 2) 
00462       goto check_node_containment_end;    
00463 
00464     sub_c.x0= worldsize->x0;
00465     sub_c.y0= y_mid;
00466     sub_c.z0= z_mid;
00467     sub_c.x1= x_mid;
00468     sub_c.y1= worldsize->y1;
00469     sub_c.z1= worldsize->z1;
00470     retvalue = check_node_containment(node->son->pointer[3], &sub_c, target);
00471     if (retvalue != 2) 
00472       goto check_node_containment_end;    
00473 
00474     sub_c.x0= x_mid;
00475     sub_c.y0= worldsize->y0;
00476     sub_c.z0= worldsize->z0;
00477     sub_c.x1= worldsize->x1;
00478     sub_c.y1= y_mid;
00479     sub_c.z1= z_mid;
00480     retvalue = check_node_containment(node->son->pointer[4], &sub_c, target);
00481     if (retvalue != 2) 
00482       goto check_node_containment_end;    
00483 
00484     sub_c.x0= x_mid;
00485     sub_c.y0= worldsize->y0;
00486     sub_c.z0= z_mid;
00487     sub_c.x1= worldsize->x1;
00488     sub_c.y1= y_mid;
00489     sub_c.z1= worldsize->z1;
00490     retvalue = check_node_containment(node->son->pointer[5], &sub_c, target);
00491     if (retvalue != 2) 
00492       goto check_node_containment_end;    
00493 
00494     sub_c.x0= x_mid;
00495     sub_c.y0= y_mid;
00496     sub_c.z0= worldsize->z0;
00497     sub_c.x1= worldsize->x1;
00498     sub_c.y1= worldsize->y1;
00499     sub_c.z1= z_mid;
00500     retvalue = check_node_containment(node->son->pointer[6], &sub_c, target);
00501     if (retvalue != 2) 
00502       goto check_node_containment_end;    
00503 
00504     sub_c.x0= x_mid;
00505     sub_c.y0= y_mid;
00506     sub_c.z0= z_mid;
00507     sub_c.x1= worldsize->x1;
00508     sub_c.y1= worldsize->y1;
00509     sub_c.z1= worldsize->z1;
00510     retvalue = check_node_containment(node->son->pointer[7], &sub_c, target);
00511     if (retvalue != 2)
00512       goto check_node_containment_end;
00513   }
00514 
00515   check_node_containment_end:
00516   return retvalue;
00517 }
00518 
00519 OctreeNode * create_block_node(int level, 
00520                                 struct cubic *desired,
00521                                 struct cubic *worldsize, int maxlevel)
00522 {
00523   OctreeNode *p;
00524   struct cubic sub_c;
00525   int x_mid, y_mid, z_mid;
00526   int next_level;
00527   
00528   if ( (desired->x0 > worldsize->x1) ||
00529     (desired->y0 > worldsize->y1) ||
00530     (desired->z0 > worldsize->z1) ||
00531     (desired->x1 <= worldsize->x0) ||
00532     (desired->y1 <= worldsize->y0) ||
00533     (desired->z1 <= worldsize->z0) )
00534   {
00535     p = assign_black_node();
00536     if (level == 0)
00537       p->father = NULL;
00538     return(p);
00539   }; 
00540   
00541   //now we know brick is inside
00542   
00543   if ( ( (desired->x0 <= worldsize->x0) && (desired->x1 >= worldsize->x1) &&
00544     (desired->y0 <= worldsize->y0) && (desired->y1 >= worldsize->y1) &&
00545     (desired->z0 <= worldsize->z0) && (desired->z1 >= worldsize->z1) ) ||
00546     (level >= maxlevel) )
00547   {
00548     p = assign_white_node();
00549     if (level == 0)
00550       p->father = NULL;
00551     return(p);
00552   }; 
00553   
00554   //now we know brick can be subdivided.
00555   
00556   x_mid = (worldsize->x1 + worldsize->x0)/2;
00557   y_mid = (worldsize->y1 + worldsize->y0)/2;
00558   z_mid = (worldsize->z1 + worldsize->z0)/2;
00559   
00560   p = (OctreeNode *) malloc(sizeof(OctreeNode));    
00561   p->son = (struct child_pointer*) malloc(sizeof(struct child_pointer));
00562   if ((p == NULL) || (p->son == NULL))
00563   {
00564     printf("space max reached\n");
00565   } 
00566   p->color = GRAY;
00567   
00568   next_level = level+1;
00569   sub_c.x0= worldsize->x0;
00570   sub_c.y0= worldsize->y0;
00571   sub_c.z0= worldsize->z0;
00572   sub_c.x1= x_mid;
00573   sub_c.y1= y_mid;
00574   sub_c.z1= z_mid; 
00575   p->son->pointer[0] = create_block_node(next_level, desired, &sub_c, maxlevel);
00576   p->son->pointer[0]->father= p;
00577   
00578   sub_c.x0= worldsize->x0;
00579   sub_c.y0= worldsize->y0;
00580   sub_c.z0= z_mid;
00581   sub_c.x1= x_mid;
00582   sub_c.y1= y_mid;
00583   sub_c.z1= worldsize->z1;
00584   p->son->pointer[1] = create_block_node(next_level, desired, &sub_c, maxlevel);
00585   p->son->pointer[1]->father= p;
00586   
00587   sub_c.x0= worldsize->x0;
00588   sub_c.y0= y_mid;
00589   sub_c.z0= worldsize->z0;
00590   sub_c.x1= x_mid;
00591   sub_c.y1= worldsize->y1;
00592   sub_c.z1= z_mid;
00593   p->son->pointer[2] = create_block_node(next_level, desired, &sub_c, maxlevel);
00594   p->son->pointer[2]->father= p;
00595   
00596   sub_c.x0= worldsize->x0;
00597   sub_c.y0= y_mid;
00598   sub_c.z0= z_mid;
00599   sub_c.x1= x_mid;
00600   sub_c.y1= worldsize->y1;
00601   sub_c.z1= worldsize->z1;
00602   p->son->pointer[3] = create_block_node(next_level, desired, &sub_c, maxlevel);
00603   p->son->pointer[3]->father= p;
00604   
00605   sub_c.x0= x_mid;
00606   sub_c.y0= worldsize->y0;
00607   sub_c.z0= worldsize->z0;
00608   sub_c.x1= worldsize->x1;
00609   sub_c.y1= y_mid;
00610   sub_c.z1= z_mid;
00611   p->son->pointer[4] = create_block_node(next_level, desired, &sub_c, maxlevel);
00612   p->son->pointer[4]->father= p;
00613   
00614   sub_c.x0= x_mid;
00615   sub_c.y0= worldsize->y0;
00616   sub_c.z0= z_mid;
00617   sub_c.x1= worldsize->x1;
00618   sub_c.y1= y_mid;
00619   sub_c.z1= worldsize->z1;
00620   p->son->pointer[5] = create_block_node(next_level, desired, &sub_c, maxlevel);
00621   p->son->pointer[5]->father= p;
00622   
00623   sub_c.x0= x_mid;
00624   sub_c.y0= y_mid;
00625   sub_c.z0= worldsize->z0;
00626   sub_c.x1= worldsize->x1;
00627   sub_c.y1= worldsize->y1;
00628   sub_c.z1= z_mid;
00629   p->son->pointer[6] = create_block_node(next_level, desired, &sub_c, maxlevel);
00630   p->son->pointer[6]->father= p;
00631   
00632   sub_c.x0= x_mid;
00633   sub_c.y0= y_mid;
00634   sub_c.z0= z_mid;
00635   sub_c.x1= worldsize->x1;
00636   sub_c.y1= worldsize->y1;
00637   sub_c.z1= worldsize->z1;
00638   p->son->pointer[7] = create_block_node(next_level, desired, &sub_c, maxlevel);
00639   p->son->pointer[7]->father= p;
00640   
00641   if (level == 0)
00642     p->father = NULL;
00643   return(p);
00644 }
00645 
00646 OctreeNode * create_line_node(int level, 
00647                                vector_i *center,
00648                                struct cubic *worldsize, int maxlevel)
00649 {
00650   OctreeNode *p;
00651   struct cubic sub_c;
00652   int x_mid, y_mid, z_mid;
00653   int next_level,i;
00654   bool lineptfound;
00655   
00656   lineptfound = false;
00657   for (i=0;i<MAXLINELENGTH;i++)
00658   {
00659     //if there is any point in the line which is not outside the current one
00660     if ( !( (center[i].x > worldsize->x1) ||
00661       (center[i].y > worldsize->y1) ||
00662       (center[i].z > worldsize->z1) ||
00663       (center[i].x <= worldsize->x0) ||
00664       (center[i].y <= worldsize->y0) ||
00665       (center[i].z <= worldsize->z0) ) )
00666     {
00667       lineptfound = true;
00668     }
00669   }
00670   
00671   
00672   if ( lineptfound == false )
00673   {
00674     p = assign_black_node();
00675     if (level == 0)
00676       p->father = NULL;
00677     return(p);
00678   }; 
00679   
00680   //now we know brick is inside
00681   //look for a minimum sized brick to make white
00682   
00683   
00684   for (i=0;i<MAXLINELENGTH;i++)
00685   {
00686     
00687     if ( ( (center[i].x <= worldsize->x0) && (center[i].x >= worldsize->x1) &&
00688       (center[i].y <= worldsize->y0) && (center[i].y >= worldsize->y1) &&
00689       (center[i].z <= worldsize->z0) && (center[i].z >= worldsize->z1) ) ||
00690       (level >= maxlevel) )
00691     {
00692       p = assign_white_node();
00693       if (level == 0)
00694         p->father = NULL;
00695       return(p);
00696     }; 
00697   }
00698   
00699   //now we know brick can be subdivided.
00700   
00701   x_mid = (worldsize->x1 + worldsize->x0)/2;
00702   y_mid = (worldsize->y1 + worldsize->y0)/2;
00703   z_mid = (worldsize->z1 + worldsize->z0)/2;
00704   
00705   p = (OctreeNode *) malloc(sizeof(OctreeNode));    
00706   p->son = (struct child_pointer*) malloc(sizeof(struct child_pointer));
00707   if ((p == NULL) || (p->son == NULL))
00708   {
00709     printf("space max reached\n");
00710   } 
00711   p->color = GRAY;
00712   
00713   next_level = level+1;
00714   sub_c.x0= worldsize->x0;
00715   sub_c.y0= worldsize->y0;
00716   sub_c.z0= worldsize->z0;
00717   sub_c.x1= x_mid;
00718   sub_c.y1= y_mid;
00719   sub_c.z1= z_mid; 
00720   p->son->pointer[0] = create_line_node(next_level, center, &sub_c, maxlevel);
00721   p->son->pointer[0]->father= p;
00722   
00723   sub_c.x0= worldsize->x0;
00724   sub_c.y0= worldsize->y0;
00725   sub_c.z0= z_mid;
00726   sub_c.x1= x_mid;
00727   sub_c.y1= y_mid;
00728   sub_c.z1= worldsize->z1;
00729   p->son->pointer[1] = create_line_node(next_level, center, &sub_c, maxlevel);
00730   p->son->pointer[1]->father= p;
00731   
00732   sub_c.x0= worldsize->x0;
00733   sub_c.y0= y_mid;
00734   sub_c.z0= worldsize->z0;
00735   sub_c.x1= x_mid;
00736   sub_c.y1= worldsize->y1;
00737   sub_c.z1= z_mid;
00738   p->son->pointer[2] = create_line_node(next_level, center, &sub_c, maxlevel);
00739   p->son->pointer[2]->father= p;
00740   
00741   sub_c.x0= worldsize->x0;
00742   sub_c.y0= y_mid;
00743   sub_c.z0= z_mid;
00744   sub_c.x1= x_mid;
00745   sub_c.y1= worldsize->y1;
00746   sub_c.z1= worldsize->z1;
00747   p->son->pointer[3] = create_line_node(next_level, center, &sub_c, maxlevel);
00748   p->son->pointer[3]->father= p;
00749   
00750   sub_c.x0= x_mid;
00751   sub_c.y0= worldsize->y0;
00752   sub_c.z0= worldsize->z0;
00753   sub_c.x1= worldsize->x1;
00754   sub_c.y1= y_mid;
00755   sub_c.z1= z_mid;
00756   p->son->pointer[4] = create_line_node(next_level, center, &sub_c, maxlevel);
00757   p->son->pointer[4]->father= p;
00758   
00759   sub_c.x0= x_mid;
00760   sub_c.y0= worldsize->y0;
00761   sub_c.z0= z_mid;
00762   sub_c.x1= worldsize->x1;
00763   sub_c.y1= y_mid;
00764   sub_c.z1= worldsize->z1;
00765   p->son->pointer[5] = create_line_node(next_level, center, &sub_c, maxlevel);
00766   p->son->pointer[5]->father= p;
00767   
00768   sub_c.x0= x_mid;
00769   sub_c.y0= y_mid;
00770   sub_c.z0= worldsize->z0;
00771   sub_c.x1= worldsize->x1;
00772   sub_c.y1= worldsize->y1;
00773   sub_c.z1= z_mid;
00774   p->son->pointer[6] = create_line_node(next_level, center, &sub_c, maxlevel);
00775   p->son->pointer[6]->father= p;
00776   
00777   sub_c.x0= x_mid;
00778   sub_c.y0= y_mid;
00779   sub_c.z0= z_mid;
00780   sub_c.x1= worldsize->x1;
00781   sub_c.y1= worldsize->y1;
00782   sub_c.z1= worldsize->z1;
00783   p->son->pointer[7] = create_line_node(next_level, center, &sub_c, maxlevel);
00784   p->son->pointer[7]->father= p;
00785   
00786   if (level == 0)
00787     p->father = NULL;
00788   return(p);
00789 }
00790 
00791 OctreeNode * create_view_node(int level, 
00792                                vector_i *center,
00793                                int arraysize,
00794                                struct cubic *worldsize, int maxlevel)
00795 {
00796   OctreeNode *p;
00797   struct cubic sub_c;
00798   int x_mid, y_mid, z_mid;
00799   int next_level,i;
00800   bool lineptfound;
00801   
00802   lineptfound = false;
00803   for (i=0;i<arraysize;i++)
00804   {
00805     //if there is any point in the line which is not outside the current one
00806     if ( !( (center[i].x > worldsize->x1) ||
00807       (center[i].y > worldsize->y1) ||
00808       (center[i].z > worldsize->z1) ||
00809       (center[i].x <= worldsize->x0) ||
00810       (center[i].y <= worldsize->y0) ||
00811       (center[i].z <= worldsize->z0) ) )
00812     {
00813       lineptfound = true;
00814     }
00815   }
00816   
00817   
00818   if ( lineptfound == false )
00819   {
00820     p = assign_black_node();
00821     if (level == 0)
00822       p->father = NULL;
00823     return(p);
00824   }; 
00825   
00826   //now we know brick is inside
00827   //look for a minimum sized brick to make white
00828   
00829   
00830   for (i=0;i<arraysize;i++)
00831   {
00832     
00833     if ( ( (center[i].x <= worldsize->x0) && (center[i].x >= worldsize->x1) &&
00834       (center[i].y <= worldsize->y0) && (center[i].y >= worldsize->y1) &&
00835       (center[i].z <= worldsize->z0) && (center[i].z >= worldsize->z1) ) ||
00836       (level >= maxlevel) )
00837     {
00838       p = assign_white_node();
00839       if (level == 0)
00840         p->father = NULL;
00841       return(p);
00842     }; 
00843   }
00844   
00845   //now we know brick can be subdivided.
00846   
00847   x_mid = (worldsize->x1 + worldsize->x0)/2;
00848   y_mid = (worldsize->y1 + worldsize->y0)/2;
00849   z_mid = (worldsize->z1 + worldsize->z0)/2;
00850   
00851   p = (OctreeNode *) malloc(sizeof(OctreeNode));    
00852   p->son = (struct child_pointer*) malloc(sizeof(struct child_pointer));
00853   if ((p == NULL) || (p->son == NULL))
00854   {
00855     printf("space max reached\n");
00856   } 
00857   p->color = GRAY;
00858   
00859   next_level = level+1;
00860   sub_c.x0= worldsize->x0;
00861   sub_c.y0= worldsize->y0;
00862   sub_c.z0= worldsize->z0;
00863   sub_c.x1= x_mid;
00864   sub_c.y1= y_mid;
00865   sub_c.z1= z_mid; 
00866   p->son->pointer[0] = create_line_node(next_level, center, &sub_c, maxlevel);
00867   p->son->pointer[0]->father= p;
00868   
00869   sub_c.x0= worldsize->x0;
00870   sub_c.y0= worldsize->y0;
00871   sub_c.z0= z_mid;
00872   sub_c.x1= x_mid;
00873   sub_c.y1= y_mid;
00874   sub_c.z1= worldsize->z1;
00875   p->son->pointer[1] = create_line_node(next_level, center, &sub_c, maxlevel);
00876   p->son->pointer[1]->father= p;
00877   
00878   sub_c.x0= worldsize->x0;
00879   sub_c.y0= y_mid;
00880   sub_c.z0= worldsize->z0;
00881   sub_c.x1= x_mid;
00882   sub_c.y1= worldsize->y1;
00883   sub_c.z1= z_mid;
00884   p->son->pointer[2] = create_line_node(next_level, center, &sub_c, maxlevel);
00885   p->son->pointer[2]->father= p;
00886   
00887   sub_c.x0= worldsize->x0;
00888   sub_c.y0= y_mid;
00889   sub_c.z0= z_mid;
00890   sub_c.x1= x_mid;
00891   sub_c.y1= worldsize->y1;
00892   sub_c.z1= worldsize->z1;
00893   p->son->pointer[3] = create_line_node(next_level, center, &sub_c, maxlevel);
00894   p->son->pointer[3]->father= p;
00895   
00896   sub_c.x0= x_mid;
00897   sub_c.y0= worldsize->y0;
00898   sub_c.z0= worldsize->z0;
00899   sub_c.x1= worldsize->x1;
00900   sub_c.y1= y_mid;
00901   sub_c.z1= z_mid;
00902   p->son->pointer[4] = create_line_node(next_level, center, &sub_c, maxlevel);
00903   p->son->pointer[4]->father= p;
00904   
00905   sub_c.x0= x_mid;
00906   sub_c.y0= worldsize->y0;
00907   sub_c.z0= z_mid;
00908   sub_c.x1= worldsize->x1;
00909   sub_c.y1= y_mid;
00910   sub_c.z1= worldsize->z1;
00911   p->son->pointer[5] = create_line_node(next_level, center, &sub_c, maxlevel);
00912   p->son->pointer[5]->father= p;
00913   
00914   sub_c.x0= x_mid;
00915   sub_c.y0= y_mid;
00916   sub_c.z0= worldsize->z0;
00917   sub_c.x1= worldsize->x1;
00918   sub_c.y1= worldsize->y1;
00919   sub_c.z1= z_mid;
00920   p->son->pointer[6] = create_line_node(next_level, center, &sub_c, maxlevel);
00921   p->son->pointer[6]->father= p;
00922   
00923   sub_c.x0= x_mid;
00924   sub_c.y0= y_mid;
00925   sub_c.z0= z_mid;
00926   sub_c.x1= worldsize->x1;
00927   sub_c.y1= worldsize->y1;
00928   sub_c.z1= worldsize->z1;
00929   p->son->pointer[7] = create_line_node(next_level, center, &sub_c, maxlevel);
00930   p->son->pointer[7]->father= p;
00931   
00932   if (level == 0)
00933     p->father = NULL;
00934   return(p);
00935 }
00936 
00937 
00938 OctreeNode * union_node(OctreeNode *node1, OctreeNode *node2)
00939 {
00940 /* construct the union of two octrees, both of the orginal 
00941   trees are NOT destroyed */
00942   int  i;
00943   OctreeNode *q, *p[8];
00944   
00945   if( white_node(node1) || white_node(node2) )
00946   {
00947     q= create_node(WHITE);
00948     //delete_node(node1);
00949     //delete_node(node2);
00950     return(q);
00951   }
00952   else if  (black_node( node1))
00953   {
00954     //delete_node(node1);
00955     //detach(node2);
00956     return(copy(node2));
00957   }
00958   else if  (black_node( node2))
00959   {
00960     //delete_node(node2);
00961     //detach(node1);
00962     return(copy(node1)); 
00963   }
00964   else
00965   {
00966     for(i = 0; i < 8; i++)
00967     {
00968       p[i]=  union_node(node1->son->pointer[i], node2->son->pointer[i]);
00969     }
00970     if(white_node(p[0])&&white_node(p[1])&&white_node(p[2])&&white_node(p[3])&&
00971       white_node(p[4])&&white_node(p[5])&&white_node(p[6])&&white_node(p[7]))
00972     {
00973       for( i = 0; i < 8; i++) 
00974       {
00975         free(p[i]);
00976       }
00977       q= create_node(WHITE);
00978       return(q); 
00979     }
00980     else
00981     {
00982       q = create_node(GRAY);
00983       for( i = 0; i < 8; i++) 
00984       {
00985         q->son->pointer[i] = p[i];
00986         q->son->pointer[i] -> father = q;
00987       }
00988       //delete_node(node1);
00989       //delete_node(node2);
00990       return(q);
00991     }
00992   }
00993 }
00994 
00995 OctreeNode *intersection_node(OctreeNode *node1, OctreeNode *node2)
00996 {
00997 /* construct the intersection of two octrees, both of the orginal 
00998   trees are NOT destroyed */
00999   int  i;  
01000   OctreeNode *q, *p[8];   
01001   
01002   if( black_node(node1) || black_node(node2) )
01003   {   
01004     q= create_node(BLACK);
01005     //delete_node(node1);  
01006     //delete_node(node2);
01007     return(q);  
01008   }   
01009   else if  (white_node( node1))
01010   {   
01011     //delete_node(node1);
01012     //detach(node2);
01013     return(copy(node2));    
01014   }   
01015   else if  (white_node( node2))
01016   {   
01017     //delete_node(node2);
01018     //detach(node1); 
01019     return(copy(node1));    
01020   }   
01021   else 
01022   {
01023     for(i = 0; i < 8; i++)
01024     {
01025       p[i]=  intersection_node(node1->son->pointer[i], node2->son->pointer[i]);
01026     }
01027     if(black_node(p[0])&&black_node(p[1])&&black_node(p[2])&&black_node(p[3])&&
01028       black_node(p[4])&&black_node(p[5])&&black_node(p[6])&&black_node(p[7]))
01029     {
01030       for( i = 0; i < 8; i++) free(p[i]);
01031       
01032       q= create_node(BLACK);
01033       return(q); 
01034     }
01035     else 
01036     {
01037       q = create_node(GRAY);  
01038       for( i = 0; i < 8; i++) 
01039       {
01040         q->son->pointer[i] = p[i];
01041         q->son->pointer[i] -> father = q;
01042       }
01043       //delete_node(node1);  
01044       //delete_node(node2);
01045       return(q);
01046     }
01047   }    
01048 }
01049 
01050 OctreeNode * construct_octree_wrapper (struct free_space * pic, int maxlevel, Range_Sensor* jc)
01051 //note: if the intersection point isn't inside the octree world, problems
01052 //(fuzziness in generated octree) result.
01053 {
01054   struct cubic incube;
01055   OctreeNode *root;
01056   
01057   incube.x0 = incube.y0 = incube.z0 = 0;   //note: other values for incube can result in errors;
01058   incube.x1 = incube.y1 = incube.z1 = 256; //should use this value...
01059   
01060   calculate_scaled_distance (pic,jc);
01061   //expand_image (pic,-5);
01062   root = construct_octree(pic, &incube, 0, maxlevel);
01063   root->father = NULL;
01064   return (root);
01065   
01066 }
01067 
01068 OctreeNode * create_block_wrapper (vector_i center, cubic dimensions, int maxlevel)
01069 {
01070   struct cubic incube,descube;
01071   
01072   incube.x0 = incube.y0 = incube.z0 = 0;   //note: other values for incube can result in errors;
01073   incube.x1 = incube.y1 = incube.z1 = 256; //should use this value...
01074   
01075   descube.x0 = LIMIT + center.x - dimensions.x0;
01076   descube.x1 = LIMIT + center.x + dimensions.x1;
01077   descube.y0 = LIMIT + center.y - dimensions.y0;
01078   descube.y1 = LIMIT + center.y + dimensions.y1;
01079   descube.z0 = LIMIT - center.z - dimensions.z0;
01080   descube.z1 = LIMIT - center.z + dimensions.z1;
01081   
01082   return (create_block_node(0,&descube,&incube,maxlevel));
01083 }
01084 
01085 
01086 
01087 bool operator< (const PointClass& p1, const PointClass& p2)
01088 {
01089   return ( memcmp( p1.p, p2.p, 3*sizeof(char)) < 0);
01090 }
01091 
01092 bool operator== (const PointClass& p1, const PointClass& p2)
01093 {
01094   return ( memcmp( p1.p, p2.p, 3*sizeof(char)) == 0);
01095 }
01096 
01097 
01098 void update_cubes_set (std::set<PointClass> &s1, Range_Sensor* camera, 
01099                        OctreeNode* node, struct cubic_d worldsize)
01100 {
01101   int i,j;
01102   PointClass temp;
01103   vector_d target;
01104 
01105   for (i=0; i<256; i++)
01106   {
01107     for (j=0; j<256; j++)
01108     {
01109       if ((camera->ray_depth_map[i][j] < camera->GetMaxRange()) && (camera->ray_depth_map[i][j] > 0))
01110       {
01111         temp.p[0] = (int) camera->ray_coord_map[i][j][0];
01112         temp.p[1] = (int) camera->ray_coord_map[i][j][1];
01113         temp.p[2] = (int) camera->ray_coord_map[i][j][2];
01114         target.x = camera->ray_coord_map[i][j][0];
01115         target.y = camera->ray_coord_map[i][j][1];
01116         target.z = camera->ray_coord_map[i][j][2];
01117         //TRACE("\ninto cubes set (%d,%d,%d)",temp.p[0],temp.p[1],temp.p[2]);
01118         //double x0 = worldsize.x0;
01119         //double x1 = worldsize.x1;
01120         //if element isn't already in set and is contained in black node, insert it
01121         if ((s1.find(temp) == s1.end()) && (check_node_containment(node, &worldsize, target) == 0))
01122         {
01123           s1.insert(temp);          
01124         }
01125       }
01126     }
01127   }
01128 }
01129 
01130 void extract_cubes_set (std::set<PointClass> &s1, double magnifyfactor, 
01131                                                             std::vector<Square> &squarevector, int maxlevel)
01132 {  
01133   PointClass pointmarker;
01134   vector_d point, farpoint;
01135 
01136   double a[3],b[3],c[3],d[3],e[3],f[3],g[3],h[3];
01137 
01138   Square tempsq;
01139 
01140   std::set<PointClass>::iterator it;
01141 
01142   it = s1.begin();
01143   while (it != s1.end())
01144   {
01145     pointmarker = *it;
01146 
01147     //TRACE("\nout of cubes set (%d,%d,%d)", pointmarker.p[0],pointmarker.p[1],pointmarker.p[2]);
01148 
01149     double baseunitshift = magnifyfactor;
01150 
01151     point.x = pointmarker.p[0] * magnifyfactor;
01152     point.y = pointmarker.p[1] * magnifyfactor;
01153     point.z = pointmarker.p[2] * magnifyfactor;
01154 
01155     farpoint.x = (pointmarker.p[0]+1) * magnifyfactor;
01156     farpoint.y = (pointmarker.p[1]+1) * magnifyfactor;
01157     farpoint.z = (pointmarker.p[2]+1) * magnifyfactor;
01158 
01159     a[0] = point.x;     a[1] = point.y;     a[2] = farpoint.z;
01160     b[0] = point.x;     b[1] = farpoint.y;  b[2] = farpoint.z;
01161     c[0] = farpoint.x;  c[1] = point.y;     c[2] = farpoint.z;
01162     d[0] = farpoint.x;  d[1] = farpoint.y;  d[2] = farpoint.z;
01163     e[0] = point.x;     e[1] = point.y;     e[2] = point.z;
01164     f[0] = point.x;     f[1] = farpoint.y;  f[2] = point.z;
01165     g[0] = farpoint.x;  g[1] = point.y;     g[2] = point.z;
01166     h[0] = farpoint.x;  h[1] = farpoint.y;  h[2] = point.z;
01167 
01168     //TRACE("\nwe have a cube at (%f,%f,%f)", a[0],a[1],a[2]);
01169     
01170     //the following is messy but helps speed the Square < and == operators
01171     //sigh
01172     tempsq.p[0][0] = a[0];tempsq.p[0][1] = a[1];tempsq.p[0][2] = a[2]; 
01173     tempsq.p[1][0] = b[0];tempsq.p[1][1] = b[1];tempsq.p[1][2] = b[2]; 
01174     tempsq.p[2][0] = d[0];tempsq.p[2][1] = d[1];tempsq.p[2][2] = d[2]; 
01175     tempsq.p[3][0] = c[0];tempsq.p[3][1] = c[1];tempsq.p[3][2] = c[2]; 
01176     squarevector.push_back(tempsq);
01177     tempsq.p[0][0] = e[0];tempsq.p[0][1] = e[1];tempsq.p[0][2] = e[2]; 
01178     tempsq.p[1][0] = f[0];tempsq.p[1][1] = f[1];tempsq.p[1][2] = f[2]; 
01179     tempsq.p[2][0] = h[0];tempsq.p[2][1] = h[1];tempsq.p[2][2] = h[2]; 
01180     tempsq.p[3][0] = g[0];tempsq.p[3][1] = g[1];tempsq.p[3][2] = g[2]; 
01181     squarevector.push_back(tempsq);
01182     tempsq.p[0][0] = c[0];tempsq.p[0][1] = c[1];tempsq.p[0][2] = c[2]; 
01183     tempsq.p[1][0] = d[0];tempsq.p[1][1] = d[1];tempsq.p[1][2] = d[2]; 
01184     tempsq.p[2][0] = h[0];tempsq.p[2][1] = h[1];tempsq.p[2][2] = h[2]; 
01185     tempsq.p[3][0] = g[0];tempsq.p[3][1] = g[1];tempsq.p[3][2] = g[2]; 
01186     squarevector.push_back(tempsq);
01187     tempsq.p[0][0] = a[0];tempsq.p[0][1] = a[1];tempsq.p[0][2] = a[2]; 
01188     tempsq.p[1][0] = b[0];tempsq.p[1][1] = b[1];tempsq.p[1][2] = b[2]; 
01189     tempsq.p[2][0] = f[0];tempsq.p[2][1] = f[1];tempsq.p[2][2] = f[2]; 
01190     tempsq.p[3][0] = e[0];tempsq.p[3][1] = e[1];tempsq.p[3][2] = e[2]; 
01191     squarevector.push_back(tempsq);
01192     tempsq.p[0][0] = d[0];tempsq.p[0][1] = d[1];tempsq.p[0][2] = d[2]; 
01193     tempsq.p[1][0] = b[0];tempsq.p[1][1] = b[1];tempsq.p[1][2] = b[2]; 
01194     tempsq.p[2][0] = f[0];tempsq.p[2][1] = f[1];tempsq.p[2][2] = f[2]; 
01195     tempsq.p[3][0] = h[0];tempsq.p[3][1] = h[1];tempsq.p[3][2] = h[2]; 
01196     squarevector.push_back(tempsq);
01197     tempsq.p[0][0] = c[0];tempsq.p[0][1] = c[1];tempsq.p[0][2] = c[2]; 
01198     tempsq.p[1][0] = a[0];tempsq.p[1][1] = a[1];tempsq.p[1][2] = a[2]; 
01199     tempsq.p[2][0] = e[0];tempsq.p[2][1] = e[1];tempsq.p[2][2] = e[2]; 
01200     tempsq.p[3][0] = g[0];tempsq.p[3][1] = g[1];tempsq.p[3][2] = g[2]; 
01201     squarevector.push_back(tempsq);
01202 
01203     it ++;
01204   }
01205     
01206   return;
01207 }
01208 
01209 void extract_block_node(OctreeNode *node, struct cubic_d *worldsize, 
01210                                                 std::vector<Square> &squarevector, bool firstlevel, int colour)
01211 {
01212   struct cubic_d sub_c;
01213   double x_mid, y_mid, z_mid;
01214   
01215   double a[3],b[3],c[3],d[3],e[3],f[3],g[3],h[3];
01216   Square tempsq;
01217   
01218   if ((node->color==colour) || ((firstlevel==true) && (node->color==WHITE)) )
01219   {
01220     //    TRACE ("\nBLACK(%f,%f,%f)(%f,%f,%f)"
01221     //      ,worldsize->x0,worldsize->y0,worldsize->z0,worldsize->x1,worldsize->y1,worldsize->z1);
01222     a[0] = worldsize->x0; a[1] = worldsize->y0; a[2] = worldsize->z1;
01223     b[0] = worldsize->x0; b[1] = worldsize->y1; b[2] = worldsize->z1;
01224     c[0] = worldsize->x1; c[1] = worldsize->y0; c[2] = worldsize->z1;
01225     d[0] = worldsize->x1; d[1] = worldsize->y1; d[2] = worldsize->z1;
01226     e[0] = worldsize->x0; e[1] = worldsize->y0; e[2] = worldsize->z0;
01227     f[0] = worldsize->x0; f[1] = worldsize->y1; f[2] = worldsize->z0;
01228     g[0] = worldsize->x1; g[1] = worldsize->y0; g[2] = worldsize->z0;
01229     h[0] = worldsize->x1; h[1] = worldsize->y1; h[2] = worldsize->z0;
01230     
01231     
01232     //the following is messy but helps speed the Square < and == operators
01233     //sigh
01234     tempsq.p[0][0] = a[0];tempsq.p[0][1] = a[1];tempsq.p[0][2] = a[2]; 
01235     tempsq.p[1][0] = b[0];tempsq.p[1][1] = b[1];tempsq.p[1][2] = b[2]; 
01236     tempsq.p[2][0] = d[0];tempsq.p[2][1] = d[1];tempsq.p[2][2] = d[2]; 
01237     tempsq.p[3][0] = c[0];tempsq.p[3][1] = c[1];tempsq.p[3][2] = c[2]; 
01238     squarevector.push_back(tempsq);
01239     tempsq.p[0][0] = e[0];tempsq.p[0][1] = e[1];tempsq.p[0][2] = e[2]; 
01240     tempsq.p[1][0] = f[0];tempsq.p[1][1] = f[1];tempsq.p[1][2] = f[2]; 
01241     tempsq.p[2][0] = h[0];tempsq.p[2][1] = h[1];tempsq.p[2][2] = h[2]; 
01242     tempsq.p[3][0] = g[0];tempsq.p[3][1] = g[1];tempsq.p[3][2] = g[2]; 
01243     squarevector.push_back(tempsq);
01244     tempsq.p[0][0] = c[0];tempsq.p[0][1] = c[1];tempsq.p[0][2] = c[2]; 
01245     tempsq.p[1][0] = d[0];tempsq.p[1][1] = d[1];tempsq.p[1][2] = d[2]; 
01246     tempsq.p[2][0] = h[0];tempsq.p[2][1] = h[1];tempsq.p[2][2] = h[2]; 
01247     tempsq.p[3][0] = g[0];tempsq.p[3][1] = g[1];tempsq.p[3][2] = g[2]; 
01248     squarevector.push_back(tempsq);
01249     tempsq.p[0][0] = a[0];tempsq.p[0][1] = a[1];tempsq.p[0][2] = a[2]; 
01250     tempsq.p[1][0] = b[0];tempsq.p[1][1] = b[1];tempsq.p[1][2] = b[2]; 
01251     tempsq.p[2][0] = f[0];tempsq.p[2][1] = f[1];tempsq.p[2][2] = f[2]; 
01252     tempsq.p[3][0] = e[0];tempsq.p[3][1] = e[1];tempsq.p[3][2] = e[2]; 
01253     squarevector.push_back(tempsq);
01254     tempsq.p[0][0] = d[0];tempsq.p[0][1] = d[1];tempsq.p[0][2] = d[2]; 
01255     tempsq.p[1][0] = b[0];tempsq.p[1][1] = b[1];tempsq.p[1][2] = b[2]; 
01256     tempsq.p[2][0] = f[0];tempsq.p[2][1] = f[1];tempsq.p[2][2] = f[2]; 
01257     tempsq.p[3][0] = h[0];tempsq.p[3][1] = h[1];tempsq.p[3][2] = h[2]; 
01258     squarevector.push_back(tempsq);
01259     tempsq.p[0][0] = c[0];tempsq.p[0][1] = c[1];tempsq.p[0][2] = c[2]; 
01260     tempsq.p[1][0] = a[0];tempsq.p[1][1] = a[1];tempsq.p[1][2] = a[2]; 
01261     tempsq.p[2][0] = e[0];tempsq.p[2][1] = e[1];tempsq.p[2][2] = e[2]; 
01262     tempsq.p[3][0] = g[0];tempsq.p[3][1] = g[1];tempsq.p[3][2] = g[2]; 
01263     squarevector.push_back(tempsq);
01264     
01265     return;
01266   }
01267   
01268   firstlevel = false;
01269   //now we know brick can be subdivided.
01270   if (node->color==GRAY)
01271   {
01272     
01273     x_mid = (worldsize->x1 + worldsize->x0)/2.0;
01274     y_mid = (worldsize->y1 + worldsize->y0)/2.0;
01275     z_mid = (worldsize->z1 + worldsize->z0)/2.0;
01276     
01277     sub_c.x0= worldsize->x0;
01278     sub_c.y0= worldsize->y0;
01279     sub_c.z0= worldsize->z0;
01280     sub_c.x1= x_mid;
01281     sub_c.y1= y_mid;
01282     sub_c.z1= z_mid; 
01283     extract_block_node(node->son->pointer[0], &sub_c, squarevector, firstlevel, colour);
01284     
01285     sub_c.x0= worldsize->x0;
01286     sub_c.y0= worldsize->y0;
01287     sub_c.z0= z_mid;
01288     sub_c.x1= x_mid;
01289     sub_c.y1= y_mid;
01290     sub_c.z1= worldsize->z1;
01291     extract_block_node(node->son->pointer[1], &sub_c, squarevector, firstlevel, colour);
01292     
01293     sub_c.x0= worldsize->x0;
01294     sub_c.y0= y_mid;
01295     sub_c.z0= worldsize->z0;
01296     sub_c.x1= x_mid;
01297     sub_c.y1= worldsize->y1;
01298     sub_c.z1= z_mid;
01299     extract_block_node(node->son->pointer[2], &sub_c, squarevector, firstlevel, colour);
01300     
01301     sub_c.x0= worldsize->x0;
01302     sub_c.y0= y_mid;
01303     sub_c.z0= z_mid;
01304     sub_c.x1= x_mid;
01305     sub_c.y1= worldsize->y1;
01306     sub_c.z1= worldsize->z1;
01307     extract_block_node(node->son->pointer[3], &sub_c, squarevector, firstlevel, colour);
01308     
01309     sub_c.x0= x_mid;
01310     sub_c.y0= worldsize->y0;
01311     sub_c.z0= worldsize->z0;
01312     sub_c.x1= worldsize->x1;
01313     sub_c.y1= y_mid;
01314     sub_c.z1= z_mid;
01315     extract_block_node(node->son->pointer[4], &sub_c, squarevector, firstlevel, colour);
01316     
01317     sub_c.x0= x_mid;
01318     sub_c.y0= worldsize->y0;
01319     sub_c.z0= z_mid;
01320     sub_c.x1= worldsize->x1;
01321     sub_c.y1= y_mid;
01322     sub_c.z1= worldsize->z1;
01323     extract_block_node(node->son->pointer[5], &sub_c, squarevector, firstlevel, colour);
01324     
01325     sub_c.x0= x_mid;
01326     sub_c.y0= y_mid;
01327     sub_c.z0= worldsize->z0;
01328     sub_c.x1= worldsize->x1;
01329     sub_c.y1= worldsize->y1;
01330     sub_c.z1= z_mid;
01331     extract_block_node(node->son->pointer[6], &sub_c, squarevector, firstlevel, colour);
01332     
01333     sub_c.x0= x_mid;
01334     sub_c.y0= y_mid;
01335     sub_c.z0= z_mid;
01336     sub_c.x1= worldsize->x1;
01337     sub_c.y1= worldsize->y1;
01338     sub_c.z1= worldsize->z1;
01339     extract_block_node(node->son->pointer[7], &sub_c, squarevector, firstlevel, colour);
01340   }
01341   
01342   return;
01343 }
01344 
01345 bool operator< (const Square& p1, const Square& p2)
01346 {
01347   return ( memcmp( p1.p, p2.p, 12*sizeof(double)) < 0);
01348 }
01349 
01350 bool operator== (const Square& p1, const Square& p2)
01351 {
01352   return ( memcmp( p1.p, p2.p, 12*sizeof(double)) == 0);
01353 }
01354 
01355 void calc_cube_facets(std::vector<Square> &squarevector, GL_Mesh &mesh)
01356 {
01357   
01358   Vector4 tempvector;
01359   tempvector[3] = 1;
01360   
01361   //construct cubes out of 12 triangles using 8 given vertices
01362   std::vector<Square>::iterator iter;
01363   std::vector<Square>::iterator dup;
01364   
01365   mesh.GetVertexes().clear();
01366   mesh.GetFacets().clear();
01367   
01368   std::sort (squarevector.begin(),squarevector.end());
01369   
01370   for (iter = squarevector.begin(); iter != squarevector.end() ; iter++)
01371   {
01372     if ((*iter == *(iter+1)) && (iter != squarevector.end()))
01373     {
01374       dup = iter;
01375       do
01376       {
01377         iter++;
01378       } while (*(iter+1) == *dup);
01379     } else
01380     {
01381       //cout << "single found" << *iter << endl;
01382       
01383       //these should hopefully be all the non duplicate triangles only
01384       tempvector[0] = (*iter).p[0][0];
01385       tempvector[1] = (*iter).p[0][1];
01386       tempvector[2] = (*iter).p[0][2];
01387       mesh.AddVertex(tempvector);
01388       tempvector[0] = (*iter).p[1][0];
01389       tempvector[1] = (*iter).p[1][1];
01390       tempvector[2] = (*iter).p[1][2];
01391       mesh.AddVertex(tempvector);
01392       tempvector[0] = (*iter).p[2][0];
01393       tempvector[1] = (*iter).p[2][1];
01394       tempvector[2] = (*iter).p[2][2];
01395       mesh.AddVertex(tempvector);
01396       tempvector[0] = (*iter).p[3][0];
01397       tempvector[1] = (*iter).p[3][1];
01398       tempvector[2] = (*iter).p[3][2];
01399       mesh.AddVertex(tempvector);
01400     }
01401   }
01402   
01403   //TRACE ("\nSize of squarevector: %d",squarevector.size());
01404   //don't need this anymore;
01405   squarevector.clear();
01406   
01407   Facet facet;
01408   facet.vertexNumbers.reserve(3);
01409   facet.direction = 1; // 1 == clockwise?
01410   //include all the triangles in the new mesh
01411   
01412   int meshsize = mesh.GetVertexes().size();
01413   
01414   for (int i = 0; i < meshsize; i=i+4)
01415   {
01416     facet.vertexNumbers.clear();
01417     facet.vertexNumbers.push_back(i);
01418     facet.vertexNumbers.push_back(i+1);
01419     facet.vertexNumbers.push_back(i+2);
01420     mesh.AddFacet(facet);
01421     
01422     facet.vertexNumbers.clear();
01423     facet.vertexNumbers.push_back(i);
01424     facet.vertexNumbers.push_back(i+2);
01425     facet.vertexNumbers.push_back(i+3);
01426     mesh.AddFacet(facet);
01427     //assert (facet.vertexNumbers.size() == 3);
01428   }
01429   
01430 }
01431 

Generated on Sat Apr 1 21:30:37 2006 for Motion Planning Kernel by  doxygen 1.4.6-NO