104 current_node->GetAABB()->GetCenter(linear[box_id].mAABB.mCenter);
105 current_node->GetAABB()->GetExtents(linear[box_id].mAABB.mExtents);
106 #if 1 // Added by AIST 107 linear[box_id].mAABB.CreateSSV();
110 if(current_node->IsLeaf())
117 linear[box_id].mData = (PrimitiveIndex<<1)|1;
122 udword PosID = current_id++;
123 udword NegID = current_id++;
125 linear[box_id].mData = (
EXWORD)&linear[PosID];
127 ASSERT(!(linear[box_id].mData&1));
166 current_node->GetAABB()->GetCenter(linear[box_id].mAABB.mCenter);
167 current_node->GetAABB()->GetExtents(linear[box_id].mAABB.mExtents);
176 linear[box_id].mPosData = (PrimitiveIndex<<1)|1;
181 udword PosID = current_id++;
183 linear[box_id].mPosData = (
EXWORD)&linear[PosID];
185 ASSERT(!(linear[box_id].mPosData&1));
197 linear[box_id].mNegData = (PrimitiveIndex<<1)|1;
202 udword NegID = current_id++;
204 linear[box_id].mNegData = (
EXWORD)&linear[NegID];
206 ASSERT(!(linear[box_id].mNegData&1));
216 AABBCollisionTree::AABBCollisionTree() : mNodes(
null)
225 AABBCollisionTree::~AABBCollisionTree()
241 if(!tree)
return false;
245 if(NbNodes!=NbTriangles*2-1)
return false;
261 mNodes[0].mB = &mNodes[0];
278 ASSERT(!
"Not implemented since AABBCollisionTrees have twice as more nodes to refit as AABBNoLeafTrees!");
292 if(!callback)
return false;
298 if(!current_node || !(callback)(current_node, user_data))
return;
300 if(!current_node->IsLeaf())
302 _Walk(current_node->GetPos(), callback, user_data);
303 _Walk(current_node->GetNeg(), callback, user_data);
307 Local::_Walk(mNodes, callback, user_data);
316 AABBNoLeafTree::AABBNoLeafTree() : mNodes(
null)
325 AABBNoLeafTree::~AABBNoLeafTree()
341 if(!tree)
return false;
345 if(NbNodes!=NbTriangles*2-1)
return false;
367 #ifdef OPC_USE_FCOMI // a 15% speedup on my machine, not much 396 if(!mesh_interface)
return false;
407 if(Current.HasPosLeaf())
409 mesh_interface->
GetTriangle(VP, Current.GetPosPrimitive());
419 if(Current.HasNegLeaf())
421 mesh_interface->
GetTriangle(VP, Current.GetNegPrimitive());
441 Current.mAABB.SetMinMax(Min, Max);
456 if(!callback)
return false;
462 if(!current_node || !(callback)(current_node, user_data))
return;
464 if(!current_node->HasPosLeaf()) _Walk(current_node->GetPos(), callback, user_data);
465 if(!current_node->HasNegLeaf()) _Walk(current_node->GetNeg(), callback, user_data);
468 Local::_Walk(mNodes, callback, user_data);
490 #define FIND_MAX_VALUES \ 492 Point CMax(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); \ 493 Point EMax(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); \ 494 for(udword i=0;i<mNbNodes;i++) \ 496 if(fabsf(Nodes[i].mAABB.mCenter.x)>CMax.x) CMax.x = fabsf(Nodes[i].mAABB.mCenter.x); \ 497 if(fabsf(Nodes[i].mAABB.mCenter.y)>CMax.y) CMax.y = fabsf(Nodes[i].mAABB.mCenter.y); \ 498 if(fabsf(Nodes[i].mAABB.mCenter.z)>CMax.z) CMax.z = fabsf(Nodes[i].mAABB.mCenter.z); \ 499 if(fabsf(Nodes[i].mAABB.mExtents.x)>EMax.x) EMax.x = fabsf(Nodes[i].mAABB.mExtents.x); \ 500 if(fabsf(Nodes[i].mAABB.mExtents.y)>EMax.y) EMax.y = fabsf(Nodes[i].mAABB.mExtents.y); \ 501 if(fabsf(Nodes[i].mAABB.mExtents.z)>EMax.z) EMax.z = fabsf(Nodes[i].mAABB.mExtents.z); \ 504 #define INIT_QUANTIZATION \ 507 if(!gFixQuantized) nbe++; \ 510 Point CQuantCoeff, EQuantCoeff; \ 511 CQuantCoeff.x = CMax.x!=0.0f ? float((1<<nbc)-1)/CMax.x : 0.0f; \ 512 CQuantCoeff.y = CMax.y!=0.0f ? float((1<<nbc)-1)/CMax.y : 0.0f; \ 513 CQuantCoeff.z = CMax.z!=0.0f ? float((1<<nbc)-1)/CMax.z : 0.0f; \ 514 EQuantCoeff.x = EMax.x!=0.0f ? float((1<<nbe)-1)/EMax.x : 0.0f; \ 515 EQuantCoeff.y = EMax.y!=0.0f ? float((1<<nbe)-1)/EMax.y : 0.0f; \ 516 EQuantCoeff.z = EMax.z!=0.0f ? float((1<<nbe)-1)/EMax.z : 0.0f; \ 518 mCenterCoeff.x = CQuantCoeff.x!=0.0f ? 1.0f / CQuantCoeff.x : 0.0f; \ 519 mCenterCoeff.y = CQuantCoeff.y!=0.0f ? 1.0f / CQuantCoeff.y : 0.0f; \ 520 mCenterCoeff.z = CQuantCoeff.z!=0.0f ? 1.0f / CQuantCoeff.z : 0.0f; \ 521 mExtentsCoeff.x = EQuantCoeff.x!=0.0f ? 1.0f / EQuantCoeff.x : 0.0f; \ 522 mExtentsCoeff.y = EQuantCoeff.y!=0.0f ? 1.0f / EQuantCoeff.y : 0.0f; \ 523 mExtentsCoeff.z = EQuantCoeff.z!=0.0f ? 1.0f / EQuantCoeff.z : 0.0f; \ 525 #define PERFORM_QUANTIZATION \ 527 mNodes[i].mAABB.mCenter[0] = sword(Nodes[i].mAABB.mCenter.x * CQuantCoeff.x); \ 528 mNodes[i].mAABB.mCenter[1] = sword(Nodes[i].mAABB.mCenter.y * CQuantCoeff.y); \ 529 mNodes[i].mAABB.mCenter[2] = sword(Nodes[i].mAABB.mCenter.z * CQuantCoeff.z); \ 530 mNodes[i].mAABB.mExtents[0] = uword(Nodes[i].mAABB.mExtents.x * EQuantCoeff.x); \ 531 mNodes[i].mAABB.mExtents[1] = uword(Nodes[i].mAABB.mExtents.y * EQuantCoeff.y); \ 532 mNodes[i].mAABB.mExtents[2] = uword(Nodes[i].mAABB.mExtents.z * EQuantCoeff.z); \ 537 Point Max = Nodes[i].mAABB.mCenter + Nodes[i].mAABB.mExtents; \ 538 Point Min = Nodes[i].mAABB.mCenter - Nodes[i].mAABB.mExtents; \ 540 for(udword j=0;j<3;j++) \ 542 float qc = float(mNodes[i].mAABB.mCenter[j]) * mCenterCoeff[j]; \ 546 float qe = float(mNodes[i].mAABB.mExtents[j]) * mExtentsCoeff[j]; \ 548 if(qc+qe<Max[j] || qc-qe>Min[j]) mNodes[i].mAABB.mExtents[j]++; \ 551 if(!mNodes[i].mAABB.mExtents[j]) \ 553 mNodes[i].mAABB.mExtents[j]=0xffff; \ 560 #if (defined __x86_64) || (defined __aarch64__) 561 #define REMAP_DATA(member) \ 563 Data = Nodes[i].member; \ 567 uqword Nb = (Data - uqword(Nodes))/Nodes[i].GetNodeSize(); \ 568 Data = uqword(&mNodes[Nb]); \ 571 mNodes[i].member = Data; 573 #define REMAP_DATA(member) \ 575 Data = Nodes[i].member; \ 579 udword Nb = (Data - udword(Nodes))/Nodes[i].GetNodeSize(); \ 580 Data = udword(&mNodes[Nb]); \ 583 mNodes[i].member = Data; 590 AABBQuantizedTree::AABBQuantizedTree() : mNodes(
null)
599 AABBQuantizedTree::~AABBQuantizedTree()
615 if(!tree)
return false;
619 if(NbNodes!=NbTriangles*2-1)
return false;
665 ASSERT(!
"Not implemented since requantizing is painful !");
679 if(!callback)
return false;
685 if(!current_node || !(callback)(current_node, user_data))
return;
687 if(!current_node->IsLeaf())
689 _Walk(current_node->GetPos(), callback, user_data);
690 _Walk(current_node->GetNeg(), callback, user_data);
694 Local::_Walk(mNodes, callback, user_data);
704 AABBQuantizedNoLeafTree::AABBQuantizedNoLeafTree() : mNodes(
null)
713 AABBQuantizedNoLeafTree::~AABBQuantizedNoLeafTree()
729 if(!tree)
return false;
733 if(NbNodes!=NbTriangles*2-1)
return false;
781 ASSERT(!
"Not implemented since requantizing is painful !");
795 if(!callback)
return false;
801 if(!current_node || !(callback)(current_node, user_data))
return;
803 if(!current_node->HasPosLeaf()) _Walk(current_node->GetPos(), callback, user_data);
804 if(!current_node->HasNegLeaf()) _Walk(current_node->GetNeg(), callback, user_data);
807 Local::_Walk(mNodes, callback, user_data);
inline_ float FCMin2(float a, float b)
A global function to find MIN(a,b) using FCOMI/FCMOV.
inline_ void GetTriangle(VertexPointers &vp, udword index) const
inline_ const udword * GetPrimitives() const
inline_ void GetMin(Point &min) const
Get min point of the box.
inline_ void ComputeMinMax(Point &min, Point &max, const VertexPointers &vp)
#define null
our own NULL pointer
static int min(int a, int b)
#define DELETEARRAY(x)
Deletes an array.
inline_ void GetMax(Point &max) const
Get max point of the box.
bool(* GenericWalkingCallback)(const void *current, void *user_data)
#define INIT_QUANTIZATION
unsigned int udword
sizeof(udword) must be 4
#define REMAP_DATA(member)
inline_ float Min() const
Returns MIN(x, y, z);.
#define PERFORM_QUANTIZATION
inline_ float Max() const
Returns MAX(x, y, z);.
virtual bool Build(AABBTree *tree)=0
static void _BuildCollisionTree(AABBCollisionNode *linear, const udword box_id, udword ¤t_id, const AABBTreeNode *current_node)
static bool gFixQuantized
virtual bool Walk(GenericWalkingCallback callback, void *user_data) const =0
virtual bool Refit(const MeshInterface *mesh_interface)=0
static void _BuildNoLeafTree(AABBNoLeafNode *linear, const udword box_id, udword ¤t_id, const AABBTreeNode *current_node)
inline_ float FCMin3(float a, float b, float c)
A global function to find MIN(a,b,c) using FCOMI/FCMOV.
inline_ float FCMax3(float a, float b, float c)
A global function to find MAX(a,b,c) using FCOMI/FCMOV.
inline_ udword GetNbPrimitives() const
inline_ udword GetNbNodes() const
Catch the number of nodes.
inline_ float FCMax2(float a, float b)
A global function to find MAX(a,b) using FCOMI/FCMOV.
static int max(int a, int b)