ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/ot/o_cone.c
Revision: 2.2
Committed: Sat Feb 22 02:07:26 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 2.1: +1 -4 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

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