absence_thelab

annotate src/3deng/lights.cpp @ 0:1cffe3409164

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 23 Oct 2014 01:46:07 +0300
parents
children
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 }