rev |
line source |
nuclear@0
|
1 #include "lights.h"
|
nuclear@0
|
2 #include <cmath>
|
nuclear@0
|
3
|
nuclear@0
|
4 Light::Light() {
|
nuclear@0
|
5 intensity = 1.0f;
|
nuclear@0
|
6 ambient_color = 0.0f;
|
nuclear@0
|
7 diffuse_color = specular_color = 1.0f;
|
nuclear@0
|
8 CastShadows = false;
|
nuclear@0
|
9 }
|
nuclear@0
|
10
|
nuclear@0
|
11 void Light::SetIntensity(float intensity) {
|
nuclear@0
|
12 this->intensity = intensity;
|
nuclear@0
|
13 }
|
nuclear@0
|
14
|
nuclear@0
|
15 float Light::GetIntensity() const {
|
nuclear@0
|
16 return intensity;
|
nuclear@0
|
17 }
|
nuclear@0
|
18
|
nuclear@0
|
19 void Light::SetColor(const Color &color, PhongComponent comp) {
|
nuclear@0
|
20 if(comp == (PhongComponent)-1) {
|
nuclear@0
|
21 diffuse_color = specular_color = color;
|
nuclear@0
|
22 } else {
|
nuclear@0
|
23 switch(comp) {
|
nuclear@0
|
24 case Ambient:
|
nuclear@0
|
25 ambient_color = color;
|
nuclear@0
|
26 break;
|
nuclear@0
|
27 case Diffuse:
|
nuclear@0
|
28 diffuse_color = color;
|
nuclear@0
|
29 break;
|
nuclear@0
|
30 case Specular:
|
nuclear@0
|
31 specular_color = color;
|
nuclear@0
|
32 break;
|
nuclear@0
|
33 }
|
nuclear@0
|
34 }
|
nuclear@0
|
35 }
|
nuclear@0
|
36
|
nuclear@0
|
37 const Color &Light::GetColor(PhongComponent comp) const {
|
nuclear@0
|
38 switch(comp) {
|
nuclear@0
|
39 case Ambient:
|
nuclear@0
|
40 return ambient_color;
|
nuclear@0
|
41 case Diffuse:
|
nuclear@0
|
42 return diffuse_color;
|
nuclear@0
|
43 case Specular:
|
nuclear@0
|
44 return specular_color;
|
nuclear@0
|
45 }
|
nuclear@0
|
46 }
|
nuclear@0
|
47
|
nuclear@0
|
48 void Light::SetShadowCasting(bool enable) {
|
nuclear@0
|
49 CastShadows = enable;
|
nuclear@0
|
50 }
|
nuclear@0
|
51
|
nuclear@0
|
52 bool Light::GetShadowCasting() const {
|
nuclear@0
|
53 return CastShadows;
|
nuclear@0
|
54 }
|
nuclear@0
|
55
|
nuclear@0
|
56 ////////// Directional Light ///////////
|
nuclear@0
|
57
|
nuclear@0
|
58 // Non-Applicable functions for this type of light
|
nuclear@0
|
59 void DirLight::SetPosition(const Vector3 &pos) {}
|
nuclear@0
|
60 void DirLight::SetRange(float range) {}
|
nuclear@0
|
61 void DirLight::SetAttenuation(float att0, float att1, float att2) {}
|
nuclear@0
|
62 Vector3 DirLight::GetPosition() const {return Direction;}
|
nuclear@0
|
63 float DirLight::GetRange() const {return 0.0f;}
|
nuclear@0
|
64 float DirLight::GetAttenuation(int degree) const {return 0.0f;}
|
nuclear@0
|
65 void DirLight::ResetTransform() {}
|
nuclear@0
|
66 void DirLight::ResetTranslation() {}
|
nuclear@0
|
67 void DirLight::ResetRotation() {}
|
nuclear@0
|
68 void DirLight::Transform(const Matrix4x4 &matrix) {}
|
nuclear@0
|
69 void DirLight::Translate(float x, float y, float z) {}
|
nuclear@0
|
70 void DirLight::Rotate(float x, float y, float z) {}
|
nuclear@0
|
71 void DirLight::Rotate(const Vector3 &axis, float angle) {}
|
nuclear@0
|
72 void DirLight::SetCone(float InnerCone, float OuterCone) {}
|
nuclear@0
|
73 float DirLight::GetInnerCone() const {return 0.0f;}
|
nuclear@0
|
74 float DirLight::GetOuterCone() const {return 0.0f;}
|
nuclear@0
|
75 void DirLight::SetFalloff(float falloff) {}
|
nuclear@0
|
76 float DirLight::GetFalloff() const {return 0.0f;}
|
nuclear@0
|
77 void DirLight::ResetTargetTransform() {}
|
nuclear@0
|
78 void DirLight::ResetTargetTranslation() {}
|
nuclear@0
|
79 void DirLight::ResetTargetRotation() {}
|
nuclear@0
|
80 void DirLight::TargetTransform(const Matrix4x4 &matrix) {}
|
nuclear@0
|
81 void DirLight::TargetTranslate(float x, float y, float z) {}
|
nuclear@0
|
82 void DirLight::TargetRotate(float x, float y, float z) {}
|
nuclear@0
|
83 void DirLight::TargetRotate(const Vector3 &axis, float angle) {}
|
nuclear@0
|
84
|
nuclear@0
|
85
|
nuclear@0
|
86
|
nuclear@0
|
87 DirLight::DirLight() {
|
nuclear@0
|
88 Direction = Vector3(0, -1, 0);
|
nuclear@0
|
89 }
|
nuclear@0
|
90
|
nuclear@0
|
91 DirLight::DirLight(const Vector3 &dir) {
|
nuclear@0
|
92 Direction = dir;
|
nuclear@0
|
93 }
|
nuclear@0
|
94
|
nuclear@0
|
95
|
nuclear@0
|
96 void DirLight::SetDirection(const Vector3 &dir) {
|
nuclear@0
|
97 Direction = dir;
|
nuclear@0
|
98 }
|
nuclear@0
|
99
|
nuclear@0
|
100 Vector3 DirLight::GetDirection() const {
|
nuclear@0
|
101 Vector3 dir = Direction;
|
nuclear@0
|
102 dir.Transform(DirRot);
|
nuclear@0
|
103 return dir;
|
nuclear@0
|
104 }
|
nuclear@0
|
105
|
nuclear@0
|
106 LightType DirLight::GetType() const {
|
nuclear@0
|
107 return LTDir;
|
nuclear@0
|
108 }
|
nuclear@0
|
109
|
nuclear@0
|
110 // direction transformations
|
nuclear@0
|
111 void DirLight::ResetDirTransform() {
|
nuclear@0
|
112 DirRot.ResetIdentity();
|
nuclear@0
|
113 }
|
nuclear@0
|
114
|
nuclear@0
|
115 void DirLight::ResetDirRotation() {
|
nuclear@0
|
116 DirRot.ResetIdentity();
|
nuclear@0
|
117 }
|
nuclear@0
|
118
|
nuclear@0
|
119 void DirLight::TransformDir(const Matrix4x4 &matrix) {
|
nuclear@0
|
120 DirRot *= matrix;
|
nuclear@0
|
121 }
|
nuclear@0
|
122
|
nuclear@0
|
123 void DirLight::RotateDir(float x, float y, float z) {
|
nuclear@0
|
124 DirRot.Rotate(x, y, z);
|
nuclear@0
|
125 }
|
nuclear@0
|
126
|
nuclear@0
|
127 void DirLight::RotateDir(const Vector3 &axis, float angle) {
|
nuclear@0
|
128 DirRot.Rotate(axis, angle);
|
nuclear@0
|
129 }
|
nuclear@0
|
130
|
nuclear@0
|
131
|
nuclear@0
|
132 void DirLight::SetLight(dword index, GraphicsContext *gc) const {
|
nuclear@0
|
133
|
nuclear@0
|
134 Vector3 dir = Direction;
|
nuclear@0
|
135 dir.Transform(DirRot);
|
nuclear@0
|
136
|
nuclear@0
|
137 D3DLIGHT8 light;
|
nuclear@0
|
138 memset(&light, 0, sizeof(D3DLIGHT8));
|
nuclear@0
|
139 light.Ambient.r = ambient_color.r * intensity;
|
nuclear@0
|
140 light.Diffuse.r = diffuse_color.r * intensity;
|
nuclear@0
|
141 light.Specular.r = specular_color.r * intensity;
|
nuclear@0
|
142 light.Ambient.g = ambient_color.g * intensity;
|
nuclear@0
|
143 light.Diffuse.g = diffuse_color.g * intensity;
|
nuclear@0
|
144 light.Specular.g = specular_color.g * intensity;
|
nuclear@0
|
145 light.Ambient.b = ambient_color.b * intensity;
|
nuclear@0
|
146 light.Diffuse.b = diffuse_color.b * intensity;
|
nuclear@0
|
147 light.Specular.b = specular_color.b * intensity;
|
nuclear@0
|
148 light.Direction = dir;
|
nuclear@0
|
149 light.Type = (D3DLIGHTTYPE)LTDir;
|
nuclear@0
|
150
|
nuclear@0
|
151 gc->D3DDevice->SetLight(index, &light);
|
nuclear@0
|
152 gc->D3DDevice->LightEnable(index, true);
|
nuclear@0
|
153 }
|
nuclear@0
|
154
|
nuclear@0
|
155 Vertex DirLightVisVertices[] = {
|
nuclear@0
|
156 Vertex(Vector3(0.0f, 0.0f, 0.1f), 0.0f, 0.0f, 0x00ff0000),
|
nuclear@0
|
157 Vertex(Vector3(0.03f, 0.03f, 0.0f), 0.0f, 0.0f, 0x000000ff),
|
nuclear@0
|
158 Vertex(Vector3(-0.03f, 0.03f, 0.0f), 0.0f, 0.0f, 0x000000ff),
|
nuclear@0
|
159 Vertex(Vector3(0.0f, -0.03f, 0.0f), 0.0f, 0.0f, 0x000000ff)
|
nuclear@0
|
160 };
|
nuclear@0
|
161
|
nuclear@0
|
162 Index DirLightVisIndices[] = {
|
nuclear@0
|
163 0, 1, 2,
|
nuclear@0
|
164 0, 2, 3,
|
nuclear@0
|
165 0, 3, 1,
|
nuclear@0
|
166 1, 3, 2
|
nuclear@0
|
167 };
|
nuclear@0
|
168
|
nuclear@0
|
169
|
nuclear@0
|
170 void DirLight::Draw(GraphicsContext *gc, float size) {
|
nuclear@0
|
171
|
nuclear@0
|
172 Material mat(0.9f, 0.8f, 0.3f);
|
nuclear@0
|
173 gc->SetMaterial(mat);
|
nuclear@0
|
174 gc->SetTexture(0, 0);
|
nuclear@0
|
175 gc->SetColorVertex(true);
|
nuclear@0
|
176 gc->SetLighting(false);
|
nuclear@0
|
177 gc->SetZBuffering(false);
|
nuclear@0
|
178
|
nuclear@0
|
179 Matrix4x4 WorldMat = (Matrix4x4)Base(Direction).CreateRotationMatrix() * DirRot;
|
nuclear@0
|
180 gc->SetWorldMatrix(WorldMat);
|
nuclear@0
|
181
|
nuclear@0
|
182 Matrix4x4 ViewMat = gc->GetViewMatrix();
|
nuclear@0
|
183 Matrix4x4 AugViewMat;
|
nuclear@0
|
184
|
nuclear@0
|
185 for(int i=0; i<4; i++) {
|
nuclear@0
|
186 AugViewMat.SetRowVector(ViewMat.GetRowVector(i).Normalized(), i);
|
nuclear@0
|
187 }
|
nuclear@0
|
188
|
nuclear@0
|
189 gc->SetViewMatrix(AugViewMat);
|
nuclear@0
|
190
|
nuclear@0
|
191 gc->Draw(DirLightVisVertices, DirLightVisIndices, 4, 12);
|
nuclear@0
|
192
|
nuclear@0
|
193 gc->SetViewMatrix(ViewMat);
|
nuclear@0
|
194
|
nuclear@0
|
195 gc->SetZBuffering(true);
|
nuclear@0
|
196 gc->SetLighting(true);
|
nuclear@0
|
197 gc->SetColorVertex(false);
|
nuclear@0
|
198
|
nuclear@0
|
199 }
|
nuclear@0
|
200
|
nuclear@0
|
201 /////////// Point Light //////////////
|
nuclear@0
|
202
|
nuclear@0
|
203 // Non-Applicable member functions
|
nuclear@0
|
204 void PointLight::SetDirection(const Vector3 &dir) {}
|
nuclear@0
|
205 Vector3 PointLight::GetDirection() const {return Position;}
|
nuclear@0
|
206 void PointLight::ResetDirTransform() {}
|
nuclear@0
|
207 void PointLight::ResetDirRotation() {}
|
nuclear@0
|
208 void PointLight::TransformDir(const Matrix4x4 &matrix) {}
|
nuclear@0
|
209 void PointLight::RotateDir(float x, float y, float z) {}
|
nuclear@0
|
210 void PointLight::RotateDir(const Vector3 &axis, float angle) {}
|
nuclear@0
|
211 void PointLight::SetCone(float InnerCone, float OuterCone) {}
|
nuclear@0
|
212 float PointLight::GetInnerCone() const {return 0.0f;}
|
nuclear@0
|
213 float PointLight::GetOuterCone() const {return 0.0f;}
|
nuclear@0
|
214 void PointLight::SetFalloff(float falloff) {}
|
nuclear@0
|
215 float PointLight::GetFalloff() const {return 0.0f;}
|
nuclear@0
|
216 void PointLight::ResetTargetTransform() {}
|
nuclear@0
|
217 void PointLight::ResetTargetTranslation() {}
|
nuclear@0
|
218 void PointLight::ResetTargetRotation() {}
|
nuclear@0
|
219 void PointLight::TargetTransform(const Matrix4x4 &matrix) {}
|
nuclear@0
|
220 void PointLight::TargetTranslate(float x, float y, float z) {}
|
nuclear@0
|
221 void PointLight::TargetRotate(float x, float y, float z) {}
|
nuclear@0
|
222 void PointLight::TargetRotate(const Vector3 &axis, float angle) {}
|
nuclear@0
|
223
|
nuclear@0
|
224
|
nuclear@0
|
225
|
nuclear@0
|
226 PointLight::PointLight() {
|
nuclear@0
|
227 Position = Vector3(0, 100, 0);
|
nuclear@0
|
228 Range = 300.0f;
|
nuclear@0
|
229 Attenuation[0] = 1.0f;
|
nuclear@0
|
230 Attenuation[1] = 0.0f;
|
nuclear@0
|
231 Attenuation[2] = 0.0f;
|
nuclear@0
|
232 }
|
nuclear@0
|
233
|
nuclear@0
|
234 PointLight::PointLight(const Vector3 &pos, float range, float att0, float att1, float att2) {
|
nuclear@0
|
235 Position = pos;
|
nuclear@0
|
236 Range = range;
|
nuclear@0
|
237 Attenuation[0] = att0;
|
nuclear@0
|
238 Attenuation[1] = att1;
|
nuclear@0
|
239 Attenuation[2] = att2;
|
nuclear@0
|
240 }
|
nuclear@0
|
241
|
nuclear@0
|
242 Matrix4x4 PointLight::GetTransform() const {
|
nuclear@0
|
243 return PosXForm * PosRot * PosTrans;
|
nuclear@0
|
244 }
|
nuclear@0
|
245
|
nuclear@0
|
246 void PointLight::SetPosition(const Vector3 &pos) {
|
nuclear@0
|
247 Position = pos;
|
nuclear@0
|
248 }
|
nuclear@0
|
249
|
nuclear@0
|
250 void PointLight::SetRange(float range) {
|
nuclear@0
|
251 Range = range;
|
nuclear@0
|
252 }
|
nuclear@0
|
253
|
nuclear@0
|
254 void PointLight::SetAttenuation(float att0, float att1, float att2) {
|
nuclear@0
|
255 Attenuation[0] = att0;
|
nuclear@0
|
256 Attenuation[1] = att1;
|
nuclear@0
|
257 Attenuation[2] = att2;
|
nuclear@0
|
258 }
|
nuclear@0
|
259
|
nuclear@0
|
260 Vector3 PointLight::GetPosition() const {
|
nuclear@0
|
261 Vector3 pos = Position;
|
nuclear@0
|
262 pos.Transform(GetTransform());
|
nuclear@0
|
263 return pos;
|
nuclear@0
|
264 }
|
nuclear@0
|
265
|
nuclear@0
|
266 float PointLight::GetRange() const {
|
nuclear@0
|
267 return Range;
|
nuclear@0
|
268 }
|
nuclear@0
|
269
|
nuclear@0
|
270 float PointLight::GetAttenuation(int degree) const {
|
nuclear@0
|
271 return Attenuation[degree];
|
nuclear@0
|
272 }
|
nuclear@0
|
273
|
nuclear@0
|
274 LightType PointLight::GetType() const {
|
nuclear@0
|
275 return LTPoint;
|
nuclear@0
|
276 }
|
nuclear@0
|
277
|
nuclear@0
|
278 // position transformations
|
nuclear@0
|
279 void PointLight::ResetTransform() {
|
nuclear@0
|
280 PosRot.ResetIdentity();
|
nuclear@0
|
281 PosTrans.ResetIdentity();
|
nuclear@0
|
282 PosXForm.ResetIdentity();
|
nuclear@0
|
283 }
|
nuclear@0
|
284
|
nuclear@0
|
285 void PointLight::ResetTranslation() {
|
nuclear@0
|
286 PosTrans.ResetIdentity();
|
nuclear@0
|
287 }
|
nuclear@0
|
288
|
nuclear@0
|
289 void PointLight::ResetRotation() {
|
nuclear@0
|
290 PosRot.ResetIdentity();
|
nuclear@0
|
291 }
|
nuclear@0
|
292
|
nuclear@0
|
293 void PointLight::Transform(const Matrix4x4 &matrix) {
|
nuclear@0
|
294 PosXForm *= matrix;
|
nuclear@0
|
295 }
|
nuclear@0
|
296
|
nuclear@0
|
297 void PointLight::Translate(float x, float y, float z) {
|
nuclear@0
|
298 PosTrans.Translate(x, y, z);
|
nuclear@0
|
299 }
|
nuclear@0
|
300
|
nuclear@0
|
301 void PointLight::Rotate(float x, float y, float z) {
|
nuclear@0
|
302 PosRot.Rotate(x, y, z);
|
nuclear@0
|
303 }
|
nuclear@0
|
304
|
nuclear@0
|
305 void PointLight::Rotate(const Vector3 &axis, float angle) {
|
nuclear@0
|
306 PosRot.Rotate(axis, angle);
|
nuclear@0
|
307 }
|
nuclear@0
|
308
|
nuclear@0
|
309
|
nuclear@0
|
310 void PointLight::SetLight(dword index, GraphicsContext *gc) const {
|
nuclear@0
|
311
|
nuclear@0
|
312 Vector3 pos = Position;
|
nuclear@0
|
313 pos.Transform(GetTransform());
|
nuclear@0
|
314
|
nuclear@0
|
315 D3DLIGHT8 light;
|
nuclear@0
|
316 memset(&light, 0, sizeof(D3DLIGHT8));
|
nuclear@0
|
317 light.Ambient.r = ambient_color.r * intensity;
|
nuclear@0
|
318 light.Diffuse.r = diffuse_color.r * intensity;
|
nuclear@0
|
319 light.Specular.r = specular_color.r * intensity;
|
nuclear@0
|
320 light.Ambient.g = ambient_color.g * intensity;
|
nuclear@0
|
321 light.Diffuse.g = diffuse_color.g * intensity;
|
nuclear@0
|
322 light.Specular.g = specular_color.g * intensity;
|
nuclear@0
|
323 light.Ambient.b = ambient_color.b * intensity;
|
nuclear@0
|
324 light.Diffuse.b = diffuse_color.b * intensity;
|
nuclear@0
|
325 light.Specular.b = specular_color.b * intensity;
|
nuclear@0
|
326 light.Position = pos;
|
nuclear@0
|
327 light.Range = Range;
|
nuclear@0
|
328 light.Attenuation0 = Attenuation[0];
|
nuclear@0
|
329 light.Attenuation1 = Attenuation[1];
|
nuclear@0
|
330 light.Attenuation2 = Attenuation[2];
|
nuclear@0
|
331 light.Type = (D3DLIGHTTYPE)LTPoint;
|
nuclear@0
|
332
|
nuclear@0
|
333 gc->D3DDevice->SetLight(index, &light);
|
nuclear@0
|
334 gc->D3DDevice->LightEnable(index, true);
|
nuclear@0
|
335 }
|
nuclear@0
|
336
|
nuclear@0
|
337
|
nuclear@0
|
338
|
nuclear@0
|
339 Index PointLightVisIndices[] = {0, 2, 1, 0, 3, 2};
|
nuclear@0
|
340
|
nuclear@0
|
341 void PointLight::Draw(GraphicsContext *gc, float size) {
|
nuclear@0
|
342
|
nuclear@0
|
343 dword color = (diffuse_color * intensity).GetPacked32();
|
nuclear@0
|
344
|
nuclear@0
|
345 float PtHalfSz = size / 2.0f;
|
nuclear@0
|
346 Vertex PointLightVisVertices[] = {
|
nuclear@0
|
347 Vertex(Vector3(-PtHalfSz, PtHalfSz, 0.0f), 0.0f, 0.0f, color),
|
nuclear@0
|
348 Vertex(Vector3(PtHalfSz, PtHalfSz, 0.0f), 1.0f, 0.0f, color),
|
nuclear@0
|
349 Vertex(Vector3(PtHalfSz, -PtHalfSz, 0.0f), 1.0f, 1.0f, color),
|
nuclear@0
|
350 Vertex(Vector3(-PtHalfSz, -PtHalfSz, 0.0f), 0.0f, 1.0f, color)
|
nuclear@0
|
351 };
|
nuclear@0
|
352
|
nuclear@0
|
353 Texture *tex = gc->texman->LoadTexture("STOCKTEX_BLOB");
|
nuclear@0
|
354 gc->SetTexture(0, tex);
|
nuclear@0
|
355 gc->SetTextureStageColor(0, TexBlendModulate, TexArgTexture, TexArgCurrent);
|
nuclear@0
|
356 gc->SetTexture(1, 0);
|
nuclear@0
|
357
|
nuclear@0
|
358 gc->SetAlphaBlending(true);
|
nuclear@0
|
359 gc->SetBlendFunc(BLEND_ONE, BLEND_ONE);
|
nuclear@0
|
360
|
nuclear@0
|
361 gc->SetColorVertex(true);
|
nuclear@0
|
362 gc->SetLighting(false);
|
nuclear@0
|
363
|
nuclear@0
|
364 Matrix4x4 InvPos;
|
nuclear@0
|
365 InvPos.Translate(Position.x, Position.y, Position.z);
|
nuclear@0
|
366 gc->SetWorldMatrix(InvPos * GetTransform());
|
nuclear@0
|
367
|
nuclear@0
|
368 gc->SetZWrite(false);
|
nuclear@0
|
369 gc->SetBillboarding(true);
|
nuclear@0
|
370 gc->Draw(PointLightVisVertices, PointLightVisIndices, 4, 6);
|
nuclear@0
|
371 gc->SetBillboarding(false);
|
nuclear@0
|
372 gc->SetZWrite(true);
|
nuclear@0
|
373
|
nuclear@0
|
374 gc->SetAlphaBlending(false);
|
nuclear@0
|
375 gc->SetLighting(true);
|
nuclear@0
|
376 gc->SetColorVertex(false);
|
nuclear@0
|
377 gc->SetTexture(0, 0);
|
nuclear@0
|
378 }
|
nuclear@0
|
379
|
nuclear@0
|
380
|
nuclear@0
|
381 ////////////// Spot Light ////////////////
|
nuclear@0
|
382 void SpotLight::ResetTargetTransform() {}
|
nuclear@0
|
383 void SpotLight::ResetTargetTranslation() {}
|
nuclear@0
|
384 void SpotLight::ResetTargetRotation() {}
|
nuclear@0
|
385 void SpotLight::TargetTransform(const Matrix4x4 &matrix) {}
|
nuclear@0
|
386 void SpotLight::TargetTranslate(float x, float y, float z) {}
|
nuclear@0
|
387 void SpotLight::TargetRotate(float x, float y, float z) {}
|
nuclear@0
|
388 void SpotLight::TargetRotate(const Vector3 &axis, float angle) {}
|
nuclear@0
|
389
|
nuclear@0
|
390 SpotLight::SpotLight() {
|
nuclear@0
|
391 Position = Vector3(0, 100, 0);
|
nuclear@0
|
392 Direction = Vector3(0, -1, 0);
|
nuclear@0
|
393 Falloff = 1.0f;
|
nuclear@0
|
394 Phi = QuarterPi;
|
nuclear@0
|
395 Theta = Phi - (Phi / 9.0f);
|
nuclear@0
|
396 }
|
nuclear@0
|
397
|
nuclear@0
|
398 SpotLight::SpotLight(const Vector3 &pos, const Vector3 &dir, float InnerCone, float OuterCone, float range, float att0, float att1, float att2) {
|
nuclear@0
|
399 Position = pos;
|
nuclear@0
|
400 Direction = dir;
|
nuclear@0
|
401 SetCone(InnerCone, OuterCone);
|
nuclear@0
|
402 Range = range;
|
nuclear@0
|
403 Attenuation[0] = att0;
|
nuclear@0
|
404 Attenuation[1] = att1;
|
nuclear@0
|
405 Attenuation[2] = att2;
|
nuclear@0
|
406 Falloff = 1.0f;
|
nuclear@0
|
407 }
|
nuclear@0
|
408
|
nuclear@0
|
409 void SpotLight::SetDirection(const Vector3 &dir) {
|
nuclear@0
|
410 Direction = dir;
|
nuclear@0
|
411 }
|
nuclear@0
|
412
|
nuclear@0
|
413 Vector3 SpotLight::GetDirection() const {
|
nuclear@0
|
414 Vector3 dir = Direction;
|
nuclear@0
|
415 dir.Transform(DirRot);
|
nuclear@0
|
416 return dir;
|
nuclear@0
|
417 }
|
nuclear@0
|
418
|
nuclear@0
|
419 // direction transformations
|
nuclear@0
|
420 void SpotLight::ResetDirTransform() {
|
nuclear@0
|
421 DirRot.ResetIdentity();
|
nuclear@0
|
422 }
|
nuclear@0
|
423
|
nuclear@0
|
424 void SpotLight::ResetDirRotation() {
|
nuclear@0
|
425 DirRot.ResetIdentity();
|
nuclear@0
|
426 }
|
nuclear@0
|
427
|
nuclear@0
|
428 void SpotLight::TransformDir(const Matrix4x4 &matrix) {
|
nuclear@0
|
429 DirRot *= matrix;
|
nuclear@0
|
430 }
|
nuclear@0
|
431
|
nuclear@0
|
432 void SpotLight::RotateDir(float x, float y, float z) {
|
nuclear@0
|
433 DirRot.Rotate(x, y, z);
|
nuclear@0
|
434 }
|
nuclear@0
|
435
|
nuclear@0
|
436 void SpotLight::RotateDir(const Vector3 &axis, float angle) {
|
nuclear@0
|
437 DirRot.Rotate(axis, angle);
|
nuclear@0
|
438 }
|
nuclear@0
|
439
|
nuclear@0
|
440
|
nuclear@0
|
441 LightType SpotLight::GetType() const {
|
nuclear@0
|
442 return LTSpot;
|
nuclear@0
|
443 }
|
nuclear@0
|
444
|
nuclear@0
|
445 void SpotLight::SetCone(float InnerCone, float OuterCone) {
|
nuclear@0
|
446 Theta = InnerCone;
|
nuclear@0
|
447 Phi = OuterCone;
|
nuclear@0
|
448 }
|
nuclear@0
|
449
|
nuclear@0
|
450 float SpotLight::GetInnerCone() const {
|
nuclear@0
|
451 return Theta;
|
nuclear@0
|
452 }
|
nuclear@0
|
453
|
nuclear@0
|
454 float SpotLight::GetOuterCone() const {
|
nuclear@0
|
455 return Phi;
|
nuclear@0
|
456 }
|
nuclear@0
|
457
|
nuclear@0
|
458 void SpotLight::SetFalloff(float falloff) {
|
nuclear@0
|
459 Falloff = falloff;
|
nuclear@0
|
460 }
|
nuclear@0
|
461
|
nuclear@0
|
462 float SpotLight::GetFalloff() const {
|
nuclear@0
|
463 return Falloff;
|
nuclear@0
|
464 }
|
nuclear@0
|
465
|
nuclear@0
|
466
|
nuclear@0
|
467 void SpotLight::SetLight(dword index, GraphicsContext *gc) const {
|
nuclear@0
|
468
|
nuclear@0
|
469 Vector3 pos = Position;
|
nuclear@0
|
470 pos.Transform(GetTransform());
|
nuclear@0
|
471
|
nuclear@0
|
472 Vector3 dir = Direction;
|
nuclear@0
|
473 dir.Transform(DirRot);
|
nuclear@0
|
474
|
nuclear@0
|
475 D3DLIGHT8 light;
|
nuclear@0
|
476 memset(&light, 0, sizeof(D3DLIGHT8));
|
nuclear@0
|
477 light.Ambient.r = ambient_color.r * intensity;
|
nuclear@0
|
478 light.Diffuse.r = diffuse_color.r * intensity;
|
nuclear@0
|
479 light.Specular.r = specular_color.r * intensity;
|
nuclear@0
|
480 light.Ambient.g = ambient_color.g * intensity;
|
nuclear@0
|
481 light.Diffuse.g = diffuse_color.g * intensity;
|
nuclear@0
|
482 light.Specular.g = specular_color.g * intensity;
|
nuclear@0
|
483 light.Ambient.b = ambient_color.b * intensity;
|
nuclear@0
|
484 light.Diffuse.b = diffuse_color.b * intensity;
|
nuclear@0
|
485 light.Specular.b = specular_color.b * intensity;
|
nuclear@0
|
486 light.Position = pos;
|
nuclear@0
|
487 light.Direction = dir;
|
nuclear@0
|
488 light.Range = Range;
|
nuclear@0
|
489 light.Attenuation0 = Attenuation[0];
|
nuclear@0
|
490 light.Attenuation1 = Attenuation[1];
|
nuclear@0
|
491 light.Attenuation2 = Attenuation[2];
|
nuclear@0
|
492 light.Falloff = Falloff;
|
nuclear@0
|
493 light.Theta = Theta;
|
nuclear@0
|
494 light.Phi = Phi;
|
nuclear@0
|
495 light.Type = (D3DLIGHTTYPE)LTSpot;
|
nuclear@0
|
496
|
nuclear@0
|
497 gc->D3DDevice->SetLight(index, &light);
|
nuclear@0
|
498 gc->D3DDevice->LightEnable(index, true);
|
nuclear@0
|
499 }
|
nuclear@0
|
500
|
nuclear@0
|
501 void SpotLight::Draw(GraphicsContext *gc, float size) {
|
nuclear@0
|
502 PointLight::Draw(gc, size);
|
nuclear@0
|
503 }
|
nuclear@0
|
504
|
nuclear@0
|
505 //////////////// Target Spot Light ////////////////////
|
nuclear@0
|
506 void TargetSpotLight::SetDirection(const Vector3 &dir) {}
|
nuclear@0
|
507 Vector3 TargetSpotLight::GetDirection() const {return Vector3();}
|
nuclear@0
|
508 void TargetSpotLight::ResetDirTransform() {}
|
nuclear@0
|
509 void TargetSpotLight::ResetDirRotation() {}
|
nuclear@0
|
510 void TargetSpotLight::TransformDir(const Matrix4x4 &matrix) {}
|
nuclear@0
|
511 void TargetSpotLight::RotateDir(float x, float y, float z) {}
|
nuclear@0
|
512 void TargetSpotLight::RotateDir(const Vector3 &axis, float angle) {}
|
nuclear@0
|
513
|
nuclear@0
|
514 TargetSpotLight::TargetSpotLight() {
|
nuclear@0
|
515 Target = Vector3(0.0f, 0.0f, 0.0f);
|
nuclear@0
|
516 }
|
nuclear@0
|
517
|
nuclear@0
|
518 TargetSpotLight::TargetSpotLight(const Vector3 &pos, const Vector3 &target, float InnerCone, float OuterCone, float range, float att0, float att1, float att2) {
|
nuclear@0
|
519 Position = pos;
|
nuclear@0
|
520 Target = target;
|
nuclear@0
|
521 SetCone(InnerCone, OuterCone);
|
nuclear@0
|
522 Range = range;
|
nuclear@0
|
523 Attenuation[0] = att0;
|
nuclear@0
|
524 Attenuation[1] = att1;
|
nuclear@0
|
525 Attenuation[2] = att2;
|
nuclear@0
|
526 Falloff = 1.0f;
|
nuclear@0
|
527 }
|
nuclear@0
|
528
|
nuclear@0
|
529 Matrix4x4 TargetSpotLight::GetTargetTransform() const {
|
nuclear@0
|
530 return TargXForm * TargRot * TargTrans;
|
nuclear@0
|
531 }
|
nuclear@0
|
532
|
nuclear@0
|
533 void TargetSpotLight::ResetTargetTransform() {
|
nuclear@0
|
534 TargRot.ResetIdentity();
|
nuclear@0
|
535 TargTrans.ResetIdentity();
|
nuclear@0
|
536 TargXForm.ResetIdentity();
|
nuclear@0
|
537 }
|
nuclear@0
|
538
|
nuclear@0
|
539 void TargetSpotLight::ResetTargetTranslation() {
|
nuclear@0
|
540 TargTrans.ResetIdentity();
|
nuclear@0
|
541 }
|
nuclear@0
|
542
|
nuclear@0
|
543 void TargetSpotLight::ResetTargetRotation() {
|
nuclear@0
|
544 TargRot.ResetIdentity();
|
nuclear@0
|
545 }
|
nuclear@0
|
546
|
nuclear@0
|
547 void TargetSpotLight::TargetTransform(const Matrix4x4 &matrix) {
|
nuclear@0
|
548 TargXForm *= matrix;
|
nuclear@0
|
549 }
|
nuclear@0
|
550
|
nuclear@0
|
551 void TargetSpotLight::TargetTranslate(float x, float y, float z) {
|
nuclear@0
|
552 TargTrans.Translate(x, y, z);
|
nuclear@0
|
553 }
|
nuclear@0
|
554
|
nuclear@0
|
555 void TargetSpotLight::TargetRotate(float x, float y, float z) {
|
nuclear@0
|
556 TargRot.Rotate(x, y, z);
|
nuclear@0
|
557 }
|
nuclear@0
|
558
|
nuclear@0
|
559 void TargetSpotLight::TargetRotate(const Vector3 &axis, float angle) {
|
nuclear@0
|
560 TargRot.Rotate(axis, angle);
|
nuclear@0
|
561 }
|
nuclear@0
|
562
|
nuclear@0
|
563
|
nuclear@0
|
564 void TargetSpotLight::SetLight(dword index, GraphicsContext *gc) const {
|
nuclear@0
|
565 Vector3 targ = Target;
|
nuclear@0
|
566 targ.Transform(GetTargetTransform());
|
nuclear@0
|
567
|
nuclear@0
|
568 Vector3 pos = Position;
|
nuclear@0
|
569 pos.Transform(GetTransform());
|
nuclear@0
|
570
|
nuclear@0
|
571 Vector3 *dir = const_cast<Vector3*>(&Direction);
|
nuclear@0
|
572 *dir = (targ - pos).Normalized();
|
nuclear@0
|
573
|
nuclear@0
|
574 SpotLight::SetLight(index, gc);
|
nuclear@0
|
575 }
|
nuclear@0
|
576
|
nuclear@0
|
577 void TargetSpotLight::Draw(GraphicsContext *gc, float size) {
|
nuclear@0
|
578 Vector3 targ = Target;
|
nuclear@0
|
579 targ.Transform(GetTargetTransform());
|
nuclear@0
|
580
|
nuclear@0
|
581 Vector3 pos = Position;
|
nuclear@0
|
582 pos.Transform(GetTransform());
|
nuclear@0
|
583
|
nuclear@0
|
584 Direction = (targ - pos).Normalized();
|
nuclear@0
|
585 SpotLight::Draw(gc, size);
|
nuclear@0
|
586 } |