![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
00001 /* 00002 Copyright 2005-2010 Intel Corporation. All Rights Reserved. 00003 00004 This file is part of Threading Building Blocks. 00005 00006 Threading Building Blocks is free software; you can redistribute it 00007 and/or modify it under the terms of the GNU General Public License 00008 version 2 as published by the Free Software Foundation. 00009 00010 Threading Building Blocks is distributed in the hope that it will be 00011 useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00012 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with Threading Building Blocks; if not, write to the Free Software 00017 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 00019 As a special exception, you may use this file as part of a free software 00020 library without restriction. Specifically, if other files instantiate 00021 templates or use macros or inline functions from this file, or you compile 00022 this file and link it with other files to produce an executable, this 00023 file does not by itself cause the resulting executable to be covered by 00024 the GNU General Public License. This exception does not however 00025 invalidate any other reasons why the executable file might be covered by 00026 the GNU General Public License. 00027 */ 00028 00029 /* 00030 The original source for this example is 00031 Copyright (c) 1994-2008 John E. Stone 00032 All rights reserved. 00033 00034 Redistribution and use in source and binary forms, with or without 00035 modification, are permitted provided that the following conditions 00036 are met: 00037 1. Redistributions of source code must retain the above copyright 00038 notice, this list of conditions and the following disclaimer. 00039 2. Redistributions in binary form must reproduce the above copyright 00040 notice, this list of conditions and the following disclaimer in the 00041 documentation and/or other materials provided with the distribution. 00042 3. The name of the author may not be used to endorse or promote products 00043 derived from this software without specific prior written permission. 00044 00045 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 00046 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00047 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00048 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00049 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00050 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00051 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00052 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00053 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00054 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00055 SUCH DAMAGE. 00056 */ 00057 00058 /* 00059 * objbound.c - This file contains the functions to find bounding boxes 00060 * for the various primitives 00061 * 00062 * $Id: objbound.cpp,v 1.2 2007-02-22 17:54:15 dpoulsen Exp $ 00063 */ 00064 00065 #include "machine.h" 00066 #include "types.h" 00067 #include "macros.h" 00068 #include "bndbox.h" 00069 00070 #define OBJBOUND_PRIVATE 00071 #include "objbound.h" 00072 00073 static void globalbound(object ** rootlist, vector * gmin, vector * gmax) { 00074 vector min, max; 00075 object * cur; 00076 00077 if (*rootlist == NULL) /* don't bound non-existant objects */ 00078 return; 00079 00080 gmin->x = FHUGE; gmin->y = FHUGE; gmin->z = FHUGE; 00081 gmax->x = -FHUGE; gmax->y = -FHUGE; gmax->z = -FHUGE; 00082 00083 cur=*rootlist; 00084 while (cur != NULL) { /* Go! */ 00085 min.x = -FHUGE; min.y = -FHUGE; min.z = -FHUGE; 00086 max.x = FHUGE; max.y = FHUGE; max.z = FHUGE; 00087 00088 cur->methods->bbox((void *) cur, &min, &max); 00089 00090 gmin->x = MYMIN( gmin->x , min.x); 00091 gmin->y = MYMIN( gmin->y , min.y); 00092 gmin->z = MYMIN( gmin->z , min.z); 00093 00094 gmax->x = MYMAX( gmax->x , max.x); 00095 gmax->y = MYMAX( gmax->y , max.y); 00096 gmax->z = MYMAX( gmax->z , max.z); 00097 00098 cur=(object *)cur->nextobj; 00099 } 00100 } 00101 00102 static int objinside(object * obj, vector * min, vector * max) { 00103 vector omin, omax; 00104 00105 if (obj == NULL) /* non-existant object, shouldn't get here */ 00106 return 0; 00107 00108 if (obj->methods->bbox((void *) obj, &omin, &omax)) { 00109 if ((min->x <= omin.x) && (min->y <= omin.y) && (min->z <= omin.z) && 00110 (max->x >= omax.x) && (max->y >= omax.y) && (max->z >= omax.z)) { 00111 return 1; 00112 } 00113 } 00114 return 0; 00115 } 00116 00117 static int countobj(object * root) { 00118 object * cur; /* counts the number of objects on a list */ 00119 int numobj; 00120 00121 numobj=0; 00122 cur=root; 00123 00124 while (cur != NULL) { 00125 cur=(object *)cur->nextobj; 00126 numobj++; 00127 } 00128 return numobj; 00129 } 00130 00131 static void movenextobj(object * thisobj, object ** root) { 00132 object * cur, * tmp; 00133 00134 /* move the object after thisobj to the front of the object list */ 00135 /* headed by root */ 00136 if (thisobj != NULL) { 00137 if (thisobj->nextobj != NULL) { 00138 cur=(object *)thisobj->nextobj; /* the object to be moved */ 00139 thisobj->nextobj = cur->nextobj; /* link around the moved obj */ 00140 tmp=*root; /* store the root node */ 00141 cur->nextobj=tmp; /* attach root to cur */ 00142 *root=cur; /* make cur, the new root */ 00143 } 00144 } 00145 } 00146 00147 static void octreespace(object ** rootlist, int maxoctnodes) { 00148 object * cur; 00149 vector gmin, gmax, gctr; 00150 vector cmin1, cmin2, cmin3, cmin4, cmin5, cmin6, cmin7, cmin8; 00151 vector cmax1, cmax2, cmax3, cmax4, cmax5, cmax6, cmax7, cmax8; 00152 bndbox * box1, * box2, * box3, * box4; 00153 bndbox * box5, * box6, * box7, * box8; 00154 int skipobj; 00155 00156 if (*rootlist == NULL) /* don't subdivide non-existant data */ 00157 return; 00158 00159 skipobj=0; 00160 globalbound(rootlist, &gmin, &gmax); /* find global min and max */ 00161 00162 gctr.x = ((gmax.x - gmin.x) / 2.0) + gmin.x; 00163 gctr.y = ((gmax.y - gmin.y) / 2.0) + gmin.y; 00164 gctr.z = ((gmax.z - gmin.z) / 2.0) + gmin.z; 00165 00166 cmin1=gmin; 00167 cmax1=gctr; 00168 box1 = newbndbox(cmin1, cmax1); 00169 00170 cmin2=gmin; 00171 cmin2.x=gctr.x; 00172 cmax2=gmax; 00173 cmax2.y=gctr.y; 00174 cmax2.z=gctr.z; 00175 box2 = newbndbox(cmin2, cmax2); 00176 00177 cmin3=gmin; 00178 cmin3.y=gctr.y; 00179 cmax3=gmax; 00180 cmax3.x=gctr.x; 00181 cmax3.z=gctr.z; 00182 box3 = newbndbox(cmin3, cmax3); 00183 00184 cmin4=gmin; 00185 cmin4.x=gctr.x; 00186 cmin4.y=gctr.y; 00187 cmax4=gmax; 00188 cmax4.z=gctr.z; 00189 box4 = newbndbox(cmin4, cmax4); 00190 00191 cmin5=gmin; 00192 cmin5.z=gctr.z; 00193 cmax5=gctr; 00194 cmax5.z=gmax.z; 00195 box5 = newbndbox(cmin5, cmax5); 00196 00197 cmin6=gctr; 00198 cmin6.y=gmin.y; 00199 cmax6=gmax; 00200 cmax6.y=gctr.y; 00201 box6 = newbndbox(cmin6, cmax6); 00202 00203 cmin7=gctr; 00204 cmin7.x=gmin.x; 00205 cmax7=gctr; 00206 cmax7.y=gmax.y; 00207 cmax7.z=gmax.z; 00208 box7 = newbndbox(cmin7, cmax7); 00209 00210 cmin8=gctr; 00211 cmax8=gmax; 00212 box8 = newbndbox(cmin8, cmax8); 00213 00214 cur = *rootlist; 00215 while (cur != NULL) { 00216 if (objinside((object *)cur->nextobj, &cmin1, &cmax1)) { 00217 movenextobj(cur, &box1->objlist); 00218 } 00219 else if (objinside((object *)cur->nextobj, &cmin2, &cmax2)) { 00220 movenextobj(cur, &box2->objlist); 00221 } 00222 else if (objinside((object *)cur->nextobj, &cmin3, &cmax3)) { 00223 movenextobj(cur, &box3->objlist); 00224 } 00225 else if (objinside((object *)cur->nextobj, &cmin4, &cmax4)) { 00226 movenextobj(cur, &box4->objlist); 00227 } 00228 else if (objinside((object *)cur->nextobj, &cmin5, &cmax5)) { 00229 movenextobj(cur, &box5->objlist); 00230 } 00231 else if (objinside((object *)cur->nextobj, &cmin6, &cmax6)) { 00232 movenextobj(cur, &box6->objlist); 00233 } 00234 else if (objinside((object *)cur->nextobj, &cmin7, &cmax7)) { 00235 movenextobj(cur, &box7->objlist); 00236 } 00237 else if (objinside((object *)cur->nextobj, &cmin8, &cmax8)) { 00238 movenextobj(cur, &box8->objlist); 00239 } 00240 else { 00241 skipobj++; 00242 cur=(object *)cur->nextobj; 00243 } 00244 } 00245 00246 /* new scope, for redefinition of cur, and old */ 00247 { bndbox * cur, * old; 00248 old=box1; 00249 cur=box2; 00250 if (countobj(cur->objlist) > 0) { 00251 old->nextobj=cur; 00252 globalbound(&cur->objlist, &cur->min, &cur->max); 00253 old=cur; 00254 } 00255 cur=box3; 00256 if (countobj(cur->objlist) > 0) { 00257 old->nextobj=cur; 00258 globalbound(&cur->objlist, &cur->min, &cur->max); 00259 old=cur; 00260 } 00261 cur=box4; 00262 if (countobj(cur->objlist) > 0) { 00263 old->nextobj=cur; 00264 globalbound(&cur->objlist, &cur->min, &cur->max); 00265 old=cur; 00266 } 00267 cur=box5; 00268 if (countobj(cur->objlist) > 0) { 00269 old->nextobj=cur; 00270 globalbound(&cur->objlist, &cur->min, &cur->max); 00271 old=cur; 00272 } 00273 cur=box6; 00274 if (countobj(cur->objlist) > 0) { 00275 old->nextobj=cur; 00276 globalbound(&cur->objlist, &cur->min, &cur->max); 00277 old=cur; 00278 } 00279 cur=box7; 00280 if (countobj(cur->objlist) > 0) { 00281 old->nextobj=cur; 00282 globalbound(&cur->objlist, &cur->min, &cur->max); 00283 old=cur; 00284 } 00285 cur=box8; 00286 if (countobj(cur->objlist) > 0) { 00287 old->nextobj=cur; 00288 globalbound(&cur->objlist, &cur->min, &cur->max); 00289 old=cur; 00290 } 00291 00292 old->nextobj=*rootlist; 00293 00294 if (countobj(box1->objlist) > 0) { 00295 globalbound(&box1->objlist, &box1->min, &box1->max); 00296 *rootlist=(object *) box1; 00297 } 00298 else { 00299 *rootlist=(object *) box1->nextobj; 00300 } 00301 00302 } /**** end of special cur and old scope */ 00303 00304 if (countobj(box1->objlist) > maxoctnodes) { 00305 octreespace(&box1->objlist, maxoctnodes); 00306 } 00307 if (countobj(box2->objlist) > maxoctnodes) { 00308 octreespace(&box2->objlist, maxoctnodes); 00309 } 00310 if (countobj(box3->objlist) > maxoctnodes) { 00311 octreespace(&box3->objlist, maxoctnodes); 00312 } 00313 if (countobj(box4->objlist) > maxoctnodes) { 00314 octreespace(&box4->objlist, maxoctnodes); 00315 } 00316 if (countobj(box5->objlist) > maxoctnodes) { 00317 octreespace(&box5->objlist, maxoctnodes); 00318 } 00319 if (countobj(box6->objlist) > maxoctnodes) { 00320 octreespace(&box6->objlist, maxoctnodes); 00321 } 00322 if (countobj(box7->objlist) > maxoctnodes) { 00323 octreespace(&box7->objlist, maxoctnodes); 00324 } 00325 if (countobj(box8->objlist) > maxoctnodes) { 00326 octreespace(&box8->objlist, maxoctnodes); 00327 } 00328 } 00329 00330 void dividespace(int maxoctnodes, object **toplist) { 00331 bndbox * gbox; 00332 vector gmin, gmax; 00333 00334 if (countobj(*toplist) > maxoctnodes) { 00335 globalbound(toplist, &gmin, &gmax); 00336 00337 octreespace(toplist, maxoctnodes); 00338 00339 gbox = newbndbox(gmin, gmax); 00340 gbox->objlist = NULL; 00341 gbox->tex = NULL; 00342 gbox->nextobj=NULL; 00343 gbox->objlist=*toplist; 00344 *toplist=(object *) gbox; 00345 } 00346 }
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.