summaryrefslogtreecommitdiff
path: root/movieobjects/dmeselection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'movieobjects/dmeselection.cpp')
-rw-r--r--movieobjects/dmeselection.cpp577
1 files changed, 577 insertions, 0 deletions
diff --git a/movieobjects/dmeselection.cpp b/movieobjects/dmeselection.cpp
new file mode 100644
index 0000000..7528f88
--- /dev/null
+++ b/movieobjects/dmeselection.cpp
@@ -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 );
+} \ No newline at end of file