ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/dircode.c
Revision: 2.5
Committed: Fri Jun 20 00:25:49 2003 UTC (20 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +7 -7 lines
Log Message:
Changed instances of "int4" to "int32" and "int2" to "int16"

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: dircode.c,v 2.4 2003/06/07 12:50:20 schorsch Exp $";
3 #endif
4 /*
5 * Compute a 4-byte direction code (int32 type defined in standard.h).
6 *
7 * Mean accuracy is 0.0022 degrees, with a maximum error of 0.0058 degrees.
8 */
9
10 #include "standard.h"
11
12 #define DCSCALE 11585.2 /* (1<<13)*sqrt(2) */
13 #define FXNEG 01
14 #define FYNEG 02
15 #define FZNEG 04
16 #define F1X 010
17 #define F2Z 020
18 #define F1SFT 5
19 #define F2SFT 18
20 #define FMASK 0x1fff
21
22 int32
23 encodedir(dv) /* encode a normalized direction vector */
24 FVECT dv;
25 {
26 register int32 dc = 0;
27 int cd[3], cm;
28 register int i;
29
30 for (i = 0; i < 3; i++)
31 if (dv[i] < 0.) {
32 cd[i] = (int)(dv[i] * -DCSCALE);
33 dc |= FXNEG<<i;
34 } else
35 cd[i] = (int)(dv[i] * DCSCALE);
36 if (cd[0] <= cd[1]) {
37 dc |= F1X | cd[0] << F1SFT;
38 cm = cd[1];
39 } else {
40 dc |= cd[1] << F1SFT;
41 cm = cd[0];
42 }
43 if (cd[2] <= cm)
44 dc |= F2Z | cd[2] << F2SFT;
45 else
46 dc |= cm << F2SFT;
47 if (!dc) /* don't generate 0 code */
48 dc = F1X;
49 return(dc);
50 }
51
52
53 void
54 decodedir(dv, dc) /* decode a normalized direction vector */
55 register FVECT dv; /* returned */
56 register int32 dc;
57 {
58 double d1, d2, der;
59
60 d1 = ((dc>>F1SFT & FMASK)+.5)*(1./DCSCALE);
61 d2 = ((dc>>F2SFT & FMASK)+.5)*(1./DCSCALE);
62 der = sqrt(1. - d1*d1 - d2*d2);
63 if (dc & F1X) {
64 dv[0] = d1;
65 if (dc & F2Z) { dv[1] = der; dv[2] = d2; }
66 else { dv[1] = d2; dv[2] = der; }
67 } else {
68 dv[1] = d1;
69 if (dc & F2Z) { dv[0] = der; dv[2] = d2; }
70 else { dv[0] = d2; dv[2] = der; }
71 }
72 if (dc & FXNEG) dv[0] = -dv[0];
73 if (dc & FYNEG) dv[1] = -dv[1];
74 if (dc & FZNEG) dv[2] = -dv[2];
75 }
76
77
78 double
79 dir2diff(dc1, dc2) /* approx. radians^2 between directions */
80 int32 dc1, dc2;
81 {
82 FVECT v1, v2;
83
84 decodedir(v1, dc1);
85 decodedir(v2, dc2);
86
87 return(2. - 2.*DOT(v1,v2));
88 }
89
90
91 double
92 fdir2diff(dc1, v2) /* approx. radians^2 between directions */
93 int32 dc1;
94 register FVECT v2;
95 {
96 FVECT v1;
97
98 decodedir(v1, dc1);
99
100 return(2. - 2.*DOT(v1,v2));
101 }