186 lines
6.1 KiB
C
186 lines
6.1 KiB
C
|
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
|
|||
|
//
|
|||
|
// Purpose:
|
|||
|
//
|
|||
|
//===========================================================================//
|
|||
|
|
|||
|
// light structure definitions.
|
|||
|
#ifndef LIGHTDESC_H
|
|||
|
#define LIGHTDESC_H
|
|||
|
|
|||
|
#include <mathlib/ssemath.h>
|
|||
|
#include <mathlib/vector.h>
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
// Light structure
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
enum LightType_t
|
|||
|
{
|
|||
|
MATERIAL_LIGHT_DISABLE = 0,
|
|||
|
MATERIAL_LIGHT_POINT,
|
|||
|
MATERIAL_LIGHT_DIRECTIONAL,
|
|||
|
MATERIAL_LIGHT_SPOT,
|
|||
|
};
|
|||
|
|
|||
|
enum LightType_OptimizationFlags_t
|
|||
|
{
|
|||
|
LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION0 = 1,
|
|||
|
LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION1 = 2,
|
|||
|
LIGHTTYPE_OPTIMIZATIONFLAGS_HAS_ATTENUATION2 = 4,
|
|||
|
LIGHTTYPE_OPTIMIZATIONFLAGS_DERIVED_VALUES_CALCED = 8,
|
|||
|
};
|
|||
|
|
|||
|
struct LightDesc_t
|
|||
|
{
|
|||
|
LightType_t m_Type; //< MATERIAL_LIGHT_xxx
|
|||
|
Vector m_Color; //< color+intensity
|
|||
|
Vector m_Position; //< light source center position
|
|||
|
Vector m_Direction; //< for SPOT, direction it is pointing
|
|||
|
float m_Range; //< distance range for light.0=infinite
|
|||
|
float m_Falloff; //< angular falloff exponent for spot lights
|
|||
|
float m_Attenuation0; //< constant distance falloff term
|
|||
|
float m_Attenuation1; //< linear term of falloff
|
|||
|
float m_Attenuation2; //< quadatic term of falloff
|
|||
|
|
|||
|
// NOTE: theta and phi are *half angles*
|
|||
|
float m_Theta; //< inner cone angle. no angular falloff
|
|||
|
//< within this cone
|
|||
|
float m_Phi; //< outer cone angle
|
|||
|
|
|||
|
// the values below are derived from the above settings for optimizations
|
|||
|
// These aren't used by DX8. . used for software lighting.
|
|||
|
|
|||
|
// NOTE: These dots are cos( m_Theta ), cos( m_Phi )
|
|||
|
float m_ThetaDot;
|
|||
|
float m_PhiDot;
|
|||
|
float m_OneOverThetaDotMinusPhiDot;
|
|||
|
unsigned int m_Flags;
|
|||
|
protected:
|
|||
|
float m_RangeSquared;
|
|||
|
public:
|
|||
|
|
|||
|
void RecalculateDerivedValues(void); // calculate m_xxDot, m_Type for changed parms
|
|||
|
void RecalculateOneOverThetaDotMinusPhiDot();
|
|||
|
|
|||
|
LightDesc_t(void)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
// constructors for various useful subtypes
|
|||
|
|
|||
|
// a point light with infinite range
|
|||
|
LightDesc_t( const Vector &pos, const Vector &color )
|
|||
|
{
|
|||
|
InitPoint( pos, color );
|
|||
|
}
|
|||
|
|
|||
|
LightDesc_t &operator=( const LightDesc_t &src )
|
|||
|
{
|
|||
|
memcpy( this, &src, sizeof(LightDesc_t) );
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
/// a simple light. cone boundaries in radians. you pass a look_at point and the
|
|||
|
/// direciton is derived from that.
|
|||
|
LightDesc_t( const Vector &pos, const Vector &color, const Vector &point_at,
|
|||
|
float inner_cone_boundary, float outer_cone_boundary )
|
|||
|
{
|
|||
|
InitSpot( pos, color, point_at, inner_cone_boundary, outer_cone_boundary );
|
|||
|
}
|
|||
|
|
|||
|
void InitPoint( const Vector &pos, const Vector &color );
|
|||
|
void InitDirectional( const Vector &dir, const Vector &color );
|
|||
|
void InitSpot(const Vector &pos, const Vector &color, const Vector &point_at,
|
|||
|
float inner_cone_boundary, float outer_cone_boundary );
|
|||
|
|
|||
|
/// Given 4 points and 4 normals, ADD lighting from this light into "color".
|
|||
|
void ComputeLightAtPoints( const FourVectors &pos, const FourVectors &normal,
|
|||
|
FourVectors &color, bool DoHalfLambert=false ) const;
|
|||
|
void ComputeNonincidenceLightAtPoints( const FourVectors &pos, FourVectors &color ) const;
|
|||
|
void ComputeLightAtPointsForDirectional( const FourVectors &pos,
|
|||
|
const FourVectors &normal,
|
|||
|
FourVectors &color, bool DoHalfLambert=false ) const;
|
|||
|
|
|||
|
// warning - modifies color!!! set color first!!
|
|||
|
void SetupOldStyleAttenuation( float fQuadatricAttn, float fLinearAttn, float fConstantAttn );
|
|||
|
|
|||
|
void SetupNewStyleAttenuation( float fFiftyPercentDistance, float fZeroPercentDistance );
|
|||
|
|
|||
|
|
|||
|
/// given a direction relative to the light source position, is this ray within the
|
|||
|
/// light cone (for spotlights..non spots consider all rays to be within their cone)
|
|||
|
bool IsDirectionWithinLightCone(const Vector &rdir) const
|
|||
|
{
|
|||
|
return ( ( m_Type != MATERIAL_LIGHT_SPOT ) || ( rdir.Dot(m_Direction) >= m_PhiDot ) );
|
|||
|
}
|
|||
|
|
|||
|
float OneOverThetaDotMinusPhiDot() const
|
|||
|
{
|
|||
|
return m_OneOverThetaDotMinusPhiDot;
|
|||
|
}
|
|||
|
|
|||
|
float DistanceAtWhichBrightnessIsLessThan( float flAmount ) const;
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
// a point light with infinite range
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
inline void LightDesc_t::InitPoint( const Vector &pos, const Vector &color )
|
|||
|
{
|
|||
|
m_Type=MATERIAL_LIGHT_POINT;
|
|||
|
m_Color=color;
|
|||
|
m_Position=pos;
|
|||
|
m_Range=0.0; // infinite
|
|||
|
m_Attenuation0=1.0;
|
|||
|
m_Attenuation1=0;
|
|||
|
m_Attenuation2=0;
|
|||
|
RecalculateDerivedValues();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
// a directional light with infinite range
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
inline void LightDesc_t::InitDirectional( const Vector &dir, const Vector &color )
|
|||
|
{
|
|||
|
m_Type=MATERIAL_LIGHT_DIRECTIONAL;
|
|||
|
m_Color=color;
|
|||
|
m_Direction=dir;
|
|||
|
m_Range=0.0; // infinite
|
|||
|
m_Attenuation0=1.0;
|
|||
|
m_Attenuation1=0;
|
|||
|
m_Attenuation2=0;
|
|||
|
RecalculateDerivedValues();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
// a simple light. cone boundaries in radians. you pass a look_at point and the
|
|||
|
// direciton is derived from that.
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
inline void LightDesc_t::InitSpot(const Vector &pos, const Vector &color, const Vector &point_at,
|
|||
|
float inner_cone_boundary, float outer_cone_boundary)
|
|||
|
{
|
|||
|
m_Type=MATERIAL_LIGHT_SPOT;
|
|||
|
m_Color=color;
|
|||
|
m_Position=pos;
|
|||
|
m_Direction=point_at;
|
|||
|
m_Direction-=pos;
|
|||
|
VectorNormalizeFast(m_Direction);
|
|||
|
m_Falloff=5.0; // linear angle falloff
|
|||
|
m_Theta=inner_cone_boundary;
|
|||
|
m_Phi=outer_cone_boundary;
|
|||
|
|
|||
|
m_Range=0.0; // infinite
|
|||
|
|
|||
|
m_Attenuation0=1.0;
|
|||
|
m_Attenuation1=0;
|
|||
|
m_Attenuation2=0;
|
|||
|
RecalculateDerivedValues();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#endif
|
|||
|
|