ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/oococt.c
Revision: 2.1
Committed: Tue Feb 24 19:39:26 2015 UTC (9 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial check-in of photon map addition by Roland Schregle

File Contents

# User Rev Content
1 greg 2.1 /*
2     ==================================================================
3     Out-of-core octree data structure
4    
5     Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
6     (c) Fraunhofer Institute for Solar Energy Systems,
7     Lucerne University of Applied Sciences & Arts
8     ==================================================================
9    
10     $Id$
11     */
12    
13    
14     #include <stdlib.h>
15     #include "oococt.h"
16     #include "oocsort.h"
17    
18    
19     static OOC_Sort_Key zInterleave (OOC_Sort_Key k)
20     /* Interleave lower 21 bits of k with 00, resulting in 63 bits.
21     This code taken from
22     http://www.forceflow.be/2013/10/07/
23     morton-encodingdecoding-through-bit-interleaving-implementations/ */
24     {
25     /* Mask out lower 21 bits, the rest is cryptic */
26     OOC_Sort_Key i = k & 0x1fffff;
27    
28     i = (i | i << 32) & 0x001f00000000ffff;
29     i = (i | i << 16) & 0x001f0000ff0000ff;
30     i = (i | i << 8) & 0x100f00f00f00f00f;
31     i = (i | i << 4) & 0x10c30c30c30c30c3;
32     i = (i | i << 2) & 0x1249249249249249;
33    
34     return i;
35     }
36    
37    
38     static OOC_Sort_Key Key2zOrder (OOC_Octree *oct, FVECT key)
39     /* Compute 63-bit Morton (Z-order) index for 3D key */
40     {
41     int i;
42     OOC_Sort_Key k [3];
43    
44     /* Normalise key and map to 21-bit int */
45     for (i = 0; i < 3; i++)
46     k [i] = (((OOC_Sort_Key)1 << 21) - 1) / oct -> size *
47     (key [i] - oct -> org [i]);
48    
49     /* Interleave each dim with zeros and merge */
50     return zInterleave(k [0]) | zInterleave(k [1]) << 1 |
51     zInterleave(k [2]) << 2;
52     }
53    
54    
55     static OOC_Node *NewNode (OOC_Octree *oct)
56     /* Allocate new octree node, enlarge array if necessary.
57     Return pointer to new node or NULL if failed. */
58     {
59     OOC_Node *n = NULL;
60    
61     if (++oct -> numNodes > oct -> maxNodes) {
62     /* Need to allocate root or enlarge array */
63     oct -> maxNodes += OOC_BLKSIZE / sizeof(OOC_Node);
64     realloc(oct -> root, oct -> maxNodes * sizeof(OOC_Node));
65     if (!oct -> root)
66     return NULL;
67     }
68    
69     n = oct -> root + oct -> numNodes - 1;
70     n -> num = n -> kid = 0;
71     }
72    
73    
74     int OOC_Init (OOC_Octree *oct, unsigned recSize, unsigned leafMax,
75     unsigned maxDepth)
76     {
77     ooc -> org [0] = oct -> org [1] = oct -> org [2] = FHUGE;
78     ooc -> size = oct -> maxNodes = oct -> lastNode = 0;
79     ooc -> recSize = recSize;
80     ooc -> leafMax = leafMax;
81     ooc -> maxDepth = maxDepth;
82     ooc -> root = NULL;
83    
84     return NewNode(oct) ? 0 : -1;
85     }
86    
87    
88     int OOC_Branch (FVECT key, FVECT org, RREAL *size);
89     /* Return index of kid containing key, update origin and size accordingly */
90     {
91     size *= 0.5;
92     int kidIdx = 0;
93    
94     for (int i = 0; i < 3; i++) {
95     RREAL cent = org [i] + size;
96     if (key [i] > cent) {
97     kidIdx |= 1 << i;
98     org [i] = cent;
99     }
100     }
101    
102     return kidIdx;
103     }
104    
105    
106     OOC_Idx OOC_Find (OOC_Octree *oct, FVECT key)
107     /* Iterative search for given key */
108     {
109     FVECT org;
110     RREAL size;
111     OOC_Idx dataIdx = 0;
112     OOC_Node *node = NULL;
113    
114     if (!oct || !oct -> root)
115     return -1;
116    
117     node = oct -> root;
118     VCOPY(org, oct -> org);
119     size = oct -> size;
120    
121     /* Quit at terminal/empty node or internal leaf */
122     while (OOC_INTNODE(*node)) {
123     /* Determine kid to branch into and update data index with skipped
124     * kids' data counts */
125     int kidIdx = OOC_Branch(key, org, size);
126     node = oct -> root + OOC_KID(*node);
127     while (kidIdx--)
128     dataIdx += OOC_NUMDATA(node++);
129     }
130    
131     /* Reached empty node -> not found */
132     if (OOC_EMPTYNODE(*node))
133     return -1;
134    
135     /* Reached terminal node -> find leaf to branch into and update data
136     * index with skipped leaves' data counts */
137     if (OOC_TERMNODE(*node)) {
138     OOC_Leaf *leaf = ooc -> leaves [OOC_KID(*node)];
139     int leafIdx = OOC_Branch(key, org, size);
140     while (leafIdx--)
141     dataIdx += *leaf++;
142     }
143    
144     /* (Reached internal leaf -> already have data index) */
145     return dataIdx;
146     }
147    
148    
149     #if 0
150     OOC_Node *FindNode (OOC_Octree *oct, FVECT key, OOC_Idx *dataIdx, int flags)
151     /* ITERATIVE node search for given key */
152     {
153     FVECT org;
154     double size;
155     OOC_Idx dataIdx = 0;
156     OOC_Node *node = NULL;
157    
158     if (!oct || !oct -> root)
159     return NULL;
160    
161     node = oct -> root;
162     VCOPY(org, oct -> org);
163     size = oct -> size;
164    
165     /* Quit at terminal or empty node */
166     while (!OOC_TERM(*node) && !OOC_EMPTY(*node)) {
167     size *= 0.5;
168     int kidIdx = 0;
169    
170     /* Determine kid to branch into and update origin accordingly */
171     for (int i = 0; i < 3; i++) {
172     RREAL cent = org [i] + size;
173     if (key [i] > cent) {
174     kidIdx |= 1 << i;
175     org [i] = cent;
176     }
177     }
178    
179     /* Increment node's data counter if inserting */
180     if (flags & OOC_INSERT)
181     node -> numData++;
182    
183     /* Update data index with skipped kids' data counts */
184     node = oct -> root + node -> kid;
185     while (kidIdx--)
186     dataIdx += node++ -> numData;
187     }
188    
189     return node;
190     }
191    
192    
193     OOC_Idx FindLeaf (OOC_Leaf *leaf, FVECT key, OOC_Idx *dataIdx);
194     /* Return index into data block for leaf containing key */
195     {
196     int kidIdx = 0;
197     OOC_Idx =
198    
199     for (int i = 0; i < 3; i++) {
200     if (key [i]
201     #endif