ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/dircode.c
Revision: 2.3
Committed: Wed Mar 12 04:59:04 2003 UTC (21 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 2.2: +3 -1 lines
Log Message:
Numerous bug fixes in new mesh code

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.2 static const char RCSid[] = "$Id$";
3 greg 2.1 #endif
4     /*
5 greg 2.3 * Compute a 4-byte direction code (int4 type defined in standard.h).
6     *
7     * Mean accuracy is 0.0022 degrees, with a maximum error of 0.0058 degrees.
8 greg 2.1 */
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     int4
23     encodedir(dv) /* encode a normalized direction vector */
24     FVECT dv;
25     {
26     register int4 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] = dv[i] * -DCSCALE;
33     dc |= FXNEG<<i;
34     } else
35     cd[i] = 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 greg 2.2 if (!dc) /* don't generate 0 code */
48     dc = F1X;
49 greg 2.1 return(dc);
50     }
51    
52    
53     void
54     decodedir(dv, dc) /* decode a normalized direction vector */
55     register FVECT dv; /* returned */
56     register int4 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     int4 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     int4 dc1;
94     register FVECT v2;
95     {
96     FVECT v1;
97    
98     decodedir(v1, dc1);
99    
100     return(2. - 2.*DOT(v1,v2));
101     }