ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/o_cone.c
Revision: 2.7
Committed: Thu Apr 21 00:40:35 2016 UTC (8 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, rad5R2, rad5R1, rad5R3, HEAD
Changes since 2.6: +14 -8 lines
Log Message:
Made zero cone and ring radii non-fatal (degenerate -> ignore)

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: o_cone.c,v 2.6 2007/11/21 18:51:04 greg Exp $";
3 #endif
4 /*
5 * o_cone.c - routines for intersecting cubes with cones.
6 *
7 * 2/3/86
8 */
9
10 #include "standard.h"
11 #include "octree.h"
12 #include "object.h"
13 #include "cone.h"
14 #include "plocate.h"
15
16 #ifndef STRICT
17 #define STRICT 1
18 #endif
19
20 #define ROOT3 1.732050808
21
22 /*
23 * The algorithm used to detect cube intersection with cones is
24 * recursive. First, we approximate the cube to be a sphere. Then
25 * we test for cone intersection with the sphere by testing the
26 * segment of the cone which is nearest the sphere's center.
27 * If the cone has points within the cube's bounding sphere,
28 * we must check for intersection with the cube. This is done with
29 * the 3D line clipper. The same cone segment is used in this test.
30 * If the clip fails, we still cannot be sure there is no intersection,
31 * so we subdivide the cube and recurse.
32 * If none of the sub-cubes intersect, then our cube does not intersect.
33 */
34
35 extern double mincusize; /* minimum cube size */
36
37 static int findcseg(FVECT ep0, FVECT ep1, CONE *co, FVECT p);
38
39
40
41 extern int
42 o_cone( /* determine if cone intersects cube */
43 OBJREC *o,
44 CUBE *cu
45 )
46 {
47 CONE *co;
48 FVECT ep0, ep1;
49 #if STRICT
50 FVECT cumin, cumax;
51 CUBE cukid;
52 int j;
53 #endif
54 double r;
55 FVECT p;
56 int i;
57 /* get cone arguments */
58 co = getcone(o, 0);
59 if (co == NULL) /* check for degenerate case */
60 return(O_MISS);
61 /* get cube center */
62 r = cu->cusize * 0.5;
63 for (i = 0; i < 3; i++)
64 p[i] = cu->cuorg[i] + r;
65 r *= ROOT3; /* bounding radius for cube */
66
67 if (findcseg(ep0, ep1, co, p)) {
68 /* check min. distance to cone */
69 if (dist2lseg(p, ep0, ep1) > (r+FTINY)*(r+FTINY))
70 return(O_MISS);
71 #if STRICT
72 /* get cube boundaries */
73 for (i = 0; i < 3; i++)
74 cumax[i] = (cumin[i] = cu->cuorg[i]) + cu->cusize;
75 /* closest segment intersects? */
76 if (clip(ep0, ep1, cumin, cumax))
77 return(O_HIT);
78 }
79 /* check sub-cubes */
80 cukid.cusize = cu->cusize * 0.5;
81 if (cukid.cusize < mincusize)
82 return(O_HIT); /* cube too small */
83 cukid.cutree = EMPTY;
84
85 for (j = 0; j < 8; j++) {
86 for (i = 0; i < 3; i++) {
87 cukid.cuorg[i] = cu->cuorg[i];
88 if (1<<i & j)
89 cukid.cuorg[i] += cukid.cusize;
90 }
91 if (o_cone(o, &cukid))
92 return(O_HIT); /* sub-cube intersects */
93 }
94 return(O_MISS); /* no intersection */
95 #else
96 }
97 return(O_HIT); /* assume intersection */
98 #endif
99 }
100
101
102 static int
103 findcseg( /* find line segment from cone closest to p */
104 FVECT ep0,
105 FVECT ep1,
106 CONE *co,
107 FVECT p
108 )
109 {
110 double d;
111 FVECT v;
112 int i;
113 /* find direction from axis to point */
114 VSUB(v, p, CO_P0(co));
115 d = DOT(v, co->ad);
116 for (i = 0; i < 3; i++)
117 v[i] -= d*co->ad[i];
118 if (normalize(v) == 0.0)
119 return(0);
120 /* find endpoints of segment */
121 for (i = 0; i < 3; i++) {
122 ep0[i] = CO_R0(co)*v[i] + CO_P0(co)[i];
123 ep1[i] = CO_R1(co)*v[i] + CO_P1(co)[i];
124 }
125 return(1); /* return distance from axis */
126 }