ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/o_cone.c
Revision: 2.5
Committed: Tue Jun 14 17:10:06 2005 UTC (19 years, 5 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R7P2, rad3R7P1, rad3R8
Changes since 2.4: +14 -14 lines
Log Message:
Fixed ancient bug in cone bounding box calculation -- caused visibility errors

File Contents

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