src/kdtree.cc
author Radek Brich <radek.brich@devl.cz>
Sat, 19 Apr 2008 18:00:27 +0200
branchpyrit
changeset 71 4fedf7290929
parent 44 3763b26244f0
child 72 7c3f38dff082
permissions -rw-r--r--
simplify kd-tree building, it's also much faster now
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
 *
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
     6
 * Copyright 2006, 2007  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>
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    29
20
f22952603f29 new C++ demo: realtime.cc (real-time scene viewer using SDL)
Radek Brich <radek.brich@devl.cz>
parents: 17
diff changeset
    30
#include "common.h"
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    31
#include "kdtree.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
    32
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
    33
class ShapeBound
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    34
{
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    35
public:
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    36
	Shape *shape;
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
    37
	Float pos;
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
    38
	bool end;
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
    39
	ShapeBound(Shape *ashape, const Float apos, const bool aend):
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
    40
		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
    41
	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
    42
	{
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
    43
		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
    44
			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
    45
		else
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
    46
			return a.pos < b.pos;
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    47
	};
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    48
};
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
// stack element for kd-tree traversal
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
    51
class StackElem
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    52
{
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
    53
public:
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    54
	KdNode* node; /* pointer to far child */
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    55
	Float t; /* the entry/exit signed distance */
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    56
	Vector3 pb; /* the coordinates of entry/exit point */
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    57
	StackElem(KdNode *anode, const Float &at, const Vector3 &apb):
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
    58
		node(anode), t(at), pb(apb) {};
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())
17
5176ba000a67 fix last leak as reported by valgrind
Radek Brich <radek.brich@devl.cz>
parents: 16
diff changeset
    66
		delete shapes;
16
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
    67
	else
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
    68
		delete[] children;
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
    69
}
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
    70
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
    71
// kd-tree recursive build algorithm, inspired by PBRT (www.pbrt.org)
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
    72
void KdNode::subdivide(BBox bounds, int maxdepth)
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    73
{
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
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
	{
15
a0a3e334744f C++ demos: prepare infrastructure, add spheres_shadow.cc
Radek Brich <radek.brich@devl.cz>
parents: 14
diff changeset
    76
		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
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
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;
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
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;
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
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();
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
    93
	//	for (int ax = 0; ax < 3; ax++)
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
    94
	//	{
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
    95
			edges[axis].push_back(ShapeBound(*shape, shapebounds.L[axis], 0));
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
    96
			edges[axis].push_back(ShapeBound(*shape, shapebounds.H[axis], 1));
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
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
	}
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
    99
	sort(edges[axis].begin(), edges[axis].end());
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   100
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   101
	// choose best split pos
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   102
	const Float K = 1.4; // 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
   103
	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
   104
		bounds.w()*bounds.d() + bounds.h()*bounds.d());
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   105
	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
   106
	BBox lbb = bounds;
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   107
	BBox rbb = bounds;
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   108
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   109
	vector<ShapeBound>::iterator edge, splitedge = edges[axis].end();
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   110
	int lnum = 0, rnum = shapes->size();
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   111
	for (edge = edges[axis].begin(); edge != edges[axis].end(); edge++)
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   112
	{
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   113
		if (edge->end)
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   114
			rnum--;
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   115
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   116
		// calculate SAH cost of this split
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   117
		lbb.H.cell[axis] = edge->pos;
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   118
		rbb.L.cell[axis] = edge->pos;
42
fbdeb3e04543 cleaned Texture interface
Radek Brich <radek.brich@devl.cz>
parents: 35
diff changeset
   119
		Float SAL = (lbb.w()*lbb.h() + lbb.w()*lbb.d() + lbb.h()*lbb.d());
fbdeb3e04543 cleaned Texture interface
Radek Brich <radek.brich@devl.cz>
parents: 35
diff changeset
   120
		Float SAR = (rbb.w()*rbb.h() + rbb.w()*rbb.d() + rbb.h()*rbb.d());
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   121
		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
   122
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   123
		if (splitcost < cost)
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   124
		{
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   125
			splitedge = edge;
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   126
			cost = splitcost;
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   127
			split = edge->pos;
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   128
		}
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   129
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   130
		if (!edge->end)
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   131
			lnum++;
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   132
	}
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
   133
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   134
	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
   135
	{
a0a3e334744f C++ demos: prepare infrastructure, add spheres_shadow.cc
Radek Brich <radek.brich@devl.cz>
parents: 14
diff changeset
   136
		setLeaf();
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   137
		return;
15
a0a3e334744f C++ demos: prepare infrastructure, add spheres_shadow.cc
Radek Brich <radek.brich@devl.cz>
parents: 14
diff changeset
   138
	}
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   139
29
574c34441a1c new C++ demo: realtime_bunny
Radek Brich <radek.brich@devl.cz>
parents: 28
diff changeset
   140
#if 0
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   141
// 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
   142
// 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
   143
	static ofstream F("kdtree.obj");
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   144
	Vector3 v;
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   145
	static int f=0;
28
ffe83ca074f3 smooth triangles (aka Phong shading)
Radek Brich <radek.brich@devl.cz>
parents: 25
diff changeset
   146
	v.cell[axis] = split;
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   147
	v.cell[(axis+1)%3] = bounds.L.cell[(axis+1)%3];
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   148
	v.cell[(axis+2)%3] = bounds.L.cell[(axis+2)%3];
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   149
	F << "v " << v.x << " " << v.y << " " << v.z << endl;
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   150
	v.cell[(axis+1)%3] = bounds.L.cell[(axis+1)%3];
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   151
	v.cell[(axis+2)%3] = bounds.H.cell[(axis+2)%3];
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   152
	F << "v " << v.x << " " << v.y << " " << v.z << endl;
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   153
	v.cell[(axis+1)%3] = bounds.H.cell[(axis+1)%3];
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   154
	v.cell[(axis+2)%3] = bounds.H.cell[(axis+2)%3];
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   155
	F << "v " << v.x << " " << v.y << " " << v.z << endl;
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   156
	v.cell[(axis+1)%3] = bounds.H.cell[(axis+1)%3];
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   157
	v.cell[(axis+2)%3] = bounds.L.cell[(axis+2)%3];
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   158
	F << "v " << v.x << " " << v.y << " " << v.z << endl;
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   159
	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
   160
	f += 4;
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   161
#endif
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   162
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   163
	// split this node
17
5176ba000a67 fix last leak as reported by valgrind
Radek Brich <radek.brich@devl.cz>
parents: 16
diff changeset
   164
	delete shapes;
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   165
	children = new KdNode[2];
71
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   166
	for (edge = edges[axis].begin(); edge != splitedge; edge++)
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   167
		if (!edge->end)
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   168
			children[0].addShape(edge->shape);
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   169
	for (edge = splitedge; edge < edges[axis].end(); edge++)
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   170
		if (edge->end)
4fedf7290929 simplify kd-tree building, it's also much faster now
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   171
			children[1].addShape(edge->shape);
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   172
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
   173
	lbb.H.cell[axis] = split;
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   174
	rbb.L.cell[axis] = split;
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   175
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   176
	children[0].subdivide(lbb, maxdepth-1);
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   177
	children[1].subdivide(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
   178
}
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   179
11
4d192e13ee84 move nearest_intersection() to Container, add dummy KdTree.load(), plus small fixes
Radek Brich <radek.brich@devl.cz>
parents: 10
diff changeset
   180
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
   181
{
30
33f95441790e pyrit_verbosity: new variable for controlling amount of output, see common.h
Radek Brich <radek.brich@devl.cz>
parents: 29
diff changeset
   182
	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
   183
	root = new KdNode();
17
5176ba000a67 fix last leak as reported by valgrind
Radek Brich <radek.brich@devl.cz>
parents: 16
diff changeset
   184
	ShapeList::iterator shape;
5176ba000a67 fix last leak as reported by valgrind
Radek Brich <radek.brich@devl.cz>
parents: 16
diff changeset
   185
	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
   186
		root->addShape(*shape);
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   187
	root->subdivide(bbox, max_depth);
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   188
	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
   189
}
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   190
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   191
/* algorithm by Vlastimil Havran, Heuristic Ray Shooting Algorithms, appendix C */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   192
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
   193
	Float &nearest_distance)
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   194
{
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   195
	Float a, b; /* entry/exit signed distance */
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   196
	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
   197
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   198
	/* 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
   199
	if (!built)
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   200
		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
   201
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   202
	if (!bbox.intersect(ray, a, b))
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   203
		return NULL;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   204
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   205
	/* 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
   206
	KdNode *farchild, *node;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   207
	node = root; /* start from the kd-tree root node */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   208
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   209
	/* std vector is much faster than stack */
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   210
	vector<StackElem*> st;
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   211
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   212
	StackElem *enPt = new StackElem(NULL, a,
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   213
		/* distinguish between internal and external origin of a ray*/
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   214
		a >= 0.0 ?
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   215
			ray.o + ray.dir * a : /* external */
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   216
			ray.o);               /* internal */
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   217
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   218
	/* setup initial exit point in the stack */
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   219
	StackElem *exPt = new StackElem(NULL, b, ray.o + ray.dir * b);
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   220
	st.push_back(exPt);
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   221
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   222
	/* loop, traverse through the whole kd-tree, until an object is intersected or ray leaves the scene */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   223
	while (node)
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   224
	{
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   225
		exPt = st.back();
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   226
		/* loop until a leaf is found */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   227
		while (!node->isLeaf())
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   228
		{
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   229
			/* retrieve position of splitting plane */
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   230
			Float splitVal = node->getSplit();
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   231
			short axis = node->getAxis();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   232
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   233
			if (enPt->pb[axis] <= splitVal)
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   234
			{
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   235
				if (exPt->pb[axis] <= splitVal)
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   236
				{ /* 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
   237
					node = node->getLeftChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   238
					continue;
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
				if (exPt->pb[axis] == splitVal)
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   241
				{ /* case Z1 */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   242
					node = node->getRightChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   243
					continue;
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
				/* case N4 */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   246
				farchild = node->getRightChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   247
				node = node->getLeftChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   248
			}
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   249
			else
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   250
			{ /* (enPt->pb[axis] > splitVal) */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   251
				if (splitVal < exPt->pb[axis])
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   252
				{
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   253
					/* case P1, P2, P3, and N5 */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   254
					node = node->getRightChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   255
					continue;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   256
				}
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   257
				/* case P4*/
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   258
				farchild = node->getLeftChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   259
				node = node->getRightChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   260
			}
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   261
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   262
			/* 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
   263
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   264
			/* signed distance to the splitting plane */
15
a0a3e334744f C++ demos: prepare infrastructure, add spheres_shadow.cc
Radek Brich <radek.brich@devl.cz>
parents: 14
diff changeset
   265
			t = (splitVal - ray.o.cell[axis]) / ray.dir.cell[axis];
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   266
16
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
   267
			/* setup the new exit point and push it onto stack */
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   268
			exPt = new StackElem(farchild, t, Vector3());
25
b8232edee786 tuned ray-triangle intersection, now there are three algorithms to choose from:
Radek Brich <radek.brich@devl.cz>
parents: 24
diff changeset
   269
			exPt->pb.cell[axis] = splitVal;
b8232edee786 tuned ray-triangle intersection, now there are three algorithms to choose from:
Radek Brich <radek.brich@devl.cz>
parents: 24
diff changeset
   270
			exPt->pb.cell[(axis+1)%3] = ray.o.cell[(axis+1)%3] + t * ray.dir.cell[(axis+1)%3];
b8232edee786 tuned ray-triangle intersection, now there are three algorithms to choose from:
Radek Brich <radek.brich@devl.cz>
parents: 24
diff changeset
   271
			exPt->pb.cell[(axis+2)%3] = ray.o.cell[(axis+2)%3] + t * ray.dir.cell[(axis+2)%3];
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   272
			st.push_back(exPt);
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   273
		} /* while */
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
		/* current node is the leaf . . . empty or full */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   276
		/* "intersect ray with each object in the object list, discarding "
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   277
		"those lying before stack[enPt].t or farther than stack[exPt].t" */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   278
		Shape *nearest_shape = NULL;
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   279
		Float dist = exPt->t;
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   280
		ShapeList::iterator shape;
15
a0a3e334744f C++ demos: prepare infrastructure, add spheres_shadow.cc
Radek Brich <radek.brich@devl.cz>
parents: 14
diff changeset
   281
		for (shape = node->shapes->begin(); shape != node->shapes->end(); shape++)
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   282
			if (*shape != origin_shape && (*shape)->intersect(ray, dist)
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   283
			&& dist >= enPt->t)
35
fb170fccb19f new space partitioning structure: octree
Radek Brich <radek.brich@devl.cz>
parents: 34
diff changeset
   284
			{
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   285
				nearest_shape = *shape;
35
fb170fccb19f new space partitioning structure: octree
Radek Brich <radek.brich@devl.cz>
parents: 34
diff changeset
   286
				nearest_distance = dist;
fb170fccb19f new space partitioning structure: octree
Radek Brich <radek.brich@devl.cz>
parents: 34
diff changeset
   287
			}
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   288
16
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
   289
		delete enPt;
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
   290
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   291
		if (nearest_shape)
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
			while (!st.empty())
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
   294
			{
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   295
				delete st.back();
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   296
				st.pop_back();
16
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
   297
			}
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   298
			return nearest_shape;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   299
		}
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   300
16
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
   301
		enPt = exPt;
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   302
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   303
		/* retrieve the pointer to the next node, it is possible that ray traversal terminates */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   304
		node = enPt->node;
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   305
		st.pop_back();
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   306
	} /* while */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   307
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
   308
	delete enPt;
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
   309
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   310
	/* ray leaves the scene */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   311
	return NULL;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   312
}
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   313
11
4d192e13ee84 move nearest_intersection() to Container, add dummy KdTree.load(), plus small fixes
Radek Brich <radek.brich@devl.cz>
parents: 10
diff changeset
   314
// this should save whole kd-tree with triangles distributed into leaves
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   315
void KdTree::save(ostream &str, KdNode *node)
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   316
{
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   317
	if (!built)
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   318
		return;
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   319
	if (node == NULL)
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   320
		node = root;
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   321
	if (node->isLeaf())
15
a0a3e334744f C++ demos: prepare infrastructure, add spheres_shadow.cc
Radek Brich <radek.brich@devl.cz>
parents: 14
diff changeset
   322
		str << "(leaf: " << node->shapes->size() << " shapes)";
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   323
	else
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   324
	{
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   325
		str << "(split " << (char)('x'+node->getAxis()) << " at " << node->getSplit() << "; L=";
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   326
		save(str, node->getLeftChild());
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   327
		str << "; R=";
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   328
		save(str, node->getRightChild());
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   329
		str << ";)";
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   330
	}
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   331
}
11
4d192e13ee84 move nearest_intersection() to Container, add dummy KdTree.load(), plus small fixes
Radek Brich <radek.brich@devl.cz>
parents: 10
diff changeset
   332
4d192e13ee84 move nearest_intersection() to Container, add dummy KdTree.load(), plus small fixes
Radek Brich <radek.brich@devl.cz>
parents: 10
diff changeset
   333
// load kd-tree from file/stream
4d192e13ee84 move nearest_intersection() to Container, add dummy KdTree.load(), plus small fixes
Radek Brich <radek.brich@devl.cz>
parents: 10
diff changeset
   334
void KdTree::load(istream &str, KdNode *node)
4d192e13ee84 move nearest_intersection() to Container, add dummy KdTree.load(), plus small fixes
Radek Brich <radek.brich@devl.cz>
parents: 10
diff changeset
   335
{
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   336
11
4d192e13ee84 move nearest_intersection() to Container, add dummy KdTree.load(), plus small fixes
Radek Brich <radek.brich@devl.cz>
parents: 10
diff changeset
   337
}