void Batch::Sector::forAllInstancesInAABB(Geometry* geometryLod0, Matrix* instances, AABB* aabb, engine::IBatchCallback callback, void* data) { if( ::intersectionAABBAABB( &boundingBox, aabb ) ) { if( !left && !right ) { AABB instanceAABB; Matrix4f instanceMatrix; unsigned int index; for( unsigned int i=0; i<numIndices; i++ ) { index = indices[i]; instanceAABB.calculate( geometryLod0->getBoundingBox(), instances + index ); if( ::intersectionAABBAABB( &instanceAABB, aabb ) ) { instanceMatrix = wrap( instances[index] ); callback( index, &instanceMatrix, data ); } } } else { if( left ) static_cast<Sector*>(left)->forAllInstancesInAABB( geometryLod0, instances, aabb, callback, data ); if( right ) static_cast<Sector*>(right)->forAllInstancesInAABB( geometryLod0, instances, aabb, callback, data ); } } }
Batch::Sector* Batch::Sector::createTree(unsigned int leafSize, Geometry* geometryLod0, Matrix* instances, unsigned int numInstances) { DynamicIndices batchIndices; for( unsigned int i=0; i<numInstances; i++ ) batchIndices.insert( i ); AABB batchAABB; AABB instanceAABB; batchAABB.calculate( geometryLod0->getBoundingBox(), instances ); for( unsigned int i=1; i<numInstances; i++ ) { instanceAABB.calculate( geometryLod0->getBoundingBox(), instances+i ); batchAABB.addAABB( &instanceAABB ); } return new Sector( leafSize, geometryLod0, instances, &batchAABB, batchIndices ); }
Batch::Sector::Sector(unsigned int leafSize, Geometry* geometryLod0, Matrix* instances, AABB* aabb, DynamicIndices& parentIndices, float treeProgress, float sectorProgress) { boundingBox = *aabb; left = right = NULL; // local indices DynamicIndices dynamicIndices; // show progress if( Engine::instance->progressCallback ) { Engine::instance->progressCallback( Gui::iLanguage->getUnicodeString(7), treeProgress, Engine::instance->progressCallbackUserData ); } // calculate bounding sphere Vector corner[8]; unsigned int i; for( i=0; i<8; i++ ) corner[i] = boundingBox.getCorner( i ); boundingSphere.calculate( 8, corner ); // build list of indices inside AABB of this unsigned int instanceId; AABB instanceAABB; DynamicIndex index; for( index = parentIndices.begin(); index != parentIndices.end(); index++ ) { instanceId = (*index); instanceAABB.calculate( geometryLod0->getBoundingBox(), instances+instanceId ); if( ::intersectionAABBAABB( &boundingBox, &instanceAABB ) ) { dynamicIndices.insert( instanceId ); } } // remove this indices from parent indices DynamicIndex parentIndex; for( index = dynamicIndices.begin(); index != dynamicIndices.end(); index++ ) { parentIndex = parentIndices.find( (*index) ); assert( parentIndex != parentIndices.end() ); parentIndices.erase( parentIndex ); } // build subsets if( dynamicIndices.size() > leafSize ) { AABB leftAABB; AABB rightAABB; boundingBox.divide( leftAABB, rightAABB, AABB::maxPlane ); left = new Sector( leafSize, geometryLod0, instances, &leftAABB, dynamicIndices, treeProgress, sectorProgress * 0.5f ); if( static_cast<Sector*>(left)->getNumInstancesInHierarchy() == 0 ) { delete left; left = NULL; } right = new Sector( leafSize, geometryLod0, instances, &rightAABB, dynamicIndices, treeProgress + sectorProgress * 0.5f, sectorProgress * 0.5f ); if( static_cast<Sector*>(right)->getNumInstancesInHierarchy() == 0 ) { delete right; right = NULL; } } if( !left && !right ) { // build static indices numIndices = dynamicIndices.size(); indices = new unsigned int[numIndices]; for( index = dynamicIndices.begin(), i = 0; index != dynamicIndices.end(); index++, i++ ) { indices[i] = *index; } dynamicIndices.clear(); } else { numIndices = 0; indices = NULL; } // show progress if( Engine::instance->progressCallback ) { Engine::instance->progressCallback( Gui::iLanguage->getUnicodeString(7), treeProgress + sectorProgress, Engine::instance->progressCallbackUserData ); } }