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 * intersect.cpp - This file contains code for CSG and intersection routines. 48*d86ed7fbStbbdev */ 49*d86ed7fbStbbdev 50*d86ed7fbStbbdev #include "machine.hpp" 51*d86ed7fbStbbdev #include "types.hpp" 52*d86ed7fbStbbdev #include "intersect.hpp" 53*d86ed7fbStbbdev #include "light.hpp" 54*d86ed7fbStbbdev #include "util.hpp" 55*d86ed7fbStbbdev #include "global.hpp" 56*d86ed7fbStbbdev 57*d86ed7fbStbbdev unsigned int new_objectid(void) { 58*d86ed7fbStbbdev return numobjects++; /* global used to generate unique object ID's */ 59*d86ed7fbStbbdev } 60*d86ed7fbStbbdev 61*d86ed7fbStbbdev unsigned int max_objectid(void) { 62*d86ed7fbStbbdev return numobjects; 63*d86ed7fbStbbdev } 64*d86ed7fbStbbdev 65*d86ed7fbStbbdev void add_object(object *obj) { 66*d86ed7fbStbbdev object *objtemp; 67*d86ed7fbStbbdev 68*d86ed7fbStbbdev if (obj == nullptr) 69*d86ed7fbStbbdev return; 70*d86ed7fbStbbdev 71*d86ed7fbStbbdev obj->id = new_objectid(); 72*d86ed7fbStbbdev 73*d86ed7fbStbbdev objtemp = rootobj; 74*d86ed7fbStbbdev rootobj = obj; 75*d86ed7fbStbbdev obj->nextobj = objtemp; 76*d86ed7fbStbbdev } 77*d86ed7fbStbbdev 78*d86ed7fbStbbdev void free_objects(object *start) { 79*d86ed7fbStbbdev object *cur; 80*d86ed7fbStbbdev object *cur2; 81*d86ed7fbStbbdev 82*d86ed7fbStbbdev cur = start; 83*d86ed7fbStbbdev while (cur->nextobj != nullptr) { 84*d86ed7fbStbbdev cur2 = (object *)cur->nextobj; 85*d86ed7fbStbbdev cur->methods->free(cur); 86*d86ed7fbStbbdev cur = cur2; 87*d86ed7fbStbbdev } 88*d86ed7fbStbbdev free(cur); 89*d86ed7fbStbbdev } 90*d86ed7fbStbbdev 91*d86ed7fbStbbdev void reset_object(void) { 92*d86ed7fbStbbdev if (rootobj != nullptr) 93*d86ed7fbStbbdev free_objects(rootobj); 94*d86ed7fbStbbdev 95*d86ed7fbStbbdev rootobj = nullptr; 96*d86ed7fbStbbdev numobjects = 0; /* set number of objects back to 0 */ 97*d86ed7fbStbbdev } 98*d86ed7fbStbbdev 99*d86ed7fbStbbdev void intersect_objects(ray *intray) { 100*d86ed7fbStbbdev object *cur; 101*d86ed7fbStbbdev object temp; 102*d86ed7fbStbbdev 103*d86ed7fbStbbdev temp.nextobj = rootobj; /* setup the initial object pointers.. */ 104*d86ed7fbStbbdev cur = &temp; /* ready, set */ 105*d86ed7fbStbbdev 106*d86ed7fbStbbdev while ((cur = (object *)cur->nextobj) != nullptr) 107*d86ed7fbStbbdev cur->methods->intersect(cur, intray); 108*d86ed7fbStbbdev } 109*d86ed7fbStbbdev 110*d86ed7fbStbbdev void reset_intersection(intersectstruct *intstruct) { 111*d86ed7fbStbbdev intstruct->num = 0; 112*d86ed7fbStbbdev intstruct->list[0].t = FHUGE; 113*d86ed7fbStbbdev intstruct->list[0].obj = nullptr; 114*d86ed7fbStbbdev intstruct->list[1].t = FHUGE; 115*d86ed7fbStbbdev intstruct->list[1].obj = nullptr; 116*d86ed7fbStbbdev } 117*d86ed7fbStbbdev 118*d86ed7fbStbbdev void add_intersection(flt t, object *obj, ray *ry) { 119*d86ed7fbStbbdev intersectstruct *intstruct = ry->intstruct; 120*d86ed7fbStbbdev 121*d86ed7fbStbbdev if (t > EPSILON) { 122*d86ed7fbStbbdev /* if we hit something before maxdist update maxdist */ 123*d86ed7fbStbbdev if (t < ry->maxdist) { 124*d86ed7fbStbbdev ry->maxdist = t; 125*d86ed7fbStbbdev 126*d86ed7fbStbbdev /* if we hit *anything* before maxdist, and we're firing a */ 127*d86ed7fbStbbdev /* shadow ray, then we are finished ray tracing the shadow */ 128*d86ed7fbStbbdev if (ry->flags & RT_RAY_SHADOW) 129*d86ed7fbStbbdev ry->flags |= RT_RAY_FINISHED; 130*d86ed7fbStbbdev } 131*d86ed7fbStbbdev 132*d86ed7fbStbbdev intstruct->num++; 133*d86ed7fbStbbdev intstruct->list[intstruct->num].obj = obj; 134*d86ed7fbStbbdev intstruct->list[intstruct->num].t = t; 135*d86ed7fbStbbdev } 136*d86ed7fbStbbdev } 137*d86ed7fbStbbdev 138*d86ed7fbStbbdev int closest_intersection(flt *t, object **obj, intersectstruct *intstruct) { 139*d86ed7fbStbbdev int i; 140*d86ed7fbStbbdev *t = FHUGE; 141*d86ed7fbStbbdev 142*d86ed7fbStbbdev for (i = 1; i <= intstruct->num; i++) { 143*d86ed7fbStbbdev if (intstruct->list[i].t < *t) { 144*d86ed7fbStbbdev *t = intstruct->list[i].t; 145*d86ed7fbStbbdev *obj = intstruct->list[i].obj; 146*d86ed7fbStbbdev } 147*d86ed7fbStbbdev } 148*d86ed7fbStbbdev 149*d86ed7fbStbbdev return intstruct->num; 150*d86ed7fbStbbdev } 151*d86ed7fbStbbdev 152*d86ed7fbStbbdev int shadow_intersection(intersectstruct *intstruct, flt maxdist) { 153*d86ed7fbStbbdev int i; 154*d86ed7fbStbbdev 155*d86ed7fbStbbdev if (intstruct->num > 0) { 156*d86ed7fbStbbdev for (i = 1; i <= intstruct->num; i++) { 157*d86ed7fbStbbdev if ((intstruct->list[i].t < maxdist) && 158*d86ed7fbStbbdev (intstruct->list[i].obj->tex->shadowcast == 1)) { 159*d86ed7fbStbbdev return 1; 160*d86ed7fbStbbdev } 161*d86ed7fbStbbdev } 162*d86ed7fbStbbdev } 163*d86ed7fbStbbdev 164*d86ed7fbStbbdev return 0; 165*d86ed7fbStbbdev } 166