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 a versatile AABB tree.
21 * \file OPC_AABBTree.cpp
22 * \author Pierre Terdiman
23 * \date March, 20, 2001
25 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
27 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
29 * Contains a generic AABB tree node.
32 * \author Pierre Terdiman
34 * \date March, 20, 2001
36 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
38 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
40 * Contains a generic AABB tree.
41 * This is a vanilla AABB tree, without any particular optimization. It contains anonymous references to
42 * user-provided primitives, which can theoretically be anything - triangles, boxes, etc. Each primitive
43 * is surrounded by an AABB, regardless of the primitive's nature. When the primitive is a triangle, the
44 * resulting tree can be converted into an optimized tree. If the primitive is a box, the resulting tree
45 * can be used for culling - VFC or occlusion -, assuming you cull on a mesh-by-mesh basis (modern way).
48 * \author Pierre Terdiman
50 * \date March, 20, 2001
52 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
54 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
58 using namespace Opcode;
60 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
64 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
65 AABBTreeNode::AABBTreeNode() :
67 #ifndef OPC_NO_NEG_VANILLA_TREE
71 mNodePrimitives (null)
73 #ifdef OPC_USE_TREE_COHERENCE
78 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
82 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
83 AABBTreeNode::~AABBTreeNode()
86 const AABBTreeNode* Pos = GetPos();
87 const AABBTreeNode* Neg = GetNeg();
88 #ifndef OPC_NO_NEG_VANILLA_TREE
89 if(!(mPos&1)) DELETESINGLE(Pos);
90 if(!(mNeg&1)) DELETESINGLE(Neg);
92 if(!(mPos&1)) DELETEARRAY(Pos);
94 mNodePrimitives = null; // This was just a shortcut to the global list => no release
98 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
100 * Splits the node along a given axis.
101 * The list of indices is reorganized according to the split values.
102 * \param axis [in] splitting axis index
103 * \param builder [in] the tree builder
104 * \return the number of primitives assigned to the first child
105 * \warning this method reorganizes the internal list of primitives
107 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
108 udword AABBTreeNode::Split(udword axis, AABBTreeBuilder* builder)
110 // Get node split value
111 float SplitValue = builder->GetSplittingValue(mNodePrimitives, mNbPrimitives, mBV, axis);
114 // Loop through all node-related primitives. Their indices range from mNodePrimitives[0] to mNodePrimitives[mNbPrimitives-1].
115 // Those indices map the global list in the tree builder.
116 for(udword i=0;i<mNbPrimitives;i++)
118 // Get index in global list
119 udword Index = mNodePrimitives[i];
121 // Test against the splitting value. The primitive value is tested against the enclosing-box center.
122 // [We only need an approximate partition of the enclosing box here.]
123 float PrimitiveValue = builder->GetSplittingValue(Index, axis);
125 // Reorganize the list of indices in this order: positive - negative.
126 if(PrimitiveValue > SplitValue)
129 udword Tmp = mNodePrimitives[i];
130 mNodePrimitives[i] = mNodePrimitives[NbPos];
131 mNodePrimitives[NbPos] = Tmp;
132 // Count primitives assigned to positive space
139 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
141 * Subdivides the node.
151 * A well-balanced tree should have a O(log n) depth.
152 * A degenerate tree would have a O(n) depth.
153 * Note a perfectly-balanced tree is not well-suited to collision detection anyway.
155 * \param builder [in] the tree builder
156 * \return true if success
158 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
159 bool AABBTreeNode::Subdivide(AABBTreeBuilder* builder)
162 if(!builder) return false;
164 // Stop subdividing if we reach a leaf node. This is always performed here,
165 // else we could end in trouble if user overrides this.
166 if(mNbPrimitives==1) return true;
168 // Let the user validate the subdivision
169 if(!builder->ValidateSubdivision(mNodePrimitives, mNbPrimitives, mBV)) return true;
171 bool ValidSplit = true; // Optimism...
173 if(builder->mSettings.mRules & SPLIT_LARGEST_AXIS)
175 // Find the largest axis to split along
176 Point Extents; mBV.GetExtents(Extents); // Box extents
177 udword Axis = Extents.LargestAxis(); // Index of largest axis
179 // Split along the axis
180 NbPos = Split(Axis, builder);
182 // Check split validity
183 if(!NbPos || NbPos==mNbPrimitives) ValidSplit = false;
185 else if(builder->mSettings.mRules & SPLIT_SPLATTER_POINTS)
188 Point Means(0.0f, 0.0f, 0.0f);
189 for(udword i=0;i<mNbPrimitives;i++)
191 udword Index = mNodePrimitives[i];
192 Means.x+=builder->GetSplittingValue(Index, 0);
193 Means.y+=builder->GetSplittingValue(Index, 1);
194 Means.z+=builder->GetSplittingValue(Index, 2);
196 Means/=float(mNbPrimitives);
199 Point Vars(0.0f, 0.0f, 0.0f);
200 for(udword i=0;i<mNbPrimitives;i++)
202 udword Index = mNodePrimitives[i];
203 float Cx = builder->GetSplittingValue(Index, 0);
204 float Cy = builder->GetSplittingValue(Index, 1);
205 float Cz = builder->GetSplittingValue(Index, 2);
206 Vars.x += (Cx - Means.x)*(Cx - Means.x);
207 Vars.y += (Cy - Means.y)*(Cy - Means.y);
208 Vars.z += (Cz - Means.z)*(Cz - Means.z);
210 Vars/=float(mNbPrimitives-1);
212 // Choose axis with greatest variance
213 udword Axis = Vars.LargestAxis();
215 // Split along the axis
216 NbPos = Split(Axis, builder);
218 // Check split validity
219 if(!NbPos || NbPos==mNbPrimitives) ValidSplit = false;
221 else if(builder->mSettings.mRules & SPLIT_BALANCED)
223 // Test 3 axis, take the best
225 NbPos = Split(0, builder); Results[0] = float(NbPos)/float(mNbPrimitives);
226 NbPos = Split(1, builder); Results[1] = float(NbPos)/float(mNbPrimitives);
227 NbPos = Split(2, builder); Results[2] = float(NbPos)/float(mNbPrimitives);
228 Results[0]-=0.5f; Results[0]*=Results[0];
229 Results[1]-=0.5f; Results[1]*=Results[1];
230 Results[2]-=0.5f; Results[2]*=Results[2];
232 if(Results[1]<Results[Min]) Min = 1;
233 if(Results[2]<Results[Min]) Min = 2;
235 // Split along the axis
236 NbPos = Split(Min, builder);
238 // Check split validity
239 if(!NbPos || NbPos==mNbPrimitives) ValidSplit = false;
241 else if(builder->mSettings.mRules & SPLIT_BEST_AXIS)
243 // Test largest, then middle, then smallest axis...
246 Point Extents; mBV.GetExtents(Extents); // Box extents
247 udword SortedAxis[] = { 0, 1, 2 };
248 float* Keys = (float*)&Extents.x;
249 for(udword j=0;j<3;j++)
251 for(udword i=0;i<2;i++)
253 if(Keys[SortedAxis[i]]<Keys[SortedAxis[i+1]])
255 udword Tmp = SortedAxis[i];
256 SortedAxis[i] = SortedAxis[i+1];
257 SortedAxis[i+1] = Tmp;
262 // Find the largest axis to split along
265 while(!ValidSplit && CurAxis!=3)
267 NbPos = Split(SortedAxis[CurAxis], builder);
268 // Check the subdivision has been successful
269 if(!NbPos || NbPos==mNbPrimitives) CurAxis++;
270 else ValidSplit = true;
273 else if(builder->mSettings.mRules & SPLIT_FIFTY)
275 // Don't even bother splitting (mainly a performance test)
276 NbPos = mNbPrimitives>>1;
278 else return false; // Unknown splitting rules
280 // Check the subdivision has been successful
283 // Here, all boxes lie in the same sub-space. Two strategies:
284 // - if the tree *must* be complete, make an arbitrary 50-50 split
285 // - else stop subdividing
286 // if(builder->mSettings.mRules&SPLIT_COMPLETE)
287 if(builder->mSettings.mLimit==1)
289 builder->IncreaseNbInvalidSplits();
290 NbPos = mNbPrimitives>>1;
295 // Now create children and assign their pointers.
296 if(builder->mNodeBase)
298 // We use a pre-allocated linear pool for complete trees [Opcode 1.3]
299 AABBTreeNode* Pool = (AABBTreeNode*)builder->mNodeBase;
300 udword Count = builder->GetCount() - 1; // Count begins to 1...
301 // Set last bit to tell it shouldn't be freed ### pretty ugly, find a better way. Maybe one bit in mNbPrimitives
302 ASSERT(!(udword(&Pool[Count+0])&1));
303 ASSERT(!(udword(&Pool[Count+1])&1));
304 mPos = udword(&Pool[Count+0])|1;
305 #ifndef OPC_NO_NEG_VANILLA_TREE
306 mNeg = udword(&Pool[Count+1])|1;
311 // Non-complete trees and/or Opcode 1.2 allocate nodes on-the-fly
312 #ifndef OPC_NO_NEG_VANILLA_TREE
313 mPos = (udword)new AABBTreeNode; CHECKALLOC(mPos);
314 mNeg = (udword)new AABBTreeNode; CHECKALLOC(mNeg);
316 AABBTreeNode* PosNeg = new AABBTreeNode[2];
318 mPos = (udword)PosNeg;
323 builder->IncreaseCount(2);
326 AABBTreeNode* Pos = (AABBTreeNode*)GetPos();
327 AABBTreeNode* Neg = (AABBTreeNode*)GetNeg();
328 Pos->mNodePrimitives = &mNodePrimitives[0];
329 Pos->mNbPrimitives = NbPos;
330 Neg->mNodePrimitives = &mNodePrimitives[NbPos];
331 Neg->mNbPrimitives = mNbPrimitives - NbPos;
336 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
338 * Recursive hierarchy building in a top-down fashion.
339 * \param builder [in] the tree builder
341 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
342 void AABBTreeNode::_BuildHierarchy(AABBTreeBuilder* builder)
344 // 1) Compute the global box for current node. The box is stored in mBV.
345 builder->ComputeGlobalBox(mNodePrimitives, mNbPrimitives, mBV);
347 // 2) Subdivide current node
351 AABBTreeNode* Pos = (AABBTreeNode*)GetPos();
352 AABBTreeNode* Neg = (AABBTreeNode*)GetNeg();
353 if(Pos) Pos->_BuildHierarchy(builder);
354 if(Neg) Neg->_BuildHierarchy(builder);
357 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
359 * Refits the tree (top-down).
360 * \param builder [in] the tree builder
362 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
363 void AABBTreeNode::_Refit(AABBTreeBuilder* builder)
365 // 1) Recompute the new global box for current node
366 builder->ComputeGlobalBox(mNodePrimitives, mNbPrimitives, mBV);
369 AABBTreeNode* Pos = (AABBTreeNode*)GetPos();
370 AABBTreeNode* Neg = (AABBTreeNode*)GetNeg();
371 if(Pos) Pos->_Refit(builder);
372 if(Neg) Neg->_Refit(builder);
377 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
381 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
382 AABBTree::AABBTree() : mIndices(null), mTotalNbNodes(0), mPool(null)
386 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
390 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
391 AABBTree::~AABBTree()
396 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
400 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
401 void AABBTree::Release()
404 DELETEARRAY(mIndices);
407 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
409 * Builds a generic AABB tree from a tree builder.
410 * \param builder [in] the tree builder
411 * \return true if success
413 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
414 bool AABBTree::Build(AABBTreeBuilder* builder)
417 if(!builder || !builder->mNbPrimitives) return false;
419 // Release previous tree
423 builder->SetCount(1);
424 builder->SetNbInvalidSplits(0);
426 // Initialize indices. This list will be modified during build.
427 mIndices = new udword[builder->mNbPrimitives];
428 CHECKALLOC(mIndices);
429 // Identity permutation
430 for(udword i=0;i<builder->mNbPrimitives;i++) mIndices[i] = i;
432 // Setup initial node. Here we have a complete permutation of the app's primitives.
433 mNodePrimitives = mIndices;
434 mNbPrimitives = builder->mNbPrimitives;
436 // Use a linear array for complete trees (since we can predict the final number of nodes) [Opcode 1.3]
437 // if(builder->mRules&SPLIT_COMPLETE)
438 if(builder->mSettings.mLimit==1)
440 // Allocate a pool of nodes
441 mPool = new AABBTreeNode[builder->mNbPrimitives*2 - 1];
443 builder->mNodeBase = mPool; // ### ugly !
446 // Build the hierarchy
447 _BuildHierarchy(builder);
449 // Get back total number of nodes
450 mTotalNbNodes = builder->GetCount();
452 // For complete trees, check the correct number of nodes has been created [Opcode 1.3]
453 if(mPool) ASSERT(mTotalNbNodes==builder->mNbPrimitives*2 - 1);
458 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
460 * Computes the depth of the tree.
461 * A well-balanced tree should have a log(n) depth. A degenerate tree O(n) depth.
462 * \return depth of the tree
464 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
465 udword AABBTree::ComputeDepth() const
467 return Walk(null, null); // Use the walking code without callback
470 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
472 * Walks the tree, calling the user back for each node.
474 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
475 udword AABBTree::Walk(WalkingCallback callback, void* user_data) const
477 // Call it without callback to compute max depth
479 udword CurrentDepth = 0;
483 static void _Walk(const AABBTreeNode* current_node, udword& max_depth, udword& current_depth, WalkingCallback callback, void* user_data)
486 if(!current_node) return;
487 // Entering a new node => increase depth
489 // Keep track of max depth
490 if(current_depth>max_depth) max_depth = current_depth;
493 if(callback && !(callback)(current_node, current_depth, user_data)) return;
496 if(current_node->GetPos()) { _Walk(current_node->GetPos(), max_depth, current_depth, callback, user_data); current_depth--; }
497 if(current_node->GetNeg()) { _Walk(current_node->GetNeg(), max_depth, current_depth, callback, user_data); current_depth--; }
500 Local::_Walk(this, MaxDepth, CurrentDepth, callback, user_data);
504 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
506 * Refits the tree in a top-down way.
507 * \param builder [in] the tree builder
509 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
510 bool AABBTree::Refit(AABBTreeBuilder* builder)
512 if(!builder) return false;
517 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
519 * Refits the tree in a bottom-up way.
520 * \param builder [in] the tree builder
522 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
523 bool AABBTree::Refit2(AABBTreeBuilder* builder)
526 if(!builder) return false;
533 udword Index = mTotalNbNodes;
536 AABBTreeNode& Current = mPool[Index];
540 builder->ComputeGlobalBox(Current.GetPrimitives(), Current.GetNbPrimitives(), *(AABB*)Current.GetAABB());
544 Current.GetPos()->GetAABB()->GetMin(Min);
545 Current.GetPos()->GetAABB()->GetMax(Max);
547 Current.GetNeg()->GetAABB()->GetMin(Min_);
548 Current.GetNeg()->GetAABB()->GetMax(Max_);
553 ((AABB*)Current.GetAABB())->SetMinMax(Min, Max);
559 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
561 * Computes the number of bytes used by the tree.
562 * \return number of bytes used
564 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
565 udword AABBTree::GetUsedBytes() const
567 udword TotalSize = mTotalNbNodes*GetNodeSize();
568 if(mIndices) TotalSize+=mNbPrimitives*sizeof(udword);
572 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
574 * Checks the tree is a complete tree or not.
575 * A complete tree is made of 2*N-1 nodes, where N is the number of primitives in the tree.
576 * \return true for complete trees
578 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
579 bool AABBTree::IsComplete() const
581 return (GetNbNodes()==GetNbPrimitives()*2-1);