src/kdtree.cc
author Radek Brich <radek.brich@devl.cz>
Sat, 12 Apr 2008 02:02:45 +0200
branchpyrit
changeset 68 2c154aad7f33
parent 44 3763b26244f0
child 71 4fedf7290929
permissions -rw-r--r--
added detection of optimal CPU flags for both GCC and IntelC
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
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    33
class SortableShape
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;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    37
	BBox bbox;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    38
	short axis;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    39
	short mark;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    40
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    41
	SortableShape(Shape *aShape, short &aAxis): shape(aShape), axis(aAxis), mark(0)
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    42
		{ bbox = shape->get_bbox(); };
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    43
	friend bool operator<(const SortableShape& a, const SortableShape& b)
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    44
		{ return a.bbox.L.cell[a.axis] < b.bbox.L.cell[b.axis]; };
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    45
	void setAxis(short aAxis) { axis = aAxis; };
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    46
	void setMark() { mark = 1; };
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    47
	short hasMark() { return mark; };
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
class SortableShapeList: public vector<SortableShape>
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
public:
15
a0a3e334744f C++ demos: prepare infrastructure, add spheres_shadow.cc
Radek Brich <radek.brich@devl.cz>
parents: 14
diff changeset
    53
	SortableShapeList(ShapeList *shapes, short axis)
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
		ShapeList::iterator shape;
15
a0a3e334744f C++ demos: prepare infrastructure, add spheres_shadow.cc
Radek Brich <radek.brich@devl.cz>
parents: 14
diff changeset
    56
		for (shape = shapes->begin(); shape != shapes->end(); shape++)
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    57
			push_back(SortableShape(*shape, axis));
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    58
	};
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
class SplitPos
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    62
{
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    63
public:
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    64
	Float pos;
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    65
	int lnum, rnum;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    66
	SplitPos(): pos(0.0), lnum(0), rnum(0) {};
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    67
	SplitPos(Float &aPos): pos(aPos), lnum(0), rnum(0) {};
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    68
	friend bool operator<(const SplitPos& a, const SplitPos& b)
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    69
		{ return a.pos < b.pos; };
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    70
	friend bool operator==(const SplitPos& a, const SplitPos& b)
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    71
		{ return a.pos == b.pos; };
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    72
};
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    73
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    74
class SplitList: public vector<SplitPos>
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    75
{
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    76
};
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    77
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    78
// stack element for kd-tree traversal
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
    79
class StackElem
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    80
{
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
    81
public:
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    82
	KdNode* node; /* pointer to far child */
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    83
	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
    84
	Vector3 pb; /* the coordinates of entry/exit point */
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    85
	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
    86
		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
    87
};
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    88
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    89
// ----------------------------------------
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
    90
16
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
    91
KdNode::~KdNode()
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
    92
{
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
    93
	if (isLeaf())
17
5176ba000a67 fix last leak as reported by valgrind
Radek Brich <radek.brich@devl.cz>
parents: 16
diff changeset
    94
		delete shapes;
16
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
    95
	else
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
    96
		delete[] children;
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
    97
}
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
    98
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
    99
void KdNode::subdivide(BBox bbox, 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
   100
{
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   101
	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
   102
	{
15
a0a3e334744f C++ demos: prepare infrastructure, add spheres_shadow.cc
Radek Brich <radek.brich@devl.cz>
parents: 14
diff changeset
   103
		setLeaf();
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   104
		return;
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   105
	}
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   106
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   107
	// choose split axis
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   108
	axis = 0;
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   109
	if (bbox.h() > bbox.w() && bbox.h() > bbox.d())
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   110
		axis = 1;
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   111
	if (bbox.d() > bbox.w() && bbox.d() > bbox.h())
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   112
		axis = 2;
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   113
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   114
	// *** find optimal split position
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   115
	SortableShapeList sslist(shapes, axis);
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   116
	sort(sslist.begin(), sslist.end());
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   117
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   118
	SplitList splitlist;
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   119
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   120
	SortableShapeList::iterator sh;
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   121
	for (sh = sslist.begin(); sh != sslist.end(); sh++)
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   122
	{
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   123
		splitlist.push_back(SplitPos(sh->bbox.L.cell[axis]));
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
   124
		splitlist.push_back(SplitPos(sh->bbox.H.cell[axis]));
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   125
	}
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   126
	sort(splitlist.begin(), splitlist.end());
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   127
	// remove duplicate splits
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   128
	splitlist.resize(unique(splitlist.begin(), splitlist.end()) - splitlist.begin());
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   129
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   130
	// find all posible splits
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   131
	SplitList::iterator spl;
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   132
	int rest;
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   133
	for (spl = splitlist.begin(); spl != splitlist.end(); spl++)
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   134
	{
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   135
		for (sh = sslist.begin(), rest = sslist.size(); sh != sslist.end(); sh++, rest--)
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   136
		{
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   137
			if (sh->hasMark())
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   138
			{
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   139
				spl->lnum++;
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   140
				continue;
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   141
			}
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   142
			// if shape is completely contained in split plane
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
   143
			if (spl->pos == sh->bbox.L.cell[axis] == sh->bbox.H.cell[axis])
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   144
			{
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
   145
				if (spl->pos - bbox.L.cell[axis] < bbox.H.cell[axis] - spl->pos)
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   146
				{
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   147
					// left subcell is smaller -> if not empty, put shape here
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   148
					if (spl->lnum)
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   149
						spl->lnum++;
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   150
					else
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   151
						spl->rnum++;
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   152
				} else {
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   153
					// right subcell is smaller
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   154
					if (spl->rnum)
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   155
						spl->rnum++;
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   156
					else
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   157
						spl->lnum++;
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   158
				}
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   159
				sh->setMark();
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   160
			} else
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   161
			// if shape is on left side of split plane
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
   162
			if (sh->bbox.H.cell[axis] <= spl->pos)
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   163
			{
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   164
				spl->lnum++;
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   165
				sh->setMark();
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   166
			} else
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   167
			// if shape occupies both sides of split plane
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
   168
			if (sh->bbox.L.cell[axis] < spl->pos && sh->bbox.H.cell[axis] > spl->pos)
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   169
			{
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   170
				spl->lnum++;
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   171
				spl->rnum++;
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   172
			} else
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   173
			// if shape is on right side of split plane
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   174
			if (sh->bbox.L.cell[axis] >= spl->pos)
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   175
			{
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   176
				spl->rnum += rest;
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   177
				break;
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   178
			}
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   179
		}
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   180
	}
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   181
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   182
	// choose best split pos
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   183
	const Float K = 1.4; // constant, K = cost of traversal / cost of ray-triangle intersection
42
fbdeb3e04543 cleaned Texture interface
Radek Brich <radek.brich@devl.cz>
parents: 35
diff changeset
   184
	Float SAV = (bbox.w()*bbox.h() + bbox.w()*bbox.d() + bbox.h()*bbox.d()); // surface area of node
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   185
	Float cost = SAV * (K + shapes->size()); // initial cost = non-split cost
15
a0a3e334744f C++ demos: prepare infrastructure, add spheres_shadow.cc
Radek Brich <radek.brich@devl.cz>
parents: 14
diff changeset
   186
	bool leaf = true;
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   187
	BBox lbb = bbox;
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   188
	BBox rbb = bbox;
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   189
	for (spl = splitlist.begin(); spl != splitlist.end(); spl++)
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   190
	{
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   191
		// calculate SAH cost of this split
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
   192
		lbb.H.cell[axis] = spl->pos;
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   193
		rbb.L.cell[axis] = spl->pos;
42
fbdeb3e04543 cleaned Texture interface
Radek Brich <radek.brich@devl.cz>
parents: 35
diff changeset
   194
		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
   195
		Float SAR = (rbb.w()*rbb.h() + rbb.w()*rbb.d() + rbb.h()*rbb.d());
fbdeb3e04543 cleaned Texture interface
Radek Brich <radek.brich@devl.cz>
parents: 35
diff changeset
   196
		Float splitcost = K*SAV + SAL*(K+spl->lnum) + SAR*(K+spl->rnum);
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   197
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   198
		if (splitcost < cost)
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   199
		{
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   200
			leaf = false;
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   201
			cost = splitcost;
23
7e258561a690 fix a bug in KdNode::subdivide and remove some extra variables
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
   202
			split = spl->pos;
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   203
		}
7
bf17f9f84c91 kd-tree: build algorithm - searching for all posible splits
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   204
	}
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
   205
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   206
	if (leaf)
15
a0a3e334744f C++ demos: prepare infrastructure, add spheres_shadow.cc
Radek Brich <radek.brich@devl.cz>
parents: 14
diff changeset
   207
	{
a0a3e334744f C++ demos: prepare infrastructure, add spheres_shadow.cc
Radek Brich <radek.brich@devl.cz>
parents: 14
diff changeset
   208
		setLeaf();
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   209
		return;
15
a0a3e334744f C++ demos: prepare infrastructure, add spheres_shadow.cc
Radek Brich <radek.brich@devl.cz>
parents: 14
diff changeset
   210
	}
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   211
29
574c34441a1c new C++ demo: realtime_bunny
Radek Brich <radek.brich@devl.cz>
parents: 28
diff changeset
   212
#if 0
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   213
// 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
   214
// 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
   215
	static ofstream F("kdtree.obj");
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   216
	Vector3 v;
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   217
	static int f=0;
28
ffe83ca074f3 smooth triangles (aka Phong shading)
Radek Brich <radek.brich@devl.cz>
parents: 25
diff changeset
   218
	v.cell[axis] = split;
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   219
	v.cell[(axis+1)%3] = bbox.L.cell[(axis+1)%3];
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   220
	v.cell[(axis+2)%3] = bbox.L.cell[(axis+2)%3];
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   221
	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
   222
	v.cell[(axis+1)%3] = bbox.L.cell[(axis+1)%3];
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
   223
	v.cell[(axis+2)%3] = bbox.H.cell[(axis+2)%3];
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   224
	F << "v " << v.x << " " << v.y << " " << v.z << endl;
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
   225
	v.cell[(axis+1)%3] = bbox.H.cell[(axis+1)%3];
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
   226
	v.cell[(axis+2)%3] = bbox.H.cell[(axis+2)%3];
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   227
	F << "v " << v.x << " " << v.y << " " << v.z << endl;
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
   228
	v.cell[(axis+1)%3] = bbox.H.cell[(axis+1)%3];
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   229
	v.cell[(axis+2)%3] = bbox.L.cell[(axis+2)%3];
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   230
	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
   231
	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
   232
	f += 4;
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   233
#endif
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   234
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   235
	// split this node
17
5176ba000a67 fix last leak as reported by valgrind
Radek Brich <radek.brich@devl.cz>
parents: 16
diff changeset
   236
	delete shapes;
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   237
	children = new KdNode[2];
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   238
	int state = 0;
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   239
	for (sh = sslist.begin(); sh != sslist.end(); sh++)
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   240
	{
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   241
		// if shape is on left side of split plane
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   242
		if (state == 1)
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   243
		{ // only right
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   244
			children[1].addShape(sh->shape);
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   245
			continue;
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   246
		}
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   247
		if (state == 0)
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   248
		{
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
   249
			if (sh->bbox.H.cell[axis] < split)
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   250
			{ // left
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   251
				children[0].addShape(sh->shape);
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   252
			} else
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
   253
			if (sh->bbox.H.cell[axis] > split)
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   254
			{
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   255
				if (sh->bbox.L.cell[axis] < split)
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   256
				{ // both
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   257
					children[0].addShape(sh->shape);
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   258
					children[1].addShape(sh->shape);
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   259
				} else
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   260
				{ // right
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   261
					children[1].addShape(sh->shape);
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   262
					state = 1;
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   263
				}
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   264
			} else
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
   265
			{ // H == split
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   266
				if (sh->bbox.L.cell[axis] < split)
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   267
				{ // left
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   268
					children[0].addShape(sh->shape);
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   269
				} else
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   270
				{ // contained
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
   271
					if (split - bbox.L.cell[axis] < bbox.H.cell[axis] - split)
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   272
					{
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   273
						// left subcell is smaller -> if not empty, put shape here
23
7e258561a690 fix a bug in KdNode::subdivide and remove some extra variables
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
   274
						if (children[0].shapes->size())
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   275
							children[0].addShape(sh->shape);
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   276
						else
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   277
							children[1].addShape(sh->shape);
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   278
					} else {
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   279
						// right subcell is smaller
23
7e258561a690 fix a bug in KdNode::subdivide and remove some extra variables
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
   280
						if (children[1].shapes->size())
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   281
							children[1].addShape(sh->shape);
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   282
						else
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   283
							children[0].addShape(sh->shape);
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   284
					}
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   285
				}
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   286
			}
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   287
		}
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   288
	}
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   289
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
   290
	lbb.H.cell[axis] = split;
9
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   291
	rbb.L.cell[axis] = split;
3239f749e394 kd-tree: build algorithm - completed, untested
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
   292
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   293
	children[0].subdivide(lbb, maxdepth-1);
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   294
	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
   295
}
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   296
11
4d192e13ee84 move nearest_intersection() to Container, add dummy KdTree.load(), plus small fixes
Radek Brich <radek.brich@devl.cz>
parents: 10
diff changeset
   297
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
   298
{
30
33f95441790e pyrit_verbosity: new variable for controlling amount of output, see common.h
Radek Brich <radek.brich@devl.cz>
parents: 29
diff changeset
   299
	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
   300
	root = new KdNode();
17
5176ba000a67 fix last leak as reported by valgrind
Radek Brich <radek.brich@devl.cz>
parents: 16
diff changeset
   301
	ShapeList::iterator shape;
5176ba000a67 fix last leak as reported by valgrind
Radek Brich <radek.brich@devl.cz>
parents: 16
diff changeset
   302
	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
   303
		root->addShape(*shape);
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   304
	root->subdivide(bbox, max_depth);
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   305
	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
   306
}
10
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   307
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   308
/* 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
   309
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
   310
	Float &nearest_distance)
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   311
{
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   312
	Float a, b; /* entry/exit signed distance */
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   313
	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
   314
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   315
	/* 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
   316
	if (!built)
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   317
		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
   318
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   319
	if (!bbox.intersect(ray, a, b))
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   320
		return NULL;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   321
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   322
	/* 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
   323
	KdNode *farchild, *node;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   324
	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
   325
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   326
	/* std vector is much faster than stack */
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   327
	vector<StackElem*> st;
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   328
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   329
	StackElem *enPt = new StackElem(NULL, a,
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   330
		/* 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
   331
		a >= 0.0 ?
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   332
			ray.o + ray.dir * a : /* external */
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   333
			ray.o);               /* internal */
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   334
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   335
	/* setup initial exit point in the stack */
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   336
	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
   337
	st.push_back(exPt);
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   338
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   339
	/* 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
   340
	while (node)
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   341
	{
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   342
		exPt = st.back();
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   343
		/* loop until a leaf is found */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   344
		while (!node->isLeaf())
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   345
		{
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   346
			/* retrieve position of splitting plane */
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   347
			Float splitVal = node->getSplit();
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   348
			short axis = node->getAxis();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   349
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   350
			if (enPt->pb[axis] <= splitVal)
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   351
			{
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   352
				if (exPt->pb[axis] <= splitVal)
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   353
				{ /* 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
   354
					node = node->getLeftChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   355
					continue;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   356
				}
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   357
				if (exPt->pb[axis] == splitVal)
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   358
				{ /* case Z1 */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   359
					node = node->getRightChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   360
					continue;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   361
				}
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   362
				/* case N4 */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   363
				farchild = node->getRightChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   364
				node = node->getLeftChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   365
			}
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   366
			else
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   367
			{ /* (enPt->pb[axis] > splitVal) */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   368
				if (splitVal < exPt->pb[axis])
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   369
				{
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   370
					/* case P1, P2, P3, and N5 */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   371
					node = node->getRightChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   372
					continue;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   373
				}
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   374
				/* case P4*/
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   375
				farchild = node->getLeftChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   376
				node = node->getRightChild();
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   377
			}
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   378
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   379
			/* 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
   380
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   381
			/* 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
   382
			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
   383
16
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
   384
			/* 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
   385
			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
   386
			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
   387
			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
   388
			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
   389
			st.push_back(exPt);
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   390
		} /* while */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   391
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   392
		/* 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
   393
		/* "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
   394
		"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
   395
		Shape *nearest_shape = NULL;
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   396
		Float dist = exPt->t;
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   397
		ShapeList::iterator shape;
15
a0a3e334744f C++ demos: prepare infrastructure, add spheres_shadow.cc
Radek Brich <radek.brich@devl.cz>
parents: 14
diff changeset
   398
		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
   399
			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
   400
			&& dist >= enPt->t)
35
fb170fccb19f new space partitioning structure: octree
Radek Brich <radek.brich@devl.cz>
parents: 34
diff changeset
   401
			{
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   402
				nearest_shape = *shape;
35
fb170fccb19f new space partitioning structure: octree
Radek Brich <radek.brich@devl.cz>
parents: 34
diff changeset
   403
				nearest_distance = dist;
fb170fccb19f new space partitioning structure: octree
Radek Brich <radek.brich@devl.cz>
parents: 34
diff changeset
   404
			}
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   405
16
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
   406
		delete enPt;
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
   407
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   408
		if (nearest_shape)
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   409
		{
16
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
   410
			while (!st.empty())
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
   411
			{
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   412
				delete st.back();
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   413
				st.pop_back();
16
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
   414
			}
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   415
			return nearest_shape;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   416
		}
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   417
16
20bceb605f48 add Raytracer::setThreads()
Radek Brich <radek.brich@devl.cz>
parents: 15
diff changeset
   418
		enPt = exPt;
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   419
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   420
		/* 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
   421
		node = enPt->node;
21
79b516a3803d naive color driven sub-sampling
Radek Brich <radek.brich@devl.cz>
parents: 20
diff changeset
   422
		st.pop_back();
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   423
	} /* while */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   424
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
   425
	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
   426
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   427
	/* ray leaves the scene */
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   428
	return NULL;
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   429
}
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   430
11
4d192e13ee84 move nearest_intersection() to Container, add dummy KdTree.load(), plus small fixes
Radek Brich <radek.brich@devl.cz>
parents: 10
diff changeset
   431
// 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
   432
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
   433
{
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   434
	if (!built)
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   435
		return;
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   436
	if (node == NULL)
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   437
		node = root;
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   438
	if (node->isLeaf())
15
a0a3e334744f C++ demos: prepare infrastructure, add spheres_shadow.cc
Radek Brich <radek.brich@devl.cz>
parents: 14
diff changeset
   439
		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
   440
	else
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   441
	{
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   442
		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
   443
		save(str, node->getLeftChild());
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   444
		str << "; R=";
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   445
		save(str, node->getRightChild());
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   446
		str << ";)";
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   447
	}
f9fad94cd0cc kd-tree: build algorithm tested and fixed
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
   448
}
11
4d192e13ee84 move nearest_intersection() to Container, add dummy KdTree.load(), plus small fixes
Radek Brich <radek.brich@devl.cz>
parents: 10
diff changeset
   449
4d192e13ee84 move nearest_intersection() to Container, add dummy KdTree.load(), plus small fixes
Radek Brich <radek.brich@devl.cz>
parents: 10
diff changeset
   450
// 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
   451
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
   452
{
12
f4fcabf05785 kd-tree: traversal algorithm (KdTree::nearest_intersection)
Radek Brich <radek.brich@devl.cz>
parents: 11
diff changeset
   453
11
4d192e13ee84 move nearest_intersection() to Container, add dummy KdTree.load(), plus small fixes
Radek Brich <radek.brich@devl.cz>
parents: 10
diff changeset
   454
}