source-engine/public/movieobjects/dmeclip.h

545 lines
18 KiB
C
Raw Normal View History

2020-04-22 16:56:21 +00:00
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#ifndef DMECLIP_H
#define DMECLIP_H
#ifdef _WIN32
#pragma once
#endif
#include "datamodel/dmelement.h"
#include "datamodel/dmattribute.h"
#include "datamodel/dmattributevar.h"
#include "datamodel/dmehandle.h"
#include "video/ivideoservices.h"
#include "materialsystem/MaterialSystemUtil.h"
#include "tier1/utlmap.h"
#include "movieobjects/timeutils.h"
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class CDmeClip;
class CDmeTimeFrame;
class CDmeBookmark;
class CDmeSound;
class CDmeChannel;
class CDmeCamera;
class CDmeLight;
class CDmeDag;
class CDmeInput;
class CDmeOperator;
class CDmeMaterial;
class CDmeTrack;
class CDmeTrackGroup;
class IMaterial;
class CDmeChannelsClip;
class CDmeAnimationSet;
class CDmeMaterialOverlayFXClip;
class DmeLog_TimeSelection_t;
struct Rect_t;
enum DmeClipSkipFlag_t
{
DMESKIP_NONE = 0,
DMESKIP_MUTED = 1,
DMESKIP_INVISIBLE = 2,
};
DEFINE_ENUM_BITWISE_OPERATORS( DmeClipSkipFlag_t )
//-----------------------------------------------------------------------------
// Clip types
//-----------------------------------------------------------------------------
enum DmeClipType_t
{
DMECLIP_UNKNOWN = -1,
DMECLIP_FIRST = 0,
DMECLIP_CHANNEL = 0,
DMECLIP_SOUND,
DMECLIP_FX,
DMECLIP_FILM,
DMECLIP_LAST = DMECLIP_FILM,
DMECLIP_TYPE_COUNT
};
DEFINE_ENUM_INCREMENT_OPERATORS( DmeClipType_t )
typedef CUtlVector< CDmeHandle< CDmeClip > > DmeClipStack_t;
//-----------------------------------------------------------------------------
// Is a particular clip type non-overlapping?
//-----------------------------------------------------------------------------
inline bool IsNonoverlapping( DmeClipType_t type )
{
return ( type == DMECLIP_FILM );
}
//-----------------------------------------------------------------------------
// String to clip type + back
//-----------------------------------------------------------------------------
DmeClipType_t ClipTypeFromString( const char *pName );
const char *ClipTypeToString( DmeClipType_t type );
//-----------------------------------------------------------------------------
// Used to move clips in non-film track groups with film clips
//-----------------------------------------------------------------------------
struct ClipAssociation_t
{
enum AssociationType_t
{
HAS_CLIP = 0,
BEFORE_START,
AFTER_END,
NO_MOVEMENT,
};
AssociationType_t m_nType;
CDmeHandle< CDmeClip > m_hClip;
CDmeHandle< CDmeClip > m_hAssociation;
DmeTime_t m_offset;
};
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
class CDmeClip : public CDmElement
{
DEFINE_ELEMENT( CDmeClip, CDmElement );
public:
// Inherited from IDmElement
virtual void OnAttributeArrayElementAdded( CDmAttribute *pAttribute, int nFirstElem, int nLastElem );
virtual void OnAttributeArrayElementRemoved( CDmAttribute *pAttribute, int nFirstElem, int nLastElem );
// Returns the time frame
CDmeTimeFrame *GetTimeFrame() const;
DmeTime_t ToChildMediaTime ( DmeTime_t t, bool bClamp = true ) const;
DmeTime_t FromChildMediaTime( DmeTime_t t, bool bClamp = true ) const;
DmeTime_t ToChildMediaDuration ( DmeTime_t dt ) const;
DmeTime_t FromChildMediaDuration( DmeTime_t dt ) const;
DmeTime_t GetStartTime() const;
DmeTime_t GetEndTime() const;
DmeTime_t GetDuration() const;
DmeTime_t GetTimeOffset() const;
DmeTime_t GetStartInChildMediaTime() const;
DmeTime_t GetEndInChildMediaTime() const;
float GetTimeScale() const;
void SetStartTime ( DmeTime_t t );
void SetDuration ( DmeTime_t t );
void SetTimeOffset( DmeTime_t t );
void SetTimeScale ( float s );
// Given a root clip and a child (or grandchild) clip, builds the stack
// from root on down to the destination clip. If shot is specified, then it
// must build a clip stack that passes through the shot
bool BuildClipStack( DmeClipStack_t* pStack, CDmeClip *pRoot, CDmeClip *pShot = NULL );
// Clip stack versions of time conversion
static DmeTime_t ToChildMediaTime ( const DmeClipStack_t& stack, DmeTime_t globalTime, bool bClamp = true );
static DmeTime_t FromChildMediaTime ( const DmeClipStack_t& stack, DmeTime_t localTime, bool bClamp = true );
static DmeTime_t ToChildMediaDuration ( const DmeClipStack_t& stack, DmeTime_t globalDuration );
static DmeTime_t FromChildMediaDuration( const DmeClipStack_t& stack, DmeTime_t localDuration );
static void ToChildMediaTime( DmeLog_TimeSelection_t &params, const DmeClipStack_t& stack );
void SetClipColor( const Color& clr );
Color GetClipColor() const;
void SetClipText( const char *pText );
const char* GetClipText() const;
// Clip type
virtual DmeClipType_t GetClipType() { return DMECLIP_UNKNOWN; }
// Track group iteration methods
int GetTrackGroupCount() const;
CDmeTrackGroup *GetTrackGroup( int nIndex ) const;
const CUtlVector< DmElementHandle_t > &GetTrackGroups( ) const;
// Track group addition/removal
void AddTrackGroup( CDmeTrackGroup *pTrackGroup );
void AddTrackGroupBefore( CDmeTrackGroup *pTrackGroup, CDmeTrackGroup *pBefore );
CDmeTrackGroup *AddTrackGroup( const char *pTrackGroupName );
void RemoveTrackGroup( int nIndex );
void RemoveTrackGroup( CDmeTrackGroup *pTrackGroup );
void RemoveTrackGroup( const char *pTrackGroupName );
// Track group finding
CDmeTrackGroup *FindTrackGroup( const char *pTrackGroupName ) const;
int GetTrackGroupIndex( CDmeTrackGroup *pTrack ) const;
CDmeTrackGroup *FindOrAddTrackGroup( const char *pTrackGroupName );
// Swap track groups
void SwapOrder( CDmeTrackGroup *pTrackGroup1, CDmeTrackGroup *pTrackGroup2 );
// Clip finding
virtual CDmeTrack *FindTrackForClip( CDmeClip *pClip, CDmeTrackGroup **ppTrackGroup = NULL ) const;
bool FindMultiTrackGroupForClip( CDmeClip *pClip, int *pTrackGroupIndex, int *pTrackIndex = NULL, int *pClipIndex = NULL ) const;
// Finding clips in tracks by time
virtual void FindClipsAtTime( DmeClipType_t clipType, DmeTime_t time, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const;
virtual void FindClipsWithinTime( DmeClipType_t clipType, DmeTime_t startTime, DmeTime_t endTime, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const;
// Is a particular clip typed able to be added?
bool IsSubClipTypeAllowed( DmeClipType_t type ) const;
// Returns the special film track group
virtual CDmeTrackGroup *GetFilmTrackGroup() const { return NULL; }
virtual CDmeTrack *GetFilmTrack() const { return NULL; }
// Checks for muteness
void SetMute( bool state );
bool IsMute( ) const;
protected:
virtual int AllowedClipTypes() const { return 1 << DMECLIP_CHANNEL; }
// Is a track group valid to add?
bool IsTrackGroupValid( CDmeTrackGroup *pTrackGroup );
CDmaElementArray< CDmeTrackGroup > m_TrackGroups;
CDmaElement< CDmeTimeFrame > m_TimeFrame;
CDmaVar< Color > m_ClipColor;
CDmaVar< bool > m_bMute;
CDmaString m_ClipText;
};
inline bool CDmeClip::IsSubClipTypeAllowed( DmeClipType_t type ) const
{
return ( AllowedClipTypes() & ( 1 << type ) ) != 0;
}
inline void CDmeClip::SetMute( bool state )
{
m_bMute = state;
}
inline bool CDmeClip::IsMute( ) const
{
return m_bMute;
}
//-----------------------------------------------------------------------------
// Sound clip
//-----------------------------------------------------------------------------
class CDmeSoundClip : public CDmeClip
{
DEFINE_ELEMENT( CDmeSoundClip, CDmeClip );
public:
virtual DmeClipType_t GetClipType() { return DMECLIP_SOUND; }
void SetShowWave( bool state );
bool ShouldShowWave( ) const;
CDmaElement< CDmeSound > m_Sound;
CDmaVar< bool > m_bShowWave;
};
//-----------------------------------------------------------------------------
// Clip containing recorded data from the game
//-----------------------------------------------------------------------------
class CDmeChannelsClip : public CDmeClip
{
DEFINE_ELEMENT( CDmeChannelsClip, CDmeClip );
public:
virtual DmeClipType_t GetClipType() { return DMECLIP_CHANNEL; }
CDmeChannel *CreatePassThruConnection
(
char const *passThruName,
CDmElement *pFrom,
char const *pFromAttribute,
CDmElement *pTo,
char const *pToAttribute,
int index = 0
);
void RemoveChannel( CDmeChannel *pChannel );
CDmaElementArray< CDmeChannel > m_Channels;
};
//-----------------------------------------------------------------------------
// An effect clip
//-----------------------------------------------------------------------------
class CDmeFXClip : public CDmeClip
{
DEFINE_ELEMENT( CDmeFXClip, CDmeClip );
public:
virtual DmeClipType_t GetClipType() { return DMECLIP_FX; }
enum
{
MAX_FX_INPUT_TEXTURES = 2
};
// All effects must be able to apply their effect
virtual void ApplyEffect( DmeTime_t time, Rect_t &currentRect, Rect_t &totalRect, ITexture *pTextures[MAX_FX_INPUT_TEXTURES] ) {}
// Global list of FX clip types
static void InstallFXClipType( const char *pElementType, const char *pDescription );
static int FXClipTypeCount();
static const char *FXClipType( int nIndex );
static const char *FXClipDescription( int nIndex );
private:
enum
{
MAX_FXCLIP_TYPES = 16
};
static const char *s_pFXClipTypes[MAX_FXCLIP_TYPES];
static const char *s_pFXClipDescriptions[MAX_FXCLIP_TYPES];
static int s_nFXClipTypeCount;
};
//-----------------------------------------------------------------------------
// Helper Template factory for simple creation of factories
//-----------------------------------------------------------------------------
template <class T>
class CDmFXClipFactory : public CDmElementFactory<T>
{
public:
CDmFXClipFactory( const char *pLookupName, const char *pDescription ) : CDmElementFactory<T>( pLookupName )
{
CDmeFXClip::InstallFXClipType( pLookupName, pDescription );
}
};
//-----------------------------------------------------------------------------
// All effects must use IMPLEMENT_FX_CLIP_ELEMENT_FACTORY instead of IMPLEMENT_ELEMENT_FACTORY
//-----------------------------------------------------------------------------
#if defined( MOVIEOBJECTS_LIB ) || defined ( DATAMODEL_LIB ) || defined ( DMECONTROLS_LIB )
#define IMPLEMENT_FX_CLIP_ELEMENT_FACTORY( lookupName, className, description ) \
IMPLEMENT_ELEMENT( className ) \
CDmFXClipFactory< className > g_##className##_Factory( #lookupName, description ); \
CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, true ); \
className *g_##className##LinkerHack = NULL;
#else
#define IMPLEMENT_FX_CLIP_ELEMENT_FACTORY( lookupName, className, description ) \
IMPLEMENT_ELEMENT( className ) \
CDmFXClipFactory< className > g_##className##_Factory( #lookupName, description ); \
CDmElementFactoryHelper g_##className##_Helper( #lookupName, &g_##className##_Factory, false ); \
className *g_##className##LinkerHack = NULL;
#endif
//-----------------------------------------------------------------------------
// Film clip
//-----------------------------------------------------------------------------
class CDmeFilmClip : public CDmeClip
{
DEFINE_ELEMENT( CDmeFilmClip, CDmeClip );
public:
virtual DmeClipType_t GetClipType() { return DMECLIP_FILM; }
// Attribute changed
virtual void OnElementUnserialized( );
virtual void PreAttributeChanged( CDmAttribute *pAttribute );
virtual void OnAttributeChanged( CDmAttribute *pAttribute );
// Resolve
virtual void Resolve();
// Returns the special film track group
virtual CDmeTrackGroup *GetFilmTrackGroup() const;
virtual CDmeTrack *GetFilmTrack() const;
CDmeTrackGroup *FindOrCreateFilmTrackGroup();
CDmeTrack *FindOrCreateFilmTrack();
// Clip finding
virtual CDmeTrack *FindTrackForClip( CDmeClip *pClip, CDmeTrackGroup **ppTrackGroup = NULL ) const;
// Finding clips in tracks by time
virtual void FindClipsAtTime( DmeClipType_t clipType, DmeTime_t time, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const;
virtual void FindClipsWithinTime( DmeClipType_t clipType, DmeTime_t startTime, DmeTime_t endTime, DmeClipSkipFlag_t flags, CUtlVector< CDmeClip * >& clips ) const;
// mapname helper methods
const char *GetMapName();
void SetMapName( const char *pMapName );
// Returns the camera associated with the clip
CDmeCamera *GetCamera();
void SetCamera( CDmeCamera *pCamera );
// Audio volume
void SetVolume( float state );
float GetVolume() const;
// Returns the monitor camera associated with the clip (for now, only 1 supported)
CDmeCamera *GetMonitorCamera();
void AddMonitorCamera( CDmeCamera *pCamera );
void RemoveMonitorCamera( CDmeCamera *pCamera );
void SelectMonitorCamera( CDmeCamera *pCamera );
int FindMonitorCamera( CDmeCamera *pCamera );
// Light helper methods
int GetLightCount();
CDmeLight *GetLight( int nIndex );
void AddLight( CDmeLight *pLight );
// Scene / Dag helper methods
void SetScene( CDmeDag *pDag );
CDmeDag *GetScene();
// helper for inputs and operators
int GetInputCount();
CDmeInput *GetInput( int nIndex );
void AddInput( CDmeInput *pInput );
void RemoveAllInputs();
void AddOperator( CDmeOperator *pOperator );
void CollectOperators( CUtlVector< DmElementHandle_t > &operators );
// Helper for overlays
// FIXME: Change this to use CDmeMaterials
IMaterial *GetOverlayMaterial();
void SetOverlay( const char *pMaterialName );
float GetOverlayAlpha();
void SetOverlayAlpha( float alpha );
void DrawOverlay( DmeTime_t time, Rect_t &currentRect, Rect_t &totalRect );
bool HasOpaqueOverlay();
// AVI tape out
void UseCachedVersion( bool bUseCachedVersion );
bool IsUsingCachedVersion() const;
IVideoMaterial *GetCachedVideoMaterial();
void SetCachedAVI( const char *pAVIFile );
int GetAnimationSetCount();
CDmeAnimationSet *GetAnimationSet( int idx );
void AddAnimationSet( CDmeAnimationSet *element );
void RemoveAllAnimationSets();
CDmaElementArray< CDmElement > &GetAnimationSets(); // raw access to the array
const CDmaElementArray< CDmElement > &GetAnimationSets() const;
const CDmaElementArray< CDmeBookmark > &GetBookmarks() const;
CDmaElementArray< CDmeBookmark > &GetBookmarks();
void SetFadeTimes( DmeTime_t fadeIn, DmeTime_t fadeOut ) { m_fadeInDuration = fadeIn.GetTenthsOfMS(); m_fadeOutDuration = fadeOut.GetTenthsOfMS(); }
void SetFadeInTime( DmeTime_t t ) { m_fadeInDuration = t.GetTenthsOfMS(); }
void SetFadeOutTime( DmeTime_t t ) { m_fadeOutDuration = t.GetTenthsOfMS(); }
DmeTime_t GetFadeInTime() const { return DmeTime_t( m_fadeInDuration.Get() ); }
DmeTime_t GetFadeOutTime() const { return DmeTime_t( m_fadeOutDuration.Get() ); }
// Used to move clips in non-film track groups with film clips
// Call BuildClipAssociations before modifying the film track,
// then UpdateAssociatedClips after modifying it.
void BuildClipAssociations( CUtlVector< ClipAssociation_t > &association, bool bHandleGaps = true );
void UpdateAssociatedClips( CUtlVector< ClipAssociation_t > &association );
// Rolls associated clips so they remain in the same relative time
void RollAssociatedClips( CDmeClip *pClip, CUtlVector< ClipAssociation_t > &association, DmeTime_t dt );
// Shifts associated clips so they remain in the same relative time when pClip is scaled
void ScaleAssociatedClips( CDmeClip *pClip, CUtlVector< ClipAssociation_t > &association, float ratio, DmeTime_t oldOffset );
private:
virtual int AllowedClipTypes() const { return (1 << DMECLIP_CHANNEL) | (1 << DMECLIP_SOUND) | (1 << DMECLIP_FX) | (1 << DMECLIP_FILM); }
CDmaElement< CDmeTrackGroup > m_FilmTrackGroup;
CDmaString m_MapName;
CDmaElement < CDmeCamera > m_Camera;
CDmaElementArray< CDmeCamera > m_MonitorCameras;
CDmaVar< int > m_nActiveMonitor;
CDmaElement < CDmeDag > m_Scene;
CDmaElementArray< CDmeLight > m_Lights;
CDmaElementArray< CDmeInput > m_Inputs;
CDmaElementArray< CDmeOperator > m_Operators;
CDmaString m_AVIFile;
CDmaVar< int > m_fadeInDuration;
CDmaVar< int > m_fadeOutDuration;
CDmaElement< CDmeMaterialOverlayFXClip >m_MaterialOverlayEffect;
CDmaVar< bool > m_bIsUsingCachedVersion;
CDmaElementArray< CDmElement > m_AnimationSets; // "animationSets"
CDmaElementArray< CDmeBookmark > m_Bookmarks;
CDmaVar< float > m_Volume;
IVideoMaterial *m_pCachedVersion;
bool m_bReloadCachedVersion;
CMaterialReference m_FadeMaterial;
};
//-----------------------------------------------------------------------------
// Fast type conversions
//-----------------------------------------------------------------------------
inline bool IsFilmClip( CDmeClip *pClip )
{
return pClip && pClip->IsA( CDmeFilmClip::GetStaticTypeSymbol() );
}
//-----------------------------------------------------------------------------
// Creates a slug clip
//-----------------------------------------------------------------------------
CDmeFilmClip *CreateSlugClip( const char *pClipName, DmeTime_t startTime, DmeTime_t endTime, DmFileId_t fileid );
//-----------------------------------------------------------------------------
// For use in template functions
//-----------------------------------------------------------------------------
template <class T>
class CDmeClipInfo
{
public:
static DmeClipType_t ClipType( ) { return DMECLIP_UNKNOWN; }
};
#define DECLARE_DMECLIP_TYPE( _className, _dmeClipType ) \
template< > class CDmeClipInfo< _className > \
{ \
public: \
static DmeClipType_t ClipType() { return _dmeClipType; } \
};
DECLARE_DMECLIP_TYPE( CDmeSoundClip, DMECLIP_SOUND )
DECLARE_DMECLIP_TYPE( CDmeChannelsClip, DMECLIP_CHANNEL )
DECLARE_DMECLIP_TYPE( CDmeFXClip, DMECLIP_FX )
DECLARE_DMECLIP_TYPE( CDmeFilmClip, DMECLIP_FILM )
#define DMECLIP_TYPE( _className ) CDmeClipInfo<T>::ClipType()
//-----------------------------------------------------------------------------
// helper methods
//-----------------------------------------------------------------------------
CDmeTrack *GetParentTrack( CDmeClip *pClip );
CDmeChannel *FindChannelTargetingElement( CDmeChannelsClip *pChannelsClip, CDmElement *pElement, const char *pAttributeName = NULL );
CDmeChannel *FindChannelTargetingElement( CDmeFilmClip *pClip, CDmElement *pElement, const char *pAttributeName, CDmeChannelsClip **ppChannelsClip, CDmeTrack **ppTrack = NULL, CDmeTrackGroup **ppTrackGroup = NULL );
#endif // DMECLIP_H