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
331 lines
10 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//============================================================================= |
|
#include "movieobjects/dmelight.h" |
|
#include "tier0/dbg.h" |
|
#include "datamodel/dmelementfactoryhelper.h" |
|
#include "mathlib/vector.h" |
|
#include "movieobjects/dmetransform.h" |
|
#include "materialsystem/imaterialsystem.h" |
|
#include "movieobjects_interfaces.h" |
|
#include "tier2/tier2.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( DmeLight, CDmeLight ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CDmeLight::OnConstruction() |
|
{ |
|
m_Color.InitAndSet( this, "color", Color( 255, 255, 255, 255 ), FATTRIB_HAS_CALLBACK ); |
|
m_flIntensity.InitAndSet( this, "intensity", 1.0f, FATTRIB_HAS_CALLBACK ); |
|
} |
|
|
|
void CDmeLight::OnDestruction() |
|
{ |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the color and intensity |
|
// NOTE: Color is specified 0-255 floating point. |
|
//----------------------------------------------------------------------------- |
|
void CDmeLight::SetColor( const Color &color ) |
|
{ |
|
m_Color.Set( color ); |
|
} |
|
|
|
void CDmeLight::SetIntensity( float flIntensity ) |
|
{ |
|
m_flIntensity = flIntensity; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets up render state in the material system for rendering |
|
//----------------------------------------------------------------------------- |
|
void CDmeLight::SetupRenderStateInternal( LightDesc_t &desc, float flAtten0, float flAtten1, float flAtten2 ) |
|
{ |
|
desc.m_Color[0] = m_Color.Get().r(); |
|
desc.m_Color[1] = m_Color.Get().g(); |
|
desc.m_Color[2] = m_Color.Get().b(); |
|
desc.m_Color *= m_flIntensity / 255.0f; |
|
|
|
desc.m_Attenuation0 = flAtten0; |
|
desc.m_Attenuation1 = flAtten1; |
|
desc.m_Attenuation2 = flAtten2; |
|
|
|
desc.m_Flags = 0; |
|
if ( desc.m_Attenuation0 != 0.0f ) |
|
{ |
|
desc.m_Flags |= LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION0; |
|
} |
|
if ( desc.m_Attenuation1 != 0.0f ) |
|
{ |
|
desc.m_Flags |= LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION1; |
|
} |
|
if ( desc.m_Attenuation2 != 0.0f ) |
|
{ |
|
desc.m_Flags |= LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION2; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets lighting state |
|
//----------------------------------------------------------------------------- |
|
void CDmeLight::SetupRenderState( int nLightIndex ) |
|
{ |
|
LightDesc_t desc; |
|
if ( GetLightDesc( &desc ) ) |
|
{ |
|
// FIXME: Should we pass the light color in? |
|
CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); |
|
pRenderContext->SetLight( nLightIndex, desc ); |
|
} |
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// A directional light |
|
// |
|
//----------------------------------------------------------------------------- |
|
IMPLEMENT_ELEMENT_FACTORY( DmeDirectionalLight, CDmeDirectionalLight ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CDmeDirectionalLight::OnConstruction() |
|
{ |
|
m_Direction.InitAndSet( this, "direction", Vector( 0.0f, 0.0f, -1.0f ), FATTRIB_HAS_CALLBACK ); |
|
} |
|
|
|
void CDmeDirectionalLight::OnDestruction() |
|
{ |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the light direction |
|
//----------------------------------------------------------------------------- |
|
void CDmeDirectionalLight::SetDirection( const Vector &direction ) |
|
{ |
|
m_Direction.Set( direction ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Gets a light desc for the light |
|
//----------------------------------------------------------------------------- |
|
bool CDmeDirectionalLight::GetLightDesc( LightDesc_t *pDesc ) |
|
{ |
|
memset( pDesc, 0, sizeof(LightDesc_t) ); |
|
|
|
pDesc->m_Type = MATERIAL_LIGHT_DIRECTIONAL; |
|
SetupRenderStateInternal( *pDesc, 1.0f, 0.0f, 0.0f ); |
|
|
|
matrix3x4_t m; |
|
GetTransform()->GetTransform( m ); |
|
VectorRotate( m_Direction.Get(), m, pDesc->m_Direction ); |
|
VectorNormalize( pDesc->m_Direction ); |
|
|
|
pDesc->m_Theta = 0.0f; |
|
pDesc->m_Phi = 0.0f; |
|
pDesc->m_Falloff = 1.0f; |
|
|
|
return true; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// A point light |
|
// |
|
//----------------------------------------------------------------------------- |
|
IMPLEMENT_ELEMENT_FACTORY( DmePointLight, CDmePointLight ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CDmePointLight::OnConstruction() |
|
{ |
|
m_Position.InitAndSet( this, "position", Vector( 0, 0, 0 ), FATTRIB_HAS_CALLBACK ); |
|
m_flAttenuation0.InitAndSet( this, "constantAttenuation", 1.0f, FATTRIB_HAS_CALLBACK ); |
|
m_flAttenuation1.InitAndSet( this, "linearAttenuation", 0.0f, FATTRIB_HAS_CALLBACK ); |
|
m_flAttenuation2.InitAndSet( this, "quadraticAttenuation", 0.0f, FATTRIB_HAS_CALLBACK ); |
|
m_flMaxDistance.InitAndSet( this, "maxDistance", 0.0f, FATTRIB_HAS_CALLBACK ); |
|
} |
|
|
|
void CDmePointLight::OnDestruction() |
|
{ |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the attenuation factors |
|
//----------------------------------------------------------------------------- |
|
void CDmePointLight::SetAttenuation( float flConstant, float flLinear, float flQuadratic ) |
|
{ |
|
m_flAttenuation0 = flConstant; |
|
m_flAttenuation1 = flLinear; |
|
m_flAttenuation2 = flQuadratic; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the maximum range |
|
//----------------------------------------------------------------------------- |
|
void CDmePointLight::SetMaxDistance( float flMaxDistance ) |
|
{ |
|
m_flMaxDistance = flMaxDistance; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets up render state in the material system for rendering |
|
//----------------------------------------------------------------------------- |
|
bool CDmePointLight::GetLightDesc( LightDesc_t *pDesc ) |
|
{ |
|
memset( pDesc, 0, sizeof(LightDesc_t) ); |
|
|
|
pDesc->m_Type = MATERIAL_LIGHT_POINT; |
|
SetupRenderStateInternal( *pDesc, m_flAttenuation0, m_flAttenuation1, m_flAttenuation2 ); |
|
|
|
matrix3x4_t m; |
|
GetTransform()->GetTransform( m ); |
|
VectorTransform( m_Position, m, pDesc->m_Position ); |
|
pDesc->m_Direction.Init( 0, 0, 1 ); |
|
pDesc->m_Range = m_flMaxDistance; |
|
|
|
pDesc->m_Theta = 0.0f; |
|
pDesc->m_Phi = 0.0f; |
|
pDesc->m_Falloff = 1.0f; |
|
|
|
return true; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// A spot light |
|
// |
|
//----------------------------------------------------------------------------- |
|
IMPLEMENT_ELEMENT_FACTORY( DmeSpotLight, CDmeSpotLight ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CDmeSpotLight::OnConstruction() |
|
{ |
|
m_Direction.InitAndSet( this, "direction", Vector( 0.0f, 0.0f, -1.0f ) ); |
|
m_flSpotInnerAngle.InitAndSet( this, "spotInnerAngle", 60.0f ); |
|
m_flSpotOuterAngle.InitAndSet( this, "spotOuterAngle", 90.0f ); |
|
m_flSpotAngularFalloff.InitAndSet( this, "spotAngularFalloff", 1.0f ); |
|
} |
|
|
|
void CDmeSpotLight::OnDestruction() |
|
{ |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the light direction |
|
//----------------------------------------------------------------------------- |
|
void CDmeSpotLight::SetDirection( const Vector &direction ) |
|
{ |
|
m_Direction = direction; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets the spotlight angle factors |
|
// Angles are specified in degrees, as full angles (as opposed to half-angles) |
|
//----------------------------------------------------------------------------- |
|
void CDmeSpotLight::SetAngles( float flInnerAngle, float flOuterAngle, float flAngularFalloff ) |
|
{ |
|
m_flSpotInnerAngle = flInnerAngle; |
|
m_flSpotOuterAngle = flOuterAngle; |
|
m_flSpotAngularFalloff = flAngularFalloff; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets up render state in the material system for rendering |
|
//----------------------------------------------------------------------------- |
|
bool CDmeSpotLight::GetLightDesc( LightDesc_t *pDesc ) |
|
{ |
|
memset( pDesc, 0, sizeof(LightDesc_t) ); |
|
|
|
pDesc->m_Type = MATERIAL_LIGHT_SPOT; |
|
SetupRenderStateInternal( *pDesc, m_flAttenuation0, m_flAttenuation1, m_flAttenuation2 ); |
|
|
|
matrix3x4_t m; |
|
GetTransform()->GetTransform( m ); |
|
VectorTransform( m_Position, m, pDesc->m_Position ); |
|
VectorRotate( m_Direction.Get(), m, pDesc->m_Direction ); |
|
VectorNormalize( pDesc->m_Direction ); |
|
pDesc->m_Range = m_flMaxDistance; |
|
|
|
// Convert to radians |
|
pDesc->m_Theta = m_flSpotInnerAngle * M_PI / 180.0f; |
|
pDesc->m_Phi = m_flSpotOuterAngle * M_PI / 180.0f; |
|
pDesc->m_Falloff = m_flSpotAngularFalloff; |
|
|
|
return true; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// An ambient light |
|
// |
|
//----------------------------------------------------------------------------- |
|
IMPLEMENT_ELEMENT_FACTORY( DmeAmbientLight, CDmeAmbientLight ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CDmeAmbientLight::OnConstruction() |
|
{ |
|
} |
|
|
|
void CDmeAmbientLight::OnDestruction() |
|
{ |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Sets up render state in the material system for rendering |
|
//----------------------------------------------------------------------------- |
|
void CDmeAmbientLight::SetupRenderState( int nLightIndex ) |
|
{ |
|
CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); |
|
Vector4D cube[6]; |
|
|
|
Vector4D vec4color( m_Color.Get().r(), m_Color.Get().g(), m_Color.Get().b(), m_Color.Get().a() ); |
|
Vector4DMultiply( vec4color, m_flIntensity / 255.0f, cube[0] ); |
|
cube[1] = cube[0]; |
|
cube[2] = cube[0]; |
|
cube[3] = cube[0]; |
|
cube[4] = cube[0]; |
|
cube[5] = cube[0]; |
|
|
|
pRenderContext->SetAmbientLightCube( cube ); |
|
} |
|
|
|
|