ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/dircode.c
Revision: 2.2
Committed: Tue Mar 4 19:02:47 2003 UTC (21 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +3 -1 lines
Log Message:
Changed encodedir() so it never generates 0

File Contents

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