//----------------------------------------------------------------------- void InstanceBatch::defragmentBatchNoCull( InstancedEntityVec &usedEntities ) { const size_t maxInstancesToCopy = std::min( mInstancesPerBatch, usedEntities.size() ); InstancedEntityVec::iterator first = usedEntities.end() - maxInstancesToCopy; //Copy from the back to front, into m_instancedEntities mInstancedEntities.insert( mInstancedEntities.begin(), first, usedEntities.end() ); //Remove them from the array usedEntities.resize( usedEntities.size() - maxInstancesToCopy ); }
//----------------------------------------------------------------------- void InstanceBatch::defragmentBatchDoCull( InstancedEntityVec &usedEntities, CustomParamsVec &usedParams ) { //Get the the entity closest to the minimum bbox edge and put into "first" InstancedEntityVec::const_iterator itor = usedEntities.begin(); InstancedEntityVec::const_iterator end = usedEntities.end(); Vector3 vMinPos = Vector3::ZERO, firstPos = Vector3::ZERO; InstancedEntity *first = 0; if( !usedEntities.empty() ) { first = *usedEntities.begin(); firstPos = first->_getDerivedPosition(); vMinPos = first->_getDerivedPosition(); } while( itor != end ) { const Vector3 &vPos = (*itor)->_getDerivedPosition(); vMinPos.x = std::min( vMinPos.x, vPos.x ); vMinPos.y = std::min( vMinPos.y, vPos.y ); vMinPos.z = std::min( vMinPos.z, vPos.z ); if( vMinPos.squaredDistance( vPos ) < vMinPos.squaredDistance( firstPos ) ) { firstPos = vPos; } ++itor; } //Now collect entities closest to 'first' while( !usedEntities.empty() && mInstancedEntities.size() < mInstancesPerBatch ) { InstancedEntityVec::iterator closest = usedEntities.begin(); InstancedEntityVec::iterator it = usedEntities.begin(); InstancedEntityVec::iterator e = usedEntities.end(); Vector3 closestPos; closestPos = (*closest)->_getDerivedPosition(); while( it != e ) { const Vector3 &vPos = (*it)->_getDerivedPosition(); if( firstPos.squaredDistance( vPos ) < firstPos.squaredDistance( closestPos ) ) { closest = it; closestPos = vPos; } ++it; } mInstancedEntities.push_back( *closest ); //Now the custom params const size_t idx = closest - usedEntities.begin(); for( unsigned char i=0; i<mCreator->getNumCustomParams(); ++i ) { mCustomParams.push_back( usedParams[idx + i] ); } //Remove 'closest' from usedEntities & usedParams using swap and pop_back trick *closest = *(usedEntities.end() - 1); usedEntities.pop_back(); for( unsigned char i=1; i<=mCreator->getNumCustomParams(); ++i ) { usedParams[idx + mCreator->getNumCustomParams() - i] = *(usedParams.end() - 1); usedParams.pop_back(); } } }