Main Page   Class Hierarchy   Alphabetical List   Data Structures   File List   Data Fields   Globals   Related Pages  

r_octree.cpp

Go to the documentation of this file.
00001 // OMICRON ENGINE HEADER FILE
00002 //
00003 // --------------------------------------------------------------------------
00004 // Copyright (C) 2001-2002 by Bjoern Paetzel <kolrabi@gmx.de>
00005 //
00006 // This file is part of the Omicron Engine.
00007 //
00008 // The Omicron Engine is free software; you can redistribute it and/or modify
00009 // it under the terms of the  GNU General Public License  as published by the
00010 // Free Software Foundation;  either version  2  of the License,  or (at your
00011 // option) any later version.
00012 //
00013 // The Omicron Engine  is distributed in the hope that it will be useful, but
00014 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00015 // or  FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License
00016 // for more details.
00017 //
00018 // You should have  received a copy of the  GNU General Public License  along
00019 // with The Omicron Engine;  if not,  write to the  Free Software Foundation,
00020 // Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
00021 //
00022 // --------------------------------------------------------------------------
00023 // Last modified:       $Date: 2002/12/07 19:02:04 $
00024 // By           :       $Author: kolrabi $
00025 // $Id: r_octree.cpp,v 1.1.1.1 2002/12/07 19:02:04 kolrabi Exp $ 
00026 
00027 /*
00028 
00029   $Log: r_octree.cpp,v $
00030   Revision 1.1.1.1  2002/12/07 19:02:04  kolrabi
00031   initial release
00032 
00033 
00034 */
00035 
00040 #include            "omicron/internal.h"
00041 #include            "omicron/list.h"
00042 #include            "omicron/octree.h"
00043 #include            "omicron/input.h"
00044 #include            "omicron/array.h"
00045 #include            "omicron/render.h"
00046 
00047 #define             BIGPOLY             100000
00048 
00049 template <class T>
00050 octree_c<T>::octree_c() 
00051 { 
00052     for (ulong i=0; i<8; i++)
00053         root.subnodes[i] = NULL;
00054     
00055     root.data = NULL;
00056 } 
00057 
00058 template <class T>
00059 octree_c<T>::~octree_c() 
00060 {
00061     AssertThis;
00062     
00063     for (ulong i=0; i<8; i++)
00064         removenode(root.subnodes[i]);
00065 } 
00066 
00067 template <class T>
00068 octree_c<T>::node_t<T> *octree_c<T>::create_node(octree_c::node_t<T> *node, ulong num)
00069 {
00070     AssertThisV;
00071     
00072     ulong i;
00073     if (!node->subnodes[num])
00074     {
00075         node->subnodes[num] = new octree_c::node_t<T>;
00076         
00077         vec3_t size;
00078         
00079         vector_subtract(node->max, node->min, size);
00080         vector_scale(size, 0.5, size);
00081         
00082         vector_copy(node->min, node->subnodes[num]->min);
00083         
00084         for (i=0; i<3; i++)
00085             if (num && (1<<i))
00086                 node->subnodes[num]->min[i]+=size[i];
00087             
00088             for (i=0; i<8; i++)
00089                 node->subnodes[num]->subnodes[i] = NULL;
00090             
00091             node->subnodes[num]->data = NULL;
00092             
00093             vector_add(node->subnodes[num]->min, size, node->subnodes[num]->max);
00094             
00095             for (i=0; i<8; i++)
00096             {
00097                 node->subnodes[num]->pts[i][0] = 
00098                     (i&1)?node->subnodes[num]->max[0]:node->subnodes[num]->min[0];
00099                 
00100                 node->subnodes[num]->pts[i][1] = 
00101                     (i&2)?node->subnodes[num]->max[1]:node->subnodes[num]->min[1];
00102                 
00103                 node->subnodes[num]->pts[i][2] = 
00104                     (i&4)?node->subnodes[num]->max[2]:node->subnodes[num]->min[2];
00105             }
00106     }
00107     
00108     return node->subnodes[num];
00109 }
00110 
00111 template <class T>
00112 slong octree_c<T>::get_subnode_num_vec(octree_c::node_t<T> *node, vec3_t p)
00113 {
00114     AssertThisV;
00115     
00116     ulong  num = 0;
00117     vec3_t center;
00118     
00119     vector_add(node->max, node->min, center);
00120     vector_scale(center, 0.5, center);
00121     
00122     for (ulong i=0; i<3; i++)
00123     {
00124         if (p[i]>=center[i])
00125             num |= 1<<i;
00126     }
00127     
00128     return num;
00129 }
00130 
00131 template <class T>
00132 slong octree_c<T>::get_subnode_num(octree_c::node_t<T> *node, vec3_t mn, vec3_t mx)
00133 {
00134     AssertThisV;
00135     
00136     ulong    num, lnum, i;
00137     vec3_t   pts[8];
00138     
00139     for (i=0; i<8; i++)
00140     {
00141         pts[i][0] = (i&1)?mx[0]:mn[0];
00142         pts[i][1] = (i&2)?mx[1]:mn[1];
00143         pts[i][2] = (i&4)?mx[2]:mn[2];
00144     }
00145     
00146     lnum = num = getsubnodenumvec(node, pts[0]);
00147     
00148     for (i=1; i<8; i++)
00149     {
00150         num = getsubnodenumvec(node, pts[i]);
00151         if (lnum != num)
00152             return -1;
00153     }
00154     
00155     return num;
00156 }
00157 
00158 template <class T>
00159 void octree_c<T>::add_to_subnode(octree_c::node_t<T> *node, T *d, vec3_t mn, vec3_t mx)
00160 {
00161     AssertThis;
00162     
00163     ulong num;
00164     
00165     num = getsubnodenum(node, mn, mx);
00166     
00167     if (num == -1)
00168     {
00169         if (!node->data)
00170             node->data = new list_c<T>;
00171         
00172         node->data->add_first(d);
00173     }
00174     else
00175     {
00176         createnode(node, num);
00177         addtosubnode(node->subnodes[num], d, mn, mx);
00178     }
00179 }
00180 
00181 template <class T>
00182 void octree_c<T>::add(T *d, vec3_t mn, vec3_t mx)
00183 {
00184     AssertThis;
00185     
00186     add_to_subnode(&root, d, mn, mx);
00187 }
00188 
00189 template <class T>
00190 void octree_c<T>::update_view()
00191 {
00192     AssertThis;
00193     
00194     /*viewplanes[0].d = vector_dot(gv.viewPos, gv.viewDir);
00195     vector_copy(gv.viewDir, viewplanes[0].n);*/
00196     
00197     vec3_t     pts[5];
00198     vec3_t     f,r,u;
00199     ulong       i;
00200     float       rpf;
00201     
00202     for (i=0; i<5; i++)
00203         vector_copy(gv.renderer->get_viewpos(), pts[i]);
00204     
00205     rpf = ftan(gv.renderer->get_fov()/2)*2500;
00206     
00207     vector_scale(gv.renderer->get_viewdir(),   5000, f);
00208     vector_scale(gv.renderer->get_viewright(), rpf,  r);
00209     vector_scale(gv.renderer->get_viewup2(),   rpf,  u);
00210     
00211     for (i=1; i<5; i++)
00212         vector_add(pts[i], f, pts[i]);
00213     
00214     vector_ma(pts[1], -1, r, pts[1]);
00215     vector_ma(pts[1], -1, u, pts[1]);
00216     
00217     vector_ma(pts[2],  1, r, pts[2]);
00218     vector_ma(pts[2], -1, u, pts[2]);
00219     
00220     vector_ma(pts[3],  1, r, pts[3]);
00221     vector_ma(pts[3],  1, u, pts[3]);
00222     
00223     vector_ma(pts[4], -1, r, pts[4]);
00224     vector_ma(pts[4],  1, u, pts[4]);
00225     
00226     vector_set(viewmin,  BIGPOLY,  BIGPOLY,  BIGPOLY);
00227     vector_set(viewmax, -BIGPOLY, -BIGPOLY, -BIGPOLY);
00228     
00229     for (i=0; i<5; i++)
00230         for (ulong j=0; j<3; j++)
00231         {
00232             if (pts[i][j]>viewmax[j])
00233                 viewmax[j] = pts[i][j];
00234             if (pts[i][j]<viewmin[j])
00235                 viewmin[j] = pts[i][j];
00236         }
00237 }
00238 
00239 // 0 not
00240 // 1 partially
00241 // 2 complete
00242 template <class T>
00243 slong octree_c<T>::get_visibility(octree_c::node_t<T> *node)
00244 {
00245     AssertThisV;
00246     
00247     ulong       visible;
00248     ulong       i, j, inside;
00249     
00250     if (node == &root)
00251         return 1;
00252     
00253     if ((gv.renderer->get_viewpos()[0]>node->min[0] && 
00254         gv.renderer->get_viewpos()[0]<node->max[0]) && 
00255         (gv.renderer->get_viewpos()[1]>node->min[1] && 
00256         gv.renderer->get_viewpos()[1]<node->max[1]) &&
00257         (gv.renderer->get_viewpos()[2]>node->min[2] && 
00258         gv.renderer->get_viewpos()[2]<node->max[2]))
00259     {
00260         return 1;
00261     }
00262     
00263     visible = 0;
00264     
00265     inside = 1;
00266     for (i=0; i<3; i++)
00267     {
00268         if (node->pts[0][i]>viewmax[i] && node->pts[0][i]<viewmin[i])
00269             inside = 0;
00270     }
00271     
00272     for (j=0; j<8; j++)
00273         for (i=0; i<3; i++)
00274         {
00275             if (node->pts[j][i]>viewmax[i] && node->pts[j][i]<viewmin[i])
00276             {
00277                 if (inside)
00278                     return 1;
00279             }
00280             else
00281             {
00282                 if (!inside)
00283                     return 1;
00284             }
00285         }
00286         
00287         if (inside)
00288             return 2;
00289         
00290         return 0;
00291 }
00292 
00293 template <class T>
00294 void octree_c<T>::add_complete_node_to_array(octree_c::node_t<T> *node, array_c<T> &list)
00295 {
00296     AssertThis;
00297     
00298     ulong i;
00299     
00300     if (!node)
00301         return;
00302     
00303     if (node->data)
00304     {
00305         ulong c = node->data->getcount();
00306         T *data = node->data->getfirst();
00307         
00308         while (data)
00309         {
00310             list.add(data);
00311             data = node->data->getnext();
00312         }
00313     }
00314     
00315     for (i=0; i<8; i++)
00316         addcompletenodetolist(node->subnodes[i], list);
00317 }
00318 
00319 template <class T>
00320 void octree_c<T>::add_node_to_array(octree_c::node_t<T> *node, array_c<T> &list)
00321 {
00322     AssertThis;
00323     
00324     if (!node)
00325         return;
00326     
00327     ulong vis = getvisibility(node);
00328     
00329     if (!vis)
00330         return;
00331     
00332     if (vis==1)
00333     {
00334         if (node->data)
00335         {
00336             T *data = node->data->getfirst();
00337             
00338             while (data)
00339             {
00340                 list.add(data);
00341                 data = node->data->getnext();
00342             }
00343         }
00344         
00345         for (ulong i=0; i<8; i++)
00346             addnodetolist(node->subnodes[i], list);
00347         
00348         return;
00349     }
00350     addcompletenodetolist(node, list);
00351 }
00352 
00353 template <class T>
00354 void octree_c<T>::get_visible(array_c<T> &list)
00355 {
00356     AssertThis;
00357     
00358     list.clear();
00359     addnodetolist(&root, list);
00360 }
00361 
00362 template <class T>
00363 void octree_c<T>::remove_node(octree_c::node_t<T> *node)
00364 {
00365     AssertThis;
00366     
00367     if (!node)
00368         return;
00369     
00370     for (ulong i=0; i<8; i++)
00371         removenode(node->subnodes[i]);
00372     
00373     SafeDelete(node->data);
00374     SafeDelete(node);
00375 }
00376 

Generated on Wed Dec 18 15:48:47 2002 for omicron engine by doxygen1.2.18