Tachyon (current)  Current Main Branch
intersect.c
Go to the documentation of this file.
1 /*
2  * intersect.c - This file contains code for CSG and intersection routines.
3  *
4  * (C) Copyright 1994-2022 John E. Stone
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * $Id: intersect.c,v 1.44 2022/02/18 17:55:28 johns Exp $
8  *
9  */
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <math.h>
15 
16 #define TACHYON_INTERNAL 1
17 #include "tachyon.h"
18 #include "intersect.h"
19 #include "macros.h"
20 
21 #if 0 && defined(__INTEL_COMPILER) && defined(__MIC__)
22 /* compiler intrinsics for prefetching */
23 #include <immintrin.h>
24 #endif
25 
26 unsigned int new_objectid(scenedef * scene) {
27  return scene->objgroup.numobjects++; /* generate unique object ID's */
28 }
29 
30 unsigned int max_objectid(scenedef * scene) {
31  return scene->objgroup.numobjects;
32 }
33 
34 void free_objects(object * start) {
35  object * cur;
36  object * next;
37 
38  cur=start;
39  while (cur != NULL) {
40  next=cur->nextobj;
41  cur->methods->freeobj(cur);
42  cur=next;
43  }
44 }
45 
46 
47 void intersect_objects(ray * ry) {
48  object * cur;
49  object temp;
50 
51  reset_intersection(ry); /* eliminate any existing intersections */
52 
53  /* do unbounded objects first, to help early-exit bounded object tests */
54  temp.nextobj = ry->scene->objgroup.unboundedobj;
55  cur = &temp;
56  while ((cur=cur->nextobj) != NULL) {
57 #if 0 && defined(__INTEL_COMPILER) && defined(__MIC__)
58  _mm_prefetch(cur->nextobj, _MM_HINT_T0); /* load into all caches */
59 #endif
60  cur->methods->intersect(cur, ry);
61  }
62 
63  /* do bounded objects last, taking advantage of early-exit opportunities */
64  temp.nextobj = ry->scene->objgroup.boundedobj;
65  cur = &temp;
66  while ((cur=cur->nextobj) != NULL) {
67 #if 0 && defined(__INTEL_COMPILER) && defined(__MIC__)
68  _mm_prefetch(cur->nextobj, _MM_HINT_T0); /* load into all caches */
69 #endif
70  cur->methods->intersect(cur, ry);
71  }
72 
73 }
74 
75 
76 /* Only keeps closest intersection, no clipping, no CSG */
77 void add_regular_intersection(flt t, const object * obj, ray * ry) {
78  if (t > EPSILON) {
79  /* if we hit something before maxdist update maxdist */
80  if (t < ry->maxdist) {
81  ry->maxdist = t;
82  ry->intstruct.num=1;
83  ry->intstruct.closest.obj = obj;
84  ry->intstruct.closest.t = t;
85  }
86  }
87 }
88 
89 /* Only keeps closest intersection, also handles clipping, no CSG */
90 void add_clipped_intersection(flt t, const object * obj, ray * ry) {
91  if (t > EPSILON) {
92  /* if we hit something before maxdist update maxdist */
93  if (t < ry->maxdist) {
94 
95  /* handle clipped object tests */
96  if (obj->clip != NULL) {
97  vector hit;
98  int i;
99 
100  RAYPNT(hit, (*ry), t); /* find the hit point for further tests */
101  for (i=0; i<obj->clip->numplanes; i++) {
102  if ((obj->clip->planes[i * 4 ] * hit.x +
103  obj->clip->planes[i * 4 + 1] * hit.y +
104  obj->clip->planes[i * 4 + 2] * hit.z) >
105  obj->clip->planes[i * 4 + 3]) {
106  return; /* hit point was clipped */
107  }
108  }
109  }
110 
111  ry->maxdist = t;
112  ry->intstruct.num=1;
113  ry->intstruct.closest.obj = obj;
114  ry->intstruct.closest.t = t;
115  }
116  }
117 }
118 
119 int closest_intersection(flt * t, object const ** obj, ray * ry) {
120  if (ry->intstruct.num > 0) {
121  *t = ry->intstruct.closest.t;
122  *obj = ry->intstruct.closest.obj;
123  }
124 
125  return ry->intstruct.num;
126 }
127 /* End of CSG-unsafe */
128 
129 
130 /* Only meant for shadow rays, unsafe for anything else */
131 void add_shadow_intersection(flt t, const object * obj, ray * ry) {
132  if (t > EPSILON) {
133  /* if we hit something before maxdist update maxdist */
134  if (t < ry->maxdist) {
135  /* if this object doesn't cast a shadow, and we aren't */
136  /* limiting the number of transparent surfaces to less */
137  /* than 5, then modulate the light by its opacity value */
138  if (!(obj->tex->flags & RT_TEXTURE_SHADOWCAST)) {
139  if (ry->scene->shadowfilter)
140  ry->intstruct.shadowfilter *= (1.0 - obj->tex->opacity);
141  return;
142  }
143 
144  ry->maxdist = t;
145  ry->intstruct.num=1;
146 
147  /* if we hit *anything* before maxdist, and we're firing a */
148  /* shadow ray, then we are finished ray tracing the shadow */
149  ry->flags |= RT_RAY_FINISHED;
150  }
151  }
152 }
153 
154 /* Only meant for clipped shadow rays, unsafe for anything else */
155 void add_clipped_shadow_intersection(flt t, const object * obj, ray * ry) {
156  if (t > EPSILON) {
157  /* if we hit something before maxdist update maxdist */
158  if (t < ry->maxdist) {
159  /* if this object doesn't cast a shadow, and we aren't */
160  /* limiting the number of transparent surfaces to less */
161  /* than 5, then modulate the light by its opacity value */
162  if (!(obj->tex->flags & RT_TEXTURE_SHADOWCAST)) {
163  if (ry->scene->shadowfilter)
164  ry->intstruct.shadowfilter *= (1.0 - obj->tex->opacity);
165  return;
166  }
167 
168  /* handle clipped object tests */
169  if (obj->clip != NULL) {
170  vector hit;
171  int i;
172 
173  RAYPNT(hit, (*ry), t); /* find the hit point for further tests */
174  for (i=0; i<obj->clip->numplanes; i++) {
175  if ((obj->clip->planes[i * 4 ] * hit.x +
176  obj->clip->planes[i * 4 + 1] * hit.y +
177  obj->clip->planes[i * 4 + 2] * hit.z) >
178  obj->clip->planes[i * 4 + 3]) {
179  return; /* hit point was clipped */
180  }
181  }
182  }
183 
184  ry->maxdist = t;
185  ry->intstruct.num=1;
186 
187  /* if we hit *anything* before maxdist, and we're firing a */
188  /* shadow ray, then we are finished ray tracing the shadow */
189  ry->flags |= RT_RAY_FINISHED;
190  }
191  }
192 }
193 
194 
195 int shadow_intersection(ray * ry) {
196  if (ry->intstruct.num > 0)
197  return 1;
198 
199  return 0;
200 }
201 
void add_clipped_shadow_intersection(flt t, const object *obj, ray *ry)
Definition: intersect.c:155
unsigned int new_objectid(scenedef *scene)
Definition: intersect.c:26
int closest_intersection(flt *t, object const **obj, ray *ry)
Definition: intersect.c:119
int shadow_intersection(ray *ry)
Definition: intersect.c:195
double flt
generic floating point number, using double
Definition: tachyon.h:47
void add_clipped_intersection(flt t, const object *obj, ray *ry)
Definition: intersect.c:90
#define RAYPNT(c, a, b)
Definition: macros.h:18
unsigned int max_objectid(scenedef *scene)
Definition: intersect.c:30
void add_shadow_intersection(flt t, const object *obj, ray *ry)
Definition: intersect.c:131
void free_objects(object *start)
Definition: intersect.c:34
void add_regular_intersection(flt t, const object *obj, ray *ry)
Definition: intersect.c:77
Tachyon public API function prototypes and declarations used to drive the ray tracing engine...
#define reset_intersection(ry)
Definition: intersect.h:24
void intersect_objects(ray *ry)
Definition: intersect.c:47