2 * OPCODE - Optimized Collision Detection
3 * http://www.codercorner.com/Opcode.htm
5 * Copyright (c) 2001-2008 Pierre Terdiman, pierre@codercorner.com
7 This software is provided 'as-is', without any express or implied warranty.
8 In no event will the authors be held liable for any damages arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it freely,
11 subject to the following restrictions:
13 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
14 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
15 3. This notice may not be removed or altered from any source distribution.
18 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
20 * Contains code for tree builders.
21 * \file OPC_TreeBuilders.h
22 * \author Pierre Terdiman
23 * \date March, 20, 2001
25 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
27 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
29 #ifndef __OPC_TREEBUILDERS_H__
30 #define __OPC_TREEBUILDERS_H__
32 //! Tree splitting rules
36 SPLIT_LARGEST_AXIS = (1<<0), //!< Split along the largest axis
37 SPLIT_SPLATTER_POINTS = (1<<1), //!< Splatter primitive centers (QuickCD-style)
38 SPLIT_BEST_AXIS = (1<<2), //!< Try largest axis, then second, then last
39 SPLIT_BALANCED = (1<<3), //!< Try to keep a well-balanced tree
40 SPLIT_FIFTY = (1<<4), //!< Arbitrary 50-50 split
42 SPLIT_GEOM_CENTER = (1<<5), //!< Split at geometric center (else split in the middle)
44 SPLIT_FORCE_DWORD = 0x7fffffff
47 //! Simple wrapper around build-related settings [Opcode 1.3]
48 struct OPCODE_API BuildSettings
50 inline_ BuildSettings() : mLimit(1), mRules(SPLIT_FORCE_DWORD) {}
52 udword mLimit; //!< Limit number of primitives / node. If limit is 1, build a complete tree (2*N-1 nodes)
53 udword mRules; //!< Building/Splitting rules (a combination of SplittingRules flags)
56 class OPCODE_API AABBTreeBuilder
64 mNbInvalidSplits(0) {}
66 virtual ~AABBTreeBuilder() {}
68 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
70 * Computes the AABB of a set of primitives.
71 * \param primitives [in] list of indices of primitives
72 * \param nb_prims [in] number of indices
73 * \param global_box [out] global AABB enclosing the set of input primitives
74 * \return true if success
76 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
77 virtual bool ComputeGlobalBox(const udword* primitives, udword nb_prims, AABB& global_box) const = 0;
79 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81 * Computes the splitting value along a given axis for a given primitive.
82 * \param index [in] index of the primitive to split
83 * \param axis [in] axis index (0,1,2)
84 * \return splitting value
86 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
87 virtual float GetSplittingValue(udword index, udword axis) const = 0;
89 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
91 * Computes the splitting value along a given axis for a given node.
92 * \param primitives [in] list of indices of primitives
93 * \param nb_prims [in] number of indices
94 * \param global_box [in] global AABB enclosing the set of input primitives
95 * \param axis [in] axis index (0,1,2)
96 * \return splitting value
98 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
99 virtual float GetSplittingValue(const udword* primitives, udword nb_prims, const AABB& global_box, udword axis) const
101 // Default split value = middle of the axis (using only the box)
102 return global_box.GetCenter(axis);
105 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
107 * Validates node subdivision. This is called each time a node is considered for subdivision, during tree building.
108 * \param primitives [in] list of indices of primitives
109 * \param nb_prims [in] number of indices
110 * \param global_box [in] global AABB enclosing the set of input primitives
111 * \return TRUE if the node should be subdivised
113 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
114 virtual BOOL ValidateSubdivision(const udword* primitives, udword nb_prims, const AABB& global_box)
116 // Check the user-defined limit
117 if(nb_prims<=mSettings.mLimit) return FALSE;
122 BuildSettings mSettings; //!< Splitting rules & split limit [Opcode 1.3]
123 udword mNbPrimitives; //!< Total number of primitives.
124 void* mNodeBase; //!< Address of node pool [Opcode 1.3]
126 inline_ void SetCount(udword nb) { mCount=nb; }
127 inline_ void IncreaseCount(udword nb) { mCount+=nb; }
128 inline_ udword GetCount() const { return mCount; }
129 inline_ void SetNbInvalidSplits(udword nb) { mNbInvalidSplits=nb; }
130 inline_ void IncreaseNbInvalidSplits() { mNbInvalidSplits++; }
131 inline_ udword GetNbInvalidSplits() const { return mNbInvalidSplits; }
134 udword mCount; //!< Stats: number of nodes created
135 udword mNbInvalidSplits; //!< Stats: number of invalid splits
138 class OPCODE_API AABBTreeOfVerticesBuilder : public AABBTreeBuilder
142 AABBTreeOfVerticesBuilder() : mVertexArray(null) {}
144 virtual ~AABBTreeOfVerticesBuilder() {}
146 override(AABBTreeBuilder) bool ComputeGlobalBox(const udword* primitives, udword nb_prims, AABB& global_box) const;
147 override(AABBTreeBuilder) float GetSplittingValue(udword index, udword axis) const;
148 override(AABBTreeBuilder) float GetSplittingValue(const udword* primitives, udword nb_prims, const AABB& global_box, udword axis) const;
150 const Point* mVertexArray; //!< Shortcut to an app-controlled array of vertices.
153 class OPCODE_API AABBTreeOfAABBsBuilder : public AABBTreeBuilder
157 AABBTreeOfAABBsBuilder() : mAABBArray(null) {}
159 virtual ~AABBTreeOfAABBsBuilder() {}
161 override(AABBTreeBuilder) bool ComputeGlobalBox(const udword* primitives, udword nb_prims, AABB& global_box) const;
162 override(AABBTreeBuilder) float GetSplittingValue(udword index, udword axis) const;
164 const AABB* mAABBArray; //!< Shortcut to an app-controlled array of AABBs.
167 class OPCODE_API AABBTreeOfTrianglesBuilder : public AABBTreeBuilder
171 AABBTreeOfTrianglesBuilder() : mIMesh(null) {}
173 virtual ~AABBTreeOfTrianglesBuilder() {}
175 override(AABBTreeBuilder) bool ComputeGlobalBox(const udword* primitives, udword nb_prims, AABB& global_box) const;
176 override(AABBTreeBuilder) float GetSplittingValue(udword index, udword axis) const;
177 override(AABBTreeBuilder) float GetSplittingValue(const udword* primitives, udword nb_prims, const AABB& global_box, udword axis) const;
179 const MeshInterface* mIMesh; //!< Shortcut to an app-controlled mesh interface
182 #endif // __OPC_TREEBUILDERS_H__