|
|
//========= 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 ); }
|