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.

331 lines
10 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "movieobjects/dmelight.h"
  7. #include "tier0/dbg.h"
  8. #include "datamodel/dmelementfactoryhelper.h"
  9. #include "mathlib/vector.h"
  10. #include "movieobjects/dmetransform.h"
  11. #include "materialsystem/imaterialsystem.h"
  12. #include "movieobjects_interfaces.h"
  13. #include "tier2/tier2.h"
  14. // memdbgon must be the last include file in a .cpp file!!!
  15. #include "tier0/memdbgon.h"
  16. //-----------------------------------------------------------------------------
  17. // Expose this class to the scene database
  18. //-----------------------------------------------------------------------------
  19. IMPLEMENT_ELEMENT_FACTORY( DmeLight, CDmeLight );
  20. //-----------------------------------------------------------------------------
  21. // Purpose:
  22. //-----------------------------------------------------------------------------
  23. void CDmeLight::OnConstruction()
  24. {
  25. m_Color.InitAndSet( this, "color", Color( 255, 255, 255, 255 ), FATTRIB_HAS_CALLBACK );
  26. m_flIntensity.InitAndSet( this, "intensity", 1.0f, FATTRIB_HAS_CALLBACK );
  27. }
  28. void CDmeLight::OnDestruction()
  29. {
  30. }
  31. //-----------------------------------------------------------------------------
  32. // Sets the color and intensity
  33. // NOTE: Color is specified 0-255 floating point.
  34. //-----------------------------------------------------------------------------
  35. void CDmeLight::SetColor( const Color &color )
  36. {
  37. m_Color.Set( color );
  38. }
  39. void CDmeLight::SetIntensity( float flIntensity )
  40. {
  41. m_flIntensity = flIntensity;
  42. }
  43. //-----------------------------------------------------------------------------
  44. // Sets up render state in the material system for rendering
  45. //-----------------------------------------------------------------------------
  46. void CDmeLight::SetupRenderStateInternal( LightDesc_t &desc, float flAtten0, float flAtten1, float flAtten2 )
  47. {
  48. desc.m_Color[0] = m_Color.Get().r();
  49. desc.m_Color[1] = m_Color.Get().g();
  50. desc.m_Color[2] = m_Color.Get().b();
  51. desc.m_Color *= m_flIntensity / 255.0f;
  52. desc.m_Attenuation0 = flAtten0;
  53. desc.m_Attenuation1 = flAtten1;
  54. desc.m_Attenuation2 = flAtten2;
  55. desc.m_Flags = 0;
  56. if ( desc.m_Attenuation0 != 0.0f )
  57. {
  58. desc.m_Flags |= LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION0;
  59. }
  60. if ( desc.m_Attenuation1 != 0.0f )
  61. {
  62. desc.m_Flags |= LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION1;
  63. }
  64. if ( desc.m_Attenuation2 != 0.0f )
  65. {
  66. desc.m_Flags |= LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION2;
  67. }
  68. }
  69. //-----------------------------------------------------------------------------
  70. // Sets lighting state
  71. //-----------------------------------------------------------------------------
  72. void CDmeLight::SetupRenderState( int nLightIndex )
  73. {
  74. LightDesc_t desc;
  75. if ( GetLightDesc( &desc ) )
  76. {
  77. // FIXME: Should we pass the light color in?
  78. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  79. pRenderContext->SetLight( nLightIndex, desc );
  80. }
  81. }
  82. //-----------------------------------------------------------------------------
  83. //
  84. // A directional light
  85. //
  86. //-----------------------------------------------------------------------------
  87. IMPLEMENT_ELEMENT_FACTORY( DmeDirectionalLight, CDmeDirectionalLight );
  88. //-----------------------------------------------------------------------------
  89. // Purpose:
  90. //-----------------------------------------------------------------------------
  91. void CDmeDirectionalLight::OnConstruction()
  92. {
  93. m_Direction.InitAndSet( this, "direction", Vector( 0.0f, 0.0f, -1.0f ), FATTRIB_HAS_CALLBACK );
  94. }
  95. void CDmeDirectionalLight::OnDestruction()
  96. {
  97. }
  98. //-----------------------------------------------------------------------------
  99. // Sets the light direction
  100. //-----------------------------------------------------------------------------
  101. void CDmeDirectionalLight::SetDirection( const Vector &direction )
  102. {
  103. m_Direction.Set( direction );
  104. }
  105. //-----------------------------------------------------------------------------
  106. // Gets a light desc for the light
  107. //-----------------------------------------------------------------------------
  108. bool CDmeDirectionalLight::GetLightDesc( LightDesc_t *pDesc )
  109. {
  110. memset( pDesc, 0, sizeof(LightDesc_t) );
  111. pDesc->m_Type = MATERIAL_LIGHT_DIRECTIONAL;
  112. SetupRenderStateInternal( *pDesc, 1.0f, 0.0f, 0.0f );
  113. matrix3x4_t m;
  114. GetTransform()->GetTransform( m );
  115. VectorRotate( m_Direction.Get(), m, pDesc->m_Direction );
  116. VectorNormalize( pDesc->m_Direction );
  117. pDesc->m_Theta = 0.0f;
  118. pDesc->m_Phi = 0.0f;
  119. pDesc->m_Falloff = 1.0f;
  120. return true;
  121. }
  122. //-----------------------------------------------------------------------------
  123. //
  124. // A point light
  125. //
  126. //-----------------------------------------------------------------------------
  127. IMPLEMENT_ELEMENT_FACTORY( DmePointLight, CDmePointLight );
  128. //-----------------------------------------------------------------------------
  129. // Purpose:
  130. //-----------------------------------------------------------------------------
  131. void CDmePointLight::OnConstruction()
  132. {
  133. m_Position.InitAndSet( this, "position", Vector( 0, 0, 0 ), FATTRIB_HAS_CALLBACK );
  134. m_flAttenuation0.InitAndSet( this, "constantAttenuation", 1.0f, FATTRIB_HAS_CALLBACK );
  135. m_flAttenuation1.InitAndSet( this, "linearAttenuation", 0.0f, FATTRIB_HAS_CALLBACK );
  136. m_flAttenuation2.InitAndSet( this, "quadraticAttenuation", 0.0f, FATTRIB_HAS_CALLBACK );
  137. m_flMaxDistance.InitAndSet( this, "maxDistance", 0.0f, FATTRIB_HAS_CALLBACK );
  138. }
  139. void CDmePointLight::OnDestruction()
  140. {
  141. }
  142. //-----------------------------------------------------------------------------
  143. // Sets the attenuation factors
  144. //-----------------------------------------------------------------------------
  145. void CDmePointLight::SetAttenuation( float flConstant, float flLinear, float flQuadratic )
  146. {
  147. m_flAttenuation0 = flConstant;
  148. m_flAttenuation1 = flLinear;
  149. m_flAttenuation2 = flQuadratic;
  150. }
  151. //-----------------------------------------------------------------------------
  152. // Sets the maximum range
  153. //-----------------------------------------------------------------------------
  154. void CDmePointLight::SetMaxDistance( float flMaxDistance )
  155. {
  156. m_flMaxDistance = flMaxDistance;
  157. }
  158. //-----------------------------------------------------------------------------
  159. // Sets up render state in the material system for rendering
  160. //-----------------------------------------------------------------------------
  161. bool CDmePointLight::GetLightDesc( LightDesc_t *pDesc )
  162. {
  163. memset( pDesc, 0, sizeof(LightDesc_t) );
  164. pDesc->m_Type = MATERIAL_LIGHT_POINT;
  165. SetupRenderStateInternal( *pDesc, m_flAttenuation0, m_flAttenuation1, m_flAttenuation2 );
  166. matrix3x4_t m;
  167. GetTransform()->GetTransform( m );
  168. VectorTransform( m_Position, m, pDesc->m_Position );
  169. pDesc->m_Direction.Init( 0, 0, 1 );
  170. pDesc->m_Range = m_flMaxDistance;
  171. pDesc->m_Theta = 0.0f;
  172. pDesc->m_Phi = 0.0f;
  173. pDesc->m_Falloff = 1.0f;
  174. return true;
  175. }
  176. //-----------------------------------------------------------------------------
  177. //
  178. // A spot light
  179. //
  180. //-----------------------------------------------------------------------------
  181. IMPLEMENT_ELEMENT_FACTORY( DmeSpotLight, CDmeSpotLight );
  182. //-----------------------------------------------------------------------------
  183. // Purpose:
  184. //-----------------------------------------------------------------------------
  185. void CDmeSpotLight::OnConstruction()
  186. {
  187. m_Direction.InitAndSet( this, "direction", Vector( 0.0f, 0.0f, -1.0f ) );
  188. m_flSpotInnerAngle.InitAndSet( this, "spotInnerAngle", 60.0f );
  189. m_flSpotOuterAngle.InitAndSet( this, "spotOuterAngle", 90.0f );
  190. m_flSpotAngularFalloff.InitAndSet( this, "spotAngularFalloff", 1.0f );
  191. }
  192. void CDmeSpotLight::OnDestruction()
  193. {
  194. }
  195. //-----------------------------------------------------------------------------
  196. // Sets the light direction
  197. //-----------------------------------------------------------------------------
  198. void CDmeSpotLight::SetDirection( const Vector &direction )
  199. {
  200. m_Direction = direction;
  201. }
  202. //-----------------------------------------------------------------------------
  203. // Sets the spotlight angle factors
  204. // Angles are specified in degrees, as full angles (as opposed to half-angles)
  205. //-----------------------------------------------------------------------------
  206. void CDmeSpotLight::SetAngles( float flInnerAngle, float flOuterAngle, float flAngularFalloff )
  207. {
  208. m_flSpotInnerAngle = flInnerAngle;
  209. m_flSpotOuterAngle = flOuterAngle;
  210. m_flSpotAngularFalloff = flAngularFalloff;
  211. }
  212. //-----------------------------------------------------------------------------
  213. // Sets up render state in the material system for rendering
  214. //-----------------------------------------------------------------------------
  215. bool CDmeSpotLight::GetLightDesc( LightDesc_t *pDesc )
  216. {
  217. memset( pDesc, 0, sizeof(LightDesc_t) );
  218. pDesc->m_Type = MATERIAL_LIGHT_SPOT;
  219. SetupRenderStateInternal( *pDesc, m_flAttenuation0, m_flAttenuation1, m_flAttenuation2 );
  220. matrix3x4_t m;
  221. GetTransform()->GetTransform( m );
  222. VectorTransform( m_Position, m, pDesc->m_Position );
  223. VectorRotate( m_Direction.Get(), m, pDesc->m_Direction );
  224. VectorNormalize( pDesc->m_Direction );
  225. pDesc->m_Range = m_flMaxDistance;
  226. // Convert to radians
  227. pDesc->m_Theta = m_flSpotInnerAngle * M_PI / 180.0f;
  228. pDesc->m_Phi = m_flSpotOuterAngle * M_PI / 180.0f;
  229. pDesc->m_Falloff = m_flSpotAngularFalloff;
  230. return true;
  231. }
  232. //-----------------------------------------------------------------------------
  233. //
  234. // An ambient light
  235. //
  236. //-----------------------------------------------------------------------------
  237. IMPLEMENT_ELEMENT_FACTORY( DmeAmbientLight, CDmeAmbientLight );
  238. //-----------------------------------------------------------------------------
  239. // Purpose:
  240. //-----------------------------------------------------------------------------
  241. void CDmeAmbientLight::OnConstruction()
  242. {
  243. }
  244. void CDmeAmbientLight::OnDestruction()
  245. {
  246. }
  247. //-----------------------------------------------------------------------------
  248. // Sets up render state in the material system for rendering
  249. //-----------------------------------------------------------------------------
  250. void CDmeAmbientLight::SetupRenderState( int nLightIndex )
  251. {
  252. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  253. Vector4D cube[6];
  254. Vector4D vec4color( m_Color.Get().r(), m_Color.Get().g(), m_Color.Get().b(), m_Color.Get().a() );
  255. Vector4DMultiply( vec4color, m_flIntensity / 255.0f, cube[0] );
  256. cube[1] = cube[0];
  257. cube[2] = cube[0];
  258. cube[3] = cube[0];
  259. cube[4] = cube[0];
  260. cube[5] = cube[0];
  261. pRenderContext->SetAmbientLightCube( cube );
  262. }