| 452 | } |
| 453 | |
| 454 | void AABBTree::markNodeForRefit(TreeNodeIndex nodeIndex) |
| 455 | { |
| 456 | if(!mRefitBitmask.getBits()) |
| 457 | mRefitBitmask.init(mTotalNbNodes); |
| 458 | |
| 459 | PX_ASSERT(nodeIndex<mTotalNbNodes); |
| 460 | |
| 461 | // PT: lazy-create parent array. Memory is not wasted for purely static trees, or dynamic trees that only do "full refit". |
| 462 | if(!mParentIndices) |
| 463 | { |
| 464 | mParentIndices = reinterpret_cast<PxU32*>(PX_ALLOC(sizeof(PxU32)*mTotalNbNodes, "AABB parent indices")); |
| 465 | _createParentArray(mTotalNbNodes, mParentIndices, mRuntimePool, mRuntimePool, mRuntimePool); |
| 466 | } |
| 467 | |
| 468 | PxU32 currentIndex = nodeIndex; |
| 469 | while(1) |
| 470 | { |
| 471 | PX_ASSERT(currentIndex<mTotalNbNodes); |
| 472 | if(mRefitBitmask.isSet(currentIndex)) |
| 473 | { |
| 474 | // We can early exit if we already visited the node! |
| 475 | return; |
| 476 | } |
| 477 | else |
| 478 | { |
| 479 | mRefitBitmask.setBit(currentIndex); |
| 480 | const PxU32 currentMarkedWord = currentIndex>>5; |
| 481 | mRefitHighestSetWord = PxMax(mRefitHighestSetWord, currentMarkedWord); |
| 482 | |
| 483 | const PxU32 parentIndex = mParentIndices[currentIndex]; |
| 484 | PX_ASSERT(parentIndex == 0 || parentIndex < currentIndex); |
| 485 | if(currentIndex == parentIndex) |
| 486 | break; |
| 487 | currentIndex = parentIndex; |
| 488 | } |
| 489 | } |
| 490 | } |
| 491 | |
| 492 | #define FIRST_VERSION |
| 493 | #ifdef FIRST_VERSION |
no test coverage detected