Counter Strike : Global Offensive Source Code
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.

217 lines
6.2 KiB

  1. //====== Copyright � 1996-2004, 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. m_bZUp = false;
  29. // SetAttributeValueElement( "transform", CreateElement< CDmeTransform >() );
  30. // SetAttributeValue( "mdlfilename", "models/alyx.mdl" );
  31. m_Color.InitAndSet( this, "color", Color( 255, 255, 255, 255 ) );
  32. m_nSkin.InitAndSet( this, "skin", 0 );
  33. m_nBody.InitAndSet( this, "body", 0 );
  34. m_nSequence.InitAndSet( this, "sequence", 0 );
  35. m_nLOD.InitAndSet( this, "lod", 0 );
  36. m_flPlaybackRate.InitAndSet( this, "playbackrate", 30.0f );
  37. m_flTime.InitAndSet( this, "time", 0.0f );
  38. m_vecViewTarget.Init( this, "viewTarget" );
  39. m_bWorldSpaceViewTarget.Init( this, "worldSpaceViewTarget" );
  40. }
  41. void CDmeMDL::OnDestruction()
  42. {
  43. m_MDL.SetMDL( MDLHANDLE_INVALID );
  44. }
  45. void CDmeMDL::SetMDL( MDLHandle_t handle )
  46. {
  47. m_MDL.SetMDL( handle );
  48. Vector vecMins, vecMaxs;
  49. GetMDLBoundingBox( &vecMins, &vecMaxs, m_MDL.GetMDL(), m_nSequence );
  50. Vector vecLookAt( 100.0f, 0.0f, vecMaxs.z );
  51. m_vecViewTarget.Set( vecLookAt );
  52. m_bWorldSpaceViewTarget = false;
  53. }
  54. MDLHandle_t CDmeMDL::GetMDL( ) const
  55. {
  56. return m_MDL.GetMDL();
  57. }
  58. //-----------------------------------------------------------------------------
  59. // Loads the model matrix based on the transform
  60. //-----------------------------------------------------------------------------
  61. void CDmeMDL::DrawInEngine( bool bDrawInEngine )
  62. {
  63. m_bDrawInEngine = bDrawInEngine;
  64. }
  65. bool CDmeMDL::IsDrawingInEngine() const
  66. {
  67. return m_bDrawInEngine;
  68. }
  69. void CDmeMDL::ZUp( bool bZUp )
  70. {
  71. m_bZUp = bZUp;
  72. }
  73. bool CDmeMDL::IsZUp() const
  74. {
  75. return m_bZUp;
  76. }
  77. //-----------------------------------------------------------------------------
  78. // Returns the bounding box for the model
  79. //-----------------------------------------------------------------------------
  80. void CDmeMDL::GetBoundingBox( Vector *pMins, Vector *pMaxs ) const
  81. {
  82. GetMDLBoundingBox( pMins, pMaxs, m_MDL.GetMDL(), m_nSequence );
  83. // Rotate the root transform to make it align with DMEs
  84. // DMEs up vector is the y axis
  85. if ( !m_bDrawInEngine )
  86. {
  87. Vector vecMins, vecMaxs;
  88. matrix3x4_t engineToDme;
  89. CDmeDag::EngineToDmeMatrix( engineToDme, m_bZUp );
  90. TransformAABB( engineToDme, *pMins, *pMaxs, vecMins, vecMaxs );
  91. *pMins = vecMins;
  92. *pMaxs = vecMaxs;
  93. }
  94. }
  95. //-----------------------------------------------------------------------------
  96. // Returns the radius of the model as measured from the origin
  97. //-----------------------------------------------------------------------------
  98. float CDmeMDL::GetRadius() const
  99. {
  100. return GetMDLRadius( m_MDL.GetMDL(), m_nSequence );
  101. }
  102. //-----------------------------------------------------------------------------
  103. // Returns a more accurate bounding sphere
  104. //-----------------------------------------------------------------------------
  105. void CDmeMDL::GetBoundingSphere( Vector &vecCenter, float &flRadius )
  106. {
  107. Vector vecEngineCenter;
  108. GetMDLBoundingSphere( &vecEngineCenter, &flRadius, m_MDL.GetMDL(), m_nSequence );
  109. // Rotate the root transform to make it align with DMEs
  110. // DMEs up vector is the y axis
  111. if ( !m_bDrawInEngine )
  112. {
  113. matrix3x4_t engineToDme;
  114. CDmeDag::EngineToDmeMatrix( engineToDme, m_bZUp );
  115. VectorTransform( vecEngineCenter, engineToDme, vecCenter );
  116. }
  117. else
  118. {
  119. vecCenter = vecEngineCenter;
  120. }
  121. }
  122. //-----------------------------------------------------------------------------
  123. // Updates the MDL rendering helper
  124. //-----------------------------------------------------------------------------
  125. void CDmeMDL::UpdateMDL()
  126. {
  127. m_MDL.m_Color = m_Color;
  128. m_MDL.m_nSkin = m_nSkin;
  129. m_MDL.m_nBody = m_nBody;
  130. m_MDL.m_nSequence = m_nSequence;
  131. m_MDL.m_nLOD = m_nLOD;
  132. m_MDL.m_flPlaybackRate = m_flPlaybackRate;
  133. m_MDL.m_flTime = m_flTime;
  134. m_MDL.m_vecViewTarget = m_vecViewTarget;
  135. m_MDL.m_Color = m_Color;
  136. m_MDL.m_bWorldSpaceViewTarget = m_bWorldSpaceViewTarget;
  137. }
  138. //-----------------------------------------------------------------------------
  139. // Draws the mesh
  140. //-----------------------------------------------------------------------------
  141. void CDmeMDL::Draw( const matrix3x4_t &shapeToWorld, CDmeDrawSettings *pDrawSettings /* = NULL */ )
  142. {
  143. UpdateMDL();
  144. studiohdr_t *pStudioHdr = m_MDL.GetStudioHdr();
  145. if ( !pStudioHdr )
  146. return;
  147. // FIXME: Why is this necessary!?!?!?
  148. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  149. if ( !m_bDrawInEngine )
  150. {
  151. pRenderContext->CullMode( MATERIAL_CULLMODE_CCW );
  152. }
  153. CMatRenderData< matrix3x4_t > rdPoseToWorld( pRenderContext, pStudioHdr->numbones );
  154. matrix3x4_t *pPoseToWorld = rdPoseToWorld.Base();
  155. SetUpBones( shapeToWorld, pStudioHdr->numbones, pPoseToWorld );
  156. m_MDL.Draw( shapeToWorld, pPoseToWorld );
  157. // FIXME: Why is this necessary!?!?!?
  158. if ( !m_bDrawInEngine )
  159. {
  160. pRenderContext->CullMode( MATERIAL_CULLMODE_CW );
  161. }
  162. }
  163. void CDmeMDL::SetUpBones( const matrix3x4_t& shapeToWorld, int nMaxBoneCount, matrix3x4_t *pOutputMatrices )
  164. {
  165. UpdateMDL();
  166. // Root transform
  167. matrix3x4_t rootToWorld;
  168. // Rotate the root transform to make it align with DMEs
  169. // DMEs up vector is the y axis
  170. if ( !m_bDrawInEngine )
  171. {
  172. matrix3x4_t engineToDme;
  173. CDmeDag::EngineToDmeMatrix( engineToDme, m_bZUp );
  174. ConcatTransforms( engineToDme, shapeToWorld, rootToWorld );
  175. }
  176. else
  177. {
  178. MatrixCopy( shapeToWorld, rootToWorld );
  179. }
  180. m_MDL.SetUpBones( rootToWorld, nMaxBoneCount, pOutputMatrices );
  181. }