Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

207 lines
6.0 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "movieobjects/dmemdl.h"
  7. #include "movieobjects/dmetransform.h"
  8. #include "movieobjects/dmedag.h"
  9. #include "movieobjects_interfaces.h"
  10. #include "datamodel/dmelementfactoryhelper.h"
  11. #include "datacache/imdlcache.h"
  12. #include "istudiorender.h"
  13. #include "bone_setup.h"
  14. #include "tier3/tier3.h"
  15. #include "tier3/mdlutils.h"
  16. // memdbgon must be the last include file in a .cpp file!!!
  17. #include "tier0/memdbgon.h"
  18. //-----------------------------------------------------------------------------
  19. // Expose this class to the scene database
  20. //-----------------------------------------------------------------------------
  21. IMPLEMENT_ELEMENT_FACTORY( DmeMDL, CDmeMDL );
  22. //-----------------------------------------------------------------------------
  23. // Purpose:
  24. //-----------------------------------------------------------------------------
  25. void CDmeMDL::OnConstruction()
  26. {
  27. m_bDrawInEngine = false;
  28. // SetAttributeValueElement( "transform", CreateElement< CDmeTransform >() );
  29. // SetAttributeValue( "mdlfilename", "models/alyx.mdl" );
  30. m_Color.InitAndSet( this, "color", Color( 255, 255, 255, 255 ) );
  31. m_nSkin.InitAndSet( this, "skin", 0 );
  32. m_nBody.InitAndSet( this, "body", 0 );
  33. m_nSequence.InitAndSet( this, "sequence", 0 );
  34. m_nLOD.InitAndSet( this, "lod", 0 );
  35. m_flPlaybackRate.InitAndSet( this, "playbackrate", 30.0f );
  36. m_flTime.InitAndSet( this, "time", 0.0f );
  37. m_vecViewTarget.Init( this, "viewTarget" );
  38. m_bWorldSpaceViewTarget.Init( this, "worldSpaceViewTarget" );
  39. }
  40. void CDmeMDL::OnDestruction()
  41. {
  42. m_MDL.SetMDL( MDLHANDLE_INVALID );
  43. }
  44. void CDmeMDL::SetMDL( MDLHandle_t handle )
  45. {
  46. m_MDL.SetMDL( handle );
  47. Vector vecMins, vecMaxs;
  48. GetMDLBoundingBox( &vecMins, &vecMaxs, m_MDL.GetMDL(), m_nSequence );
  49. Vector vecLookAt( 100.0f, 0.0f, vecMaxs.z );
  50. m_vecViewTarget.Set( vecLookAt );
  51. m_bWorldSpaceViewTarget = false;
  52. }
  53. MDLHandle_t CDmeMDL::GetMDL( ) const
  54. {
  55. return m_MDL.GetMDL();
  56. }
  57. //-----------------------------------------------------------------------------
  58. // Loads the model matrix based on the transform
  59. //-----------------------------------------------------------------------------
  60. void CDmeMDL::DrawInEngine( bool bDrawInEngine )
  61. {
  62. m_bDrawInEngine = bDrawInEngine;
  63. }
  64. bool CDmeMDL::IsDrawingInEngine() const
  65. {
  66. return m_bDrawInEngine;
  67. }
  68. //-----------------------------------------------------------------------------
  69. // Returns the bounding box for the model
  70. //-----------------------------------------------------------------------------
  71. void CDmeMDL::GetBoundingBox( Vector *pMins, Vector *pMaxs ) const
  72. {
  73. GetMDLBoundingBox( pMins, pMaxs, m_MDL.GetMDL(), m_nSequence );
  74. // Rotate the root transform to make it align with DMEs
  75. // DMEs up vector is the y axis
  76. if ( !m_bDrawInEngine )
  77. {
  78. Vector vecMins, vecMaxs;
  79. matrix3x4_t engineToDme;
  80. CDmeDag::EngineToDmeMatrix( engineToDme );
  81. TransformAABB( engineToDme, *pMins, *pMaxs, vecMins, vecMaxs );
  82. *pMins = vecMins;
  83. *pMaxs = vecMaxs;
  84. }
  85. }
  86. //-----------------------------------------------------------------------------
  87. // Returns the radius of the model as measured from the origin
  88. //-----------------------------------------------------------------------------
  89. float CDmeMDL::GetRadius() const
  90. {
  91. return GetMDLRadius( m_MDL.GetMDL(), m_nSequence );
  92. }
  93. //-----------------------------------------------------------------------------
  94. // Returns a more accurate bounding sphere
  95. //-----------------------------------------------------------------------------
  96. void CDmeMDL::GetBoundingSphere( Vector &vecCenter, float &flRadius )
  97. {
  98. Vector vecEngineCenter;
  99. GetMDLBoundingSphere( &vecEngineCenter, &flRadius, m_MDL.GetMDL(), m_nSequence );
  100. // Rotate the root transform to make it align with DMEs
  101. // DMEs up vector is the y axis
  102. if ( !m_bDrawInEngine )
  103. {
  104. matrix3x4_t engineToDme;
  105. CDmeDag::EngineToDmeMatrix( engineToDme );
  106. VectorTransform( vecEngineCenter, engineToDme, vecCenter );
  107. }
  108. else
  109. {
  110. vecCenter = vecEngineCenter;
  111. }
  112. }
  113. //-----------------------------------------------------------------------------
  114. // Updates the MDL rendering helper
  115. //-----------------------------------------------------------------------------
  116. void CDmeMDL::UpdateMDL()
  117. {
  118. m_MDL.m_Color = m_Color;
  119. m_MDL.m_nSkin = m_nSkin;
  120. m_MDL.m_nBody = m_nBody;
  121. m_MDL.m_nSequence = m_nSequence;
  122. m_MDL.m_nLOD = m_nLOD;
  123. m_MDL.m_flPlaybackRate = m_flPlaybackRate;
  124. m_MDL.m_flTime = m_flTime;
  125. m_MDL.m_vecViewTarget = m_vecViewTarget;
  126. m_MDL.m_Color = m_Color;
  127. m_MDL.m_bWorldSpaceViewTarget = m_bWorldSpaceViewTarget;
  128. }
  129. //-----------------------------------------------------------------------------
  130. // Draws the mesh
  131. //-----------------------------------------------------------------------------
  132. void CDmeMDL::Draw( const matrix3x4_t &shapeToWorld, CDmeDrawSettings *pDrawSettings /* = NULL */ )
  133. {
  134. UpdateMDL();
  135. studiohdr_t *pStudioHdr = m_MDL.GetStudioHdr();
  136. if ( !pStudioHdr )
  137. return;
  138. // FIXME: Why is this necessary!?!?!?
  139. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  140. if ( !m_bDrawInEngine )
  141. {
  142. pRenderContext->CullMode( MATERIAL_CULLMODE_CCW );
  143. }
  144. matrix3x4_t *pBoneToWorld = g_pStudioRender->LockBoneMatrices( pStudioHdr->numbones );
  145. SetUpBones( shapeToWorld, pStudioHdr->numbones, pBoneToWorld );
  146. g_pStudioRender->UnlockBoneMatrices();
  147. m_MDL.Draw( shapeToWorld, pBoneToWorld );
  148. // FIXME: Why is this necessary!?!?!?
  149. if ( !m_bDrawInEngine )
  150. {
  151. pRenderContext->CullMode( MATERIAL_CULLMODE_CW );
  152. }
  153. }
  154. void CDmeMDL::SetUpBones( const matrix3x4_t& shapeToWorld, int nMaxBoneCount, matrix3x4_t *pOutputMatrices )
  155. {
  156. UpdateMDL();
  157. // Root transform
  158. matrix3x4_t rootToWorld;
  159. // Rotate the root transform to make it align with DMEs
  160. // DMEs up vector is the y axis
  161. if ( !m_bDrawInEngine )
  162. {
  163. matrix3x4_t engineToDme;
  164. CDmeDag::EngineToDmeMatrix( engineToDme );
  165. ConcatTransforms( engineToDme, shapeToWorld, rootToWorld );
  166. }
  167. else
  168. {
  169. MatrixCopy( shapeToWorld, rootToWorld );
  170. }
  171. m_MDL.SetUpBones( rootToWorld, nMaxBoneCount, pOutputMatrices );
  172. }