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.

246 lines
6.6 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "DmeVMFEntity.h"
  7. #include "datamodel/dmelementfactoryhelper.h"
  8. #include "toolframework/itoolentity.h"
  9. #include "materialsystem/imesh.h"
  10. #include "materialsystem/imaterial.h"
  11. #include "materialsystem/imaterialsystem.h"
  12. #include "engine/iclientleafsystem.h"
  13. #include "toolutils/enginetools_int.h"
  14. #include "foundrytool.h"
  15. // memdbgon must be the last include file in a .cpp file!!!
  16. #include "tier0/memdbgon.h"
  17. #define SPHERE_RADIUS 16
  18. //-----------------------------------------------------------------------------
  19. // Expose this class to the scene database
  20. //-----------------------------------------------------------------------------
  21. IMPLEMENT_ELEMENT_FACTORY( DmeVMFEntity, CDmeVMFEntity );
  22. //-----------------------------------------------------------------------------
  23. // Purpose:
  24. //-----------------------------------------------------------------------------
  25. void CDmeVMFEntity::OnConstruction()
  26. {
  27. m_ClassName.Init( this, "classname" );
  28. m_TargetName.Init( this, "targetname" );
  29. m_bIsPlaceholder.InitAndSet( this, "_placeholder", false, FATTRIB_DONTSAVE );
  30. m_vecLocalOrigin.Init( this, "origin" );
  31. m_vecLocalAngles.Init( this, "angles" );
  32. // Used to make sure these aren't saved if they aren't changed
  33. m_TargetName.GetAttribute()->AddFlag( FATTRIB_DONTSAVE | FATTRIB_HAS_CALLBACK );
  34. m_vecLocalAngles.GetAttribute()->AddFlag( FATTRIB_DONTSAVE | FATTRIB_HAS_CALLBACK );
  35. m_hEngineEntity = HTOOLHANDLE_INVALID;
  36. m_Wireframe.Init( "debug/debugwireframe", "editor" );
  37. }
  38. void CDmeVMFEntity::OnDestruction()
  39. {
  40. // Unhook it from the engine
  41. AttachToEngineEntity( false );
  42. m_Wireframe.Shutdown();
  43. }
  44. //-----------------------------------------------------------------------------
  45. // Called whem attributes change
  46. //-----------------------------------------------------------------------------
  47. void CDmeVMFEntity::OnAttributeChanged( CDmAttribute *pAttribute )
  48. {
  49. BaseClass::OnAttributeChanged( pAttribute );
  50. // Once these have changed, then save them out, and don't bother calling back
  51. if ( pAttribute == m_TargetName.GetAttribute() ||
  52. pAttribute == m_vecLocalAngles.GetAttribute() )
  53. {
  54. pAttribute->RemoveFlag( FATTRIB_DONTSAVE | FATTRIB_HAS_CALLBACK );
  55. return;
  56. }
  57. }
  58. //-----------------------------------------------------------------------------
  59. // Returns the entity ID
  60. //-----------------------------------------------------------------------------
  61. int CDmeVMFEntity::GetEntityId() const
  62. {
  63. return atoi( GetName() );
  64. }
  65. //-----------------------------------------------------------------------------
  66. // Entity Key iteration
  67. //-----------------------------------------------------------------------------
  68. bool CDmeVMFEntity::IsEntityKey( CDmAttribute *pEntityKey )
  69. {
  70. return pEntityKey->IsFlagSet( FATTRIB_USERDEFINED );
  71. }
  72. CDmAttribute *CDmeVMFEntity::FirstEntityKey()
  73. {
  74. for ( CDmAttribute *pAttribute = FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
  75. {
  76. if ( IsEntityKey( pAttribute ) )
  77. return pAttribute;
  78. }
  79. return NULL;
  80. }
  81. CDmAttribute *CDmeVMFEntity::NextEntityKey( CDmAttribute *pEntityKey )
  82. {
  83. if ( !pEntityKey )
  84. return NULL;
  85. for ( CDmAttribute *pAttribute = pEntityKey->NextAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() )
  86. {
  87. if ( IsEntityKey( pAttribute ) )
  88. return pAttribute;
  89. }
  90. return NULL;
  91. }
  92. //-----------------------------------------------------------------------------
  93. // Attach/detach from an engine entity with the same editor index
  94. //-----------------------------------------------------------------------------
  95. void CDmeVMFEntity::AttachToEngineEntity( bool bAttach )
  96. {
  97. if ( !bAttach )
  98. {
  99. m_hEngineEntity = HTOOLHANDLE_INVALID;
  100. }
  101. else
  102. {
  103. }
  104. }
  105. //-----------------------------------------------------------------------------
  106. // Draws the helper for the entity
  107. //-----------------------------------------------------------------------------
  108. int CDmeVMFEntity::DrawModel( int flags )
  109. {
  110. Assert( IsDrawingInEngine() );
  111. matrix3x4_t mat;
  112. AngleMatrix( m_vecLocalAngles, m_vecLocalOrigin, mat );
  113. CMatRenderContextPtr rc( g_pMaterialSystem->GetRenderContext() );
  114. rc->MatrixMode( MATERIAL_MODEL );
  115. rc->PushMatrix();
  116. rc->LoadMatrix( mat );
  117. int nTheta = 20, nPhi = 20;
  118. float flRadius = SPHERE_RADIUS;
  119. int nVertices = nTheta * nPhi;
  120. int nIndices = 2 * ( nTheta + 1 ) * ( nPhi - 1 );
  121. rc->FogMode( MATERIAL_FOG_NONE );
  122. rc->SetNumBoneWeights( 0 );
  123. rc->Bind( m_Wireframe );
  124. rc->CullMode( MATERIAL_CULLMODE_CW );
  125. IMesh* pMesh = rc->GetDynamicMesh();
  126. CMeshBuilder meshBuilder;
  127. meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, nVertices, nIndices );
  128. //
  129. // Build the index buffer.
  130. //
  131. int i, j;
  132. for ( i = 0; i < nPhi; ++i )
  133. {
  134. for ( j = 0; j < nTheta; ++j )
  135. {
  136. float u = j / ( float )(nTheta - 1);
  137. float v = i / ( float )(nPhi - 1);
  138. float theta = ( j != nTheta-1 ) ? 2.0f * M_PI * u : 0.0f;
  139. float phi = M_PI * v;
  140. Vector vecPos;
  141. vecPos.x = flRadius * sin(phi) * cos(theta);
  142. vecPos.y = flRadius * cos(phi);
  143. vecPos.z = -flRadius * sin(phi) * sin(theta);
  144. unsigned char red = (int)( u * 255.0f );
  145. unsigned char green = (int)( v * 255.0f );
  146. unsigned char blue = (int)( v * 255.0f );
  147. unsigned char alpha = (int)( v * 255.0f );
  148. meshBuilder.Position3fv( vecPos.Base() );
  149. meshBuilder.Color4ub( red, green, blue, alpha );
  150. meshBuilder.TexCoord2f( 0, u, v );
  151. meshBuilder.BoneWeight( 0, 1.0f );
  152. meshBuilder.BoneMatrix( 0, 0 );
  153. meshBuilder.AdvanceVertex();
  154. }
  155. }
  156. //
  157. // Emit the triangle strips.
  158. //
  159. int idx = 0;
  160. for ( i = 0; i < nPhi - 1; ++i )
  161. {
  162. for ( j = 0; j < nTheta; ++j )
  163. {
  164. idx = nTheta * i + j;
  165. meshBuilder.FastIndex( idx );
  166. meshBuilder.FastIndex( idx + nTheta );
  167. }
  168. //
  169. // Emit a degenerate triangle to skip to the next row without
  170. // a connecting triangle.
  171. //
  172. if ( i < nPhi - 2 )
  173. {
  174. meshBuilder.FastIndex( idx + 1 );
  175. meshBuilder.FastIndex( idx + 1 + nTheta );
  176. }
  177. }
  178. meshBuilder.End();
  179. pMesh->Draw();
  180. rc->CullMode( MATERIAL_CULLMODE_CCW );
  181. rc->MatrixMode( MATERIAL_MODEL );
  182. rc->PopMatrix();
  183. return 0;
  184. }
  185. //-----------------------------------------------------------------------------
  186. // Position and bounds for the model
  187. //-----------------------------------------------------------------------------
  188. const Vector &CDmeVMFEntity::GetRenderOrigin( void )
  189. {
  190. return m_vecLocalOrigin;
  191. }
  192. const QAngle &CDmeVMFEntity::GetRenderAngles( void )
  193. {
  194. return m_vecLocalAngles;
  195. }
  196. void CDmeVMFEntity::GetRenderBounds( Vector& mins, Vector& maxs )
  197. {
  198. mins.Init( -SPHERE_RADIUS, -SPHERE_RADIUS, -SPHERE_RADIUS );
  199. maxs.Init( SPHERE_RADIUS, SPHERE_RADIUS, SPHERE_RADIUS );
  200. }