summaryrefslogtreecommitdiff
path: root/movieobjects/dmemdl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'movieobjects/dmemdl.cpp')
-rw-r--r--movieobjects/dmemdl.cpp207
1 files changed, 207 insertions, 0 deletions
diff --git a/movieobjects/dmemdl.cpp b/movieobjects/dmemdl.cpp
new file mode 100644
index 0000000..3b720f0
--- /dev/null
+++ b/movieobjects/dmemdl.cpp
@@ -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 );
+}