2 Copyright (c) 2005-2017 Intel Corporation
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
22 The original source for this example is
23 Copyright (c) 1994-2008 John E. Stone
26 Redistribution and use in source and binary forms, with or without
27 modification, are permitted provided that the following conditions
29 1. Redistributions of source code must retain the above copyright
30 notice, this list of conditions and the following disclaimer.
31 2. Redistributions in binary form must reproduce the above copyright
32 notice, this list of conditions and the following disclaimer in the
33 documentation and/or other materials provided with the distribution.
34 3. The name of the author may not be used to endorse or promote products
35 derived from this software without specific prior written permission.
37 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
38 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
39 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
40 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
41 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
43 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
46 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * objbound.cpp - This file contains the functions to find bounding boxes
52 * for the various primitives
60 #define OBJBOUND_PRIVATE
63 static void globalbound(object ** rootlist, vector * gmin, vector * gmax) {
67 if (*rootlist == NULL) /* don't bound non-existant objects */
70 gmin->x = FHUGE; gmin->y = FHUGE; gmin->z = FHUGE;
71 gmax->x = -FHUGE; gmax->y = -FHUGE; gmax->z = -FHUGE;
74 while (cur != NULL) { /* Go! */
75 min.x = -FHUGE; min.y = -FHUGE; min.z = -FHUGE;
76 max.x = FHUGE; max.y = FHUGE; max.z = FHUGE;
78 cur->methods->bbox((void *) cur, &min, &max);
80 gmin->x = MYMIN( gmin->x , min.x);
81 gmin->y = MYMIN( gmin->y , min.y);
82 gmin->z = MYMIN( gmin->z , min.z);
84 gmax->x = MYMAX( gmax->x , max.x);
85 gmax->y = MYMAX( gmax->y , max.y);
86 gmax->z = MYMAX( gmax->z , max.z);
88 cur=(object *)cur->nextobj;
92 static int objinside(object * obj, vector * min, vector * max) {
95 if (obj == NULL) /* non-existant object, shouldn't get here */
98 if (obj->methods->bbox((void *) obj, &omin, &omax)) {
99 if ((min->x <= omin.x) && (min->y <= omin.y) && (min->z <= omin.z) &&
100 (max->x >= omax.x) && (max->y >= omax.y) && (max->z >= omax.z)) {
107 static int countobj(object * root) {
108 object * cur; /* counts the number of objects on a list */
114 while (cur != NULL) {
115 cur=(object *)cur->nextobj;
121 static void movenextobj(object * thisobj, object ** root) {
124 /* move the object after thisobj to the front of the object list */
126 if (thisobj != NULL) {
127 if (thisobj->nextobj != NULL) {
128 cur=(object *)thisobj->nextobj; /* the object to be moved */
129 thisobj->nextobj = cur->nextobj; /* link around the moved obj */
130 tmp=*root; /* store the root node */
131 cur->nextobj=tmp; /* attach root to cur */
132 *root=cur; /* make cur, the new root */
137 static void octreespace(object ** rootlist, int maxoctnodes) {
139 vector gmin, gmax, gctr;
140 vector cmin1, cmin2, cmin3, cmin4, cmin5, cmin6, cmin7, cmin8;
141 vector cmax1, cmax2, cmax3, cmax4, cmax5, cmax6, cmax7, cmax8;
142 bndbox * box1, * box2, * box3, * box4;
143 bndbox * box5, * box6, * box7, * box8;
146 if (*rootlist == NULL) /* don't subdivide non-existant data */
150 globalbound(rootlist, &gmin, &gmax); /* find global min and max */
152 gctr.x = ((gmax.x - gmin.x) / 2.0) + gmin.x;
153 gctr.y = ((gmax.y - gmin.y) / 2.0) + gmin.y;
154 gctr.z = ((gmax.z - gmin.z) / 2.0) + gmin.z;
158 box1 = newbndbox(cmin1, cmax1);
165 box2 = newbndbox(cmin2, cmax2);
172 box3 = newbndbox(cmin3, cmax3);
179 box4 = newbndbox(cmin4, cmax4);
185 box5 = newbndbox(cmin5, cmax5);
191 box6 = newbndbox(cmin6, cmax6);
198 box7 = newbndbox(cmin7, cmax7);
202 box8 = newbndbox(cmin8, cmax8);
205 while (cur != NULL) {
206 if (objinside((object *)cur->nextobj, &cmin1, &cmax1)) {
207 movenextobj(cur, &box1->objlist);
209 else if (objinside((object *)cur->nextobj, &cmin2, &cmax2)) {
210 movenextobj(cur, &box2->objlist);
212 else if (objinside((object *)cur->nextobj, &cmin3, &cmax3)) {
213 movenextobj(cur, &box3->objlist);
215 else if (objinside((object *)cur->nextobj, &cmin4, &cmax4)) {
216 movenextobj(cur, &box4->objlist);
218 else if (objinside((object *)cur->nextobj, &cmin5, &cmax5)) {
219 movenextobj(cur, &box5->objlist);
221 else if (objinside((object *)cur->nextobj, &cmin6, &cmax6)) {
222 movenextobj(cur, &box6->objlist);
224 else if (objinside((object *)cur->nextobj, &cmin7, &cmax7)) {
225 movenextobj(cur, &box7->objlist);
227 else if (objinside((object *)cur->nextobj, &cmin8, &cmax8)) {
228 movenextobj(cur, &box8->objlist);
232 cur=(object *)cur->nextobj;
236 /* new scope, for redefinition of cur, and old */
237 { bndbox * cur, * old;
240 if (countobj(cur->objlist) > 0) {
242 globalbound(&cur->objlist, &cur->min, &cur->max);
246 if (countobj(cur->objlist) > 0) {
248 globalbound(&cur->objlist, &cur->min, &cur->max);
252 if (countobj(cur->objlist) > 0) {
254 globalbound(&cur->objlist, &cur->min, &cur->max);
258 if (countobj(cur->objlist) > 0) {
260 globalbound(&cur->objlist, &cur->min, &cur->max);
264 if (countobj(cur->objlist) > 0) {
266 globalbound(&cur->objlist, &cur->min, &cur->max);
270 if (countobj(cur->objlist) > 0) {
272 globalbound(&cur->objlist, &cur->min, &cur->max);
276 if (countobj(cur->objlist) > 0) {
278 globalbound(&cur->objlist, &cur->min, &cur->max);
282 old->nextobj=*rootlist;
284 if (countobj(box1->objlist) > 0) {
285 globalbound(&box1->objlist, &box1->min, &box1->max);
286 *rootlist=(object *) box1;
289 *rootlist=(object *) box1->nextobj;
292 } /**** end of special cur and old scope */
294 if (countobj(box1->objlist) > maxoctnodes) {
295 octreespace(&box1->objlist, maxoctnodes);
297 if (countobj(box2->objlist) > maxoctnodes) {
298 octreespace(&box2->objlist, maxoctnodes);
300 if (countobj(box3->objlist) > maxoctnodes) {
301 octreespace(&box3->objlist, maxoctnodes);
303 if (countobj(box4->objlist) > maxoctnodes) {
304 octreespace(&box4->objlist, maxoctnodes);
306 if (countobj(box5->objlist) > maxoctnodes) {
307 octreespace(&box5->objlist, maxoctnodes);
309 if (countobj(box6->objlist) > maxoctnodes) {
310 octreespace(&box6->objlist, maxoctnodes);
312 if (countobj(box7->objlist) > maxoctnodes) {
313 octreespace(&box7->objlist, maxoctnodes);
315 if (countobj(box8->objlist) > maxoctnodes) {
316 octreespace(&box8->objlist, maxoctnodes);
320 void dividespace(int maxoctnodes, object **toplist) {
324 if (countobj(*toplist) > maxoctnodes) {
325 globalbound(toplist, &gmin, &gmax);
327 octreespace(toplist, maxoctnodes);
329 gbox = newbndbox(gmin, gmax);
330 gbox->objlist = NULL;
333 gbox->objlist=*toplist;
334 *toplist=(object *) gbox;