Exemplo n.º 1
0
    void DiInstanceBatch::DefragmentBatchDoCull( InstancedModelVec &usedEntities )
    {
        auto itor = usedEntities.begin();
        auto end = usedEntities.end();

        DiVec3 vMinPos = DiVec3::ZERO, firstPos = DiVec3::ZERO;
        DiInstancedModelPtr first;

        if( !usedEntities.empty() )
        {
            first    = *usedEntities.begin();
            firstPos= first->GetDerivedPosition();
            vMinPos = first->GetDerivedPosition();
        }

        while( itor != end )
        {
            const DiVec3 &vPos = (*itor)->GetDerivedPosition();

            vMinPos.x = DiMath::Min( vMinPos.x, vPos.x );
            vMinPos.y = DiMath::Min( vMinPos.y, vPos.y );
            vMinPos.z = DiMath::Min( vMinPos.z, vPos.z );
            if( vMinPos.squaredDistance( vPos ) < vMinPos.squaredDistance( firstPos ) )
            {
                firstPos = vPos;
            }
            ++itor;
        }

        while( !usedEntities.empty() && mInstancedModels.size() < mInstancesPerBatch )
        {
            auto closest = usedEntities.begin();
            auto it = usedEntities.begin();
            auto e = usedEntities.end();

            DiVec3 closestPos;
            closestPos = (*closest)->GetDerivedPosition();

            while( it != e )
            {
                const DiVec3 &vPos = (*it)->GetDerivedPosition();
                if( firstPos.squaredDistance( vPos ) < firstPos.squaredDistance( closestPos ) )
                {
                    closest      = it;
                    closestPos   = vPos;
                }
                ++it;
            }

            mInstancedModels.push_back( *closest );

            *closest = *(usedEntities.end() - 1);
            usedEntities.pop_back();
        }
    }