ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/dircode.c
Revision: 2.8
Committed: Fri Nov 9 01:35:00 2012 UTC (11 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R2, rad4R2P2, rad5R0, rad5R1, rad4R2, rad4R2P1
Changes since 2.7: +7 -13 lines
Log Message:
ANSIfication

File Contents

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