mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 20:54:46 +00:00
226 lines
5.7 KiB
C++
226 lines
5.7 KiB
C++
//-----------------------------------------------------------------------------
|
|
// Copyright (c) 2012 GarageGames, LLC
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to
|
|
// deal in the Software without restriction, including without limitation the
|
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
// sell copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
// IN THE SOFTWARE.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "platform/platform.h"
|
|
#include "shaderGen/featureSet.h"
|
|
|
|
#include "shaderGen/featureType.h"
|
|
#include "platform/profiler.h"
|
|
#include "core/util/hashFunction.h"
|
|
|
|
|
|
const FeatureSet FeatureSet::EmptySet;
|
|
|
|
|
|
S32 QSORT_CALLBACK FeatureSet::_typeCmp( const FeatureInfo* a, const FeatureInfo* b )
|
|
{
|
|
if ( a->type->getGroup() < b->type->getGroup() )
|
|
return -1;
|
|
else if ( a->type->getGroup() > b->type->getGroup() )
|
|
return 1;
|
|
else if ( a->index < b->index )
|
|
return -1;
|
|
else if ( a->index > b->index )
|
|
return 1;
|
|
else if ( a->type->getOrder() < b->type->getOrder() )
|
|
return -1;
|
|
else if ( a->type->getOrder() > b->type->getOrder() )
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
void FeatureSet::_rebuildDesc()
|
|
{
|
|
PROFILE_SCOPE( FeatureSet_RebuildDesc );
|
|
|
|
// First get the features in the proper order.
|
|
mFeatures.sort( _typeCmp );
|
|
|
|
String desc;
|
|
|
|
for ( U32 i=0; i < mFeatures.size(); i++ )
|
|
desc += String::ToString( "%s,%d\n",
|
|
mFeatures[i].type->getName().c_str(),
|
|
mFeatures[i].index );
|
|
|
|
// By interning the description we have only
|
|
// one instance in the system and we get fast
|
|
// pointer compares for equality.
|
|
mDescription = desc.intern();
|
|
}
|
|
|
|
const FeatureType& FeatureSet::getAt( U32 index, S32 *outIndex ) const
|
|
{
|
|
// We want to make sure we access the features in the
|
|
// correct order. By asking for the description we ensure
|
|
// the feature set is properly sorted.
|
|
getDescription();
|
|
|
|
if ( outIndex )
|
|
*outIndex = mFeatures[index].index;
|
|
|
|
return *mFeatures[index].type;
|
|
}
|
|
|
|
void FeatureSet::clear()
|
|
{
|
|
mDescription.clear();
|
|
mFeatures.clear();
|
|
}
|
|
|
|
FeatureSet& FeatureSet::operator =( const FeatureSet &h )
|
|
{
|
|
clear();
|
|
merge( h );
|
|
return *this;
|
|
}
|
|
|
|
bool FeatureSet::hasFeature( const FeatureType &type, S32 index ) const
|
|
{
|
|
PROFILE_SCOPE(FeatureSet_hasFeature);
|
|
|
|
for ( U32 i = 0; i < mFeatures.size(); i++)
|
|
{
|
|
if ( mFeatures[i].type == &type &&
|
|
( index < 0 || mFeatures[i].index == index ) )
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void FeatureSet::setFeature( const FeatureType &type, bool set, S32 index )
|
|
{
|
|
for ( U32 i=0; i < mFeatures.size(); i++ )
|
|
{
|
|
const FeatureInfo &info = mFeatures[i];
|
|
if ( info.type == &type && info.index == index )
|
|
{
|
|
if ( set )
|
|
return;
|
|
else
|
|
{
|
|
mFeatures.erase_fast( i );
|
|
mDescription.clear();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( !set )
|
|
return;
|
|
|
|
FeatureInfo info;
|
|
info.type = &type;
|
|
info.index = index;
|
|
mFeatures.push_back( info );
|
|
|
|
mDescription.clear();
|
|
}
|
|
|
|
void FeatureSet::addFeature( const FeatureType &type, S32 index )
|
|
{
|
|
for ( U32 i=0; i < mFeatures.size(); i++ )
|
|
{
|
|
const FeatureInfo &info = mFeatures[i];
|
|
if ( info.type == &type &&
|
|
info.index == index )
|
|
return;
|
|
}
|
|
|
|
FeatureInfo info;
|
|
info.type = &type;
|
|
info.index = index;
|
|
mFeatures.push_back( info );
|
|
|
|
mDescription.clear();
|
|
}
|
|
|
|
void FeatureSet::removeFeature( const FeatureType &type )
|
|
{
|
|
for ( U32 i=0; i < mFeatures.size(); i++ )
|
|
{
|
|
const FeatureInfo &info = mFeatures[i];
|
|
if ( info.type == &type )
|
|
{
|
|
mFeatures.erase_fast( i );
|
|
mDescription.clear();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
S32 FeatureSet::getNextFeatureIndex( const FeatureType &type, S32 index ) const
|
|
{
|
|
for ( U32 i=0; i < mFeatures.size(); i++ )
|
|
{
|
|
const FeatureInfo &info = mFeatures[i];
|
|
if ( info.type == &type && info.index > index )
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void FeatureSet::filter( const FeatureSet &features )
|
|
{
|
|
PROFILE_SCOPE( FeatureSet_Filter );
|
|
|
|
for ( U32 i=0; i < mFeatures.size(); )
|
|
{
|
|
if ( !features.hasFeature( *mFeatures[i].type ) )
|
|
mFeatures.erase_fast( i );
|
|
else
|
|
i++;
|
|
}
|
|
|
|
mDescription.clear();
|
|
}
|
|
|
|
void FeatureSet::exclude( const FeatureSet &features )
|
|
{
|
|
PROFILE_SCOPE( FeatureSet_Exclude );
|
|
|
|
for ( U32 i=0; i < features.mFeatures.size(); i++ )
|
|
removeFeature( *features.mFeatures[i].type );
|
|
|
|
mDescription.clear();
|
|
}
|
|
|
|
void FeatureSet::merge( const FeatureSet &features )
|
|
{
|
|
PROFILE_SCOPE( FeatureSet_Merge );
|
|
|
|
if ( mFeatures.empty() )
|
|
{
|
|
mFeatures.merge( features.mFeatures );
|
|
mDescription = features.mDescription;
|
|
return;
|
|
}
|
|
|
|
for ( U32 i=0; i < features.mFeatures.size(); i++ )
|
|
addFeature( *features.mFeatures[i].type,
|
|
features.mFeatures[i].index );
|
|
}
|
|
|