1*d86ed7fbStbbdev /* 2*d86ed7fbStbbdev Copyright (c) 2005-2020 Intel Corporation 3*d86ed7fbStbbdev 4*d86ed7fbStbbdev Licensed under the Apache License, Version 2.0 (the "License"); 5*d86ed7fbStbbdev you may not use this file except in compliance with the License. 6*d86ed7fbStbbdev You may obtain a copy of the License at 7*d86ed7fbStbbdev 8*d86ed7fbStbbdev http://www.apache.org/licenses/LICENSE-2.0 9*d86ed7fbStbbdev 10*d86ed7fbStbbdev Unless required by applicable law or agreed to in writing, software 11*d86ed7fbStbbdev distributed under the License is distributed on an "AS IS" BASIS, 12*d86ed7fbStbbdev WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*d86ed7fbStbbdev See the License for the specific language governing permissions and 14*d86ed7fbStbbdev limitations under the License. 15*d86ed7fbStbbdev */ 16*d86ed7fbStbbdev 17*d86ed7fbStbbdev /* 18*d86ed7fbStbbdev The original source for this example is 19*d86ed7fbStbbdev Copyright (c) 1994-2008 John E. Stone 20*d86ed7fbStbbdev All rights reserved. 21*d86ed7fbStbbdev 22*d86ed7fbStbbdev Redistribution and use in source and binary forms, with or without 23*d86ed7fbStbbdev modification, are permitted provided that the following conditions 24*d86ed7fbStbbdev are met: 25*d86ed7fbStbbdev 1. Redistributions of source code must retain the above copyright 26*d86ed7fbStbbdev notice, this list of conditions and the following disclaimer. 27*d86ed7fbStbbdev 2. Redistributions in binary form must reproduce the above copyright 28*d86ed7fbStbbdev notice, this list of conditions and the following disclaimer in the 29*d86ed7fbStbbdev documentation and/or other materials provided with the distribution. 30*d86ed7fbStbbdev 3. The name of the author may not be used to endorse or promote products 31*d86ed7fbStbbdev derived from this software without specific prior written permission. 32*d86ed7fbStbbdev 33*d86ed7fbStbbdev THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 34*d86ed7fbStbbdev OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 35*d86ed7fbStbbdev WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 36*d86ed7fbStbbdev ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 37*d86ed7fbStbbdev DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 38*d86ed7fbStbbdev DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 39*d86ed7fbStbbdev OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 40*d86ed7fbStbbdev HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 41*d86ed7fbStbbdev LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 42*d86ed7fbStbbdev OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 43*d86ed7fbStbbdev SUCH DAMAGE. 44*d86ed7fbStbbdev */ 45*d86ed7fbStbbdev 46*d86ed7fbStbbdev /* 47*d86ed7fbStbbdev * objbound.cpp - This file contains the functions to find bounding boxes 48*d86ed7fbStbbdev * for the various primitives 49*d86ed7fbStbbdev */ 50*d86ed7fbStbbdev 51*d86ed7fbStbbdev #include "machine.hpp" 52*d86ed7fbStbbdev #include "types.hpp" 53*d86ed7fbStbbdev #include "macros.hpp" 54*d86ed7fbStbbdev #include "bndbox.hpp" 55*d86ed7fbStbbdev 56*d86ed7fbStbbdev #define OBJBOUND_PRIVATE 57*d86ed7fbStbbdev #include "objbound.hpp" 58*d86ed7fbStbbdev 59*d86ed7fbStbbdev static void globalbound(object **rootlist, vector *gmin, vector *gmax) { 60*d86ed7fbStbbdev vector min, max; 61*d86ed7fbStbbdev object *cur; 62*d86ed7fbStbbdev 63*d86ed7fbStbbdev if (*rootlist == nullptr) /* don't bound non-existent objects */ 64*d86ed7fbStbbdev return; 65*d86ed7fbStbbdev 66*d86ed7fbStbbdev gmin->x = FHUGE; 67*d86ed7fbStbbdev gmin->y = FHUGE; 68*d86ed7fbStbbdev gmin->z = FHUGE; 69*d86ed7fbStbbdev gmax->x = -FHUGE; 70*d86ed7fbStbbdev gmax->y = -FHUGE; 71*d86ed7fbStbbdev gmax->z = -FHUGE; 72*d86ed7fbStbbdev 73*d86ed7fbStbbdev cur = *rootlist; 74*d86ed7fbStbbdev while (cur != nullptr) { /* Go! */ 75*d86ed7fbStbbdev min.x = -FHUGE; 76*d86ed7fbStbbdev min.y = -FHUGE; 77*d86ed7fbStbbdev min.z = -FHUGE; 78*d86ed7fbStbbdev max.x = FHUGE; 79*d86ed7fbStbbdev max.y = FHUGE; 80*d86ed7fbStbbdev max.z = FHUGE; 81*d86ed7fbStbbdev 82*d86ed7fbStbbdev cur->methods->bbox((void *)cur, &min, &max); 83*d86ed7fbStbbdev 84*d86ed7fbStbbdev gmin->x = MYMIN(gmin->x, min.x); 85*d86ed7fbStbbdev gmin->y = MYMIN(gmin->y, min.y); 86*d86ed7fbStbbdev gmin->z = MYMIN(gmin->z, min.z); 87*d86ed7fbStbbdev 88*d86ed7fbStbbdev gmax->x = MYMAX(gmax->x, max.x); 89*d86ed7fbStbbdev gmax->y = MYMAX(gmax->y, max.y); 90*d86ed7fbStbbdev gmax->z = MYMAX(gmax->z, max.z); 91*d86ed7fbStbbdev 92*d86ed7fbStbbdev cur = (object *)cur->nextobj; 93*d86ed7fbStbbdev } 94*d86ed7fbStbbdev } 95*d86ed7fbStbbdev 96*d86ed7fbStbbdev static int objinside(object *obj, vector *min, vector *max) { 97*d86ed7fbStbbdev vector omin, omax; 98*d86ed7fbStbbdev 99*d86ed7fbStbbdev if (obj == nullptr) /* non-existent object, shouldn't get here */ 100*d86ed7fbStbbdev return 0; 101*d86ed7fbStbbdev 102*d86ed7fbStbbdev if (obj->methods->bbox((void *)obj, &omin, &omax)) { 103*d86ed7fbStbbdev if ((min->x <= omin.x) && (min->y <= omin.y) && (min->z <= omin.z) && (max->x >= omax.x) && 104*d86ed7fbStbbdev (max->y >= omax.y) && (max->z >= omax.z)) { 105*d86ed7fbStbbdev return 1; 106*d86ed7fbStbbdev } 107*d86ed7fbStbbdev } 108*d86ed7fbStbbdev return 0; 109*d86ed7fbStbbdev } 110*d86ed7fbStbbdev 111*d86ed7fbStbbdev static int countobj(object *root) { 112*d86ed7fbStbbdev object *cur; /* counts the number of objects on a list */ 113*d86ed7fbStbbdev int numobj; 114*d86ed7fbStbbdev 115*d86ed7fbStbbdev numobj = 0; 116*d86ed7fbStbbdev cur = root; 117*d86ed7fbStbbdev 118*d86ed7fbStbbdev while (cur != nullptr) { 119*d86ed7fbStbbdev cur = (object *)cur->nextobj; 120*d86ed7fbStbbdev numobj++; 121*d86ed7fbStbbdev } 122*d86ed7fbStbbdev return numobj; 123*d86ed7fbStbbdev } 124*d86ed7fbStbbdev 125*d86ed7fbStbbdev static void movenextobj(object *thisobj, object **root) { 126*d86ed7fbStbbdev object *cur, *tmp; 127*d86ed7fbStbbdev 128*d86ed7fbStbbdev /* move the object after thisobj to the front of the object list */ 129*d86ed7fbStbbdev /* headed by root */ 130*d86ed7fbStbbdev if (thisobj != nullptr) { 131*d86ed7fbStbbdev if (thisobj->nextobj != nullptr) { 132*d86ed7fbStbbdev cur = (object *)thisobj->nextobj; /* the object to be moved */ 133*d86ed7fbStbbdev thisobj->nextobj = cur->nextobj; /* link around the moved obj */ 134*d86ed7fbStbbdev tmp = *root; /* store the root node */ 135*d86ed7fbStbbdev cur->nextobj = tmp; /* attach root to cur */ 136*d86ed7fbStbbdev *root = cur; /* make cur, the new root */ 137*d86ed7fbStbbdev } 138*d86ed7fbStbbdev } 139*d86ed7fbStbbdev } 140*d86ed7fbStbbdev 141*d86ed7fbStbbdev static void octreespace(object **rootlist, int maxoctnodes) { 142*d86ed7fbStbbdev object *cur; 143*d86ed7fbStbbdev vector gmin, gmax, gctr; 144*d86ed7fbStbbdev vector cmin1, cmin2, cmin3, cmin4, cmin5, cmin6, cmin7, cmin8; 145*d86ed7fbStbbdev vector cmax1, cmax2, cmax3, cmax4, cmax5, cmax6, cmax7, cmax8; 146*d86ed7fbStbbdev bndbox *box1, *box2, *box3, *box4; 147*d86ed7fbStbbdev bndbox *box5, *box6, *box7, *box8; 148*d86ed7fbStbbdev int skipobj; 149*d86ed7fbStbbdev 150*d86ed7fbStbbdev if (*rootlist == nullptr) /* don't subdivide non-existent data */ 151*d86ed7fbStbbdev return; 152*d86ed7fbStbbdev 153*d86ed7fbStbbdev skipobj = 0; 154*d86ed7fbStbbdev globalbound(rootlist, &gmin, &gmax); /* find global min and max */ 155*d86ed7fbStbbdev 156*d86ed7fbStbbdev gctr.x = ((gmax.x - gmin.x) / 2.0) + gmin.x; 157*d86ed7fbStbbdev gctr.y = ((gmax.y - gmin.y) / 2.0) + gmin.y; 158*d86ed7fbStbbdev gctr.z = ((gmax.z - gmin.z) / 2.0) + gmin.z; 159*d86ed7fbStbbdev 160*d86ed7fbStbbdev cmin1 = gmin; 161*d86ed7fbStbbdev cmax1 = gctr; 162*d86ed7fbStbbdev box1 = newbndbox(cmin1, cmax1); 163*d86ed7fbStbbdev 164*d86ed7fbStbbdev cmin2 = gmin; 165*d86ed7fbStbbdev cmin2.x = gctr.x; 166*d86ed7fbStbbdev cmax2 = gmax; 167*d86ed7fbStbbdev cmax2.y = gctr.y; 168*d86ed7fbStbbdev cmax2.z = gctr.z; 169*d86ed7fbStbbdev box2 = newbndbox(cmin2, cmax2); 170*d86ed7fbStbbdev 171*d86ed7fbStbbdev cmin3 = gmin; 172*d86ed7fbStbbdev cmin3.y = gctr.y; 173*d86ed7fbStbbdev cmax3 = gmax; 174*d86ed7fbStbbdev cmax3.x = gctr.x; 175*d86ed7fbStbbdev cmax3.z = gctr.z; 176*d86ed7fbStbbdev box3 = newbndbox(cmin3, cmax3); 177*d86ed7fbStbbdev 178*d86ed7fbStbbdev cmin4 = gmin; 179*d86ed7fbStbbdev cmin4.x = gctr.x; 180*d86ed7fbStbbdev cmin4.y = gctr.y; 181*d86ed7fbStbbdev cmax4 = gmax; 182*d86ed7fbStbbdev cmax4.z = gctr.z; 183*d86ed7fbStbbdev box4 = newbndbox(cmin4, cmax4); 184*d86ed7fbStbbdev 185*d86ed7fbStbbdev cmin5 = gmin; 186*d86ed7fbStbbdev cmin5.z = gctr.z; 187*d86ed7fbStbbdev cmax5 = gctr; 188*d86ed7fbStbbdev cmax5.z = gmax.z; 189*d86ed7fbStbbdev box5 = newbndbox(cmin5, cmax5); 190*d86ed7fbStbbdev 191*d86ed7fbStbbdev cmin6 = gctr; 192*d86ed7fbStbbdev cmin6.y = gmin.y; 193*d86ed7fbStbbdev cmax6 = gmax; 194*d86ed7fbStbbdev cmax6.y = gctr.y; 195*d86ed7fbStbbdev box6 = newbndbox(cmin6, cmax6); 196*d86ed7fbStbbdev 197*d86ed7fbStbbdev cmin7 = gctr; 198*d86ed7fbStbbdev cmin7.x = gmin.x; 199*d86ed7fbStbbdev cmax7 = gctr; 200*d86ed7fbStbbdev cmax7.y = gmax.y; 201*d86ed7fbStbbdev cmax7.z = gmax.z; 202*d86ed7fbStbbdev box7 = newbndbox(cmin7, cmax7); 203*d86ed7fbStbbdev 204*d86ed7fbStbbdev cmin8 = gctr; 205*d86ed7fbStbbdev cmax8 = gmax; 206*d86ed7fbStbbdev box8 = newbndbox(cmin8, cmax8); 207*d86ed7fbStbbdev 208*d86ed7fbStbbdev cur = *rootlist; 209*d86ed7fbStbbdev while (cur != nullptr) { 210*d86ed7fbStbbdev if (objinside((object *)cur->nextobj, &cmin1, &cmax1)) { 211*d86ed7fbStbbdev movenextobj(cur, &box1->objlist); 212*d86ed7fbStbbdev } 213*d86ed7fbStbbdev else if (objinside((object *)cur->nextobj, &cmin2, &cmax2)) { 214*d86ed7fbStbbdev movenextobj(cur, &box2->objlist); 215*d86ed7fbStbbdev } 216*d86ed7fbStbbdev else if (objinside((object *)cur->nextobj, &cmin3, &cmax3)) { 217*d86ed7fbStbbdev movenextobj(cur, &box3->objlist); 218*d86ed7fbStbbdev } 219*d86ed7fbStbbdev else if (objinside((object *)cur->nextobj, &cmin4, &cmax4)) { 220*d86ed7fbStbbdev movenextobj(cur, &box4->objlist); 221*d86ed7fbStbbdev } 222*d86ed7fbStbbdev else if (objinside((object *)cur->nextobj, &cmin5, &cmax5)) { 223*d86ed7fbStbbdev movenextobj(cur, &box5->objlist); 224*d86ed7fbStbbdev } 225*d86ed7fbStbbdev else if (objinside((object *)cur->nextobj, &cmin6, &cmax6)) { 226*d86ed7fbStbbdev movenextobj(cur, &box6->objlist); 227*d86ed7fbStbbdev } 228*d86ed7fbStbbdev else if (objinside((object *)cur->nextobj, &cmin7, &cmax7)) { 229*d86ed7fbStbbdev movenextobj(cur, &box7->objlist); 230*d86ed7fbStbbdev } 231*d86ed7fbStbbdev else if (objinside((object *)cur->nextobj, &cmin8, &cmax8)) { 232*d86ed7fbStbbdev movenextobj(cur, &box8->objlist); 233*d86ed7fbStbbdev } 234*d86ed7fbStbbdev else { 235*d86ed7fbStbbdev skipobj++; 236*d86ed7fbStbbdev cur = (object *)cur->nextobj; 237*d86ed7fbStbbdev } 238*d86ed7fbStbbdev } 239*d86ed7fbStbbdev 240*d86ed7fbStbbdev /* new scope, for redefinition of cur, and old */ 241*d86ed7fbStbbdev { 242*d86ed7fbStbbdev bndbox *cur, *old; 243*d86ed7fbStbbdev old = box1; 244*d86ed7fbStbbdev cur = box2; 245*d86ed7fbStbbdev if (countobj(cur->objlist) > 0) { 246*d86ed7fbStbbdev old->nextobj = cur; 247*d86ed7fbStbbdev globalbound(&cur->objlist, &cur->min, &cur->max); 248*d86ed7fbStbbdev old = cur; 249*d86ed7fbStbbdev } 250*d86ed7fbStbbdev cur = box3; 251*d86ed7fbStbbdev if (countobj(cur->objlist) > 0) { 252*d86ed7fbStbbdev old->nextobj = cur; 253*d86ed7fbStbbdev globalbound(&cur->objlist, &cur->min, &cur->max); 254*d86ed7fbStbbdev old = cur; 255*d86ed7fbStbbdev } 256*d86ed7fbStbbdev cur = box4; 257*d86ed7fbStbbdev if (countobj(cur->objlist) > 0) { 258*d86ed7fbStbbdev old->nextobj = cur; 259*d86ed7fbStbbdev globalbound(&cur->objlist, &cur->min, &cur->max); 260*d86ed7fbStbbdev old = cur; 261*d86ed7fbStbbdev } 262*d86ed7fbStbbdev cur = box5; 263*d86ed7fbStbbdev if (countobj(cur->objlist) > 0) { 264*d86ed7fbStbbdev old->nextobj = cur; 265*d86ed7fbStbbdev globalbound(&cur->objlist, &cur->min, &cur->max); 266*d86ed7fbStbbdev old = cur; 267*d86ed7fbStbbdev } 268*d86ed7fbStbbdev cur = box6; 269*d86ed7fbStbbdev if (countobj(cur->objlist) > 0) { 270*d86ed7fbStbbdev old->nextobj = cur; 271*d86ed7fbStbbdev globalbound(&cur->objlist, &cur->min, &cur->max); 272*d86ed7fbStbbdev old = cur; 273*d86ed7fbStbbdev } 274*d86ed7fbStbbdev cur = box7; 275*d86ed7fbStbbdev if (countobj(cur->objlist) > 0) { 276*d86ed7fbStbbdev old->nextobj = cur; 277*d86ed7fbStbbdev globalbound(&cur->objlist, &cur->min, &cur->max); 278*d86ed7fbStbbdev old = cur; 279*d86ed7fbStbbdev } 280*d86ed7fbStbbdev cur = box8; 281*d86ed7fbStbbdev if (countobj(cur->objlist) > 0) { 282*d86ed7fbStbbdev old->nextobj = cur; 283*d86ed7fbStbbdev globalbound(&cur->objlist, &cur->min, &cur->max); 284*d86ed7fbStbbdev old = cur; 285*d86ed7fbStbbdev } 286*d86ed7fbStbbdev 287*d86ed7fbStbbdev old->nextobj = *rootlist; 288*d86ed7fbStbbdev 289*d86ed7fbStbbdev if (countobj(box1->objlist) > 0) { 290*d86ed7fbStbbdev globalbound(&box1->objlist, &box1->min, &box1->max); 291*d86ed7fbStbbdev *rootlist = (object *)box1; 292*d86ed7fbStbbdev } 293*d86ed7fbStbbdev else { 294*d86ed7fbStbbdev *rootlist = (object *)box1->nextobj; 295*d86ed7fbStbbdev } 296*d86ed7fbStbbdev 297*d86ed7fbStbbdev } /**** end of special cur and old scope */ 298*d86ed7fbStbbdev 299*d86ed7fbStbbdev if (countobj(box1->objlist) > maxoctnodes) { 300*d86ed7fbStbbdev octreespace(&box1->objlist, maxoctnodes); 301*d86ed7fbStbbdev } 302*d86ed7fbStbbdev if (countobj(box2->objlist) > maxoctnodes) { 303*d86ed7fbStbbdev octreespace(&box2->objlist, maxoctnodes); 304*d86ed7fbStbbdev } 305*d86ed7fbStbbdev if (countobj(box3->objlist) > maxoctnodes) { 306*d86ed7fbStbbdev octreespace(&box3->objlist, maxoctnodes); 307*d86ed7fbStbbdev } 308*d86ed7fbStbbdev if (countobj(box4->objlist) > maxoctnodes) { 309*d86ed7fbStbbdev octreespace(&box4->objlist, maxoctnodes); 310*d86ed7fbStbbdev } 311*d86ed7fbStbbdev if (countobj(box5->objlist) > maxoctnodes) { 312*d86ed7fbStbbdev octreespace(&box5->objlist, maxoctnodes); 313*d86ed7fbStbbdev } 314*d86ed7fbStbbdev if (countobj(box6->objlist) > maxoctnodes) { 315*d86ed7fbStbbdev octreespace(&box6->objlist, maxoctnodes); 316*d86ed7fbStbbdev } 317*d86ed7fbStbbdev if (countobj(box7->objlist) > maxoctnodes) { 318*d86ed7fbStbbdev octreespace(&box7->objlist, maxoctnodes); 319*d86ed7fbStbbdev } 320*d86ed7fbStbbdev if (countobj(box8->objlist) > maxoctnodes) { 321*d86ed7fbStbbdev octreespace(&box8->objlist, maxoctnodes); 322*d86ed7fbStbbdev } 323*d86ed7fbStbbdev } 324*d86ed7fbStbbdev 325*d86ed7fbStbbdev void dividespace(int maxoctnodes, object **toplist) { 326*d86ed7fbStbbdev bndbox *gbox; 327*d86ed7fbStbbdev vector gmin, gmax; 328*d86ed7fbStbbdev 329*d86ed7fbStbbdev if (countobj(*toplist) > maxoctnodes) { 330*d86ed7fbStbbdev globalbound(toplist, &gmin, &gmax); 331*d86ed7fbStbbdev 332*d86ed7fbStbbdev octreespace(toplist, maxoctnodes); 333*d86ed7fbStbbdev 334*d86ed7fbStbbdev gbox = newbndbox(gmin, gmax); 335*d86ed7fbStbbdev gbox->objlist = nullptr; 336*d86ed7fbStbbdev gbox->tex = nullptr; 337*d86ed7fbStbbdev gbox->nextobj = nullptr; 338*d86ed7fbStbbdev gbox->objlist = *toplist; 339*d86ed7fbStbbdev *toplist = (object *)gbox; 340*d86ed7fbStbbdev } 341*d86ed7fbStbbdev } 342