55 AABBTreeNode::AABBTreeNode() :
61 mNodePrimitives (
null),
64 #ifdef OPC_USE_TREE_COHERENCE
73 AABBTreeNode::~AABBTreeNode()
78 #ifndef OPC_NO_NEG_VANILLA_TREE
85 mNodePrimitives =
null;
102 float SplitValue = builder->
GetSplittingValue(mNodePrimitives, mNbPrimitives, mBV, axis);
110 udword Index = mNodePrimitives[
i];
117 if(PrimitiveValue > SplitValue)
120 udword Tmp = mNodePrimitives[
i];
121 mNodePrimitives[
i] = mNodePrimitives[NbPos];
122 mNodePrimitives[NbPos] = Tmp;
153 if(!builder)
return false;
157 if(mNbPrimitives==1)
return true;
162 bool ValidSplit =
true;
167 Point Extents; mBV.GetExtents(Extents);
168 udword Axis = Extents.LargestAxis();
171 NbPos = Split(Axis, builder);
174 if(!NbPos || NbPos==mNbPrimitives) ValidSplit =
false;
179 Point Means(0.0
f, 0.0
f, 0.0
f);
182 udword Index = mNodePrimitives[
i];
187 Means/=float(mNbPrimitives);
190 Point Vars(0.0
f, 0.0
f, 0.0
f);
193 udword Index = mNodePrimitives[
i];
197 Vars.x += (Cx - Means.x)*(Cx - Means.x);
198 Vars.y += (Cy - Means.y)*(Cy - Means.y);
199 Vars.z += (Cz - Means.z)*(Cz - Means.z);
201 Vars/=float(mNbPrimitives-1);
204 udword Axis = Vars.LargestAxis();
207 NbPos = Split(Axis, builder);
210 if(!NbPos || NbPos==mNbPrimitives) ValidSplit =
false;
216 NbPos = Split(0, builder); Results[0] = float(NbPos)/float(mNbPrimitives);
217 NbPos = Split(1, builder); Results[1] = float(NbPos)/float(mNbPrimitives);
218 NbPos = Split(2, builder); Results[2] = float(NbPos)/float(mNbPrimitives);
219 Results[0]-=0.5f; Results[0]*=Results[0];
220 Results[1]-=0.5f; Results[1]*=Results[1];
221 Results[2]-=0.5f; Results[2]*=Results[2];
223 if(Results[1]<Results[Min]) Min = 1;
224 if(Results[2]<Results[Min]) Min = 2;
227 NbPos = Split(Min, builder);
230 if(!NbPos || NbPos==mNbPrimitives) ValidSplit =
false;
237 Point Extents; mBV.GetExtents(Extents);
238 udword SortedAxis[] = { 0, 1, 2 };
239 float* Keys = (
float*)&Extents.x;
244 if(Keys[SortedAxis[
i]]<Keys[SortedAxis[
i+1]])
247 SortedAxis[
i] = SortedAxis[
i+1];
248 SortedAxis[
i+1] = Tmp;
256 while(!ValidSplit && CurAxis!=3)
258 NbPos = Split(SortedAxis[CurAxis], builder);
260 if(!NbPos || NbPos==mNbPrimitives) CurAxis++;
261 else ValidSplit =
true;
267 NbPos = mNbPrimitives>>1;
281 NbPos = mNbPrimitives>>1;
295 mPos =
EXWORD(&Pool[Count+0])|1;
296 #ifndef OPC_NO_NEG_VANILLA_TREE
297 mNeg =
EXWORD(&Pool[Count+1])|1;
303 #ifndef OPC_NO_NEG_VANILLA_TREE
320 Pos->mNbPrimitives = NbPos;
363 if(Neg) Neg->
_Refit(builder);
424 mNodePrimitives = mIndices;
438 _BuildHierarchy(builder);
441 mTotalNbNodes = builder->
GetCount();
458 return Walk(
null,
null);
477 if(!current_node)
return;
481 if(current_depth>max_depth) max_depth = current_depth;
484 if(callback && !(callback)(current_node, current_depth, user_data))
return;
487 if(current_node->GetPos()) { _Walk(current_node->GetPos(), max_depth, current_depth, callback, user_data); current_depth--; }
488 if(current_node->GetNeg()) { _Walk(current_node->GetNeg(), max_depth, current_depth, callback, user_data); current_depth--; }
491 Local::_Walk(
this, MaxDepth, CurrentDepth, callback, user_data);
503 if(!builder)
return false;
517 if(!builder)
return false;
524 udword Index = mTotalNbNodes;
535 Current.GetPos()->GetAABB()->GetMin(Min);
536 Current.GetPos()->GetAABB()->GetMax(Max);
538 Current.GetNeg()->GetAABB()->GetMin(Min_);
539 Current.GetNeg()->GetAABB()->GetMax(Max_);
544 ((
AABB*)Current.GetAABB())->SetMinMax(Min, Max);
558 udword TotalSize = mTotalNbNodes*GetNodeSize();
559 if(mIndices) TotalSize+=mNbPrimitives*
sizeof(
udword);
572 return (GetNbNodes()==GetNbPrimitives()*2-1);