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

# 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     * 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 greg 2.2 if (!dc) /* don't generate 0 code */
46     dc = F1X;
47 greg 2.1 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     }