/
a_dynlight.h
239 lines (209 loc) · 5.8 KB
/
a_dynlight.h
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#pragma once
#include "c_cvars.h"
#include "actor.h"
#include "cycler.h"
EXTERN_CVAR(Bool, r_dynlights)
EXTERN_CVAR(Bool, gl_lights)
EXTERN_CVAR(Bool, gl_attachedlights)
struct side_t;
struct seg_t;
class ADynamicLight;
class FSerializer;
struct FSectionLine;
enum ELightType
{
PointLight,
PulseLight,
FlickerLight,
RandomFlickerLight,
SectorLight,
DummyLight,
ColorPulseLight,
ColorFlickerLight,
RandomColorFlickerLight
};
enum
{
LIGHT_RED = 0,
LIGHT_GREEN = 1,
LIGHT_BLUE = 2,
LIGHT_INTENSITY = 3,
LIGHT_SECONDARY_INTENSITY = 4,
LIGHT_SCALE = 3,
};
enum LightFlag
{
LF_SUBTRACTIVE = 1,
LF_ADDITIVE = 2,
LF_DONTLIGHTSELF = 4,
LF_ATTENUATE = 8,
LF_NOSHADOWMAP = 16,
LF_DONTLIGHTACTORS = 32,
LF_SPOT = 64
};
//==========================================================================
//
// Light definitions
//
//==========================================================================
class FLightDefaults
{
public:
FLightDefaults(FName name, ELightType type);
void ApplyProperties(ADynamicLight * light) const;
FName GetName() const { return m_Name; }
void SetParameter(double p) { m_Param = p; }
void SetArg(int arg, int val) { m_Args[arg] = val; }
int GetArg(int arg) { return m_Args[arg]; }
uint8_t GetAttenuate() const { return m_attenuate; }
void SetOffset(float* ft) { m_Pos.X = ft[0]; m_Pos.Z = ft[1]; m_Pos.Y = ft[2]; }
void SetSubtractive(bool subtract) { m_subtractive = subtract; }
void SetAdditive(bool add) { m_additive = add; }
void SetDontLightSelf(bool add) { m_dontlightself = add; }
void SetAttenuate(bool on) { m_attenuate = on; }
void SetHalo(bool halo) { m_halo = halo; }
void SetDontLightActors(bool on) { m_dontlightactors = on; }
void SetSpot(bool spot) { m_spot = spot; }
void SetSpotInnerAngle(double angle) { m_spotInnerAngle = angle; }
void SetSpotOuterAngle(double angle) { m_spotOuterAngle = angle; }
void OrderIntensities()
{
if (m_Args[LIGHT_INTENSITY] > m_Args[LIGHT_SECONDARY_INTENSITY])
{
std::swap(m_Args[LIGHT_INTENSITY], m_Args[LIGHT_SECONDARY_INTENSITY]);
m_swapped = true;
}
}
protected:
FName m_Name = NAME_None;
int m_Args[5] = { 0,0,0,0,0 };
double m_Param = 0;
DVector3 m_Pos = { 0,0,0 };
ELightType m_type;
int8_t m_attenuate = -1;
bool m_subtractive = false;
bool m_additive = false;
bool m_halo = false;
bool m_dontlightself = false;
bool m_dontlightactors = false;
bool m_swapped = false;
bool m_spot = false;
double m_spotInnerAngle = 10.0;
double m_spotOuterAngle = 25.0;
};
//==========================================================================
//
// Light associations (intermediate parser data)
//
//==========================================================================
class FLightAssociation
{
public:
//FLightAssociation();
FLightAssociation(FName actorName, const char *frameName, FName lightName)
: m_ActorName(actorName), m_AssocLight(lightName)
{
strncpy(m_FrameName, frameName, 8);
}
FName ActorName() { return m_ActorName; }
const char *FrameName() { return m_FrameName; }
FName Light() { return m_AssocLight; }
void ReplaceLightName(FName newName) { m_AssocLight = newName; }
protected:
char m_FrameName[8];
FName m_ActorName, m_AssocLight;
};
//==========================================================================
//
// Light associations per actor class
//
//==========================================================================
class FInternalLightAssociation
{
public:
FInternalLightAssociation(FLightAssociation * asso);
int Sprite() const { return m_sprite; }
int Frame() const { return m_frame; }
const FLightDefaults *Light() const { return m_AssocLight; }
protected:
int m_sprite;
int m_frame;
FLightDefaults * m_AssocLight;
};
typedef TFlags<LightFlag> LightFlags;
DEFINE_TFLAGS_OPERATORS(LightFlags)
struct FLightNode
{
FLightNode ** prevTarget;
FLightNode * nextTarget;
FLightNode ** prevLight;
FLightNode * nextLight;
ADynamicLight * lightsource;
union
{
side_t * targLine;
subsector_t * targSubsector;
void * targ;
};
};
//
// Base class
//
// [CO] I merged everything together in this one class so that I don't have
// to create and re-create an excessive amount of objects
//
class ADynamicLight : public AActor
{
friend class FLightDefaults;
DECLARE_CLASS(ADynamicLight, AActor)
public:
virtual void Tick();
void Serialize(FSerializer &arc);
void PostSerialize();
uint8_t GetRed() const { return args[LIGHT_RED]; }
uint8_t GetGreen() const { return args[LIGHT_GREEN]; }
uint8_t GetBlue() const { return args[LIGHT_BLUE]; }
float GetRadius() const { return (IsActive() ? m_currentRadius * 2.f : 0.f); }
void LinkLight();
void UnlinkLight();
size_t PointerSubstitution(DObject *old, DObject *notOld);
void BeginPlay();
void SetOrigin(double x, double y, double z, bool moving = false);
void PostBeginPlay();
void OnDestroy() override;
void Activate(AActor *activator);
void Deactivate(AActor *activator);
void SetOffset(const DVector3 &pos);
void UpdateLocation();
bool IsOwned() const { return owned; }
bool IsActive() const { return !(flags2&MF2_DORMANT); }
bool IsSubtractive() { return !!(lightflags & LF_SUBTRACTIVE); }
bool IsAdditive() { return !!(lightflags & LF_ADDITIVE); }
bool IsSpot() { return !!(lightflags & LF_SPOT); }
FState *targetState;
FLightNode * touching_sides;
FLightNode * touching_sector;
private:
double DistToSeg(const DVector3 &pos, vertex_t *start, vertex_t *end);
void CollectWithinRadius(const DVector3 &pos, FSection *section, float radius);
protected:
DVector3 m_off;
float m_currentRadius;
unsigned int m_lastUpdate;
FCycler m_cycler;
subsector_t * subsector;
public:
int m_tickCount;
uint8_t lighttype;
bool owned;
bool halo;
uint8_t color2[3];
bool visibletoplayer;
bool swapped;
bool shadowmapped;
int bufferindex;
LightFlags lightflags;
DAngle SpotInnerAngle;
DAngle SpotOuterAngle;
int mShadowmapIndex;
};