218 lines
6.2 KiB
C++
218 lines
6.2 KiB
C++
//====== Copyright © 1996-2004, 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;
|
|
m_bZUp = 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;
|
|
}
|
|
|
|
void CDmeMDL::ZUp( bool bZUp )
|
|
{
|
|
m_bZUp = bZUp;
|
|
}
|
|
|
|
bool CDmeMDL::IsZUp() const
|
|
{
|
|
return m_bZUp;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// 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, m_bZUp );
|
|
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, m_bZUp );
|
|
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 );
|
|
}
|
|
|
|
CMatRenderData< matrix3x4_t > rdPoseToWorld( pRenderContext, pStudioHdr->numbones );
|
|
matrix3x4_t *pPoseToWorld = rdPoseToWorld.Base();
|
|
SetUpBones( shapeToWorld, pStudioHdr->numbones, pPoseToWorld );
|
|
|
|
m_MDL.Draw( shapeToWorld, pPoseToWorld );
|
|
|
|
// 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, m_bZUp );
|
|
ConcatTransforms( engineToDme, shapeToWorld, rootToWorld );
|
|
}
|
|
else
|
|
{
|
|
MatrixCopy( shapeToWorld, rootToWorld );
|
|
}
|
|
|
|
m_MDL.SetUpBones( rootToWorld, nMaxBoneCount, pOutputMatrices );
|
|
}
|