72 using namespace Opcode;
106 current_node->GetAABB()->GetCenter(linear[box_id].mAABB.mCenter);
107 current_node->GetAABB()->GetExtents(linear[box_id].mAABB.mExtents);
109 if(current_node->IsLeaf())
116 linear[box_id].mData = (PrimitiveIndex<<1)|1;
121 udword PosID = current_id++;
122 udword NegID = current_id++;
124 linear[box_id].mData = (uintptr_t)&linear[PosID];
126 OPASSERT(!(linear[box_id].mData&1));
160 current_node->GetAABB()->GetCenter(linear[box_id].mAABB.mCenter);
161 current_node->GetAABB()->GetExtents(linear[box_id].mAABB.mExtents);
170 linear[box_id].mPosData = (PrimitiveIndex<<1)|1;
175 udword PosID = current_id++;
177 linear[box_id].mPosData = (uintptr_t)&linear[PosID];
179 OPASSERT(!(linear[box_id].mPosData&1));
191 linear[box_id].mNegData = (PrimitiveIndex<<1)|1;
196 udword NegID = current_id++;
198 linear[box_id].mNegData = (uintptr_t)&linear[NegID];
200 OPASSERT(!(linear[box_id].mNegData&1));
210 AABBCollisionTree::AABBCollisionTree() : mNodes(
null)
219 AABBCollisionTree::~AABBCollisionTree()
235 if(!tree)
return false;
239 if(NbNodes!=NbTriangles*2-1)
return false;
267 OPASSERT(!
"Not implemented since AABBCollisionTrees have twice as more nodes to refit as AABBNoLeafTrees!");
281 if(!callback)
return false;
287 if(!current_node || !(callback)(current_node, user_data))
return;
289 if(!current_node->IsLeaf())
291 _Walk(current_node->GetPos(), callback, user_data);
292 _Walk(current_node->GetNeg(), callback, user_data);
296 Local::_Walk(mNodes, callback, user_data);
305 AABBNoLeafTree::AABBNoLeafTree() : mNodes(
null)
314 AABBNoLeafTree::~AABBNoLeafTree()
330 if(!tree)
return false;
334 if(NbNodes!=NbTriangles*2-1)
return false;
356 #ifdef OPC_USE_FCOMI // a 15% speedup on my machine, not much
385 if(!mesh_interface)
return false;
396 if(Current.HasPosLeaf())
398 mesh_interface->
GetTriangle(VP, Current.GetPosPrimitive());
408 if(Current.HasNegLeaf())
410 mesh_interface->
GetTriangle(VP, Current.GetNegPrimitive());
420 Min.
x = FCMin2(Min.
x, Min_.
x);
421 Max.
x = FCMax2(Max.
x, Max_.
x);
422 Min.
y = FCMin2(Min.
y, Min_.
y);
423 Max.
y = FCMax2(Max.
y, Max_.
y);
424 Min.
z = FCMin2(Min.
z, Min_.
z);
425 Max.
z = FCMax2(Max.
z, Max_.
z);
430 Current.mAABB.SetMinMax(Min, Max);
445 if(!callback)
return false;
451 if(!current_node || !(callback)(current_node, user_data))
return;
453 if(!current_node->HasPosLeaf()) _Walk(current_node->GetPos(), callback, user_data);
454 if(!current_node->HasNegLeaf()) _Walk(current_node->GetNeg(), callback, user_data);
457 Local::_Walk(mNodes, callback, user_data);
479 #define FIND_MAX_VALUES \
481 Point CMax(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); \
482 Point EMax(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); \
483 for(i=0;i<mNbNodes;i++) \
485 if(fabsf(Nodes[i].mAABB.mCenter.x)>CMax.x) CMax.x = fabsf(Nodes[i].mAABB.mCenter.x); \
486 if(fabsf(Nodes[i].mAABB.mCenter.y)>CMax.y) CMax.y = fabsf(Nodes[i].mAABB.mCenter.y); \
487 if(fabsf(Nodes[i].mAABB.mCenter.z)>CMax.z) CMax.z = fabsf(Nodes[i].mAABB.mCenter.z); \
488 if(fabsf(Nodes[i].mAABB.mExtents.x)>EMax.x) EMax.x = fabsf(Nodes[i].mAABB.mExtents.x); \
489 if(fabsf(Nodes[i].mAABB.mExtents.y)>EMax.y) EMax.y = fabsf(Nodes[i].mAABB.mExtents.y); \
490 if(fabsf(Nodes[i].mAABB.mExtents.z)>EMax.z) EMax.z = fabsf(Nodes[i].mAABB.mExtents.z); \
493 #define INIT_QUANTIZATION \
496 if(!gFixQuantized) nbe++; \
499 Point CQuantCoeff, EQuantCoeff; \
500 CQuantCoeff.x = CMax.x!=0.0f ? float((1<<nbc)-1)/CMax.x : 0.0f; \
501 CQuantCoeff.y = CMax.y!=0.0f ? float((1<<nbc)-1)/CMax.y : 0.0f; \
502 CQuantCoeff.z = CMax.z!=0.0f ? float((1<<nbc)-1)/CMax.z : 0.0f; \
503 EQuantCoeff.x = EMax.x!=0.0f ? float((1<<nbe)-1)/EMax.x : 0.0f; \
504 EQuantCoeff.y = EMax.y!=0.0f ? float((1<<nbe)-1)/EMax.y : 0.0f; \
505 EQuantCoeff.z = EMax.z!=0.0f ? float((1<<nbe)-1)/EMax.z : 0.0f; \
507 mCenterCoeff.x = CQuantCoeff.x!=0.0f ? 1.0f / CQuantCoeff.x : 0.0f; \
508 mCenterCoeff.y = CQuantCoeff.y!=0.0f ? 1.0f / CQuantCoeff.y : 0.0f; \
509 mCenterCoeff.z = CQuantCoeff.z!=0.0f ? 1.0f / CQuantCoeff.z : 0.0f; \
510 mExtentsCoeff.x = EQuantCoeff.x!=0.0f ? 1.0f / EQuantCoeff.x : 0.0f; \
511 mExtentsCoeff.y = EQuantCoeff.y!=0.0f ? 1.0f / EQuantCoeff.y : 0.0f; \
512 mExtentsCoeff.z = EQuantCoeff.z!=0.0f ? 1.0f / EQuantCoeff.z : 0.0f; \
514 #define PERFORM_QUANTIZATION \
516 mNodes[i].mAABB.mCenter[0] = sword(Nodes[i].mAABB.mCenter.x * CQuantCoeff.x); \
517 mNodes[i].mAABB.mCenter[1] = sword(Nodes[i].mAABB.mCenter.y * CQuantCoeff.y); \
518 mNodes[i].mAABB.mCenter[2] = sword(Nodes[i].mAABB.mCenter.z * CQuantCoeff.z); \
519 mNodes[i].mAABB.mExtents[0] = uword(Nodes[i].mAABB.mExtents.x * EQuantCoeff.x); \
520 mNodes[i].mAABB.mExtents[1] = uword(Nodes[i].mAABB.mExtents.y * EQuantCoeff.y); \
521 mNodes[i].mAABB.mExtents[2] = uword(Nodes[i].mAABB.mExtents.z * EQuantCoeff.z); \
526 Point Max = Nodes[i].mAABB.mCenter + Nodes[i].mAABB.mExtents; \
527 Point Min = Nodes[i].mAABB.mCenter - Nodes[i].mAABB.mExtents; \
529 for(udword j=0;j<3;j++) \
531 if (fabs (mExtentsCoeff[j]) < 0.00001) \
533 mNodes[i].mAABB.mExtents[j]=0xffff; \
537 float qc = float(mNodes[i].mAABB.mCenter[j]) * mCenterCoeff[j]; \
541 float qe = float(mNodes[i].mAABB.mExtents[j]) * mExtentsCoeff[j]; \
543 if(qc+qe<Max[j] || qc-qe>Min[j]) mNodes[i].mAABB.mExtents[j]++; \
546 if(!mNodes[i].mAABB.mExtents[j]) \
548 mNodes[i].mAABB.mExtents[j]=0xffff; \
556 #define REMAP_DATA(member) \
558 Data = Nodes[i].member; \
562 udword Nb = (Data - uintptr_t(Nodes))/Nodes[i].GetNodeSize(); \
563 Data = uintptr_t(&mNodes[Nb]); \
566 mNodes[i].member = Data;
572 AABBQuantizedTree::AABBQuantizedTree() : mNodes(
null)
581 AABBQuantizedTree::~AABBQuantizedTree()
597 if(!tree)
return false;
601 if(NbNodes!=NbTriangles*2-1)
return false;
648 OPASSERT(!
"Not implemented since requantizing is painful !");
662 if(!callback)
return false;
668 if(!current_node || !(callback)(current_node, user_data))
return;
670 if(!current_node->IsLeaf())
672 _Walk(current_node->GetPos(), callback, user_data);
673 _Walk(current_node->GetNeg(), callback, user_data);
677 Local::_Walk(mNodes, callback, user_data);
687 AABBQuantizedNoLeafTree::AABBQuantizedNoLeafTree() : mNodes(
null)
696 AABBQuantizedNoLeafTree::~AABBQuantizedNoLeafTree()
712 if(!tree)
return false;
716 if(NbNodes!=NbTriangles*2-1)
return false;
765 OPASSERT(!
"Not implemented since requantizing is painful !");
779 if(!callback)
return false;
785 if(!current_node || !(callback)(current_node, user_data))
return;
787 if(!current_node->HasPosLeaf()) _Walk(current_node->GetPos(), callback, user_data);
788 if(!current_node->HasNegLeaf()) _Walk(current_node->GetNeg(), callback, user_data);
791 Local::_Walk(mNodes, callback, user_data);