src/kdtree.cc
author Radek Brich <radek.brich@devl.cz>
Sat, 10 May 2008 14:29:37 +0200
branchpyrit
changeset 95 ca7d4c665531
parent 93 96d65f841791
child 103 3b3257a410fe
permissions -rw-r--r--
build script fixes, add ldflags build option update and enhance demos fix bug in 4x grid oversampling warn if writePNG called while compiled without libpng make shapes in ShapeList const and add many other const needed due to snowball effect slightly optimize Camera::makeRayPacket using _mm_shuffle_ps make Vector SIMD vectorization disabled by default (causes problems) fix bug in implicit reflection of transmissive surfaces, when surface's reflection parameter is set to zero
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
34
28f6e8b9d5d1 quaternion moved to extra header file
Radek Brich <radek.brich@devl.cz>
parents: 30
diff changeset
     1
/*
44
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
     2
 * kdtree.cc: KdTree class
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
     3
 *
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
     4
 * This file is part of Pyrit Ray Tracer.
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
     5
 *
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 87
diff changeset
     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
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
     8
 * Permission is hereby granted, free of charge, to any person obtaining a copy
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
     9
 * of this software and associated documentation files (the "Software"), to deal
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    10
 * in the Software without restriction, including without limitation the rights
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    11
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    12
 * copies of the Software, and to permit persons to whom the Software is
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    13
 * furnished to do so, subject to the following conditions:
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    14
 *
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    15
 * The above copyright notice and this permission notice shall be included in
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    16
 * all copies or substantial portions of the Software.
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    17
 *
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    23
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    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
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    56
	Float t; /* the entry/exit signed distance */
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 87
diff changeset
    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
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
    69
// 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
    70
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
    71
{
76
3b60fd0bea64 kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents: 74
diff changeset
    72
	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
    73
3b60fd0bea64 kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents: 74
diff changeset
    74
	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
    75
	{
76
3b60fd0bea64 kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents: 74
diff changeset
    76
		node->setLeaf();
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
    77
		return;
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
    78
	}
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
    79
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    80
	// 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
    81
	/*axis = 0;
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
    82
	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
    83
		axis = 1;
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.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
    85
		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
    86
*/
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
    87
	// 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
    88
	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
    89
	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
    90
	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
    91
	{
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
    92
		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
    93
		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
    94
		{
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
			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
    96
			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
    97
		}
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    98
	}
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
    99
	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
   100
		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
   101
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   102
	// 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
   103
	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
   104
	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
   105
		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
   106
	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
   107
92
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   108
	vector<ShapeBound>::iterator edge, splitedge = edges[0].end();
74
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   109
	int axis = 0;
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
   110
	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
   111
	{
93
96d65f841791 more build script tuning
Radek Brich <radek.brich@devl.cz>
parents: 92
diff changeset
   112
		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
   113
		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
   114
		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
   115
		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
   116
		{
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
			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
   118
				rnum--;
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   119
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
   120
			// 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
   121
			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
   122
			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
   123
			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
   124
			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
   125
			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
   126
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
   127
			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
   128
			{
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
				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
   130
				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
   131
				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
   132
			}
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
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
			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
   135
				lnum++;
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   136
		}
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   137
	}
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
   138
92
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   139
	// we actually need to compare with edges[0].end(), but
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   140
	// MSVC does not allow comparison of iterators from differen instances of vector
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   141
	// it's OK this way, because axis will be zero if no good split was found
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   142
	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
   143
	{
76
3b60fd0bea64 kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents: 74
diff changeset
   144
		node->setLeaf();
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   145
		return;
15
a0a3e334744f C++ demos: prepare infrastructure, add spheres_shadow.cc
Radek Brich <radek.brich@devl.cz>
parents: 14
diff changeset
   146
	}
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   147
76
3b60fd0bea64 kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents: 74
diff changeset
   148
	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
   149
29
574c34441a1c new C++ demo: realtime_bunny
Radek Brich <radek.brich@devl.cz>
parents: 28
diff changeset
   150
#if 0
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   151
// 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
   152
// 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
   153
	static ofstream F("kdtree.obj");
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 87
diff changeset
   154
	Vector v;
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   155
	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
   156
	v[axis] = node->getSplit();
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   157
	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
   158
	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
   159
	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
   160
	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
   161
	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
   162
	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
   163
	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
   164
	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
   165
	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
   166
	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
   167
	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
   168
	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
   169
	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
   170
	f += 4;
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   171
#endif
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   172
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   173
	// 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
   174
	delete shapes;
74
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   175
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
   176
	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
   177
	BBox rbb = bounds;
92
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   178
	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
   179
	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
   180
	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
   181
	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
   182
	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
   183
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   184
	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
   185
		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
   186
			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
   187
	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
   188
		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
   189
			node->getRightChild()->addShape(edge->shape);
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   190
76
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->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
   192
	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
   193
}
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   194
11
4d192e13ee84 move nearest_intersection() to Container, add dummy KdTree.load(), plus small fixes
Radek Brich <radek.brich@devl.cz>
parents: 10
diff changeset
   195
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
   196
{
30
33f95441790e pyrit_verbosity: new variable for controlling amount of output, see common.h
Radek Brich <radek.brich@devl.cz>
parents: 29
diff changeset
   197
	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
   198
	root = new KdNode();
17
5176ba000a67 fix last leak as reported by valgrind
Radek Brich <radek.brich@devl.cz>
parents: 16
diff changeset
   199
	ShapeList::iterator shape;
5176ba000a67 fix last leak as reported by valgrind
Radek Brich <radek.brich@devl.cz>
parents: 16
diff changeset
   200
	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
   201
		root->addShape(*shape);
76
3b60fd0bea64 kd-tree: move recursive build subroutine from KdNode to KdTree
Radek Brich <radek.brich@devl.cz>
parents: 74
diff changeset
   202
	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
   203
	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
   204
}
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   205
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   206
/* 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
   207
const Shape *KdTree::nearest_intersection(const Shape *origin_shape, const Ray &ray,
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   208
	Float &nearest_distance)
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   209
{
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   210
	Float a, b; /* entry/exit signed distance */
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   211
	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
   212
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   213
	/* 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
   214
	if (!built)
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   215
		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
   216
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   217
	if (!bbox.intersect(ray, a, b))
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   218
		return NULL;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   219
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   220
	/* 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
   221
	KdNode *farchild, *node;
74
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   222
	node = root;
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   223
92
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   224
#ifdef MSVC
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   225
	// MSVC wants constant expression here... hope it won't overflow :)
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   226
	StackElem stack[64];
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   227
#else
74
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   228
	StackElem stack[max_depth];
92
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   229
#endif
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   230
74
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   231
	int entry = 0, exit = 1;
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   232
	stack[entry].t = a;
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   233
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   234
	/* 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
   235
	if (a >= 0.0)
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   236
		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
   237
	else
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   238
		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
   239
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   240
	/* 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
   241
	stack[exit].t = b;
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   242
	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
   243
	stack[exit].node = NULL;
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   244
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   245
	/* 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
   246
	Float splitVal;
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   247
	int axis;
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   248
	static const int mod3[] = {0,1,2,0,1};
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 87
diff changeset
   249
	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
   250
	while (node)
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   251
	{
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   252
		/* loop until a leaf is found */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   253
		while (!node->isLeaf())
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   254
		{
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   255
			/* retrieve position of splitting plane */
74
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   256
			splitVal = node->getSplit();
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   257
			axis = node->getAxis();
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   258
74
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   259
			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
   260
			{
74
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   261
				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
   262
				{ /* 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
   263
					node = node->getLeftChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   264
					continue;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   265
				}
84
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   266
				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
   267
				{ /* case Z1 */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   268
					node = node->getRightChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   269
					continue;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   270
				}
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   271
				/* case N4 */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   272
				farchild = node->getRightChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   273
				node = node->getLeftChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   274
			}
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   275
			else
74
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   276
			{ /* (stack[entry].pb[axis] > splitVal) */
78
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   277
				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
   278
				{
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   279
					/* case P1, P2, P3, and N5 */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   280
					node = node->getRightChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   281
					continue;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   282
				}
74
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   283
				/* case P4 */
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   284
				farchild = node->getLeftChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   285
				node = node->getRightChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   286
			}
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   287
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   288
			/* 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
   289
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   290
			/* 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
   291
			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
   292
16
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
   293
			/* 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
   294
			register int tmp = exit;
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   295
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   296
			exit++;
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   297
			if (exit == entry)
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   298
				exit++;
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   299
			assert(exit < max_depth);
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   300
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   301
			stack[exit].prev = tmp;
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   302
			stack[exit].t = t;
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   303
			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
   304
			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
   305
			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
   306
				+ 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
   307
			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
   308
				+ 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
   309
		}
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   310
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   311
		/* 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
   312
		const Shape *nearest_shape = NULL;
74
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   313
		Float dist = stack[exit].t;
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   314
		ShapeList::iterator shape;
74
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   315
		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
   316
			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
   317
			&& dist >= stack[entry].t - Eps)
35
fb170fccb19f new space partitioning structure: octree
Radek Brich <radek.brich@devl.cz>
parents: 34
diff changeset
   318
			{
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   319
				nearest_shape = *shape;
35
fb170fccb19f new space partitioning structure: octree
Radek Brich <radek.brich@devl.cz>
parents: 34
diff changeset
   320
				nearest_distance = dist;
fb170fccb19f new space partitioning structure: octree
Radek Brich <radek.brich@devl.cz>
parents: 34
diff changeset
   321
			}
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   322
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   323
		if (nearest_shape)
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   324
			return nearest_shape;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   325
74
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   326
		entry = exit;
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   327
74
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   328
		/* 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
   329
		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
   330
		node = stack[entry].node;
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   331
		exit = stack[entry].prev;
09aedbf5f95f kd-tree traversal - avoid dynamic memory allocation
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   332
	}
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
   333
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   334
	/* ray leaves the scene */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   335
	return NULL;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   336
}
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   337
92
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   338
#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
   339
// 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
   340
struct StackElem4
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   341
{
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   342
	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
   343
	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
   344
	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
   345
	int prev;
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   346
};
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   347
92
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   348
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
   349
		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
   350
{
92
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   351
	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
   352
	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
   353
	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
   354
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   355
	/* 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
   356
	if (!built)
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   357
		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
   358
86
ce6abe0aeeae BBox - RayPacket intersection
Radek Brich <radek.brich@devl.cz>
parents: 85
diff changeset
   359
	// nearest_shapes[0..4] = NULL
ce6abe0aeeae BBox - RayPacket intersection
Radek Brich <radek.brich@devl.cz>
parents: 85
diff changeset
   360
	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
   361
86
ce6abe0aeeae BBox - RayPacket intersection
Radek Brich <radek.brich@devl.cz>
parents: 85
diff changeset
   362
	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
   363
	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
   364
		return;
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
	/* 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
   367
	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
   368
	node = root;
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   369
92
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   370
#ifdef MSVC
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   371
	// MSVC wants constant expression here... hope it won't overflow :)
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   372
	StackElem4 stack[64];
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   373
#else
84
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   374
	StackElem4 stack[max_depth];
92
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   375
#endif
84
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   376
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   377
	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
   378
	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
   379
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   380
	/* 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
   381
	t = mcmplt(a, mZero);
87
1081e3dd3f3e Sphere, Box - RayPacket intersection
Radek Brich <radek.brich@devl.cz>
parents: 86
diff changeset
   382
	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
   383
	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
   384
	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
   385
	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
   386
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   387
	/* 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
   388
	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
   389
	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
   390
	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
   391
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   392
	/* 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
   393
	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
   394
	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
   395
	int axis;
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   396
	static const int mod3[] = {0,1,2,0,1};
86
ce6abe0aeeae BBox - RayPacket intersection
Radek Brich <radek.brich@devl.cz>
parents: 85
diff changeset
   397
	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
   398
	while (node)
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   399
	{
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   400
		/* 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
   401
		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
   402
		{
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   403
			/* 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
   404
			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
   405
			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
   406
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   407
			// 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
   408
			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
   409
			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
   410
			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
   411
			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
   412
			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
   413
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   414
			// 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
   415
			// 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
   416
			// 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
   417
			if (!mmovemask(
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   418
				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
   419
			{
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   420
				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
   421
				continue;
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
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   424
			// 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
   425
			// 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
   426
			// 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
   427
			if (!mmovemask(
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   428
				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
   429
			{
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   430
				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
   431
				continue;
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   432
			}
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   433
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   434
			// any of
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   435
			// 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
   436
			// 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
   437
			int cond1 = mmovemask(
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   438
				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
   439
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   440
			// any of
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   441
			// 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
   442
			// 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
   443
			int cond2 = mmovemask(
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   444
				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
   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 && !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
   447
			{
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   448
				// 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
   449
				// 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
   450
				for (int i = 0; i < 4; i++)
85
907a634e5c02 implement triangle packet intersection
Radek Brich <radek.brich@devl.cz>
parents: 84
diff changeset
   451
					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
   452
						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
   453
							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
   454
				return;
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
			if (cond1)
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
				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
   460
				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
   461
			}
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   462
			else
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   463
			{
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   464
				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
   465
				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
   466
			}
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   467
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   468
			/* 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
   469
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   470
			/* 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
   471
			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
   472
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   473
			/* 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
   474
			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
   475
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   476
			exit++;
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   477
			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
   478
				exit++;
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   479
			assert(exit < max_depth);
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   480
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   481
			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
   482
			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
   483
			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
   484
			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
   485
			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
   486
				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
   487
			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
   488
				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
   489
		}
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   490
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   491
		/* 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
   492
		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
   493
		ShapeList::iterator shape;
92
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   494
		mfloat4 results;
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   495
		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
   496
		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
   497
		{
85
907a634e5c02 implement triangle packet intersection
Radek Brich <radek.brich@devl.cz>
parents: 84
diff changeset
   498
			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
   499
			int valid = mmovemask(
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   500
				mand(mask, mand(results,
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   501
				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
   502
			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
   503
			{
85
907a634e5c02 implement triangle packet intersection
Radek Brich <radek.brich@devl.cz>
parents: 84
diff changeset
   504
				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
   505
				{
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   506
					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
   507
					nearest_distances[i] = ((float*)&dists)[i];
86
ce6abe0aeeae BBox - RayPacket intersection
Radek Brich <radek.brich@devl.cz>
parents: 85
diff changeset
   508
					((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
   509
				}
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   510
			}
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   511
		}
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   512
86
ce6abe0aeeae BBox - RayPacket intersection
Radek Brich <radek.brich@devl.cz>
parents: 85
diff changeset
   513
		mask = newmask;
92
9af5c039b678 add MSVC compiler support, make it default for Windows
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   514
		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
   515
			return;
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   516
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   517
		entry = exit;
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   518
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   519
		/* 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
   520
		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
   521
		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
   522
		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
   523
	}
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   524
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   525
	/* 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
   526
}
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 87
diff changeset
   527
#endif
84
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 80
diff changeset
   528
78
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   529
ostream & operator<<(ostream &st, KdNode &node)
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   530
{
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   531
	if (node.isLeaf())
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   532
	{
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   533
		st << "(l," << node.getShapes()->size();
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   534
		ShapeList::iterator shape;
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   535
		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
   536
			st << "," << shape_index[*shape];
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   537
		st << ")";
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   538
	}
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   539
	else
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   540
	{
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   541
		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
   542
		st << *node.getLeftChild() << ",";
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   543
		st << *node.getRightChild() << ")";
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   544
	}
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   545
	return st;
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   546
}
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   547
95
ca7d4c665531 build script fixes, add ldflags build option
Radek Brich <radek.brich@devl.cz>
parents: 93
diff changeset
   548
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
   549
{
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   550
	if (!built)
78
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   551
		return Container::dump(st);
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
	st << "(kdtree," << shapes.size();
95
ca7d4c665531 build script fixes, add ldflags build option
Radek Brich <radek.brich@devl.cz>
parents: 93
diff changeset
   554
	ShapeList::const_iterator shape;
78
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   555
	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
   556
	{
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   557
		int idx;
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   558
		if (!shape_index.get(*shape, idx))
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   559
			st << "," << endl << **shape;
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   560
	}
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   561
	return st << "," << endl << *getRootNode() << ")";
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   562
}
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   563
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   564
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
   565
{
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   566
	string s;
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   567
	istringstream is;
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
	trim(s);
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   571
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   572
	if (s.compare("(s") == 0)
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   573
	{
78
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   574
		// split
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   575
		int axis;
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   576
		Float split;
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   577
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   578
		delete node->getShapes();
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   579
		node->setChildren(new KdNode[2]);
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   580
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   581
		getline(st, s, ',');
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   582
		axis = s.c_str()[0]-'x';
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   583
		node->setAxis(axis);
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
		st >> split;
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   586
		getline(st, s, ',');
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   587
		node->setSplit(split);
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   588
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   589
		recursive_load(st, node->getLeftChild());
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   590
		getline(st, s, ',');
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   591
		recursive_load(st, node->getRightChild());
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   592
		getline(st, s, ')');
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   593
	}
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   594
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   595
	if (s.compare("(l") == 0)
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
		// leaf
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   598
		int count, idx;
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   599
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   600
		node->setLeaf();
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   601
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   602
		st >> count;
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   603
		for (int i = 0; i < count; i++)
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   604
		{
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   605
			getline(st, s, ',');
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   606
			st >> idx;
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   607
			node->addShape(shapes[idx]);
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   608
		}
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   609
		getline(st, s, ')');
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   610
	}
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   611
}
11
4d192e13ee84 move nearest_intersection() to Container, add dummy KdTree.load(), plus small fixes
Radek Brich <radek.brich@devl.cz>
parents: 10
diff changeset
   612
80
907929fa9b59 remove forgotten noise.h includes
Radek Brich <radek.brich@devl.cz>
parents: 78
diff changeset
   613
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
   614
{
78
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   615
	string s;
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   616
	istringstream is;
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   617
78
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   618
	getline(st, s, ',');
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   619
	if (s.compare("(kdtree") != 0)
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   620
		return st;
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   621
80
907929fa9b59 remove forgotten noise.h includes
Radek Brich <radek.brich@devl.cz>
parents: 78
diff changeset
   622
	dbgmsg(1, "* loading kd-tree\n");
907929fa9b59 remove forgotten noise.h includes
Radek Brich <radek.brich@devl.cz>
parents: 78
diff changeset
   623
78
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   624
	shapes.clear();
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   625
	if (root) delete root;
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   626
	root = new KdNode();
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
	getline(st, s, ',');
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   629
	int shape_count;
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   630
	is.str(s);
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   631
	is >> shape_count;
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   632
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   633
	Shape *shape;
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   634
	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
   635
	{
80
907929fa9b59 remove forgotten noise.h includes
Radek Brich <radek.brich@devl.cz>
parents: 78
diff changeset
   636
		shape = loadShape(st, mat);
78
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   637
		Container::addShape(shape);
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   638
		getline(st, s, ',');
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   639
	}
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   640
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   641
	recursive_load(st, root);
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   642
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   643
	built = true;
9569e9f35374 move shapes to extra source file
Radek Brich <radek.brich@devl.cz>
parents: 76
diff changeset
   644
	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
   645
}