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