1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
//========= Copyright 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
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.
float m_ThetaDot;
float m_PhiDot;
unsigned int m_Flags;
protected:
float OneOver_ThetaDot_Minus_PhiDot;
float m_RangeSquared;
public:
void RecalculateDerivedValues(void); // calculate m_xxDot, m_Type for changed parms
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 );
}
/// 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 OneOver_ThetaDot_Minus_PhiDot;
}
};
//-----------------------------------------------------------------------------
// 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
|