This commit is contained in:
FluorescentCIAAfricanAmerican
2020-04-22 12:56:21 -04:00
commit 3bf9df6b27
15370 changed files with 5489726 additions and 0 deletions

View File

@ -0,0 +1,68 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// An element that contains a list of animations
//
//=============================================================================
#include "movieobjects/dmeanimationlist.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "movieobjects/dmeclip.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( DmeAnimationList, CDmeAnimationList );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeAnimationList::OnConstruction()
{
m_Animations.Init( this, "animations" );
}
void CDmeAnimationList::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Adds, removes animations
//-----------------------------------------------------------------------------
int CDmeAnimationList::AddAnimation( CDmeChannelsClip *pAnimation )
{
return m_Animations.AddToTail( pAnimation );
}
void CDmeAnimationList::RemoveAnimation( int nIndex )
{
m_Animations.Remove( nIndex );
}
//-----------------------------------------------------------------------------
// Sets the transform
//-----------------------------------------------------------------------------
void CDmeAnimationList::SetAnimation( int nIndex, CDmeChannelsClip *pAnimation )
{
m_Animations.Set( nIndex, pAnimation );
}
//-----------------------------------------------------------------------------
// Finds an animation by name
//-----------------------------------------------------------------------------
int CDmeAnimationList::FindAnimation( const char *pAnimName )
{
int nCount = m_Animations.Count();
for ( int i = 0; i < nCount; ++i )
{
if ( !Q_stricmp( m_Animations[i]->GetName(), pAnimName ) )
return i;
}
return -1;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,103 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Dme version of a model attachment point
//
//=============================================================================
#include "movieobjects/dmeattachment.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "materialsystem/imaterialsystem.h"
#include "materialsystem/imesh.h"
#include "tier1/KeyValues.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( DmeAttachment, CDmeAttachment );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeAttachment::OnConstruction()
{
if ( !g_pMaterialSystem )
return;
m_bIsRigid.Init( this, "isRigid" );
m_bIsWorldAligned.Init( this, "isWorldAligned" );
KeyValues *pVMTKeyValues = new KeyValues( "wireframe" );
pVMTKeyValues->SetInt( "$vertexcolor", 1 );
pVMTKeyValues->SetInt( "$ignorez", 0 );
m_AttachmentMaterial.Init( "__DmeJointMaterial", pVMTKeyValues );
}
void CDmeAttachment::OnDestruction()
{
if ( !g_pMaterialSystem )
return;
m_AttachmentMaterial.Shutdown();
}
//-----------------------------------------------------------------------------
// For rendering joints
//-----------------------------------------------------------------------------
#define AXIS_SIZE 6.0f
//-----------------------------------------------------------------------------
// Rendering method for the dag
//-----------------------------------------------------------------------------
void CDmeAttachment::Draw( const matrix3x4_t &shapeToWorld, CDmeDrawSettings *pDrawSettings /* = NULL */ )
{
if ( !g_pMaterialSystem )
return;
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->PushMatrix();
pRenderContext->LoadMatrix( shapeToWorld );
pRenderContext->Bind( m_AttachmentMaterial );
IMesh *pMesh = pRenderContext->GetDynamicMesh( );
CMeshBuilder meshBuilder;
meshBuilder.Begin( pMesh, MATERIAL_LINES, 3 );
meshBuilder.Position3f( 0.0f, 0.0f, 0.0f );
meshBuilder.Color4ub( 255, 0, 0, 255 );
meshBuilder.AdvanceVertex();
meshBuilder.Position3f( AXIS_SIZE, 0.0f, 0.0f );
meshBuilder.Color4ub( 255, 0, 0, 255 );
meshBuilder.AdvanceVertex();
meshBuilder.Position3f( 0.0f, 0.0f, 0.0f );
meshBuilder.Color4ub( 0, 255, 0, 255 );
meshBuilder.AdvanceVertex();
meshBuilder.Position3f( 0.0f, AXIS_SIZE, 0.0f );
meshBuilder.Color4ub( 0, 255, 0, 255 );
meshBuilder.AdvanceVertex();
meshBuilder.Position3f( 0.0f, 0.0f, 0.0f );
meshBuilder.Color4ub( 0, 0, 255, 255 );
meshBuilder.AdvanceVertex();
meshBuilder.Position3f( 0.0f, 0.0f, AXIS_SIZE );
meshBuilder.Color4ub( 0, 0, 255, 255 );
meshBuilder.AdvanceVertex();
meshBuilder.End();
pMesh->Draw();
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->PopMatrix();
}

View File

@ -0,0 +1,105 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// The expression operator class - scalar math calculator
// for a good list of operators and simple functions, see:
// \\fileserver\user\MarcS\boxweb\aliveDistLite\v4.2.0\doc\alive\functions.txt
// (although we'll want to implement elerp as the standard 3x^2 - 2x^3 with rescale)
//
//=============================================================================
#include "movieobjects/dmebalancetostereocalculatoroperator.h"
#include "movieobjects/dmechannel.h"
#include "movieobjects_interfaces.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "datamodel/dmattribute.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( DmeBalanceToStereoCalculatorOperator, CDmeBalanceToStereoCalculatorOperator );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeBalanceToStereoCalculatorOperator::OnConstruction()
{
m_result_left.Init( this, "result_left" );
m_result_right.Init( this, "result_right" );
m_result_multi.Init( this, "result_multi" );
m_value.Init( this, "value" );
m_balance.InitAndSet( this, "balance", 0.5f );
m_multilevel.InitAndSet( this, "multilevel", 0.5f );
m_bSpewResult.Init( this, "spewresult" );
m_flDefaultValue = FLT_MAX;
}
void CDmeBalanceToStereoCalculatorOperator::OnDestruction()
{
}
void CDmeBalanceToStereoCalculatorOperator::GetInputAttributes ( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_value.GetAttribute() );
attrs.AddToTail( m_balance.GetAttribute() );
attrs.AddToTail( m_multilevel.GetAttribute() );
}
void CDmeBalanceToStereoCalculatorOperator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_result_left.GetAttribute() );
attrs.AddToTail( m_result_right.GetAttribute() );
attrs.AddToTail( m_result_multi.GetAttribute() );
}
float CDmeBalanceToStereoCalculatorOperator::ComputeDefaultValue()
{
// NOTE: This is a total hack, which we expect to remove soon, when the balance work is done.
const static UtlSymId_t symToElement = g_pDataModel->GetSymbol( "toElement" );
CDmeChannel *pChannel = FindReferringElement<CDmeChannel>( this, symToElement );
if ( !pChannel )
return 0.0f;
CDmElement *pControl = pChannel->GetFromElement();
if ( !pControl )
return 0.0f;
return pControl->GetValue<float>( "defaultValue" );
}
void CDmeBalanceToStereoCalculatorOperator::Operate()
{
if ( m_flDefaultValue == FLT_MAX )
{
m_flDefaultValue = ComputeDefaultValue();
}
float flValue = m_value - m_flDefaultValue;
if ( m_balance > 0.5f )
{
m_result_right = m_value;
m_result_left = ( ( 1.0f - m_balance ) / 0.5f ) * flValue + m_flDefaultValue;
}
else
{
m_result_right = ( m_balance / 0.5f ) * flValue + m_flDefaultValue;
m_result_left = m_value;
}
m_result_multi = m_multilevel;
if ( m_bSpewResult )
{
Msg( "%s = l('%f') r('%f') m('%f')\n", GetName(), (float)m_result_left, (float)m_result_right, (float)m_result_multi );
}
}
void CDmeBalanceToStereoCalculatorOperator::SetSpewResult( bool state )
{
m_bSpewResult = state;
}

View File

@ -0,0 +1,32 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmebookmark.h"
#include "tier0/dbg.h"
#include "datamodel/dmelementfactoryhelper.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Class factory
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeBookmark, CDmeBookmark );
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
void CDmeBookmark::OnConstruction()
{
m_Time.InitAndSet( this, "time", 0 );
m_Duration.InitAndSet( this, "duration", 0 );
m_Note.Init( this, "note" );
}
void CDmeBookmark::OnDestruction()
{
}

288
movieobjects/dmecamera.cpp Normal file
View File

@ -0,0 +1,288 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmecamera.h"
#include "tier0/dbg.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "mathlib/vector.h"
#include "movieobjects/dmetransform.h"
#include "materialsystem/imaterialsystem.h"
#include "movieobjects_interfaces.h"
#include "tier2/tier2.h"
// FIXME: REMOVE
#include "istudiorender.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( DmeCamera, CDmeCamera );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeCamera::OnConstruction()
{
m_fieldOfView.InitAndSet( this, "fieldOfView", 30.0f );
// FIXME: This currently matches the client DLL for HL2
// but we probably need a way of getting this state from the client DLL
m_zNear.InitAndSet( this, "znear", 3.0f );
m_zFar.InitAndSet( this, "zfar", 16384.0f * 1.73205080757f );
m_fFocalDistance.InitAndSet( this, "focalDistance", 72.0f);
m_fAperture.InitAndSet( this, "aperture", 0.2f);
m_fShutterSpeed.InitAndSet( this, "shutterSpeed", 1.0f / 48.0f );
m_fToneMapScale.InitAndSet( this, "toneMapScale", 1.0f );
m_fBloomScale.InitAndSet( this, "bloomScale", 0.28f );
m_nDoFQuality.InitAndSet( this, "depthOfFieldQuality", 0 );
m_nMotionBlurQuality.InitAndSet( this, "motionBlurQuality", 0 );
}
void CDmeCamera::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Loads the material system view matrix based on the transform
//-----------------------------------------------------------------------------
void CDmeCamera::LoadViewMatrix( bool bUseEngineCoordinateSystem )
{
if ( !g_pMaterialSystem )
return;
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
VMatrix view;
GetViewMatrix( view, bUseEngineCoordinateSystem );
pRenderContext->MatrixMode( MATERIAL_VIEW );
pRenderContext->LoadMatrix( view );
}
//-----------------------------------------------------------------------------
// Loads the material system projection matrix based on the fov, etc.
//-----------------------------------------------------------------------------
void CDmeCamera::LoadProjectionMatrix( int nDisplayWidth, int nDisplayHeight )
{
if ( !g_pMaterialSystem )
return;
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
VMatrix proj;
GetProjectionMatrix( proj, nDisplayWidth, nDisplayHeight );
pRenderContext->LoadMatrix( proj );
}
//-----------------------------------------------------------------------------
// Sets up studiorender camera state
//-----------------------------------------------------------------------------
void CDmeCamera::LoadStudioRenderCameraState()
{
// FIXME: Remove this! This should automatically happen in DrawModel
// in studiorender.
if ( !g_pStudioRender )
return;
matrix3x4_t transform;
GetTransform()->GetTransform( transform );
Vector vecOrigin, vecRight, vecUp, vecForward;
MatrixGetColumn( transform, 0, vecRight );
MatrixGetColumn( transform, 1, vecUp );
MatrixGetColumn( transform, 2, vecForward );
MatrixGetColumn( transform, 3, vecOrigin );
g_pStudioRender->SetViewState( vecOrigin, vecRight, vecUp, vecForward );
}
//-----------------------------------------------------------------------------
// Returns the x FOV (the full angle)
//-----------------------------------------------------------------------------
float CDmeCamera::GetFOVx() const
{
return m_fieldOfView;
}
void CDmeCamera::SetFOVx( float fov )
{
m_fieldOfView = fov;
}
//-----------------------------------------------------------------------------
// Returns the focal distance in inches
//-----------------------------------------------------------------------------
float CDmeCamera::GetFocalDistance() const
{
return m_fFocalDistance;
}
//-----------------------------------------------------------------------------
// Sets the focal distance in inches
//-----------------------------------------------------------------------------
void CDmeCamera::SetFocalDistance( const float &fFocalDistance )
{
m_fFocalDistance = fFocalDistance;
}
//-----------------------------------------------------------------------------
// Returns the camera aperture in inches
//-----------------------------------------------------------------------------
float CDmeCamera::GetAperture() const
{
return m_fAperture;
}
//-----------------------------------------------------------------------------
// Returns the camera aperture in inches
//-----------------------------------------------------------------------------
float CDmeCamera::GetShutterSpeed() const
{
return m_fShutterSpeed;
}
//-----------------------------------------------------------------------------
// Returns the tone map scale
//-----------------------------------------------------------------------------
float CDmeCamera::GetToneMapScale() const
{
return m_fToneMapScale;
}
//-----------------------------------------------------------------------------
// Returns the bloom scale
//-----------------------------------------------------------------------------
float CDmeCamera::GetBloomScale() const
{
return m_fBloomScale;
}
//-----------------------------------------------------------------------------
// Returns the number of Depth of Field samples
//-----------------------------------------------------------------------------
int CDmeCamera::GetDepthOfFieldQuality() const
{
return m_nDoFQuality;
}
//-----------------------------------------------------------------------------
// Returns the number of Motion Blur samples
//-----------------------------------------------------------------------------
int CDmeCamera::GetMotionBlurQuality() const
{
return m_nMotionBlurQuality;
}
//-----------------------------------------------------------------------------
// Returns the view direction
//-----------------------------------------------------------------------------
void CDmeCamera::GetViewDirection( Vector *pDirection )
{
matrix3x4_t transform;
GetTransform()->GetTransform( transform );
MatrixGetColumn( transform, 2, *pDirection );
// We look down the -z axis
*pDirection *= -1.0f;
}
//-----------------------------------------------------------------------------
// Sets up render state in the material system for rendering
//-----------------------------------------------------------------------------
void CDmeCamera::SetupRenderState( int nDisplayWidth, int nDisplayHeight, bool bUseEngineCoordinateSystem /* = false */ )
{
LoadViewMatrix( bUseEngineCoordinateSystem );
LoadProjectionMatrix( nDisplayWidth, nDisplayHeight );
LoadStudioRenderCameraState( );
}
//-----------------------------------------------------------------------------
// accessors for generated matrices
//-----------------------------------------------------------------------------
void CDmeCamera::GetViewMatrix( VMatrix &view, bool bUseEngineCoordinateSystem /* = false */ )
{
matrix3x4_t transform, invTransform;
CDmeTransform *pTransform = GetTransform();
pTransform->GetTransform( transform );
if ( bUseEngineCoordinateSystem )
{
VMatrix matRotate( transform );
VMatrix matRotateZ;
MatrixBuildRotationAboutAxis( matRotateZ, Vector(0,0,1), -90 );
MatrixMultiply( matRotate, matRotateZ, matRotate );
VMatrix matRotateX;
MatrixBuildRotationAboutAxis( matRotateX, Vector(1,0,0), 90 );
MatrixMultiply( matRotate, matRotateX, matRotate );
transform = matRotate.As3x4();
}
MatrixInvert( transform, invTransform );
view = invTransform;
}
void CDmeCamera::GetProjectionMatrix( VMatrix &proj, int width, int height )
{
float flFOV = m_fieldOfView.Get();
float flZNear = m_zNear.Get();
float flZFar = m_zFar.Get();
float flApsectRatio = (float)width / (float)height;
// MatrixBuildPerspective( proj, flFOV, flFOV * flApsectRatio, flZNear, flZFar );
#if 1
float halfWidth = tan( flFOV * M_PI / 360.0 );
float halfHeight = halfWidth / flApsectRatio;
#else
float halfHeight = tan( flFOV * M_PI / 360.0 );
float halfWidth = flApsectRatio * halfHeight;
#endif
memset( proj.Base(), 0, sizeof( proj ) );
proj[0][0] = 1.0f / halfWidth;
proj[1][1] = 1.0f / halfHeight;
proj[2][2] = flZFar / ( flZNear - flZFar );
proj[3][2] = -1.0f;
proj[2][3] = flZNear * flZFar / ( flZNear - flZFar );
}
void CDmeCamera::GetViewProjectionInverse( VMatrix &viewprojinv, int width, int height )
{
VMatrix view, proj;
GetViewMatrix( view );
GetProjectionMatrix( proj, width, height );
VMatrix viewproj;
MatrixMultiply( proj, view, viewproj );
bool success = MatrixInverseGeneral( viewproj, viewprojinv );
if ( !success )
{
Assert( 0 );
MatrixInverseTR( viewproj, viewprojinv );
}
}
//-----------------------------------------------------------------------------
// Computes the screen space position given a screen size
//-----------------------------------------------------------------------------
void CDmeCamera::ComputeScreenSpacePosition( const Vector &vecWorldPosition, int width, int height, Vector2D *pScreenPosition )
{
VMatrix view, proj, viewproj;
GetViewMatrix( view );
GetProjectionMatrix( proj, width, height );
MatrixMultiply( proj, view, viewproj );
Vector vecScreenPos;
Vector3DMultiplyPositionProjective( viewproj, vecWorldPosition, vecScreenPos );
pScreenPosition->x = ( vecScreenPos.x + 1.0f ) * width / 2.0f;
pScreenPosition->y = ( -vecScreenPos.y + 1.0f ) * height / 2.0f;
}

1007
movieobjects/dmechannel.cpp Normal file

File diff suppressed because it is too large Load Diff

1725
movieobjects/dmeclip.cpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

438
movieobjects/dmedag.cpp Normal file
View File

@ -0,0 +1,438 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmedag.h"
#include "movieobjects/dmeshape.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "movieobjects/dmetransform.h"
#include "movieobjects_interfaces.h"
#include "movieobjects/dmedrawsettings.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( DmeDag, CDmeDag );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CUtlStack<CDmeDag::TransformInfo_t> CDmeDag::s_TransformStack;
bool CDmeDag::s_bDrawUsingEngineCoordinates = false;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeDag::OnConstruction()
{
m_Transform.InitAndCreate( this, "transform", GetName() );
m_Shape.Init( this, "shape" );
m_Visible.InitAndSet( this, "visible", true, FATTRIB_HAS_CALLBACK );
m_Children.Init( this, "children" );
}
void CDmeDag::OnDestruction()
{
g_pDataModel->DestroyElement( m_Transform.Get() );
}
//-----------------------------------------------------------------------------
// Accessors
//-----------------------------------------------------------------------------
CDmeTransform *CDmeDag::GetTransform()
{
return m_Transform.GetElement();
}
CDmeShape *CDmeDag::GetShape()
{
return m_Shape.GetElement();
}
void CDmeDag::SetShape( CDmeShape *pShape )
{
m_Shape = pShape;
}
bool CDmeDag::IsVisible() const
{
return m_Visible;
}
void CDmeDag::SetVisible( bool bVisible )
{
m_Visible = bVisible;
}
//-----------------------------------------------------------------------------
// Returns the visibility attribute for DmeRenderable support
//-----------------------------------------------------------------------------
CDmAttribute *CDmeDag::GetVisibilityAttribute()
{
return m_Visible.GetAttribute();
}
//-----------------------------------------------------------------------------
// child helpers
//-----------------------------------------------------------------------------
const CUtlVector< DmElementHandle_t > &CDmeDag::GetChildren() const
{
return m_Children.Get();
}
int CDmeDag::GetChildCount() const
{
return m_Children.Count();
}
CDmeDag *CDmeDag::GetChild( int i ) const
{
if ( i < 0 || i >= m_Children.Count() )
return NULL;
return m_Children.Get( i );
}
void CDmeDag::AddChild( CDmeDag* pDag )
{
m_Children.AddToTail( pDag );
}
void CDmeDag::RemoveChild( int i )
{
m_Children.FastRemove( i );
}
void CDmeDag::RemoveChild( const CDmeDag *pChild, bool bRecurse )
{
int i = FindChild( pChild );
if ( i >= 0 )
{
RemoveChild( i );
}
}
int CDmeDag::FindChild( const CDmeDag *pChild ) const
{
return m_Children.Find( pChild->GetHandle() );
}
// recursive
int CDmeDag::FindChild( CDmeDag *&pParent, const CDmeDag *pChild )
{
int index = FindChild( pChild );
if ( index >= 0 )
{
pParent = this;
return index;
}
int nChildren = m_Children.Count();
for ( int ci = 0; ci < nChildren; ++ci )
{
index = m_Children[ ci ]->FindChild( pParent, pChild );
if ( index >= 0 )
return index;
}
pParent = NULL;
return -1;
}
int CDmeDag::FindChild( const char *name ) const
{
int nChildren = m_Children.Count();
for ( int ci = 0; ci < nChildren; ++ci )
{
if ( V_strcmp( m_Children[ ci ]->GetName(), name ) == 0 )
return ci;
}
return -1;
}
CDmeDag *CDmeDag::FindOrAddChild( const char *name )
{
int i = FindChild( name );
if ( i >= 0 )
return GetChild( i );
CDmeDag *pChild = CreateElement< CDmeDag >( name, GetFileId() );
AddChild( pChild );
return pChild;
}
//-----------------------------------------------------------------------------
// Recursively render the Dag hierarchy
//-----------------------------------------------------------------------------
void CDmeDag::PushDagTransform()
{
int i = s_TransformStack.Push();
TransformInfo_t &info = s_TransformStack[i];
info.m_pTransform = GetTransform();
info.m_bComputedDagToWorld = false;
}
void CDmeDag::PopDagTransform()
{
Assert( s_TransformStack.Top().m_pTransform == GetTransform() );
s_TransformStack.Pop();
}
//-----------------------------------------------------------------------------
// Transform from DME to engine coordinates
//-----------------------------------------------------------------------------
void CDmeDag::DmeToEngineMatrix( matrix3x4_t& dmeToEngine )
{
VMatrix rotation, rotationZ;
MatrixBuildRotationAboutAxis( rotation, Vector( 1, 0, 0 ), 90 );
MatrixBuildRotationAboutAxis( rotationZ, Vector( 0, 1, 0 ), 90 );
ConcatTransforms( rotation.As3x4(), rotationZ.As3x4(), dmeToEngine );
}
//-----------------------------------------------------------------------------
// Transform from engine to DME coordinates
//-----------------------------------------------------------------------------
void CDmeDag::EngineToDmeMatrix( matrix3x4_t& engineToDme )
{
VMatrix rotation, rotationZ;
MatrixBuildRotationAboutAxis( rotation, Vector( 1, 0, 0 ), -90 );
MatrixBuildRotationAboutAxis( rotationZ, Vector( 0, 1, 0 ), -90 );
ConcatTransforms( rotationZ.As3x4(), rotation.As3x4(), engineToDme );
}
void CDmeDag::GetShapeToWorldTransform( matrix3x4_t &mat )
{
int nCount = s_TransformStack.Count();
if ( nCount == 0 )
{
if ( !s_bDrawUsingEngineCoordinates )
{
SetIdentityMatrix( mat );
}
else
{
DmeToEngineMatrix( mat );
}
return;
}
if ( s_TransformStack.Top().m_bComputedDagToWorld )
{
MatrixCopy( s_TransformStack.Top().m_DagToWorld, mat );
return;
}
// Compute all uncomputed dag to worls
int i;
for ( i = 0; i < nCount; ++i )
{
TransformInfo_t &info = s_TransformStack[i];
if ( !info.m_bComputedDagToWorld )
break;
}
// Set up the initial transform
if ( i == 0 )
{
if ( !s_bDrawUsingEngineCoordinates )
{
SetIdentityMatrix( mat );
}
else
{
DmeToEngineMatrix( mat );
}
}
else
{
MatrixCopy( s_TransformStack[i-1].m_DagToWorld, mat );
}
// Compute all transforms
for ( ; i < nCount; ++i )
{
matrix3x4_t localToParent;
TransformInfo_t &info = s_TransformStack[i];
info.m_pTransform->GetTransform( localToParent );
ConcatTransforms( mat, localToParent, info.m_DagToWorld );
info.m_bComputedDagToWorld = true;
MatrixCopy( info.m_DagToWorld, mat );
}
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDag::GetLocalMatrix( matrix3x4_t &m )
{
CDmeTransform *pTransform = GetTransform();
if ( pTransform )
{
pTransform->GetTransform( m );
}
else
{
SetIdentityMatrix( m );
}
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDag::GetWorldMatrix( matrix3x4_t &m )
{
GetLocalMatrix( m );
const static UtlSymId_t symChildren = g_pDataModel->GetSymbol( "children" );
CDmeDag *pParent = FindReferringElement< CDmeDag >( this, symChildren );
if ( pParent )
{
matrix3x4_t localMatrix;
GetLocalMatrix( localMatrix );
matrix3x4_t parentWorldMatrix;
pParent->GetWorldMatrix( parentWorldMatrix );
ConcatTransforms( parentWorldMatrix, localMatrix, m );
}
else
{
GetLocalMatrix( m );
}
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDag::GetParentWorldMatrix( matrix3x4_t &m )
{
const static UtlSymId_t symChildren = g_pDataModel->GetSymbol( "children" );
CDmeDag *pParent = FindReferringElement< CDmeDag >( this, symChildren );
if ( pParent )
{
pParent->GetWorldMatrix( m );
}
else
{
SetIdentityMatrix( m );
}
}
//-----------------------------------------------------------------------------
// Recursively render the Dag hierarchy
//-----------------------------------------------------------------------------
void CDmeDag::DrawUsingEngineCoordinates( bool bEnable )
{
s_bDrawUsingEngineCoordinates = bEnable;
}
//-----------------------------------------------------------------------------
// Recursively render the Dag hierarchy
//-----------------------------------------------------------------------------
void CDmeDag::Draw( CDmeDrawSettings *pDrawSettings )
{
if ( !m_Visible )
return;
PushDagTransform();
CDmeShape *pShape = GetShape();
if ( pShape )
{
matrix3x4_t shapeToWorld;
GetShapeToWorldTransform( shapeToWorld );
pShape->Draw( shapeToWorld, pDrawSettings );
}
uint cn = m_Children.Count();
for ( uint ci = 0; ci < cn; ++ci )
{
m_Children[ ci ]->Draw( pDrawSettings );
}
PopDagTransform();
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDag::GetBoundingSphere( Vector &c0, float &r0, const matrix3x4_t &pMat ) const
{
matrix3x4_t lMat;
m_Transform.GetElement()->GetTransform( lMat );
matrix3x4_t wMat;
ConcatTransforms( pMat, lMat, wMat );
c0.Zero();
r0 = 0.0f;
const CDmeShape *pShape = m_Shape.GetElement();
if ( pShape )
{
pShape->GetBoundingSphere( c0, r0 );
}
// No scale in Dme! :)
Vector vTemp;
VectorTransform( c0, pMat, vTemp );
const int nChildren = m_Children.Count();
if ( nChildren > 0 )
{
Vector c1; // Child center
float r1; // Child radius
Vector v01; // c1 - c0
float l01; // |v01|
for ( int i = 0; i < nChildren; ++i )
{
m_Children[ i ]->GetBoundingSphere( c1, r1, wMat );
if ( r0 == 0.0f )
{
c0 = c1;
r0 = r1;
continue;
}
v01 = c1 - c0;
l01 = v01.NormalizeInPlace();
if ( r0 < l01 + r1 )
{
// Current sphere doesn't contain both spheres
if ( r1 < l01 + r0 )
{
// Child sphere doesn't contain both spheres
c0 = c0 + 0.5f * ( r1 + l01 - r0 ) * v01;
r0 = 0.5f * ( r0 + l01 + r1 );
}
else
{
// Child sphere contains both spheres
c0 = c1;
r0 = r1;
}
}
}
}
}

View File

@ -0,0 +1,323 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Describes an asset: something that is compiled from sources,
// in potentially multiple steps, to a compiled resource
//
//=============================================================================
#include "movieobjects/dmedccmakefile.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "tier2/fileutils.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Hook into datamodel
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeSourceDCCFile, CDmeSourceDCCFile );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeSourceDCCFile::OnConstruction()
{
m_RootDCCObjects.Init( this, "rootDCCObjects" );
m_ExportType.InitAndSet( this, "exportType", 0 );
m_FrameStart.InitAndSet( this, "frameStart", 0.0f );
m_FrameEnd.InitAndSet( this, "frameEnd", 0.0f );
m_FrameIncrement.InitAndSet( this, "frameIncrement", 1.0f );
}
void CDmeSourceDCCFile::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Hook into datamodel
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeSourceMayaFile, CDmeSourceMayaFile );
IMPLEMENT_ELEMENT_FACTORY( DmeSourceMayaModelFile, CDmeSourceMayaModelFile );
IMPLEMENT_ELEMENT_FACTORY( DmeSourceMayaAnimationFile, CDmeSourceMayaAnimationFile );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeSourceMayaFile::OnConstruction()
{
}
void CDmeSourceMayaFile::OnDestruction()
{
}
void CDmeSourceMayaModelFile::OnConstruction()
{
m_ExportType = 0;
}
void CDmeSourceMayaModelFile::OnDestruction()
{
}
void CDmeSourceMayaAnimationFile::OnConstruction()
{
m_ExportType = 1;
}
void CDmeSourceMayaAnimationFile::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Hook into datamodel
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeSourceXSIFile, CDmeSourceXSIFile );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeSourceXSIFile::OnConstruction()
{
}
void CDmeSourceXSIFile::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Hook into datamodel
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeDCCMakefile, CDmeDCCMakefile );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeDCCMakefile::OnConstruction()
{
m_bFlushFile = false;
}
void CDmeDCCMakefile::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Compile assets
//-----------------------------------------------------------------------------
void CDmeDCCMakefile::GetOutputs( CUtlVector<CUtlString> &fullPaths )
{
fullPaths.RemoveAll();
char pOutputName[MAX_PATH];
Q_FileBase( GetFileName(), pOutputName, sizeof(pOutputName) );
if ( !pOutputName[0] )
return;
// FIXME: We need to come up with an appropriate directory structure for export
char pOutputDir[MAX_PATH];
GetMakefilePath( pOutputDir, sizeof(pOutputDir) );
if ( !pOutputDir[0] )
return;
Q_StripTrailingSlash( pOutputDir );
char pFullPath[MAX_PATH];
Q_snprintf( pFullPath, sizeof(pFullPath), "%s\\%s.dmx", pOutputDir, pOutputName );
fullPaths.AddToTail( pFullPath );
}
//-----------------------------------------------------------------------------
// Creates, destroys the output element associated with this makefile
//-----------------------------------------------------------------------------
CDmElement *CDmeDCCMakefile::CreateOutputElement( )
{
if ( m_bFlushFile )
{
m_bFlushFile = false;
if ( GetFileId() != DMFILEID_INVALID )
{
// NOTE: CDmeHandles will correctly re-hook up to the new makefile after load
// If the file fails to load, we have the copy. If the file correctly has the make in it
// it will replace this copy I made
CDmeHandle< CDmeDCCMakefile > hMakefileOld;
hMakefileOld = this;
// NOTE NOTE NOTE
// UnloadFile essentially calls delete this!
// So don't refer to any state in this DmElement after that
DmFileId_t fileId = GetFileId();
g_pDataModel->UnloadFile( fileId );
CDmElement *pRoot = NULL;
if ( g_pDataModel->RestoreFromFile( g_pDataModel->GetFileName( fileId ), NULL, NULL, &pRoot, CR_DELETE_OLD ) != DMFILEID_INVALID )
{
// NOTE: Unload/restore kills the this pointer, we need to redo this
if ( hMakefileOld.Get() )
{
hMakefileOld->SetDirty( false );
return hMakefileOld->CreateOutputElement();
}
}
// NOTE: We expect file backup prior to compile to avoid really fatal errors
// This case happens if the file failed to load. In this case, we must use
// the copy of the makefile
Assert( 0 );
return NULL;
}
}
// The output element is the root element containing the makefile
return FindReferringElement< CDmElement >( this, "makefile" );
}
void CDmeDCCMakefile::DestroyOutputElement( CDmElement *pOutput )
{
m_bFlushFile = true;
}
//-----------------------------------------------------------------------------
// Hook into datamodel
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeMayaMakefile, CDmeMayaMakefile );
IMPLEMENT_ELEMENT_FACTORY( DmeMayaModelMakefile, CDmeMayaModelMakefile );
IMPLEMENT_ELEMENT_FACTORY( DmeMayaAnimationMakefile, CDmeMayaAnimationMakefile );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeMayaMakefile::OnConstruction()
{
}
void CDmeMayaMakefile::OnDestruction()
{
}
void CDmeMayaModelMakefile::OnConstruction()
{
}
void CDmeMayaModelMakefile::OnDestruction()
{
}
void CDmeMayaAnimationMakefile::OnConstruction()
{
}
void CDmeMayaAnimationMakefile::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Returns source types
//-----------------------------------------------------------------------------
static DmeMakefileType_t s_pMayaModelSourceTypes[] =
{
{ "DmeSourceMayaModelFile", "Maya Model File", true, "makefiledir:../maya", "*.ma;*.mb", "Maya File (*.ma,*.mb)" },
{ NULL, NULL, false, NULL, NULL, NULL },
};
DmeMakefileType_t* CDmeMayaModelMakefile::GetSourceTypes()
{
return s_pMayaModelSourceTypes;
}
static DmeMakefileType_t s_pMayaAnimationSourceTypes[] =
{
{ "DmeSourceMayaAnimationFile", "Maya Animation File", true, "makefiledir:../maya", "*.ma;*.mb", "Maya File (*.ma,*.mb)" },
{ NULL, NULL, false, NULL, NULL, NULL },
};
DmeMakefileType_t* CDmeMayaAnimationMakefile::GetSourceTypes()
{
return s_pMayaAnimationSourceTypes;
}
//-----------------------------------------------------------------------------
// Makefile type
//-----------------------------------------------------------------------------
static DmeMakefileType_t s_MayaModelMakefileType =
{
"DmeMayaModelMakefile", "Maya Model Component", true, "contentdir:models", "*.dmx", "DMX File (*.dmx)"
};
DmeMakefileType_t *CDmeMayaModelMakefile::GetMakefileType()
{
return &s_MayaModelMakefileType;
}
static DmeMakefileType_t s_MayaAnimationMakefileType =
{
"DmeMayaAnimationMakefile", "Maya Animation Component", true, "contentdir:models", "*.dmx", "DMX File (*.dmx)"
};
DmeMakefileType_t *CDmeMayaAnimationMakefile::GetMakefileType()
{
return &s_MayaAnimationMakefileType;
}
//-----------------------------------------------------------------------------
// Hook into datamodel
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeXSIMakefile, CDmeXSIMakefile );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeXSIMakefile::OnConstruction()
{
}
void CDmeXSIMakefile::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Returns source types
//-----------------------------------------------------------------------------
static DmeMakefileType_t s_pXSISourceTypes[] =
{
{ "DmeSourceXSIFile", "XSI File", true, "makefiledir:../xsi", "*.xsi", "XSI File (*.xsi)" },
{ NULL, NULL, false, NULL, NULL, NULL },
};
DmeMakefileType_t* CDmeXSIMakefile::GetSourceTypes()
{
return s_pXSISourceTypes;
}
//-----------------------------------------------------------------------------
// Makefile type
//-----------------------------------------------------------------------------
static DmeMakefileType_t s_XSIMakefileType =
{
"DmeXSIMakefile", "XSI Model Component", true, "contentdir:models", "*.dmx", "DMX File (*.dmx)",
};
DmeMakefileType_t *CDmeXSIMakefile::GetMakefileType()
{
return &s_XSIMakefileType;
}

View File

@ -0,0 +1,265 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "datamodel/dmelementfactoryhelper.h"
#include "tier1/KeyValues.h"
#include "tier1/utlrbtree.h"
#include "movieobjects/dmedag.h"
#include "movieobjects/dmedrawsettings.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( DmeDrawSettings, CDmeDrawSettings );
//-----------------------------------------------------------------------------
// Statics
//-----------------------------------------------------------------------------
bool CDmeDrawSettings::s_bWireframeMaterialInitialized( false );
CMaterialReference CDmeDrawSettings::s_WireframeMaterial;
bool CDmeDrawSettings::s_bWireframeOnShadedMaterialInitialized( false );
CMaterialReference CDmeDrawSettings::s_WireframeOnShadedMaterial;
bool CDmeDrawSettings::s_bFlatGrayMaterial( false );
CMaterialReference CDmeDrawSettings::s_FlatGrayMaterial;
bool CDmeDrawSettings::s_bUnlitGrayMaterial( false );
CMaterialReference CDmeDrawSettings::s_UnlitGrayMaterial;
CUtlRBTree< CUtlSymbol > CDmeDrawSettings::s_KnownDrawableTypes;
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDrawSettings::OnConstruction()
{
if ( s_KnownDrawableTypes.Count() == 0 )
{
BuildKnownDrawableTypes();
}
SetDefLessFunc< CUtlRBTree< CUtlSymbol > >( m_NotDrawable );
m_NotDrawable.RemoveAll();
m_DrawType.InitAndSet( this, "drawType", static_cast< int >( DRAW_SMOOTH ) );
m_bBackfaceCulling.InitAndSet( this, "backfaceCulling", true );
m_bWireframeOnShaded.InitAndSet( this, "wireframeOnShaded", false );
m_bXRay.InitAndSet( this, "xray", false );
m_bGrayShade.InitAndSet( this, "grayShade", false );
m_bNormals.InitAndSet( this, "normals", false );
m_NormalLength.InitAndSet( this, "normalLength", 1.0 );
m_Color.InitAndSet( this, "color", Color( 0, 0, 0, 1 ) );
m_bDeltaHighlight.InitAndSet( this, "highlightDeltas", false );
m_flHighlightSize.InitAndSet( this, "highlightSize", 1.5f );
m_cHighlightColor.InitAndSet( this, "highlightColor", Color( 0xff, 0x14, 0x93, 0xff ) ); // Deep Pink
m_IsAMaterialBound = false;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDrawSettings::OnDestruction()
{
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDrawSettings::Resolve()
{
}
//-----------------------------------------------------------------------------
// Wireframe
//-----------------------------------------------------------------------------
void CDmeDrawSettings::BindWireframe()
{
if ( !s_bWireframeMaterialInitialized )
{
s_bWireframeMaterialInitialized = true;
KeyValues *pKeyValues = new KeyValues( "wireframe" );
pKeyValues->SetInt( "$decal", 0 );
pKeyValues->SetInt( "$vertexcolor", 1 );
pKeyValues->SetInt( "$ignorez", 1 );
s_WireframeMaterial.Init( "__DmeWireframe", pKeyValues );
}
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
pRenderContext->Bind( s_WireframeMaterial );
m_IsAMaterialBound = true;
}
//-----------------------------------------------------------------------------
// Wireframe as a decal
//-----------------------------------------------------------------------------
void CDmeDrawSettings::BindWireframeOnShaded()
{
if ( !s_bWireframeOnShadedMaterialInitialized )
{
s_bWireframeOnShadedMaterialInitialized = true;
KeyValues *pKeyValues = new KeyValues( "wireframe" );
pKeyValues->SetInt( "$decal", 0 );
pKeyValues->SetInt( "$vertexcolor", 1 );
pKeyValues->SetInt( "$ignorez", 0 );
s_WireframeOnShadedMaterial.Init( "__DmeWireframeOnShaded", pKeyValues );
}
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
pRenderContext->Bind( s_WireframeOnShadedMaterial );
m_IsAMaterialBound = true;
}
//-----------------------------------------------------------------------------
// Flat Gray Shaded
//-----------------------------------------------------------------------------
void CDmeDrawSettings::BindGray()
{
if ( !s_bFlatGrayMaterial )
{
s_bFlatGrayMaterial = true;
KeyValues *pKeyValues = new KeyValues( "VertexLitGeneric" );
pKeyValues->SetInt( "$model", 1 );
s_FlatGrayMaterial.Init( "__DmeFlatGray", pKeyValues );
}
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
pRenderContext->Bind( s_FlatGrayMaterial );
m_IsAMaterialBound = true;
}
//-----------------------------------------------------------------------------
// Flat Gray Shaded
//-----------------------------------------------------------------------------
void CDmeDrawSettings::BindUnlitGray()
{
if ( !s_bUnlitGrayMaterial )
{
s_bUnlitGrayMaterial = true;
KeyValues *pKeyValues = new KeyValues( "UnlitGeneric" );
pKeyValues->SetInt( "$model", 1 );
pKeyValues->SetInt( "$vertexcolor", 1 );
s_UnlitGrayMaterial.Init( "__DmeUnlitGray", pKeyValues );
}
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
pRenderContext->Bind( s_UnlitGrayMaterial );
m_IsAMaterialBound = true;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
bool CDmeDrawSettings::Drawable( CDmElement *pElement )
{
if ( m_NotDrawable.IsValidIndex( m_NotDrawable.Find( pElement->GetType() ) ) )
return false;
return true;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDrawSettings::BuildKnownDrawableTypes()
{
SetDefLessFunc< CUtlRBTree< CUtlSymbol > >( s_KnownDrawableTypes );
s_KnownDrawableTypes.RemoveAll();
s_KnownDrawableTypes.InsertIfNotFound( g_pDataModel->GetSymbol( "DmeMesh" ) );
s_KnownDrawableTypes.InsertIfNotFound( g_pDataModel->GetSymbol( "DmeJoint" ) );
s_KnownDrawableTypes.InsertIfNotFound( g_pDataModel->GetSymbol( "DmeModel" ) );
s_KnownDrawableTypes.InsertIfNotFound( g_pDataModel->GetSymbol( "DmeAttachment" ) );
m_NotDrawable.RemoveAll();
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeDrawSettings::DrawDag( CDmeDag *pDag )
{
if ( !pDag )
return;
m_vHighlightPoints.RemoveAll();
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
m_IsAMaterialBound = false;
if ( GetDeltaHighlight() )
{
BindUnlitGray();
}
else
{
if ( !Shaded() )
{
BindWireframe();
}
else if ( GetGrayShade() )
{
BindGray();
}
}
pDag->Draw( this );
m_IsAMaterialBound = false;
if ( GetDeltaHighlight() || ( GetWireframeOnShaded() && Shaded() ) )
{
VMatrix m;
pRenderContext->GetMatrix( MATERIAL_PROJECTION, &m );
/* Extract the near and far clipping plane values from projection matrix
float c = m[ 2 ][ 2 ];
float d = m[ 2 ][ 3 ];
const float near = d / ( c - 1.0f );
const float far = d / ( c + 1.0f );
*/
const float zBias = 0.00025;
m[ 2 ][ 2 ] += zBias;
m[ 2 ][ 3 ] += zBias;
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
pRenderContext->PushMatrix();
pRenderContext->LoadMatrix( m );
BindWireframeOnShaded();
PushDrawType();
SetDrawType( CDmeDrawSettings::DRAW_WIREFRAME );
pDag->Draw( this );
PopDrawType();
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
pRenderContext->PopMatrix();
}
}

View File

@ -0,0 +1,328 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Contains a bunch of information about editor types
// Editor types are arbitrary
//
// $NoKeywords: $
//
//=============================================================================//
#include "movieobjects/dmeeditortypedictionary.h"
#include "datamodel/dmelementfactoryhelper.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Expose DmeEditorAttributeInfo to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeEditorAttributeInfo, CDmeEditorAttributeInfo );
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
void CDmeEditorAttributeInfo::OnConstruction()
{
m_Widget.Init( this, "widget" );
m_bIsVisible.Init( this, "isVisible" );
m_bIsReadOnly.Init( this, "isReadOnly" );
m_ArrayEntries.Init( this, "arrayEntries" );
m_bHideType.Init( this, "hideType" );
m_bHideValue.Init( this, "hideValue" );
m_Help.Init( this, "help" );
m_bIsVisible = true;
m_bIsReadOnly = false;
}
void CDmeEditorAttributeInfo::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Returns the attribute name this info is associated with
//-----------------------------------------------------------------------------
const char *CDmeEditorAttributeInfo::GetAttributeName() const
{
return GetName();
}
//-----------------------------------------------------------------------------
// Returns the widget name
//-----------------------------------------------------------------------------
const char *CDmeEditorAttributeInfo::GetWidgetName() const
{
return m_Widget.Get();
}
//-----------------------------------------------------------------------------
// Returns the info for a entry in an attribute array, if this attribute is an array type
//-----------------------------------------------------------------------------
CDmeEditorAttributeInfo *CDmeEditorAttributeInfo::GetArrayInfo()
{
return m_ArrayEntries;
}
//-----------------------------------------------------------------------------
// Sets the info for an entry in an attribute array
//-----------------------------------------------------------------------------
void CDmeEditorAttributeInfo::SetArrayInfo( CDmeEditorAttributeInfo *pInfo )
{
m_ArrayEntries = pInfo;
}
//-----------------------------------------------------------------------------
//
// CDmeEditorChoicesInfo, Base class for configuration for choices
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Expose DmeEditorChoicesInfo to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeEditorChoicesInfo, CDmeEditorChoicesInfo );
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
void CDmeEditorChoicesInfo::OnConstruction()
{
m_Choices.Init( this, "choices" );
m_ChoiceType.Init( this, "choicetype" );
}
void CDmeEditorChoicesInfo::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Sets/gets choice type
//-----------------------------------------------------------------------------
void CDmeEditorChoicesInfo::SetChoiceType( const char *pChoiceType )
{
m_ChoiceType = pChoiceType;
}
const char *CDmeEditorChoicesInfo::GetChoiceType() const
{
return m_ChoiceType;
}
bool CDmeEditorChoicesInfo::HasChoiceType() const
{
return m_ChoiceType.Length() > 0;
}
//-----------------------------------------------------------------------------
// Gets the choices
//-----------------------------------------------------------------------------
int CDmeEditorChoicesInfo::GetChoiceCount() const
{
return m_Choices.Count();
}
CDmElement *CDmeEditorChoicesInfo::CreateChoice( const char *pChoiceString )
{
CDmElement *pChoice = CreateElement< CDmElement >( "", GetFileId() );
m_Choices.AddToTail( pChoice );
pChoice->SetValue<CUtlString>( "string", pChoiceString );
return pChoice;
}
const char *CDmeEditorChoicesInfo::GetChoiceString( int nIndex ) const
{
Assert( ( nIndex < GetChoiceCount() ) && ( nIndex >= 0 ) );
CDmElement *pChoice = m_Choices[nIndex];
if ( !pChoice )
return "";
return pChoice->GetValueString( "string" );
}
//-----------------------------------------------------------------------------
// Expose DmeEditorType class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeEditorType, CDmeEditorType );
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
void CDmeEditorType::OnConstruction()
{
}
void CDmeEditorType::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Computes the actual attribute name stored in the type
//-----------------------------------------------------------------------------
const char *CDmeEditorType::GetActualAttributeName( const char *pAttributeName )
{
// Fixup the names of the attribute info for the 3 standard fields (name, type, id)
if ( !V_stricmp( "name", pAttributeName ) )
return "__name";
if ( !V_stricmp( "id", pAttributeName ) )
return "__id";
if ( !V_stricmp( "type", pAttributeName ) )
return "__type";
return pAttributeName;
}
//-----------------------------------------------------------------------------
// Returns the editor info associated with an editor type
//-----------------------------------------------------------------------------
void CDmeEditorType::AddAttributeInfo( const char *pAttributeName, CDmeEditorAttributeInfo *pInfo )
{
pAttributeName = GetActualAttributeName( pAttributeName );
SetValue( pAttributeName, pInfo );
}
//-----------------------------------------------------------------------------
// Removes a editor type associated with a particular attribute
//-----------------------------------------------------------------------------
void CDmeEditorType::RemoveAttributeInfo( const char *pAttributeName )
{
pAttributeName = GetActualAttributeName( pAttributeName );
if ( HasAttribute( pAttributeName ) )
{
RemoveAttribute( pAttributeName );
}
}
//-----------------------------------------------------------------------------
// Returns the editor info associated with an editor type
//-----------------------------------------------------------------------------
CDmeEditorAttributeInfo *CDmeEditorType::GetAttributeInfo( const char *pAttributeName )
{
pAttributeName = GetActualAttributeName( pAttributeName );
if ( !HasAttribute( pAttributeName ) )
return NULL;
return GetValueElement< CDmeEditorAttributeInfo >( pAttributeName );
}
//-----------------------------------------------------------------------------
// Returns the editor info associated with a single entry in an attribute array
//-----------------------------------------------------------------------------
CDmeEditorAttributeInfo *CDmeEditorType::GetAttributeArrayInfo( const char *pAttributeName )
{
CDmeEditorAttributeInfo *pAttributeInfo = GetAttributeInfo( pAttributeName );
if ( !pAttributeInfo )
return NULL;
return pAttributeInfo->GetArrayInfo();
}
//-----------------------------------------------------------------------------
// Expose DmeEditorTypeDictionary class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeEditorTypeDictionary, CDmeEditorTypeDictionary );
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
void CDmeEditorTypeDictionary::OnConstruction()
{
}
void CDmeEditorTypeDictionary::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
void CDmeEditorTypeDictionary::AddEditorType( CDmeEditorType *pEditorType )
{
const char *pEditorTypeName = pEditorType->GetName();
if ( HasAttribute( pEditorTypeName ) )
{
Warning( "Editor type %s is already defined! Ignoring...\n", pEditorTypeName );
return;
}
SetValue( pEditorTypeName, pEditorType->GetHandle() );
}
void CDmeEditorTypeDictionary::AddEditorTypesFromFile( const char *pFileName, const char *pPathID )
{
}
//-----------------------------------------------------------------------------
// Returns the editor type to use with an element
//-----------------------------------------------------------------------------
CDmeEditorType *CDmeEditorTypeDictionary::GetEditorType( CDmElement *pElement )
{
if ( !pElement )
return NULL;
const char *pEditorTypeName = NULL;
if ( pElement->HasAttribute( "editorType" ) )
{
pEditorTypeName = pElement->GetValueString( "editorType" );
}
if ( !pEditorTypeName || !pEditorTypeName[0] )
{
// Try to use the type name as an editor
pEditorTypeName = pElement->GetTypeString();
}
if ( !pEditorTypeName || !pEditorTypeName[0] )
return NULL;
if ( !HasAttribute( pEditorTypeName ) )
return NULL;
return GetValueElement< CDmeEditorType >( pEditorTypeName );
}
//-----------------------------------------------------------------------------
// Returns the editor info associated with an editor type
//-----------------------------------------------------------------------------
CDmeEditorAttributeInfo *CDmeEditorTypeDictionary::GetAttributeInfo( CDmElement *pElement, const char *pAttributeName )
{
CDmeEditorType *pEditorType = GetEditorType( pElement );
if ( !pEditorType )
return NULL;
return pEditorType->GetAttributeInfo( pAttributeName );
}
//-----------------------------------------------------------------------------
// Returns the editor info associated with an editor type
//-----------------------------------------------------------------------------
CDmeEditorAttributeInfo *CDmeEditorTypeDictionary::GetAttributeArrayInfo( CDmElement *pElement, const char *pAttributeName )
{
CDmeEditorType *pEditorType = GetEditorType( pElement );
if ( !pEditorType )
return NULL;
return pEditorType->GetAttributeArrayInfo( pAttributeName );
}

View File

@ -0,0 +1,942 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// The expression operator class - scalar math calculator
// for a good list of operators and simple functions, see:
// \\fileserver\user\MarcS\boxweb\aliveDistLite\v4.2.0\doc\alive\functions.txt
// (although we'll want to implement elerp as the standard 3x^2 - 2x^3 with rescale)
//
//=============================================================================
#include "movieobjects/dmeexpressionoperator.h"
#include "movieobjects_interfaces.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "datamodel/dmattribute.h"
#include "mathlib/noise.h"
#include "mathlib/vector.h"
#include <ctype.h>
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Parsing helper methods
//-----------------------------------------------------------------------------
bool ParseLiteral( const char *&expr, float &value )
{
const char *startExpr = expr;
value = ( float )strtod( startExpr, const_cast< char** >( &expr ) );
return ( startExpr != expr );
}
bool ParseString( const char *&expr, const char *str )
{
const char *startExpr = expr;
while ( ( *expr == ' ' ) || ( *expr == '\t' ) )
expr++; // skip whitespace
expr = StringAfterPrefix( expr, str );
if ( expr )
return true;
expr = startExpr;
return false;
}
bool ParseStringList( const char *&expr, const char **pOps, int &nOp )
{
while ( nOp-- )
{
if ( ParseString( expr, pOps[ nOp ] ) )
return true;
}
return false;
}
bool ParseStringList( const char *&expr, const CUtlVector< CUtlString > &strings, int &nOp )
{
while ( nOp-- )
{
if ( ParseString( expr, strings[ nOp ] ) )
return true;
}
return false;
}
int FindString( const CUtlVector< CUtlString > &strings, const char *str )
{
uint sn = strings.Count();
for ( uint si = 0; si < sn; ++si )
{
if ( !Q_strcmp( str, strings[ si ] ) )
return si;
}
return -1;
}
class ParseState_t
{
public:
ParseState_t( const CUtlStack<float> &stack, const char *expr )
: m_stacksize( stack.Count() ), m_startingExpr( expr ) {}
void Reset( CUtlStack<float> &stack, const char *&expr )
{
Assert( m_stacksize <= stack.Count() );
stack.PopMultiple( stack.Count() - m_stacksize );
expr = m_startingExpr;
}
private:
int m_stacksize;
const char* m_startingExpr;
};
void CExpressionCalculator::SetVariable( int nVariableIndex, float value )
{
m_varValues[ nVariableIndex ] = value;
}
void CExpressionCalculator::SetVariable( const char *var, float value )
{
int vi = FindString( m_varNames, var );
if ( vi >= 0 )
{
m_varValues[ vi ] = value;
}
else
{
m_varNames.AddToTail( var );
m_varValues.AddToTail( value );
}
}
int CExpressionCalculator::FindVariableIndex( const char *var )
{
return FindString( m_varNames, var );
}
bool CExpressionCalculator::Evaluate( float &value )
{
m_bIsBuildingArgumentList = false;
m_stack.PopMultiple( m_stack.Count() );
const char *pExpr = m_expr.Get();
bool success = ParseExpr( pExpr );
if ( success && m_stack.Count() == 1 )
{
value = m_stack.Top();
return true;
}
value = 0.0f;
return false;
}
//-----------------------------------------------------------------------------
// Builds a list of variable names from the expression
//-----------------------------------------------------------------------------
bool CExpressionCalculator::BuildVariableListFromExpression( )
{
m_bIsBuildingArgumentList = true;
m_stack.PopMultiple( m_stack.Count() );
const char *pExpr = m_expr.Get();
bool bSuccess = ParseExpr( pExpr );
m_bIsBuildingArgumentList = false;
if ( !bSuccess || m_stack.Count() != 1 )
{
m_varNames.RemoveAll();
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Iterate over variables
//-----------------------------------------------------------------------------
int CExpressionCalculator::VariableCount()
{
return m_varNames.Count();
}
const char *CExpressionCalculator::VariableName( int nIndex )
{
return m_varNames[nIndex];
}
bool CExpressionCalculator::ParseExpr( const char *&expr )
{
return ( expr != NULL ) && ParseConditional( expr );
}
bool CExpressionCalculator::ParseConditional( const char *&expr )
{
ParseState_t ps0( m_stack, expr );
if ( !ParseOr( expr ) )
{
ps0.Reset( m_stack, expr );
return false; // nothing matched
}
ParseState_t ps1( m_stack, expr );
if ( ParseString( expr, "?" ) &&
ParseExpr( expr ) &&
ParseString( expr, ":" ) &&
ParseExpr( expr ) )
{
float f3 = m_stack.Top();
m_stack.Pop();
float f2 = m_stack.Top();
m_stack.Pop();
float f1 = m_stack.Top();
m_stack.Pop();
m_stack.Push( f1 != 0.0f ? f2 : f3 );
return true; // and matched
}
ps1.Reset( m_stack, expr );
return true; // equality (or lower) matched
}
bool CExpressionCalculator::ParseOr( const char *&expr )
{
ParseState_t ps0( m_stack, expr );
if ( !ParseAnd( expr ) )
{
ps0.Reset( m_stack, expr );
return false; // nothing matched
}
ParseState_t ps1( m_stack, expr );
if ( ParseString( expr, "||" ) &&
ParseOr( expr ) )
{
float f2 = m_stack.Top();
m_stack.Pop();
float f1 = m_stack.Top();
m_stack.Pop();
m_stack.Push( ( f1 != 0.0f ) || ( f2 != 0.0f ) ? 1 : 0 );
return true; // and matched
}
ps1.Reset( m_stack, expr );
return true; // equality (or lower) matched
}
bool CExpressionCalculator::ParseAnd( const char *&expr )
{
ParseState_t ps0( m_stack, expr );
if ( !ParseEquality( expr ) )
{
ps0.Reset( m_stack, expr );
return false; // nothing matched
}
ParseState_t ps1( m_stack, expr );
if ( ParseString( expr, "&&" ) &&
ParseAnd( expr ) )
{
float f2 = m_stack.Top();
m_stack.Pop();
float f1 = m_stack.Top();
m_stack.Pop();
m_stack.Push( ( f1 != 0.0f ) && ( f2 != 0.0f ) ? 1 : 0 );
return true; // and matched
}
ps1.Reset( m_stack, expr );
return true; // equality (or lower) matched
}
bool CExpressionCalculator::ParseEquality( const char *&expr )
{
ParseState_t ps0( m_stack, expr );
if ( !ParseLessGreater( expr ) )
{
ps0.Reset( m_stack, expr );
return false; // nothing matched
}
const char *pOps[] = { "==", "!=" };
int nOp = 2;
ParseState_t ps1( m_stack, expr );
if ( ParseStringList( expr, pOps, nOp ) &&
ParseEquality( expr ) )
{
float f2 = m_stack.Top();
m_stack.Pop();
float f1 = m_stack.Top();
m_stack.Pop();
switch ( nOp )
{
case 0: // ==
m_stack.Push( f1 == f2 ? 1 : 0 );
break;
case 1: // !=
m_stack.Push( f1 != f2 ? 1 : 0 );
break;
}
return true; // equality matched
}
ps1.Reset( m_stack, expr );
return true; // lessgreater (or lower) matched
}
bool CExpressionCalculator::ParseLessGreater( const char *&expr )
{
ParseState_t ps0( m_stack, expr );
if ( !ParseAddSub( expr ) )
{
ps0.Reset( m_stack, expr );
return false; // nothing matched
}
const char *pOps[] = { "<", ">", "<=", ">=" };
int nOp = 4;
ParseState_t ps1( m_stack, expr );
if ( ParseStringList( expr, pOps, nOp ) &&
ParseLessGreater( expr ) )
{
float f2 = m_stack.Top();
m_stack.Pop();
float f1 = m_stack.Top();
m_stack.Pop();
switch ( nOp )
{
case 0: // <
m_stack.Push( f1 < f2 ? 1 : 0 );
break;
case 1: // >
m_stack.Push( f1 > f2 ? 1 : 0 );
break;
case 2: // <=
m_stack.Push( f1 <= f2 ? 1 : 0 );
break;
case 3: // >=
m_stack.Push( f1 >= f2 ? 1 : 0 );
break;
}
return true; // inequality matched
}
ps1.Reset( m_stack, expr );
return true; // addsub (or lower) matched
}
bool CExpressionCalculator::ParseAddSub( const char *&expr )
{
ParseState_t ps0( m_stack, expr );
if ( !ParseDivMul( expr ) )
{
ps0.Reset( m_stack, expr );
return false; // nothing matched
}
const char *pOps[] = { "+", "-" };
int nOp = 2;
ParseState_t ps1( m_stack, expr );
if ( ParseStringList( expr, pOps, nOp ) &&
ParseAddSub( expr ) )
{
float f2 = m_stack.Top();
m_stack.Pop();
float f1 = m_stack.Top();
m_stack.Pop();
switch ( nOp )
{
case 0: // +
m_stack.Push( f1 + f2 );
break;
case 1: // -
m_stack.Push( f1 - f2 );
break;
}
return true; // addsub matched
}
ps1.Reset( m_stack, expr );
return true; // divmul (or lower) matched
}
bool CExpressionCalculator::ParseDivMul( const char *&expr )
{
ParseState_t ps0( m_stack, expr );
if ( !ParseUnary( expr ) )
{
ps0.Reset( m_stack, expr );
return false; // nothing matched
}
const char *pOps[] = { "*", "/", "%" };
int nOp = 3;
ParseState_t ps1( m_stack, expr );
if ( ParseStringList( expr, pOps, nOp ) &&
ParseDivMul( expr ) )
{
float f2 = m_stack.Top();
m_stack.Pop();
float f1 = m_stack.Top();
m_stack.Pop();
switch ( nOp )
{
case 0: // *
m_stack.Push( f1 * f2 );
break;
case 1: // /
m_stack.Push( f1 / f2 );
break;
case 2: // %
m_stack.Push( fmod( f1, f2 ) );
break;
}
return true; // divmul matched
}
ps1.Reset( m_stack, expr );
return true; // unary (or lower) matched
}
bool CExpressionCalculator::ParseUnary( const char *&expr )
{
ParseState_t ps( m_stack, expr );
const char *pOps[] = { "+", "-", "!" };
int nOp = 3;
if ( ParseStringList( expr, pOps, nOp ) &&
ParseUnary( expr ) )
{
float f1 = m_stack.Top();
m_stack.Pop();
switch ( nOp )
{
case 0: // +
m_stack.Push( f1 );
break;
case 1: // -
m_stack.Push( -f1 );
break;
case 2: // !
m_stack.Push( f1 == 0 ? 1 : 0 );
break;
}
return true;
}
ps.Reset( m_stack, expr );
if ( ParsePrimary( expr ) )
return true;
ps.Reset( m_stack, expr );
return false;
}
bool CExpressionCalculator::ParsePrimary( const char *&expr )
{
ParseState_t ps( m_stack, expr );
float value = 0.0f;
if ( ParseLiteral( expr, value ) )
{
m_stack.Push( value );
return true;
}
ps.Reset( m_stack, expr );
int nVar = m_varNames.Count();
if ( ParseStringList( expr, m_varNames, nVar) )
{
m_stack.Push( m_varValues[ nVar ] );
return true;
}
ps.Reset( m_stack, expr );
if ( ParseString( expr, "(" ) &&
ParseExpr( expr ) &&
ParseString( expr, ")" ) )
{
return true;
}
ps.Reset( m_stack, expr );
if ( Parse1ArgFunc( expr ) ||
Parse2ArgFunc( expr ) ||
Parse3ArgFunc( expr ) ||
// Parse4ArgFunc( expr ) ||
Parse5ArgFunc( expr ) )
{
return true;
}
// If we're parsing it to discover names of variable names, add them here
if ( !m_bIsBuildingArgumentList )
return false;
// Variables can't start with a number
if ( isdigit( *expr ) )
return false;
const char *pStart = expr;
while ( isalnum( *expr ) || *expr == '_' )
{
++expr;
}
int nLen = (size_t)expr - (size_t)pStart;
char *pVariableName = (char*)_alloca( nLen+1 );
memcpy( pVariableName, pStart, nLen );
pVariableName[nLen] = 0;
SetVariable( pVariableName, 0.0f );
m_stack.Push( 0.0f );
return true;
}
/*
dtor(d) : converts degrees to radians
rtod(r) : converts radians to degrees
abs(a) : absolute value
floor(a) : rounds down to the nearest integer
ceiling(a) : rounds up to the nearest integer
round(a) : rounds to the nearest integer
sgn(a) : if a < 0 returns -1 else 1
sqr(a) : returns a * a
sqrt(a) : returns sqrt(a)
sin(a) : sin(a), a is in degrees
asin(a) : asin(a) returns degrees
cos(a) : cos(a), a is in degrees
acos(a) : acos(a) returns degrees
tan(a) : tan(a), a is in degrees
exp(a) : returns the exponential function of a
log(a) : returns the natural logaritm of a
*/
bool CExpressionCalculator::Parse1ArgFunc( const char *&expr )
{
ParseState_t ps( m_stack, expr );
const char *pFuncs[] =
{
"abs", "sqr", "sqrt", "sin", "asin", "cos", "acos", "tan",
"exp", "log", "dtor", "rtod", "floor", "ceiling", "round", "sign"
};
int nFunc = 16;
if ( ParseStringList( expr, pFuncs, nFunc ) &&
ParseString( expr, "(" ) &&
ParseExpr( expr ) &&
ParseString( expr, ")" ) )
{
float f1 = m_stack.Top();
m_stack.Pop();
switch ( nFunc )
{
case 0: // abs
m_stack.Push( fabs( f1 ) );
break;
case 1: // sqr
m_stack.Push( f1 * f1 );
break;
case 2: // sqrt
m_stack.Push( sqrt( f1 ) );
break;
case 3: // sin
m_stack.Push( sin( f1 ) );
break;
case 4: // asin
m_stack.Push( asin( f1 ) );
break;
case 5: // cos
m_stack.Push( cos( f1 ) );
break;
case 6: // acos
m_stack.Push( acos( f1 ) );
break;
case 7: // tan
m_stack.Push( tan( f1 ) );
break;
case 8: // exp
m_stack.Push( exp( f1 ) );
break;
case 9: // log
m_stack.Push( log( f1 ) );
break;
case 10: // dtor
m_stack.Push( DEG2RAD( f1 ) );
break;
case 11: // rtod
m_stack.Push( RAD2DEG( f1 ) );
break;
case 12: // floor
m_stack.Push( floor( f1 ) );
break;
case 13: // ceiling
m_stack.Push( ceil( f1 ) );
break;
case 14: // round
m_stack.Push( floor( f1 + 0.5f ) );
break;
case 15: // sign
m_stack.Push( f1 >= 0.0f ? 1.0f : -1.0f );
break;
}
return true;
}
return false;
}
/*
min(a,b) : if a<b returns a else b
max(a,b) : if a>b returns a else b
atan2(a,b) : atan2(a/b) returns degrees
pow(a,b) : function returns a raised to the power of b
*/
bool CExpressionCalculator::Parse2ArgFunc( const char *&expr )
{
ParseState_t ps( m_stack, expr );
const char *pFuncs[] = { "min", "max", "atan2", "pow" };
int nFunc = 4;
if ( ParseStringList( expr, pFuncs, nFunc ) &&
ParseString( expr, "(" ) &&
ParseExpr( expr ) &&
ParseString( expr, "," ) &&
ParseExpr( expr ) &&
ParseString( expr, ")" ) )
{
float f2 = m_stack.Top();
m_stack.Pop();
float f1 = m_stack.Top();
m_stack.Pop();
switch ( nFunc )
{
case 0: // min
m_stack.Push( min( f1, f2 ) );
break;
case 1: // max
m_stack.Push( max( f1, f2 ) );
break;
case 2: // atan2
m_stack.Push( atan2( f1, f2 ) );
break;
case 3: // pow
m_stack.Push( pow( f1, f2 ) );
break;
}
return true;
}
return false;
}
/*
inrange(x,a,b) : if x is between a and b, returns 1 else returns 0
clamp(x,a,b) : see bound() above
ramp(value,a,b) : returns 0 -> 1 as value goes from a to b
lerp(factor,a,b) : returns a -> b as value goes from 0 to 1
cramp(value,a,b) : clamp(ramp(value,a,b),0,1)
clerp(factor,a,b) : clamp(lerp(factor,a,b),a,b)
elerp(x,a,b) : ramp( 3*x*x - 2*x*x*x, a, b)
//elerp(factor,a,b) : lerp(lerp(sind(clerp(factor,-90,90)),0.5,1.0),a,b)
noise(a,b,c) : { solid noise pattern (improved perlin noise) indexed with three numbers }
*/
float ramp( float x, float a, float b )
{
return ( x - a ) / ( b - a );
}
float lerp( float x, float a, float b )
{
return a + x * ( b - a );
}
float smoothstep( float x )
{
return 3*x*x - 2*x*x*x;
}
bool CExpressionCalculator::Parse3ArgFunc( const char *&expr )
{
ParseState_t ps( m_stack, expr );
const char *pFuncs[] = { "inrange", "clamp", "ramp", "lerp", "cramp", "clerp", "elerp", "noise" };
int nFunc = 8;
if ( ParseStringList( expr, pFuncs, nFunc ) &&
ParseString( expr, "(" ) &&
ParseExpr( expr ) &&
ParseString( expr, "," ) &&
ParseExpr( expr ) &&
ParseString( expr, "," ) &&
ParseExpr( expr ) &&
ParseString( expr, ")" ) )
{
float f3 = m_stack.Top();
m_stack.Pop();
float f2 = m_stack.Top();
m_stack.Pop();
float f1 = m_stack.Top();
m_stack.Pop();
switch ( nFunc )
{
case 0: // inrange
m_stack.Push( ( f1 >= f2 ) && ( f1 <= f3 ) ? 1.0f : 0.0f );
break;
case 1: // clamp
m_stack.Push( clamp( f1, f2, f3 ) );
break;
case 2: // ramp
m_stack.Push( ramp( f1, f2, f3 ) );
break;
case 3: // lerp
m_stack.Push( lerp( f1, f2, f3 ) );
break;
case 4: // cramp
m_stack.Push( clamp( ramp( f1, f2, f3 ), 0, 1 ) );
break;
case 5: // clerp
m_stack.Push( clamp( lerp( f1, f2, f3 ), f2, f3 ) );
break;
case 6: // elerp
m_stack.Push( lerp( smoothstep( f1 ), f2, f3 ) );
break;
case 7: // noise
m_stack.Push( ImprovedPerlinNoise( Vector( f1, f2, f3 ) ) );
break;
}
return true;
}
return false;
}
//bool CExpressionCalculator::Parse4ArgFunc( const char *&expr );
/*
rescale (X,Xa,Xb,Ya,Yb) : lerp(ramp(X,Xa,Xb),Ya,Yb)
crescale(X,Xa,Xb,Ya,Yb) : clamp(rescale(X,Xa,Xb,Ya,Yb),Ya,Yb)
*/
float rescale( float x, float a, float b, float c, float d )
{
return lerp( ramp( x, a, b ), c, d );
}
bool CExpressionCalculator::Parse5ArgFunc( const char *&expr )
{
ParseState_t ps( m_stack, expr );
const char *pFuncs[] = { "rescale", "crescale" };
int nFunc = 2;
if ( ParseStringList( expr, pFuncs, nFunc ) &&
ParseString( expr, "(" ) &&
ParseExpr( expr ) &&
ParseString( expr, "," ) &&
ParseExpr( expr ) &&
ParseString( expr, "," ) &&
ParseExpr( expr ) &&
ParseString( expr, "," ) &&
ParseExpr( expr ) &&
ParseString( expr, "," ) &&
ParseExpr( expr ) &&
ParseString( expr, ")" ) )
{
float f5 = m_stack.Top();
m_stack.Pop();
float f4 = m_stack.Top();
m_stack.Pop();
float f3 = m_stack.Top();
m_stack.Pop();
float f2 = m_stack.Top();
m_stack.Pop();
float f1 = m_stack.Top();
m_stack.Pop();
switch ( nFunc )
{
case 0: // rescale
m_stack.Push( rescale( f1, f2, f3, f4, f5 ) );
break;
case 1: // crescale
m_stack.Push( clamp( rescale( f1, f2, f3, f4, f5 ), f4, f5 ) );
break;
}
return true;
}
return false;
}
void TestCalculator( const char *expr, float answer )
{
CExpressionCalculator calc( expr );
float result = 0.0f;
#ifdef DBGFLAG_ASSERT
bool success =
#endif
calc.Evaluate( result );
Assert( success && ( result == answer ) );
}
void TestCalculator( const char *expr, float answer, const char *var, float value )
{
CExpressionCalculator calc( expr );
calc.SetVariable( var, value );
float result = 0.0f;
#ifdef DBGFLAG_ASSERT
bool success =
#endif
calc.Evaluate( result );
Assert( success && ( result == answer ) );
}
void TestCalculator()
{
// TestCalculator( "-1", 1 );
TestCalculator( "2 * 3 + 4", 10 );
TestCalculator( "2 + 3 * 4", 14 );
TestCalculator( "2 * 3 * 4", 24 );
TestCalculator( "2 * -3 + 4", -2 );
TestCalculator( "12.0 / 2.0", 6 );
TestCalculator( "(2*3)+4", 10 );
TestCalculator( "( 1 + 2 ) / (1+2)", 1 );
TestCalculator( "(((5)))", 5 );
TestCalculator( "--5", 5 );
TestCalculator( "3.5 % 2", 1.5 );
TestCalculator( "1e-2", 0.01 );
TestCalculator( "9 == ( 3 * ( 1 + 2 ) )", 1 );
TestCalculator( "9 != ( 3 * ( 1 + 2 ) )", 0 );
TestCalculator( "9 <= ( 3 * ( 1 + 2 ) )", 1 );
TestCalculator( "9 < ( 3 * ( 1 + 2 ) )", 0 );
TestCalculator( "9 < 3", 0 );
TestCalculator( "10 >= 5", 1 );
// TestCalculator( "9 < ( 3 * ( 2 + 2 ) )", 0 );
TestCalculator( "x + 1", 5, "x", 4 );
TestCalculator( "pi - 3.14159", 0, "pi", 3.14159 );
// TestCalculator( "pi / 2", 0, "pi", 3.14159 );
TestCalculator( "abs(-10)", 10 );
TestCalculator( "sqr(-5)", 25 );
TestCalculator( "sqrt(9)", 3 );
// TestCalculator( "sqrt(-9)", -3 );
TestCalculator( "pow(2,3)", 8 );
TestCalculator( "min(abs(-4),2+3/2)", 3.5 );
TestCalculator( "round(0.5)", 1 );
TestCalculator( "round(0.49)", 0 );
TestCalculator( "round(-0.5)", 0 );
TestCalculator( "round(-0.51)", -1 );
TestCalculator( "inrange( 5, -8, 10 )", 1 );
TestCalculator( "inrange( 5, 5, 10 )", 1 );
TestCalculator( "inrange( 5, 6, 10 )", 0 );
TestCalculator( "elerp( 1/4, 0, 1 )", 3/16.0f - 1/32.0f );
TestCalculator( "rescale( 0.5, -1, 1, 0, 100 )", 75 );
TestCalculator( "1 > 2 ? 6 : 9", 9 );
TestCalculator( "1 ? 1 ? 2 : 4 : 1 ? 6 : 8", 2 );
TestCalculator( "0 ? 1 ? 2 : 4 : 1 ? 6 : 8", 6 );
TestCalculator( "noise( 0.123, 4.56, 78.9 )", ImprovedPerlinNoise( Vector( 0.123, 4.56, 78.9 ) ) );
}
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeExpressionOperator, CDmeExpressionOperator );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeExpressionOperator::OnConstruction()
{
m_result.Init( this, "result" );
m_expr.Init( this, "expr" );
m_bSpewResult.Init( this, "spewresult" );
#ifdef _DEBUG
TestCalculator();
#endif _DEBUG
}
void CDmeExpressionOperator::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CDmeExpressionOperator::IsInputAttribute( CDmAttribute *pAttribute )
{
const char *pName = pAttribute->GetName( );
#if 0 // skip this test, since none of these are float attributes, but leave the code as a reminder
if ( Q_strcmp( pName, "name" ) == 0 )
return false;
if ( Q_strcmp( pName, "expr" ) == 0 )
return false;
#endif
if ( Q_strcmp( pName, "result" ) == 0 )
return false;
if ( pAttribute->GetType() != AT_FLOAT )
return false;
return true;
}
void CDmeExpressionOperator::Operate()
{
CExpressionCalculator calc( m_expr.Get() );
for ( CDmAttribute *pAttribute = FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
{
if ( IsInputAttribute( pAttribute ) )
{
const char *pName = pAttribute->GetName( );
calc.SetVariable( pName, pAttribute->GetValue< float >() );
}
}
float oldValue = m_result;
calc.Evaluate( oldValue );
m_result = oldValue;
if ( m_bSpewResult )
{
Msg( "%s = '%f'\n", GetName(), (float)m_result );
}
}
void CDmeExpressionOperator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
for ( CDmAttribute *pAttribute = FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
{
if ( IsInputAttribute( pAttribute ) )
{
attrs.AddToTail( pAttribute );
}
}
attrs.AddToTail( m_expr.GetAttribute() );
}
void CDmeExpressionOperator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_result.GetAttribute() );
}
void CDmeExpressionOperator::SetSpewResult( bool state )
{
m_bSpewResult = state;
}

View File

@ -0,0 +1,48 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
//=============================================================================
// Valve includes
#include "datamodel/dmelementfactoryhelper.h"
#include "movieobjects/dmeeyeball.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( DmeEyeball, CDmeEyeball );
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeEyeball::OnConstruction()
{
m_flDiameter.InitAndSet( this, "diameter", 1.0 );
m_flYawAngle.InitAndSet( this, "angle", 2.0 );
m_flPupilScale.InitAndSet( this, "pupilScale", 1.0 );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeEyeball::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Returns the model relative position of the eyeball Position
//-----------------------------------------------------------------------------
void CDmeEyeball::GetWorldPosition( Vector &worldPosition )
{
matrix3x4_t mWorld;
GetShapeToWorldTransform( mWorld );
MatrixPosition( mWorld, worldPosition );
}

View File

@ -0,0 +1,46 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
//=============================================================================
// Valve includes
#include "datamodel/dmelementfactoryhelper.h"
#include "movieobjects/dmeeyeposition.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( DmeEyePosition, CDmeEyePosition );
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeEyePosition::OnConstruction()
{
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeEyePosition::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Returns the model relative position of the eyePosition
//-----------------------------------------------------------------------------
void CDmeEyePosition::GetWorldPosition( Vector &worldPosition )
{
matrix3x4_t mWorld;
GetShapeToWorldTransform( mWorld );
MatrixPosition( mWorld, worldPosition );
}

187
movieobjects/dmefaceset.cpp Normal file
View File

@ -0,0 +1,187 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmefaceset.h"
#include "movieobjects/dmematerial.h"
#include "tier0/dbg.h"
#include "UtlBuffer.h"
#include "datamodel/dmelementfactoryhelper.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( DmeFaceSet, CDmeFaceSet );
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
void CDmeFaceSet::OnConstruction()
{
m_indices.Init( this, "faces" );
m_material.Init( this, "material" );
}
void CDmeFaceSet::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// accessors
//-----------------------------------------------------------------------------
CDmeMaterial *CDmeFaceSet::GetMaterial()
{
return m_material.GetElement();
}
void CDmeFaceSet::SetMaterial( CDmeMaterial *pMaterial )
{
m_material = pMaterial;
}
int CDmeFaceSet::AddIndices( int nCount )
{
int nCurrentCount = m_indices.Count();
m_indices.EnsureCount( nCount + nCurrentCount );
return nCurrentCount;
}
void CDmeFaceSet::SetIndices( int nFirstIndex, int nCount, int *pIndices )
{
m_indices.SetMultiple( nFirstIndex, nCount, pIndices );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFaceSet::SetIndex( int i, int nValue )
{
m_indices.Set( i, nValue );
}
//-----------------------------------------------------------------------------
// Returns the number of triangulated indices
//-----------------------------------------------------------------------------
int CDmeFaceSet::GetNextPolygonVertexCount( int nFirstIndex ) const
{
int nCurrIndex = nFirstIndex;
int nTotalCount = m_indices.Count();
while( nCurrIndex < nTotalCount )
{
if ( m_indices[nCurrIndex] == -1 )
break;
++nCurrIndex;
}
return nCurrIndex - nFirstIndex;
}
//-----------------------------------------------------------------------------
// Returns the number of triangulated indices total
//-----------------------------------------------------------------------------
int CDmeFaceSet::GetTriangulatedIndexCount() const
{
int nIndexCount = 0;
int nVertexCount = 0;
int nTotalCount = m_indices.Count();
for ( int nCurrIndex = 0; nCurrIndex < nTotalCount; ++nCurrIndex )
{
if ( m_indices[nCurrIndex] == -1 )
{
if ( nVertexCount >= 3 )
{
nIndexCount += ( nVertexCount - 2 ) * 3;
}
nVertexCount = 0;
continue;
}
++nVertexCount;
}
if ( nVertexCount >= 3 )
{
nIndexCount += ( nVertexCount - 2 ) * 3;
}
return nIndexCount;
}
//-----------------------------------------------------------------------------
// Returns the number of indices total
//-----------------------------------------------------------------------------
int CDmeFaceSet::GetIndexCount() const
{
int nIndexCount = 0;
int nVertexCount = 0;
int nTotalCount = m_indices.Count();
for ( int nCurrIndex = 0; nCurrIndex < nTotalCount; ++nCurrIndex )
{
if ( m_indices[nCurrIndex] == -1 )
{
nIndexCount += nVertexCount;
nVertexCount = 0;
continue;
}
++nVertexCount;
}
nIndexCount += nVertexCount;
return nIndexCount;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeFaceSet::RemoveMultiple( int elem, int num )
{
m_indices.RemoveMultiple( elem, num );
}
//-----------------------------------------------------------------------------
// Returns the number of faces in the face set
//-----------------------------------------------------------------------------
int CDmeFaceSet::GetFaceCount() const
{
int nFaceCount = 0;
int nVertexCount = 0;
const int nIndexCount = NumIndices();
for ( int i = 0; i < nIndexCount; ++i )
{
if ( GetIndex( i ) < 0 )
{
if ( nVertexCount > 0 )
{
++nFaceCount;
}
nVertexCount = 0;
continue;
}
++nVertexCount;
}
if ( nVertexCount > 0 )
{
++nFaceCount;
}
return nFaceCount;
}

View File

@ -0,0 +1,694 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Dme version of a game model (MDL)
//
//=============================================================================
#include "movieobjects/dmegamemodel.h"
#include "movieobjects_interfaces.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "datacache/imdlcache.h"
#include "studio.h"
#include "tier3/tier3.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( DmeGlobalFlexControllerOperator, CDmeGlobalFlexControllerOperator );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeGlobalFlexControllerOperator::OnConstruction()
{
m_flexWeight.Init( this, "flexWeight" );
m_gameModel.Init( this, "gameModel", FATTRIB_HAS_CALLBACK );
m_ToAttributeHandle = DMATTRIBUTE_HANDLE_INVALID;
m_nFlexControllerIndex = -1;
}
void CDmeGlobalFlexControllerOperator::OnDestruction()
{
}
void CDmeGlobalFlexControllerOperator::Resolve()
{
if ( m_nFlexControllerIndex < 0 )
{
m_nFlexControllerIndex = FindGlobalFlexControllerIndex();
}
}
void CDmeGlobalFlexControllerOperator::OnAttributeChanged( CDmAttribute *pAttribute )
{
// Don't have the required interface...
if ( !g_pGlobalFlexController )
return;
if ( pAttribute == m_gameModel.GetAttribute() && m_gameModel.GetElement() )
{
m_nFlexControllerIndex = FindGlobalFlexControllerIndex();
SetupToAttribute();
}
}
void CDmeGlobalFlexControllerOperator::Operate()
{
CDmAttribute *pToAttr = g_pDataModel->GetAttribute( m_ToAttributeHandle );
if ( !pToAttr )
return;
DmAttributeType_t type = m_flexWeight.GetAttribute()->GetType();
const void *pValue = m_flexWeight.GetAttribute()->GetValueUntyped();
if ( IsArrayType( pToAttr->GetType() ) )
{
if ( m_nFlexControllerIndex == -1 )
return;
CDmrGenericArray array( pToAttr );
array.Set( m_nFlexControllerIndex, type, pValue );
}
else
{
pToAttr->SetValue( type, pValue );
}
}
void CDmeGlobalFlexControllerOperator::SetGameModel( CDmeGameModel *gameModel )
{
m_gameModel = gameModel;
}
void CDmeGlobalFlexControllerOperator::SetWeight( float flWeight )
{
m_flexWeight = flWeight;
}
void CDmeGlobalFlexControllerOperator::SetMapping( int globalIndex )
{
m_nFlexControllerIndex = globalIndex;
if ( m_gameModel.GetElement() )
{
if ( (uint)globalIndex >= m_gameModel->NumFlexWeights() )
{
m_gameModel->SetNumFlexWeights( (uint)( globalIndex + 1 ) );
}
}
}
int CDmeGlobalFlexControllerOperator::GetGlobalIndex() const
{
return m_nFlexControllerIndex;
}
void CDmeGlobalFlexControllerOperator::GetInputAttributes ( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_flexWeight.GetAttribute() );
}
void CDmeGlobalFlexControllerOperator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
CDmAttribute *toAttribute = g_pDataModel->GetAttribute( m_ToAttributeHandle );
if ( toAttribute )
{
attrs.AddToTail( toAttribute );
}
}
void CDmeGlobalFlexControllerOperator::SetupToAttribute()
{
CDmElement *pObject = m_gameModel.GetElement();
if ( pObject == NULL)
return;
CDmAttribute *pAttr = pObject->GetAttribute( "flexWeights" );
Assert( pAttr );
if ( !pAttr )
return;
m_ToAttributeHandle = pAttr->GetHandle();
return;
}
//-----------------------------------------------------------------------------
// Connect up stuff by index
//-----------------------------------------------------------------------------
int CDmeGlobalFlexControllerOperator::FindGlobalFlexControllerIndex() const
{
int nGlobalFlexControllerIndex = -1;
const char *pModelName = m_gameModel->GetModelName();
MDLHandle_t h = pModelName && pModelName[0] ? g_pMDLCache->FindMDL( pModelName ) : MDLHANDLE_INVALID;
if ( h != MDLHANDLE_INVALID )
{
studiohdr_t *hdr = g_pMDLCache->GetStudioHdr( h );
Assert( hdr );
if ( hdr )
{
int fc = hdr->numflexcontrollers;
for ( LocalFlexController_t i = LocalFlexController_t(0) ; i < fc; ++i )
{
mstudioflexcontroller_t *flex = hdr->pFlexcontroller( i );
if ( flex->localToGlobal == -1 )
{
flex->localToGlobal = g_pGlobalFlexController->FindGlobalFlexController( flex->pszName() );
}
if ( !Q_stricmp( flex->pszName(), GetName() ) )
{
nGlobalFlexControllerIndex = flex->localToGlobal;
// Grow the array
if ( (uint)flex->localToGlobal >= m_gameModel->NumFlexWeights() )
{
m_gameModel->SetNumFlexWeights( (uint)( flex->localToGlobal + 1 ) );
}
break;
}
}
}
g_pMDLCache->Release( h );
}
return nGlobalFlexControllerIndex;
}
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeGameModel, CDmeGameModel );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeGameModel::OnConstruction()
{
m_flexWeights.Init( this, "flexWeights" );
m_viewTarget.Init( this, "viewTarget" );
m_modelName.Init( this, "modelName", FATTRIB_HAS_CALLBACK );
m_skin.Init( this, "skin" );
m_body.Init( this, "body" );
m_sequence.Init( this, "sequence" );
m_flags.Init( this, "flags" );
m_bones.Init( this, "bones" );
m_globalFlexControllers.Init( this, "globalFlexControllers" );
m_bComputeBounds.Init( this, "computeBounds" );
}
void CDmeGameModel::OnDestruction()
{
}
CDmeGlobalFlexControllerOperator *CDmeGameModel::AddGlobalFlexController( const char *controllerName, int globalIndex )
{
int i, c;
c = m_globalFlexControllers.Count();
for ( i = 0; i < c; ++i )
{
CDmeGlobalFlexControllerOperator *op = m_globalFlexControllers.Get( i );
Assert( op );
if ( op && !Q_stricmp( op->GetName(), controllerName ) )
break;
}
if ( i >= c )
{
CDmeGlobalFlexControllerOperator *newOperator = CreateElement< CDmeGlobalFlexControllerOperator >( controllerName, GetFileId() );
Assert( newOperator );
if ( !newOperator )
return NULL;
i = m_globalFlexControllers.AddToTail( newOperator );
}
Assert( m_globalFlexControllers.IsValidIndex( i ) );
CDmeGlobalFlexControllerOperator *op = m_globalFlexControllers.Get( i );
Assert( op );
if ( op )
{
op->SetMapping( globalIndex );
op->SetGameModel( this );
}
if ( (uint)globalIndex >= NumFlexWeights() )
{
SetNumFlexWeights( globalIndex + 1 );
}
return op;
}
//-----------------------------------------------------------------------------
// Find a flex controller by its global index
//-----------------------------------------------------------------------------
CDmeGlobalFlexControllerOperator *CDmeGameModel::FindGlobalFlexController( int nGlobalIndex )
{
int i, c;
c = m_globalFlexControllers.Count();
for ( i = 0; i < c; ++i )
{
CDmeGlobalFlexControllerOperator *op = m_globalFlexControllers.Get( i );
Assert( op );
if ( op && op->GetGlobalIndex() == nGlobalIndex )
return op;
}
return NULL;
}
studiohdr_t* CDmeGameModel::GetStudioHdr() const
{
const char *pModelName = GetModelName();
MDLHandle_t h = pModelName && pModelName[0] ? g_pMDLCache->FindMDL( pModelName ) : MDLHANDLE_INVALID;
return ( h != MDLHANDLE_INVALID ) ? g_pMDLCache->GetStudioHdr( h ) : NULL;
}
// A src bone transform transforms pre-compiled data (.dmx or .smd files, for example)
// into post-compiled data (.mdl or .ani files)
bool CDmeGameModel::GetSrcBoneTransforms( matrix3x4_t *pPreTransform, matrix3x4_t *pPostTransform, int nBoneIndex ) const
{
studiohdr_t *pStudioHdr = GetStudioHdr();
if ( !pStudioHdr )
return false;
if ( pStudioHdr->numbones <= nBoneIndex )
return false;
const char *pBoneName = pStudioHdr->pBone( nBoneIndex )->pszName();
int nCount = pStudioHdr->NumSrcBoneTransforms();
for ( int i = 0; i < nCount; ++i )
{
const mstudiosrcbonetransform_t *pSrcTransform = pStudioHdr->SrcBoneTransform( i );
if ( Q_stricmp( pSrcTransform->pszName(), pBoneName ) )
continue;
MatrixCopy( pSrcTransform->pretransform, *pPreTransform );
MatrixCopy( pSrcTransform->posttransform, *pPostTransform );
return true;
}
return false;
}
bool CDmeGameModel::IsRootTransform( int nBoneIndex ) const
{
studiohdr_t *pStudioHdr = GetStudioHdr();
if ( !pStudioHdr )
return true;
if ( pStudioHdr->numbones <= nBoneIndex )
return true;
mstudiobone_t *pBone = pStudioHdr->pBone( nBoneIndex );
return pBone->parent == -1;
}
int CDmeGameModel::NumGlobalFlexControllers() const
{
return m_globalFlexControllers.Count();
}
CDmeGlobalFlexControllerOperator *CDmeGameModel::GetGlobalFlexController( int localIndex )
{
return m_globalFlexControllers.Get( localIndex );
}
void CDmeGameModel::RemoveGlobalFlexController( CDmeGlobalFlexControllerOperator *controller )
{
int c = m_globalFlexControllers.Count();
for ( int i = 0; i < c; ++i )
{
CDmeGlobalFlexControllerOperator *check = m_globalFlexControllers.Get( i );
if ( check == controller )
{
m_globalFlexControllers.Remove( i );
break;
}
}
}
void CDmeGameModel::AppendGlobalFlexControllerOperators( CUtlVector< IDmeOperator * >& list )
{
int c = m_globalFlexControllers.Count();
for ( int i = 0 ; i < c; ++i )
{
CDmeOperator *op = m_globalFlexControllers.Get( i );
if ( !op )
continue;
list.AddToTail( op );
}
}
//-----------------------------------------------------------------------------
// accessors
//-----------------------------------------------------------------------------
void CDmeGameModel::AddBone( CDmeTransform* pTransform )
{
m_bones.AddToTail( pTransform );
}
//-----------------------------------------------------------------------------
// Is this dag under the game model?
//-----------------------------------------------------------------------------
static bool IsDagUnderGameModel( CDmeDag *pDag, CDmeGameModel *pGameModel )
{
if ( pDag == pGameModel )
return true;
DmAttributeReferenceIterator_t i = g_pDataModel->FirstAttributeReferencingElement( pDag->GetHandle() );
while ( i != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID )
{
CDmAttribute *pAttribute = g_pDataModel->GetAttribute( i );
CDmElement *pDmeParent = pAttribute->GetOwner();
const static UtlSymId_t symChildren = g_pDataModel->GetSymbol( "children" );
if ( pDmeParent && pAttribute->GetNameSymbol() == symChildren )
{
CDmeDag *pParent = CastElement< CDmeDag >( pDmeParent );
if ( pParent && ( pParent->GetFileId() == pDag->GetFileId() ) )
{
if ( IsDagUnderGameModel( pParent, pGameModel ) )
return true;
}
}
i = g_pDataModel->NextAttributeReferencingElement( i );
}
return false;
}
//-----------------------------------------------------------------------------
// Is this dag under the game model?
//-----------------------------------------------------------------------------
static CDmeDag* GetDagForTransform( CDmeTransform *pTransform, CDmeGameModel *pGameModel )
{
DmAttributeReferenceIterator_t i = g_pDataModel->FirstAttributeReferencingElement( pTransform->GetHandle() );
while ( i != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID )
{
CDmAttribute *pAttribute = g_pDataModel->GetAttribute( i );
CDmElement *pDmeParent = pAttribute->GetOwner();
const static UtlSymId_t symTransform = g_pDataModel->GetSymbol( "transform" );
if ( pDmeParent && pAttribute->GetNameSymbol() == symTransform )
{
CDmeDag *pParent = CastElement< CDmeDag >( pDmeParent );
if ( pParent && ( pParent->GetFileId() == pTransform->GetFileId() ) )
{
if ( IsDagUnderGameModel( pParent, pGameModel ) )
return pParent;
}
}
i = g_pDataModel->NextAttributeReferencingElement( i );
}
return NULL;
}
//-----------------------------------------------------------------------------
// Finds existing dags
//-----------------------------------------------------------------------------
void CDmeGameModel::PopulateExistingDagList( CDmeDag** pDags, int nCount )
{
int nCurrentBoneCount = m_bones.Count();
for ( int i = 0; i < nCount; ++i )
{
if ( i >= nCurrentBoneCount )
{
pDags[ i ] = NULL;
continue;
}
CDmeTransform *pTransform = GetBone( i );
Assert( pTransform );
pDags[ i ] = pTransform ? GetDagForTransform( pTransform, this ) : NULL;
}
}
//-----------------------------------------------------------------------------
// Adds bones to the game model
//-----------------------------------------------------------------------------
void CDmeGameModel::AddBones( studiohdr_t *pStudioHdr, const char *pBaseName, int nFirstBone, int nCount )
{
if ( nFirstBone + nCount > pStudioHdr->numbones )
{
nCount = pStudioHdr->numbones - nFirstBone;
if ( nCount <= 0 )
return;
}
// make room for bones
CDmeDag** pDags = ( CDmeDag** )_alloca( pStudioHdr->numbones * sizeof(CDmeDag*) );
int nDagCount = nFirstBone;
PopulateExistingDagList( pDags, nFirstBone );
char name[ 256 ];
for ( int i = 0; i < nCount; ++i )
{
int bi = i + nFirstBone;
// get parent
mstudiobone_t *pBone = pStudioHdr->pBone( bi );
int parentIndex = pBone->parent;
Assert( parentIndex < nDagCount );
// build dag hierarchy to match bone hierarchy
CDmeDag *pParent = ( parentIndex < 0 ) ? this : pDags[ parentIndex ];
Q_snprintf( name, sizeof( name ), "%s_bone %d (%s)", pBaseName, bi, pBone->pszName() );
CDmeDag *pDag = CreateElement< CDmeDag >( name, GetFileId() );
pDags[nDagCount++] = pDag;
pParent->AddChild( pDag );
CDmeTransform *pTransform = pDag->GetTransform();
pTransform->SetName( name );
// add different bone representations to dme model and input
AddBone( pTransform );
}
}
void CDmeGameModel::SetBone( uint index, const Vector& pos, const Quaternion& rot )
{
m_bones[ index ]->SetPosition( pos );
m_bones[ index ]->SetOrientation( rot );
}
void CDmeGameModel::RemoveAllBones()
{
m_bones.RemoveAll();
}
uint CDmeGameModel::NumBones() const
{
return m_bones.Count();
}
CDmeTransform *CDmeGameModel::GetBone( uint index ) const
{
return m_bones[ index ];
}
int CDmeGameModel::FindBone( CDmeTransform *pTransform ) const
{
return m_bones.Find( pTransform );
}
uint CDmeGameModel::NumFlexWeights() const
{
return m_flexWeights.Count();
}
const CUtlVector< float >& CDmeGameModel::GetFlexWeights() const
{
return m_flexWeights.Get();
}
void CDmeGameModel::SetNumFlexWeights( uint nFlexWeights )
{
if ( nFlexWeights > (uint)m_flexWeights.Count() )
{
while ( (uint)m_flexWeights.Count() < nFlexWeights )
{
m_flexWeights.AddToTail( 0.0f );
}
}
else
{
while ( (uint)m_flexWeights.Count() > nFlexWeights )
{
m_flexWeights.Remove( (uint)m_flexWeights.Count() - 1 );
}
}
}
void CDmeGameModel::SetFlexWeights( uint nFlexWeights, const float* flexWeights )
{
m_flexWeights.CopyArray( flexWeights, nFlexWeights );
}
const Vector& CDmeGameModel::GetViewTarget() const
{
return m_viewTarget.Get();
}
void CDmeGameModel::SetViewTarget( const Vector &viewTarget )
{
m_viewTarget = viewTarget;
}
void CDmeGameModel::SetFlags( int nFlags )
{
m_flags = nFlags;
}
void CDmeGameModel::SetSkin( int nSkin )
{
m_skin = nSkin;
}
void CDmeGameModel::SetBody( int nBody )
{
m_body = nBody;
}
void CDmeGameModel::SetSequence( int nSequence )
{
m_sequence = nSequence;
}
int CDmeGameModel::GetSkin() const
{
return m_skin;
}
int CDmeGameModel::GetBody() const
{
return m_body;
}
int CDmeGameModel::GetSequence() const
{
return m_sequence;
}
const char *CDmeGameModel::GetModelName() const
{
return m_modelName.Get();
}
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeGameSprite, CDmeGameSprite );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeGameSprite::OnConstruction()
{
m_modelName .Init( this, "modelName" );
m_frame .Init( this, "frame" );
m_rendermode.Init( this, "rendermode" );
m_renderfx .Init( this, "renderfx" );
m_renderscale.Init( this, "renderscale" );
m_color .Init( this, "color" );
m_proxyRadius.Init( this, "proxyRadius" );
}
void CDmeGameSprite::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// accessors
//-----------------------------------------------------------------------------
const char *CDmeGameSprite::GetModelName() const
{
return m_modelName.Get();
}
float CDmeGameSprite::GetScale() const
{
return m_renderscale;
}
float CDmeGameSprite::GetFrame() const
{
return m_frame;
}
int CDmeGameSprite::GetRenderMode() const
{
return m_rendermode;
}
int CDmeGameSprite::GetRenderFX() const
{
return m_renderfx;
}
const Color &CDmeGameSprite::GetColor() const
{
return m_color;
}
float CDmeGameSprite::GetProxyRadius() const
{
return m_proxyRadius;
}
void CDmeGameSprite::SetState( bool bVisible, float nFrame, int nRenderMode, int nRenderFX, float flRenderScale, float flProxyRadius,
const Vector &pos, const Quaternion &rot, const Color &color )
{
m_Visible = bVisible;
m_frame = nFrame;
m_rendermode = nRenderMode;
m_renderfx = nRenderFX;
m_renderscale = flRenderScale;
m_proxyRadius = flProxyRadius;
m_color = color;
CDmeTransform *pTransform = GetTransform();
pTransform->SetPosition( pos );
pTransform->SetOrientation( rot );
}
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeGamePortal, CDmeGamePortal );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeGamePortal::OnConstruction()
{
m_flStaticAmount .Init( this, "staticAmount" );
m_flSecondaryStaticAmount .Init( this, "secondaryStaticAmount" );
m_flOpenAmount .Init( this, "openAmount" );
m_nPortalId .Init( this, "portalId" );
m_nLinkedPortalId .Init( this, "linkedPortalId" );
m_bIsPortal2 .Init( this, "isPortal2" );
}
void CDmeGamePortal::OnDestruction()
{
}

View File

@ -0,0 +1,253 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// game model input - gets its values from an MDL within the game
//
//=============================================================================
#include "movieobjects/dmegamemodelinput.h"
#include "movieobjects_interfaces.h"
#include "datamodel/dmelementfactoryhelper.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( DmeGameModelInput, CDmeGameModelInput );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeGameModelInput::OnConstruction()
{
m_skin.Init( this, "skin" );
m_body.Init( this, "body" );
m_sequence.Init( this, "sequence" );
m_visible.Init( this, "visible" );
m_flags.Init( this, "flags" );
m_flexWeights.Init( this, "flexWeights" );
m_viewTarget.Init( this, "viewTarget" );
m_bonePositions.Init( this, "bonePositions" );
m_boneRotations.Init( this, "boneRotations" );
m_position.Init( this, "position" );
m_rotation.Init( this, "rotation" );
}
void CDmeGameModelInput::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Operator methods
//-----------------------------------------------------------------------------
bool CDmeGameModelInput::IsDirty()
{
return true; // TODO - keep some bit of state that remembers when its changed
}
void CDmeGameModelInput::Operate()
{
}
void CDmeGameModelInput::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_skin.GetAttribute() );
attrs.AddToTail( m_body.GetAttribute() );
attrs.AddToTail( m_sequence.GetAttribute() );
attrs.AddToTail( m_visible.GetAttribute() );
attrs.AddToTail( m_flags.GetAttribute() );
attrs.AddToTail( m_flexWeights.GetAttribute() );
attrs.AddToTail( m_viewTarget.GetAttribute() );
attrs.AddToTail( m_bonePositions.GetAttribute() );
attrs.AddToTail( m_boneRotations.GetAttribute() );
attrs.AddToTail( m_position.GetAttribute() );
attrs.AddToTail( m_rotation.GetAttribute() );
}
//-----------------------------------------------------------------------------
// accessors
//-----------------------------------------------------------------------------
void CDmeGameModelInput::SetFlags( int nFlags )
{
m_flags = nFlags;
}
//-----------------------------------------------------------------------------
// accessors
//-----------------------------------------------------------------------------
void CDmeGameModelInput::AddBone( const Vector& pos, const Quaternion& rot )
{
m_bonePositions.AddToTail( pos );
m_boneRotations.AddToTail( rot );
}
void CDmeGameModelInput::SetBone( uint index, const Vector& pos, const Quaternion& rot )
{
m_bonePositions.Set( index, pos );
m_boneRotations.Set( index, rot );
}
void CDmeGameModelInput::SetRootBone( const Vector& pos, const Quaternion& rot )
{
m_position.Set( pos );
m_rotation.Set( rot );
}
uint CDmeGameModelInput::NumBones() const
{
Assert( m_bonePositions.Count() == m_boneRotations.Count() );
return m_bonePositions.Count();
}
void CDmeGameModelInput::SetFlexWeights( uint nFlexWeights, const float* flexWeights )
{
m_flexWeights.CopyArray( flexWeights, nFlexWeights );
}
uint CDmeGameModelInput::NumFlexWeights() const
{
return m_flexWeights.Count();
}
const Vector& CDmeGameModelInput::GetViewTarget() const
{
return m_viewTarget;
}
void CDmeGameModelInput::SetViewTarget( const Vector &viewTarget )
{
m_viewTarget = viewTarget;
}
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeGameSpriteInput, CDmeGameSpriteInput );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeGameSpriteInput::OnConstruction()
{
m_visible .Init( this, "visible" );
m_frame .Init( this, "frame" );
m_rendermode .Init( this, "rendermode" );
m_renderfx .Init( this, "renderfx" );
m_renderscale.Init( this, "renderscale" );
m_proxyRadius.Init( this, "proxyRadius" );
m_position .Init( this, "position" );
m_rotation .Init( this, "rotation" );
m_color .Init( this, "color" );
}
void CDmeGameSpriteInput::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Operator methods
//-----------------------------------------------------------------------------
bool CDmeGameSpriteInput::IsDirty()
{
return true; // TODO - keep some bit of state that remembers when its changed
}
void CDmeGameSpriteInput::Operate()
{
}
void CDmeGameSpriteInput::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_visible.GetAttribute() );
attrs.AddToTail( m_frame.GetAttribute() );
attrs.AddToTail( m_rendermode.GetAttribute() );
attrs.AddToTail( m_renderfx.GetAttribute() );
attrs.AddToTail( m_renderscale.GetAttribute() );
attrs.AddToTail( m_proxyRadius.GetAttribute() );
attrs.AddToTail( m_position.GetAttribute() );
attrs.AddToTail( m_rotation.GetAttribute() );
attrs.AddToTail( m_color.GetAttribute() );
}
//-----------------------------------------------------------------------------
// accessors
//-----------------------------------------------------------------------------
void CDmeGameSpriteInput::SetState( bool bVisible, float nFrame, int nRenderMode, int nRenderFX, float flRenderScale, float flProxyRadius,
const Vector &pos, const Quaternion &rot, const Color &color )
{
m_visible = bVisible;
m_frame = nFrame;
m_rendermode = nRenderMode;
m_renderfx = nRenderFX;
m_renderscale = flRenderScale;
m_proxyRadius = flProxyRadius;
m_position = pos;
m_rotation = rot;
m_color = color;
}
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeGameCameraInput, CDmeGameCameraInput );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeGameCameraInput::OnConstruction()
{
m_position.Init( this, "position" );
m_rotation.Init( this, "rotation" );
m_fov.Init( this, "fov" );
}
void CDmeGameCameraInput::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Operator methods
//-----------------------------------------------------------------------------
bool CDmeGameCameraInput::IsDirty()
{
return true; // TODO - keep some bit of state that remembers when its changed
}
void CDmeGameCameraInput::Operate()
{
}
void CDmeGameCameraInput::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_position.GetAttribute() );
attrs.AddToTail( m_rotation.GetAttribute() );
attrs.AddToTail( m_fov.GetAttribute() );
}
//-----------------------------------------------------------------------------
// accessors
//-----------------------------------------------------------------------------
void CDmeGameCameraInput::SetPosition( const Vector& pos )
{
m_position.Set( pos );
}
void CDmeGameCameraInput::SetOrientation( const Quaternion& rot )
{
m_rotation.Set( rot );
}
void CDmeGameCameraInput::SetFOV( float fov )
{
m_fov = fov;
}

45
movieobjects/dmeimage.cpp Normal file
View File

@ -0,0 +1,45 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmeimage.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "bitmap/imageformat.h"
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeImage, CDmeImage );
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
void CDmeImage::OnConstruction()
{
m_Width.Init( this, "width" );
m_Height.Init( this, "height" );
m_Format.Init( this, "format" );
m_Bits.Init( this, "bits" );
}
void CDmeImage::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Image format
//-----------------------------------------------------------------------------
ImageFormat CDmeImage::Format() const
{
return (ImageFormat)( m_Format.Get() );
}
const char *CDmeImage::FormatName() const
{
return ImageLoader::GetName( Format() );
}

36
movieobjects/dmeinput.cpp Normal file
View File

@ -0,0 +1,36 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmeinput.h"
#include "datamodel/dmelementfactoryhelper.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ABSTRACT_ELEMENT( DmeInput, CDmeInput );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeInput::OnConstruction()
{
}
void CDmeInput::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// IsDirty - ie needs to operate
//-----------------------------------------------------------------------------
bool CDmeInput::IsDirty()
{
return true;
}

151
movieobjects/dmejoint.cpp Normal file
View File

@ -0,0 +1,151 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Dme version of a joint of a skeletal model (gets compiled into a MDL)
//
//=============================================================================
#include "movieobjects/dmejoint.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "materialsystem/imaterialsystem.h"
#include "materialsystem/imesh.h"
#include "tier1/KeyValues.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( DmeJoint, CDmeJoint );
//-----------------------------------------------------------------------------
// Should I draw joints?
//-----------------------------------------------------------------------------
bool CDmeJoint::s_bDrawJoints = false;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeJoint::OnConstruction()
{
if ( !g_pMaterialSystem )
return;
KeyValues *pVMTKeyValues = new KeyValues( "wireframe" );
pVMTKeyValues->SetInt( "$vertexcolor", 1 );
pVMTKeyValues->SetInt( "$ignorez", 1 );
m_JointMaterial.Init( "__DmeJointMaterial", pVMTKeyValues );
}
void CDmeJoint::OnDestruction()
{
if ( !g_pMaterialSystem )
return;
m_JointMaterial.Shutdown();
}
//-----------------------------------------------------------------------------
// Activate, deactivate joint drawing
//-----------------------------------------------------------------------------
void CDmeJoint::DrawJointHierarchy( bool bDrawJoints )
{
s_bDrawJoints = bDrawJoints;
}
//-----------------------------------------------------------------------------
// For rendering joints
//-----------------------------------------------------------------------------
#define AXIS_SIZE 3.0f
void CDmeJoint::DrawJoints( )
{
if ( !g_pMaterialSystem )
return;
int cn = GetChildCount();
// Draw the joint hierarchy
PushDagTransform();
matrix3x4_t shapeToWorld;
GetShapeToWorldTransform( shapeToWorld );
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->LoadMatrix( shapeToWorld );
pRenderContext->Bind( m_JointMaterial );
IMesh *pMesh = pRenderContext->GetDynamicMesh( );
CMeshBuilder meshBuilder;
meshBuilder.Begin( pMesh, MATERIAL_LINES, 3 + cn );
for ( int ci = 0; ci < cn; ++ci )
{
CDmeJoint *pJoint = CastElement<CDmeJoint>( GetChild( ci ) );
if ( !pJoint )
continue;
Vector vecChildPosition = pJoint->GetTransform()->GetPosition();
meshBuilder.Position3f( 0.0f, 0.0f, 0.0f );
meshBuilder.Color4ub( 128, 128, 128, 255 );
meshBuilder.AdvanceVertex();
meshBuilder.Position3fv( vecChildPosition.Base() );
meshBuilder.Color4ub( 128, 128, 128, 255 );
meshBuilder.AdvanceVertex();
}
meshBuilder.Position3f( 0.0f, 0.0f, 0.0f );
meshBuilder.Color4ub( 255, 0, 0, 255 );
meshBuilder.AdvanceVertex();
meshBuilder.Position3f( AXIS_SIZE, 0.0f, 0.0f );
meshBuilder.Color4ub( 255, 0, 0, 255 );
meshBuilder.AdvanceVertex();
meshBuilder.Position3f( 0.0f, 0.0f, 0.0f );
meshBuilder.Color4ub( 0, 255, 0, 255 );
meshBuilder.AdvanceVertex();
meshBuilder.Position3f( 0.0f, AXIS_SIZE, 0.0f );
meshBuilder.Color4ub( 0, 255, 0, 255 );
meshBuilder.AdvanceVertex();
meshBuilder.Position3f( 0.0f, 0.0f, 0.0f );
meshBuilder.Color4ub( 0, 0, 255, 255 );
meshBuilder.AdvanceVertex();
meshBuilder.Position3f( 0.0f, 0.0f, AXIS_SIZE );
meshBuilder.Color4ub( 0, 0, 255, 255 );
meshBuilder.AdvanceVertex();
meshBuilder.End();
pMesh->Draw();
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->LoadIdentity();
PopDagTransform();
}
//-----------------------------------------------------------------------------
// Rendering method for the dag
//-----------------------------------------------------------------------------
void CDmeJoint::Draw( CDmeDrawSettings *pDrawSettings /* = NULL */ )
{
if ( s_bDrawJoints && IsVisible() )
{
DrawJoints();
}
BaseClass::Draw( pDrawSettings );
}

View File

@ -0,0 +1,141 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmekeyboardinput.h"
#include "movieobjects_interfaces.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "vgui/iinput.h"
#include "vgui/keycode.h"
#include "tier3/tier3.h"
#include "tier0/dbg.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// global list of all keys supported
//-----------------------------------------------------------------------------
struct KeyInfo
{
vgui::KeyCode code;
const char *str;
};
const uint g_nKeys = 48;
const KeyInfo g_keyInfo[ g_nKeys ] =
{
{ KEY_0, "0" },
{ KEY_1, "1" },
{ KEY_2, "2" },
{ KEY_3, "3" },
{ KEY_4, "4" },
{ KEY_5, "5" },
{ KEY_6, "6" },
{ KEY_7, "7" },
{ KEY_8, "8" },
{ KEY_9, "9" },
{ KEY_A, "A" },
{ KEY_B, "B" },
{ KEY_C, "C" },
{ KEY_D, "D" },
{ KEY_E, "E" },
{ KEY_F, "F" },
{ KEY_G, "G" },
{ KEY_H, "H" },
{ KEY_I, "I" },
{ KEY_J, "J" },
{ KEY_K, "K" },
{ KEY_L, "L" },
{ KEY_M, "M" },
{ KEY_N, "N" },
{ KEY_O, "O" },
{ KEY_P, "P" },
{ KEY_Q, "Q" },
{ KEY_R, "R" },
{ KEY_S, "S" },
{ KEY_T, "T" },
{ KEY_U, "U" },
{ KEY_V, "V" },
{ KEY_W, "W" },
{ KEY_X, "X" },
{ KEY_Y, "Y" },
{ KEY_Z, "Z" },
{ KEY_F1, "F1" },
{ KEY_F2, "F2" },
{ KEY_F3, "F3" },
{ KEY_F4, "F4" },
{ KEY_F5, "F5" },
{ KEY_F6, "F6" },
{ KEY_F7, "F7" },
{ KEY_F8, "F8" },
{ KEY_F9, "F9" },
{ KEY_F10, "F10" },
{ KEY_F11, "F11" },
{ KEY_F12, "F12" },
};
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeKeyboardInput, CDmeKeyboardInput );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeKeyboardInput::OnConstruction()
{
m_keys = new CDmaVar< bool >[ g_nKeys ];
for ( uint ki = 0; ki < g_nKeys; ++ki )
{
m_keys[ ki ].Init( this, g_keyInfo[ ki ].str );
}
}
void CDmeKeyboardInput::OnDestruction()
{
delete[] m_keys;
}
bool CDmeKeyboardInput::IsDirty()
{
for ( uint ki = 0; ki < g_nKeys; ++ki )
{
if ( m_keys[ ki ].Get() != GetKeyStatus( ki ) )
return true;
}
return false;
}
void CDmeKeyboardInput::Operate()
{
for ( uint ki = 0; ki < g_nKeys; ++ki )
{
m_keys[ ki ].Set( GetKeyStatus( ki ) );
}
}
void CDmeKeyboardInput::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
}
void CDmeKeyboardInput::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
for ( uint ki = 0; ki < g_nKeys; ++ki )
{
attrs.AddToTail( m_keys[ ki ].GetAttribute() );
}
}
bool CDmeKeyboardInput::GetKeyStatus( uint ki )
{
return g_pVGuiInput->IsKeyDown( g_keyInfo[ ki ].code );
}

331
movieobjects/dmelight.cpp Normal file
View File

@ -0,0 +1,331 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmelight.h"
#include "tier0/dbg.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "mathlib/vector.h"
#include "movieobjects/dmetransform.h"
#include "materialsystem/imaterialsystem.h"
#include "movieobjects_interfaces.h"
#include "tier2/tier2.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( DmeLight, CDmeLight );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeLight::OnConstruction()
{
m_Color.InitAndSet( this, "color", Color( 255, 255, 255, 255 ), FATTRIB_HAS_CALLBACK );
m_flIntensity.InitAndSet( this, "intensity", 1.0f, FATTRIB_HAS_CALLBACK );
}
void CDmeLight::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Sets the color and intensity
// NOTE: Color is specified 0-255 floating point.
//-----------------------------------------------------------------------------
void CDmeLight::SetColor( const Color &color )
{
m_Color.Set( color );
}
void CDmeLight::SetIntensity( float flIntensity )
{
m_flIntensity = flIntensity;
}
//-----------------------------------------------------------------------------
// Sets up render state in the material system for rendering
//-----------------------------------------------------------------------------
void CDmeLight::SetupRenderStateInternal( LightDesc_t &desc, float flAtten0, float flAtten1, float flAtten2 )
{
desc.m_Color[0] = m_Color.Get().r();
desc.m_Color[1] = m_Color.Get().g();
desc.m_Color[2] = m_Color.Get().b();
desc.m_Color *= m_flIntensity / 255.0f;
desc.m_Attenuation0 = flAtten0;
desc.m_Attenuation1 = flAtten1;
desc.m_Attenuation2 = flAtten2;
desc.m_Flags = 0;
if ( desc.m_Attenuation0 != 0.0f )
{
desc.m_Flags |= LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION0;
}
if ( desc.m_Attenuation1 != 0.0f )
{
desc.m_Flags |= LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION1;
}
if ( desc.m_Attenuation2 != 0.0f )
{
desc.m_Flags |= LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION2;
}
}
//-----------------------------------------------------------------------------
// Sets lighting state
//-----------------------------------------------------------------------------
void CDmeLight::SetupRenderState( int nLightIndex )
{
LightDesc_t desc;
if ( GetLightDesc( &desc ) )
{
// FIXME: Should we pass the light color in?
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
pRenderContext->SetLight( nLightIndex, desc );
}
}
//-----------------------------------------------------------------------------
//
// A directional light
//
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeDirectionalLight, CDmeDirectionalLight );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeDirectionalLight::OnConstruction()
{
m_Direction.InitAndSet( this, "direction", Vector( 0.0f, 0.0f, -1.0f ), FATTRIB_HAS_CALLBACK );
}
void CDmeDirectionalLight::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Sets the light direction
//-----------------------------------------------------------------------------
void CDmeDirectionalLight::SetDirection( const Vector &direction )
{
m_Direction.Set( direction );
}
//-----------------------------------------------------------------------------
// Gets a light desc for the light
//-----------------------------------------------------------------------------
bool CDmeDirectionalLight::GetLightDesc( LightDesc_t *pDesc )
{
memset( pDesc, 0, sizeof(LightDesc_t) );
pDesc->m_Type = MATERIAL_LIGHT_DIRECTIONAL;
SetupRenderStateInternal( *pDesc, 1.0f, 0.0f, 0.0f );
matrix3x4_t m;
GetTransform()->GetTransform( m );
VectorRotate( m_Direction.Get(), m, pDesc->m_Direction );
VectorNormalize( pDesc->m_Direction );
pDesc->m_Theta = 0.0f;
pDesc->m_Phi = 0.0f;
pDesc->m_Falloff = 1.0f;
return true;
}
//-----------------------------------------------------------------------------
//
// A point light
//
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmePointLight, CDmePointLight );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmePointLight::OnConstruction()
{
m_Position.InitAndSet( this, "position", Vector( 0, 0, 0 ), FATTRIB_HAS_CALLBACK );
m_flAttenuation0.InitAndSet( this, "constantAttenuation", 1.0f, FATTRIB_HAS_CALLBACK );
m_flAttenuation1.InitAndSet( this, "linearAttenuation", 0.0f, FATTRIB_HAS_CALLBACK );
m_flAttenuation2.InitAndSet( this, "quadraticAttenuation", 0.0f, FATTRIB_HAS_CALLBACK );
m_flMaxDistance.InitAndSet( this, "maxDistance", 0.0f, FATTRIB_HAS_CALLBACK );
}
void CDmePointLight::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Sets the attenuation factors
//-----------------------------------------------------------------------------
void CDmePointLight::SetAttenuation( float flConstant, float flLinear, float flQuadratic )
{
m_flAttenuation0 = flConstant;
m_flAttenuation1 = flLinear;
m_flAttenuation2 = flQuadratic;
}
//-----------------------------------------------------------------------------
// Sets the maximum range
//-----------------------------------------------------------------------------
void CDmePointLight::SetMaxDistance( float flMaxDistance )
{
m_flMaxDistance = flMaxDistance;
}
//-----------------------------------------------------------------------------
// Sets up render state in the material system for rendering
//-----------------------------------------------------------------------------
bool CDmePointLight::GetLightDesc( LightDesc_t *pDesc )
{
memset( pDesc, 0, sizeof(LightDesc_t) );
pDesc->m_Type = MATERIAL_LIGHT_POINT;
SetupRenderStateInternal( *pDesc, m_flAttenuation0, m_flAttenuation1, m_flAttenuation2 );
matrix3x4_t m;
GetTransform()->GetTransform( m );
VectorTransform( m_Position, m, pDesc->m_Position );
pDesc->m_Direction.Init( 0, 0, 1 );
pDesc->m_Range = m_flMaxDistance;
pDesc->m_Theta = 0.0f;
pDesc->m_Phi = 0.0f;
pDesc->m_Falloff = 1.0f;
return true;
}
//-----------------------------------------------------------------------------
//
// A spot light
//
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeSpotLight, CDmeSpotLight );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeSpotLight::OnConstruction()
{
m_Direction.InitAndSet( this, "direction", Vector( 0.0f, 0.0f, -1.0f ) );
m_flSpotInnerAngle.InitAndSet( this, "spotInnerAngle", 60.0f );
m_flSpotOuterAngle.InitAndSet( this, "spotOuterAngle", 90.0f );
m_flSpotAngularFalloff.InitAndSet( this, "spotAngularFalloff", 1.0f );
}
void CDmeSpotLight::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Sets the light direction
//-----------------------------------------------------------------------------
void CDmeSpotLight::SetDirection( const Vector &direction )
{
m_Direction = direction;
}
//-----------------------------------------------------------------------------
// Sets the spotlight angle factors
// Angles are specified in degrees, as full angles (as opposed to half-angles)
//-----------------------------------------------------------------------------
void CDmeSpotLight::SetAngles( float flInnerAngle, float flOuterAngle, float flAngularFalloff )
{
m_flSpotInnerAngle = flInnerAngle;
m_flSpotOuterAngle = flOuterAngle;
m_flSpotAngularFalloff = flAngularFalloff;
}
//-----------------------------------------------------------------------------
// Sets up render state in the material system for rendering
//-----------------------------------------------------------------------------
bool CDmeSpotLight::GetLightDesc( LightDesc_t *pDesc )
{
memset( pDesc, 0, sizeof(LightDesc_t) );
pDesc->m_Type = MATERIAL_LIGHT_SPOT;
SetupRenderStateInternal( *pDesc, m_flAttenuation0, m_flAttenuation1, m_flAttenuation2 );
matrix3x4_t m;
GetTransform()->GetTransform( m );
VectorTransform( m_Position, m, pDesc->m_Position );
VectorRotate( m_Direction.Get(), m, pDesc->m_Direction );
VectorNormalize( pDesc->m_Direction );
pDesc->m_Range = m_flMaxDistance;
// Convert to radians
pDesc->m_Theta = m_flSpotInnerAngle * M_PI / 180.0f;
pDesc->m_Phi = m_flSpotOuterAngle * M_PI / 180.0f;
pDesc->m_Falloff = m_flSpotAngularFalloff;
return true;
}
//-----------------------------------------------------------------------------
//
// An ambient light
//
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeAmbientLight, CDmeAmbientLight );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeAmbientLight::OnConstruction()
{
}
void CDmeAmbientLight::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Sets up render state in the material system for rendering
//-----------------------------------------------------------------------------
void CDmeAmbientLight::SetupRenderState( int nLightIndex )
{
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
Vector4D cube[6];
Vector4D vec4color( m_Color.Get().r(), m_Color.Get().g(), m_Color.Get().b(), m_Color.Get().a() );
Vector4DMultiply( vec4color, m_flIntensity / 255.0f, cube[0] );
cube[1] = cube[0];
cube[2] = cube[0];
cube[3] = cube[0];
cube[4] = cube[0];
cube[5] = cube[0];
pRenderContext->SetAmbientLightCube( cube );
}

6209
movieobjects/dmelog.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,628 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Describes an asset: something that is compiled from sources,
// in potentially multiple steps, to a compiled resource
//
//=============================================================================
#include "movieobjects/dmemdlmakefile.h"
#include "movieobjects/idmemakefileutils.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "tier2/fileutils.h"
#include "tier3/tier3.h"
#include "filesystem.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Hook into element factories
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeSource, CDmeSource );
//-----------------------------------------------------------------------------
// Construction/destruction
//-----------------------------------------------------------------------------
void CDmeSource::OnConstruction()
{
m_DependentMakefile = NULL;
}
void CDmeSource::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Sets/gets the makefile that was used to build this source
//-----------------------------------------------------------------------------
void CDmeSource::SetDependentMakefile( CDmeMakefile *pMakeFile )
{
m_DependentMakefile = pMakeFile;
}
CDmeMakefile *CDmeSource::GetDependentMakefile()
{
return m_DependentMakefile.Get();
}
//-----------------------------------------------------------------------------
// Call this to open the source file in an editor
//-----------------------------------------------------------------------------
void CDmeSource::OpenEditor()
{
if ( g_pDmeMakefileUtils )
{
g_pDmeMakefileUtils->PerformOpenEditor( this );
}
}
//-----------------------------------------------------------------------------
// Hook into element factories
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeMakefile, CDmeMakefile );
//-----------------------------------------------------------------------------
// Construction/destruction
//-----------------------------------------------------------------------------
void CDmeMakefile::OnConstruction()
{
m_Sources.Init( this, "sources" );
m_hOutput = NULL;
m_hCompileProcess = PROCESS_HANDLE_INVALID;
m_bIsDirty = false;
}
void CDmeMakefile::OnDestruction()
{
DestroyOutputElement( m_hOutput.Get() );
m_hOutput = NULL;
}
//-----------------------------------------------------------------------------
// Performs pre-compilation step
//-----------------------------------------------------------------------------
void CDmeMakefile::PreCompile( )
{
// Make all outputs writeable
MakeOutputsWriteable();
// Destroy the current output object; we'll need to reload it
// NOTE: Don't check for m_hOutput == 0; we always need to call DestroyOutputElement
// Sometimes makefiles have to do stuff even if m_hOutput == NULL
DestroyOutputElement( m_hOutput );
m_hOutput = NULL;
}
void CDmeMakefile::PostCompile( )
{
}
//-----------------------------------------------------------------------------
// Gets the output element created by compilation of this makefile
//-----------------------------------------------------------------------------
CDmElement *CDmeMakefile::GetOutputElement( bool bCreateIfNecessary )
{
if ( m_hOutput.Get() )
return m_hOutput.Get();
if ( !bCreateIfNecessary )
return NULL;
if ( !g_pDmeMakefileUtils || !g_pDmeMakefileUtils->IsCurrentlyCompiling() )
{
m_hOutput = CreateOutputElement();
}
return m_hOutput.Get();
}
//-----------------------------------------------------------------------------
// Gets the path of the makefile
//-----------------------------------------------------------------------------
void CDmeMakefile::GetMakefilePath( char *pFullPath, int nBufLen )
{
DmFileId_t fileId = GetFileId();
const char *pFileName = ( fileId != DMFILEID_INVALID ) ? g_pDataModel->GetFileName( fileId ) : "";
Assert( !pFileName[0] || Q_IsAbsolutePath( pFileName ) );
Q_ExtractFilePath( pFileName, pFullPath, nBufLen );
}
//-----------------------------------------------------------------------------
// Returns the output directory we expect to compile files into
//-----------------------------------------------------------------------------
bool CDmeMakefile::GetOutputDirectory( char *pFullPath, int nBufLen )
{
return GetDefaultDirectory( GetOutputDirectoryID(), pFullPath, nBufLen );
}
//-----------------------------------------------------------------------------
// Returns the output name (output directory + filename, no extension)
//-----------------------------------------------------------------------------
bool CDmeMakefile::GetOutputName( char *pFullPath, int nBufLen )
{
pFullPath[0] = 0;
char pOutputPath[MAX_PATH];
if ( !GetDefaultDirectory( GetOutputDirectoryID(), pOutputPath, sizeof(pOutputPath) ) )
return false;
DmFileId_t fileId = GetFileId();
const char *pFileName = ( fileId != DMFILEID_INVALID ) ? g_pDataModel->GetFileName( fileId ) : "";
if ( !pFileName || !pFileName[0] )
return false;
Q_ComposeFileName( pOutputPath, Q_UnqualifiedFileName(pFileName), pFullPath, nBufLen );
Q_RemoveDotSlashes( pFullPath );
return true;
}
//-----------------------------------------------------------------------------
// Converts the m_pDefaultDirectoryID field of the DmeMakefileType_t to a full path
//-----------------------------------------------------------------------------
bool CDmeMakefile::GetDefaultDirectory( const char *pDefaultDirectoryID, char *pFullPath, int nBufLen )
{
if ( StringHasPrefix( pDefaultDirectoryID, "contentdir:" ) )
{
pDefaultDirectoryID += 11;
GetModContentSubdirectory( pDefaultDirectoryID, pFullPath, nBufLen );
Q_RemoveDotSlashes( pFullPath );
return true;
}
if ( StringHasPrefix( pDefaultDirectoryID, "gamedir:" ) )
{
pDefaultDirectoryID += 8;
GetModSubdirectory( pDefaultDirectoryID, pFullPath, nBufLen );
Q_RemoveDotSlashes( pFullPath );
return true;
}
if ( StringHasPrefix( pDefaultDirectoryID, "makefiledir:" ) )
{
char pMakefilePath[MAX_PATH];
GetMakefilePath( pMakefilePath, sizeof(pMakefilePath) );
pDefaultDirectoryID += 12;
Q_ComposeFileName( pMakefilePath, pDefaultDirectoryID, pFullPath, nBufLen );
Q_RemoveDotSlashes( pFullPath );
return true;
}
if ( StringHasPrefix( pDefaultDirectoryID, "makefilegamedir:" ) )
{
char pMakefilePath[MAX_PATH];
GetMakefilePath( pMakefilePath, sizeof(pMakefilePath) );
char pModContentDirectory[MAX_PATH];
GetModContentSubdirectory( NULL, pModContentDirectory, sizeof(pModContentDirectory) );
char pRelativePath[MAX_PATH];
if ( !Q_MakeRelativePath( pMakefilePath, pModContentDirectory, pRelativePath, sizeof(pRelativePath) ) )
{
pFullPath[0] = 0;
return false;
}
char pModDirectory[MAX_PATH];
GetModSubdirectory( NULL, pModDirectory, sizeof(pModDirectory) );
char pMakefileGamePath[MAX_PATH];
Q_ComposeFileName( pModDirectory, pRelativePath, pMakefileGamePath, sizeof(pMakefileGamePath) );
pDefaultDirectoryID += 16;
Q_ComposeFileName( pMakefileGamePath, pDefaultDirectoryID, pFullPath, nBufLen );
Q_RemoveDotSlashes( pFullPath );
return true;
}
// Assume it's a content subdir
GetModContentSubdirectory( pDefaultDirectoryID, pFullPath, nBufLen );
Q_RemoveDotSlashes( pFullPath );
return true;
}
//-----------------------------------------------------------------------------
// Relative path to full path
//-----------------------------------------------------------------------------
void CDmeMakefile::RelativePathToFullPath( const char *pRelativePath, char *pFullPath, int nBufLen )
{
if ( !pRelativePath[0] )
{
pFullPath[0] = 0;
return;
}
char pRootDir[ MAX_PATH ];
GetMakefilePath( pRootDir, sizeof(pRootDir) );
Q_ComposeFileName( pRootDir, pRelativePath, pFullPath, nBufLen );
Q_RemoveDotSlashes( pFullPath );
}
//-----------------------------------------------------------------------------
// Fullpath to relative path
//-----------------------------------------------------------------------------
void CDmeMakefile::FullPathToRelativePath( const char *pFullPath, char *pRelativePath, int nBufLen )
{
if ( !pFullPath[0] )
{
pRelativePath[0] = 0;
return;
}
char pRootDir[ MAX_PATH ];
GetMakefilePath( pRootDir, sizeof(pRootDir) );
if ( pRootDir[0] )
{
Q_MakeRelativePath( pFullPath, pRootDir, pRelativePath, nBufLen );
}
else
{
Q_strncpy( pRelativePath, pFullPath, nBufLen );
Q_FixSlashes( pRelativePath );
}
}
//-----------------------------------------------------------------------------
// Adds a single source
//-----------------------------------------------------------------------------
CDmeSource *CDmeMakefile::AddSource( const char *pSourceType, const char *pFullPath )
{
if ( pFullPath[0] && FindSource( pSourceType, pFullPath ) )
{
Warning( "Attempted to add the same source twice %s!\n", pFullPath );
return NULL;
}
CDmElement *pElement = GetElement< CDmElement >( g_pDataModel->CreateElement( pSourceType, "", GetFileId() ) );
CDmeSource *pSource = CastElement< CDmeSource >( pElement );
Assert( pSource );
if ( !pSource )
{
Warning( "Invalid source type name %s!\n", pSourceType );
if ( pElement )
{
DestroyElement( pElement );
}
return NULL;
}
char pRelativePath[MAX_PATH];
FullPathToRelativePath( pFullPath, pRelativePath, sizeof( pRelativePath ) );
pSource->SetRelativeFileName( pRelativePath );
m_Sources.AddToTail( pSource );
return pSource;
}
//-----------------------------------------------------------------------------
// Removes a single source
//-----------------------------------------------------------------------------
CDmeSource *CDmeMakefile::FindSource( const char *pSourceType, const char *pFullPath )
{
char pRelativePath[MAX_PATH];
FullPathToRelativePath( pFullPath, pRelativePath, sizeof( pRelativePath ) );
int nCount = m_Sources.Count();
for ( int i = 0; i < nCount; ++i )
{
if ( Q_stricmp( pSourceType, m_Sources[i]->GetTypeString() ) )
continue;
if ( !Q_stricmp( pRelativePath, m_Sources[i]->GetRelativeFileName() ) )
return m_Sources[i];
}
return NULL;
}
//-----------------------------------------------------------------------------
// Sets a source to be a single source
//-----------------------------------------------------------------------------
CDmeSource *CDmeMakefile::SetSingleSource( const char *pSourceType, const char *pFullPath )
{
// FIXME: we maybe shouldn't remove everything if the source can't be created for some reason?
RemoveAllSources( pSourceType );
return AddSource( pSourceType, pFullPath );
}
//-----------------------------------------------------------------------------
// Changes a source
//-----------------------------------------------------------------------------
void CDmeMakefile::SetSourceFullPath( CDmeSource *pSource, const char *pFullPath )
{
char pRelativePath[MAX_PATH];
FullPathToRelativePath( pFullPath, pRelativePath, sizeof( pRelativePath ) );
if ( Q_stricmp( pRelativePath, pSource->GetRelativeFileName() ) )
{
pSource->SetRelativeFileName( pRelativePath );
// FIXME: Should we delete the dependent makefile?
pSource->SetDependentMakefile( NULL );
}
}
//-----------------------------------------------------------------------------
// Returns the full path of a source
//-----------------------------------------------------------------------------
void CDmeMakefile::GetSourceFullPath( CDmeSource *pSource, char *pFullPath, int nBufLen )
{
const char *pRelativePath = pSource->GetRelativeFileName( );
RelativePathToFullPath( pRelativePath, pFullPath, nBufLen );
}
//-----------------------------------------------------------------------------
// Returns a list of sources
//-----------------------------------------------------------------------------
void CDmeMakefile::GetSources( const char *pSourceType, CUtlVector< CDmeHandle< CDmeSource > > &sources )
{
int nCount = m_Sources.Count();
sources.EnsureCapacity( nCount );
for ( int i = 0; i < nCount; ++i )
{
if ( m_Sources[i]->IsA( pSourceType ) )
{
int j = sources.AddToTail();
sources[j] = m_Sources[i];
}
}
}
//-----------------------------------------------------------------------------
// Gets a list of all sources, regardless of type
//-----------------------------------------------------------------------------
int CDmeMakefile::GetSourceCount()
{
return m_Sources.Count();
}
CDmeSource *CDmeMakefile::GetSource( int nIndex )
{
return m_Sources[nIndex];
}
//-----------------------------------------------------------------------------
// Removes a single source
//-----------------------------------------------------------------------------
void CDmeMakefile::RemoveSource( CDmeSource *pSource )
{
int nCount = m_Sources.Count();
for ( int i = 0; i < nCount; ++i )
{
if ( m_Sources[i] == pSource )
{
m_Sources.Remove( i );
break;
}
}
}
void CDmeMakefile::RemoveSource( const char *pSourceType, const char *pFullPath )
{
char pRelativePath[MAX_PATH];
FullPathToRelativePath( pFullPath, pRelativePath, sizeof( pRelativePath ) );
int nCount = m_Sources.Count();
for ( int i = 0; i < nCount; ++i )
{
if ( Q_stricmp( pSourceType, m_Sources[i]->GetTypeString() ) )
continue;
if ( !Q_stricmp( pRelativePath, m_Sources[i]->GetRelativeFileName() ) )
{
m_Sources.Remove( i );
break;
}
}
}
//-----------------------------------------------------------------------------
// Removes all sources of a particular type
//-----------------------------------------------------------------------------
void CDmeMakefile::RemoveAllSources( const char *pSourceType )
{
int nCount = m_Sources.Count();
for ( int i = nCount; --i >= 0; )
{
if ( !Q_stricmp( pSourceType, m_Sources[i]->GetTypeString() ) )
{
// NOTE: This works because we're iterating backward
m_Sources.Remove( i );
}
}
}
//-----------------------------------------------------------------------------
// Source iteration
//-----------------------------------------------------------------------------
bool CDmeMakefile::HasSourceOfType( const char *pSourceType )
{
int nCount = m_Sources.Count();
for ( int i = nCount; --i >= 0; )
{
if ( !Q_stricmp( pSourceType, m_Sources[i]->GetTypeString() ) )
return true;
}
return false;
}
//-----------------------------------------------------------------------------
// Updates the source names to be relative to a particular path
//-----------------------------------------------------------------------------
bool CDmeMakefile::UpdateSourceNames( const char *pOldRootDir, const char *pNewRootDir, bool bApplyChanges )
{
char pOldSourcePath[ MAX_PATH ];
char pNewSourcePath[ MAX_PATH ];
int nCount = m_Sources.Count();
for ( int i = 0; i < nCount; ++i )
{
const char *pOldRelativePath = m_Sources[i]->GetRelativeFileName();
if ( pOldRelativePath[0] )
{
Q_ComposeFileName( pOldRootDir, pOldRelativePath, pOldSourcePath, sizeof(pOldSourcePath) );
Q_RemoveDotSlashes( pOldSourcePath );
if ( !Q_MakeRelativePath( pOldSourcePath, pNewRootDir, pNewSourcePath, sizeof(pNewSourcePath) ) )
{
Assert( !bApplyChanges );
return false;
}
}
else
{
pNewSourcePath[0] = 0;
}
if ( !bApplyChanges )
continue;
m_Sources[i]->SetRelativeFileName( pNewSourcePath );
}
return true;
}
//-----------------------------------------------------------------------------
// Returns the filename
//-----------------------------------------------------------------------------
const char *CDmeMakefile::GetFileName() const
{
DmFileId_t fileId = GetFileId();
return g_pDataModel->GetFileName( fileId );
}
//-----------------------------------------------------------------------------
// Call this to change the file the makefile is stored in
// Will make all sources be relative to this path
//-----------------------------------------------------------------------------
bool CDmeMakefile::SetFileName( const char *pFileName )
{
if ( !Q_IsAbsolutePath( pFileName ) )
return false;
char pOldRootDir[ MAX_PATH ];
char pNewRootDir[ MAX_PATH ];
GetMakefilePath( pOldRootDir, sizeof(pOldRootDir) );
Q_ExtractFilePath( pFileName, pNewRootDir, sizeof(pNewRootDir) );
// Gotta do this twice; once to check for validity, once to actually do it
if ( !UpdateSourceNames( pOldRootDir, pNewRootDir, false ) )
return false;
UpdateSourceNames( pOldRootDir, pNewRootDir, true );
DmFileId_t fileId = GetFileId();
if ( fileId == DMFILEID_INVALID )
{
fileId = g_pDataModel->FindOrCreateFileId( pFileName );
SetFileId( fileId, TD_DEEP );
}
else
{
g_pDataModel->SetFileName( fileId, pFileName );
}
return true;
}
//-----------------------------------------------------------------------------
// Make all outputs writeable
//-----------------------------------------------------------------------------
void CDmeMakefile::MakeOutputsWriteable( )
{
// When we publish, we'll check them out.
CUtlVector<CUtlString> outputs;
GetOutputs( outputs );
int nCount = outputs.Count();
for ( int i = 0; i < nCount; ++i )
{
g_pFullFileSystem->SetFileWritable( outputs[i], true );
}
}
//-----------------------------------------------------------------------------
// Sets a makefile/source association
//-----------------------------------------------------------------------------
void CDmeMakefile::SetAssociation( CDmeSource *pSource, CDmeMakefile *pSourceMakefile )
{
if ( !pSource )
return;
int nCount = m_Sources.Count();
for ( int i = 0; i < nCount; ++i )
{
if ( m_Sources[i] != pSource )
continue;
CDmeMakefile *pDependentMakeFile = m_Sources[i]->GetDependentMakefile();
if ( pSourceMakefile != pDependentMakeFile )
{
// FIXME: Should I recursively delete pDependentMakeFile ?
m_Sources[i]->SetDependentMakefile( pSourceMakefile );
}
return;
}
}
//-----------------------------------------------------------------------------
// Finds a dependent makefile
//-----------------------------------------------------------------------------
CDmeMakefile *CDmeMakefile::FindDependentMakefile( CDmeSource *pSource )
{
if ( !pSource )
return NULL;
int nCount = m_Sources.Count();
for ( int i = 0; i < nCount; ++i )
{
if ( m_Sources[i] == pSource )
return m_Sources[i]->GetDependentMakefile();
}
return NULL;
}
//-----------------------------------------------------------------------------
// Finds the associated source
//-----------------------------------------------------------------------------
CDmeSource *CDmeMakefile::FindAssociatedSource( CDmeMakefile *pChildMakefile )
{
if ( !pChildMakefile )
return NULL;
int nCount = m_Sources.Count();
for ( int i = 0; i < nCount; ++i )
{
if ( m_Sources[i]->GetDependentMakefile() == pChildMakefile )
return m_Sources[i];
}
return NULL;
}

View File

@ -0,0 +1,613 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Interface for makefiles to build differently depending on where they are run from
//
//===========================================================================//
#include "movieobjects/dmemakefileutils.h"
#include "movieobjects/dmemdlmakefile.h"
#include "movieobjects/dmedccmakefile.h"
#include "tier2/fileutils.h"
#include "filesystem.h"
//-----------------------------------------------------------------------------
// Statics
//-----------------------------------------------------------------------------
IMPLEMENT_DMEMAKEFILE_UTIL_CLASS( CDmeMakefileUtils );
//-----------------------------------------------------------------------------
// Default implementation
//-----------------------------------------------------------------------------
static CDmeMakefileUtils s_MakefileUtils;
IDmeMakefileUtils *GetDefaultDmeMakefileUtils()
{
return &s_MakefileUtils;
}
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
CDmeMakefileUtils::CDmeMakefileUtils() : BaseClass( false )
{
m_CompilationStep = NOT_COMPILING;
m_hCompileProcess = PROCESS_HANDLE_INVALID;
m_nCurrentCompileTask = -1;
m_nExitCode = 0;
}
CDmeMakefileUtils::~CDmeMakefileUtils()
{
}
//-----------------------------------------------------------------------------
// Here's where systems can access other interfaces implemented by this object
//-----------------------------------------------------------------------------
void *CDmeMakefileUtils::QueryInterface( const char *pInterfaceName )
{
if ( !V_strcmp( pInterfaceName, DMEMAKEFILE_UTILS_INTERFACE_VERSION ) )
return (IDmeMakefileUtils*)this;
return NULL;
}
//-----------------------------------------------------------------------------
// Initialization.. set up messagemaps
//-----------------------------------------------------------------------------
InitReturnVal_t CDmeMakefileUtils::Init()
{
InitializeFuncMaps();
return INIT_OK;
}
//-----------------------------------------------------------------------------
// Looks for an appropriate method to compile this element with
//-----------------------------------------------------------------------------
CCompileFuncAdapterBase *CDmeMakefileUtils::DetermineCompileAdapter( CDmElement *pElement )
{
int nBestInheritanceDepth = -1;
CCompileFuncAdapterBase *pBestAdapter = NULL;
CompileFuncTree_t *pTree = GetCompileTree();
while ( pTree )
{
CCompileFuncAdapterBase *pCurr = pTree->m_pFirstAdapter;
for ( ; pCurr; pCurr = pCurr->m_pNext )
{
// Choose this factory if it's more derived than the previous best
int nInheritanceDepth = pElement->GetInheritanceDepth( pCurr->m_ElementType );
if ( nInheritanceDepth < 0 )
continue;
if ( nInheritanceDepth == 0 )
{
// Found exact match.. do it!
return pCurr;
}
// Don't look for the best thingy if we're not the root
if ( nBestInheritanceDepth >= 0 && ( nInheritanceDepth >= nBestInheritanceDepth ) )
continue;
nBestInheritanceDepth = nInheritanceDepth;
pBestAdapter = pCurr;
}
pTree = pTree->m_pBaseAdapterTree;
}
// Return the closest match we could find
return pBestAdapter;
}
//-----------------------------------------------------------------------------
// Looks for an appropriate method to open this element with
//-----------------------------------------------------------------------------
COpenEditorFuncAdapterBase *CDmeMakefileUtils::DetermineOpenEditorAdapter( CDmElement *pElement )
{
int nBestInheritanceDepth = -1;
COpenEditorFuncAdapterBase *pBestAdapter = NULL;
OpenEditorFuncTree_t *pTree = GetOpenEditorTree();
while ( pTree )
{
COpenEditorFuncAdapterBase *pCurr = pTree->m_pFirstAdapter;
for ( ; pCurr; pCurr = pCurr->m_pNext )
{
// Choose this factory if it's more derived than the previous best
int nInheritanceDepth = pElement->GetInheritanceDepth( pCurr->m_ElementType );
if ( nInheritanceDepth < 0 )
continue;
// Found exact match.. do it!
if ( nInheritanceDepth == 0 )
return pCurr;
if ( nBestInheritanceDepth >= 0 && ( nInheritanceDepth >= nBestInheritanceDepth ) )
continue;
nBestInheritanceDepth = nInheritanceDepth;
pBestAdapter = pCurr;
}
pTree = pTree->m_pBaseAdapterTree;
}
return pBestAdapter;
}
//-----------------------------------------------------------------------------
// Opens a element in an external editor
//-----------------------------------------------------------------------------
void CDmeMakefileUtils::PerformOpenEditor( CDmElement *pElement )
{
COpenEditorFuncAdapterBase *pAdapter = DetermineOpenEditorAdapter( pElement );
if ( pAdapter )
{
pAdapter->OpenEditor( pElement );
}
}
//-----------------------------------------------------------------------------
// Queues up a compilation task
//-----------------------------------------------------------------------------
void CDmeMakefileUtils::AddCompilationTask( CDmElement* pElement, CCompileFuncAdapterBase *pAdapter )
{
Assert( m_CompilationStep == BUILDING_STANDARD_DEPENDENCIES || m_CompilationStep == BUILDING_ALL_DEPENDENCIES );
// Queue up the compilation task
int j = m_CompileTasks.AddToTail();
m_CompileTasks[j].m_hElement = pElement;
m_CompileTasks[j].m_pAdapter = pAdapter;
}
void CDmeMakefileUtils::AddCompilationTask( CDmElement* pElement )
{
CCompileFuncAdapterBase *pAdapter = DetermineCompileAdapter( pElement );
if ( pAdapter )
{
// Queue up the compilation task
AddCompilationTask( pElement, pAdapter );
}
}
//-----------------------------------------------------------------------------
// Sets the compile process
//-----------------------------------------------------------------------------
void CDmeMakefileUtils::SetCompileProcess( ProcessHandle_t hProcess )
{
Assert( m_CompilationStep == PERFORMING_COMPILATION );
m_hCompileProcess = hProcess;
if ( m_hCompileProcess == PROCESS_HANDLE_INVALID )
{
m_CompilationStep = AFTER_COMPILATION_FAILED;
}
}
//-----------------------------------------------------------------------------
// Default implementatations for compile dependencies
//-----------------------------------------------------------------------------
bool CDmeMakefileUtils::AddCompileDependencies( CDmeMakefile *pMakefile, bool bBuildAllDependencies )
{
if ( !pMakefile )
return true;
CUtlVector< CUtlString > outputs;
int nCount = pMakefile->GetSourceCount();
for ( int i = 0; i < nCount; ++i )
{
CDmeSource *pSource = pMakefile->GetSource( i );
if ( !pSource )
continue;
CDmeMakefile *pDependentMakefile = pSource->GetDependentMakefile();
if ( !pDependentMakefile )
continue;
bool bShouldBuildFile = bBuildAllDependencies;
// Does the output files exist?
int j = 0;
if ( !bBuildAllDependencies )
{
pDependentMakefile->GetOutputs( outputs );
int nOutputCount = outputs.Count();
for ( j = 0; j < nOutputCount; ++j )
{
// If the file doesn't exist, we have to build it
if ( !g_pFullFileSystem->FileExists( outputs[j] ) )
break;
bShouldBuildFile = true;
break;
}
}
if ( !bShouldBuildFile )
continue;
CCompileFuncAdapterBase *pAdapter = DetermineCompileAdapter( pDependentMakefile );
if ( pAdapter )
{
// Add dependent makefiles first
if ( !pAdapter->PerformCompilationStep( pDependentMakefile, bBuildAllDependencies ? BUILDING_ALL_DEPENDENCIES : BUILDING_STANDARD_DEPENDENCIES ) )
return false;
}
// Queue up the compilation task
AddCompilationTask( pDependentMakefile, pAdapter );
}
return true;
}
//-----------------------------------------------------------------------------
// Default implementatations for precompilation step
//-----------------------------------------------------------------------------
bool CDmeMakefileUtils::PerformCompilationStep( CDmElement *pElement, CompilationStep_t step )
{
// Do nothing
return true;
}
bool CDmeMakefileUtils::PerformCompilationStep( CDmeMakefile *pMakefile, CompilationStep_t step )
{
switch( step )
{
case BUILDING_ALL_DEPENDENCIES:
return AddCompileDependencies( pMakefile, true );
case BUILDING_STANDARD_DEPENDENCIES:
return AddCompileDependencies( pMakefile, false );
case BEFORE_COMPILATION:
pMakefile->PreCompile();
break;
case AFTER_COMPILATION_SUCCEEDED:
pMakefile->PostCompile();
break;
}
return true;
}
//-----------------------------------------------------------------------------
// Starts the next compile task
//-----------------------------------------------------------------------------
void CDmeMakefileUtils::StartNextCompileTask( )
{
Assert( m_hCompileProcess == PROCESS_HANDLE_INVALID );
++m_nCurrentCompileTask;
if ( m_nCurrentCompileTask == m_CompileTasks.Count() )
{
PerformCompilationStep( AFTER_COMPILATION_SUCCEEDED );
m_nCurrentCompileTask = -1;
m_CompileTasks.RemoveAll();
return;
}
m_hCompileProcess = PROCESS_HANDLE_INVALID;
// NOTE: PerformCompilationStep is expected to call SetCompileProcess to set m_hCompileProcess
CompileInfo_t &info = m_CompileTasks[m_nCurrentCompileTask];
bool bOk = info.m_pAdapter->PerformCompilationStep( info.m_hElement, PERFORMING_COMPILATION );
if ( !bOk || ( m_hCompileProcess == PROCESS_HANDLE_INVALID ) )
{
AbortCurrentCompilation();
return;
}
}
//-----------------------------------------------------------------------------
// Performs the compilation step on all elements
//-----------------------------------------------------------------------------
bool CDmeMakefileUtils::PerformCompilationStep( CompilationStep_t step )
{
// Iterate through all elements and run a compilation step
m_CompilationStep = step;
int nCount = m_CompileTasks.Count();
for ( int i = 0; i < nCount; ++i )
{
CompileInfo_t &info = m_CompileTasks[i];
if ( info.m_hElement.Get() )
{
if ( !info.m_pAdapter->PerformCompilationStep( info.m_hElement, step ) )
return false;
}
}
return true;
}
//-----------------------------------------------------------------------------
// Main entry point for compilation
//-----------------------------------------------------------------------------
void CDmeMakefileUtils::PerformCompile( CDmElement *pElement, bool bBuildAllDependencies )
{
if ( IsCurrentlyCompiling() )
{
AbortCurrentCompilation();
}
CCompileFuncAdapterBase *pAdapter = DetermineCompileAdapter( pElement );
if ( !pAdapter )
{
m_CompilationStep = AFTER_COMPILATION_FAILED;
return;
}
// Add dependent makefiles first
m_CompilationStep = bBuildAllDependencies ? BUILDING_ALL_DEPENDENCIES : BUILDING_STANDARD_DEPENDENCIES;
if ( !pAdapter->PerformCompilationStep( pElement, m_CompilationStep ) )
{
AbortCurrentCompilation();
return;
}
// Queue up the compilation task
AddCompilationTask( pElement, pAdapter );
// Iterate through all elements and run a precompilation step
// NOTE: This is where perforce integration should go
if ( !PerformCompilationStep( BEFORE_COMPILATION ) )
{
AbortCurrentCompilation();
return;
}
// Dequeue the first compile task and start it up
m_CompilationStep = PERFORMING_COMPILATION;
StartNextCompileTask();
}
//-----------------------------------------------------------------------------
// Are we in the middle of compiling this makefile?
//-----------------------------------------------------------------------------
bool CDmeMakefileUtils::IsCurrentlyCompiling()
{
return ( m_CompilationStep != NOT_COMPILING );
}
//-----------------------------------------------------------------------------
// Aborts any current compilation
//-----------------------------------------------------------------------------
void CDmeMakefileUtils::AbortCurrentCompilation()
{
if ( m_hCompileProcess != PROCESS_HANDLE_INVALID )
{
g_pProcessUtils->AbortProcess( m_hCompileProcess );
m_hCompileProcess = PROCESS_HANDLE_INVALID;
}
if ( IsCurrentlyCompiling() )
{
PerformCompilationStep( AFTER_COMPILATION_FAILED );
m_nCurrentCompileTask = -1;
m_CompileTasks.RemoveAll();
}
}
//-----------------------------------------------------------------------------
// Returns the exit code of the failed compilation (if COMPILATION_FAILED occurred)
//-----------------------------------------------------------------------------
int CDmeMakefileUtils::GetExitCode()
{
return m_nExitCode;
}
//-----------------------------------------------------------------------------
// Returns output from the compilation
//-----------------------------------------------------------------------------
int CDmeMakefileUtils::GetCompileOutputSize()
{
if ( m_hCompileProcess == PROCESS_HANDLE_INVALID )
return 0;
return g_pProcessUtils->GetProcessOutputSize( m_hCompileProcess );
}
CompilationState_t CDmeMakefileUtils::UpdateCompilation( char *pOutputBuf, int nBufLen )
{
switch( m_CompilationStep )
{
case BUILDING_STANDARD_DEPENDENCIES:
case BUILDING_ALL_DEPENDENCIES:
case BEFORE_COMPILATION:
return COMPILATION_NOT_COMPLETE;
case AFTER_COMPILATION_FAILED:
m_CompilationStep = NOT_COMPILING;
return COMPILATION_FAILED;
case AFTER_COMPILATION_SUCCEEDED:
m_CompilationStep = NOT_COMPILING;
return COMPILATION_SUCCESSFUL;
}
// This is the PERFORMING_COMPILATION case:
// FIXME: Check return codes from compile process..
// fail if compilation process had a problem
if ( m_hCompileProcess == PROCESS_HANDLE_INVALID )
{
if ( nBufLen > 0 )
{
pOutputBuf[0] = 0;
}
return COMPILATION_SUCCESSFUL;
}
if ( nBufLen > 0 )
{
g_pProcessUtils->GetProcessOutput( m_hCompileProcess, pOutputBuf, nBufLen );
}
if ( !g_pProcessUtils->IsProcessComplete( m_hCompileProcess ) )
return COMPILATION_NOT_COMPLETE;
m_nExitCode = g_pProcessUtils->GetProcessExitCode( m_hCompileProcess );
bool bCompileSucceeded = ( m_nExitCode == 0 );
g_pProcessUtils->CloseProcess( m_hCompileProcess );
m_hCompileProcess = PROCESS_HANDLE_INVALID;
if ( !bCompileSucceeded )
{
AbortCurrentCompilation();
return COMPILATION_NOT_COMPLETE;
}
StartNextCompileTask();
if ( m_CompilationStep == PERFORMING_COMPILATION )
return COMPILATION_NOT_COMPLETE;
CompilationState_t retVal = ( m_CompilationStep == AFTER_COMPILATION_SUCCEEDED ) ? COMPILATION_SUCCESSFUL : COMPILATION_FAILED;
m_CompilationStep = NOT_COMPILING;
return retVal;
}
//-----------------------------------------------------------------------------
// Type-specific compilation functions
//-----------------------------------------------------------------------------
bool CDmeMakefileUtils::PerformCompilationStep( CDmeMDLMakefile *pMakeFile, CompilationStep_t step )
{
if ( step != PERFORMING_COMPILATION )
return PerformCompilationStep( static_cast<CDmeMakefile*>( pMakeFile ), step );
char pBinDirectory[MAX_PATH];
GetModSubdirectory( "..\\bin", pBinDirectory, sizeof(pBinDirectory) );
Q_RemoveDotSlashes( pBinDirectory );
char pStudioMDLCmd[MAX_PATH];
#ifdef _DEBUG
Q_snprintf( pStudioMDLCmd, sizeof(pStudioMDLCmd), "%s\\studiomdl.exe -allowdebug %s", pBinDirectory, pMakeFile->GetFileName() );
#else
Q_snprintf( pStudioMDLCmd, sizeof(pStudioMDLCmd), "%s\\studiomdl.exe %s", pBinDirectory, pMakeFile->GetFileName() );
#endif
ProcessHandle_t hProcess = g_pProcessUtils->StartProcess( pStudioMDLCmd, true );
SetCompileProcess( hProcess );
return true;
}
//-----------------------------------------------------------------------------
// Exports a Maya file to a DMX file
//-----------------------------------------------------------------------------
bool CDmeMakefileUtils::PerformCompilationStep( CDmeMayaMakefile *pMakeFile, CompilationStep_t step )
{
if ( step != PERFORMING_COMPILATION )
return PerformCompilationStep( static_cast<CDmeMakefile*>( pMakeFile ), step );
// FIXME: Create batch export command here
CUtlString mayaCommand;
mayaCommand = "vsDmxIO -export";
CUtlVector< CDmeHandle< CDmeSourceMayaFile > > sources;
pMakeFile->GetSources( sources );
if ( !sources.Count() )
return false;
CDmeSourceMayaFile *pDmeSourceDCCFile( sources[ 0 ].Get() );
mayaCommand += " -selection";
char pObjectId[128];
UniqueIdToString( pMakeFile->GetId(), pObjectId, sizeof(pObjectId) );
mayaCommand += " -makefileObjectId \\\"";
mayaCommand += pObjectId;
mayaCommand += "\\\"";
mayaCommand += " -";
mayaCommand += pDmeSourceDCCFile->m_ExportType.GetAttribute()->GetName();
switch ( pDmeSourceDCCFile->m_ExportType.Get() )
{
case 1: // skeletal animation
mayaCommand += " skeletalAnimation";
mayaCommand += " -";
mayaCommand += pDmeSourceDCCFile->m_FrameStart.GetAttribute()->GetName();
mayaCommand += " ";
mayaCommand += pDmeSourceDCCFile->m_FrameStart.Get();
mayaCommand += " -";
mayaCommand += pDmeSourceDCCFile->m_FrameEnd.GetAttribute()->GetName();
mayaCommand += " ";
mayaCommand += pDmeSourceDCCFile->m_FrameEnd.Get();
mayaCommand += " -";
mayaCommand += pDmeSourceDCCFile->m_FrameIncrement.GetAttribute()->GetName();
mayaCommand += " ";
mayaCommand += pDmeSourceDCCFile->m_FrameIncrement.Get();
break;
default: // Model
mayaCommand += " model";
break;
}
char pFileName[MAX_PATH];
Q_strncpy( pFileName, pMakeFile->GetFileName(), sizeof( pFileName ) );
Q_FixSlashes( pFileName, '/' );
mayaCommand += " -filename \\\"";
mayaCommand += pFileName;
mayaCommand += "\\\"";
const int rootObjectCount( pDmeSourceDCCFile->m_RootDCCObjects.Count() );
for ( int rootObjectIndex( 0 ); rootObjectIndex < rootObjectCount; ++rootObjectIndex )
{
mayaCommand += " ";
mayaCommand += pDmeSourceDCCFile->m_RootDCCObjects[ rootObjectIndex ];
}
char pSourcePath[MAX_PATH];
pMakeFile->GetSourceFullPath( pDmeSourceDCCFile, pSourcePath, sizeof(pSourcePath) );
// Maya wants forward slashes
Q_FixSlashes( pSourcePath, '/' );
char pMayaCommand[1024];
Q_snprintf( pMayaCommand, sizeof(pMayaCommand), "mayabatch.exe -batch -file \"%s\" -command \"%s\"", pSourcePath, mayaCommand.Get() );
ProcessHandle_t hProcess = g_pProcessUtils->StartProcess( pMayaCommand, true );
SetCompileProcess( hProcess );
return true;
}
//-----------------------------------------------------------------------------
// Opens Maya with a particular file
//-----------------------------------------------------------------------------
void CDmeMakefileUtils::OpenEditor( CDmeSourceMayaFile *pDmeSourceDCCFile )
{
CDmeMayaMakefile *pMakefile = FindReferringElement< CDmeMayaMakefile >( pDmeSourceDCCFile, "sources" );
if ( !pMakefile )
return;
char pSourcePath[MAX_PATH];
pMakefile->GetSourceFullPath( pDmeSourceDCCFile, pSourcePath, sizeof(pSourcePath) );
// Maya wants forward slashes
Q_FixSlashes( pSourcePath, '/' );
char pMayaCommand[1024];
Q_snprintf( pMayaCommand, sizeof(pMayaCommand), "maya.exe -file \"%s\"", pSourcePath );
g_pProcessUtils->StartProcess( pMayaCommand, true );
}

View File

@ -0,0 +1,82 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmematerial.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "movieobjects_interfaces.h"
#include "materialsystem/imaterial.h"
#include "materialsystem/imaterialsystem.h"
#include "tier2/tier2.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( DmeMaterial, CDmeMaterial );
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
void CDmeMaterial::OnConstruction()
{
m_pMTL = NULL;
m_mtlName.Init( this, "mtlName" );
}
void CDmeMaterial::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// resolve
//-----------------------------------------------------------------------------
void CDmeMaterial::Resolve()
{
BaseClass::Resolve();
if ( m_mtlName.IsDirty() )
{
m_pMTL = NULL; // no cleanup necessary
}
}
//-----------------------------------------------------------------------------
// Sets the material
//-----------------------------------------------------------------------------
void CDmeMaterial::SetMaterial( const char *pMaterialName )
{
m_mtlName = pMaterialName;
}
//-----------------------------------------------------------------------------
// Returns the material name
//-----------------------------------------------------------------------------
const char *CDmeMaterial::GetMaterialName() const
{
return m_mtlName;
}
//-----------------------------------------------------------------------------
// accessor for cached IMaterial
//-----------------------------------------------------------------------------
IMaterial *CDmeMaterial::GetCachedMTL()
{
if ( m_pMTL == NULL )
{
const char *mtlName = m_mtlName.Get();
if ( mtlName == NULL )
return NULL;
m_pMTL = g_pMaterialSystem->FindMaterial( mtlName, NULL, false );
}
return m_pMTL;
}

View File

@ -0,0 +1,270 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmematerialoverlayfxclip.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "materialsystem/imesh.h"
#include "materialsystem/imaterial.h"
#include "tier1/KeyValues.h"
#include "tier1/convar.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// CDmeClip - common base class for filmclips, soundclips, and channelclips
//-----------------------------------------------------------------------------
IMPLEMENT_FX_CLIP_ELEMENT_FACTORY( DmeMaterialOverlayFXClip, CDmeMaterialOverlayFXClip, "Material Overlay Effect" );
void CDmeMaterialOverlayFXClip::OnConstruction()
{
m_Material.Init( this, "material" );
m_Color.Init( this, "overlaycolor" );
m_nLeft.Init( this, "left" );
m_nTop.Init( this, "top" );
m_nWidth.Init( this, "width" );
m_nHeight.Init( this, "height" );
m_bFullScreen.Init( this, "fullscreen" );
m_bUseSubRect.Init( this, "useSubRect" );
m_flMovementAngle.Init( this, "movementAngle" );
m_flMovementSpeed.Init( this, "movementSpeed" );
m_nSubRectLeft.Init( this, "subRectLeft" );
m_nSubRectTop.Init( this, "subRectTop" );
m_nSubRectWidth.Init( this, "subRectWidth" );
m_nSubRectHeight.Init( this, "subRectHeight" );
m_Color.SetColor( 255, 255, 255, 255 );
m_bFullScreen = true;
m_nLeft = m_nTop = 0;
m_nWidth = m_nHeight = 1;
}
void CDmeMaterialOverlayFXClip::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Resolve
//-----------------------------------------------------------------------------
void CDmeMaterialOverlayFXClip::Resolve()
{
if ( m_Material.IsDirty() )
{
m_OverlayMaterial.Shutdown();
const char *pName = m_Material.Get();
if ( pName && pName[0] )
{
m_OverlayMaterial.Init( pName, NULL, false );
}
m_Material.GetAttribute()->RemoveFlag( FATTRIB_DIRTY );
}
}
//-----------------------------------------------------------------------------
// Helper for overlays
//-----------------------------------------------------------------------------
void CDmeMaterialOverlayFXClip::SetOverlayEffect( const char *pMaterialName )
{
m_Material = pMaterialName;
}
void CDmeMaterialOverlayFXClip::SetAlpha( float flAlpha )
{
m_Color.SetAlpha( flAlpha * 255 );
}
float CDmeMaterialOverlayFXClip::GetAlpha( void )
{
return ( (float)m_Color.a() ) / 255.0f;
}
bool CDmeMaterialOverlayFXClip::HasOpaqueOverlay( void )
{
if ( m_OverlayMaterial )
return ( !m_OverlayMaterial->IsTranslucent() && ( m_Color.a() == 255 ) && m_bFullScreen );
// no material overlay set
return false;
}
IMaterial *CDmeMaterialOverlayFXClip::GetMaterial()
{
return m_OverlayMaterial;
}
//-----------------------------------------------------------------------------
// All effects must be able to apply their effect
//-----------------------------------------------------------------------------
void CDmeMaterialOverlayFXClip::ApplyEffect( DmeTime_t time, Rect_t &currentRect, Rect_t &totalRect, ITexture *pTextures[MAX_FX_INPUT_TEXTURES] )
{
if ( !m_OverlayMaterial || m_Color.a() == 0 )
return;
time = ToChildMediaTime( time, false );
// Clip the overlay rectangle to the currently drawn one
int x, y, w, h;
int tx, ty, tw, th;
if ( m_bFullScreen )
{
x = currentRect.x;
y = currentRect.y;
w = currentRect.width;
h = currentRect.height;
tx = ty = 0;
tw = totalRect.width;
th = totalRect.height;
}
else
{
x = clamp( m_nLeft, currentRect.x, currentRect.x + currentRect.width );
y = clamp( m_nTop, currentRect.y, currentRect.y + currentRect.height );
int x1 = clamp( m_nLeft + m_nWidth, currentRect.x, currentRect.x + currentRect.width );
int y1 = clamp( m_nTop + m_nHeight, currentRect.y, currentRect.y + currentRect.height );
w = x1 - x;
h = y1 - y;
tx = m_nLeft;
ty = m_nTop;
tw = m_nWidth;
th = m_nHeight;
// Clipped...
if ( w <= 0 || h <= 0 )
return;
}
if ( tw == 0 || th == 0 )
return;
// Compute texture coordinate range of the entire texture
int mw = m_OverlayMaterial->GetMappingWidth();
int mh = m_OverlayMaterial->GetMappingHeight();
// Compute the texture coords in texels we want over the entire image
float uMin = 0;
float uMax = mw;
float vMin = 0;
float vMax = mh;
if ( m_bUseSubRect )
{
uMin = m_nSubRectLeft;
vMin = m_nSubRectTop;
uMax = uMin + m_nSubRectWidth;
vMax = vMin + m_nSubRectHeight;
}
if ( m_flMovementSpeed )
{
float flRadians = M_PI * m_flMovementAngle / 180.0f;
float dUdT = -m_flMovementSpeed * cos( flRadians );
float dVdT = m_flMovementSpeed * sin( flRadians );
float dU = time.GetSeconds() * dUdT;
float dV = time.GetSeconds() * dVdT;
uMin += dU; uMax += dU;
vMin += dV; vMax += dV;
}
// This is the range of normalizes (u,v) coordinates over the *total* image
uMin = ( uMin + 0.5f ) / mw;
vMin = ( vMin + 0.5f ) / mh;
uMax = ( uMax - 0.5f ) / mw;
vMax = ( vMax - 0.5f ) / mh;
// Now determine the subrange we should use given we're rendering a portion of the image
float u0, v0, u1, v1, f;
f = ( x - tx ) / tw;
u0 = Lerp( f, uMin, uMax );
f = ( x + w - tx ) / tw;
u1 = Lerp( f, uMin, uMax );
f = ( y - ty ) / th;
v0 = Lerp( f, vMin, vMax );
f = ( y + h - ty ) / th;
v1 = Lerp( f, vMin, vMax );
x -= currentRect.x;
y -= currentRect.y;
if ( m_OverlayMaterial->NeedsPowerOfTwoFrameBufferTexture() )
{
CMatRenderContextPtr pRenderContext( materials );
ITexture *pTexture = materials->FindTexture( "_rt_PowerOfTwoFB", TEXTURE_GROUP_RENDER_TARGET );
// forced or only once per frame
Rect_t rect;
rect.x = 0;
rect.y = 0;
rect.width = currentRect.width;
rect.height = currentRect.height;
pRenderContext->CopyRenderTargetToTextureEx( pTexture, 0, &rect, NULL );
pRenderContext->SetFrameBufferCopyTexture( pTexture );
}
float r, g, b, a;
m_OverlayMaterial->GetColorModulation( &r, &g, &b );
a = m_OverlayMaterial->GetAlphaModulation();
m_OverlayMaterial->ColorModulate( m_Color.r() / 255.0f, m_Color.g() / 255.0f, m_Color.b() / 255.0f );
m_OverlayMaterial->AlphaModulate( m_Color.a() / 255.0f );
CMatRenderContextPtr pRenderContext( materials );
pRenderContext->Bind( m_OverlayMaterial );
IMesh *pMesh = pRenderContext->GetDynamicMesh();
CMeshBuilder meshBuilder;
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, 2 );
meshBuilder.Position3f( x, y, 0.0f );
meshBuilder.BoneWeight( 0, 1.0f );
meshBuilder.BoneMatrix( 0, 0 );
meshBuilder.Color4ub( 255, 255, 255, 255 );
meshBuilder.TexCoord2f( 0, u0, v0 );
meshBuilder.TexCoord2f( 1, 0.0f, 0.0f );
meshBuilder.TexCoord2f( 2, 0.0f, 0.0f );
meshBuilder.AdvanceVertex();
meshBuilder.Position3f( x, y+h, 0.0f );
meshBuilder.BoneWeight( 0, 1.0f );
meshBuilder.BoneMatrix( 0, 0 );
meshBuilder.Color4ub( 255, 255, 255, 255 );
meshBuilder.TexCoord2f( 0, u0, v1 );
meshBuilder.TexCoord2f( 1, 0.0f, 1.0f );
meshBuilder.TexCoord2f( 2, 0.0f, 0.0f );
meshBuilder.AdvanceVertex();
meshBuilder.Position3f( x+w, y, 0.0f );
meshBuilder.BoneWeight( 0, 1.0f );
meshBuilder.BoneMatrix( 0, 0 );
meshBuilder.Color4ub( 255, 255, 255, 255 );
meshBuilder.TexCoord2f( 0, u1, v0 );
meshBuilder.TexCoord2f( 1, 1.0f, 0.0f );
meshBuilder.TexCoord2f( 2, 0.0f, 0.0f );
meshBuilder.AdvanceVertex();
meshBuilder.Position3f( x+w, y+h, 0.0f );
meshBuilder.BoneWeight( 0, 1.0f );
meshBuilder.BoneMatrix( 0, 0 );
meshBuilder.Color4ub( 255, 255, 255, 255 );
meshBuilder.TexCoord2f( 0, u1, v1 );
meshBuilder.TexCoord2f( 1, 1.0f, 1.0f );
meshBuilder.TexCoord2f( 2, 0.0f, 0.0f );
meshBuilder.AdvanceVertex();
meshBuilder.End();
pMesh->Draw();
m_OverlayMaterial->ColorModulate( r, g, b );
m_OverlayMaterial->AlphaModulate( a );
}

207
movieobjects/dmemdl.cpp Normal file
View File

@ -0,0 +1,207 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmemdl.h"
#include "movieobjects/dmetransform.h"
#include "movieobjects/dmedag.h"
#include "movieobjects_interfaces.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "datacache/imdlcache.h"
#include "istudiorender.h"
#include "bone_setup.h"
#include "tier3/tier3.h"
#include "tier3/mdlutils.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( DmeMDL, CDmeMDL );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeMDL::OnConstruction()
{
m_bDrawInEngine = false;
// SetAttributeValueElement( "transform", CreateElement< CDmeTransform >() );
// SetAttributeValue( "mdlfilename", "models/alyx.mdl" );
m_Color.InitAndSet( this, "color", Color( 255, 255, 255, 255 ) );
m_nSkin.InitAndSet( this, "skin", 0 );
m_nBody.InitAndSet( this, "body", 0 );
m_nSequence.InitAndSet( this, "sequence", 0 );
m_nLOD.InitAndSet( this, "lod", 0 );
m_flPlaybackRate.InitAndSet( this, "playbackrate", 30.0f );
m_flTime.InitAndSet( this, "time", 0.0f );
m_vecViewTarget.Init( this, "viewTarget" );
m_bWorldSpaceViewTarget.Init( this, "worldSpaceViewTarget" );
}
void CDmeMDL::OnDestruction()
{
m_MDL.SetMDL( MDLHANDLE_INVALID );
}
void CDmeMDL::SetMDL( MDLHandle_t handle )
{
m_MDL.SetMDL( handle );
Vector vecMins, vecMaxs;
GetMDLBoundingBox( &vecMins, &vecMaxs, m_MDL.GetMDL(), m_nSequence );
Vector vecLookAt( 100.0f, 0.0f, vecMaxs.z );
m_vecViewTarget.Set( vecLookAt );
m_bWorldSpaceViewTarget = false;
}
MDLHandle_t CDmeMDL::GetMDL( ) const
{
return m_MDL.GetMDL();
}
//-----------------------------------------------------------------------------
// Loads the model matrix based on the transform
//-----------------------------------------------------------------------------
void CDmeMDL::DrawInEngine( bool bDrawInEngine )
{
m_bDrawInEngine = bDrawInEngine;
}
bool CDmeMDL::IsDrawingInEngine() const
{
return m_bDrawInEngine;
}
//-----------------------------------------------------------------------------
// Returns the bounding box for the model
//-----------------------------------------------------------------------------
void CDmeMDL::GetBoundingBox( Vector *pMins, Vector *pMaxs ) const
{
GetMDLBoundingBox( pMins, pMaxs, m_MDL.GetMDL(), m_nSequence );
// Rotate the root transform to make it align with DMEs
// DMEs up vector is the y axis
if ( !m_bDrawInEngine )
{
Vector vecMins, vecMaxs;
matrix3x4_t engineToDme;
CDmeDag::EngineToDmeMatrix( engineToDme );
TransformAABB( engineToDme, *pMins, *pMaxs, vecMins, vecMaxs );
*pMins = vecMins;
*pMaxs = vecMaxs;
}
}
//-----------------------------------------------------------------------------
// Returns the radius of the model as measured from the origin
//-----------------------------------------------------------------------------
float CDmeMDL::GetRadius() const
{
return GetMDLRadius( m_MDL.GetMDL(), m_nSequence );
}
//-----------------------------------------------------------------------------
// Returns a more accurate bounding sphere
//-----------------------------------------------------------------------------
void CDmeMDL::GetBoundingSphere( Vector &vecCenter, float &flRadius )
{
Vector vecEngineCenter;
GetMDLBoundingSphere( &vecEngineCenter, &flRadius, m_MDL.GetMDL(), m_nSequence );
// Rotate the root transform to make it align with DMEs
// DMEs up vector is the y axis
if ( !m_bDrawInEngine )
{
matrix3x4_t engineToDme;
CDmeDag::EngineToDmeMatrix( engineToDme );
VectorTransform( vecEngineCenter, engineToDme, vecCenter );
}
else
{
vecCenter = vecEngineCenter;
}
}
//-----------------------------------------------------------------------------
// Updates the MDL rendering helper
//-----------------------------------------------------------------------------
void CDmeMDL::UpdateMDL()
{
m_MDL.m_Color = m_Color;
m_MDL.m_nSkin = m_nSkin;
m_MDL.m_nBody = m_nBody;
m_MDL.m_nSequence = m_nSequence;
m_MDL.m_nLOD = m_nLOD;
m_MDL.m_flPlaybackRate = m_flPlaybackRate;
m_MDL.m_flTime = m_flTime;
m_MDL.m_vecViewTarget = m_vecViewTarget;
m_MDL.m_Color = m_Color;
m_MDL.m_bWorldSpaceViewTarget = m_bWorldSpaceViewTarget;
}
//-----------------------------------------------------------------------------
// Draws the mesh
//-----------------------------------------------------------------------------
void CDmeMDL::Draw( const matrix3x4_t &shapeToWorld, CDmeDrawSettings *pDrawSettings /* = NULL */ )
{
UpdateMDL();
studiohdr_t *pStudioHdr = m_MDL.GetStudioHdr();
if ( !pStudioHdr )
return;
// FIXME: Why is this necessary!?!?!?
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
if ( !m_bDrawInEngine )
{
pRenderContext->CullMode( MATERIAL_CULLMODE_CCW );
}
matrix3x4_t *pBoneToWorld = g_pStudioRender->LockBoneMatrices( pStudioHdr->numbones );
SetUpBones( shapeToWorld, pStudioHdr->numbones, pBoneToWorld );
g_pStudioRender->UnlockBoneMatrices();
m_MDL.Draw( shapeToWorld, pBoneToWorld );
// FIXME: Why is this necessary!?!?!?
if ( !m_bDrawInEngine )
{
pRenderContext->CullMode( MATERIAL_CULLMODE_CW );
}
}
void CDmeMDL::SetUpBones( const matrix3x4_t& shapeToWorld, int nMaxBoneCount, matrix3x4_t *pOutputMatrices )
{
UpdateMDL();
// Root transform
matrix3x4_t rootToWorld;
// Rotate the root transform to make it align with DMEs
// DMEs up vector is the y axis
if ( !m_bDrawInEngine )
{
matrix3x4_t engineToDme;
CDmeDag::EngineToDmeMatrix( engineToDme );
ConcatTransforms( engineToDme, shapeToWorld, rootToWorld );
}
else
{
MatrixCopy( shapeToWorld, rootToWorld );
}
m_MDL.SetUpBones( rootToWorld, nMaxBoneCount, pOutputMatrices );
}

View File

@ -0,0 +1,287 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Describes an asset: something that is compiled from sources,
// in potentially multiple steps, to a compiled resource
//
//=============================================================================
#include "movieobjects/dmemdlmakefile.h"
#include "movieobjects/dmedag.h"
#include "movieobjects/dmemdl.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "datacache/imdlcache.h"
#include "filesystem.h"
#include "tier3/tier3.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Hook into datamodel
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeSourceSkin, CDmeSourceSkin );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeSourceSkin::OnConstruction()
{
m_SkinName.Init( this, "skinName" );
m_bFlipTriangles.Init( this, "flipTriangles" );
m_flScale.InitAndSet( this, "scale", 1.0f );
}
void CDmeSourceSkin::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// These can be built from DCC makefiles
//-----------------------------------------------------------------------------
static const char *s_pSkinMakeFiles[] =
{
"DmeMayaModelMakefile",
"DmeXSIModelMakefile",
NULL
};
const char **CDmeSourceSkin::GetSourceMakefileTypes()
{
return s_pSkinMakeFiles;
}
//-----------------------------------------------------------------------------
// Hook into datamodel
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeSourceCollisionModel, CDmeSourceCollisionModel );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeSourceCollisionModel::OnConstruction()
{
}
void CDmeSourceCollisionModel::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// These can be built from DCC makefiles
//-----------------------------------------------------------------------------
const char **CDmeSourceCollisionModel::GetSourceMakefileTypes()
{
return s_pSkinMakeFiles;
}
//-----------------------------------------------------------------------------
// Hook into datamodel
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeSourceAnimation, CDmeSourceAnimation );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeSourceAnimation::OnConstruction()
{
m_AnimationName.Init( this, "animationName" );
m_SourceAnimationName.Init( this, "sourceAnimationName" );
}
void CDmeSourceAnimation::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// These can be built from DCC makefiles
//-----------------------------------------------------------------------------
static const char *s_pAnimationMakeFiles[] =
{
"DmeMayaAnimationMakefile",
"DmeXSIAnimationMakefile",
NULL
};
const char **CDmeSourceAnimation::GetSourceMakefileTypes()
{
return s_pAnimationMakeFiles;
}
//-----------------------------------------------------------------------------
// Hook into datamodel
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeMDLMakefile, CDmeMDLMakefile );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeMDLMakefile::OnConstruction()
{
m_hMDL = CreateElement< CDmeMDL >( "MDLMakefile Preview" );
m_bFlushMDL = false;
}
void CDmeMDLMakefile::OnDestruction()
{
DestroyElement( m_hMDL.Get() );
}
//-----------------------------------------------------------------------------
// Returns source types
//-----------------------------------------------------------------------------
static DmeMakefileType_t s_pSourceTypes[] =
{
{ "DmeSourceSkin", "Skin", true, "makefiledir:models\\dmx", "*.dmx", "Valve DMX File (*.dmx)" },
{ "DmeSourceAnimation", "Animation", false, "makefiledir:animations\\dmx", "*.dmx", "Valve DMX File (*.dmx)" },
{ "DmeSourceCollisionModel", "Collision Model", true, "makefiledir:models\\dmx", "*.dmx", "Valve DMX File (*.dmx)" },
{ NULL, NULL, false, NULL, NULL, NULL },
};
DmeMakefileType_t* CDmeMDLMakefile::GetSourceTypes()
{
return s_pSourceTypes;
}
//-----------------------------------------------------------------------------
// Makefile type
//-----------------------------------------------------------------------------
static DmeMakefileType_t s_MakefileType =
{
"DmeMDLMakefile", "Model", true, "contentdir:models", "*.dmx", "Valve Model MakeFile (*.dmx)"
};
DmeMakefileType_t *CDmeMDLMakefile::GetMakefileType()
{
return &s_MakefileType;
}
//-----------------------------------------------------------------------------
// Add, remove sources
//-----------------------------------------------------------------------------
void CDmeMDLMakefile::SetSkin( const char *pFullPath )
{
RemoveAllSources( "DmeSourceSkin" );
AddSource( "DmeSourceSkin", pFullPath );
}
void CDmeMDLMakefile::AddAnimation( const char *pFullPath )
{
AddSource( "animation", pFullPath );
}
void CDmeMDLMakefile::RemoveAnimation( const char *pFullPath )
{
RemoveSource( "animation", pFullPath );
}
void CDmeMDLMakefile::RemoveAllAnimations( )
{
RemoveAllSources( "animation" );
}
//-----------------------------------------------------------------------------
// Inherited classes should re-implement these methods
//-----------------------------------------------------------------------------
CDmElement *CDmeMDLMakefile::CreateOutputElement( )
{
if ( m_bFlushMDL )
{
// Flush the model out of the cache; detach it from the MDL
MDLHandle_t h = m_hMDL->GetMDL();
if ( h != MDLHANDLE_INVALID )
{
g_pMDLCache->Flush( h );
}
m_bFlushMDL = false;
}
m_hMDL->SetMDL( MDLHANDLE_INVALID );
// FIXME: Should we ask the tool (studiomdl) for this?
// Should we have output type names? Not sure yet..
// Doing the simplest thing first.
char pOutputName[MAX_PATH];
Q_FileBase( GetFileName(), pOutputName, sizeof(pOutputName) );
if ( !pOutputName[0] )
return m_hMDL.Get();
char pOutputDir[MAX_PATH];
GetOutputDirectory( pOutputDir, sizeof(pOutputDir) );
if ( !pOutputDir[0] )
return m_hMDL.Get();
Q_StripTrailingSlash( pOutputDir );
char pFullPath[MAX_PATH];
Q_snprintf( pFullPath, sizeof(pFullPath), "%s\\%s.mdl", pOutputDir, pOutputName );
char pRelativePath[MAX_PATH];
g_pFullFileSystem->FullPathToRelativePathEx( pFullPath, "GAME", pRelativePath, sizeof( pRelativePath ) );
MDLHandle_t h = g_pMDLCache->FindMDL( pRelativePath );
m_hMDL->SetMDL( h );
return m_hMDL.Get();
}
void CDmeMDLMakefile::DestroyOutputElement( CDmElement *pOutput )
{
m_bFlushMDL = true;
}
//-----------------------------------------------------------------------------
// Compile assets
//-----------------------------------------------------------------------------
static const char *s_pOutputExtensions[] =
{
"dx80.vtx",
"dx90.vtx",
"sw.vtx",
"mdl",
"vvd",
"phy",
NULL
};
void CDmeMDLMakefile::GetOutputs( CUtlVector<CUtlString> &fullPaths )
{
fullPaths.RemoveAll();
// FIXME: Should we ask the tool (studiomdl) for this?
// Should we have output type names? Not sure yet..
// Doing the simplest thing first.
char pOutputName[MAX_PATH];
Q_FileBase( GetFileName(), pOutputName, sizeof(pOutputName) );
if ( !pOutputName[0] )
return;
char pOutputDir[MAX_PATH];
GetOutputDirectory( pOutputDir, sizeof(pOutputDir) );
if ( !pOutputDir[0] )
return;
Q_StripTrailingSlash( pOutputDir );
char pFullPath[MAX_PATH];
for ( int i = 0; s_pOutputExtensions[i]; ++i )
{
Q_snprintf( pFullPath, sizeof(pFullPath), "%s\\%s.%s", pOutputDir, pOutputName, s_pOutputExtensions[i] );
fullPaths.AddToTail( pFullPath );
}
}

5017
movieobjects/dmemesh.cpp Normal file

File diff suppressed because it is too large Load Diff

335
movieobjects/dmemodel.cpp Normal file
View File

@ -0,0 +1,335 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Dme version of a skeletal model (gets compiled into a MDL)
//
//=============================================================================
#include "movieobjects/dmemodel.h"
#include "movieobjects_interfaces.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "datacache/imdlcache.h"
#include "materialsystem/imaterialsystem.h"
#include "tier2/tier2.h"
#include "studio.h"
#include "materialsystem/imaterialsystemhardwareconfig.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( DmeModel, CDmeModel );
//-----------------------------------------------------------------------------
// Stack of DmeModels currently being rendered. Used to set up render state
//-----------------------------------------------------------------------------
CUtlStack< CDmeModel * > CDmeModel::s_ModelStack;
static CUtlVector< matrix3x4_t > s_PoseToWorld;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeModel::OnConstruction()
{
m_JointTransforms.Init( this, "jointTransforms" );
m_BaseStates.Init( this, "baseStates" );
}
void CDmeModel::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Add joint
//-----------------------------------------------------------------------------
int CDmeModel::AddJoint( CDmeDag *pJoint )
{
int nIndex = GetJointTransformIndex( pJoint->GetTransform() );
if ( nIndex >= 0 )
return nIndex;
return m_JointTransforms.AddToTail( pJoint->GetTransform() );
}
//-----------------------------------------------------------------------------
// Add joint
//-----------------------------------------------------------------------------
CDmeJoint *CDmeModel::AddJoint( const char *pJointName, CDmeDag *pParent )
{
CDmeJoint *pJoint = CreateElement<CDmeJoint>( pJointName, GetFileId() );
CDmeTransform *pTransform = pJoint->GetTransform();
pTransform->SetName( pJointName );
if ( !pParent )
{
pParent = this;
}
pParent->AddChild( pJoint );
m_JointTransforms.AddToTail( pTransform );
return pJoint;
}
//-----------------------------------------------------------------------------
// Returns the number of joint transforms we know about
//-----------------------------------------------------------------------------
int CDmeModel::GetJointTransformCount() const
{
return m_JointTransforms.Count();
}
//-----------------------------------------------------------------------------
// Determines joint transform index given a joint transform
//-----------------------------------------------------------------------------
int CDmeModel::GetJointTransformIndex( CDmeTransform *pTransform ) const
{
int nCount = m_JointTransforms.Count();
for ( int i = 0; i < nCount; ++i )
{
if ( pTransform == m_JointTransforms[i] )
return i;
}
return -1;
}
//-----------------------------------------------------------------------------
// Determines joint transform index given a joint
//-----------------------------------------------------------------------------
int CDmeModel::GetJointTransformIndex( CDmeDag *pJoint ) const
{
return GetJointTransformIndex( pJoint->GetTransform() );
}
//-----------------------------------------------------------------------------
// Determines joint transform index given a joint name
//-----------------------------------------------------------------------------
CDmeTransform *CDmeModel::GetJointTransform( int nIndex )
{
return m_JointTransforms[ nIndex ];
}
const CDmeTransform *CDmeModel::GetJointTransform( int nIndex ) const
{
return m_JointTransforms[ nIndex ];
}
//-----------------------------------------------------------------------------
// Finds a base state by name, returns NULL if not found
//-----------------------------------------------------------------------------
CDmeTransformList *CDmeModel::FindBaseState( const char *pBaseStateName )
{
int nCount = m_BaseStates.Count();
for ( int i = 0; i < nCount; ++i )
{
if ( !Q_stricmp( m_BaseStates[i]->GetName(), pBaseStateName ) )
return m_BaseStates[i];
}
return NULL;
}
//-----------------------------------------------------------------------------
// Captures the current joint transforms into a base state
//-----------------------------------------------------------------------------
void CDmeModel::CaptureJointsToBaseState( const char *pBaseStateName )
{
CDmeTransformList *pTransformList = FindBaseState( pBaseStateName );
if ( !pTransformList )
{
pTransformList = CreateElement<CDmeTransformList>( pBaseStateName, GetFileId() );
m_BaseStates.AddToTail( pTransformList );
}
// Make the transform list have the correct number of elements
int nJointCount = m_JointTransforms.Count();
int nCurrentCount = pTransformList->GetTransformCount();
if ( nJointCount > nCurrentCount )
{
for ( int i = nCurrentCount; i < nJointCount; ++i )
{
CDmeTransform *pTransform = CreateElement<CDmeTransform>( m_JointTransforms[i]->GetName(), pTransformList->GetFileId() );
pTransformList->m_Transforms.AddToTail( pTransform );
}
}
else if ( nJointCount < nCurrentCount )
{
pTransformList->m_Transforms.RemoveMultiple( nJointCount, nCurrentCount - nJointCount );
}
// Copy the state over
for ( int i = 0; i < nJointCount; ++i )
{
matrix3x4_t mat;
m_JointTransforms[i]->GetTransform( mat );
pTransformList->SetTransform( i, mat );
}
}
//-----------------------------------------------------------------------------
// Loads up joint transforms for this model
//-----------------------------------------------------------------------------
void CDmeModel::LoadJointTransform( CDmeDag *pJoint, CDmeTransformList *pBindPose, const matrix3x4_t &parentToWorld, const matrix3x4_t &parentToBindPose, bool bSetHardwareState )
{
CDmeTransform *pTransform = pJoint->GetTransform();
// Determines joint transform index; no index, no traversing lower in the hierarchy
int nJointIndex = GetJointTransformIndex( pTransform );
if ( nJointIndex < 0 )
return;
// FIXME: Sucky search here necessary to find bone matrix index
matrix3x4_t jointToWorld, jointToParent;
pTransform->GetTransform( jointToParent );
ConcatTransforms( parentToWorld, jointToParent, jointToWorld );
matrix3x4_t bindJointToParent, bindPoseToJoint, bindPoseToWorld, jointToBindPose;
if ( pBindPose )
{
if ( nJointIndex >= pBindPose->GetTransformCount() )
{
Warning( "Model is in an invalid state! There are different numbers of bones in the bind pose and joint transform list!\n" );
return;
}
pBindPose->GetTransform( nJointIndex )->GetTransform( bindJointToParent );
}
else
{
MatrixCopy( jointToParent, bindJointToParent );
}
ConcatTransforms( parentToBindPose, bindJointToParent, jointToBindPose );
MatrixInvert( jointToBindPose, bindPoseToJoint );
ConcatTransforms( jointToWorld, bindPoseToJoint, bindPoseToWorld );
if ( bSetHardwareState )
{
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
pRenderContext->LoadBoneMatrix( nJointIndex, bindPoseToWorld );
}
MatrixCopy( bindPoseToWorld, s_PoseToWorld[ nJointIndex ] );
int nChildCount = pJoint->GetChildCount();
for ( int i = 0; i < nChildCount; ++i )
{
CDmeDag *pChildJoint = pJoint->GetChild(i);
if ( !pChildJoint )
continue;
LoadJointTransform( pChildJoint, pBindPose, jointToWorld, jointToBindPose, bSetHardwareState );
}
}
//-----------------------------------------------------------------------------
// Sets up the render state for the model
//-----------------------------------------------------------------------------
CDmeModel::SetupBoneRetval_t CDmeModel::SetupBoneMatrixState( const matrix3x4_t& shapeToWorld, bool bForceSoftwareSkin )
{
int nJointCount = m_JointTransforms.Count();
if ( nJointCount <= 0 )
return NO_SKIN_DATA;
int nBoneBatchCount = g_pMaterialSystemHardwareConfig->MaxVertexShaderBlendMatrices();
bool bSetHardwareState = ( nJointCount <= nBoneBatchCount ) && !bForceSoftwareSkin;
s_PoseToWorld.EnsureCount( nJointCount );
// Finds a base state by name, returns NULL if not found
CDmeTransformList *pBindPose = FindBaseState( "bind" );
matrix3x4_t parentToBindPose;
SetIdentityMatrix( parentToBindPose );
int nChildCount = GetChildCount();
for ( int i = 0; i < nChildCount; ++i )
{
CDmeDag *pChildJoint = GetChild(i);
if ( !pChildJoint )
continue;
LoadJointTransform( pChildJoint, pBindPose, shapeToWorld, parentToBindPose, bSetHardwareState );
}
return bSetHardwareState ? BONES_SET_UP : TOO_MANY_BONES;
}
matrix3x4_t *CDmeModel::SetupModelRenderState( const matrix3x4_t& shapeToWorld, bool bHasSkinningData, bool bForceSoftwareSkin )
{
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
if ( bHasSkinningData && ( s_ModelStack.Count() > 0 ) )
{
SetupBoneRetval_t retVal = s_ModelStack.Top()->SetupBoneMatrixState( shapeToWorld, bForceSoftwareSkin );
if ( retVal == TOO_MANY_BONES )
{
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->LoadIdentity( );
return s_PoseToWorld.Base();
}
if ( retVal != NO_SKIN_DATA )
return NULL;
}
if ( bForceSoftwareSkin )
{
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->LoadIdentity( );
s_PoseToWorld.EnsureCount( 1 );
MatrixCopy( shapeToWorld, s_PoseToWorld[0] );
return s_PoseToWorld.Base();
}
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->LoadMatrix( shapeToWorld );
return NULL;
}
void CDmeModel::CleanupModelRenderState()
{
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->LoadIdentity();
}
//-----------------------------------------------------------------------------
// Recursively render the Dag hierarchy
//-----------------------------------------------------------------------------
void CDmeModel::Draw( CDmeDrawSettings *pDrawSettings /* = NULL */ )
{
s_ModelStack.Push( this );
BaseClass::Draw( pDrawSettings );
s_ModelStack.Pop( );
}
//-----------------------------------------------------------------------------
// Set if Z is the up axis of the model
//-----------------------------------------------------------------------------
void CDmeModel::ZUp( bool bZUp )
{
SetValue( "upAxis", bZUp ? "Z" : "Y" );
}
//-----------------------------------------------------------------------------
// Returns true if the DmeModel is Z Up.
// NOTE: Since Y & Z are the only supported modes and Y is the default
// because that's how DmeModel data was originally defined,
// assume Y is up if the m_UpAxis attribute is not "Z"
//-----------------------------------------------------------------------------
bool CDmeModel::IsZUp() const
{
const char *pszZUp = this->GetValueString( "upAxis" );
return ( pszZUp && *pszZUp ) ? StringHasPrefix( pszZUp, "Z" ) : false;
}

View File

@ -0,0 +1,157 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmemorphoperator.h"
#include "movieobjects/dmevertexdata.h"
#include "movieobjects/dmemesh.h"
#include "movieobjects_interfaces.h"
#include "datamodel/dmelementfactoryhelper.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( DmeMorphOperator, CDmeMorphOperator );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeMorphOperator::OnConstruction()
{
m_mesh.Init( this, "mesh", FATTRIB_HAS_CALLBACK );
m_deltaStateWeights.Init( this, "deltaStateWeights", FATTRIB_MUSTCOPY );
m_baseStateName.Init( this, "baseStateName", FATTRIB_TOPOLOGICAL );
}
void CDmeMorphOperator::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// accessors
//-----------------------------------------------------------------------------
uint CDmeMorphOperator::NumDeltaStateWeights()
{
return m_deltaStateWeights.Count();
}
CDmElement *CDmeMorphOperator::GetDeltaStateWeight( uint i )
{
return m_deltaStateWeights[ i ];
}
CDmeMesh *CDmeMorphOperator::GetMesh()
{
return m_mesh.GetElement();
}
//-----------------------------------------------------------------------------
// This function gets called whenever an attribute changes
//-----------------------------------------------------------------------------
void CDmeMorphOperator::OnAttributeChanged( CDmAttribute *pAttribute )
{
if ( pAttribute == m_mesh.GetAttribute() )
{
CDmeMesh *pMesh = GetMesh();
if ( pMesh )
{
#if 0 // right now, the file already contains these weights, and re-creating them breaks the channel connections
m_deltaStateWeights.RemoveAll();
uint dn = pMesh->NumDeltaStates();
for ( uint di = 0; di < dn; ++di )
{
CDmElement *pDeltaState = pMesh->GetDeltaState( di );
const char *name = pDeltaState->GetName();
CDmElement *pDeltaWeight = CreateElement< CDmElement >( name, GetFileId() );
pDeltaWeight->SetAttributeValue( "weight", 0.0f );
m_deltaStateWeights.AddToTail( pDeltaWeight->GetHandle() );
}
#endif
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeMorphOperator::Operate()
{
CDmeMesh *mesh = GetMesh();
uint mn = NumDeltaStateWeights();
for ( uint mi = 0; mi < mn; ++mi )
{
CDmElement *pDeltaState = GetDeltaStateWeight( mi );
const char *deltaName = pDeltaState->GetName();
float deltaWeight = pDeltaState->GetValue< float >( "weight" );
int di = mesh->FindDeltaStateIndex( deltaName );
if ( di != -1 )
{
mesh->SetDeltaStateWeight( di, MESH_DELTA_WEIGHT_NORMAL, deltaWeight );
}
else
{
Msg( "MorphOperator::Operate: invalid delta state name: %s\n", deltaName );
}
}
}
// hack to avoid MSVC complaining about multiply defined symbols
namespace MorphOp
{
void AddAttr( CUtlVector< CDmAttribute * > &attrs, CDmAttribute *pAttr )
{
if ( pAttr == NULL )
return;
attrs.AddToTail( pAttr );
}
void AddVertexAttributes( CUtlVector< CDmAttribute * > &attrs, CDmElement *pObject )
{
AddAttr( attrs, pObject->GetAttribute( "coordinates" ) );
AddAttr( attrs, pObject->GetAttribute( "normals" ) );
AddAttr( attrs, pObject->GetAttribute( "textureCoordinates" ) );
// TODO - add colors, occlusionFactors, boneIndices*, boneWeights*, tangents
}
};
using namespace MorphOp;
void CDmeMorphOperator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
uint nWeights = NumDeltaStateWeights();
for ( uint wi = 0; wi < nWeights; ++wi )
{
CDmElement *pDelta = GetDeltaStateWeight( wi );
AddAttr( attrs, pDelta->GetAttribute( "weight" ) );
}
CDmeMesh *pMesh = GetMesh();
CDmeVertexData *pBaseState = pMesh->FindBaseState( m_baseStateName.Get() );
AddVertexAttributes( attrs, pBaseState );
uint nDeltas = pMesh->DeltaStateCount();
for ( uint di = 0; di < nDeltas; ++di )
{
CDmElement *pDeltaState = pMesh->GetDeltaState( di );
AddAttr( attrs, pDeltaState->GetAttribute( "indices" ) );
AddVertexAttributes( attrs, pDeltaState );
}
}
void CDmeMorphOperator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
AddVertexAttributes( attrs, GetMesh() );
}

View File

@ -0,0 +1,104 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmemouseinput.h"
#include "movieobjects_interfaces.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "vgui/iinput.h"
#include "vgui/ipanel.h"
#include "tier3/tier3.h"
#include "tier0/dbg.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( DmeMouseInput, CDmeMouseInput );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeMouseInput::OnConstruction()
{
m_x.Init( this, "x" );
m_y.Init( this, "y" );
m_xOrigin = 0.0f;
m_yOrigin = 0.0f;
}
void CDmeMouseInput::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// IsDirty - ie needs to operate
//-----------------------------------------------------------------------------
bool CDmeMouseInput::IsDirty()
{
float flX, flY;
GetNormalizedCursorPos( flX, flY );
flX -= m_xOrigin;
flY -= m_yOrigin;
return ( flX != GetValue< float >( "x" ) ) || ( flY != GetValue< float >( "y" ) );
}
void CDmeMouseInput::Operate()
{
float flX, flY;
GetNormalizedCursorPos( flX, flY );
SetValue( "x", flX - m_xOrigin );
SetValue( "y", flY - m_yOrigin );
// Msg( "CDmeMouseInput::Operate() at <%f, %f>\n", flX, flY );
}
void CDmeMouseInput::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
}
void CDmeMouseInput::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( GetAttribute( "x" ) );
attrs.AddToTail( GetAttribute( "y" ) );
}
void CDmeMouseInput::ResetOrigin( float dx, float dy )
{
GetNormalizedCursorPos( m_xOrigin, m_yOrigin );
m_xOrigin += dx;
m_yOrigin += dy;
}
void CDmeMouseInput::GetNormalizedCursorPos( float &flX, float &flY )
{
int x, y;
g_pVGuiInput->GetCursorPos( x, y );
vgui::VPANEL vpanel = g_pVGuiInput->GetFocus();
if ( !vpanel )
{
flX = flY = 0.0f;
return;
}
int x0, y0;
g_pVGuiPanel->GetPos( vpanel, x0, y0 );
int w, h;
g_pVGuiPanel->GetSize( vpanel, w, h );
flX = ( x - x0 ) / float(w);
flY = ( y - y0 ) / float(h);
}

View File

@ -0,0 +1,36 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmeoperator.h"
#include "datamodel/dmelementfactoryhelper.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ABSTRACT_ELEMENT( DmeOperator, CDmeOperator );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeOperator::OnConstruction()
{
}
void CDmeOperator::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// IsDirty - ie needs to operate
//-----------------------------------------------------------------------------
bool CDmeOperator::IsDirty()
{
return BaseClass::IsDirty();
}

View File

@ -0,0 +1,321 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmepackoperators.h"
#include "movieobjects_interfaces.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "datamodel/dmattribute.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// CDmePackColorOperator
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmePackColorOperator, CDmePackColorOperator );
void CDmePackColorOperator::OnConstruction()
{
m_color.Init( this, "color" );
m_red .Init( this, "red" );
m_green.Init( this, "green" );
m_blue .Init( this, "blue" );
m_alpha.Init( this, "alpha" );
}
void CDmePackColorOperator::OnDestruction()
{
}
bool CDmePackColorOperator::IsDirty()
{
const Color &c = m_color.Get();
// float s = 255.999f;
// return c.r() != s*m_red.Get() || c.g() != s*m_green.Get() || c.b() != s*m_blue.Get() || c.a() != s*m_alpha.Get();
return c.r() != m_red.Get() || c.g() != m_green.Get() || c.b() != m_blue.Get() || c.a() != m_alpha.Get();
}
void CDmePackColorOperator::Operate()
{
// float s = 255.999f;
// m_color.Set( Color( s*m_red.Get(), s*m_green.Get(), s*m_blue.Get(), s*m_alpha.Get() ) );
m_color.Set( Color( m_red.Get(), m_green.Get(), m_blue.Get(), m_alpha.Get() ) );
}
void CDmePackColorOperator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_red.GetAttribute() );
attrs.AddToTail( m_green.GetAttribute() );
attrs.AddToTail( m_blue.GetAttribute() );
attrs.AddToTail( m_alpha.GetAttribute() );
}
void CDmePackColorOperator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_color.GetAttribute() );
}
//-----------------------------------------------------------------------------
// CDmePackVector2Operator
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmePackVector2Operator, CDmePackVector2Operator );
void CDmePackVector2Operator::OnConstruction()
{
m_vector.Init( this, "vector" );
m_x.Init( this, "x" );
m_y.Init( this, "y" );
}
void CDmePackVector2Operator::OnDestruction()
{
}
bool CDmePackVector2Operator::IsDirty()
{
const Vector2D &v = m_vector.Get();
return v.x != m_x.Get() || v.y != m_y.Get();
}
void CDmePackVector2Operator::Operate()
{
m_vector.Set( Vector2D( m_x.Get(), m_y.Get() ) );
}
void CDmePackVector2Operator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_x.GetAttribute() );
attrs.AddToTail( m_y.GetAttribute() );
}
void CDmePackVector2Operator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_vector.GetAttribute() );
}
//-----------------------------------------------------------------------------
// CDmePackVector3Operator
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmePackVector3Operator, CDmePackVector3Operator );
void CDmePackVector3Operator::OnConstruction()
{
m_vector.Init( this, "vector" );
m_x.Init( this, "x" );
m_y.Init( this, "y" );
m_z.Init( this, "z" );
}
void CDmePackVector3Operator::OnDestruction()
{
}
bool CDmePackVector3Operator::IsDirty()
{
const Vector &v = m_vector.Get();
return v.x != m_x.Get() || v.y != m_y.Get() || v.z != m_z.Get();
}
void CDmePackVector3Operator::Operate()
{
m_vector.Set( Vector( m_x.Get(), m_y.Get(), m_z.Get() ) );
}
void CDmePackVector3Operator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_x.GetAttribute() );
attrs.AddToTail( m_y.GetAttribute() );
attrs.AddToTail( m_z.GetAttribute() );
}
void CDmePackVector3Operator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_vector.GetAttribute() );
}
//-----------------------------------------------------------------------------
// CDmePackVector4Operator
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmePackVector4Operator, CDmePackVector4Operator );
void CDmePackVector4Operator::OnConstruction()
{
m_vector.Init( this, "vector" );
m_x.Init( this, "x" );
m_y.Init( this, "y" );
m_z.Init( this, "z" );
m_w.Init( this, "w" );
}
void CDmePackVector4Operator::OnDestruction()
{
}
bool CDmePackVector4Operator::IsDirty()
{
const Vector4D &v = m_vector.Get();
return v.x != m_x.Get() || v.y != m_y.Get() || v.z != m_z.Get() || v.w != m_w.Get();
}
void CDmePackVector4Operator::Operate()
{
m_vector.Set( Vector4D( m_x.Get(), m_y.Get(), m_z.Get(), m_w.Get() ) );
}
void CDmePackVector4Operator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_x.GetAttribute() );
attrs.AddToTail( m_y.GetAttribute() );
attrs.AddToTail( m_z.GetAttribute() );
attrs.AddToTail( m_w.GetAttribute() );
}
void CDmePackVector4Operator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_vector.GetAttribute() );
}
//-----------------------------------------------------------------------------
// CDmePackQAngleOperator
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmePackQAngleOperator, CDmePackQAngleOperator );
void CDmePackQAngleOperator::OnConstruction()
{
m_qangle.Init( this, "qangle" );
m_x.Init( this, "x" );
m_y.Init( this, "y" );
m_z.Init( this, "z" );
}
void CDmePackQAngleOperator::OnDestruction()
{
}
bool CDmePackQAngleOperator::IsDirty()
{
const QAngle &q = m_qangle.Get();
return q.x != m_x.Get() || q.y != m_y.Get() || q.z != m_z.Get();
}
void CDmePackQAngleOperator::Operate()
{
m_qangle.Set( QAngle( m_x.Get(), m_y.Get(), m_z.Get() ) );
}
void CDmePackQAngleOperator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_x.GetAttribute() );
attrs.AddToTail( m_y.GetAttribute() );
attrs.AddToTail( m_z.GetAttribute() );
}
void CDmePackQAngleOperator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_qangle.GetAttribute() );
}
//-----------------------------------------------------------------------------
// CDmePackQuaternionOperator
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmePackQuaternionOperator, CDmePackQuaternionOperator );
void CDmePackQuaternionOperator::OnConstruction()
{
m_quaternion.Init( this, "quaternion" );
m_x.Init( this, "x" );
m_y.Init( this, "y" );
m_z.Init( this, "z" );
m_w.Init( this, "w" );
}
void CDmePackQuaternionOperator::OnDestruction()
{
}
bool CDmePackQuaternionOperator::IsDirty()
{
const Quaternion &q = m_quaternion.Get();
return q.x != m_x.Get() || q.y != m_y.Get() || q.z != m_z.Get() || q.w != m_w.Get();
}
void CDmePackQuaternionOperator::Operate()
{
m_quaternion.Set( Quaternion( m_x.Get(), m_y.Get(), m_z.Get(), m_w.Get() ) );
}
void CDmePackQuaternionOperator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_x.GetAttribute() );
attrs.AddToTail( m_y.GetAttribute() );
attrs.AddToTail( m_z.GetAttribute() );
attrs.AddToTail( m_w.GetAttribute() );
}
void CDmePackQuaternionOperator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_quaternion.GetAttribute() );
}
//-----------------------------------------------------------------------------
// CDmePackVMatrixOperator
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmePackVMatrixOperator, CDmePackVMatrixOperator );
void CDmePackVMatrixOperator::OnConstruction()
{
m_vmatrix.Init( this, "vmatrix" );
char name[ 4 ];
for ( uint i = 0; i < 16; ++i )
{
Q_snprintf( name, sizeof(name), "m%d%d", i >> 2, i & 0x3 );
m_cells[ i ].Init( this, name );
}
}
void CDmePackVMatrixOperator::OnDestruction()
{
}
bool CDmePackVMatrixOperator::IsDirty()
{
const VMatrix &v = m_vmatrix.Get();
for ( uint i = 0; i < 16; ++i )
{
if ( *( v[ i ] ) != m_cells[ i ].Get() )
return true;
}
return false;
}
void CDmePackVMatrixOperator::Operate()
{
VMatrix v;
for ( uint i = 0; i < 16; ++i )
{
*( v[ i ] ) = m_cells[ i ].Get();
}
m_vmatrix.Set( v );
}
void CDmePackVMatrixOperator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
for ( uint i = 0; i < 16; ++i )
{
attrs.AddToTail( m_cells[i].GetAttribute() );
}
}
void CDmePackVMatrixOperator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_vmatrix.GetAttribute() );
}

View File

@ -0,0 +1,598 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmeparticlesystemdefinition.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "movieobjects/dmeeditortypedictionary.h"
#include "toolutils/enginetools_int.h"
#include "tier1/KeyValues.h"
#include "tier1/utlbuffer.h"
#include "tier1/convar.h"
#include "particles/particles.h"
#include "dme_controls/attributeintchoicepanel.h"
#include "dme_controls/attributeboolchoicepanel.h"
#include "dme_controls/attributestringchoicepanel.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Human readable string for the particle functions
//-----------------------------------------------------------------------------
static const char *s_pParticleFuncTypeName[PARTICLE_FUNCTION_COUNT] =
{
"Renderer", // FUNCTION_RENDERER = 0,
"Operator", // FUNCTION_OPERATOR,
"Initializer", // FUNCTION_INITIALIZER,
"Emitter", // FUNCTION_EMITTER,
"Children", // FUNCTION_CHILDREN,
"ForceGenerator", // FUNCTION_FORCEGENERATOR
"Constraint", // FUNCTION_CONSTRAINT
};
const char *GetParticleFunctionTypeName( ParticleFunctionType_t type )
{
return s_pParticleFuncTypeName[type];
}
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY_INSTALL_EXPLICITLY( DmeParticleFunction, CDmeParticleFunction );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeParticleFunction::OnConstruction()
{
m_bSkipNextResolve = false;
}
void CDmeParticleFunction::OnDestruction()
{
DestroyElement( m_hTypeDictionary, TD_DEEP );
}
//-----------------------------------------------------------------------------
// Construct an appropriate editor attribute info
//-----------------------------------------------------------------------------
static void CreateEditorAttributeInfo( CDmeEditorType *pEditorType, const char *pAttributeName, const char *pWidgetInfo )
{
if ( !pWidgetInfo )
return;
CCommand parse;
parse.Tokenize( pWidgetInfo );
if ( parse.ArgC() == 1 )
{
CDmeEditorAttributeInfo *pInfo = CreateElement< CDmeEditorAttributeInfo >( "field info" );
pEditorType->AddAttributeInfo( pAttributeName, pInfo );
pInfo->m_Widget = parse[0];
return;
}
if ( parse.ArgC() == 2 )
{
CDmeEditorChoicesInfo *pInfo = NULL;
if ( !Q_stricmp( parse[0], "intchoice" ) )
{
pInfo = CreateElement< CDmeEditorIntChoicesInfo >( "field info" );
}
if ( !Q_stricmp( parse[0], "boolchoice" ) )
{
pInfo = CreateElement< CDmeEditorBoolChoicesInfo >( "field info" );
}
if ( !Q_stricmp( parse[0], "stringchoice" ) )
{
pInfo = CreateElement< CDmeEditorStringChoicesInfo >( "field info" );
}
if ( !Q_stricmp( parse[0], "elementchoice" ) )
{
pInfo = CreateElement< CDmeEditorChoicesInfo >( "field info" );
}
if ( pInfo )
{
pInfo->SetChoiceType( parse[1] );
pEditorType->AddAttributeInfo( pAttributeName, pInfo );
pInfo->m_Widget = parse[0];
return;
}
}
}
//-----------------------------------------------------------------------------
// Used for backward compat
//-----------------------------------------------------------------------------
void CDmeParticleFunction::AddMissingFields( const DmxElementUnpackStructure_t *pUnpack )
{
DestroyElement( m_hTypeDictionary, TD_DEEP );
m_hTypeDictionary = CreateElement< CDmeEditorTypeDictionary >( "particleFunctionDict" );
CDmeEditorType *pEditorType = CreateElement< CDmeEditorType >( GetTypeString() );
for ( ; pUnpack->m_pAttributeName; ++pUnpack )
{
CreateEditorAttributeInfo( pEditorType, pUnpack->m_pAttributeName, (const char *)pUnpack->m_pUserData );
// Can happen if 'name' or 'functionName' is used
if ( HasAttribute( pUnpack->m_pAttributeName ) )
continue;
CDmAttribute *pAttribute = AddAttribute( pUnpack->m_pAttributeName, pUnpack->m_AttributeType );
if ( pUnpack->m_pDefaultString )
{
int nLen = Q_strlen( pUnpack->m_pDefaultString );
CUtlBuffer bufParse( pUnpack->m_pDefaultString, nLen, CUtlBuffer::TEXT_BUFFER | CUtlBuffer::READ_ONLY );
pAttribute->Unserialize( bufParse );
}
}
m_hTypeDictionary->AddEditorType( pEditorType );
}
//-----------------------------------------------------------------------------
// Sets the particle operator
//-----------------------------------------------------------------------------
void CDmeParticleFunction::UpdateAttributes( const DmxElementUnpackStructure_t *pUnpack )
{
// Delete all old attributes
CDmAttribute *pNext;
for( CDmAttribute *pAttr = FirstAttribute(); pAttr; pAttr = pNext )
{
pNext = pAttr->NextAttribute();
if ( pAttr->IsFlagSet( FATTRIB_EXTERNAL | FATTRIB_STANDARD ) )
continue;
RemoveAttributeByPtr( pAttr );
}
AddMissingFields( pUnpack );
}
//-----------------------------------------------------------------------------
// Marks a particle system as a new instance
// This is basically a workaround to prevent newly-copied particle functions
// from recompiling themselves a zillion times
//-----------------------------------------------------------------------------
void CDmeParticleFunction::MarkNewInstance()
{
m_bSkipNextResolve = true;
}
//-----------------------------------------------------------------------------
// Don't bother resolving during unserialization, the owning def will handle it
//-----------------------------------------------------------------------------
void CDmeParticleFunction::OnElementUnserialized()
{
BaseClass::OnElementUnserialized();
MarkNewInstance();
}
//-----------------------------------------------------------------------------
// Recompiles the particle system when a change occurs
//-----------------------------------------------------------------------------
void CDmeParticleFunction::Resolve()
{
BaseClass::Resolve();
if ( m_bSkipNextResolve )
{
m_bSkipNextResolve = false;
return;
}
for( CDmAttribute* pAttr = FirstAttribute(); pAttr; pAttr = pAttr->NextAttribute() )
{
if ( !pAttr->IsFlagSet( FATTRIB_DIRTY ) )
continue;
// Find all CDmeParticleSystemDefinitions referring to this function
DmAttributeReferenceIterator_t i = g_pDataModel->FirstAttributeReferencingElement( GetHandle() );
while ( i != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID )
{
CDmAttribute *pAttribute = g_pDataModel->GetAttribute( i );
// NOTE: This could cause the same particle system definition to recompile
// multiple times if it refers to the same function multiple times,
// but we don't expect that to happen, so we won't bother checking for it
CDmeParticleSystemDefinition *pDef = CastElement<CDmeParticleSystemDefinition>( pAttribute->GetOwner() );
if ( pDef && pDef->GetFileId() == GetFileId() )
{
pDef->RecompileParticleSystem();
}
i = g_pDataModel->NextAttributeReferencingElement( i );
}
break;
}
}
//-----------------------------------------------------------------------------
// Returns the editor type dictionary
//-----------------------------------------------------------------------------
CDmeEditorTypeDictionary* CDmeParticleFunction::GetEditorTypeDictionary()
{
return m_hTypeDictionary;
}
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY_INSTALL_EXPLICITLY( DmeParticleOperator, CDmeParticleOperator );
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
void CDmeParticleOperator::OnConstruction()
{
m_FunctionName.Init( this, "functionName" );
}
void CDmeParticleOperator::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Sets the particle operator
//-----------------------------------------------------------------------------
void CDmeParticleOperator::SetFunction( IParticleOperatorDefinition *pDefinition )
{
m_FunctionName = pDefinition->GetName();
const DmxElementUnpackStructure_t *pUnpack = pDefinition->GetUnpackStructure();
UpdateAttributes( pUnpack );
}
const char *CDmeParticleOperator::GetFunctionType() const
{
return m_FunctionName;
}
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY_INSTALL_EXPLICITLY( DmeParticleChild, CDmeParticleChild );
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
void CDmeParticleChild::OnConstruction()
{
m_Child.Init( this, "child", FATTRIB_NEVERCOPY );
}
void CDmeParticleChild::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Sets the particle system child
//-----------------------------------------------------------------------------
void CDmeParticleChild::SetChildParticleSystem( CDmeParticleSystemDefinition *pDef, IParticleOperatorDefinition *pDefinition )
{
// FIXME: Convert system name into a
m_Child = pDef;
const DmxElementUnpackStructure_t *pUnpack = pDefinition->GetUnpackStructure();
UpdateAttributes( pUnpack );
}
const char *CDmeParticleChild::GetFunctionType() const
{
const CDmeParticleSystemDefinition *pChild = m_Child;
return pChild ? pChild->GetName() : "";
}
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY_INSTALL_EXPLICITLY( DmeParticleSystemDefinition, CDmeParticleSystemDefinition );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeParticleSystemDefinition::OnConstruction()
{
m_ParticleFunction[FUNCTION_RENDERER].Init( this, "renderers" );
m_ParticleFunction[FUNCTION_OPERATOR].Init( this, "operators" );
m_ParticleFunction[FUNCTION_INITIALIZER].Init( this, "initializers" );
m_ParticleFunction[FUNCTION_EMITTER].Init( this, "emitters" );
m_ParticleFunction[FUNCTION_CHILDREN].Init( this, "children" );
m_ParticleFunction[FUNCTION_FORCEGENERATOR].Init( this, "forces" );
m_ParticleFunction[FUNCTION_CONSTRAINT].Init( this, "constraints" );
m_bPreventNameBasedLookup.Init( this, "preventNameBasedLookup" );
m_hTypeDictionary = CreateElement< CDmeEditorTypeDictionary >( "particleSystemDefinitionDict" );
CDmeEditorType *pEditorType = CreateElement< CDmeEditorType >( "DmeParticleSystemDefinition" );
const DmxElementUnpackStructure_t *pUnpack = g_pParticleSystemMgr->GetParticleSystemDefinitionUnpackStructure();
for ( ; pUnpack->m_pAttributeName; ++pUnpack )
{
CreateEditorAttributeInfo( pEditorType, pUnpack->m_pAttributeName, (const char *)pUnpack->m_pUserData );
CDmAttribute *pAttribute = AddAttribute( pUnpack->m_pAttributeName, pUnpack->m_AttributeType );
if ( pUnpack->m_pDefaultString )
{
int nLen = Q_strlen( pUnpack->m_pDefaultString );
CUtlBuffer bufParse( pUnpack->m_pDefaultString, nLen, CUtlBuffer::TEXT_BUFFER | CUtlBuffer::READ_ONLY );
pAttribute->Unserialize( bufParse );
}
}
m_hTypeDictionary->AddEditorType( pEditorType );
}
void CDmeParticleSystemDefinition::OnDestruction()
{
DestroyElement( m_hTypeDictionary, TD_DEEP );
}
//-----------------------------------------------------------------------------
// Returns the editor type dictionary
//-----------------------------------------------------------------------------
CDmeEditorTypeDictionary* CDmeParticleSystemDefinition::GetEditorTypeDictionary()
{
return m_hTypeDictionary;
}
//-----------------------------------------------------------------------------
// Remove obsolete attributes
//-----------------------------------------------------------------------------
static void RemoveObsoleteAttributes( CDmElement *pElement, const DmxElementUnpackStructure_t *pUnpack )
{
// Delete all obsolete attributes
CDmAttribute *pNext;
for( CDmAttribute *pAttr = pElement->FirstAttribute(); pAttr; pAttr = pNext )
{
pNext = pAttr->NextAttribute();
if ( pAttr->IsFlagSet( FATTRIB_EXTERNAL | FATTRIB_STANDARD ) )
continue;
bool bFound = false;
for ( const DmxElementUnpackStructure_t *pTrav = pUnpack; pTrav->m_pAttributeName; ++pTrav )
{
if ( !Q_stricmp( pTrav->m_pAttributeName, pAttr->GetName() ) )
{
bFound = true;
break;
}
}
if ( !bFound )
{
pElement->RemoveAttributeByPtr( pAttr );
}
}
}
//-----------------------------------------------------------------------------
// Used for automatic handling of backward compatability
//-----------------------------------------------------------------------------
void CDmeParticleSystemDefinition::OnElementUnserialized()
{
BaseClass::OnElementUnserialized();
RemoveObsoleteAttributes( this, g_pParticleSystemMgr->GetParticleSystemDefinitionUnpackStructure() );
// Add missing fields that are new
for ( int i = 0; i < PARTICLE_FUNCTION_COUNT; ++i )
{
ParticleFunctionType_t type = (ParticleFunctionType_t)i;
CUtlVector< IParticleOperatorDefinition *> &list = g_pParticleSystemMgr->GetAvailableParticleOperatorList( type );
int nAvailType = list.Count();
int nCount = GetParticleFunctionCount( type );
for ( int j = 0; j < nCount; ++j )
{
CDmeParticleFunction *pFunction = GetParticleFunction( type, j );
if ( i == FUNCTION_CHILDREN )
{
RemoveObsoleteAttributes( pFunction, list[0]->GetUnpackStructure() );
pFunction->AddMissingFields( list[0]->GetUnpackStructure() );
continue;
}
for ( int k = 0; k < nAvailType; ++k )
{
if ( Q_stricmp( pFunction->GetName(), list[k]->GetName() ) )
continue;
RemoveObsoleteAttributes( pFunction, list[k]->GetUnpackStructure() );
pFunction->AddMissingFields( list[k]->GetUnpackStructure() );
break;
}
}
}
}
//-----------------------------------------------------------------------------
// Check to see if any attributes changed
//-----------------------------------------------------------------------------
void CDmeParticleSystemDefinition::Resolve()
{
BaseClass::Resolve();
for( CDmAttribute* pAttr = FirstAttribute(); pAttr; pAttr = pAttr->NextAttribute() )
{
if ( pAttr->IsFlagSet( FATTRIB_DIRTY ) )
{
RecompileParticleSystem();
break;
}
}
}
//-----------------------------------------------------------------------------
// Add, remove
//-----------------------------------------------------------------------------
CDmeParticleFunction* CDmeParticleSystemDefinition::AddOperator( ParticleFunctionType_t type, const char *pFunctionName )
{
CUtlVector< IParticleOperatorDefinition *> &list = g_pParticleSystemMgr->GetAvailableParticleOperatorList( type );
int nCount = list.Count();
for ( int i = 0; i < nCount; ++i )
{
if ( Q_stricmp( pFunctionName, list[i]->GetName() ) )
continue;
CDmeParticleOperator *pFunction = CreateElement< CDmeParticleOperator >( pFunctionName, GetFileId() );
m_ParticleFunction[type].AddToTail( pFunction );
pFunction->SetFunction( list[i] );
return pFunction;
}
return NULL;
}
CDmeParticleFunction* CDmeParticleSystemDefinition::AddChild( CDmeParticleSystemDefinition *pChild )
{
Assert( pChild );
CUtlVector< IParticleOperatorDefinition *> &list = g_pParticleSystemMgr->GetAvailableParticleOperatorList( FUNCTION_CHILDREN );
Assert( list.Count() == 1 );
CDmeParticleChild *pFunction = CreateElement< CDmeParticleChild >( pChild->GetName(), GetFileId() );
m_ParticleFunction[FUNCTION_CHILDREN].AddToTail( pFunction );
pFunction->SetChildParticleSystem( pChild, list[0] );
return pFunction;
}
//-----------------------------------------------------------------------------
// Remove
void CDmeParticleSystemDefinition::RemoveFunction( ParticleFunctionType_t type, CDmeParticleFunction *pFunction )
{
int nIndex = FindFunction( type, pFunction );
RemoveFunction( type, nIndex );
}
void CDmeParticleSystemDefinition::RemoveFunction( ParticleFunctionType_t type, int nIndex )
{
if ( nIndex >= 0 )
{
m_ParticleFunction[type].Remove(nIndex);
}
}
//-----------------------------------------------------------------------------
// Find
//-----------------------------------------------------------------------------
int CDmeParticleSystemDefinition::FindFunction( ParticleFunctionType_t type, CDmeParticleFunction *pParticleFunction )
{
int nCount = m_ParticleFunction[type].Count();
for ( int i = 0; i < nCount; ++i )
{
if ( pParticleFunction == m_ParticleFunction[type][i] )
return i;
}
return -1;
}
int CDmeParticleSystemDefinition::FindFunction( ParticleFunctionType_t type, const char *pFunctionName )
{
int nCount = m_ParticleFunction[type].Count();
for ( int i = 0; i < nCount; ++i )
{
if ( !Q_stricmp( pFunctionName, m_ParticleFunction[type][i]->GetFunctionType() ) )
return i;
}
return -1;
}
//-----------------------------------------------------------------------------
// Iteration
//-----------------------------------------------------------------------------
int CDmeParticleSystemDefinition::GetParticleFunctionCount( ParticleFunctionType_t type ) const
{
return m_ParticleFunction[type].Count();
}
CDmeParticleFunction *CDmeParticleSystemDefinition::GetParticleFunction( ParticleFunctionType_t type, int nIndex )
{
return m_ParticleFunction[type][nIndex];
}
//-----------------------------------------------------------------------------
// Reordering
//-----------------------------------------------------------------------------
void CDmeParticleSystemDefinition::MoveFunctionUp( ParticleFunctionType_t type, CDmeParticleFunction *pElement )
{
int nIndex = FindFunction( type, pElement );
if ( nIndex > 0 )
{
m_ParticleFunction[type].Swap( nIndex, nIndex - 1 );
}
}
void CDmeParticleSystemDefinition::MoveFunctionDown( ParticleFunctionType_t type, CDmeParticleFunction *pElement )
{
int nIndex = FindFunction( type, pElement );
int nLastIndex = m_ParticleFunction[type].Count() - 1;
if ( nIndex >= 0 && nIndex < nLastIndex )
{
m_ParticleFunction[type].Swap( nIndex, nIndex + 1 );
}
}
//-----------------------------------------------------------------------------
// Marks a particle system as a new instance
// This is basically a workaround to prevent newly-copied particle functions
// from recompiling themselves a zillion times
//-----------------------------------------------------------------------------
void CDmeParticleSystemDefinition::MarkNewInstance()
{
for ( int i = 0; i < PARTICLE_FUNCTION_COUNT; ++i )
{
int nCount = m_ParticleFunction[i].Count();
for ( int j = 0; j < nCount; ++j )
{
m_ParticleFunction[i][j]->MarkNewInstance();
}
}
}
//-----------------------------------------------------------------------------
// Recompiles the particle system when a change occurs
//-----------------------------------------------------------------------------
void CDmeParticleSystemDefinition::RecompileParticleSystem()
{
const char *pFileFormat = "pcf";
const char *pEncoding = g_pDataModel->GetDefaultEncoding( pFileFormat );
int nFlags = g_pDataModel->IsEncodingBinary( pEncoding ) ? 0 : CUtlBuffer::TEXT_BUFFER;
CUtlBuffer buf( 0, 0, nFlags );
if ( g_pDataModel->Serialize( buf, pEncoding, pFileFormat, GetHandle() ) )
{
g_pParticleSystemMgr->ReadParticleConfigFile( buf, true, NULL );
}
}

View File

@ -0,0 +1,22 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmephonememapping.h"
#include "datamodel/dmelementfactoryhelper.h"
//-----------------------------------------------------------------------------
// CDmePhonemeMapping
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmePhonemeMapping, CDmePhonemeMapping );
void CDmePhonemeMapping::OnConstruction()
{
m_Preset.Init( this, "preset" );
m_Weight.InitAndSet( this, "weight", 1.0f );
}
void CDmePhonemeMapping::OnDestruction()
{
}

View File

@ -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 );
}

260
movieobjects/dmeshader.cpp Normal file
View File

@ -0,0 +1,260 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmeshader.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "movieobjects_interfaces.h"
#include "materialsystem/IShader.h"
#include "materialsystem/imaterialsystem.h"
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeShader, CDmeShader );
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
void CDmeShader::OnConstruction()
{
m_ShaderName.Init( this, "shaderName" );
m_ShaderName = "wireframe";
m_pShader = NULL;
}
void CDmeShader::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Shader name access
//-----------------------------------------------------------------------------
void CDmeShader::SetShaderName( const char *pShaderName )
{
m_ShaderName = pShaderName;
}
const char *CDmeShader::GetShaderName() const
{
return m_ShaderName;
}
//-----------------------------------------------------------------------------
// Finds a shader
//-----------------------------------------------------------------------------
IShader *CDmeShader::FindShader()
{
int nCount = MaterialSystem()->ShaderCount();
IShader **ppShaderList = (IShader**)_alloca( nCount * sizeof(IShader*) );
MaterialSystem()->GetShaders( 0, nCount, ppShaderList );
for ( int i = 0; i < nCount; ++i )
{
if ( !Q_stricmp( m_ShaderName, ppShaderList[i]->GetName() ) )
return ppShaderList[i];
}
return NULL;
}
//-----------------------------------------------------------------------------
// Remove all shader parameters that don't exist in the new shader
//-----------------------------------------------------------------------------
void CDmeShader::RemoveUnusedShaderParams( IShader *pShader )
{
IDmAttribute* pAttribute = FirstAttribute();
IDmAttribute* pNextAttribute = NULL;
for ( ; pAttribute; pAttribute = pNextAttribute )
{
pNextAttribute = pAttribute->NextAttribute();
// Don't remove name, type, or id
if ( pAttribute->IsFlagSet( FATTRIB_STANDARD ) )
continue;
const char *pShaderParam = pAttribute->GetName();
int nCount = pShader->GetNumParams();
int i;
for ( i = 0; i < nCount; ++i )
{
if ( !Q_stricmp( pShaderParam, pShader->GetParamName( i ) ) )
break;
}
// No match? Remove it!
if ( i == nCount )
{
RemoveAttributeByPtr( pAttribute );
}
}
}
//-----------------------------------------------------------------------------
// Add attribute for shader parameter
//-----------------------------------------------------------------------------
IDmAttribute* CDmeShader::AddAttributeForShaderParameter( IShader *pShader, int nIndex )
{
ShaderParamType_t paramType = pShader->GetParamType( nIndex );
const char *pParamName = pShader->GetParamName( nIndex );
IDmAttribute *pAttribute = NULL;
switch ( paramType )
{
case SHADER_PARAM_TYPE_INTEGER:
pAttribute = AddAttributeTyped<int>( pParamName );
break;
case SHADER_PARAM_TYPE_BOOL:
pAttribute = AddAttributeTyped<bool>( pParamName );
break;
case SHADER_PARAM_TYPE_FLOAT:
pAttribute = AddAttributeTyped<float>( pParamName );
break;
case SHADER_PARAM_TYPE_STRING:
pAttribute = AddAttributeTyped<CUtlString>( pParamName );
break;
case SHADER_PARAM_TYPE_COLOR:
pAttribute = AddAttributeTyped<Color>( pParamName );
break;
case SHADER_PARAM_TYPE_VEC2:
pAttribute = AddAttributeTyped<Vector2D>( pParamName );
break;
case SHADER_PARAM_TYPE_VEC3:
pAttribute = AddAttributeTyped<Vector>( pParamName );
break;
case SHADER_PARAM_TYPE_VEC4:
pAttribute = AddAttributeTyped<Vector4D>( pParamName );
break;
case SHADER_PARAM_TYPE_FOURCC:
Assert( 0 );
break;
case SHADER_PARAM_TYPE_MATRIX:
pAttribute = AddAttributeTyped<VMatrix>( pParamName );
break;
case SHADER_PARAM_TYPE_TEXTURE:
pAttribute = AddAttributeTyped<CDmElementRef>( pParamName );
break;
case SHADER_PARAM_TYPE_MATERIAL:
pAttribute = AddAttributeTyped<CDmElementRef>( pParamName );
break;
default:
break;
}
return pAttribute;
}
//-----------------------------------------------------------------------------
// Add all shader parameters that don't currently exist
//-----------------------------------------------------------------------------
void CDmeShader::AddNewShaderParams( IShader *pShader )
{
int nCount = pShader->GetNumParams();
int i;
for ( i = 0; i < nCount; ++i )
{
const char *pParamName = pShader->GetParamName( i );
IDmAttribute* pAttribute = NULL;
for ( pAttribute = FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
{
// Don't remove name, type, or id
if ( pAttribute->IsFlagSet( FATTRIB_STANDARD ) )
continue;
const char *pAttributeName = pAttribute->GetName();
if ( !Q_stricmp( pAttributeName, pParamName ) )
break;
}
// No match? Add it!
if ( pAttribute != NULL )
continue;
pAttribute = AddAttributeForShaderParameter( pShader, i );
if ( pAttribute )
{
const char *pDefault = pShader->GetParamDefault( i );
SetAttributeValueFromString( pParamName, pDefault );
}
}
}
//-----------------------------------------------------------------------------
// resolve
//-----------------------------------------------------------------------------
void CDmeShader::Resolve()
{
if ( !m_ShaderName.IsDirty() || !MaterialSystem() )
return;
// First, find the shader
IShader *pShader = FindShader();
// Remove all shader parameters that don't exist in the new shader
RemoveUnusedShaderParams( pShader );
// Add all shader parameters that don't currently exist
AddNewShaderParams( pShader );
}
//-----------------------------------------------------------------------------
// Returns a procedural material to be associated with this shader
//-----------------------------------------------------------------------------
void CDmeShader::CreateMaterial( const char *pMaterialName )
{
KeyValues *pVMTKeyValues = new KeyValues( GetShaderName() );
IDmAttribute* pAttribute = FirstAttribute();
IDmAttribute* pNextAttribute = NULL;
for ( ; pAttribute; pAttribute = pNextAttribute )
{
pNextAttribute = pAttribute->NextAttribute();
// Don't remove name, type, or id
if ( pAttribute->IsFlagSet( FATTRIB_STANDARD ) )
continue;
const char *pShaderParam = pAttribute->GetName();
int nCount = pShader->GetNumParams();
int i;
for ( i = 0; i < nCount; ++i )
{
if ( !Q_stricmp( pShaderParam, pShader->GetParamName( i ) ) )
break;
}
// No match? Remove it!
if ( i == nCount )
{
RemoveAttributeByPtr( pAttribute );
}
}
pVMTKeyValues->SetInt( "$model", 1 );
pVMTKeyValues->SetFloat( "$decalscale", 0.05f );
pVMTKeyValues->SetString( "$basetexture", "error" );
return MaterialSystem()->CreateMaterial( pMaterialName, pVMTKeyValues );
}

115
movieobjects/dmeshape.cpp Normal file
View File

@ -0,0 +1,115 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmeshape.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "movieobjects_interfaces.h"
#include "movieobjects/dmedag.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( DmeShape, CDmeShape );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeShape::OnConstruction()
{
m_visible.InitAndSet( this, "visible", true );
}
void CDmeShape::OnDestruction()
{
}
void CDmeShape::Draw( const matrix3x4_t &shapeToWorld, CDmeDrawSettings *pDrawSettings /* = NULL */ )
{
Assert( 0 );
}
//-----------------------------------------------------------------------------
// The default bounding sphere is empty at the origin
//-----------------------------------------------------------------------------
void CDmeShape::GetBoundingSphere( Vector &c, float &r ) const
{
c.Zero();
r = 0.0f;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int CDmeShape::GetParentCount() const
{
int nReferringDags = 0;
DmAttributeReferenceIterator_t i = g_pDataModel->FirstAttributeReferencingElement( GetHandle() );
while ( i != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID )
{
CDmAttribute *pAttribute = g_pDataModel->GetAttribute( i );
CDmeDag *pDag = CastElement< CDmeDag >( pAttribute->GetOwner() );
const static UtlSymId_t symShape = g_pDataModel->GetSymbol( "shape" );
if ( pDag && pAttribute->GetNameSymbol() == symShape && pDag->GetFileId() == GetFileId() )
{
++nReferringDags;
}
i = g_pDataModel->NextAttributeReferencingElement( i );
}
return nReferringDags;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
CDmeDag *CDmeShape::GetParent( int nParentIndex /*= 0 */ ) const
{
int nReferringDags = 0;
DmAttributeReferenceIterator_t i = g_pDataModel->FirstAttributeReferencingElement( GetHandle() );
while ( i != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID )
{
CDmAttribute *pAttribute = g_pDataModel->GetAttribute( i );
CDmeDag *pDag = CastElement< CDmeDag >( pAttribute->GetOwner() );
const static UtlSymId_t symShape = g_pDataModel->GetSymbol( "shape" );
if ( pDag && pAttribute->GetNameSymbol() == symShape && pDag->GetFileId() == GetFileId() )
{
if ( nReferringDags == nParentIndex )
return pDag;
++nReferringDags;
}
i = g_pDataModel->NextAttributeReferencingElement( i );
}
return NULL;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CDmeShape::GetShapeToWorldTransform( matrix3x4_t &mat, int nParentIndex /*= 0 */ ) const
{
CDmeDag *pDag = GetParent( nParentIndex );
if ( pDag )
{
pDag->GetShapeToWorldTransform( mat );
}
else
{
SetIdentityMatrix( mat );
}
}

93
movieobjects/dmesound.cpp Normal file
View File

@ -0,0 +1,93 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmesound.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "movieobjects_interfaces.h"
#include "tier2/tier2.h"
#include "filesystem.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( DmeSound, CDmeSound );
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
void CDmeSound::OnConstruction()
{
m_SoundName.Init( this, "soundname" );
m_GameSoundName.Init( this, "gameSoundName" );
}
void CDmeSound::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// For sounds that are relative paths (instead of GameSound names), get full path
//-----------------------------------------------------------------------------
bool CDmeSound::ComputeSoundFullPath( char *pBuf, int nBufLen )
{
if ( !m_SoundName[0] )
{
pBuf[0] = 0;
return false;
}
// Compute the full path of the sound
char pRelativePath[MAX_PATH];
Q_snprintf( pRelativePath, sizeof(pRelativePath), "sound\\%s", m_SoundName.Get() );
return g_pFullFileSystem->RelativePathToFullPath( pRelativePath, "GAME", pBuf, nBufLen ) != NULL;
}
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeGameSound, CDmeGameSound );
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
void CDmeGameSound::OnConstruction()
{
m_Volume .Init( this, "volume" );
m_Level .Init( this, "level" );
m_Pitch .Init( this, "pitch" );
m_IsStatic .Init( this, "static" );
m_Channel .Init( this, "channel" );
m_Flags .Init( this, "flags" );
// m_Source .Init( this, "source" );
// m_FollowSource.Init( this, "followsource" );
m_Origin .Init( this, "origin" );
m_Direction .Init( this, "direction" );
}
void CDmeGameSound::OnDestruction()
{
}
CDmElement *CDmeGameSound::FindOrAddPhonemeExtractionSettings()
{
if ( HasAttribute( "PhonemeExtractionSettings" ) )
return GetValueElement< CDmElement >( "PhonemeExtractionSettings" );
CDmElement *settings = CreateElement< CDmElement >( "PhonemeExtractionSettings", GetFileId() );
if ( !settings )
return NULL;
SetValue( "PhonemeExtractionSettings", settings );
return settings;
}

1757
movieobjects/dmetestmesh.cpp Normal file

File diff suppressed because it is too large Load Diff

290
movieobjects/dmetexture.cpp Normal file
View File

@ -0,0 +1,290 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmetexture.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "movieobjects_interfaces.h"
#include "materialsystem/imaterial.h"
#include "materialsystem/imaterialsystem.h"
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeBaseTexture, CDmeBaseTexture );
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
void CDmeBaseTexture::OnConstruction()
{
m_pVTFTexture = CreateVTFTexture();
m_bClampS.Init( this, "clampS" );
m_bClampT.Init( this, "clampT" );
m_bClampU.Init( this, "clampU" );
m_bNoLod.Init( this, "noMipmapLOD" );
m_bNiceFiltered.Init( this, "niceFiltered" );
m_bNormalMap.Init( this, "normalMap" );
m_flBumpScale.Init( this, "bumpScale" );
m_nCompressType.Init( this, "compressType" );
m_nFilterType.Init( this, "filterType" );
m_nMipmapType.Init( this, "mipmapType" );
}
void CDmeBaseTexture::OnDestruction()
{
if ( m_pVTFTexture )
{
DestroyVTFTexture( m_pVTFTexture );
m_pVTFTexture = NULL;
}
}
//-----------------------------------------------------------------------------
// accessor for cached ITexture
//-----------------------------------------------------------------------------
ITexture *CDmeBaseTexture::GetCachedTexture()
{
return m_Texture;
}
//-----------------------------------------------------------------------------
// Computes texture flags
//-----------------------------------------------------------------------------
int CDmeBaseTexture::CalcTextureFlags( int nDepth ) const
{
int nFlags = 0;
if ( m_bClampS )
{
nFlags |= TEXTUREFLAGS_CLAMPS;
}
if ( m_bClampT )
{
nFlags |= TEXTUREFLAGS_CLAMPT;
}
if ( m_bClampU )
{
nFlags |= TEXTUREFLAGS_CLAMPU;
}
if ( m_bNoLod )
{
nFlags |= TEXTUREFLAGS_NOLOD;
}
if ( m_bNiceFiltered )
{
nFlags |= TEXTUREFLAGS_NICEFILTERED;
}
if ( m_bNormalMap )
{
nFlags |= TEXTUREFLAGS_NORMAL;
}
if ( m_bNormalMap )
{
nFlags |= TEXTUREFLAGS_NORMAL;
}
if ( m_bNoDebugOverride )
{
nFlags |= TEXTUREFLAGS_NODEBUGOVERRIDE;
}
switch ( m_nCompressType )
{
case DMETEXTURE_COMPRESS_DEFAULT:
case DMETEXTURE_COMPRESS_DXT1:
break;
case DMETEXTURE_COMPRESS_NONE:
nFlags |= TEXTUREFLAGS_NOCOMPRESS;
break;
case DMETEXTURE_COMPRESS_DXT5:
nFlags |= TEXTUREFLAGS_HINT_DXT5;
break;
}
switch ( m_nFilterType )
{
case DMETEXTURE_FILTER_DEFAULT:
case DMETEXTURE_FILTER_BILINEAR:
break;
case DMETEXTURE_FILTER_ANISOTROPIC:
nFlags |= TEXTUREFLAGS_ANISOTROPIC;
break;
case DMETEXTURE_FILTER_TRILINEAR:
nFlags |= TEXTUREFLAGS_TRILINEAR;
break;
case DMETEXTURE_FILTER_POINT:
nFlags |= TEXTUREFLAGS_POINTSAMPLE;
break;
}
switch ( m_nMipmapType )
{
case DMETEXTURE_MIPMAP_DEFAULT:
case DMETEXTURE_MIPMAP_ALL_LEVELS:
break;
case DMETEXTURE_MIPMAP_NONE:
nFlags |= TEXTUREFLAGS_NOMIP;
break;
}
if ( nDepth > 1 )
{
// FIXME: Volume textures don't currently support DXT compression
nFlags &= ~TEXTUREFLAGS_HINT_DXT5;
nFlags |= TEXTUREFLAGS_NOCOMPRESS;
// FIXME: Volume textures don't currently support NICE filtering
nFlags &= ~TEXTUREFLAGS_NICEFILTERED;
}
return nFlags;
}
//-----------------------------------------------------------------------------
// Computes the desired texture format based on flags
//-----------------------------------------------------------------------------
ImageFormat CDmeBaseTexture::ComputeDesiredImageFormat( ImageFormat srcFormat, int nWidth, int nHeight, int nDepth, int nFlags )
{
// HDRFIXME: Need to figure out what format to use here.
if ( srcFormat == IMAGE_FORMAT_RGB323232F )
return IMAGE_FORMAT_RGBA16161616F;
/*
if( bDUDVTarget)
{
if ( bCopyAlphaToLuminance && ( nFlags & ( TEXTUREFLAGS_ONEBITALPHA | TEXTUREFLAGS_EIGHTBITALPHA ) ) )
return IMAGE_FORMAT_UVLX8888;
return IMAGE_FORMAT_UV88;
}
*/
// can't compress textures that are smaller than 4x4
if ( (nFlags & TEXTUREFLAGS_NOCOMPRESS) || (nFlags & TEXTUREFLAGS_PROCEDURAL) ||
( nWidth < 4 ) || ( nHeight < 4 ) || ( nDepth > 1 ) )
{
if ( nFlags & ( TEXTUREFLAGS_ONEBITALPHA | TEXTUREFLAGS_EIGHTBITALPHA ) )
return IMAGE_FORMAT_BGRA8888;
return IMAGE_FORMAT_BGR888;
}
if( nFlags & TEXTUREFLAGS_HINT_DXT5 )
return IMAGE_FORMAT_DXT5;
// compressed with alpha blending
if ( nFlags & TEXTUREFLAGS_EIGHTBITALPHA )
return IMAGE_FORMAT_DXT5;
if ( nFlags & TEXTUREFLAGS_ONEBITALPHA )
return IMAGE_FORMAT_DXT5; // IMAGE_FORMAT_DXT1_ONEBITALPHA
return IMAGE_FORMAT_DXT1;
}
//-----------------------------------------------------------------------------
//
// Normal texture
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeTexture, CDmeTexture );
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
void CDmeTexture::OnConstruction()
{
m_Images.Init( this, "images" );
}
void CDmeTexture::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Build a VTF representing the
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// resolve
//-----------------------------------------------------------------------------
void CDmeTexture::Resolve()
{
// FIXME: Could change this to not shutdown if only the bits have changed
m_Texture.Shutdown();
int nFrameCount = m_Images.Count();
if ( nFrameCount == 0 )
return;
// Use the size of the 0th image
CDmeImage *pImage = m_Images[0];
int nWidth = pImage->m_Width;
int nHeight = pImage->m_Height;
int nDepth = pImage->m_Depth;
ImageFormat srcFormat = pImage->Format();
// FIXME: How should this work exactly?
int nFlags = CalcTextureFlags( nDepth );
m_pVTFTexture->Init( nWidth, nHeight, nDepth, srcFormat, nFlags, nFrameCount );
ImageFormat format = ComputeDesiredImageFormat( pImage->Format(), nWidth, nHeight, nDepth, nFlags );
// m_Texture.InitProceduralTexture( GetName(), "DmeTexture", nWidth, nHeight, nDepth, nFrameCount, format, nFlags );
// m_Texture->SetTextureRegenerator( this );
// Fill in the texture bits
}
/*
//-----------------------------------------------------------------------------
// Fill in the texture bits
//-----------------------------------------------------------------------------
void CDmeTexture::RegenerateTextureBits( ITexture *pTexture, IVTFTexture *pVTFTexture, Rect_t *pRect )
{
}
*/
//-----------------------------------------------------------------------------
//
// Cube texture
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeCubeTexture, CDmeCubeTexture );
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
void CDmeCubeTexture::OnConstruction()
{
m_ImagesPosX.Init( this, "imagesPosX" );
m_ImagesNegX.Init( this, "imagesNegX" );
m_ImagesPosY.Init( this, "imagesPosY" );
m_ImagesNegY.Init( this, "imagesNegY" );
m_ImagesPosZ.Init( this, "imagesPosZ" );
m_ImagesNegZ.Init( this, "imagesNegZ" );
}
void CDmeCubeTexture::OnDestruction()
{
}

View File

@ -0,0 +1,95 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmetimeframe.h"
#include "tier0/dbg.h"
#include "datamodel/dmelementfactoryhelper.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Class factory
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeTimeFrame, CDmeTimeFrame );
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
void CDmeTimeFrame::OnConstruction()
{
m_Start .InitAndSet( this, "startTime", 0, FATTRIB_HAS_CALLBACK );
m_Duration.InitAndSet( this, "durationTime", 0, FATTRIB_HAS_CALLBACK );
m_Offset .InitAndSet( this, "offsetTime", 0 );
m_Scale .InitAndSet( this, "scale", 1.0f );
}
void CDmeTimeFrame::OnDestruction()
{
}
void CDmeTimeFrame::OnAttributeChanged( CDmAttribute *pAttribute )
{
BaseClass::OnAttributeChanged( pAttribute );
// notify parent clip that the time has changed
if ( pAttribute == m_Start.GetAttribute() || pAttribute == m_Duration.GetAttribute() )
{
InvokeOnAttributeChangedOnReferrers( GetHandle(), pAttribute );
}
}
void CDmeTimeFrame::SetEndTime( DmeTime_t endTime, bool bChangeDuration )
{
if ( bChangeDuration )
{
m_Duration = endTime.GetTenthsOfMS() - m_Start;
}
else
{
m_Start = endTime.GetTenthsOfMS() - m_Duration;
}
}
void CDmeTimeFrame::SetTimeScale( float flScale, DmeTime_t scaleCenter, bool bChangeDuration )
{
#ifdef _DEBUG
DmeTime_t preCenterTime = ToChildMediaTime( scaleCenter, false );
#endif
float ratio = m_Scale / flScale;
int t = scaleCenter.GetTenthsOfMS() - m_Start;
if ( bChangeDuration )
{
int newDuration = int( m_Duration * ratio );
if ( scaleCenter.GetTenthsOfMS() != m_Start )
{
int newStart = int( ( m_Start - scaleCenter.GetTenthsOfMS() ) * ratio + scaleCenter.GetTenthsOfMS() );
SetStartTime( DmeTime_t( newStart ) );
}
int newStart = m_Start;
int newOffset = int( ( t + m_Offset ) * ratio + newStart - scaleCenter.GetTenthsOfMS() );
SetTimeOffset( DmeTime_t( newOffset ) );
SetDuration( DmeTime_t( newDuration ) );
}
else
{
int newOffset = int( ( t + m_Offset ) * ratio - t );
SetTimeOffset( DmeTime_t( newOffset ) );
}
SetTimeScale( flScale );
#ifdef _DEBUG
DmeTime_t postCenterTime = ToChildMediaTime( scaleCenter, false );
Assert( abs( preCenterTime - postCenterTime ) <= DMETIME_MINDELTA );
#endif
}

View File

@ -0,0 +1,336 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
#include "movieobjects/dmetimeselection.h"
#include "interpolatortypes.h"
#include "datamodel/dmelementfactoryhelper.h"
// #include "dme_controls/RecordingState.h"
IMPLEMENT_ELEMENT_FACTORY( DmeTimeSelection, CDmeTimeSelection );
void CDmeTimeSelection::OnConstruction()
{
m_bEnabled.InitAndSet( this, "enabled", false );
m_bRelative.InitAndSet( this, "relative", false );
DmeTime_t one( 1.0f );
m_falloff[ 0 ].InitAndSet( this, "falloff_left", -one.GetTenthsOfMS() );
m_falloff[ 1 ].InitAndSet( this, "falloff_right", one.GetTenthsOfMS() );
m_hold[ 0 ].Init( this, "hold_left" );
m_hold[ 1 ].Init( this, "hold_right" );
m_nFalloffInterpolatorType[ 0 ].InitAndSet( this, "interpolator_left", INTERPOLATE_LINEAR_INTERP );
m_nFalloffInterpolatorType[ 1 ].InitAndSet( this, "interpolator_right", INTERPOLATE_LINEAR_INTERP );
m_threshold.InitAndSet( this, "threshold", 0.0005f );
m_nRecordingState.InitAndSet( this, "recordingstate", 3 /*AS_PLAYBACK : HACK THIS SHOULD MOVE TO A PUBLIC HEADER*/ );
}
void CDmeTimeSelection::OnDestruction()
{
}
static int g_InterpolatorTypes[] =
{
INTERPOLATE_LINEAR_INTERP,
INTERPOLATE_EASE_IN,
INTERPOLATE_EASE_OUT,
INTERPOLATE_EASE_INOUT,
};
float CDmeTimeSelection::AdjustFactorForInterpolatorType( float factor, int side )
{
Vector points[ 4 ];
points[ 0 ].Init();
points[ 1 ].Init( 0.0, 0.0, 0.0f );
points[ 2 ].Init( 1.0f, 1.0f, 0.0f );
points[ 3 ].Init();
Vector out;
Interpolator_CurveInterpolate
(
GetFalloffInterpolatorType( side ),
points[ 0 ], // unused
points[ 1 ],
points[ 2 ],
points[ 3 ], // unused
factor,
out
);
return out.y; // clamp( out.y, 0.0f, 1.0f );
}
//-----------------------------------------------------------------------------
// per-type averaging methods
//-----------------------------------------------------------------------------
float CDmeTimeSelection::GetAmountForTime( DmeTime_t t, DmeTime_t curtime )
{
Assert( IsEnabled() );
float minfrac = 0.0f;
// FIXME, this is slow, we should cache this maybe?
DmeTime_t times[ 4 ];
times[ 0 ] = GetAbsFalloff( curtime, 0 );
times[ 1 ] = GetAbsHold( curtime, 0 );
times[ 2 ] = GetAbsHold( curtime, 1 );
times[ 3 ] = GetAbsFalloff( curtime, 1 );
Vector points[ 4 ];
points[ 0 ].Init();
points[ 1 ].Init( 0.0, 0.0, 0.0f );
points[ 2 ].Init( 1.0f, 1.0f, 0.0f );
points[ 3 ].Init();
if ( t >= times[ 0 ] && t < times[ 1 ] )
{
float f = GetFractionOfTimeBetween( t, times[ 0 ], times[ 1 ], true );
Vector out;
Interpolator_CurveInterpolate
(
GetFalloffInterpolatorType( 0 ),
points[ 0 ], // unused
points[ 1 ],
points[ 2 ],
points[ 3 ], // unused
f,
out
);
return clamp( out.y, minfrac, 1.0f );
}
if ( t >= times[ 1 ] && t <= times[ 2 ] )
{
return 1.0f;
}
if ( t > times[ 2 ] && t <= times[ 3 ] )
{
float f = 1.0f - GetFractionOfTimeBetween( t, times[ 2 ], times[ 3 ], true );
Vector out;
Interpolator_CurveInterpolate
(
GetFalloffInterpolatorType( 1 ),
points[ 0 ], // unused
points[ 1 ],
points[ 2 ],
points[ 3 ], // unused
f,
out
);
return clamp( out.y, minfrac, 1.0f );
}
return minfrac;
}
void CDmeTimeSelection::GetAlphaForTime( DmeTime_t t, DmeTime_t curtime, byte& alpha )
{
Assert( IsEnabled() );
byte minAlpha = 31;
// FIXME, this is slow, we should cache this maybe?
DmeTime_t times[ 4 ];
times[ 0 ] = GetAbsFalloff( curtime, 0 );
times[ 1 ] = GetAbsHold( curtime, 0 );
times[ 2 ] = GetAbsHold( curtime, 1 );
times[ 3 ] = GetAbsFalloff( curtime, 1 );
DmeTime_t dt1, dt2;
dt1 = times[ 1 ] - times[ 0 ];
dt2 = times[ 3 ] - times[ 2 ];
if ( dt1 > DmeTime_t( 0 ) &&
t >= times[ 0 ] && t < times[ 1 ] )
{
float frac = GetFractionOfTime( t - times[ 0 ], dt1, false );
alpha = clamp( alpha * frac, minAlpha, 255 );
return;
}
if ( dt2 > DmeTime_t( 0 ) &&
t > times[ 2 ] && t <= times[ 3 ] )
{
float frac = GetFractionOfTime( times[ 3 ] - t, dt2, false );
alpha = clamp( alpha * frac, minAlpha, 255 );
return;
}
if ( t < times[ 0 ] )
alpha = minAlpha;
else if ( t > times[ 3 ] )
alpha = minAlpha;
}
int CDmeTimeSelection::GetFalloffInterpolatorType( int side )
{
return m_nFalloffInterpolatorType[ side ];
}
void CDmeTimeSelection::SetFalloffInterpolatorType( int side, int interpolatorType )
{
m_nFalloffInterpolatorType[ side ] = interpolatorType;
}
bool CDmeTimeSelection::IsEnabled() const
{
return m_bEnabled;
}
void CDmeTimeSelection::SetEnabled( bool state )
{
m_bEnabled = state;
}
bool CDmeTimeSelection::IsRelative() const
{
return m_bRelative;
}
void CDmeTimeSelection::SetRelative( DmeTime_t time, bool state )
{
bool changed = m_bRelative != state;
m_bRelative = state;
if ( changed )
{
if ( state )
ConvertToRelative( time );
else
ConvertToAbsolute( time );
}
}
DmeTime_t CDmeTimeSelection::GetAbsFalloff( DmeTime_t time, int side )
{
if ( m_bRelative )
{
return DmeTime_t( m_falloff[ side ] ) + time;
}
return DmeTime_t( m_falloff[ side ] );
}
DmeTime_t CDmeTimeSelection::GetAbsHold( DmeTime_t time, int side )
{
if ( m_bRelative )
{
return DmeTime_t( m_hold[ side ] ) + time;
}
return DmeTime_t( m_hold[ side ] );
}
DmeTime_t CDmeTimeSelection::GetRelativeFalloff( DmeTime_t time, int side )
{
if ( m_bRelative )
{
return DmeTime_t( m_falloff[ side ] );
}
return DmeTime_t( m_falloff[ side ] ) - time;
}
DmeTime_t CDmeTimeSelection::GetRelativeHold( DmeTime_t time, int side )
{
if ( m_bRelative )
{
return DmeTime_t( m_hold[ side ] );
}
return DmeTime_t( m_hold[ side ] ) - time;
}
void CDmeTimeSelection::ConvertToRelative( DmeTime_t time )
{
m_falloff[ 0 ] -= time.GetTenthsOfMS();
m_falloff[ 1 ] -= time.GetTenthsOfMS();
m_hold[ 0 ] -= time.GetTenthsOfMS();
m_hold[ 1 ] -= time.GetTenthsOfMS();
}
void CDmeTimeSelection::ConvertToAbsolute( DmeTime_t time )
{
m_falloff[ 0 ] += time.GetTenthsOfMS();
m_falloff[ 1 ] += time.GetTenthsOfMS();
m_hold[ 0 ] += time.GetTenthsOfMS();
m_hold[ 1 ] += time.GetTenthsOfMS();
}
void CDmeTimeSelection::SetAbsFalloff( DmeTime_t time, int side, DmeTime_t absfallofftime )
{
DmeTime_t newTime;
if ( m_bRelative )
{
newTime = absfallofftime - time;
}
else
{
newTime = absfallofftime;
}
m_falloff[ side ] = newTime.GetTenthsOfMS();
}
void CDmeTimeSelection::SetAbsHold( DmeTime_t time, int side, DmeTime_t absholdtime )
{
DmeTime_t newTime;
if ( m_bRelative )
{
newTime = absholdtime - time;
}
else
{
newTime = absholdtime;
}
m_hold[ side ] = newTime.GetTenthsOfMS();
}
void CDmeTimeSelection::CopyFrom( const CDmeTimeSelection& src )
{
m_bEnabled = src.m_bEnabled;
m_bRelative = src.m_bRelative;
m_threshold = src.m_threshold;
for ( int i = 0 ; i < 2; ++i )
{
m_falloff[ i ] = src.m_falloff[ i ];
m_hold[ i ] = src.m_hold[ i ];
m_nFalloffInterpolatorType[ i ] = src.m_nFalloffInterpolatorType[ i ];
}
m_nRecordingState = src.m_nRecordingState;
}
void CDmeTimeSelection::GetCurrent( DmeTime_t pTimes[TS_TIME_COUNT] )
{
pTimes[TS_LEFT_FALLOFF].SetTenthsOfMS( m_falloff[ 0 ] );
pTimes[TS_LEFT_HOLD].SetTenthsOfMS( m_hold[ 0 ] );
pTimes[TS_RIGHT_HOLD].SetTenthsOfMS( m_hold[ 1 ] );
pTimes[TS_RIGHT_FALLOFF].SetTenthsOfMS( m_falloff[ 1 ] );
}
void CDmeTimeSelection::SetCurrent( DmeTime_t* pTimes )
{
m_falloff[ 0 ] = pTimes[ TS_LEFT_FALLOFF ].GetTenthsOfMS();
m_hold[ 0 ] = pTimes[ TS_LEFT_HOLD ].GetTenthsOfMS();
m_hold[ 1 ] = pTimes[ TS_RIGHT_HOLD ].GetTenthsOfMS();
m_falloff[ 1 ] = pTimes[ TS_RIGHT_FALLOFF ].GetTenthsOfMS();
}
float CDmeTimeSelection::GetThreshold()
{
return m_threshold;
}
void CDmeTimeSelection::SetRecordingState( RecordingState_t state )
{
m_nRecordingState = ( int )state;
}
RecordingState_t CDmeTimeSelection::GetRecordingState() const
{
return ( RecordingState_t )m_nRecordingState.Get();
}

818
movieobjects/dmetrack.cpp Normal file
View File

@ -0,0 +1,818 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmetrack.h"
#include "tier0/dbg.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "movieobjects/dmeclip.h"
#include "movieobjects/dmetrackgroup.h"
#include "movieobjects_interfaces.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// The solo track
//-----------------------------------------------------------------------------
DmElementHandle_t CDmeTrack::m_hSoloTrack[ DMECLIP_TYPE_COUNT ] =
{
DMELEMENT_HANDLE_INVALID,
DMELEMENT_HANDLE_INVALID,
DMELEMENT_HANDLE_INVALID,
DMELEMENT_HANDLE_INVALID,
};
//-----------------------------------------------------------------------------
// CDmeTrack - common container class for clip objects
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeTrack, CDmeTrack );
void CDmeTrack::OnConstruction()
{
m_hOwner = DMELEMENT_HANDLE_INVALID;
m_Flags.ClearAllFlags();
m_Clips.Init( this, "children" );
m_Collapsed.InitAndSet( this, "collapsed", true );
m_Mute.InitAndSet( this, "mute", false );
m_Synched.InitAndSet( this, "synched", true );
m_ClipType.InitAndSet( this, "clipType", DMECLIP_UNKNOWN, FATTRIB_HAS_CALLBACK | FATTRIB_HAS_PRE_CALLBACK );
m_Volume.InitAndSet( this, "volume", 1.0 );
}
void CDmeTrack::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Methods of IDmElement
//-----------------------------------------------------------------------------
void CDmeTrack::OnAttributeChanged( CDmAttribute *pAttribute )
{
BaseClass::OnAttributeChanged( pAttribute );
// Attach callbacks to detected sorted conditions if we're a film clip
if ( pAttribute == m_ClipType.GetAttribute() )
{
if ( m_ClipType == DMECLIP_FILM )
{
m_Flags.ClearFlag( IS_SORTED );
}
return;
}
// This gets called when start/end time of children change, or if the array changes
// This is a hack, since any OnAttributeChanged call that gets chained here from another element will trigger this
// At some point, we'll probably have to start sending more data through OnAttributeChanged, (like an event string or chain path)
// or perhaps add a new callback OnElementChanged() with this data
if ( pAttribute == m_Clips.GetAttribute() || ( pAttribute->GetOwner() != this ) )
{
if ( !m_Flags.IsFlagSet( SUPPRESS_DIRTY_ORDERING ) )
{
m_Flags.ClearFlag( IS_SORTED );
}
return;
}
}
//-----------------------------------------------------------------------------
// Clip type
//-----------------------------------------------------------------------------
DmeClipType_t CDmeTrack::GetClipType() const
{
return (DmeClipType_t)m_ClipType.Get();
}
void CDmeTrack::SetClipType( DmeClipType_t type )
{
m_ClipType = type;
}
void CDmeTrack::SetCollapsed( bool state )
{
m_Collapsed = state;
}
bool CDmeTrack::IsCollapsed() const
{
return m_Collapsed.Get();
}
void CDmeTrack::SetMute( bool state )
{
m_Mute = state;
}
//-----------------------------------------------------------------------------
// Volume
//-----------------------------------------------------------------------------
void CDmeTrack::SetVolume( float state )
{
m_Volume = state;
}
float CDmeTrack::GetVolume() const
{
return m_Volume.Get();
}
// Is this track synched to the film track?
void CDmeTrack::SetSynched( bool bState )
{
m_Synched = bState;
}
bool CDmeTrack::IsSynched() const
{
return m_Synched;
}
bool CDmeTrack::IsMute( bool bCheckSoloing ) const
{
// if we're muted, don't play regardless of whether we're solo
CDmeTrack *pSoloTrack = bCheckSoloing ? GetSoloTrack() : NULL;
return m_Mute.Get() || ( pSoloTrack != this && pSoloTrack != NULL );
}
int CDmeTrack::GetClipCount() const
{
return m_Clips.Count();
}
CDmeClip *CDmeTrack::GetClip( int i ) const
{
return m_Clips[ i ];
}
const CUtlVector< DmElementHandle_t > &CDmeTrack::GetClips( ) const
{
return m_Clips.Get();
}
void CDmeTrack::AddClip( CDmeClip *clip )
{
if ( clip->GetClipType() == GetClipType() )
{
// FIXME: In the case of a non-overlapped track,
// we could optimize this to insert the clip in sorted order,
// then fix overlaps (fixing overlaps requires a sorted list)
Assert( FindClip( clip ) < 0 );
m_Clips.AddToTail( clip );
}
}
void CDmeTrack::RemoveClip( int i )
{
// NOTE: Removal shouldn't cause sort order or fixup to become invalid
CSuppressAutoFixup suppress( this, SUPPRESS_OVERLAP_FIXUP | SUPPRESS_DIRTY_ORDERING );
m_Clips.Remove( i );
}
bool CDmeTrack::RemoveClip( CDmeClip *clip )
{
Assert( clip->GetClipType() == GetClipType() );
int i = FindClip( clip );
if ( i != -1 )
{
RemoveClip( i );
return true;
}
return false;
}
void CDmeTrack::RemoveAllClips()
{
CSuppressAutoFixup suppress( this, SUPPRESS_OVERLAP_FIXUP | SUPPRESS_DIRTY_ORDERING );
m_Clips.RemoveAll();
}
//-----------------------------------------------------------------------------
// Returns the solo track, if any
//-----------------------------------------------------------------------------
CDmeTrack *CDmeTrack::GetSoloTrack( DmeClipType_t clipType )
{
return GetElement< CDmeTrack >( m_hSoloTrack[ clipType ] );
}
void CDmeTrack::SetSoloTrack( DmeClipType_t clipType, CDmeTrack *pTrack )
{
m_hSoloTrack[ clipType ] = pTrack->GetHandle();
}
bool CDmeTrack::IsSoloTrack() const
{
return m_hSoloTrack[ GetClipType() ] == GetHandle();
}
CDmeTrack *CDmeTrack::GetSoloTrack() const
{
return GetSoloTrack( GetClipType() );
}
void CDmeTrack::SetSoloTrack( )
{
m_hSoloTrack[ GetClipType() ] = GetHandle();
}
//-----------------------------------------------------------------------------
// Methods related to finding clips
//-----------------------------------------------------------------------------
int CDmeTrack::FindClip( CDmeClip *clip )
{
Assert( clip->GetClipType() == GetClipType() );
int c = m_Clips.Count();
for ( int i = c - 1; i >= 0; --i )
{
if ( m_Clips[ i ] == clip )
return i;
}
return -1;
}
CDmeClip *CDmeTrack::FindNamedClip( const char *name )
{
int c = m_Clips.Count();
for ( int i = c - 1; i >= 0; --i )
{
CDmeClip *child = m_Clips[ i ];
if ( child && !Q_stricmp( child->GetName(), name ) )
return child;
}
return NULL;
}
//-----------------------------------------------------------------------------
// Find clips at, intersecting or within a particular time interval
//-----------------------------------------------------------------------------
void CDmeTrack::FindClipsAtTime( DmeTime_t time, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const
{
if ( ( flags & DMESKIP_INVISIBLE ) && IsCollapsed() )
return;
if ( ( flags & DMESKIP_MUTED ) && IsMute() )
return;
int nClipCount = GetClipCount();
for ( int j = 0; j < nClipCount; ++j )
{
CDmeClip *pSubClip = GetClip( j );
if ( !pSubClip )
continue;
if ( ( flags & DMESKIP_MUTED ) && pSubClip->IsMute() )
continue;
if ( time.IsInRange( pSubClip->GetStartTime(), pSubClip->GetEndTime() ) )
{
clips.AddToTail( pSubClip );
}
}
}
void CDmeTrack::FindClipsIntersectingTime( DmeTime_t startTime, DmeTime_t endTime, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const
{
if ( ( flags & DMESKIP_INVISIBLE ) && IsCollapsed() )
return;
if ( ( flags & DMESKIP_MUTED ) && IsMute() )
return;
int nClipCount = GetClipCount();
for ( int j = 0; j < nClipCount; ++j )
{
CDmeClip *pSubClip = GetClip( j );
if ( !pSubClip )
continue;
if ( ( flags & DMESKIP_MUTED ) && pSubClip->IsMute() )
continue;
DmeTime_t clipStart = pSubClip->GetStartTime();
DmeTime_t clipEnd = pSubClip->GetEndTime();
if ( clipEnd >= startTime && clipStart < endTime )
{
clips.AddToTail( pSubClip );
}
}
}
void CDmeTrack::FindClipsWithinTime( DmeTime_t startTime, DmeTime_t endTime, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const
{
if ( ( flags & DMESKIP_INVISIBLE ) && IsCollapsed() )
return;
if ( ( flags & DMESKIP_MUTED ) && IsMute() )
return;
int nClipCount = GetClipCount();
for ( int j = 0; j < nClipCount; ++j )
{
CDmeClip *pSubClip = GetClip( j );
if ( !pSubClip )
continue;
if ( ( flags & DMESKIP_MUTED ) && pSubClip->IsMute() )
continue;
DmeTime_t clipStart = pSubClip->GetStartTime();
DmeTime_t clipEnd = pSubClip->GetEndTime();
if ( clipStart >= startTime && clipEnd <= endTime )
{
clips.AddToTail( pSubClip );
}
}
}
//-----------------------------------------------------------------------------
// Methods related to shifting clips
//-----------------------------------------------------------------------------
void CDmeTrack::ShiftAllClips( DmeTime_t dt )
{
if ( dt == DmeTime_t( 0 ) )
return;
CSuppressAutoFixup suppress( this, SUPPRESS_OVERLAP_FIXUP | SUPPRESS_DIRTY_ORDERING );
int c = GetClipCount();
for ( int i = 0; i < c; ++i )
{
CDmeClip *pSubClip = m_Clips[ i ];
pSubClip->SetStartTime( pSubClip->GetStartTime() + dt );
}
}
void CDmeTrack::ShiftAllClipsAfter( DmeTime_t startTime, DmeTime_t dt, bool bTestStartingTime )
{
if ( dt == DmeTime_t( 0 ) )
return;
int c = GetClipCount();
for ( int i = 0; i < c; ++i )
{
CDmeClip *pSubClip = GetClip( i );
DmeTime_t testTime = bTestStartingTime ? pSubClip->GetStartTime() : pSubClip->GetEndTime();
if ( startTime < testTime )
{
pSubClip->SetStartTime( pSubClip->GetStartTime() + dt );
}
}
}
void CDmeTrack::ShiftAllClipsBefore( DmeTime_t endTime, DmeTime_t dt, bool bTestEndingTime )
{
if ( dt == DmeTime_t( 0 ) )
return;
int c = GetClipCount();
for ( int i = 0; i < c; ++i )
{
CDmeClip *pSubClip = GetClip( i );
DmeTime_t testTime = bTestEndingTime ? pSubClip->GetEndTime() : pSubClip->GetStartTime();
if ( endTime > testTime )
{
DmeTime_t startTime = pSubClip->GetStartTime();
pSubClip->SetStartTime( startTime + dt );
}
}
}
//-----------------------------------------------------------------------------
// A version that works only on film clips
//-----------------------------------------------------------------------------
void CDmeTrack::ShiftAllFilmClipsAfter( CDmeClip *pClip, DmeTime_t dt, bool bShiftClip )
{
Assert( IsFilmTrack() );
if ( !IsFilmTrack() || ( m_Clips.Count() == 0 ) || ( dt == DmeTime_t( 0 ) ) )
return;
// This algorithm requires sorted clips
SortClipsByStartTime();
int c = GetClipCount();
for ( int i = c; --i >= 0; )
{
CDmeClip *pSubClip = GetClip( i );
if ( pSubClip == pClip )
{
if ( bShiftClip )
{
pSubClip->SetStartTime( pSubClip->GetStartTime() + dt );
}
return;
}
pSubClip->SetStartTime( pSubClip->GetStartTime() + dt );
}
// Clip wasn't found!
Assert( 0 );
}
void CDmeTrack::ShiftAllFilmClipsBefore( CDmeClip *pClip, DmeTime_t dt, bool bShiftClip )
{
Assert( IsFilmTrack() );
if ( !IsFilmTrack() || ( m_Clips.Count() == 0 ) || ( dt == DmeTime_t( 0 ) ) )
return;
// This algorithm requires sorted clips
SortClipsByStartTime();
int c = GetClipCount();
for ( int i = 0; i < c; ++i )
{
CDmeClip *pSubClip = GetClip( i );
if ( pSubClip == pClip )
{
if ( bShiftClip )
{
pSubClip->SetStartTime( pSubClip->GetStartTime() + dt );
}
return;
}
pSubClip->SetStartTime( pSubClip->GetStartTime() + dt );
}
// Clip wasn't found!
Assert( 0 );
}
//-----------------------------------------------------------------------------
// Method to sort clips by start time
//-----------------------------------------------------------------------------
struct SortInfo_t
{
DmeTime_t m_startTime;
CDmeClip *m_pClip;
};
static int ClipStartLessFunc( const void * lhs, const void * rhs )
{
SortInfo_t *pInfo1 = (SortInfo_t*)lhs;
SortInfo_t *pInfo2 = (SortInfo_t*)rhs;
if ( pInfo1->m_startTime == pInfo2->m_startTime )
return 0;
return pInfo1->m_startTime < pInfo2->m_startTime ? -1 : 1;
}
void CDmeTrack::SortClipsByStartTime( )
{
// If we're not a film clip, then we haven't installed callbacks to make sorting fast.
// The IS_SORTED flag is some random state
if ( (m_ClipType == DMECLIP_FILM) && m_Flags.IsFlagSet( IS_SORTED ) )
return;
m_Flags.SetFlag( IS_SORTED );
int c = GetClipCount();
if ( c <= 1 )
return;
DmeTime_t lastTime;
SortInfo_t *pSortInfo = (SortInfo_t*)_alloca( c * sizeof(SortInfo_t) );
for ( int i = 0; i < c; ++i )
{
CDmeClip *pSubClip = GetClip(i);
pSortInfo[i].m_startTime = pSubClip ? pSubClip->GetStartTime() : DmeTime_t::InvalidTime();
pSortInfo[i].m_pClip = pSubClip;
if ( lastTime > pSortInfo[i].m_startTime )
{
m_Flags.ClearFlag( IS_SORTED );
}
lastTime = pSortInfo[i].m_startTime;
}
if ( m_Flags.IsFlagSet( IS_SORTED ) )
return;
m_Flags.SetFlag( IS_SORTED );
qsort( pSortInfo, c, sizeof(SortInfo_t), ClipStartLessFunc );
CSuppressAutoFixup suppress( this, SUPPRESS_OVERLAP_FIXUP | SUPPRESS_DIRTY_ORDERING );
m_Clips.RemoveAll();
for ( int i = 0; i < c; ++i )
{
m_Clips.AddToTail( pSortInfo[i].m_pClip );
}
}
//-----------------------------------------------------------------------------
// Shifts all clips to be non-overlapping
//-----------------------------------------------------------------------------
void CDmeTrack::FixOverlaps()
{
int c = GetClipCount();
if ( c <= 1 )
return;
SortClipsByStartTime();
CSuppressAutoFixup suppress( this, SUPPRESS_OVERLAP_FIXUP | SUPPRESS_DIRTY_ORDERING );
// Cull NULL clips
int nActualCount = 0;
CDmeClip **pClips = (CDmeClip**)_alloca( c * sizeof(CDmeClip*) );
for ( int i = 0; i < c; ++i )
{
CDmeClip *pCurr = GetClip( i );
if ( pCurr && ((i == 0) || (pClips[i-1] != pCurr)) )
{
pClips[nActualCount++] = pCurr;
}
}
if ( nActualCount <= 1 )
return;
CDmeClip *pPrev = pClips[0];
for ( int i = 1; i < nActualCount; ++i )
{
CDmeClip *pCurr = pClips[i];
DmeTime_t prevEndTime = pPrev->GetEndTime();
DmeTime_t startTime = pCurr->GetStartTime();
if ( startTime < prevEndTime )
{
pCurr->SetStartTime( prevEndTime );
}
pPrev = pCurr;
}
}
//-----------------------------------------------------------------------------
// Finds a clip at a particular time
//-----------------------------------------------------------------------------
CDmeClip* CDmeTrack::FindFilmClipAtTime( DmeTime_t localTime )
{
if ( !IsFilmTrack() || ( m_Clips.Count() == 0 ) )
return NULL;
// This algorithm requires sorted clips
SortClipsByStartTime();
int c = GetClipCount();
for ( int i = 0; i < c; ++i )
{
CDmeClip *pSubClip = GetClip( i );
if ( pSubClip && pSubClip->GetStartTime() <= localTime && pSubClip->GetEndTime() > localTime )
return pSubClip;
}
return NULL;
}
//-----------------------------------------------------------------------------
// Find first clip in a specific time range
//-----------------------------------------------------------------------------
CDmeClip* CDmeTrack::FindFirstFilmClipIntesectingTime( DmeTime_t localStartTime, DmeTime_t localEndTime )
{
if ( !IsFilmTrack() || ( m_Clips.Count() == 0 ) )
return NULL;
// This algorithm requires sorted clips
SortClipsByStartTime();
int c = GetClipCount();
for ( int i = 0; i < c; ++i )
{
CDmeClip *pSubClip = GetClip( i );
if ( !pSubClip )
continue;
if ( ( localStartTime < pSubClip->GetEndTime() ) && ( localEndTime >= pSubClip->GetStartTime() ) )
return static_cast<CDmeFilmClip*>( pSubClip );
if ( localEndTime <= pSubClip->GetStartTime() )
break;
}
return NULL;
}
//-----------------------------------------------------------------------------
// Inserts space in a film track for a film clip
//-----------------------------------------------------------------------------
void CDmeTrack::InsertSpaceInFilmTrack( DmeTime_t localStartTime, DmeTime_t localEndTime )
{
if ( !IsFilmTrack() || ( m_Clips.Count() == 0 ) )
return;
// This algorithm requires sorted clips
SortClipsByStartTime();
CDmeClip *pClip = FindFirstFilmClipIntesectingTime( localStartTime, localEndTime );
if ( pClip )
{
DmeTime_t filmStart = pClip->GetStartTime();
DmeTime_t dt = localEndTime - filmStart;
ShiftAllFilmClipsAfter( pClip, dt, true );
}
return;
}
//-----------------------------------------------------------------------------
// Returns the next/previous clip in a film track
//-----------------------------------------------------------------------------
CDmeClip* CDmeTrack::FindPrevFilmClip( CDmeClip *pClip )
{
Assert( IsFilmTrack() );
if ( !IsFilmTrack() || ( m_Clips.Count() == 0 ) )
return NULL;
// This algorithm requires sorted clips
SortClipsByStartTime();
if ( !pClip )
return m_Clips[ m_Clips.Count() - 1 ];
// FIXME: Could use a binary search here based on time.
// Probably doesn't matter though, since there will usually not be a ton of tracks
CDmeClip *pPrevClip = NULL;
int c = GetClipCount();
for ( int i = 0; i < c; ++i )
{
CDmeClip *pSubClip = GetClip( i );
if ( pSubClip == pClip )
return pPrevClip;
pPrevClip = pSubClip;
}
return NULL;
}
CDmeClip* CDmeTrack::FindNextFilmClip( CDmeClip *pClip )
{
Assert( IsFilmTrack() );
if ( !IsFilmTrack() || ( m_Clips.Count() == 0 ) )
return NULL;
// This algorithm requires sorted clips
SortClipsByStartTime();
if ( !pClip )
return m_Clips[ 0 ];
CDmeClip *pNextClip = NULL;
int c = GetClipCount();
for ( int i = c; --i >= 0; )
{
CDmeClip *pSubClip = GetClip( i );
if ( pSubClip == pClip )
return pNextClip;
pNextClip = pSubClip;
}
return NULL;
}
void CDmeTrack::FindAdjacentFilmClips( CDmeClip *pClip, CDmeClip *&pPrevClip, CDmeClip *&pNextClip )
{
pPrevClip = pNextClip = NULL;
Assert( IsFilmTrack() );
if ( !IsFilmTrack() || !pClip || ( m_Clips.Count() == 0 ) )
return;
// This algorithm requires sorted clips
SortClipsByStartTime();
int c = GetClipCount();
for ( int i = 0; i < c; ++i )
{
CDmeClip *pSubClip = GetClip( i );
if ( pSubClip == pClip )
{
pNextClip = ( i != c-1 ) ? GetClip( i+1 ) : NULL;
return;
}
pPrevClip = pSubClip;
}
pPrevClip = NULL;
}
//-----------------------------------------------------------------------------
// Gets the start/end time of the owning clip in local time
//-----------------------------------------------------------------------------
void CDmeTrack::FindAdjacentFilmClips( DmeTime_t localTime, CDmeClip *&pPrevClip, CDmeClip *&pNextClip )
{
pPrevClip = pNextClip = NULL;
Assert( IsFilmTrack() );
if ( !IsFilmTrack() || ( m_Clips.Count() == 0 ) )
return;
// This algorithm requires sorted clips
SortClipsByStartTime();
int c = GetClipCount();
for ( int i = 0; i < c; ++i )
{
CDmeClip *pSubClip = GetClip( i );
if ( localTime >= pSubClip->GetEndTime() )
{
pPrevClip = pSubClip;
}
if ( localTime < pSubClip->GetStartTime() )
{
pNextClip = pSubClip;
break;
}
}
}
//-----------------------------------------------------------------------------
// Fills all gaps in a film track with slugs
//-----------------------------------------------------------------------------
void CDmeTrack::FillAllGapsWithSlugs( const char *pSlugName, DmeTime_t startTime, DmeTime_t endTime )
{
if ( !IsFilmTrack() )
return;
FixOverlaps();
// Create temporary slugs to fill in the gaps
bool bSlugAdded = false;
int c = GetClipCount();
for ( int i = 0; i < c; ++i )
{
CDmeClip *pFilmClip = GetClip(i);
DmeTime_t clipStartTime = pFilmClip->GetStartTime();
if ( clipStartTime > startTime )
{
// There's a gap, create a slug
CDmeFilmClip *pSlug = CreateSlugClip( pSlugName, startTime, clipStartTime, GetFileId() );
// This will add the slug to the end; so we don't have to
// worry about iterating over it (we've cached off the initial count)
AddClip( pSlug );
bSlugAdded = true;
}
startTime = pFilmClip->GetEndTime();
}
if ( endTime > startTime )
{
// There's a gap, create a temporary slug
CDmeFilmClip *pSlug = CreateSlugClip( pSlugName, startTime, endTime, GetFileId() );
// This will add the slug to the end; so we don't have to
// worry about iterating over it (we've cached off the initial count)
AddClip( pSlug );
bSlugAdded = true;
}
if ( bSlugAdded )
{
FixOverlaps();
}
}
//-----------------------------------------------------------------------------
// helper methods
//-----------------------------------------------------------------------------
CDmeTrackGroup *GetParentTrackGroup( CDmeTrack *pTrack )
{
DmAttributeReferenceIterator_t hAttr = g_pDataModel->FirstAttributeReferencingElement( pTrack->GetHandle() );
for ( ; hAttr != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID; hAttr = g_pDataModel->NextAttributeReferencingElement( hAttr ) )
{
CDmAttribute *pAttr = g_pDataModel->GetAttribute( hAttr );
if ( !pAttr )
continue;
CDmeTrackGroup *pTrackGroup = CastElement< CDmeTrackGroup >( pAttr->GetOwner() );
if ( pTrackGroup )
return pTrackGroup;
}
return NULL;
}

View File

@ -0,0 +1,524 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmetrackgroup.h"
#include <limits.h>
#include "tier0/dbg.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "movieobjects/dmetrack.h"
#include "movieobjects/dmeclip.h"
#include "movieobjects_interfaces.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// CDmeTrackGroup - contains a list of tracks
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeTrackGroup, CDmeTrackGroup );
void CDmeTrackGroup::OnConstruction()
{
m_hOwner = DMELEMENT_HANDLE_INVALID;
m_Tracks.Init( this, "tracks", FATTRIB_MUSTCOPY | FATTRIB_HAS_ARRAY_CALLBACK );
m_bIsVisible.InitAndSet( this, "visible", true );
m_bMute.Init( this, "mute" );
m_nDisplaySize.InitAndSet( this, "displaySize", 110 );
m_bMinimized.InitAndSet( this, "minimized", true );
m_nMaxTrackCount = INT_MAX;
m_Volume.InitAndSet( this, "volume", 1.0 );
}
void CDmeTrackGroup::OnDestruction()
{
// NOTE: The track owner handles may still be pointing to us when we get destructed,
// but their handles will be invalid, so GetTrackGroup on a track
// will correctly return NULL.
}
//-----------------------------------------------------------------------------
// Max track count
//-----------------------------------------------------------------------------
void CDmeTrackGroup::SetMaxTrackCount( int nCount )
{
m_nMaxTrackCount = nCount;
}
//-----------------------------------------------------------------------------
// Mute
//-----------------------------------------------------------------------------
void CDmeTrackGroup::SetMute( bool state )
{
m_bMute = state;
}
bool CDmeTrackGroup::IsMute( ) const
{
return m_bMute;
}
//-----------------------------------------------------------------------------
// Volume
//-----------------------------------------------------------------------------
void CDmeTrackGroup::SetVolume( float state )
{
m_Volume = state;
}
float CDmeTrackGroup::GetVolume() const
{
return m_Volume.Get();
}
//-----------------------------------------------------------------------------
// Owning clip
//-----------------------------------------------------------------------------
CDmeClip *CDmeTrackGroup::GetOwnerClip()
{
return GetElement< CDmeClip >( m_hOwner );
}
void CDmeTrackGroup::SetOwnerClip( CDmeClip *pClip )
{
m_hOwner = pClip ? pClip->GetHandle() : DMELEMENT_HANDLE_INVALID;
}
//-----------------------------------------------------------------------------
// Are we a film track group?
//-----------------------------------------------------------------------------
bool CDmeTrackGroup::IsFilmTrackGroup()
{
CDmeClip *pOwnerClip = GetOwnerClip();
if ( pOwnerClip )
return pOwnerClip->GetFilmTrackGroup() == this;
return m_nMaxTrackCount == 1;
}
//-----------------------------------------------------------------------------
// Is a particular clip typed able to be added?
//-----------------------------------------------------------------------------
bool CDmeTrackGroup::IsSubClipTypeAllowed( DmeClipType_t type )
{
if ( IsFilmTrackGroup() )
{
if ( type != DMECLIP_FILM )
return false;
}
else
{
if ( type == DMECLIP_FILM )
return false;
}
CDmeClip *pOwnerClip = GetOwnerClip();
Assert( pOwnerClip );
if ( !pOwnerClip )
return true;
return pOwnerClip->IsSubClipTypeAllowed( type );
}
//-----------------------------------------------------------------------------
// Track addition/removal
//-----------------------------------------------------------------------------
void CDmeTrackGroup::AddTrack( CDmeTrack *pTrack )
{
// FIXME: Should check if track with same name already exists???
if ( GetTrackIndex( pTrack ) < 0 )
{
// Tracks can only exist in one track group
Assert( GetTrackIndex( pTrack ) >= 0 );
m_Tracks.AddToTail( pTrack );
Assert( m_nMaxTrackCount >= m_Tracks.Count() );
}
}
CDmeTrack* CDmeTrackGroup::AddTrack( const char *pTrackName, DmeClipType_t trackType )
{
CDmeTrack *pTrack = CreateElement< CDmeTrack >( pTrackName, GetFileId() );
pTrack->SetClipType( trackType );
pTrack->SetCollapsed( false );
m_Tracks.AddToTail( pTrack );
Assert( m_nMaxTrackCount >= m_Tracks.Count() );
return pTrack;
}
CDmeTrack* CDmeTrackGroup::FindOrAddTrack( const char *pTrackName, DmeClipType_t trackType )
{
CDmeTrack *pTrack = FindTrack( pTrackName );
if ( pTrack )
{
// If we found it, but it's the wrong type, no dice
if ( pTrack->GetClipType() != trackType )
return NULL;
}
else
{
pTrack = AddTrack( pTrackName, trackType );
}
return pTrack;
}
void CDmeTrackGroup::RemoveTrack( int nIndex )
{
m_Tracks.Remove( nIndex );
}
void CDmeTrackGroup::RemoveTrack( CDmeTrack *pTrack )
{
int i = GetTrackIndex( pTrack );
if ( i >= 0 )
{
m_Tracks.Remove( i );
}
}
void CDmeTrackGroup::RemoveTrack( const char *pTrackName )
{
if ( !pTrackName )
{
pTrackName = DMETRACK_DEFAULT_NAME;
}
int c = m_Tracks.Count();
for ( int i = c; --i >= 0; )
{
if ( !Q_strcmp( m_Tracks[i]->GetName(), pTrackName ) )
{
m_Tracks.Remove( i );
return;
}
}
}
//-----------------------------------------------------------------------------
// Track finding
//-----------------------------------------------------------------------------
CDmeTrack *CDmeTrackGroup::FindTrack( const char *pTrackName ) const
{
if ( !pTrackName )
{
pTrackName = DMETRACK_DEFAULT_NAME;
}
int c = m_Tracks.Count();
for ( int i = 0 ; i < c; ++i )
{
CDmeTrack *pTrack = m_Tracks[i];
if ( !pTrack )
continue;
if ( !Q_strcmp( pTrack->GetName(), pTrackName ) )
return pTrack;
}
return NULL;
}
int CDmeTrackGroup::GetTrackIndex( CDmeTrack *pTrack ) const
{
int nTracks = m_Tracks.Count();
for ( int i = 0 ; i < nTracks; ++i )
{
if ( pTrack == m_Tracks[i] )
return i;
}
return -1;
}
//-----------------------------------------------------------------------------
// Creates the film track group [for internal use only]
//-----------------------------------------------------------------------------
CDmeTrack *CDmeTrackGroup::CreateFilmTrack()
{
Assert( GetTrackCount() == 0 );
return AddTrack( "Film", DMECLIP_FILM );
}
//-----------------------------------------------------------------------------
// Returns the film track, if any
//-----------------------------------------------------------------------------
CDmeTrack *CDmeTrackGroup::GetFilmTrack()
{
if ( !IsFilmTrackGroup() )
return NULL;
if ( GetTrackCount() > 0 )
{
Assert( GetTrackCount() == 1 );
return m_Tracks[0];
}
return NULL;
}
//-----------------------------------------------------------------------------
// Adding/removing clips from tracks
//-----------------------------------------------------------------------------
CDmeTrack *CDmeTrackGroup::AddClip( CDmeClip *pClip, const char *pTrackName )
{
DmeClipType_t type = pClip->GetClipType();
if ( !pTrackName )
{
pTrackName = DMETRACK_DEFAULT_NAME;
}
CDmeTrack *pTrack = FindOrAddTrack( pTrackName, type );
if ( pTrack )
{
pTrack->AddClip( pClip );
}
return pTrack;
}
bool CDmeTrackGroup::RemoveClip( CDmeClip *pClip )
{
CDmeTrack *pTrack = FindTrackForClip( pClip );
if ( pTrack )
return pTrack->RemoveClip( pClip );
return false;
}
//-----------------------------------------------------------------------------
// Changing clip track
//-----------------------------------------------------------------------------
CDmeTrack *CDmeTrackGroup::ChangeTrack( CDmeClip *pClip, const char *pNewTrack )
{
// Add, then remove, to avoid refcount problems
// Don't remove if it wasn't added for some reason.
CDmeTrack *pOldTrack = FindTrackForClip( pClip );
CDmeTrack *pTrack = AddClip( pClip, pNewTrack );
if ( pTrack && pOldTrack )
{
pOldTrack->RemoveClip( pClip );
}
return pTrack;
}
//-----------------------------------------------------------------------------
// Finding clips in tracks
//-----------------------------------------------------------------------------
CDmeTrack *CDmeTrackGroup::FindTrackForClip( CDmeClip *pClip ) const
{
int nTrackIndex = -1;
if ( !FindTrackForClip( pClip, &nTrackIndex, NULL ) )
return NULL;
return GetTrack( nTrackIndex );
}
bool CDmeTrackGroup::FindTrackForClip( CDmeClip *pClip, int *pTrackIndex, int *pClipIndex ) const
{
DmeClipType_t type = pClip->GetClipType();
int c = GetTrackCount();
for ( int i = 0; i < c; ++i )
{
CDmeTrack *pTrack = GetTrack( i );
if ( !pTrack )
continue;
if ( pTrack->GetClipType() != type )
continue;
int nClipCount = pTrack->GetClipCount();
for ( int j = 0; j < nClipCount; ++j )
{
if ( pTrack->GetClip( j ) == pClip )
{
if ( pTrackIndex )
{
*pTrackIndex = i;
}
if ( pClipIndex )
{
*pClipIndex = j;
}
return true;
}
}
}
return false;
}
//-----------------------------------------------------------------------------
// Finding clips in tracks by time
//-----------------------------------------------------------------------------
void CDmeTrackGroup::FindClipsAtTime( DmeClipType_t clipType, DmeTime_t time, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const
{
if ( ( flags & DMESKIP_INVISIBLE ) && ( !IsVisible() || IsMinimized() ) )
return;
if ( ( flags & DMESKIP_MUTED ) && IsMute() )
return;
int c = GetTrackCount();
for ( int i = 0; i < c; ++i )
{
CDmeTrack *pTrack = GetTrack( i );
if ( !pTrack )
continue;
if ( ( clipType != DMECLIP_UNKNOWN ) && ( pTrack->GetClipType() != clipType ) )
continue;
pTrack->FindClipsAtTime( time, flags, clips );
}
}
void CDmeTrackGroup::FindClipsIntersectingTime( DmeClipType_t clipType, DmeTime_t startTime, DmeTime_t endTime, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const
{
if ( ( flags & DMESKIP_INVISIBLE ) && ( !IsVisible() || IsMinimized() ) )
return;
if ( ( flags & DMESKIP_MUTED ) && IsMute() )
return;
int c = GetTrackCount();
for ( int i = 0; i < c; ++i )
{
CDmeTrack *pTrack = GetTrack( i );
if ( !pTrack )
continue;
if ( ( clipType != DMECLIP_UNKNOWN ) && ( pTrack->GetClipType() != clipType ) )
continue;
pTrack->FindClipsIntersectingTime( startTime, endTime, flags, clips );
}
}
void CDmeTrackGroup::FindClipsWithinTime( DmeClipType_t clipType, DmeTime_t startTime, DmeTime_t endTime, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const
{
if ( ( flags & DMESKIP_INVISIBLE ) && ( !IsVisible() || IsMinimized() ) )
return;
if ( ( flags & DMESKIP_MUTED ) && IsMute() )
return;
int c = GetTrackCount();
for ( int i = 0; i < c; ++i )
{
CDmeTrack *pTrack = GetTrack( i );
if ( !pTrack )
continue;
if ( ( clipType != DMECLIP_UNKNOWN ) && ( pTrack->GetClipType() != clipType ) )
continue;
pTrack->FindClipsWithinTime( startTime, endTime, flags, clips );
}
}
//-----------------------------------------------------------------------------
// Removes empty tracks
//-----------------------------------------------------------------------------
void CDmeTrackGroup::RemoveEmptyTracks()
{
int tc = GetTrackCount();
for ( int i = tc; --i >= 0; )
{
CDmeTrack *pTrack = GetTrack( i );
if ( pTrack->GetClipCount() == 0 )
{
RemoveTrack( i );
}
}
}
//-----------------------------------------------------------------------------
// Sort tracks by track type, then alphabetically
//-----------------------------------------------------------------------------
static int TrackLessFunc( const void * lhs, const void * rhs )
{
CDmeTrack *pInfo1 = *(CDmeTrack**)lhs;
CDmeTrack *pInfo2 = *(CDmeTrack**)rhs;
if ( pInfo1->GetClipType() < pInfo2->GetClipType() )
return -1;
if ( pInfo1->GetClipType() > pInfo2->GetClipType() )
return 1;
return Q_strcmp( pInfo1->GetName(), pInfo2->GetName() );
}
void CDmeTrackGroup::SortTracksByType()
{
int tc = GetTrackCount();
if ( tc == 0 )
return;
CDmeTrack **ppTrack = (CDmeTrack**)_alloca( tc * sizeof(CDmeTrack*) );
for ( int i = 0; i < tc; ++i )
{
ppTrack[i] = GetTrack(i);
}
qsort( ppTrack, tc, sizeof(CDmeTrack*), TrackLessFunc );
m_Tracks.RemoveAll();
for ( int i = 0; i < tc; ++i )
{
m_Tracks.AddToTail( ppTrack[i] );
}
}
//-----------------------------------------------------------------------------
// Returns the flattened clip count
//-----------------------------------------------------------------------------
int CDmeTrackGroup::GetSubClipCount() const
{
int nCount = 0;
DMETRACKGROUP_FOREACH_CLIP_START( this, pTrack, pClip )
++nCount;
DMETRACKGROUP_FOREACH_CLIP_END()
return nCount;
}
void CDmeTrackGroup::GetSubClips( CDmeClip **ppClips )
{
int nCount = 0;
DMETRACKGROUP_FOREACH_CLIP_START( this, pTrack, pClip )
ppClips[nCount++] = pClip;
DMETRACKGROUP_FOREACH_CLIP_END()
}
//-----------------------------------------------------------------------------
// helper methods
//-----------------------------------------------------------------------------
CDmeFilmClip *GetParentClip( CDmeTrackGroup *pTrackGroup )
{
DmAttributeReferenceIterator_t hAttr = g_pDataModel->FirstAttributeReferencingElement( pTrackGroup->GetHandle() );
for ( ; hAttr != DMATTRIBUTE_REFERENCE_ITERATOR_INVALID; hAttr = g_pDataModel->NextAttributeReferencingElement( hAttr ) )
{
CDmAttribute *pAttr = g_pDataModel->GetAttribute( hAttr );
if ( !pAttr )
continue;
CDmeFilmClip *pFilmClip = CastElement< CDmeFilmClip >( pAttr->GetOwner() );
if ( pFilmClip )
return pFilmClip;
}
return NULL;
}

View File

@ -0,0 +1,82 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmetransform.h"
#include "tier0/dbg.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "mathlib/vector.h"
#include "mathlib/mathlib.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( DmeTransform, CDmeTransform );
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
void CDmeTransform::OnConstruction()
{
m_Position.Init( this, "position" );
m_Orientation.Init( this, "orientation" );
}
void CDmeTransform::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// FIXME: Replace this with actual methods to do editing
//-----------------------------------------------------------------------------
void CDmeTransform::SetTransform( const matrix3x4_t &transform )
{
Vector origin;
Quaternion angles;
MatrixAngles( transform, angles, origin );
m_Orientation.Set( angles );
m_Position.Set( origin );
}
void CDmeTransform::GetTransform( matrix3x4_t &transform )
{
QuaternionMatrix( m_Orientation.Get(), m_Position.Get(), transform );
}
const Vector &CDmeTransform::GetPosition() const
{
return m_Position.Get();
}
void CDmeTransform::SetPosition( const Vector &vecPosition )
{
m_Position = vecPosition;
}
const Quaternion &CDmeTransform::GetOrientation() const
{
return m_Orientation.Get();
}
void CDmeTransform::SetOrientation( const Quaternion &orientation )
{
m_Orientation = orientation;
}
CDmAttribute *CDmeTransform::GetPositionAttribute()
{
return m_Position.GetAttribute();
}
CDmAttribute *CDmeTransform::GetOrientationAttribute()
{
return m_Orientation.GetAttribute();
}

View File

@ -0,0 +1,98 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmetransforminput.h"
#include "movieobjects_interfaces.h"
#include "datamodel/dmelementfactoryhelper.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( DmeTranslationInput, CDmeTranslationInput );
void CDmeTranslationInput::OnConstruction()
{
m_translation.Init( this, "translation" );
}
void CDmeTranslationInput::OnDestruction()
{
}
bool CDmeTranslationInput::IsDirty()
{
return true;
}
void CDmeTranslationInput::Operate()
{
}
void CDmeTranslationInput::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
}
void CDmeTranslationInput::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_translation.GetAttribute() );
}
//-----------------------------------------------------------------------------
// Expose this class to the scene database
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeRotationInput, CDmeRotationInput );
void CDmeRotationInput::OnConstruction()
{
m_orientation.Init( this, "orientation" );
m_angles.Init( this, "angles" );
}
void CDmeRotationInput::OnDestruction()
{
}
bool CDmeRotationInput::IsDirty()
{
return true;
}
void CDmeRotationInput::Operate()
{
}
void CDmeRotationInput::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
}
void CDmeRotationInput::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_orientation.GetAttribute() );
attrs.AddToTail( m_angles.GetAttribute() );
}
void CDmeRotationInput::SetRotation( const Quaternion& quat )
{
QAngle qangle;
QuaternionAngles( quat, qangle );
m_angles = qangle;
m_orientation = quat;
}
void CDmeRotationInput::SetRotation( const QAngle& qangle )
{
Quaternion quat;
AngleQuaternion( qangle, quat );
m_orientation = quat;
m_angles = qangle;
}

View File

@ -0,0 +1,38 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// An element that contains a transformlist
//
//=============================================================================
#include "movieobjects/dmetransformlist.h"
#include "datamodel/dmelementfactoryhelper.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( DmeTransformList, CDmeTransformList );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeTransformList::OnConstruction()
{
m_Transforms.Init( this, "transforms" );
}
void CDmeTransformList::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Sets the transform
//-----------------------------------------------------------------------------
void CDmeTransformList::SetTransform( int nIndex, const matrix3x4_t& mat )
{
m_Transforms[nIndex]->SetTransform( mat );
}

View File

@ -0,0 +1,107 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// The transform operator class - shortcut to setting transform values from floats
//
//=============================================================================
#include "movieobjects/dmetransformoperator.h"
#include "movieobjects/dmetransform.h"
#include "movieobjects_interfaces.h"
#include "datamodel/dmelementfactoryhelper.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( DmeTransformOperator, CDmeTransformOperator );
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeTransformOperator::OnConstruction()
{
m_transform.Init( this, "transform" );
m_positionX.Init( this, "positionX" );
m_positionY.Init( this, "positionY" );
m_positionZ.Init( this, "positionZ" );
m_orientationX.Init( this, "orientationX" );
m_orientationY.Init( this, "orientationY" );
m_orientationZ.Init( this, "orientationZ" );
m_orientationW.Init( this, "orientationW" );
}
void CDmeTransformOperator::OnDestruction()
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CDmeTransformOperator::Operate()
{
CDmeTransform *pTransform = m_transform.GetElement();
if ( pTransform == NULL )
return;
Vector position = pTransform->GetValue< Vector >( "position" );
Quaternion orientation = pTransform->GetValue< Quaternion >( "orientation" );
position.x = m_positionX.Get();
position.y = m_positionY.Get();
position.z = m_positionZ.Get();
orientation.x = m_orientationX.Get();
orientation.y = m_orientationY.Get();
orientation.z = m_orientationZ.Get();
orientation.w = m_orientationW.Get();
pTransform->SetValue( "position", position );
pTransform->SetValue( "orientation", orientation );
}
// hack to avoid MSVC complaining about multiply defined symbols
namespace TransformOp
{
void AddAttr( CUtlVector< CDmAttribute * > &attrs, CDmAttribute *pAttr )
{
if ( pAttr == NULL )
return;
attrs.AddToTail( pAttr );
}
};
using namespace TransformOp;
void CDmeTransformOperator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
AddAttr( attrs, m_positionX.GetAttribute() );
AddAttr( attrs, m_positionY.GetAttribute() );
AddAttr( attrs, m_positionZ.GetAttribute() );
AddAttr( attrs, m_orientationX.GetAttribute() );
AddAttr( attrs, m_orientationY.GetAttribute() );
AddAttr( attrs, m_orientationZ.GetAttribute() );
AddAttr( attrs, m_orientationW.GetAttribute() );
}
void CDmeTransformOperator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
CDmeTransform *pTransform = m_transform.GetElement();
if ( pTransform == NULL )
return;
AddAttr( attrs, pTransform->GetAttribute( "position" ) );
AddAttr( attrs, pTransform->GetAttribute( "orientation" ) );
}
void CDmeTransformOperator::SetTransform( CDmeTransform *pTransform )
{
m_transform.Set( pTransform );
}
const CDmeTransform *CDmeTransformOperator::GetTransform() const
{
return m_transform.GetElement();
}

View File

@ -0,0 +1,335 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/dmeunpackoperators.h"
#include "movieobjects_interfaces.h"
#include "datamodel/dmelementfactoryhelper.h"
#include "datamodel/dmattribute.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// CDmeUnpackColorOperator
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeUnpackColorOperator, CDmeUnpackColorOperator );
void CDmeUnpackColorOperator::OnConstruction()
{
m_color.Init( this, "color" );
m_red .Init( this, "red" );
m_green.Init( this, "green" );
m_blue .Init( this, "blue" );
m_alpha.Init( this, "alpha" );
}
void CDmeUnpackColorOperator::OnDestruction()
{
}
bool CDmeUnpackColorOperator::IsDirty()
{
const Color &c = m_color.Get();
// float s = 255.999f;
// return c.r() != s*m_red.Get() || c.g() != s*m_green.Get() || c.b() != s*m_blue.Get() || c.a() != s*m_alpha.Get();
return c.r() != m_red.Get() || c.g() != m_green.Get() || c.b() != m_blue.Get() || c.a() != m_alpha.Get();
}
void CDmeUnpackColorOperator::Operate()
{
// float s = 255.999f;
// m_color.Set( Color( s*m_red.Get(), s*m_green.Get(), s*m_blue.Get(), s*m_alpha.Get() ) );
m_red .Set( m_color.Get().r() );
m_green.Set( m_color.Get().g() );
m_blue .Set( m_color.Get().b() );
m_alpha.Set( m_color.Get().a() );
}
void CDmeUnpackColorOperator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_color.GetAttribute() );
}
void CDmeUnpackColorOperator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_red.GetAttribute() );
attrs.AddToTail( m_green.GetAttribute() );
attrs.AddToTail( m_blue.GetAttribute() );
attrs.AddToTail( m_alpha.GetAttribute() );
}
//-----------------------------------------------------------------------------
// CDmeUnpackVector2Operator
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeUnpackVector2Operator, CDmeUnpackVector2Operator );
void CDmeUnpackVector2Operator::OnConstruction()
{
m_vector.Init( this, "vector" );
m_x.Init( this, "x" );
m_y.Init( this, "y" );
}
void CDmeUnpackVector2Operator::OnDestruction()
{
}
bool CDmeUnpackVector2Operator::IsDirty()
{
const Vector2D &v = m_vector.Get();
return v.x != m_x.Get() || v.y != m_y.Get();
}
void CDmeUnpackVector2Operator::Operate()
{
m_x.Set( m_vector.Get().x );
m_y.Set( m_vector.Get().y );
}
void CDmeUnpackVector2Operator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_vector.GetAttribute() );
}
void CDmeUnpackVector2Operator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_x.GetAttribute() );
attrs.AddToTail( m_y.GetAttribute() );
}
//-----------------------------------------------------------------------------
// CDmeUnpackVector3Operator
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeUnpackVector3Operator, CDmeUnpackVector3Operator );
void CDmeUnpackVector3Operator::OnConstruction()
{
m_vector.Init( this, "vector" );
m_x.Init( this, "x" );
m_y.Init( this, "y" );
m_z.Init( this, "z" );
}
void CDmeUnpackVector3Operator::OnDestruction()
{
}
bool CDmeUnpackVector3Operator::IsDirty()
{
const Vector &v = m_vector.Get();
return v.x != m_x.Get() || v.y != m_y.Get() || v.z != m_z.Get();
}
void CDmeUnpackVector3Operator::Operate()
{
m_x.Set( m_vector.Get().x );
m_y.Set( m_vector.Get().y );
m_z.Set( m_vector.Get().z );
}
void CDmeUnpackVector3Operator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_vector.GetAttribute() );
}
void CDmeUnpackVector3Operator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_x.GetAttribute() );
attrs.AddToTail( m_y.GetAttribute() );
attrs.AddToTail( m_z.GetAttribute() );
}
//-----------------------------------------------------------------------------
// CDmeUnpackVector4Operator
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeUnpackVector4Operator, CDmeUnpackVector4Operator );
void CDmeUnpackVector4Operator::OnConstruction()
{
m_vector.Init( this, "vector" );
m_x.Init( this, "x" );
m_y.Init( this, "y" );
m_z.Init( this, "z" );
m_w.Init( this, "w" );
}
void CDmeUnpackVector4Operator::OnDestruction()
{
}
bool CDmeUnpackVector4Operator::IsDirty()
{
const Vector4D &v = m_vector.Get();
return v.x != m_x.Get() || v.y != m_y.Get() || v.z != m_z.Get() || v.w != m_w.Get();
}
void CDmeUnpackVector4Operator::Operate()
{
m_x.Set( m_vector.Get().x );
m_y.Set( m_vector.Get().y );
m_z.Set( m_vector.Get().z );
m_w.Set( m_vector.Get().w );
}
void CDmeUnpackVector4Operator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_vector.GetAttribute() );
}
void CDmeUnpackVector4Operator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_x.GetAttribute() );
attrs.AddToTail( m_y.GetAttribute() );
attrs.AddToTail( m_z.GetAttribute() );
attrs.AddToTail( m_w.GetAttribute() );
}
//-----------------------------------------------------------------------------
// CDmeUnpackQAngleOperator
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeUnpackQAngleOperator, CDmeUnpackQAngleOperator );
void CDmeUnpackQAngleOperator::OnConstruction()
{
m_qangle.Init( this, "qangle" );
m_x.Init( this, "x" );
m_y.Init( this, "y" );
m_z.Init( this, "z" );
}
void CDmeUnpackQAngleOperator::OnDestruction()
{
}
bool CDmeUnpackQAngleOperator::IsDirty()
{
const QAngle &q = m_qangle.Get();
return q.x != m_x.Get() || q.y != m_y.Get() || q.z != m_z.Get();
}
void CDmeUnpackQAngleOperator::Operate()
{
m_x.Set( m_qangle.Get().x );
m_y.Set( m_qangle.Get().y );
m_z.Set( m_qangle.Get().z );
}
void CDmeUnpackQAngleOperator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_qangle.GetAttribute() );
}
void CDmeUnpackQAngleOperator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_x.GetAttribute() );
attrs.AddToTail( m_y.GetAttribute() );
attrs.AddToTail( m_z.GetAttribute() );
}
//-----------------------------------------------------------------------------
// CDmeUnpackQuaternionOperator
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeUnpackQuaternionOperator, CDmeUnpackQuaternionOperator );
void CDmeUnpackQuaternionOperator::OnConstruction()
{
m_quaternion.Init( this, "quaternion" );
m_x.Init( this, "x" );
m_y.Init( this, "y" );
m_z.Init( this, "z" );
m_w.Init( this, "w" );
}
void CDmeUnpackQuaternionOperator::OnDestruction()
{
}
bool CDmeUnpackQuaternionOperator::IsDirty()
{
const Quaternion &q = m_quaternion.Get();
return q.x != m_x.Get() || q.y != m_y.Get() || q.z != m_z.Get() || q.w != m_w.Get();
}
void CDmeUnpackQuaternionOperator::Operate()
{
m_x.Set( m_quaternion.Get().x );
m_y.Set( m_quaternion.Get().y );
m_z.Set( m_quaternion.Get().z );
m_w.Set( m_quaternion.Get().w );
}
void CDmeUnpackQuaternionOperator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_quaternion.GetAttribute() );
}
void CDmeUnpackQuaternionOperator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_x.GetAttribute() );
attrs.AddToTail( m_y.GetAttribute() );
attrs.AddToTail( m_z.GetAttribute() );
attrs.AddToTail( m_w.GetAttribute() );
}
//-----------------------------------------------------------------------------
// CDmeUnpackVMatrixOperator
//-----------------------------------------------------------------------------
IMPLEMENT_ELEMENT_FACTORY( DmeUnpackVMatrixOperator, CDmeUnpackVMatrixOperator );
void CDmeUnpackVMatrixOperator::OnConstruction()
{
m_vmatrix.Init( this, "vmatrix" );
char name[ 4 ];
for ( uint i = 0; i < 16; ++i )
{
Q_snprintf( name, sizeof(name), "m%d%d", i >> 2, i & 0x3 );
m_cells[ i ].Init( this, name );
}
}
void CDmeUnpackVMatrixOperator::OnDestruction()
{
}
bool CDmeUnpackVMatrixOperator::IsDirty()
{
const VMatrix &v = m_vmatrix.Get();
for ( uint i = 0; i < 16; ++i )
{
if ( *( v[ i ] ) != m_cells[ i ].Get() )
return true;
}
return false;
}
void CDmeUnpackVMatrixOperator::Operate()
{
VMatrix v;
for ( uint i = 0; i < 16; ++i )
{
m_cells[ i ].Set( *( v[ i ] ) );
}
m_vmatrix.Set( v );
}
void CDmeUnpackVMatrixOperator::GetInputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
attrs.AddToTail( m_vmatrix.GetAttribute() );
}
void CDmeUnpackVMatrixOperator::GetOutputAttributes( CUtlVector< CDmAttribute * > &attrs )
{
for ( uint i = 0; i < 16; ++i )
{
attrs.AddToTail( m_cells[i].GetAttribute() );
}
}

File diff suppressed because it is too large Load Diff

480
movieobjects/dmmeshcomp.cpp Normal file
View File

@ -0,0 +1,480 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Implementation of CDmMeshComp - CDmeMesh computation class
//
//=============================================================================
// Valve includes
#include "movieobjects/dmmeshcomp.h"
#include "movieobjects/dmefaceset.h"
#include "movieobjects/dmemesh.h"
#include "movieobjects/dmevertexdata.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//=============================================================================
//
//=============================================================================
CDmMeshComp::CDmMeshComp( CDmeMesh *pMesh, CDmeVertexData *pPassedBase )
: m_pMesh( pMesh )
, m_pBase( NULL )
{
m_pBase = pPassedBase ? pPassedBase : pMesh->GetCurrentBaseState();
if ( !m_pBase )
return;
const FieldIndex_t pIndex( m_pBase->FindFieldIndex( CDmeVertexData::FIELD_POSITION ) );
if ( pIndex < 0 )
return;
const CUtlVector< Vector > &pPositionData( m_pBase->GetPositionData() );
const CUtlVector<int> &pPositionIndices( m_pBase->GetVertexIndexData( CDmeVertexData::FIELD_POSITION ) );
const int nVertices( pPositionData.Count() );
if ( nVertices <= 0 )
return;
// Create vertices
// TODO: check for duplicates in pPositionData - that would break this algorithm
m_verts.EnsureCapacity( nVertices );
for ( int i = 0; i < nVertices; ++i )
{
const CUtlVector< int > &vertexIndices = m_pBase->FindVertexIndicesFromDataIndex( CDmeVertexData::FIELD_POSITION, i );
m_verts.AddToTail( new CVert( i, &vertexIndices, &pPositionData[ i ] ) );
}
// Create edges and faces
const int nFaceSets( pMesh->FaceSetCount() );
for ( int i = 0; i < nFaceSets; ++i )
{
CDmeFaceSet *pFaceSet( pMesh->GetFaceSet( i ) );
const int nIndices( pFaceSet->NumIndices() );
if ( nIndices < 4 ) // At least a triangle and a -1
continue;
m_faces.EnsureCapacity( m_faces.Count() + nIndices / 4 ); // # new faces <= nIndices/4 (tri + -1)
m_edges.EnsureCapacity( m_edges.Count() + nIndices / 2 ); // # new edges <= 2*new faces
int facePosIndex( -1 );
int edgePosIndex0( -1 );
int edgePosIndex1( -1 );
CUtlVector< CVert * > verts;
CUtlVector< CEdge * > edges;
CUtlVector< bool > edgeReverseMap;
bool bReverse = false;
for ( int j( 0 ); j < nIndices; ++j )
{
const int faceVertexIndex( pFaceSet->GetIndex( j ) );
if ( faceVertexIndex < 0 )
{
// End of face
edgePosIndex0 = edgePosIndex1;
edgePosIndex1 = facePosIndex;
Assert( edgePosIndex0 >= 0 );
Assert( edgePosIndex1 >= 0 );
edges.AddToTail( FindOrCreateEdge( edgePosIndex0, edgePosIndex1, &bReverse ) );
edgeReverseMap.AddToTail( bReverse );
CreateFace( verts, edges, edgeReverseMap );
facePosIndex = -1;
verts.RemoveAll();
edges.RemoveAll();
edgeReverseMap.RemoveAll();
continue;
}
if ( facePosIndex < 0 )
{
// First vertex
facePosIndex = pPositionIndices[ faceVertexIndex ];
edgePosIndex1 = facePosIndex;
verts.AddToTail( m_verts[ edgePosIndex1 ] );
continue;
}
// 2nd through last vertex
edgePosIndex0 = edgePosIndex1;
edgePosIndex1 = pPositionIndices[ faceVertexIndex ];
verts.AddToTail( m_verts[ edgePosIndex1 ] );
Assert( edgePosIndex0 >= 0 );
Assert( edgePosIndex1 >= 0 );
edges.AddToTail( FindOrCreateEdge( edgePosIndex0, edgePosIndex1, &bReverse ) );
edgeReverseMap.AddToTail( bReverse );
}
}
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
CDmMeshComp::~CDmMeshComp()
{
m_verts.PurgeAndDeleteElements();
m_edges.PurgeAndDeleteElements();
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
CDmMeshComp::CVert::CVert( int nPositionIndex, const CUtlVector< int > *pVertexIndices, const Vector *pPosition )
: m_positionIndex( nPositionIndex )
, m_pVertexIndices( pVertexIndices )
, m_pPosition( pPosition )
, m_edges( 8, 8 )
{
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
CDmMeshComp::CVert::CVert( const CVert &src )
: m_positionIndex( src.m_positionIndex )
, m_pVertexIndices( src.m_pVertexIndices )
, m_pPosition( src.m_pPosition )
, m_edges( 8, 8 )
{
m_edges.AddMultipleToTail( src.m_edges.Count(), src.m_edges.Base() );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int CDmMeshComp::CVert::PositionIndex() const
{
return m_positionIndex;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
const Vector *CDmMeshComp::CVert::Position() const
{
return m_pPosition;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
const CUtlVector< int > *CDmMeshComp::CVert::VertexIndices() const
{
return m_pVertexIndices;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
bool CDmMeshComp::CVert::operator==( const CVert &rhs ) const
{
return ( m_pPosition->DistToSqr( *rhs.m_pPosition ) < FLT_EPSILON );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
CDmMeshComp::CEdge::CEdge()
: m_pVert0( NULL )
, m_pVert1( NULL )
, m_faceCount( 0 )
{
}
//-----------------------------------------------------------------------------
// Returns the vertex position index given the edge relative vertex index
//-----------------------------------------------------------------------------
int CDmMeshComp::CEdge::GetVertPositionIndex( int edgeRelativeVertexIndex ) const
{
if ( edgeRelativeVertexIndex == 0 && m_pVert0 )
return m_pVert0->PositionIndex();
if ( edgeRelativeVertexIndex == 1 && m_pVert1 )
return m_pVert1->PositionIndex();
return -1;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
CDmMeshComp::CVert *CDmMeshComp::CEdge::GetVert( int edgeRelativeVertexIndex ) const
{
if ( edgeRelativeVertexIndex == 0 )
return m_pVert0;
if ( edgeRelativeVertexIndex == 1 )
return m_pVert1;
return NULL;
}
//-----------------------------------------------------------------------------
// Returns true if the edge starts and stops at the same position in space
// The order of the vertices is not checked
//-----------------------------------------------------------------------------
bool CDmMeshComp::CEdge::operator==( const CEdge &rhs ) const
{
return (
( *m_pVert0 == *rhs.m_pVert0 && *m_pVert1 == *rhs.m_pVert1 ) ||
( *m_pVert0 == *rhs.m_pVert1 && *m_pVert1 == *rhs.m_pVert0 ) );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
Vector CDmMeshComp::CEdge::EdgeVector() const
{
if ( m_pVert0 && m_pVert1 )
return *m_pVert1->Position() - *m_pVert0->Position();
return vec3_origin;
}
//-----------------------------------------------------------------------------
// Finds or Creates an edge... Can still return NULL if vertices do not exist
//-----------------------------------------------------------------------------
CDmMeshComp::CEdge *CDmMeshComp::FindOrCreateEdge( int vIndex0, int vIndex1, bool *pReverse /* = NULL */ )
{
CEdge *pEdge = FindEdge( vIndex0, vIndex1, pReverse );
if ( pEdge )
return pEdge;
CVert *pVert0 = m_verts[ vIndex0 ];
if ( pVert0 == NULL )
return NULL;
CVert *pVert1 = m_verts[ vIndex1 ];
if ( pVert1 == NULL )
return NULL;
pEdge = m_edges[ m_edges.AddToTail( new CEdge() ) ];
pEdge->m_pVert0 = pVert0;
pEdge->m_pVert1 = pVert1;
pVert0->m_edges.AddToTail( pEdge );
if ( vIndex0 != vIndex1 )
pVert1->m_edges.AddToTail( pEdge );
if ( pReverse )
{
*pReverse = false;
}
return pEdge;
}
//-----------------------------------------------------------------------------
// Returns the edge between vIndex0 & vIndex1 (or vice versa), NULL if not found
//-----------------------------------------------------------------------------
CDmMeshComp::CEdge *CDmMeshComp::FindEdge( int vIndex0, int vIndex1, bool *pReverse /* = NULL */ )
{
CUtlVector< CEdge * > &edges = m_verts[ vIndex0 ]->m_edges;
for ( int i = 0; i < edges.Count(); i++ )
{
CEdge *e = edges[ i ];
if ( e->GetVertPositionIndex( 0 ) == vIndex0 && e->GetVertPositionIndex( 1 ) == vIndex1 )
{
if ( pReverse )
{
*pReverse = false;
}
return e;
}
if ( e->GetVertPositionIndex( 1 ) == vIndex0 && e->GetVertPositionIndex( 0 ) == vIndex1 )
{
if ( pReverse )
{
*pReverse = true;
}
return e;
}
}
return NULL;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
CDmMeshComp::CFace *CDmMeshComp::CreateFace( const CUtlVector< CVert * > &verts, const CUtlVector< CEdge * > &edges, const CUtlVector< bool > &edgeReverseMap )
{
CFace *pFace = &m_faces[ m_faces.AddToTail() ];
pFace->m_verts.RemoveAll();
pFace->m_verts.AddVectorToTail( verts );
pFace->m_edges.RemoveAll();
pFace->m_edges.AddVectorToTail( edges );
pFace->m_edgeReverseMap.RemoveAll();
pFace->m_edgeReverseMap.AddVectorToTail( edgeReverseMap );
for ( int nEdgeIndex = edges.Count() - 1; nEdgeIndex >= 0; --nEdgeIndex )
{
edges[ nEdgeIndex ]->m_faceCount += 1;
}
return pFace;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int CDmMeshComp::FindFacesWithVert( int vIndex, CUtlVector< CFace * > &faces )
{
// TODO: optimize this by adding a vector of face pointers to each vertex
faces.RemoveAll();
for ( int fi( m_faces.Head() ); fi != m_faces.InvalidIndex(); fi = m_faces.Next( fi ) )
{
CFace &face( m_faces[ fi ] );
for ( int i = 0; i < face.m_verts.Count(); ++i )
{
if ( face.m_verts[ i ]->PositionIndex() == vIndex )
{
faces.AddToTail( &face );
break;
}
}
}
return faces.Count();
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
int CDmMeshComp::FindNeighbouringVerts( int vIndex, CUtlVector< CVert * > &verts )
{
verts.RemoveAll();
const CUtlVector< CEdge * > & edges = m_verts[ vIndex ]->m_edges;
for ( int i = 0; i < edges.Count(); ++i )
{
CEdge *e = edges[ i ];
if ( e->GetVertPositionIndex( 0 ) == vIndex )
{
verts.AddToTail( e->GetVert( 1 ) );
}
else
{
verts.AddToTail( e->GetVert( 0 ) );
}
}
return verts.Count();
}
//-----------------------------------------------------------------------------
// Find all edges that are only used by 1 face
//-----------------------------------------------------------------------------
int CDmMeshComp::GetBorderEdges( CUtlVector< CUtlVector< CEdge * > > &borderEdgesList )
{
// TODO: optimize this by stepping from edge to edge to build chains, using CVert::m_edges
int retVal = 0;
borderEdgesList.RemoveAll();
bool connected;
for ( int ei = 0; ei < m_edges.Count(); ei++ )
{
CEdge *pEdge = m_edges[ ei ];
if ( pEdge->IsBorderEdge() )
{
++retVal;
connected = false;
for ( int i = borderEdgesList.Count() - 1; !connected && i >= 0; --i )
{
CUtlVector< CEdge * > &borderEdges = borderEdgesList[ i ];
for ( int j = borderEdges.Count() - 1; j >= 0; --j )
{
if ( borderEdges[ j ]->ConnectedTo( pEdge ) )
{
borderEdges.AddToTail( pEdge );
connected = true;
break;
}
}
}
if ( !connected )
{
CUtlVector< CEdge * > &borderEdges = borderEdgesList[ borderEdgesList.AddToTail() ];
borderEdges.AddToTail( pEdge );
}
}
}
// Shrink the borderEdgesList to minimum number required
bool anyConnected = false;
do
{
anyConnected = false;
for ( int i = borderEdgesList.Count() - 1; i >= 0; --i )
{
CUtlVector< CEdge * > &srcBorderEdges = borderEdgesList[ i ];
for ( int j = srcBorderEdges.Count() - 1; j >= 0; --j )
{
CEdge *pSrcEdge = srcBorderEdges[ j ];
connected = false;
for ( int k = 0; !connected && k < i; ++k )
{
CUtlVector< CEdge * > &dstBorderEdges = borderEdgesList[ k ];
for ( int l = dstBorderEdges.Count() - 1; l >= 0; --l )
{
if ( dstBorderEdges[ l ]->ConnectedTo( pSrcEdge ) )
{
connected = true;
anyConnected = true;
dstBorderEdges.AddToTail( pSrcEdge );
srcBorderEdges.Remove( j );
break;
}
}
}
}
if ( srcBorderEdges.Count() == 0 )
{
borderEdgesList.Remove( i );
}
}
} while( anyConnected );
return retVal;
}

3313
movieobjects/dmmeshutils.cpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1052
movieobjects/dmx_to_vcd.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,863 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects/importintovcd.h"
#include "movieobjects/movieobjects.h"
#include "tier3/scenetokenprocessor.h"
#include "choreoscene.h"
#include "choreoactor.h"
#include "choreochannel.h"
#include "choreoevent.h"
#include "tier2/p4helpers.h"
#include "tier1/utlbuffer.h"
#include "tier3/tier3.h"
#include "datacache/imdlcache.h"
#include "filesystem.h"
#include "studio.h"
//-----------------------------------------------------------------------------
// Helper wrapper class for log layers (necessary to avoid movieobjects dependence)
//-----------------------------------------------------------------------------
class CDmeLogLayerHelper
{
public:
CDmeLogLayerHelper( CDmElement *pLogLayer, int nDefaultCurveType );
// Finds a key
int FindKey( int nTime ) const;
// Gets a value at a particular time
float GetValue( int nTime ) const;
// Inserts keys
void AddToTail( int nTime, float flValue, int nCurveType );
void InsertAfter( int nAfter, int nTime, float flValue, int nCurveType );
int InsertKey( int nTime, float flValue, int nCurveType );
// Simplifies the curve
void Simplify( float flThreshhold );
void SetCurveType( int nKey, int nCurveType );
// Total simplified points
static int TotalRemovedPoints();
private:
void CurveSimplify_R( float flThreshold, int nStartPoint, int nEndPoint, CDmeLogLayerHelper *pDest );
// Computes the total error
float ComputeTotalError( CDmeLogLayerHelper *pDest, int nStartPoint, int nEndPoint );
// Select the best fit curve type
void ChooseBestCurveType( int nKey, int nStartPoint, int nEndPoint, CDmeLogLayerHelper *pDest );
// Compute first + second derivatives of data
void ComputeDerivates( float *pSlope, float *pAccel, int nPoint, CDmeLogLayerHelper *pDest );
CDmElement *m_pLogLayer;
CDmrArray<int> m_times;
CDmrArray<float> m_values;
CDmrArray<int> m_curvetypes;
int m_nDefaultCurveType;
static int s_nTotalRemovedPoints;
};
//-----------------------------------------------------------------------------
// Total simplified points
//-----------------------------------------------------------------------------
int CDmeLogLayerHelper::s_nTotalRemovedPoints = 0;
int CDmeLogLayerHelper::TotalRemovedPoints()
{
return s_nTotalRemovedPoints;
}
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
CDmeLogLayerHelper::CDmeLogLayerHelper( CDmElement *pLogLayer, int nDefaultCurveType ) :
m_pLogLayer( pLogLayer ), m_times( pLogLayer, "times", true ),
m_values( pLogLayer, "values", true ), m_curvetypes( pLogLayer, "curvetypes", true )
{
m_nDefaultCurveType = nDefaultCurveType;
}
//-----------------------------------------------------------------------------
// Inserts keys
//-----------------------------------------------------------------------------
void CDmeLogLayerHelper::AddToTail( int nTime, float flValue, int nCurveType )
{
m_times.AddToTail( nTime );
m_values.AddToTail( flValue );
m_curvetypes.AddToTail( nCurveType );
}
void CDmeLogLayerHelper::InsertAfter( int nAfter, int nTime, float flValue, int nCurveType )
{
int nBefore = nAfter + 1;
m_times.InsertBefore( nBefore, nTime );
m_values.InsertBefore( nBefore, flValue );
m_curvetypes.InsertBefore( nBefore, nCurveType );
}
int CDmeLogLayerHelper::InsertKey( int nTime, float flValue, int nCurveType )
{
int nAfter = FindKey( nTime );
InsertAfter( nAfter, nTime, flValue, nCurveType );
return nAfter + 1;
}
void CDmeLogLayerHelper::SetCurveType( int nKey, int nCurveType )
{
m_curvetypes.Set( nKey, nCurveType );
}
//-----------------------------------------------------------------------------
// Finds a key
//-----------------------------------------------------------------------------
int CDmeLogLayerHelper::FindKey( int nTime ) const
{
int tn = m_times.Count();
for ( int ti = tn - 1; ti >= 0; --ti )
{
if ( nTime >= m_times[ ti ] )
return ti;
}
return -1;
}
//-----------------------------------------------------------------------------
// Gets a value at a particular time
//-----------------------------------------------------------------------------
float CDmeLogLayerHelper::GetValue( int nTime ) const
{
int tc = m_times.Count();
Assert( m_values.Count() == tc );
int ti = FindKey( nTime );
if ( ti < 0 )
{
if ( tc > 0 )
return m_values[ 0 ];
return 0.0f;
}
// Early out if we're at the end
if ( ti >= tc - 1 )
return m_values[ ti ];
// Figure out the lerp factor
int nDummy, nInterpolationType;
int nCurveType = m_curvetypes.Count() ? m_curvetypes[ti] : m_nDefaultCurveType;
Interpolator_CurveInterpolatorsForType( nCurveType, nInterpolationType, nDummy );
Vector vecOutput;
Vector vecArg1( 0.0f, m_values[ti], 0.0f );
Vector vecArg2( 1.0f, m_values[ti+1], 0.0f );
float t = (float)( nTime - m_times[ti] ) / (float)( m_times[ti+1] - m_times[ti] );
Interpolator_CurveInterpolate( nInterpolationType, vecArg1, vecArg1, vecArg2, vecArg2, t, vecOutput );
return vecOutput.y;
}
//-----------------------------------------------------------------------------
// Computes the total error
//-----------------------------------------------------------------------------
float CDmeLogLayerHelper::ComputeTotalError( CDmeLogLayerHelper *pDest, int nStartPoint, int nEndPoint )
{
float flTotalDistance = 0.0f;
for ( int i = nStartPoint; i <= nEndPoint; ++i )
{
float flCheck = m_values[i];
float flCheck2 = pDest->GetValue( m_times[i] );
float flDistance = fabs( flCheck2 - flCheck );
flTotalDistance += flDistance;
}
return flTotalDistance;
}
//-----------------------------------------------------------------------------
// Select the best fit curve type
//-----------------------------------------------------------------------------
static int s_nInterpTypes[] =
{
INTERPOLATE_LINEAR_INTERP,
INTERPOLATE_EASE_INOUT,
// INTERPOLATE_EASE_IN,
// INTERPOLATE_EASE_OUT,
// INTERPOLATE_EXPONENTIAL_DECAY,
// INTERPOLATE_HOLD,
-1,
};
void CDmeLogLayerHelper::ChooseBestCurveType( int nKey, int nStartPoint, int nEndPoint, CDmeLogLayerHelper *pDest )
{
return;
float flMinError = FLT_MAX;
int nBestInterpType = -1;
for ( int i = 0; s_nInterpTypes[i] >= 0; ++i )
{
pDest->SetCurveType( nKey, MAKE_CURVE_TYPE( s_nInterpTypes[i], s_nInterpTypes[i] ) );
float flError = ComputeTotalError( pDest, nStartPoint, nEndPoint );
if ( flMinError > flError )
{
nBestInterpType = s_nInterpTypes[i];
flMinError = flError;
}
}
Assert( nBestInterpType >= 0 );
pDest->SetCurveType( nKey, MAKE_CURVE_TYPE( nBestInterpType, nBestInterpType ) );
}
//-----------------------------------------------------------------------------
// Compute first + second derivatives of data
//-----------------------------------------------------------------------------
void CDmeLogLayerHelper::ComputeDerivates( float *pSlope, float *pAccel, int nPoint, CDmeLogLayerHelper *pDest )
{
// Central difference, assume linear slope between points.
// Find neighboring point with minimum distance
bool bLeftEdge = ( nPoint == 0 );
bool bRightEdge = ( nPoint == m_times.Count() - 1 );
int nTime = m_times[nPoint];
int nPrevTime = ( !bLeftEdge ) ? m_times[ nPoint - 1 ] : nTime - 1000;
int nNextTime = ( !bRightEdge ) ? m_times[ nPoint + 1 ] : nTime + 1000;
float flPrevPoint, flNextPoint;
if ( nTime - nPrevTime < nNextTime - nTime )
{
// prev point is closer
flPrevPoint = ( !bLeftEdge ) ? m_values[ nPoint - 1 ] : m_values[ nPoint ];
nNextTime = nTime + ( nTime - nPrevTime );
flNextPoint = GetValue( nNextTime );
}
else
{
// next point is closer
flNextPoint = ( !bRightEdge ) ? m_values[ nPoint + 1 ] : m_values[ nPoint ];
nPrevTime = nTime - ( nNextTime - nTime );
flPrevPoint = GetValue( nPrevTime );
}
// Central difference: slope = ( vnext - vprev ) / ( tnext - tprev );
// accel = ( vnext - 2 * vcurr + vprev ) / ( 0.5 * ( tnext - tprev ) )^2
float flCurrPoint = m_values[nPoint];
flPrevPoint -= pDest->GetValue( nPrevTime );
flCurrPoint -= pDest->GetValue( nTime );
flNextPoint -= pDest->GetValue( nNextTime );
float flDeltaTime = DMETIME_TO_SECONDS( nTime - nPrevTime );
*pSlope = ( flNextPoint - flPrevPoint ) / ( 2.0f * flDeltaTime );
*pAccel = ( flNextPoint - 2 * flCurrPoint + flPrevPoint ) / ( flDeltaTime * flDeltaTime );
}
//-----------------------------------------------------------------------------
// Implementation of Douglas-Peucker curve simplification routine
// (hacked to only care about error against original curve (sort of 1D)
//-----------------------------------------------------------------------------
void CDmeLogLayerHelper::CurveSimplify_R( float flThreshold, int nStartPoint, int nEndPoint, CDmeLogLayerHelper *pDest )
{
if ( nEndPoint <= nStartPoint + 1 )
return;
int nMaxPoint = nStartPoint;
float flMaxDistance = 0.0f;
for ( int i = nStartPoint + 1 ; i < nEndPoint; ++i )
{
float flCheck = m_values[i];
float flCheck2 = pDest->GetValue( m_times[i] );
float flDistance = fabs( flCheck2 - flCheck );
if ( flDistance < flMaxDistance )
continue;
nMaxPoint = i;
flMaxDistance = flDistance;
}
/*
float flMaxAccel = 0.0f;
for ( int i = nStartPoint + 1 ; i < nEndPoint; ++i )
{
float flSlope, flAccel;
ComputeDerivates( &flSlope, &flAccel, i, pDest );
flAccel = fabs( flAccel );
if ( flAccel < flMaxAccel )
continue;
nMaxPoint = i;
flMaxAccel = flAccel;
}
*/
if ( flMaxDistance > flThreshold )
{
int nKey = pDest->InsertKey( m_times[ nMaxPoint ], m_values[ nMaxPoint ], m_nDefaultCurveType );
Assert( nKey != 0 );
ChooseBestCurveType( nKey-1, nStartPoint, nMaxPoint, pDest );
ChooseBestCurveType( nKey, nMaxPoint, nEndPoint, pDest );
CurveSimplify_R( flThreshold, nStartPoint, nMaxPoint, pDest );
CurveSimplify_R( flThreshold, nMaxPoint, nEndPoint, pDest );
}
}
//-----------------------------------------------------------------------------
// Simplifies the curve
//-----------------------------------------------------------------------------
void CDmeLogLayerHelper::Simplify( float flThreshhold )
{
int nFirstKey, nLastKey;
int nKeys = m_values.Count();
if ( nKeys <= 1 )
return;
for ( nFirstKey = 1; nFirstKey < nKeys; ++nFirstKey )
{
// FIXME: Should we use a tolerance check here?
if ( m_values[ nFirstKey ] != m_values[ nFirstKey - 1 ] )
break;
}
--nFirstKey;
for ( nLastKey = nKeys; --nLastKey >= 1; )
{
// FIXME: Should we use a tolerance check here?
if ( m_values[ nLastKey ] != m_values[ nLastKey - 1 ] )
break;
}
if ( nLastKey <= nFirstKey )
{
m_times.RemoveMultiple( 1, nKeys - 1 );
m_values.RemoveMultiple( 1, nKeys - 1 );
s_nTotalRemovedPoints += nKeys - 1;
return;
}
CDmElement *pTemp = CreateElement< CDmElement >( "simplified" );
CDmeLogLayerHelper destLayer( pTemp, m_nDefaultCurveType );
destLayer.AddToTail( m_times[nFirstKey], m_values[nFirstKey], m_nDefaultCurveType );
destLayer.AddToTail( m_times[nLastKey], m_values[nLastKey], m_nDefaultCurveType );
// Recursively finds the point with the largest error from the "simplified curve"
// and subdivides the problem on both sides until the largest delta from the simplified
// curve is less than the tolerance
CurveSimplify_R( flThreshhold, nFirstKey, nLastKey, &destLayer );
m_times.CopyArray( destLayer.m_times.Base(), destLayer.m_times.Count() );
m_values.CopyArray( destLayer.m_values.Base(), destLayer.m_values.Count() );
m_curvetypes.CopyArray( destLayer.m_curvetypes.Base(), destLayer.m_curvetypes.Count() );
DestroyElement( pTemp );
s_nTotalRemovedPoints += nKeys - m_times.Count();
}
//-----------------------------------------------------------------------------
// Finds or adds actors, channels
//-----------------------------------------------------------------------------
static CChoreoActor* FindOrAddActor( CChoreoScene *pScene, const char *pActorName, const char *pActorModel )
{
CChoreoActor *a = pScene->FindActor( pActorName );
if ( !a )
{
a = pScene->AllocActor();
Assert( a );
a->SetName( pActorName );
a->SetActive( true );
a->SetFacePoserModelName( pActorModel );
}
return a;
}
//-----------------------------------------------------------------------------
// Finds animation events
//-----------------------------------------------------------------------------
static CChoreoEvent* FindOrAddAnimationEvent( CChoreoScene *pScene, CChoreoActor *pActor )
{
int nEventCount = pScene->GetNumEvents();
for ( int i = 0; i < nEventCount; ++i )
{
CChoreoEvent* pEvent = pScene->GetEvent(i);
if ( pEvent->GetActor() != pActor )
continue;
if ( pEvent->GetType() != CChoreoEvent::FLEXANIMATION )
continue;
return pEvent;
}
// Allocate new channel
CChoreoChannel *pChannel = pScene->AllocChannel();
pChannel->SetName( "imported_flex" );
pChannel->SetActor( pActor );
pChannel->SetActive( true );
pActor->AddChannel( pChannel );
// Allocate choreo event
CChoreoEvent *pEvent = pScene->AllocEvent();
pEvent->SetName( pActor->GetName() );
pEvent->SetType( CChoreoEvent::FLEXANIMATION );
pEvent->SetActor( pActor );
pEvent->SetChannel( pChannel );
pEvent->SetActive( true );
pChannel->AddEvent( pEvent );
return pEvent;
}
//-----------------------------------------------------------------------------
// Finds sound events
//-----------------------------------------------------------------------------
static CChoreoEvent* FindOrAddSoundEvent( CChoreoScene *pScene, CChoreoActor *pActor, const char *pEventName )
{
int nEventCount = pScene->GetNumEvents();
for ( int i = 0; i < nEventCount; ++i )
{
CChoreoEvent* pEvent = pScene->GetEvent(i);
if ( pEvent->GetActor() != pActor )
continue;
if ( pEvent->GetType() != CChoreoEvent::SPEAK )
continue;
if ( Q_stricmp( pEvent->GetName(), pEventName ) )
continue;
return pEvent;
}
// Allocate new channel
CChoreoChannel *pChannel = pScene->AllocChannel();
pChannel->SetName( "imported sounds" );
pChannel->SetActor( pActor );
pChannel->SetActive( true );
pActor->AddChannel( pChannel );
// Allocate sound event
CChoreoEvent *pEvent = pScene->AllocEvent();
pEvent->SetName( pEventName );
pEvent->SetType( CChoreoEvent::SPEAK );
pEvent->SetActor( pActor );
pEvent->SetChannel( pChannel );
pEvent->SetActive( true );
pChannel->AddEvent( pEvent );
return pEvent;
}
static CFlexAnimationTrack *FindOrCreateTrack( CChoreoEvent *pEvent, const char *pFlexControllerName )
{
CFlexAnimationTrack *pTrack = pEvent->FindTrack( pFlexControllerName );
if ( pTrack )
{
pTrack->Clear();
}
else
{
pTrack = pEvent->AddTrack( pFlexControllerName );
pTrack->SetTrackActive( true );
}
pTrack->SetMin( 0.0f );
pTrack->SetMax( 1.0f );
pTrack->SetInverted( false );
return pTrack;
}
//-----------------------------------------------------------------------------
// Returns flex controller ranges
//-----------------------------------------------------------------------------
void GetStereoFlexControllerRange( float *pMin, float *pMax, studiohdr_t *pStudioHdr, const char *pFlexName )
{
char pRightBuf[MAX_PATH];
char pLeftBuf[MAX_PATH];
Q_snprintf( pRightBuf, sizeof(pRightBuf), "right_%s", pFlexName );
Q_snprintf( pLeftBuf, sizeof(pLeftBuf), "left_%s", pFlexName );
for ( LocalFlexController_t i = LocalFlexController_t(0); i < pStudioHdr->numflexcontrollers; ++i )
{
mstudioflexcontroller_t *pFlex = pStudioHdr->pFlexcontroller( i );
const char *pFlexControllerName = pFlex->pszName();
if ( !Q_stricmp( pFlexControllerName, pFlexName ) )
{
*pMin = pFlex->min;
*pMax = pFlex->max;
return;
}
// FIXME: Probably want to get the left + right controller + find the min and max of each, but this is unnecessary.
if ( !Q_stricmp( pFlexControllerName, pRightBuf ) )
{
*pMin = pFlex->min;
*pMax = pFlex->max;
return;
}
}
*pMin = 0.0f;
*pMax = 1.0f;
}
void GetFlexControllerRange( float *pMin, float *pMax, studiohdr_t *pStudioHdr, const char *pFlexName )
{
for ( LocalFlexController_t i = LocalFlexController_t(0); i < pStudioHdr->numflexcontrollers; ++i )
{
mstudioflexcontroller_t *pFlex = pStudioHdr->pFlexcontroller( i );
const char *pFlexControllerName = pFlex->pszName();
if ( !Q_stricmp( pFlexControllerName, pFlexName ) )
{
*pMin = pFlex->min;
*pMax = pFlex->max;
return;
}
}
*pMin = 0.0f;
*pMax = 1.0f;
}
//-----------------------------------------------------------------------------
// Imports samples into a track
//-----------------------------------------------------------------------------
void ImportSamplesIntoTrack( CFlexAnimationTrack *pTrack, CDmElement *pLog, int nSampleType, int nTimeOffset, const ImportVCDInfo_t& info )
{
CDmrArray<int> times( pLog, "times" );
CDmrArray<float> values( pLog, "values" );
// Add the samples
int nSampleCount = times.Count();
if ( nSampleCount == 0 )
return;
int nDefaultCurveType = MAKE_CURVE_TYPE( info.m_nInterpolationType, info.m_nInterpolationType );
if ( info.m_flSimplificationThreshhold > 0.0f )
{
CDmeLogLayerHelper helper( pLog, nDefaultCurveType );
helper.Simplify( info.m_flSimplificationThreshhold );
}
CDmrArray<int> curveTypes( pLog, "curvetypes" );
nSampleCount = times.Count();
bool bHasCurveTypeData = ( curveTypes.Count() > 0 );
for ( int j = 0; j < nSampleCount; ++j )
{
int nCurveType = bHasCurveTypeData ? curveTypes[j] : nDefaultCurveType;
float flValue = values[j];
float flTime = DMETIME_TO_SECONDS( times[j] - nTimeOffset );
CExpressionSample *pSample = pTrack->AddSample( flTime, flValue, nSampleType );
pSample->SetCurveType( nCurveType );
}
if ( nSampleType == 0 )
{
pTrack->SetEdgeActive( true, true );
pTrack->SetEdgeActive( false, true );
int nCurveType0, nCurveType1;
if ( bHasCurveTypeData )
{
nCurveType0 = curveTypes[0];
nCurveType1 = curveTypes[nSampleCount-1];
}
else
{
nCurveType0 = nCurveType1 = nDefaultCurveType;
}
pTrack->SetEdgeInfo( true, nCurveType0, values[ 0 ] );
pTrack->SetEdgeInfo( false, nCurveType1, values[ nSampleCount-1 ] );
}
}
//-----------------------------------------------------------------------------
// Imports mono log data into a event, creates a new track if necessary
//-----------------------------------------------------------------------------
void ImportMonoLogDataIntoEvent( studiohdr_t *pStudioHdr, CChoreoEvent *pEvent, const char *pTrackName, CDmElement *pLog, int nTimeOffset, const ImportVCDInfo_t& info )
{
CDmrArray<int> times( pLog, "times" );
if ( times.Count() == 0 )
return;
float flMin, flMax;
GetFlexControllerRange( &flMin, &flMax, pStudioHdr, pTrackName );
CFlexAnimationTrack *pTrack = FindOrCreateTrack( pEvent, pTrackName );
pTrack->Clear();
pTrack->SetComboType( false );
pTrack->SetMin( flMin );
pTrack->SetMax( flMax );
ImportSamplesIntoTrack( pTrack, pLog, 0, nTimeOffset, info );
}
//-----------------------------------------------------------------------------
// Imports stereo log data into a event, creates a new track if necessary
//-----------------------------------------------------------------------------
void ImportStereoLogDataIntoEvent( studiohdr_t *pStudioHdr, CChoreoEvent *pEvent, const char *pTrackName, CDmElement *pValueLog, CDmElement *pBalanceLog, int nTimeOffset, const ImportVCDInfo_t& info )
{
CDmrArray<int> valueTimes( pValueLog, "times" );
CDmrArray<int> balanceTimes( pBalanceLog, "times" );
if ( valueTimes.Count() == 0 && balanceTimes.Count() == 0 )
return;
float flMin, flMax;
GetStereoFlexControllerRange( &flMin, &flMax, pStudioHdr, pTrackName );
CFlexAnimationTrack *pTrack = FindOrCreateTrack( pEvent, pTrackName );
pTrack->Clear();
pTrack->SetComboType( true );
pTrack->SetMin( flMin );
pTrack->SetMax( flMax );
ImportSamplesIntoTrack( pTrack, pValueLog, 0, nTimeOffset, info );
ImportSamplesIntoTrack( pTrack, pBalanceLog, 1, nTimeOffset, info );
}
//-----------------------------------------------------------------------------
// Compute track start, end time
//-----------------------------------------------------------------------------
static int ComputeEventTime( CDmElement *pRoot, CChoreoEvent *pEvent )
{
int nStartTime = INT_MAX;
int nEndTime = INT_MIN;
// Iterate over all elements in the animations attribute; each one refers to a log.
CDmrElementArray<> animations( pRoot, "animations" );
if ( !animations.IsValid() )
return 0;
int nCount = animations.Count();
for( int i = 0; i < nCount; ++i )
{
CDmElement *pLog = animations[i];
if ( !pLog )
continue;
CDmrArray<int> times( pLog, "times" );
int nSampleCount = times.Count();
if ( nSampleCount == 0 )
continue;
if ( nStartTime > times[0] )
{
nStartTime = times[0];
}
if ( nEndTime < times[nSampleCount-1] )
{
nEndTime = times[nSampleCount-1];
}
}
pEvent->SetStartTime( DMETIME_TO_SECONDS( nStartTime ) );
pEvent->SetEndTime( DMETIME_TO_SECONDS( nEndTime ) );
return nStartTime;
}
//-----------------------------------------------------------------------------
// Main entry point for importing animations
//-----------------------------------------------------------------------------
void ImportAnimations( CDmElement *pRoot, CChoreoScene *pChoreoScene, CChoreoActor *pActor, studiohdr_t *pStudioHdr, const ImportVCDInfo_t& info )
{
CChoreoEvent *pEvent = FindOrAddAnimationEvent( pChoreoScene, pActor );
pEvent->SetDefaultCurveType( MAKE_CURVE_TYPE( info.m_nInterpolationType, info.m_nInterpolationType ) );
int nTimeOffset = ComputeEventTime( pRoot, pEvent );
// Iterate over all elements in the animations attribute; each one refers to a log.
CDmrElementArray<> animations( pRoot, "animations" );
if ( !animations.IsValid() )
return;
int nCount = animations.Count();
for( int i = 0; i < nCount; ++i )
{
CDmElement *pLog = animations[i];
if ( !pLog )
continue;
const char *pLogName = pLog->GetName();
// Balance is done at the same time as value
if ( StringHasPrefix( pLogName, "balance_" ) )
continue;
if ( StringHasPrefix( pLogName, "value_" ) )
{
if ( i == nCount - 1 )
continue;
char pBalanceName[256];
Q_snprintf( pBalanceName, sizeof(pBalanceName), "balance_%s", pLogName + 6 );
CDmElement *pBalanceLog = animations[i+1];
if ( !Q_stricmp( pBalanceName, pBalanceLog->GetName() ) )
{
++i;
}
else
{
pBalanceLog = NULL;
}
if ( pBalanceLog )
{
ImportStereoLogDataIntoEvent( pStudioHdr, pEvent, pLogName + 6, pLog, pBalanceLog, nTimeOffset, info );
}
}
else
{
ImportMonoLogDataIntoEvent( pStudioHdr, pEvent, pLogName, pLog, nTimeOffset, info );
}
}
}
//-----------------------------------------------------------------------------
// Main entry point for importing sounds
//-----------------------------------------------------------------------------
void ImportSounds( CDmElement *pRoot, CChoreoScene *pChoreoScene, CChoreoActor *pActor, const ImportVCDInfo_t& info )
{
// Iterate over all element in the sound attribute; each one refers to a sound
CDmrElementArray<> sounds( pRoot, "sounds" );
if ( !sounds.IsValid() )
return;
int nCount = sounds.Count();
for( int i = 0; i < nCount; ++i )
{
CDmElement *pSound = sounds[i];
if ( !pSound )
continue;
const char *pEventName = pSound->GetName();
CChoreoEvent *pEvent = FindOrAddSoundEvent( pChoreoScene, pActor, pEventName );
int nStart = pSound->GetValue<int>( "start" );
int nEnd = pSound->GetValue<int>( "end" );
const char *pGameSound = pSound->GetValueString( "gamesound" );
pEvent->SetStartTime( DMETIME_TO_SECONDS( nStart ) );
pEvent->SetEndTime( DMETIME_TO_SECONDS( nEnd ) );
pEvent->SetParameters( pGameSound );
pEvent->SetCloseCaptionType( CChoreoEvent::CC_MASTER );
}
}
//-----------------------------------------------------------------------------
// Main entry point for importing a .fac file into a .vcd file
//-----------------------------------------------------------------------------
bool ImportLogsIntoVCD( const char *pFacFullPath, CChoreoScene *pChoreoScene, const ImportVCDInfo_t& info )
{
CDmElement *pRoot;
DmFileId_t id = g_pDataModel->RestoreFromFile( pFacFullPath, NULL, NULL, &pRoot, CR_FORCE_COPY );
if ( id == DMFILEID_INVALID )
{
Warning( "Unable to load file %s\n", pFacFullPath );
return false;
}
pChoreoScene->IgnorePhonemes( info.m_bIgnorePhonemes );
// Create the actor in the scene
const char *pActorName = pRoot->GetName();
const char *pActorModel = pRoot->GetValueString( "gamemodel" );
MDLHandle_t hMDL = g_pMDLCache->FindMDL( pActorModel );
if ( hMDL == MDLHANDLE_INVALID )
{
Warning( "vcdimport: Model %s doesn't exist!\n", pActorModel );
return false;
}
studiohdr_t *pStudioHdr = g_pMDLCache->GetStudioHdr( hMDL );
if ( !pStudioHdr || g_pMDLCache->IsErrorModel( hMDL ) )
{
Warning( "vcdimport: Model %s doesn't exist!\n", pActorModel );
return false;
}
CChoreoActor *pActor = FindOrAddActor( pChoreoScene, pActorName, pActorModel );
ImportAnimations( pRoot, pChoreoScene, pActor, pStudioHdr, info );
ImportSounds( pRoot, pChoreoScene, pActor, info );
DestroyElement( pRoot, TD_DEEP );
return true;
}
//-----------------------------------------------------------------------------
// Main entry point for importing a .fac file into a .vcd file
//-----------------------------------------------------------------------------
bool ImportLogsIntoVCD( const char *pFacFullPath, const char *pVCDInFullPath, const char *pVCDOutPath, const ImportVCDInfo_t& info )
{
CUtlBuffer buf;
if ( !g_pFullFileSystem->ReadFile( pVCDInFullPath, NULL, buf ) )
{
Warning( "Unable to load file %s\n", pVCDInFullPath );
return false;
}
SetTokenProcessorBuffer( (char *)buf.Base() );
CChoreoScene *pScene = ChoreoLoadScene( pVCDInFullPath, NULL, GetTokenProcessor(), NULL );
if ( !pScene )
{
Warning( "Unable to parse file %s\n", pVCDInFullPath );
return false;
}
bool bOk = ImportLogsIntoVCD( pFacFullPath, pScene, info );
if ( !bOk )
return false;
Msg( "Removed %d samples\n", CDmeLogLayerHelper::TotalRemovedPoints() );
char pTemp[MAX_PATH];
if ( !Q_IsAbsolutePath( pVCDOutPath ) )
{
g_pFullFileSystem->RelativePathToFullPath( pVCDOutPath, NULL, pTemp, sizeof(pTemp) );
if ( !Q_IsAbsolutePath( pTemp ) )
{
char pDir[MAX_PATH];
if ( g_pFullFileSystem->GetCurrentDirectory( pDir, sizeof(pDir) ) )
{
Q_ComposeFileName( pDir, pVCDOutPath, pTemp, sizeof(pTemp) );
pVCDOutPath = pTemp;
}
}
else
{
pVCDOutPath = pTemp;
}
}
CP4AutoEditFile checkout( pVCDOutPath );
return pScene->SaveToFile( pVCDOutPath );
}

View File

@ -0,0 +1,162 @@
//-----------------------------------------------------------------------------
// MOVIEOBJECTS.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$Macro SRCDIR ".."
$include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
$Configuration
{
$Compiler
{
$PreprocessorDefinitions "$BASE;MOVIEOBJECTS_LIB"
}
}
$Project "Movieobjects"
{
$Folder "Header Files"
{
$File "movieobjects_interfaces.h"
}
$Folder "Source Files"
{
$File "dmeanimationlist.cpp"
$File "dmeanimationset.cpp"
$File "dmeattachment.cpp"
$File "dmebalancetostereocalculatoroperator.cpp"
$File "dmebookmark.cpp"
$File "dmecamera.cpp"
$File "dmechannel.cpp"
$File "dmeclip.cpp"
$File "dmecombinationoperator.cpp"
$File "dmedag.cpp"
$File "dmedccmakefile.cpp"
$File "dmeeditortypedictionary.cpp"
$File "dmeexpressionoperator.cpp"
$File "dmefaceset.cpp"
$File "dmegamemodel.cpp"
$File "dmegamemodelinput.cpp"
$File "dmeinput.cpp"
$File "dmejoint.cpp"
$File "dmekeyboardinput.cpp"
$File "dmelight.cpp"
$File "dmelog.cpp"
$File "dmemakefile.cpp"
$File "dmemakefileutils.cpp"
$File "dmematerial.cpp"
$File "dmematerialoverlayfxclip.cpp"
$File "dmemdl.cpp"
$File "dmemdlmakefile.cpp"
$File "dmemesh.cpp"
$File "dmemodel.cpp"
$File "dmemorphoperator.cpp"
$File "dmemouseinput.cpp"
$File "dmeoperator.cpp"
$File "dmepackoperators.cpp"
$File "dmeparticlesystemdefinition.cpp"
$File "dmephonememapping.cpp"
$File "dmeselection.cpp"
$File "dmeshape.cpp"
$File "dmesound.cpp"
$File "dmetimeframe.cpp"
$File "dmetimeselection.cpp"
$File "dmetrack.cpp"
$File "dmetrackgroup.cpp"
$File "dmetransform.cpp"
$File "dmetransforminput.cpp"
$File "dmetransformlist.cpp"
$File "dmetransformoperator.cpp"
$File "dmeunpackoperators.cpp"
$File "dmevertexdata.cpp"
$File "dmobjserializer.cpp"
$File "movieobjects_interfaces.cpp"
$File "$SRCDIR\common\movieobjects\timeutils.cpp"
$File "dmedrawsettings.cpp"
$File "dmmeshutils.cpp"
$File "dmmeshcomp.cpp"
$File "dmeeyeposition.cpp"
$File "dmeeyeball.cpp"
$File "dmmeshutils.cpp"
$File "dmsmdserializer.cpp"
}
$Folder "Interface"
{
$File "$SRCDIR\public\movieobjects\dmeanimationlist.h"
$File "$SRCDIR\public\movieobjects\dmeanimationset.h"
$File "$SRCDIR\public\movieobjects\dmebalancetostereocalculatoroperator.h"
$File "$SRCDIR\public\movieobjects\dmebookmark.h"
$File "$SRCDIR\public\movieobjects\dmecamera.h"
$File "$SRCDIR\public\movieobjects\dmechannel.h"
$File "$SRCDIR\public\movieobjects\dmeclip.h"
$File "$SRCDIR\public\movieobjects\dmecombinationoperator.h"
$File "$SRCDIR\public\movieobjects\dmedag.h"
$File "$SRCDIR\public\movieobjects\dmedccmakefile.h"
$File "$SRCDIR\public\movieobjects\dmeexpressionoperator.h"
$File "$SRCDIR\public\movieobjects\dmefaceset.h"
$File "$SRCDIR\public\movieobjects\dmegamemodel.h"
$File "$SRCDIR\public\movieobjects\dmegamemodelinput.h"
$File "$SRCDIR\public\movieobjects\dmeinput.h"
$File "$SRCDIR\public\movieobjects\dmejoint.h"
$File "$SRCDIR\public\movieobjects\dmekeyboardinput.h"
$File "$SRCDIR\public\movieobjects\dmelight.h"
$File "$SRCDIR\public\movieobjects\dmelog.h"
$File "$SRCDIR\public\movieobjects\dmemakefile.h"
$File "$SRCDIR\public\movieobjects\dmemakefileutils.h"
$File "$SRCDIR\public\movieobjects\dmematerial.h"
$File "$SRCDIR\public\movieobjects\dmemdl.h"
$File "$SRCDIR\public\movieobjects\dmemdlmakefile.h"
$File "$SRCDIR\public\movieobjects\dmemesh.h"
$File "$SRCDIR\public\movieobjects\dmemodel.h"
$File "$SRCDIR\public\movieobjects\dmemorphoperator.h"
$File "$SRCDIR\public\movieobjects\dmemouseinput.h"
$File "$SRCDIR\public\movieobjects\dmeoperator.h"
$File "$SRCDIR\public\movieobjects\dmepackoperators.h"
$File "$SRCDIR\public\movieobjects\dmephonememapping.h"
$File "$SRCDIR\public\movieobjects\dmeselection.h"
$File "$SRCDIR\public\movieobjects\dmeshape.h"
$File "$SRCDIR\public\movieobjects\dmesound.h"
$File "$SRCDIR\public\movieobjects\dmetestmesh.h"
$File "$SRCDIR\public\movieobjects\dmetimeframe.h"
$File "$SRCDIR\public\movieobjects\dmetimeselection.h"
$File "$SRCDIR\public\movieobjects\dmetimeselectiontimes.h"
$File "$SRCDIR\public\movieobjects\dmetrack.h"
$File "$SRCDIR\public\movieobjects\dmetrackgroup.h"
$File "$SRCDIR\public\movieobjects\dmetransform.h"
$File "$SRCDIR\public\movieobjects\dmetransforminput.h"
$File "$SRCDIR\public\movieobjects\dmetransformlist.h"
$File "$SRCDIR\public\movieobjects\dmetransformoperator.h"
$File "$SRCDIR\public\movieobjects\dmeunpackoperators.h"
$File "$SRCDIR\public\movieobjects\dmevertexdata.h"
$File "$SRCDIR\public\movieobjects\dmobjserializer.h"
$File "$SRCDIR\public\movieobjects\idmemakefileutils.h"
$File "$SRCDIR\public\movieobjects\movieobjects.h"
$File "$SRCDIR\public\movieobjects\timeutils.h"
$File "$SRCDIR\public\movieobjects\dmeattachment.h"
$File "$SRCDIR\public\movieobjects\dmeeditortypedictionary.h"
$File "$SRCDIR\public\movieobjects\dmeparticlesystemdefinition.h"
$File "$SRCDIR\public\movieobjects\dmematerialoverlayfxclip.h"
$File "$SRCDIR\public\movieobjects\dmedrawsettings.h"
$File "$SRCDIR\public\movieobjects\dmmeshutils.h"
$File "$SRCDIR\public\movieobjects\dmmeshcomp.h"
$File "$SRCDIR\public\movieobjects\dmeeyeposition.h"
$File "$SRCDIR\public\movieobjects\dmeeyeball.h"
$File "$SRCDIR\public\movieobjects\dmmeshutils.h"
$File "$SRCDIR\public\movieobjects\dmsmdserializer.h"
}
$Folder "external"
{
$File "$SRCDIR\public\bone_setup.cpp"
$File "$SRCDIR\public\collisionutils.cpp"
$File "$SRCDIR\public\mathlib\mathlib.h"
$File "$SRCDIR\public\phonemeconverter.cpp"
$File "$SRCDIR\public\phonemeconverter.h"
$File "$SRCDIR\public\studio.cpp"
$File "$SRCDIR\public\mathlib\vector.h"
}
}

View File

@ -0,0 +1,8 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "movieobjects_interfaces.h"
IGlobalFlexController *g_pGlobalFlexController = 0;

View File

@ -0,0 +1,36 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#ifndef MOVIEOBJECTS_INTERFACE_H
#define MOVIEOBJECTS_INTERFACE_H
#ifdef _WIN32
#pragma once
#endif
//-----------------------------------------------------------------------------
// typedefs that should be in platform.h
//-----------------------------------------------------------------------------
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class IGlobalFlexController;
//-----------------------------------------------------------------------------
// Global interfaces used by the movieobjects library
//-----------------------------------------------------------------------------
extern IGlobalFlexController *g_pGlobalFlexController;
#endif // MOVIEOBJECTS_INTERFACE_H