mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-08 09:49:36 +00:00
1
This commit is contained in:
@@ -0,0 +1,577 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#include "datamodel/dmelementfactoryhelper.h"
|
||||
#include "movieobjects/dmeselection.h"
|
||||
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Expose this class to the scene database
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_ELEMENT_FACTORY( DmeComponent, CDmeComponent );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeComponent::OnConstruction()
|
||||
{
|
||||
m_Type.InitAndSet( this, "componentType", COMP_INVALID );
|
||||
m_bComplete.InitAndSet( this, "complete", false );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeComponent::OnDestruction()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeComponent::Resolve()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Expose this class to the scene database
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_ELEMENT_FACTORY( DmeSingleIndexedComponent, CDmeSingleIndexedComponent );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSingleIndexedComponent::OnConstruction()
|
||||
{
|
||||
m_CompleteCount.InitAndSet( this, "completeCount", 0 );
|
||||
m_Components.Init( this, "components" );
|
||||
m_Weights.Init( this, "weights" );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSingleIndexedComponent::OnDestruction()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSingleIndexedComponent::Resolve()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
int CDmeSingleIndexedComponent::Count() const
|
||||
{
|
||||
return IsComplete() ? m_CompleteCount.Get() : m_Components.Count();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CDmeSingleIndexedComponent::SetType( Component_t type )
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case COMP_VTX:
|
||||
case COMP_FACE:
|
||||
m_Type.Set( type );
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSingleIndexedComponent::AddComponent( int component, float weight /*= 1.0f */ )
|
||||
{
|
||||
if ( IsComplete() )
|
||||
return;
|
||||
|
||||
const int index( BinarySearch( component ) );
|
||||
Assert( index >= 0 );
|
||||
Assert( index <= m_Components.Count() );
|
||||
if ( index == m_Components.Count() )
|
||||
{
|
||||
m_Components.AddToTail( component );
|
||||
m_Weights.AddToTail( weight );
|
||||
}
|
||||
else if ( component == m_Components.Get( index ) )
|
||||
{
|
||||
Assert( index < m_Weights.Count() );
|
||||
m_Weights.Set( index, weight );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Components.InsertBefore( index, component );
|
||||
m_Weights.InsertBefore( index, weight );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSingleIndexedComponent::AddComponents( const CUtlVector< int > &components )
|
||||
{
|
||||
const int nComponents( components.Count() );
|
||||
for ( int i( 0 ); i < nComponents; ++i )
|
||||
{
|
||||
AddComponent( components[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSingleIndexedComponent::AddComponents(
|
||||
const CUtlVector< int > &components, const CUtlVector< float > &weights )
|
||||
{
|
||||
const int nComponents( min( components.Count(), weights.Count() ) );
|
||||
for ( int i( 0 ); i < nComponents; ++i )
|
||||
{
|
||||
AddComponent( components[ i ], weights[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSingleIndexedComponent::RemoveComponent( int component )
|
||||
{
|
||||
Assert( !IsComplete() ); // TODO: Convert from complete to complete - component
|
||||
|
||||
const int cIndex = BinarySearch( component );
|
||||
if ( cIndex >= m_Components.Count() || m_Components[ cIndex ] != component ) // Component not in selection
|
||||
return;
|
||||
|
||||
m_Components.Remove( cIndex );
|
||||
m_Weights.Remove( cIndex );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CDmeSingleIndexedComponent::GetComponent( int index, int &component, float &weight ) const
|
||||
{
|
||||
if ( index < Count() )
|
||||
{
|
||||
if ( IsComplete() )
|
||||
{
|
||||
component = index;
|
||||
weight = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
component = m_Components[ index ];
|
||||
weight = m_Weights[ index ];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSingleIndexedComponent::GetComponents( CUtlVector< int > &components, CUtlVector< float > &weights ) const
|
||||
{
|
||||
if ( IsComplete() )
|
||||
{
|
||||
const int nComponents = Count();
|
||||
|
||||
int *pComponents = reinterpret_cast< int * >( alloca( nComponents * sizeof( int ) ) );
|
||||
float *pWeights = reinterpret_cast< float * >( alloca( nComponents * sizeof( float ) ) );
|
||||
|
||||
for ( int i = 0; i < nComponents; ++i )
|
||||
{
|
||||
pComponents[ i ] = i;
|
||||
pWeights[ i ] = 1.0f;
|
||||
}
|
||||
|
||||
components.CopyArray( pComponents, nComponents );
|
||||
weights.CopyArray( pWeights, nComponents );
|
||||
}
|
||||
else
|
||||
{
|
||||
components.RemoveAll();
|
||||
components.CopyArray( m_Components.Base(), m_Components.Count() );
|
||||
|
||||
weights.RemoveAll();
|
||||
weights.CopyArray( m_Weights.Base(), m_Weights.Count() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSingleIndexedComponent::GetComponents( CUtlVector< int > &components ) const
|
||||
{
|
||||
if ( IsComplete() )
|
||||
{
|
||||
const int nComponents = Count();
|
||||
|
||||
int *pComponents = reinterpret_cast< int * >( alloca( nComponents * sizeof( int ) ) );
|
||||
|
||||
for ( int i = 0; i < nComponents; ++i )
|
||||
{
|
||||
pComponents[ i ] = i;
|
||||
}
|
||||
|
||||
components.CopyArray( pComponents, nComponents );
|
||||
}
|
||||
else
|
||||
{
|
||||
components.RemoveAll();
|
||||
components.CopyArray( m_Components.Base(), m_Components.Count() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSingleIndexedComponent::SetComplete( int nComplete )
|
||||
{
|
||||
m_bComplete.Set( true );
|
||||
m_CompleteCount.Set( max( 0, nComplete ) );
|
||||
m_Components.Purge();
|
||||
m_Weights.Purge();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
int CDmeSingleIndexedComponent::GetComplete() const
|
||||
{
|
||||
return IsComplete() ? m_CompleteCount.Get() : 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Reset to an empty selection
|
||||
//-----------------------------------------------------------------------------
|
||||
inline void CDmeSingleIndexedComponent::Clear()
|
||||
{
|
||||
CDmeComponent::Clear();
|
||||
m_CompleteCount.Set( 0 );
|
||||
m_Components.RemoveAll();
|
||||
m_Weights.RemoveAll();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Searches for the component in the sorted component list and returns the
|
||||
// index if it's found or if it's not found, returns the index at which it
|
||||
// should be inserted to maintain the sorted order of the component list
|
||||
//-----------------------------------------------------------------------------
|
||||
int CDmeSingleIndexedComponent::BinarySearch( int component ) const
|
||||
{
|
||||
const CUtlVector< int > &components( m_Components.Get() );
|
||||
const int nComponents( components.Count() );
|
||||
|
||||
int left( 0 );
|
||||
int right( nComponents - 1 );
|
||||
int mid;
|
||||
|
||||
while ( left <= right )
|
||||
{
|
||||
mid = ( left + right ) >> 1; // floor( ( left + right ) / 2.0 )
|
||||
if ( component > m_Components[ mid ] )
|
||||
{
|
||||
left = mid + 1;
|
||||
}
|
||||
else if ( component < m_Components[ mid ] )
|
||||
{
|
||||
right = mid - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
|
||||
return left;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CDmeSingleIndexedComponent::HasComponent( int component ) const
|
||||
{
|
||||
if ( IsComplete() )
|
||||
return true;
|
||||
|
||||
const int cIndex = BinarySearch( component );
|
||||
if ( cIndex >= m_Components.Count() )
|
||||
return false;
|
||||
|
||||
if ( m_Components[ cIndex ] == component )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CDmeSingleIndexedComponent::GetWeight( int component, float &weight ) const
|
||||
{
|
||||
Assert( !IsComplete() );
|
||||
|
||||
const int cIndex = BinarySearch( component );
|
||||
if ( cIndex >= m_Components.Count() )
|
||||
return false;
|
||||
|
||||
if ( m_Components[ cIndex ] == component )
|
||||
{
|
||||
weight = m_Weights[ cIndex ];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSingleIndexedComponent::Subtract( const CDmeSingleIndexedComponent &rhs )
|
||||
{
|
||||
const int nLhs = Count();
|
||||
const int nRhs = rhs.Count();
|
||||
|
||||
int l = 0;
|
||||
int r = 0;
|
||||
|
||||
if ( IsComplete() )
|
||||
{
|
||||
// TODO
|
||||
Assert( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
CUtlVector< int > newComponents;
|
||||
newComponents.EnsureCapacity( nLhs );
|
||||
CUtlVector< float > newWeights;
|
||||
newWeights.EnsureCapacity( nLhs );
|
||||
|
||||
while ( l < nLhs || r < nRhs )
|
||||
{
|
||||
// In LHS but not RHS
|
||||
while ( l < nLhs && ( r >= nRhs || m_Components[ l ] < rhs.m_Components[ r ] ) )
|
||||
{
|
||||
newComponents.AddToTail( m_Components[ l ] );
|
||||
newWeights.AddToTail( m_Weights[ l ] );
|
||||
++l;
|
||||
}
|
||||
|
||||
// In RHS but not LHS
|
||||
while ( r < nRhs && ( l >= nLhs || m_Components[ l ] > rhs.m_Components[ r ] ) )
|
||||
{
|
||||
++r;
|
||||
}
|
||||
|
||||
// In Both LHS & RHS
|
||||
while ( l < nLhs && r < nRhs && m_Components[ l ] == rhs.m_Components[ r ] )
|
||||
{
|
||||
++l;
|
||||
++r;
|
||||
}
|
||||
}
|
||||
|
||||
m_Components.CopyArray( newComponents.Base(), newComponents.Count() );
|
||||
m_Weights.CopyArray( newWeights.Base(), newWeights.Count() );
|
||||
}
|
||||
|
||||
m_CompleteCount.Set( 0 );
|
||||
m_bComplete.Set( false );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSingleIndexedComponent::Add( const CDmeSingleIndexedComponent &rhs )
|
||||
{
|
||||
int nLhs = Count();
|
||||
const int nRhs = rhs.Count();
|
||||
|
||||
int l = 0;
|
||||
int r = 0;
|
||||
|
||||
if ( IsComplete() )
|
||||
{
|
||||
if ( rhs.IsComplete() && nRhs > nLhs )
|
||||
{
|
||||
m_CompleteCount.Set( nRhs );
|
||||
}
|
||||
else
|
||||
{
|
||||
while ( r < nRhs )
|
||||
{
|
||||
if ( rhs.m_Components[ r ] >= nLhs )
|
||||
{
|
||||
// Got one that's greater than the complete count of this one
|
||||
|
||||
CUtlVector< int > newComponents;
|
||||
newComponents.EnsureCapacity( nLhs + nRhs - r );
|
||||
|
||||
CUtlVector< float > newWeights;
|
||||
newWeights.EnsureCapacity( nLhs + nRhs - r );
|
||||
|
||||
GetComponents( newComponents, newWeights );
|
||||
|
||||
while ( r < nRhs )
|
||||
{
|
||||
newComponents.AddToTail( rhs.m_Components[ r ] );
|
||||
newWeights.AddToTail( rhs.m_Weights[ r ] );
|
||||
++r;
|
||||
}
|
||||
|
||||
m_Components.CopyArray( newComponents.Base(), newComponents.Count() );
|
||||
m_Weights.CopyArray( newWeights.Base(), newWeights.Count() );
|
||||
|
||||
m_CompleteCount.Set( 0 );
|
||||
m_bComplete.Set( false );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
++r;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CUtlVector< int > newComponents;
|
||||
newComponents.EnsureCapacity( nLhs + nRhs * 0.5 ); // Just an estimate assuming 50% of the components in rhs aren't in lhs
|
||||
CUtlVector< float > newWeights;
|
||||
newWeights.EnsureCapacity( nLhs + nRhs * 0.5 ); // Just an estimate
|
||||
|
||||
while ( l < nLhs || r < nRhs )
|
||||
{
|
||||
while ( l < nLhs && ( r >= nRhs || m_Components[ l ] < rhs.m_Components[ r ] ) )
|
||||
{
|
||||
newComponents.AddToTail( m_Components[ l ] );
|
||||
newWeights.AddToTail( m_Weights[ l ] );
|
||||
++l;
|
||||
}
|
||||
|
||||
// In RHS but not LHS
|
||||
while ( r < nRhs && ( l >= nLhs || m_Components[ l ] > rhs.m_Components[ r ] ) )
|
||||
{
|
||||
newComponents.AddToTail( rhs.m_Components[ r ] );
|
||||
newWeights.AddToTail( rhs.m_Weights[ r ] );
|
||||
++r;
|
||||
}
|
||||
|
||||
// In Both LHS & RHS
|
||||
while ( l < nLhs && r < nRhs && m_Components[ l ] == rhs.m_Components[ r ] )
|
||||
{
|
||||
newComponents.AddToTail( m_Components[ l ] );
|
||||
newWeights.AddToTail( m_Weights[ l ] );
|
||||
++l;
|
||||
++r;
|
||||
}
|
||||
}
|
||||
|
||||
m_Components.CopyArray( newComponents.Base(), newComponents.Count() );
|
||||
m_Weights.CopyArray( newWeights.Base(), newWeights.Count() );
|
||||
}
|
||||
|
||||
m_CompleteCount.Set( 0 );
|
||||
m_bComplete.Set( false );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void CDmeSingleIndexedComponent::Intersection( const CDmeSingleIndexedComponent &rhs )
|
||||
{
|
||||
const int nLhs = Count();
|
||||
const int nRhs = rhs.Count();
|
||||
|
||||
int l = 0;
|
||||
int r = 0;
|
||||
|
||||
if ( IsComplete() )
|
||||
{
|
||||
// TODO
|
||||
Assert( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
CUtlVector< int > newComponents;
|
||||
newComponents.EnsureCapacity( nLhs );
|
||||
CUtlVector< float > newWeights;
|
||||
newWeights.EnsureCapacity( nLhs );
|
||||
|
||||
while ( l < nLhs || r < nRhs )
|
||||
{
|
||||
// In LHS but not RHS
|
||||
while ( l < nLhs && ( r >= nRhs || m_Components[ l ] < rhs.m_Components[ r ] ) )
|
||||
{
|
||||
++l;
|
||||
}
|
||||
|
||||
// In RHS but not LHS
|
||||
while ( r < nRhs && ( l >= nLhs || m_Components[ l ] > rhs.m_Components[ r ] ) )
|
||||
{
|
||||
++r;
|
||||
}
|
||||
|
||||
// In Both LHS & RHS
|
||||
while ( l < nLhs && r < nRhs && m_Components[ l ] == rhs.m_Components[ r ] )
|
||||
{
|
||||
newComponents.AddToTail( m_Components[ l ] );
|
||||
newWeights.AddToTail( m_Weights[ l ] );
|
||||
++l;
|
||||
++r;
|
||||
}
|
||||
}
|
||||
|
||||
m_Components.CopyArray( newComponents.Base(), newComponents.Count() );
|
||||
m_Weights.CopyArray( newWeights.Base(), newWeights.Count() );
|
||||
}
|
||||
|
||||
m_CompleteCount.Set( 0 );
|
||||
m_bComplete.Set( false );
|
||||
}
|
||||
Reference in New Issue
Block a user