diff options
author | Peter Kohaut | 2019-01-24 22:56:10 +0100 |
---|---|---|
committer | Peter Kohaut | 2019-01-24 22:59:49 +0100 |
commit | 2fd29c5193a0b9e6d3920f0512ce3ca37b00bf7e (patch) | |
tree | 77563b1fab1720e4ea892d2202ca4dd7416c260b /engines/bladerunner | |
parent | 5475bca1e1996977a45c598d61e186f10c407155 (diff) | |
download | scummvm-rg350-2fd29c5193a0b9e6d3920f0512ce3ca37b00bf7e.tar.gz scummvm-rg350-2fd29c5193a0b9e6d3920f0512ce3ca37b00bf7e.tar.bz2 scummvm-rg350-2fd29c5193a0b9e6d3920f0512ce3ca37b00bf7e.zip |
BLADERUNNER: Fixed fog rendering
Fogs were not animated.
Clean up of the fog calculation routines.
Diffstat (limited to 'engines/bladerunner')
-rw-r--r-- | engines/bladerunner/debugger.cpp | 81 | ||||
-rw-r--r-- | engines/bladerunner/debugger.h | 9 | ||||
-rw-r--r-- | engines/bladerunner/fog.cpp | 359 | ||||
-rw-r--r-- | engines/bladerunner/fog.h | 21 | ||||
-rw-r--r-- | engines/bladerunner/set_effects.cpp | 7 | ||||
-rw-r--r-- | engines/bladerunner/set_effects.h | 2 | ||||
-rw-r--r-- | engines/bladerunner/vector.h | 13 |
7 files changed, 237 insertions, 255 deletions
diff --git a/engines/bladerunner/debugger.cpp b/engines/bladerunner/debugger.cpp index b65088c711..996873bb1c 100644 --- a/engines/bladerunner/debugger.cpp +++ b/engines/bladerunner/debugger.cpp @@ -61,15 +61,16 @@ Debugger::Debugger(BladeRunnerEngine *vm) : GUI::Debugger() { _isDebuggerOverlay = false; - _viewSceneObjects = false; _viewActorsOnly = false; _viewLights = false; _viewFogs = false; + _viewSceneObjects = false; + _viewScreenEffects = false; + _viewObstacles = false; _viewRegions = false; + _viewUI = false; _viewWaypoints = false; _viewWalkboxes = false; - _viewObstacles = false; - _viewUI = false; _viewZBuffer = false; registerCmd("anim", WRAP_METHOD(Debugger, cmdAnimation)); @@ -122,53 +123,72 @@ bool Debugger::cmdAnimation(int argc, const char **argv) { bool Debugger::cmdDraw(int argc, const char **argv) { if (argc != 2) { - debugPrintf("Enables debug rendering of scene objects, obstacles, ui elements, zbuffer or disables debug rendering.\n"); - debugPrintf("Usage: %s (obj | reg | lit | fog | way | walk | act | obstacles | ui | zbuf | reset)\n", argv[0]); + debugPrintf("Enables debug rendering of actors, screen effect, fogs, lights, scene objects, obstacles, regsions, ui elements, walk boxes, waypoints, zbuffer or disables debug rendering.\n"); + debugPrintf("Usage: %s (act | eff | fog | lit | obj | obstacles | reg | ui | walk | way | zbuf | reset)\n", argv[0]); return true; } Common::String arg = argv[1]; - if (arg == "obj") { + if (arg == "act") { _viewSceneObjects = !_viewSceneObjects; - debugPrintf("Drawing scene objects = %i\n", _viewSceneObjects); - } else if (arg == "reg") { - _viewRegions = !_viewRegions; - debugPrintf("Drawing regions = %i\n", _viewRegions); - } else if (arg == "lit") { - _viewLights = !_viewLights; - debugPrintf("Drawing lights = %i\n", _viewLights); + _viewActorsOnly = _viewSceneObjects; + debugPrintf("Drawing actors = %i\n", _viewSceneObjects); + } else if (arg == "eff") { + _viewScreenEffects = !_viewScreenEffects; + debugPrintf("Drawing screen effects = %i\n", _viewScreenEffects); } else if (arg == "fog") { _viewFogs = !_viewFogs; debugPrintf("Drawing fogs = %i\n", _viewFogs); - } else if (arg == "way") { - _viewWaypoints = !_viewWaypoints; - debugPrintf("Drawing waypoints = %i\n", _viewWaypoints); - } else if (arg == "walk") { - _viewWalkboxes = !_viewWalkboxes; - debugPrintf("Drawing walk boxes = %i\n", _viewWalkboxes); - } else if (arg == "actors") { + } else if (arg == "lit") { + _viewLights = !_viewLights; + debugPrintf("Drawing lights = %i\n", _viewLights); + } else if (arg == "reg") { + _viewRegions = !_viewRegions; + debugPrintf("Drawing regions = %i\n", _viewRegions); + }else if (arg == "obj") { _viewSceneObjects = !_viewSceneObjects; - _viewActorsOnly = _viewSceneObjects; - debugPrintf("Drawing scene actors = %i\n", _viewSceneObjects); + debugPrintf("Drawing scene objects = %i\n", _viewSceneObjects); } else if (arg == "obstacles") { _viewObstacles = !_viewObstacles; debugPrintf("Drawing obstacles = %i\n", _viewObstacles); } else if (arg == "ui") { _viewUI = !_viewUI; debugPrintf("Drawing UI elements = %i\n", _viewUI); + } else if (arg == "way") { + _viewWaypoints = !_viewWaypoints; + debugPrintf("Drawing waypoints = %i\n", _viewWaypoints); + } else if (arg == "walk") { + _viewWalkboxes = !_viewWalkboxes; + debugPrintf("Drawing walk boxes = %i\n", _viewWalkboxes); } else if (arg == "zbuf") { _viewZBuffer = !_viewZBuffer; debugPrintf("Drawing Z buffer = %i\n", _viewZBuffer); } else if (arg == "reset") { + _viewActorsOnly = false; + _viewScreenEffects = false; + _viewFogs = false; + _viewLights = false; + _viewObstacles = false; + _viewRegions = false; _viewSceneObjects = false; _viewUI = false; + _viewWaypoints = false; + _viewWalkboxes = false; _viewZBuffer = false; + + debugPrintf("Drawing screen effects = %i\n", _viewScreenEffects); + debugPrintf("Drawing fogs = %i\n", _viewFogs); + debugPrintf("Drawing lights = %i\n", _viewLights); + debugPrintf("Drawing obstacles = %i\n", _viewObstacles); + debugPrintf("Drawing regions = %i\n", _viewRegions); debugPrintf("Drawing scene objects = %i\n", _viewSceneObjects); debugPrintf("Drawing UI elements = %i\n", _viewUI); + debugPrintf("Drawing waypoints = %i\n", _viewWaypoints); + debugPrintf("Drawing walkboxes = %i\n", _viewWalkboxes); debugPrintf("Drawing Z buffer = %i\n", _viewZBuffer); } - _isDebuggerOverlay = _viewSceneObjects | _viewRegions | _viewLights | _viewFogs | _viewWaypoints | _viewWalkboxes; + _isDebuggerOverlay = _viewSceneObjects | _viewScreenEffects | _viewRegions | _viewLights | _viewFogs | _viewWaypoints | _viewWalkboxes; return true; } @@ -650,6 +670,7 @@ bool Debugger::cmdSave(int argc, const char **argv) { void Debugger::drawDebuggerOverlay() { if (_viewSceneObjects) drawSceneObjects(); + if (_viewScreenEffects) drawScreenEffects(); if (_viewLights) drawLights(); if (_viewFogs) drawFogs(); if (_viewRegions) drawRegions(); @@ -760,13 +781,14 @@ void Debugger::drawLights() { Vector3 posOriginT = _vm->_view->calculateScreenPosition(posOrigin); Vector3 posTargetT = _vm->_view->calculateScreenPosition(posTarget); + _vm->_surfaceFront.drawLine(posOriginT.x, posOriginT.y, posTargetT.x, posTargetT.y, color); + _vm->_mainFont->drawColor(light->_name, _vm->_surfaceFront, posOriginT.x, posOriginT.y, color); } } void Debugger::drawFogs() { - // draw fogs for (Fog *fog = _vm->_scene->_set->_effects->_fogs; fog != nullptr; fog = fog->_next) { // Matrix4x3 m = fog->_matrix; @@ -779,6 +801,10 @@ void Debugger::drawFogs() { posOrigin.y = posOrigin.z; posOrigin.z = -t; + Vector3 posTarget = m * Vector3(0.0f, 0.0f, -100.0f); + t = posTarget.y; + posTarget.y = posTarget.z; + posTarget.z = -t; Vector3 size = Vector3(5.0f, 5.0f, 5.0f); int colorR = (fog->_fogColor.r * 31.0f); @@ -789,8 +815,11 @@ void Debugger::drawFogs() { drawBBox(posOrigin - size, posOrigin + size, _vm->_view, &_vm->_surfaceFront, color); Vector3 posOriginT = _vm->_view->calculateScreenPosition(posOrigin); - // Vector3 posTargetT = _vm->_view->calculateScreenPosition(posTarget); - // _vm->_surfaceFront.drawLine(posOriginT.x, posOriginT.y, posTargetT.x, posTargetT.y, color); + Vector3 posTargetT = _vm->_view->calculateScreenPosition(posTarget); + + // TODO: draw line only for cone fogs, draw boxes or circles for the other types + _vm->_surfaceFront.drawLine(posOriginT.x, posOriginT.y, posTargetT.x, posTargetT.y, color); + _vm->_mainFont->drawColor(fog->_name, _vm->_surfaceFront, posOriginT.x, posOriginT.y, color); } } diff --git a/engines/bladerunner/debugger.h b/engines/bladerunner/debugger.h index 0946e7f39d..9b3d169ebe 100644 --- a/engines/bladerunner/debugger.h +++ b/engines/bladerunner/debugger.h @@ -42,15 +42,16 @@ class Debugger : public GUI::Debugger{ public: bool _isDebuggerOverlay; - bool _viewSceneObjects; bool _viewActorsOnly; - bool _viewLights; bool _viewFogs; + bool _viewLights; + bool _viewScreenEffects; + bool _viewSceneObjects; + bool _viewObstacles; bool _viewRegions; + bool _viewUI; bool _viewWaypoints; bool _viewWalkboxes; - bool _viewObstacles; - bool _viewUI; bool _viewZBuffer; diff --git a/engines/bladerunner/fog.cpp b/engines/bladerunner/fog.cpp index cb8235ba64..dac7f29679 100644 --- a/engines/bladerunner/fog.cpp +++ b/engines/bladerunner/fog.cpp @@ -43,9 +43,6 @@ Fog::Fog() { _m32ptr = nullptr; _m33ptr = nullptr; _m34ptr = nullptr; - _parameter1 = 0.0f; - _parameter2 = 0.0f; - _parameter3 = 0.0f; _next = nullptr; } @@ -74,14 +71,14 @@ void Fog::readAnimationData(Common::ReadStream *stream, int size) { } _m11ptr = _animationData; - _m12ptr = _m11ptr + (_animatedParameters & 0x1 ? _frameCount : 1); - _m13ptr = _m12ptr + (_animatedParameters & 0x2 ? _frameCount : 1); - _m14ptr = _m13ptr + (_animatedParameters & 0x4 ? _frameCount : 1); - _m21ptr = _m14ptr + (_animatedParameters & 0x08 ? _frameCount : 1); - _m22ptr = _m21ptr + (_animatedParameters & 0x10 ? _frameCount : 1); - _m23ptr = _m22ptr + (_animatedParameters & 0x20 ? _frameCount : 1); - _m24ptr = _m23ptr + (_animatedParameters & 0x40 ? _frameCount : 1); - _m31ptr = _m24ptr + (_animatedParameters & 0x80 ? _frameCount : 1); + _m12ptr = _m11ptr + (_animatedParameters & 0x1 ? _frameCount : 1); + _m13ptr = _m12ptr + (_animatedParameters & 0x2 ? _frameCount : 1); + _m14ptr = _m13ptr + (_animatedParameters & 0x4 ? _frameCount : 1); + _m21ptr = _m14ptr + (_animatedParameters & 0x8 ? _frameCount : 1); + _m22ptr = _m21ptr + (_animatedParameters & 0x10 ? _frameCount : 1); + _m23ptr = _m22ptr + (_animatedParameters & 0x20 ? _frameCount : 1); + _m24ptr = _m23ptr + (_animatedParameters & 0x40 ? _frameCount : 1); + _m31ptr = _m24ptr + (_animatedParameters & 0x80 ? _frameCount : 1); _m32ptr = _m31ptr + (_animatedParameters & 0x100 ? _frameCount : 1); _m33ptr = _m32ptr + (_animatedParameters & 0x200 ? _frameCount : 1); _m34ptr = _m33ptr + (_animatedParameters & 0x400 ? _frameCount : 1); @@ -94,14 +91,14 @@ void Fog::reset() { void Fog::setupFrame(int frame) { int offset = frame % _frameCount; - _matrix._m[0][0] = (_animatedParameters & 0x1 ? _m11ptr[offset] : *_m11ptr); - _matrix._m[0][1] = (_animatedParameters & 0x2 ? _m12ptr[offset] : *_m12ptr); - _matrix._m[0][2] = (_animatedParameters & 0x4 ? _m13ptr[offset] : *_m13ptr); - _matrix._m[0][3] = (_animatedParameters & 0x8 ? _m14ptr[offset] : *_m14ptr); - _matrix._m[1][0] = (_animatedParameters & 0x10 ? _m21ptr[offset] : *_m21ptr); - _matrix._m[1][1] = (_animatedParameters & 0x20 ? _m22ptr[offset] : *_m22ptr); - _matrix._m[1][2] = (_animatedParameters & 0x40 ? _m23ptr[offset] : *_m23ptr); - _matrix._m[1][3] = (_animatedParameters & 0x80 ? _m24ptr[offset] : *_m24ptr); + _matrix._m[0][0] = (_animatedParameters & 0x1 ? _m11ptr[offset] : *_m11ptr); + _matrix._m[0][1] = (_animatedParameters & 0x2 ? _m12ptr[offset] : *_m12ptr); + _matrix._m[0][2] = (_animatedParameters & 0x4 ? _m13ptr[offset] : *_m13ptr); + _matrix._m[0][3] = (_animatedParameters & 0x8 ? _m14ptr[offset] : *_m14ptr); + _matrix._m[1][0] = (_animatedParameters & 0x10 ? _m21ptr[offset] : *_m21ptr); + _matrix._m[1][1] = (_animatedParameters & 0x20 ? _m22ptr[offset] : *_m22ptr); + _matrix._m[1][2] = (_animatedParameters & 0x40 ? _m23ptr[offset] : *_m23ptr); + _matrix._m[1][3] = (_animatedParameters & 0x80 ? _m24ptr[offset] : *_m24ptr); _matrix._m[2][0] = (_animatedParameters & 0x100 ? _m31ptr[offset] : *_m31ptr); _matrix._m[2][1] = (_animatedParameters & 0x200 ? _m32ptr[offset] : *_m32ptr); _matrix._m[2][2] = (_animatedParameters & 0x400 ? _m33ptr[offset] : *_m33ptr); @@ -109,175 +106,119 @@ void Fog::setupFrame(int frame) { _inverted = invertMatrix(_matrix); } -void FogCone::read(Common::ReadStream *stream, int frameCount) { +void FogSphere::read(Common::ReadStream *stream, int frameCount) { _frameCount = frameCount; int size = readCommon(stream); - _parameter1 = stream->readFloatLE(); + _radius = stream->readFloatLE(); readAnimationData(stream, size - 52); } -void FogCone::calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient) { +void FogSphere::calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient) { *coeficient = 0.0f; - Vector3 positionT = _matrix * position; - Vector3 viewPositionT = _matrix * viewPosition; - - Vector3 vectorT = (viewPositionT - positionT).normalize(); - - float v67 = - positionT.x * vectorT.x - positionT.y * vectorT.y - positionT.z * vectorT.z; - float v66 = - (positionT.z * positionT.z) - (positionT.y * positionT.y) - (positionT.x * positionT.x) + (v67 * v67) + (_parameter1 * _parameter1); + // ray - sphere intersection, where sphere center is always at 0, 0, 0 as everything else tranformed by the fog matrix + Vector3 rayOrigin = _matrix * position; + Vector3 rayDestination = _matrix * viewPosition; + Vector3 rayDirection = (rayDestination - rayOrigin).normalize(); - if (v66 >= 0.0f) { - float v24 = sqrt(v66); + float b = Vector3::dot(rayDirection, rayOrigin); + float c = Vector3::dot(rayOrigin, rayOrigin) - (_radius * _radius); + float t = b * b - c; - Vector3 v29 = positionT + (v67 - v24) * vectorT; - Vector3 v36 = positionT + (v67 + v24) * vectorT; + if (t >= 0.0f) { // there is an interstection between ray and the sphere + Vector3 intersection1 = rayOrigin + (-b - sqrt(t)) * rayDirection; + Vector3 intersection2 = rayOrigin + (-b + sqrt(t)) * rayDirection; - Vector3 v39 = _inverted * v29; - Vector3 v42 = _inverted * v36; + Vector3 intersection1World = _inverted * intersection1; + Vector3 intersection2World = _inverted * intersection2; - float v74 = (v39 - position).length(); - float v76 = (v42 - position).length(); + float intersection1Distance = (intersection1World - position).length(); + float intersection2Distance = (intersection2World - position).length(); - Vector3 vector = viewPosition - position; + float distance = (viewPosition - position).length(); - float vectorLength = vector.length(); - - if (v74 < 0.0f) { - v74 = 0.0f; + if (intersection1Distance < 0.0f) { + intersection1Distance = 0.0f; } - if (v76 > vectorLength) { - v76 = vectorLength; + if (intersection2Distance > distance) { + intersection2Distance = distance; } - if (v76 >= v74) { - *coeficient = v76 - v74; + if (intersection2Distance >= intersection1Distance) { + *coeficient = intersection2Distance - intersection1Distance; } } } -void FogSphere::read(Common::ReadStream *stream, int frameCount) { +void FogCone::read(Common::ReadStream *stream, int frameCount) { _frameCount = frameCount; int size = readCommon(stream); - _parameter1 = stream->readFloatLE(); + _coneAngle = stream->readFloatLE(); readAnimationData(stream, size - 52); } -void FogSphere::calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient) { +void FogCone::calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient) { *coeficient = 0.0f; + // ray - cone intersection, cone vertex V lies at (0,0,0) and direction v = (0,0,-1) + // The algorithm looks like from book Alan W. Paeth (1995), Graphics Gems V (p. 228-230) + Vector3 positionT = _matrix * position; Vector3 viewPositionT = _matrix * viewPosition; - Vector3 v158 = Vector3::cross(positionT, viewPositionT); - - if (v158.x != 0.0f || v158.y != 0.0f || v158.z != 0.0f) { - Vector3 v167 = v158.normalize(); - if (v167.z < 0.0f) { - v167 = -1.0f * v167; - } + Vector3 v(0.0f, 0.0f, -1.0f); - float v173 = sqrt(1.0f - v167.z * v167.z); - if (v173 > cos(_parameter1)) { - Vector3 v37 = Vector3(v167.y, -v167.x, 0.0f).normalize(); + Vector3 planeNormal = Vector3::cross(positionT, viewPositionT).normalize(); - float v41 = 1.0f / v173 / v173 - 1.0f; - float v42 = sqrt(v41); - float v43 = tan(_parameter1); - float v44 = sqrt(v43 * v43 - v41); + if (planeNormal.x != 0.0f || planeNormal.y != 0.0f || planeNormal.z != 0.0f) { - Vector3 v45 = v44 * v37; + if (planeNormal.z < 0.0f) { + planeNormal = -1.0f * planeNormal; + } - Vector3 v48 = Vector3( - -v37.y * v42, - v37.x * v42, - 0.0f * v42); + float cosTheta = sqrt(1.0f - Vector3::dot(planeNormal, v) * Vector3::dot(planeNormal, v)); - Vector3 v51 = v48 + Vector3(0.0f, 0.0f, -1.0f); + if (cosTheta > cos(_coneAngle)) { + Vector3 u = Vector3::cross(v, planeNormal).normalize(); + Vector3 w = Vector3::cross(u, v).normalize(); - Vector3 v186 = v51 - v45; - Vector3 v183 = v51 + v45; + float tanTheta = sqrt(1.0f - cosTheta * cosTheta) / cosTheta; - Vector3 vector = viewPositionT - positionT; + Vector3 temp1 = tanTheta * w; + Vector3 temp2 = sqrt(tan(_coneAngle) * tan(_coneAngle) - tanTheta * tanTheta) * u; - Vector3 v177 = -1.0f * positionT; - Vector3 v174 = Vector3::cross(v186, vector); + Vector3 delta1 = v + temp1 - temp2; + Vector3 delta2 = v + temp1 + temp2; - float v189, v191; - if (fabs(v174.x) <= fabs(v174.y)) { - if (fabs(v174.y) <= fabs(v174.z)) { - v191 = v177.x * v186.y - v177.y * v186.x; - v189 = v186.y * vector.x - v186.x * vector.y; - } else { - v191 = v177.z * v186.x - v186.z * v177.x; - v189 = v186.x * vector.z - v186.z * vector.x; - } - } else { - if (fabs(v174.x) <= fabs(v174.z)) { - v191 = v177.x * v186.y - v177.y * v186.x; - v189 = v186.y * vector.x - v186.x * vector.y; - } else { - v191 = v186.z * v177.y - v186.y * v177.z; - v189 = v186.z * vector.y - v186.y * vector.z; - } - } + Vector3 d = viewPositionT - positionT; + Vector3 vecVD = -1.0f * positionT; - float v88; - if (v189 == 0.0f) { - v88 = 0.0f; - } else { - v88 = v191 / v189; - } + Vector3 crossddelta1 = Vector3::cross(d, delta1); + Vector3 crossddelta2 = Vector3::cross(d, delta2); - Vector3 v196 = -1.0f * positionT; - Vector3 v193 = Vector3::cross(v183, vector); - - float v190, v192; - if (fabs(v193.x) <= fabs(v193.y)) { - if (fabs(v193.y) <= fabs(v193.z)) { - v192 = v196.x * v183.y - v196.y * v183.x; - v190 = v183.y * vector.x - v183.x * vector.y; - } else { - v192 = v196.z * v183.x - v183.z * v196.x; - v190 = v183.x * vector.z - v183.z * vector.x; - } - } else { - if (fabs(v193.x) <= fabs(v193.z)) { - v192 = v196.x * v183.y - v196.y * v183.x; - v190 = v183.y * vector.x - v183.x * vector.y; - } else { - v192 = v183.z * v196.y - v183.y * v196.z; - v190 = v183.z * vector.y - v183.y * vector.z; - } - } + float r1 = Vector3::dot(Vector3::cross(vecVD, delta1), crossddelta1) / Vector3::dot(crossddelta1, crossddelta1); + float r2 = Vector3::dot(Vector3::cross(vecVD, delta2), crossddelta2) / Vector3::dot(crossddelta2, crossddelta2); - float v114; - if (v190 == 0.0f) { - v114 = 0.0f; - } else { - v114 = v192 / v190; + if (r2 < r1) { + float temp = r1; + r1 = r2; + r2 = temp; } - if (v114 < v88) { - float temp = v88; - v88 = v114; - v114 = temp; - } - - if (v88 <= 1.0f && v114 >= 0.0f) { - if (v88 < 0.0f) { - v88 = 0.0; + if (r1 <= 1.0f && r2 >= 0.0f) { + if (r1 < 0.0f) { + r1 = 0.0; } - if (v114 > 1.0f) { - v114 = 1.0; + if (r2 > 1.0f) { + r2 = 1.0; } - Vector3 v139 = positionT + (v88 * vector); - Vector3 v142 = _inverted * v139; + Vector3 intersection1 = positionT + (r1 * d); + Vector3 intersection1World = _inverted * intersection1; - Vector3 v148 = positionT + (v114 * vector); - Vector3 v151 = _inverted * v148; + Vector3 intersection2 = positionT + (r2 * d); + Vector3 intersection2World = _inverted * intersection2; - *coeficient = (v151 - v142).length(); + *coeficient = (intersection2World - intersection1World).length(); } } } @@ -286,111 +227,101 @@ void FogSphere::calculateCoeficient(Vector3 position, Vector3 viewPosition, floa void FogBox::read(Common::ReadStream *stream, int frameCount) { _frameCount = frameCount; int size = readCommon(stream); - _parameter1 = stream->readFloatLE(); - _parameter2 = stream->readFloatLE(); - _parameter3 = stream->readFloatLE(); + _size.x = stream->readFloatLE(); + _size.y = stream->readFloatLE(); + _size.z = stream->readFloatLE(); readAnimationData(stream, size - 60); } void FogBox::calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient) { - Vector3 positionT = _matrix * position; - Vector3 viewPositionT = _matrix * viewPosition; + *coeficient = 0.0f; + + // line - box intersection, where everything is rotated to box orientation by the fog matrix + + Vector3 point1 = _matrix * position; + Vector3 point2 = _matrix * viewPosition; - Vector3 positionTadj = positionT; - Vector3 viewPositionTadj = viewPositionT; + Vector3 intersection1 = point1; + Vector3 intersection2 = point2; - Vector3 direction = viewPositionT - positionT; + Vector3 direction = point2 - point1; - float parameter1half = _parameter1 * 0.5f; - if (positionT.x < -parameter1half) { - if (viewPositionT.x < -parameter1half) { - *coeficient = 0.0f; + // clip X + float minX = -(_size.x * 0.5f); + if (point1.x < minX) { + if (point2.x < minX) { return; } - float v28 = (-positionT.x - parameter1half) / direction.x; - Vector3 v29 = v28 * direction; - positionTadj = positionT + v29; - } else if (viewPositionT.x < -parameter1half) { - float v19 = (-viewPositionT.x - parameter1half) / direction.x; - Vector3 v20 = v19 * direction; - viewPositionTadj = viewPositionT + v20; + float scale = (minX - point1.x) / direction.x; + intersection1 = point1 + scale * direction; + } else if (point2.x < minX) { + float scale = (minX - point2.x) / direction.x; + intersection2 = point2 + scale * direction; } - if (parameter1half < positionTadj.x) { - if (parameter1half < viewPositionTadj.x) { - *coeficient = 0.0f; + float maxX = _size.x * 0.5f; + if (intersection1.x > maxX ) { + if (intersection2.x > maxX) { return; } - float v48 = (parameter1half - positionTadj.x) / direction.x; - Vector3 v49 = v48 * direction; - positionTadj = positionTadj + v49; - } else if (parameter1half < viewPositionTadj.x) { - float v40 = (parameter1half - viewPositionTadj.x) / direction.x; - Vector3 v41 = v40 * direction; - viewPositionTadj = viewPositionTadj + v41; + float scale = (maxX - intersection1.x) / direction.x; + intersection1 = intersection1 + scale * direction; + } else if (intersection2.x > maxX) { + float scale = (maxX - intersection2.x) / direction.x; + intersection2 = intersection2 + scale * direction; } - float parameter2half = _parameter2 * 0.5f; - if (positionTadj.y < -parameter2half) { - if (viewPositionTadj.y < -parameter2half) { - *coeficient = 0.0f; + // clip Y + float minY = -(_size.y * 0.5f); + if (intersection1.y < minY) { + if (intersection2.y < minY) { return; } - float v71 = (-positionTadj.y - parameter2half) / direction.y; - Vector3 v72 = v71 * direction; - positionTadj = positionTadj + v72; - } else if (viewPositionTadj.y < -parameter2half) { - float v62 = (-viewPositionTadj.y - parameter2half) / direction.y; - Vector3 v63 = v62 * direction; - viewPositionTadj = viewPositionTadj + v63; + float scale = (minY - intersection1.y) / direction.y; + intersection1 = intersection1 + scale * direction; + } else if (intersection2.y < minY) { + float scale = (minY - intersection2.y) / direction.y; + intersection2 = intersection2 + scale * direction; } - if (parameter2half < positionTadj.y) { - if (parameter2half < viewPositionTadj.y) { - *coeficient = 0.0f; + float maxY = _size.y * 0.5f; + if (intersection1.y > maxY) { + if (intersection2.y > maxY) { return; } - float v91 = (parameter2half - positionTadj.y) / direction.y; - Vector3 v92 = v91 * direction; - positionTadj = positionTadj + v92; - } else if (parameter2half < viewPositionTadj.y) { - float v83 = (parameter2half - viewPositionTadj.y) / direction.y; - Vector3 v84 = v83 * direction; - viewPositionTadj = viewPositionTadj + v84; + float scale = (maxY - intersection1.y) / direction.y; + intersection1 = intersection1 + scale * direction; + } else if (intersection2.y > maxY) { + float scale = (maxY - intersection2.y) / direction.y; + intersection2 = intersection2 + scale * direction; } - if (0.0f > positionTadj.z) { - if (0.0f > viewPositionTadj.z) { - *coeficient = 0.0f; + // clip Z + if (intersection1.z < 0.0f) { + if (intersection2.z < 0.0f) { return; } - float v111 = -positionTadj.z / direction.z; - Vector3 v112 = v111 * direction; - positionTadj = positionTadj + v112; - } else if (0.0f > viewPositionTadj.z) { - float v103 = -viewPositionTadj.z / direction.z; - Vector3 v104 = v103 * direction; - viewPositionTadj = viewPositionTadj + v104; + float scale = -intersection1.z / direction.z; + intersection1 = intersection1 + scale * direction; + } else if (intersection2.z < 0.0f) { + float scale = -intersection2.z / direction.z; + intersection2 = intersection2 + scale * direction; } - if (positionTadj.z > _parameter3) { - if (viewPositionTadj.z > _parameter3) { - *coeficient = 0.0f; + if (intersection1.z > _size.z) { + if (intersection2.z > _size.z) { return; } - float v132 = (_parameter3 - positionTadj.z) / direction.z; - Vector3 v133 = v132 * direction; - positionTadj = positionTadj + v133; - } else if (viewPositionTadj.z > _parameter3) { - float v124 = (_parameter3 - viewPositionTadj.z) / direction.z; - Vector3 v125 = v124 * direction; - viewPositionTadj = viewPositionTadj + v125; + float scale = (_size.z - intersection1.z) / direction.z; + intersection1 = intersection1 + scale * direction; + } else if (intersection2.z > _size.z) { + float scale = (_size.z - intersection2.z) / direction.z; + intersection2 = intersection2 + scale * direction; } - Vector3 v137 = _inverted * positionTadj; - Vector3 v140 = _inverted * viewPositionTadj; - Vector3 v143 = v140 - v137; + Vector3 intersection1World = _inverted * intersection1; + Vector3 intersection2World = _inverted * intersection2; - *coeficient = v143.length(); + *coeficient = (intersection2World - intersection1World).length(); } } // End of namespace BladeRunner diff --git a/engines/bladerunner/fog.h b/engines/bladerunner/fog.h index e952d24165..d9e32f6e6a 100644 --- a/engines/bladerunner/fog.h +++ b/engines/bladerunner/fog.h @@ -36,6 +36,7 @@ class SetEffects; class Fog { friend class SetEffects; + friend class Debugger; protected: Common::String _name; @@ -60,10 +61,6 @@ protected: float *_m33ptr; float *_m34ptr; - float _parameter1; - float _parameter2; - float _parameter3; - Fog *_next; public: @@ -82,17 +79,29 @@ protected: }; -class FogCone : public Fog { +class FogSphere : public Fog { +private: + float _radius = 0.0f; + +public: void read(Common::ReadStream *stream, int frameCount); void calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient); }; -class FogSphere : public Fog { +class FogCone : public Fog { +private: + float _coneAngle = 0.0f; + +public: void read(Common::ReadStream *stream, int frameCount); void calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient); }; class FogBox : public Fog { +private: + Vector3 _size; + +public: void read(Common::ReadStream *stream, int frameCount); void calculateCoeficient(Vector3 position, Vector3 viewPosition, float *coeficient); }; diff --git a/engines/bladerunner/set_effects.cpp b/engines/bladerunner/set_effects.cpp index 3d46e41e7b..99cb030e8f 100644 --- a/engines/bladerunner/set_effects.cpp +++ b/engines/bladerunner/set_effects.cpp @@ -58,10 +58,10 @@ void SetEffects::read(Common::ReadStream *stream, int frameCount) { Fog *fog = nullptr; switch (type) { case 0: - fog = new FogCone(); + fog = new FogSphere(); break; case 1: - fog = new FogSphere(); + fog = new FogCone(); break; case 2: fog = new FogBox(); @@ -92,6 +92,9 @@ void SetEffects::reset() { } void SetEffects::setupFrame(int frame) { + for (Fog *fog = _fogs; fog != nullptr; fog = fog->_next) { + fog->setupFrame(frame); + } } void SetEffects::setFadeColor(float r, float g, float b) { diff --git a/engines/bladerunner/set_effects.h b/engines/bladerunner/set_effects.h index 6bd139c4d6..6145b48eca 100644 --- a/engines/bladerunner/set_effects.h +++ b/engines/bladerunner/set_effects.h @@ -32,6 +32,8 @@ namespace BladeRunner { class SetEffects { + friend class Debugger; + BladeRunnerEngine *_vm; Color _distanceColor; diff --git a/engines/bladerunner/vector.h b/engines/bladerunner/vector.h index d5d6365a81..52883cb587 100644 --- a/engines/bladerunner/vector.h +++ b/engines/bladerunner/vector.h @@ -55,8 +55,11 @@ public: Vector3(float ax, float ay, float az) : x(ax), y(ay), z(az) {} - float length() { return sqrt(x * x + y * y + z * z); } - Vector3 normalize() { + inline float length() { + return sqrt(x * x + y * y + z * z); + } + + inline Vector3 normalize() { float len = length(); if (len == 0) { return Vector3(0.0f, 0.0f, 0.0f); @@ -64,13 +67,17 @@ public: return Vector3(x / len, y / len, z / len); } - static Vector3 cross(Vector3 a, Vector3 b) { + inline static Vector3 cross(Vector3 a, Vector3 b) { return Vector3( a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); } + inline static float dot(Vector3 a, Vector3 b) { + return a.x * b.x + a.y * b.y + a.z * b.z; + } + Vector2 xz() const { return Vector2(x, z); } |