author | Radek Brich <radek.brich@devl.cz> |
Tue, 26 Jul 2016 18:19:37 +0200 | |
branch | pyrit |
changeset 104 | 2274a07510c1 |
parent 103 | 3b3257a410fe |
permissions | -rw-r--r-- |
34
28f6e8b9d5d1
quaternion moved to extra header file
Radek Brich <radek.brich@devl.cz>
parents:
30
diff
changeset
|
1 |
/* |
44 | 2 |
* kdtree.cc: KdTree class |
3 |
* |
|
4 |
* This file is part of Pyrit Ray Tracer. |
|
5 |
* |
|
91 | 6 |
* Copyright 2006, 2007, 2008 Radek Brich |
34
28f6e8b9d5d1
quaternion moved to extra header file
Radek Brich <radek.brich@devl.cz>
parents:
30
diff
changeset
|
7 |
* |
44 | 8 |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
9 |
* of this software and associated documentation files (the "Software"), to deal |
|
10 |
* in the Software without restriction, including without limitation the rights |
|
11 |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
12 |
* copies of the Software, and to permit persons to whom the Software is |
|
13 |
* furnished to do so, subject to the following conditions: |
|
14 |
* |
|
15 |
* The above copyright notice and this permission notice shall be included in |
|
16 |
* all copies or substantial portions of the Software. |
|
17 |
* |
|
18 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
19 |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
20 |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
21 |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
22 |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
23 |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
24 |
* THE SOFTWARE. |
|
34
28f6e8b9d5d1
quaternion moved to extra header file
Radek Brich <radek.brich@devl.cz>
parents:
30
diff
changeset
|
25 |
*/ |
28f6e8b9d5d1
quaternion moved to extra header file
Radek Brich <radek.brich@devl.cz>
parents:
30
diff
changeset
|
26 |
|
7
bf17f9f84c91
kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents:
0
diff
changeset
|
27 |
#include <algorithm> |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
28 |
#include <stack> |
78
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
29 |
#include <string> |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
30 |
#include <sstream> |
7
bf17f9f84c91
kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents:
0
diff
changeset
|
31 |
|
bf17f9f84c91
kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents:
0
diff
changeset
|
32 |
#include "kdtree.h" |
78
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
33 |
#include "serialize.h" |
0
3547b885df7e
initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
34 |
|
71
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
35 |
class ShapeBound |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
36 |
{ |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
37 |
public: |
95
ca7d4c665531
build script fixes, add ldflags build option
Radek Brich <radek.brich@devl.cz>
parents:
93
diff
changeset
|
38 |
const Shape *shape; |
71
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
39 |
Float pos; |
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
40 |
bool end; |
95
ca7d4c665531
build script fixes, add ldflags build option
Radek Brich <radek.brich@devl.cz>
parents:
93
diff
changeset
|
41 |
ShapeBound(const Shape *ashape, const Float apos, const bool aend): |
71
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
42 |
shape(ashape), pos(apos), end(aend) {}; |
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
43 |
friend bool operator<(const ShapeBound& a, const ShapeBound& b) |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
44 |
{ |
71
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
45 |
if (a.pos == b.pos) |
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
46 |
return a.shape < b.shape; |
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
47 |
else |
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
48 |
return a.pos < b.pos; |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
49 |
}; |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
50 |
}; |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
51 |
|
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
52 |
// stack element for kd-tree traversal |
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
53 |
struct StackElem |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
54 |
{ |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
55 |
KdNode* node; /* pointer to far child */ |
22 | 56 |
Float t; /* the entry/exit signed distance */ |
91 | 57 |
Vector pb; /* the coordinates of entry/exit point */ |
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
58 |
int prev; |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
59 |
}; |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
60 |
|
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
61 |
// ---------------------------------------- |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
62 |
|
16
20bceb605f48
add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents:
15
diff
changeset
|
63 |
KdNode::~KdNode() |
20bceb605f48
add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents:
15
diff
changeset
|
64 |
{ |
20bceb605f48
add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents:
15
diff
changeset
|
65 |
if (isLeaf()) |
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
66 |
delete getShapes(); |
16
20bceb605f48
add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents:
15
diff
changeset
|
67 |
} |
20bceb605f48
add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents:
15
diff
changeset
|
68 |
|
103 | 69 |
const int KdTree::MAX_DEPTH = 32; |
70 |
||
71
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
71 |
// kd-tree recursive build algorithm, inspired by PBRT (www.pbrt.org) |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
72 |
void KdTree::recursive_build(KdNode *node, const BBox &bounds, int maxdepth) |
0
3547b885df7e
initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
73 |
{ |
76
3b60fd0bea64
kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents:
74
diff
changeset
|
74 |
ShapeList *shapes = node->getShapes(); |
3b60fd0bea64
kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents:
74
diff
changeset
|
75 |
|
3b60fd0bea64
kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents:
74
diff
changeset
|
76 |
if (maxdepth <= 0 || shapes->size() <= 2) |
10
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
77 |
{ |
76
3b60fd0bea64
kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents:
74
diff
changeset
|
78 |
node->setLeaf(); |
10
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
79 |
return; |
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
80 |
} |
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
81 |
|
7
bf17f9f84c91
kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents:
0
diff
changeset
|
82 |
// choose split axis |
72
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
83 |
/*axis = 0; |
71
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
84 |
if (bounds.h() > bounds.w() && bounds.h() > bounds.d()) |
7
bf17f9f84c91
kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents:
0
diff
changeset
|
85 |
axis = 1; |
71
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
86 |
if (bounds.d() > bounds.w() && bounds.d() > bounds.h()) |
7
bf17f9f84c91
kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents:
0
diff
changeset
|
87 |
axis = 2; |
72
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
88 |
*/ |
71
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
89 |
// create sorted list of shape bounds (= find all posible splits) |
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
90 |
vector<ShapeBound> edges[3]; |
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
91 |
ShapeList::iterator shape; |
76
3b60fd0bea64
kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents:
74
diff
changeset
|
92 |
for (shape = shapes->begin(); shape != shapes->end(); shape++) |
7
bf17f9f84c91
kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents:
0
diff
changeset
|
93 |
{ |
71
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
94 |
BBox shapebounds = (*shape)->get_bbox(); |
72
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
95 |
for (int ax = 0; ax < 3; ax++) |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
96 |
{ |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
97 |
edges[ax].push_back(ShapeBound(*shape, shapebounds.L[ax], 0)); |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
98 |
edges[ax].push_back(ShapeBound(*shape, shapebounds.H[ax], 1)); |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
99 |
} |
7
bf17f9f84c91
kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents:
0
diff
changeset
|
100 |
} |
72
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
101 |
for (int ax = 0; ax < 3; ax++) |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
102 |
sort(edges[ax].begin(), edges[ax].end()); |
7
bf17f9f84c91
kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents:
0
diff
changeset
|
103 |
|
bf17f9f84c91
kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents:
0
diff
changeset
|
104 |
// choose best split pos |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
105 |
const Float K = 1.4f; // constant, K = cost of traversal / cost of ray-triangle intersection |
71
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
106 |
Float SAV = (bounds.w()*bounds.h() + // surface area of node |
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
107 |
bounds.w()*bounds.d() + bounds.h()*bounds.d()); |
76
3b60fd0bea64
kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents:
74
diff
changeset
|
108 |
Float cost = SAV * (K + shapes->size()); // initial cost = non-split cost |
71
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
109 |
|
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
110 |
int axis = 0; |
104
2274a07510c1
Cleanup, dropped Windows support
Radek Brich <radek.brich@devl.cz>
parents:
103
diff
changeset
|
111 |
vector<ShapeBound>::iterator edge, splitedge = edges[axis].end(); |
72
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
112 |
for (int ax = 0; ax < 3; ax++) |
7
bf17f9f84c91
kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents:
0
diff
changeset
|
113 |
{ |
93 | 114 |
int lnum = 0, rnum = (int)shapes->size(); |
72
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
115 |
BBox lbb = bounds; |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
116 |
BBox rbb = bounds; |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
117 |
for (edge = edges[ax].begin(); edge != edges[ax].end(); edge++) |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
118 |
{ |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
119 |
if (edge->end) |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
120 |
rnum--; |
71
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
121 |
|
72
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
122 |
// calculate SAH cost of this split |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
123 |
lbb.H[ax] = edge->pos; |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
124 |
rbb.L[ax] = edge->pos; |
72
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
125 |
Float SAL = (lbb.w()*lbb.h() + lbb.w()*lbb.d() + lbb.h()*lbb.d()); |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
126 |
Float SAR = (rbb.w()*rbb.h() + rbb.w()*rbb.d() + rbb.h()*rbb.d()); |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
127 |
Float splitcost = K*SAV + SAL*(K + lnum) + SAR*(K + rnum); |
9
3239f749e394
kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents:
7
diff
changeset
|
128 |
|
72
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
129 |
if (splitcost < cost) |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
130 |
{ |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
131 |
axis = ax; |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
132 |
splitedge = edge; |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
133 |
cost = splitcost; |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
134 |
} |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
135 |
|
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
136 |
if (!edge->end) |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
137 |
lnum++; |
9
3239f749e394
kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents:
7
diff
changeset
|
138 |
} |
7
bf17f9f84c91
kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents:
0
diff
changeset
|
139 |
} |
0
3547b885df7e
initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
140 |
|
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
141 |
if (splitedge == edges[axis].end()) |
15
a0a3e334744f
C++ demos: prepare infrastructure, add spheres_shadow.cc
Radek Brich <radek.brich@devl.cz>
parents:
14
diff
changeset
|
142 |
{ |
76
3b60fd0bea64
kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents:
74
diff
changeset
|
143 |
node->setLeaf(); |
9
3239f749e394
kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents:
7
diff
changeset
|
144 |
return; |
15
a0a3e334744f
C++ demos: prepare infrastructure, add spheres_shadow.cc
Radek Brich <radek.brich@devl.cz>
parents:
14
diff
changeset
|
145 |
} |
9
3239f749e394
kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents:
7
diff
changeset
|
146 |
|
76
3b60fd0bea64
kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents:
74
diff
changeset
|
147 |
node->setSplit(splitedge->pos); |
3b60fd0bea64
kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents:
74
diff
changeset
|
148 |
|
29
574c34441a1c
new C++ demo: realtime_bunny
Radek Brich <radek.brich@devl.cz>
parents:
28
diff
changeset
|
149 |
#if 0 |
10
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
150 |
// export kd-tree as .obj for visualization |
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
151 |
// this would be hard to reconstruct later |
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
152 |
static ofstream F("kdtree.obj"); |
91 | 153 |
Vector v; |
10
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
154 |
static int f=0; |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
155 |
v[axis] = node->getSplit(); |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
156 |
v[(axis+1)%3] = bounds.L[(axis+1)%3]; |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
157 |
v[(axis+2)%3] = bounds.L[(axis+2)%3]; |
10
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
158 |
F << "v " << v.x << " " << v.y << " " << v.z << endl; |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
159 |
v[(axis+1)%3] = bounds.L[(axis+1)%3]; |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
160 |
v[(axis+2)%3] = bounds.H[(axis+2)%3]; |
10
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
161 |
F << "v " << v.x << " " << v.y << " " << v.z << endl; |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
162 |
v[(axis+1)%3] = bounds.H[(axis+1)%3]; |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
163 |
v[(axis+2)%3] = bounds.H[(axis+2)%3]; |
10
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
164 |
F << "v " << v.x << " " << v.y << " " << v.z << endl; |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
165 |
v[(axis+1)%3] = bounds.H[(axis+1)%3]; |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
166 |
v[(axis+2)%3] = bounds.L[(axis+2)%3]; |
10
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
167 |
F << "v " << v.x << " " << v.y << " " << v.z << endl; |
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
168 |
F << "f " << f+1 << " " << f+2 << " " << f+3 << " " << f+4 << endl; |
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
169 |
f += 4; |
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
170 |
#endif |
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
171 |
|
9
3239f749e394
kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents:
7
diff
changeset
|
172 |
// split this node |
76
3b60fd0bea64
kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents:
74
diff
changeset
|
173 |
delete shapes; |
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
174 |
|
72
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
175 |
BBox lbb = bounds; |
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
176 |
BBox rbb = bounds; |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
177 |
lbb.H[axis] = node->getSplit(); |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
178 |
rbb.L[axis] = node->getSplit(); |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
179 |
node->setChildren(new (mempool.alloc()) KdNode); |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
180 |
new (mempool.alloc()) KdNode; |
76
3b60fd0bea64
kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents:
74
diff
changeset
|
181 |
node->setAxis(axis); |
72
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
182 |
|
71
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
183 |
for (edge = edges[axis].begin(); edge != splitedge; edge++) |
72
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
184 |
if (!edge->end && edge->shape->intersect_bbox(lbb)) |
76
3b60fd0bea64
kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents:
74
diff
changeset
|
185 |
node->getLeftChild()->addShape(edge->shape); |
71
4fedf7290929
simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents:
44
diff
changeset
|
186 |
for (edge = splitedge; edge < edges[axis].end(); edge++) |
72
7c3f38dff082
kd-tree building - check all axes for best split, add additional shape-bbox check
Radek Brich <radek.brich@devl.cz>
parents:
71
diff
changeset
|
187 |
if (edge->end && edge->shape->intersect_bbox(rbb)) |
76
3b60fd0bea64
kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents:
74
diff
changeset
|
188 |
node->getRightChild()->addShape(edge->shape); |
9
3239f749e394
kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents:
7
diff
changeset
|
189 |
|
76
3b60fd0bea64
kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents:
74
diff
changeset
|
190 |
recursive_build(node->getLeftChild(), lbb, maxdepth-1); |
3b60fd0bea64
kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents:
74
diff
changeset
|
191 |
recursive_build(node->getRightChild(), rbb, maxdepth-1); |
0
3547b885df7e
initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
192 |
} |
3547b885df7e
initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
193 |
|
11
4d192e13ee84
move nearest_intersection() to Container, add dummy KdTree.load(), plus small fixes
Radek Brich <radek.brich@devl.cz>
parents:
10
diff
changeset
|
194 |
void KdTree::build() |
0
3547b885df7e
initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
195 |
{ |
30
33f95441790e
pyrit_verbosity: new variable for controlling amount of output, see common.h
Radek Brich <radek.brich@devl.cz>
parents:
29
diff
changeset
|
196 |
dbgmsg(1, "* building kd-tree\n"); |
7
bf17f9f84c91
kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents:
0
diff
changeset
|
197 |
root = new KdNode(); |
17
5176ba000a67
fix last leak as reported by valgrind
Radek Brich <radek.brich@devl.cz>
parents:
16
diff
changeset
|
198 |
ShapeList::iterator shape; |
5176ba000a67
fix last leak as reported by valgrind
Radek Brich <radek.brich@devl.cz>
parents:
16
diff
changeset
|
199 |
for (shape = shapes.begin(); shape != shapes.end(); shape++) |
5176ba000a67
fix last leak as reported by valgrind
Radek Brich <radek.brich@devl.cz>
parents:
16
diff
changeset
|
200 |
root->addShape(*shape); |
103 | 201 |
recursive_build(root, bbox, MAX_DEPTH); |
10
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
202 |
built = true; |
0
3547b885df7e
initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff
changeset
|
203 |
} |
10
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
204 |
|
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
205 |
/* algorithm by Vlastimil Havran, Heuristic Ray Shooting Algorithms, appendix C */ |
95
ca7d4c665531
build script fixes, add ldflags build option
Radek Brich <radek.brich@devl.cz>
parents:
93
diff
changeset
|
206 |
const Shape *KdTree::nearest_intersection(const Shape *origin_shape, const Ray &ray, |
22 | 207 |
Float &nearest_distance) |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
208 |
{ |
22 | 209 |
Float a, b; /* entry/exit signed distance */ |
210 |
Float t; /* signed distance to the splitting plane */ |
|
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
211 |
|
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
212 |
/* if we have no tree, fall back to naive test */ |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
213 |
if (!built) |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
214 |
return Container::nearest_intersection(origin_shape, ray, nearest_distance); |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
215 |
|
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
216 |
if (!bbox.intersect(ray, a, b)) |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
217 |
return NULL; |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
218 |
|
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
219 |
/* pointers to the far child node and current node */ |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
220 |
KdNode *farchild, *node; |
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
221 |
node = root; |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
222 |
|
103 | 223 |
StackElem stack[MAX_DEPTH]; |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
224 |
|
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
225 |
int entry = 0, exit = 1; |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
226 |
stack[entry].t = a; |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
227 |
|
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
228 |
/* distinguish between internal and external origin of a ray*/ |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
229 |
if (a >= 0.0) |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
230 |
stack[entry].pb = ray.o + ray.dir * a; /* external */ |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
231 |
else |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
232 |
stack[entry].pb = ray.o; /* internal */ |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
233 |
|
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
234 |
/* setup initial exit point in the stack */ |
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
235 |
stack[exit].t = b; |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
236 |
stack[exit].pb = ray.o + ray.dir * b; |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
237 |
stack[exit].node = NULL; |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
238 |
|
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
239 |
/* loop, traverse through the whole kd-tree, until an object is intersected or ray leaves the scene */ |
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
240 |
Float splitVal; |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
241 |
int axis; |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
242 |
static const int mod3[] = {0,1,2,0,1}; |
91 | 243 |
const Vector invdir = 1 / ray.dir; |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
244 |
while (node) |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
245 |
{ |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
246 |
/* loop until a leaf is found */ |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
247 |
while (!node->isLeaf()) |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
248 |
{ |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
249 |
/* retrieve position of splitting plane */ |
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
250 |
splitVal = node->getSplit(); |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
251 |
axis = node->getAxis(); |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
252 |
|
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
253 |
if (stack[entry].pb[axis] <= splitVal) |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
254 |
{ |
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
255 |
if (stack[exit].pb[axis] <= splitVal) |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
256 |
{ /* case N1, N2, N3, P5, Z2, and Z3 */ |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
257 |
node = node->getLeftChild(); |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
258 |
continue; |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
259 |
} |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
260 |
if (stack[entry].pb[axis] == splitVal) |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
261 |
{ /* case Z1 */ |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
262 |
node = node->getRightChild(); |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
263 |
continue; |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
264 |
} |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
265 |
/* case N4 */ |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
266 |
farchild = node->getRightChild(); |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
267 |
node = node->getLeftChild(); |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
268 |
} |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
269 |
else |
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
270 |
{ /* (stack[entry].pb[axis] > splitVal) */ |
78
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
271 |
if (stack[exit].pb[axis] > splitVal) |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
272 |
{ |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
273 |
/* case P1, P2, P3, and N5 */ |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
274 |
node = node->getRightChild(); |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
275 |
continue; |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
276 |
} |
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
277 |
/* case P4 */ |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
278 |
farchild = node->getLeftChild(); |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
279 |
node = node->getRightChild(); |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
280 |
} |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
281 |
|
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
282 |
/* case P4 or N4 . . . traverse both children */ |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
283 |
|
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
284 |
/* signed distance to the splitting plane */ |
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
285 |
t = (splitVal - ray.o[axis]) * invdir[axis]; |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
286 |
|
16
20bceb605f48
add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents:
15
diff
changeset
|
287 |
/* setup the new exit point and push it onto stack */ |
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
288 |
register int tmp = exit; |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
289 |
|
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
290 |
exit++; |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
291 |
if (exit == entry) |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
292 |
exit++; |
103 | 293 |
assert(exit < MAX_DEPTH); |
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
294 |
|
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
295 |
stack[exit].prev = tmp; |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
296 |
stack[exit].t = t; |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
297 |
stack[exit].node = farchild; |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
298 |
stack[exit].pb[axis] = splitVal; |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
299 |
stack[exit].pb[mod3[axis+1]] = ray.o[mod3[axis+1]] |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
300 |
+ t * ray.dir[mod3[axis+1]]; |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
301 |
stack[exit].pb[mod3[axis+2]] = ray.o[mod3[axis+2]] |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
302 |
+ t * ray.dir[mod3[axis+2]]; |
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
303 |
} |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
304 |
|
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
305 |
/* current node is the leaf . . . empty or full */ |
95
ca7d4c665531
build script fixes, add ldflags build option
Radek Brich <radek.brich@devl.cz>
parents:
93
diff
changeset
|
306 |
const Shape *nearest_shape = NULL; |
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
307 |
Float dist = stack[exit].t; |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
308 |
ShapeList::iterator shape; |
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
309 |
for (shape = node->getShapes()->begin(); shape != node->getShapes()->end(); shape++) |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
310 |
if (*shape != origin_shape && (*shape)->intersect(ray, dist) |
78
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
311 |
&& dist >= stack[entry].t - Eps) |
35
fb170fccb19f
new space partitioning structure: octree
Radek Brich <radek.brich@devl.cz>
parents:
34
diff
changeset
|
312 |
{ |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
313 |
nearest_shape = *shape; |
35
fb170fccb19f
new space partitioning structure: octree
Radek Brich <radek.brich@devl.cz>
parents:
34
diff
changeset
|
314 |
nearest_distance = dist; |
fb170fccb19f
new space partitioning structure: octree
Radek Brich <radek.brich@devl.cz>
parents:
34
diff
changeset
|
315 |
} |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
316 |
|
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
317 |
if (nearest_shape) |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
318 |
return nearest_shape; |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
319 |
|
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
320 |
entry = exit; |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
321 |
|
74
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
322 |
/* retrieve the pointer to the next node, |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
323 |
it is possible that ray traversal terminates */ |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
324 |
node = stack[entry].node; |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
325 |
exit = stack[entry].prev; |
09aedbf5f95f
kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents:
72
diff
changeset
|
326 |
} |
14
fc18ac4833f2
replace Plane with axis-aligned Box (because infinite Plane is not usable with kd-tree)
Radek Brich <radek.brich@devl.cz>
parents:
13
diff
changeset
|
327 |
|
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
328 |
/* ray leaves the scene */ |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
329 |
return NULL; |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
330 |
} |
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
331 |
|
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
332 |
#ifndef NO_SIMD |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
333 |
// stack element for kd-tree traversal (packet version) |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
334 |
struct StackElem4 |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
335 |
{ |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
336 |
KdNode* node; /* pointer to far child */ |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
337 |
mfloat4 t; /* the entry/exit signed distance */ |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
338 |
VectorPacket pb; /* the coordinates of entry/exit point */ |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
339 |
int prev; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
340 |
}; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
341 |
|
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
342 |
void KdTree::packet_intersection(const Shape* const* origin_shapes, const RayPacket &rays, |
95
ca7d4c665531
build script fixes, add ldflags build option
Radek Brich <radek.brich@devl.cz>
parents:
93
diff
changeset
|
343 |
Float *nearest_distances, const Shape **nearest_shapes) |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
344 |
{ |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
345 |
mfloat4 a, b; /* entry/exit signed distance */ |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
346 |
mfloat4 t; /* signed distance to the splitting plane */ |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
347 |
mfloat4 mask = mZero; |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
348 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
349 |
/* if we have no tree, fall back to naive test */ |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
350 |
if (!built) |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
351 |
Container::packet_intersection(origin_shapes, rays, nearest_distances, nearest_shapes); |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
352 |
|
86
ce6abe0aeeae
BBox - RayPacket intersection
Radek Brich <radek.brich@devl.cz>
parents:
85
diff
changeset
|
353 |
// nearest_shapes[0..4] = NULL |
ce6abe0aeeae
BBox - RayPacket intersection
Radek Brich <radek.brich@devl.cz>
parents:
85
diff
changeset
|
354 |
memset(nearest_shapes, 0, 4*sizeof(Shape*)); |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
355 |
|
86
ce6abe0aeeae
BBox - RayPacket intersection
Radek Brich <radek.brich@devl.cz>
parents:
85
diff
changeset
|
356 |
mask = bbox.intersect_packet(rays, a, b); |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
357 |
if (!mmovemask(mask)) |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
358 |
return; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
359 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
360 |
/* pointers to the far child node and current node */ |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
361 |
KdNode *farchild, *node; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
362 |
node = root; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
363 |
|
103 | 364 |
StackElem4 stack[MAX_DEPTH]; |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
365 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
366 |
int entry = 0, exit = 1; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
367 |
stack[entry].t = a; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
368 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
369 |
/* distinguish between internal and external origin of a ray*/ |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
370 |
t = mcmplt(a, mZero); |
87
1081e3dd3f3e
Sphere, Box - RayPacket intersection
Radek Brich <radek.brich@devl.cz>
parents:
86
diff
changeset
|
371 |
stack[entry].pb = rays.o + rays.dir * a; |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
372 |
stack[entry].pb.mx = mselect(t, rays.o.mx, stack[entry].pb.mx); |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
373 |
stack[entry].pb.my = mselect(t, rays.o.my, stack[entry].pb.my); |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
374 |
stack[entry].pb.mz = mselect(t, rays.o.mz, stack[entry].pb.mz); |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
375 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
376 |
/* setup initial exit point in the stack */ |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
377 |
stack[exit].t = b; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
378 |
stack[exit].pb = rays.o + rays.dir * b; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
379 |
stack[exit].node = NULL; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
380 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
381 |
/* loop, traverse through the whole kd-tree, |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
382 |
until an object is intersected or ray leaves the scene */ |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
383 |
mfloat4 splitVal; |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
384 |
int axis; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
385 |
static const int mod3[] = {0,1,2,0,1}; |
86
ce6abe0aeeae
BBox - RayPacket intersection
Radek Brich <radek.brich@devl.cz>
parents:
85
diff
changeset
|
386 |
const VectorPacket invdirs = mOne / rays.dir; |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
387 |
while (node) |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
388 |
{ |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
389 |
/* loop until a leaf is found */ |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
390 |
while (!node->isLeaf()) |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
391 |
{ |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
392 |
/* retrieve position of splitting plane */ |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
393 |
splitVal = mset1(node->getSplit()); |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
394 |
axis = node->getAxis(); |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
395 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
396 |
// mask out invalid rays with near > far |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
397 |
const mfloat4 curmask = mand(mask, mcmple(stack[entry].t, stack[exit].t)); |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
398 |
const mfloat4 entry_lt = mcmplt(stack[entry].pb.ma[axis], splitVal); |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
399 |
const mfloat4 entry_gt = mcmpgt(stack[entry].pb.ma[axis], splitVal); |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
400 |
const mfloat4 exit_lt = mcmplt(stack[exit].pb.ma[axis], splitVal); |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
401 |
const mfloat4 exit_gt = mcmpgt(stack[exit].pb.ma[axis], splitVal); |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
402 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
403 |
// if all of |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
404 |
// stack[entry].pb[axis] <= splitVal, |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
405 |
// stack[exit].pb[axis] <= splitVal |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
406 |
if (!mmovemask( |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
407 |
mand(mor(entry_gt, exit_gt), curmask))) |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
408 |
{ |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
409 |
node = node->getLeftChild(); |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
410 |
continue; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
411 |
} |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
412 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
413 |
// if all of |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
414 |
// stack[entry].pb[axis] >= splitVal, |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
415 |
// stack[exit].pb[axis] >= splitVal |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
416 |
if (!mmovemask( |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
417 |
mand(mor(entry_lt, exit_lt), curmask))) |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
418 |
{ |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
419 |
node = node->getRightChild(); |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
420 |
continue; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
421 |
} |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
422 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
423 |
// any of |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
424 |
// stack[entry].pb[axis] < splitVal, |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
425 |
// stack[exit].pb[axis] > splitVal |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
426 |
int cond1 = mmovemask( |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
427 |
mand(mand(entry_lt, exit_gt), curmask)); |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
428 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
429 |
// any of |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
430 |
// stack[entry].pb[axis] > splitVal, |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
431 |
// stack[exit].pb[axis] < splitVal |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
432 |
int cond2 = mmovemask( |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
433 |
mand(mand(entry_gt, exit_lt), curmask)); |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
434 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
435 |
if ((!cond1 && !cond2) || (cond1 && cond2)) |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
436 |
{ |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
437 |
// fall back to single rays |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
438 |
// FIXME: split rays and continue |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
439 |
for (int i = 0; i < 4; i++) |
85
907a634e5c02
implement triangle packet intersection
Radek Brich <radek.brich@devl.cz>
parents:
84
diff
changeset
|
440 |
if (!nearest_shapes[i]) |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
441 |
nearest_shapes[i] = nearest_intersection(origin_shapes[i], |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
442 |
rays[i], nearest_distances[i]); |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
443 |
return; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
444 |
} |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
445 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
446 |
if (cond1) |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
447 |
{ |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
448 |
farchild = node->getRightChild(); |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
449 |
node = node->getLeftChild(); |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
450 |
} |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
451 |
else |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
452 |
{ |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
453 |
farchild = node->getLeftChild(); |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
454 |
node = node->getRightChild(); |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
455 |
} |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
456 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
457 |
/* traverse both children */ |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
458 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
459 |
/* signed distance to the splitting plane */ |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
460 |
t = mmul(msub(splitVal, rays.o.ma[axis]), invdirs.ma[axis]); |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
461 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
462 |
/* setup the new exit point and push it onto stack */ |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
463 |
register int tmp = exit; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
464 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
465 |
exit++; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
466 |
if (exit == entry) |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
467 |
exit++; |
103 | 468 |
assert(exit < MAX_DEPTH); |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
469 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
470 |
stack[exit].prev = tmp; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
471 |
stack[exit].t = t; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
472 |
stack[exit].node = farchild; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
473 |
stack[exit].pb.ma[axis] = splitVal; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
474 |
stack[exit].pb.ma[mod3[axis+1]] = |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
475 |
madd(rays.o.ma[mod3[axis+1]], mmul(t, rays.dir.ma[mod3[axis+1]])); |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
476 |
stack[exit].pb.ma[mod3[axis+2]] = |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
477 |
madd(rays.o.ma[mod3[axis+2]], mmul(t, rays.dir.ma[mod3[axis+2]])); |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
478 |
} |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
479 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
480 |
/* current node is the leaf . . . empty or full */ |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
481 |
mfloat4 dists = stack[exit].t; |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
482 |
ShapeList::iterator shape; |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
483 |
mfloat4 results; |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
484 |
mfloat4 newmask = mask; |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
485 |
for (shape = node->getShapes()->begin(); shape != node->getShapes()->end(); shape++) |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
486 |
{ |
85
907a634e5c02
implement triangle packet intersection
Radek Brich <radek.brich@devl.cz>
parents:
84
diff
changeset
|
487 |
results = (*shape)->intersect_packet(rays, dists); |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
488 |
int valid = mmovemask( |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
489 |
mand(mask, mand(results, |
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
490 |
mcmpge(dists, msub(stack[entry].t, mEps))))); |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
491 |
for (int i = 0; i < 4; i++) |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
492 |
{ |
85
907a634e5c02
implement triangle packet intersection
Radek Brich <radek.brich@devl.cz>
parents:
84
diff
changeset
|
493 |
if (*shape != origin_shapes[i] && ((valid>>i)&1)) |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
494 |
{ |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
495 |
nearest_shapes[i] = *shape; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
496 |
nearest_distances[i] = ((float*)&dists)[i]; |
86
ce6abe0aeeae
BBox - RayPacket intersection
Radek Brich <radek.brich@devl.cz>
parents:
85
diff
changeset
|
497 |
((int*)&newmask)[i] = 0; |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
498 |
} |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
499 |
} |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
500 |
} |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
501 |
|
86
ce6abe0aeeae
BBox - RayPacket intersection
Radek Brich <radek.brich@devl.cz>
parents:
85
diff
changeset
|
502 |
mask = newmask; |
92
9af5c039b678
add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents:
91
diff
changeset
|
503 |
if (!mmovemask(mask)) |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
504 |
return; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
505 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
506 |
entry = exit; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
507 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
508 |
/* retrieve the pointer to the next node, |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
509 |
it is possible that ray traversal terminates */ |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
510 |
node = stack[entry].node; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
511 |
exit = stack[entry].prev; |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
512 |
} |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
513 |
|
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
514 |
/* ray leaves the scene */ |
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
515 |
} |
91 | 516 |
#endif |
84
6f7fe14782c2
prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents:
80
diff
changeset
|
517 |
|
78
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
518 |
ostream & operator<<(ostream &st, KdNode &node) |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
519 |
{ |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
520 |
if (node.isLeaf()) |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
521 |
{ |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
522 |
st << "(l," << node.getShapes()->size(); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
523 |
ShapeList::iterator shape; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
524 |
for (shape = node.getShapes()->begin(); shape != node.getShapes()->end(); shape++) |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
525 |
st << "," << shape_index[*shape]; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
526 |
st << ")"; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
527 |
} |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
528 |
else |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
529 |
{ |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
530 |
st << "(s," << (char)('x'+node.getAxis()) << "," << node.getSplit() << ","; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
531 |
st << *node.getLeftChild() << ","; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
532 |
st << *node.getRightChild() << ")"; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
533 |
} |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
534 |
return st; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
535 |
} |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
536 |
|
95
ca7d4c665531
build script fixes, add ldflags build option
Radek Brich <radek.brich@devl.cz>
parents:
93
diff
changeset
|
537 |
ostream & KdTree::dump(ostream &st) const |
10
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
538 |
{ |
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
539 |
if (!built) |
78
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
540 |
return Container::dump(st); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
541 |
|
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
542 |
st << "(kdtree," << shapes.size(); |
95
ca7d4c665531
build script fixes, add ldflags build option
Radek Brich <radek.brich@devl.cz>
parents:
93
diff
changeset
|
543 |
ShapeList::const_iterator shape; |
78
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
544 |
for (shape = shapes.begin(); shape != shapes.end(); shape++) |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
545 |
{ |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
546 |
int idx; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
547 |
if (!shape_index.get(*shape, idx)) |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
548 |
st << "," << endl << **shape; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
549 |
} |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
550 |
return st << "," << endl << *getRootNode() << ")"; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
551 |
} |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
552 |
|
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
553 |
void KdTree::recursive_load(istream &st, KdNode *node) |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
554 |
{ |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
555 |
string s; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
556 |
|
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
557 |
getline(st, s, ','); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
558 |
trim(s); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
559 |
|
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
560 |
if (s.compare("(s") == 0) |
10
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
561 |
{ |
78
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
562 |
// split |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
563 |
int axis; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
564 |
Float split; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
565 |
|
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
566 |
delete node->getShapes(); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
567 |
node->setChildren(new KdNode[2]); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
568 |
|
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
569 |
getline(st, s, ','); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
570 |
axis = s.c_str()[0]-'x'; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
571 |
node->setAxis(axis); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
572 |
|
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
573 |
st >> split; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
574 |
getline(st, s, ','); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
575 |
node->setSplit(split); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
576 |
|
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
577 |
recursive_load(st, node->getLeftChild()); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
578 |
getline(st, s, ','); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
579 |
recursive_load(st, node->getRightChild()); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
580 |
getline(st, s, ')'); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
581 |
} |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
582 |
|
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
583 |
if (s.compare("(l") == 0) |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
584 |
{ |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
585 |
// leaf |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
586 |
int count, idx; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
587 |
|
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
588 |
node->setLeaf(); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
589 |
|
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
590 |
st >> count; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
591 |
for (int i = 0; i < count; i++) |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
592 |
{ |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
593 |
getline(st, s, ','); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
594 |
st >> idx; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
595 |
node->addShape(shapes[idx]); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
596 |
} |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
597 |
getline(st, s, ')'); |
10
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
598 |
} |
f9fad94cd0cc
kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents:
9
diff
changeset
|
599 |
} |
11
4d192e13ee84
move nearest_intersection() to Container, add dummy KdTree.load(), plus small fixes
Radek Brich <radek.brich@devl.cz>
parents:
10
diff
changeset
|
600 |
|
80
907929fa9b59
remove forgotten noise.h includes
Radek Brich <radek.brich@devl.cz>
parents:
78
diff
changeset
|
601 |
istream & KdTree::load(istream &st, Material *mat) |
11
4d192e13ee84
move nearest_intersection() to Container, add dummy KdTree.load(), plus small fixes
Radek Brich <radek.brich@devl.cz>
parents:
10
diff
changeset
|
602 |
{ |
78
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
603 |
string s; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
604 |
istringstream is; |
12
f4fcabf05785
kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents:
11
diff
changeset
|
605 |
|
78
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
606 |
getline(st, s, ','); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
607 |
if (s.compare("(kdtree") != 0) |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
608 |
return st; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
609 |
|
80
907929fa9b59
remove forgotten noise.h includes
Radek Brich <radek.brich@devl.cz>
parents:
78
diff
changeset
|
610 |
dbgmsg(1, "* loading kd-tree\n"); |
907929fa9b59
remove forgotten noise.h includes
Radek Brich <radek.brich@devl.cz>
parents:
78
diff
changeset
|
611 |
|
78
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
612 |
shapes.clear(); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
613 |
if (root) delete root; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
614 |
root = new KdNode(); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
615 |
|
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
616 |
getline(st, s, ','); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
617 |
int shape_count; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
618 |
is.str(s); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
619 |
is >> shape_count; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
620 |
|
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
621 |
Shape *shape; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
622 |
for (int i = 0; i < shape_count; i++) |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
623 |
{ |
80
907929fa9b59
remove forgotten noise.h includes
Radek Brich <radek.brich@devl.cz>
parents:
78
diff
changeset
|
624 |
shape = loadShape(st, mat); |
78
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
625 |
Container::addShape(shape); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
626 |
getline(st, s, ','); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
627 |
} |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
628 |
|
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
629 |
recursive_load(st, root); |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
630 |
|
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
631 |
built = true; |
9569e9f35374
move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents:
76
diff
changeset
|
632 |
return st; |
11
4d192e13ee84
move nearest_intersection() to Container, add dummy KdTree.load(), plus small fixes
Radek Brich <radek.brich@devl.cz>
parents:
10
diff
changeset
|
633 |
} |