aboutsummaryrefslogtreecommitdiff
path: root/engines/bladerunner/slice_renderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/bladerunner/slice_renderer.cpp')
-rw-r--r--engines/bladerunner/slice_renderer.cpp649
1 files changed, 649 insertions, 0 deletions
diff --git a/engines/bladerunner/slice_renderer.cpp b/engines/bladerunner/slice_renderer.cpp
new file mode 100644
index 0000000000..4f2d52c0b8
--- /dev/null
+++ b/engines/bladerunner/slice_renderer.cpp
@@ -0,0 +1,649 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "bladerunner/slice_renderer.h"
+
+#include "bladerunner/bladerunner.h"
+#include "bladerunner/lights.h"
+#include "bladerunner/set_effects.h"
+#include "bladerunner/slice_animations.h"
+
+#include "common/memstream.h"
+#include "common/rect.h"
+#include "common/util.h"
+
+namespace BladeRunner {
+
+SliceRenderer::SliceRenderer(BladeRunnerEngine *vm) {
+ _vm = vm;
+ _pixelFormat = createRGB555();
+ int i;
+
+ for (i = 0; i < 942; i++) { // yes, its going just to 942 and not 997
+ _animationsShadowEnabled[i] = true;
+ }
+}
+
+SliceRenderer::~SliceRenderer() {
+}
+
+void SliceRenderer::setView(const View &view) {
+ _view = view;
+}
+
+void SliceRenderer::setLights(Lights *lights) {
+ _lights = lights;
+}
+
+void SliceRenderer::setSetEffects(SetEffects *setEffects) {
+ _setEffects = setEffects;
+}
+
+void SliceRenderer::setupFrameInWorld(int animationId, int animationFrame, Vector3 position, float facing, float scale) {
+ _position = position;
+ _facing = facing;
+ _scale = scale;
+
+ loadFrame(animationId, animationFrame);
+
+ calculateBoundingRect();
+}
+
+void SliceRenderer::getScreenRectangle(Common::Rect *screenRectangle, int animationId, int animationFrame, Vector3 position, float facing, float scale) {
+ assert(screenRectangle);
+ setupFrameInWorld(animationId, animationFrame, position, facing, scale);
+ *screenRectangle = _screenRectangle;
+}
+
+Matrix3x2 SliceRenderer::calculateFacingRotationMatrix() {
+ assert(_sliceFramePtr);
+
+ Matrix4x3 viewMatrix = _view._sliceViewMatrix;
+ Vector3 viewPos = viewMatrix * _position;
+ float dir = atan2f(viewPos.x, viewPos.z) + _facing;
+ float s = sinf(dir);
+ float c = cosf(dir);
+
+ Matrix3x2 rotation( c, -s, 0.0f,
+ s, c, 0.0f);
+
+ Matrix3x2 viewRotation(viewMatrix(0,0), viewMatrix(0,1), 0.0f,
+ viewMatrix(2,0), viewMatrix(2,1), 0.0f);
+
+ return viewRotation * rotation;
+}
+
+void SliceRenderer::calculateBoundingRect() {
+ assert(_sliceFramePtr);
+
+ _screenRectangle.left = 0;
+ _screenRectangle.right = 0;
+ _screenRectangle.top = 0;
+ _screenRectangle.bottom = 0;
+
+ Matrix4x3 viewMatrix = _view._sliceViewMatrix;
+
+ Vector3 frameBottom = Vector3(0.0f, 0.0f, _frameBottomZ);
+ Vector3 frameTop = Vector3(0.0f, 0.0f, _frameBottomZ + _frameSliceCount * _frameSliceHeight);
+
+ Vector3 bottom = viewMatrix * (_position + frameBottom);
+ Vector3 top = viewMatrix * (_position + frameTop);
+
+ top = bottom + _scale * (top - bottom);
+
+ if (bottom.z < 0.0f || top.z < 0.0f)
+ return;
+
+ Matrix3x2 facingRotation = calculateFacingRotationMatrix();
+
+ Matrix3x2 m_projection(_view._viewportDistance / bottom.z, 0.0f, 0.0f,
+ 0.0f, 25.5f, 0.0f);
+
+ Matrix3x2 m_frame(_frameScale.x, 0.0f, _framePos.x,
+ 0.0f, _frameScale.y, _framePos.y);
+
+ _modelMatrix = m_projection * (facingRotation * m_frame);
+
+ Vector4 startScreenVector(
+ _view._viewportHalfWidth + top.x / top.z * _view._viewportDistance,
+ _view._viewportHalfHeight + top.y / top.z * _view._viewportDistance,
+ 1.0f / top.z,
+ _frameSliceCount * (1.0f / top.z));
+
+ Vector4 endScreenVector(
+ _view._viewportHalfWidth + bottom.x / bottom.z * _view._viewportDistance,
+ _view._viewportHalfHeight + bottom.y / bottom.z * _view._viewportDistance,
+ 1.0f / bottom.z,
+ 0.0f);
+
+ _startScreenVector.x = startScreenVector.x;
+ _startScreenVector.y = startScreenVector.y;
+ _startScreenVector.z = startScreenVector.z;
+ _endScreenVector.x = endScreenVector.x;
+ _endScreenVector.y = endScreenVector.y;
+ _endScreenVector.z = endScreenVector.z;
+ _startSlice = startScreenVector.w;
+ _endSlice = endScreenVector.w;
+
+ Vector4 delta = endScreenVector - startScreenVector;
+
+ if (delta.y == 0.0f) {
+ return;
+ }
+
+ /*
+ * Calculate min and max Y
+ */
+
+ float screenMinY = 0.0f;
+ float screenMaxY = 479.0f;
+
+ if (startScreenVector.y < screenMinY) {
+ if (endScreenVector.y < screenMinY)
+ return;
+
+ float f = (screenMinY - startScreenVector.y) / delta.y;
+ startScreenVector = startScreenVector + f * delta;
+ } else if (startScreenVector.y > screenMaxY) {
+ if (endScreenVector.y >= screenMaxY)
+ return;
+
+ float f = (screenMaxY - startScreenVector.y) / delta.y;
+ startScreenVector = startScreenVector + f * delta;
+ }
+
+ if (endScreenVector.y < screenMinY) {
+ float f = (screenMinY - endScreenVector.y) / delta.y;
+ endScreenVector = endScreenVector + f * delta;
+ } else if (endScreenVector.y > screenMaxY) {
+ float f = (screenMaxY - endScreenVector.y) / delta.y;
+ endScreenVector = endScreenVector + f * delta;
+ }
+
+ int bbox_min_y = (int)MIN(startScreenVector.y, endScreenVector.y);
+ int bbox_max_y = (int)MAX(startScreenVector.y, endScreenVector.y) + 1;
+
+ /*
+ * Calculate min and max X
+ */
+
+ Matrix3x2 mB6 = _modelMatrix + Vector2(startScreenVector.x, 25.5f / startScreenVector.z);
+ Matrix3x2 mC2 = _modelMatrix + Vector2(endScreenVector.x, 25.5f / endScreenVector.z);
+
+ float min_x = 640.0f;
+ float max_x = 0.0f;
+
+ for (float i = 0.0f; i <= 256.0f; i += 255.0f) {
+ for (float j = 0.0f; j <= 256.0f; j += 255.0f) {
+ Vector2 v1 = mB6 * Vector2(i, j);
+
+ min_x = MIN(min_x, v1.x);
+ max_x = MAX(max_x, v1.x);
+
+ Vector2 v2 = mC2 * Vector2(i, j);
+
+ min_x = MIN(min_x, v2.x);
+ max_x = MAX(max_x, v2.x);
+ }
+ }
+
+ int bbox_min_x = CLIP((int)min_x, 0, 640);
+ int bbox_max_x = CLIP((int)max_x + 1, 0, 640);
+
+ _startScreenVector.x = startScreenVector.x;
+ _startScreenVector.y = startScreenVector.y;
+ _startScreenVector.z = startScreenVector.z;
+ _endScreenVector.x = endScreenVector.x;
+ _endScreenVector.y = endScreenVector.y;
+ _endScreenVector.z = endScreenVector.z;
+ _startSlice = startScreenVector.w;
+ _endSlice = endScreenVector.w;
+
+ _screenRectangle.left = bbox_min_x;
+ _screenRectangle.right = bbox_max_x;
+ _screenRectangle.top = bbox_min_y;
+ _screenRectangle.bottom = bbox_max_y;
+}
+
+void SliceRenderer::loadFrame(int animation, int frame) {
+ _animation = animation;
+ _frame = frame;
+ _sliceFramePtr = _vm->_sliceAnimations->getFramePtr(_animation, _frame);
+
+ Common::MemoryReadStream stream((byte*)_sliceFramePtr, _vm->_sliceAnimations->_animations[_animation].frameSize);
+
+ _frameScale.x = stream.readFloatLE();
+ _frameScale.y = stream.readFloatLE();
+ _frameSliceHeight = stream.readFloatLE();
+ _framePos.x = stream.readFloatLE();
+ _framePos.y = stream.readFloatLE();
+ _frameBottomZ = stream.readFloatLE();
+ _framePaletteIndex = stream.readUint32LE();
+ _frameSliceCount = stream.readUint32LE();
+}
+
+struct SliceLineIterator {
+ int _sliceMatrix[2][3];
+ int _startY;
+ int _endY;
+
+ float _currentZ;
+ float _stepZ;
+ float _currentSlice;
+ float _stepSlice;
+ float _currentX;
+ float _stepX;
+ int _field_38;
+ int _currentY;
+
+ void setup(float endScreenX, float endScreenY, float endScreenZ,
+ float startScreenX, float startScreenY, float startScreenZ,
+ float endSlice, float startSlice,
+ Matrix3x2 m);
+ float line();
+ void advance();
+};
+
+void SliceLineIterator::setup(
+ float endScreenX, float endScreenY, float endScreenZ,
+ float startScreenX, float startScreenY, float startScreenZ,
+ float endSlice, float startSlice,
+ Matrix3x2 m) {
+ _startY = (int)startScreenY;
+ _endY = (int)endScreenY;
+
+ float size = endScreenY - startScreenY;
+
+ if (size <= 0.0f || startScreenZ <= 0.0f)
+ _currentY = _endY + 1;
+
+ _currentZ = startScreenZ;
+ _stepZ = (endScreenZ - startScreenZ) / size;
+
+ _stepSlice = (endSlice - startSlice) / size;
+ _currentSlice = startSlice - (startScreenY - floor(startScreenY) - 1.0f) * _stepSlice;
+
+ _currentX = startScreenX;
+ _stepX = (endScreenX - startScreenX) / size;
+
+ _field_38 = (int)((25.5f / size) * (1.0f / endScreenZ - 1.0f / startScreenZ) * 64.0);
+ _currentY = _startY;
+
+ float offsetX = _currentX;
+ float offsetZ = 25.5f / _currentZ;
+
+ Matrix3x2 translate_matrix = Matrix3x2(1.0f, 0.0f, offsetX,
+ 0.0f, 1.0f, offsetZ);
+
+ Matrix3x2 scale_matrix = Matrix3x2(65536.0f, 0.0f, 0.0f,
+ 0.0f, 64.0f, 0.0f);
+
+ m = scale_matrix * (translate_matrix * m);
+
+ for (int r = 0; r != 2; ++r)
+ for (int c = 0; c != 3; ++c)
+ _sliceMatrix[r][c] = m(r, c);
+}
+
+float SliceLineIterator::line() {
+ float var_0 = 0.0f;
+
+ if (_currentZ != 0.0f)
+ var_0 = _currentSlice / _currentZ;
+
+ if (var_0 < 0.0)
+ var_0 = 0.0f;
+
+ return var_0;
+}
+
+void SliceLineIterator::advance() {
+ _currentZ += _stepZ;
+ _currentSlice += _stepSlice;
+ _currentX += _stepX;
+ _currentY += 1;
+ _sliceMatrix[0][2] += (int)(65536.0f * _stepX);
+ _sliceMatrix[1][2] += _field_38;
+}
+
+static void setupLookupTable(int t[256], int inc) {
+ int v = 0;
+ for (int i = 0; i != 256; ++i) {
+ t[i] = v;
+ v += inc;
+ }
+}
+
+void SliceRenderer::drawInWorld(int animationId, int animationFrame, Vector3 position, float facing, float scale, Graphics::Surface &surface, uint16 *zbuffer) {
+ assert(_lights);
+ assert(_setEffects);
+ //assert(_view);
+
+ _vm->_sliceRenderer->setupFrameInWorld(animationId, animationFrame, position, facing);
+ assert(_sliceFramePtr);
+
+ SliceLineIterator sliceLineIterator;
+ sliceLineIterator.setup(
+ _endScreenVector.x, _endScreenVector.y, _endScreenVector.z,
+ _startScreenVector.x, _startScreenVector.y, _startScreenVector.z,
+ _endSlice, _startSlice,
+ _modelMatrix
+ );
+
+ SliceRendererLights sliceRendererLights = SliceRendererLights(_lights);
+
+ _lights->setupFrame(_view._frame);
+ _setEffects->setupFrame(_view._frame);
+
+ float sliceLine = sliceLineIterator.line();
+
+ sliceRendererLights.calculateColorBase(
+ Vector3(_position.x, _position.y, _position.z + _frameBottomZ + sliceLine * _frameSliceHeight),
+ Vector3(_position.x, _position.y, _position.z + _frameBottomZ),
+ sliceLineIterator._endY - sliceLineIterator._startY);
+
+ float setEffectsColorCoeficient;
+ Color setEffectColor;
+ _setEffects->calculateColor(
+ _view._cameraPosition,
+ Vector3(_position.x, _position.y, _position.z + _frameBottomZ + sliceLine * _frameSliceHeight),
+ &setEffectsColorCoeficient,
+ &setEffectColor);
+
+ _lightsColor.r = setEffectsColorCoeficient * sliceRendererLights._finalColor.r * 65536.0f;
+ _lightsColor.g = setEffectsColorCoeficient * sliceRendererLights._finalColor.g * 65536.0f;
+ _lightsColor.b = setEffectsColorCoeficient * sliceRendererLights._finalColor.b * 65536.0f;
+
+ _setEffectColor.r = setEffectColor.r * 31.0f * 65536.0f;
+ _setEffectColor.g = setEffectColor.g * 31.0f * 65536.0f;
+ _setEffectColor.b = setEffectColor.b * 31.0f * 65536.0f;
+
+ setupLookupTable(_m11lookup, sliceLineIterator._sliceMatrix[0][0]);
+ setupLookupTable(_m12lookup, sliceLineIterator._sliceMatrix[0][1]);
+ _m13 = sliceLineIterator._sliceMatrix[0][2];
+ setupLookupTable(_m21lookup, sliceLineIterator._sliceMatrix[1][0]);
+ setupLookupTable(_m22lookup, sliceLineIterator._sliceMatrix[1][1]);
+ _m23 = sliceLineIterator._sliceMatrix[1][2];
+
+
+ if(_animationsShadowEnabled[_animation]) {
+ //TODO: draw shadows
+ }
+
+ int frameY = sliceLineIterator._startY;
+
+ uint16 *frameLinePtr = (uint16*)surface.getPixels() + 640 * frameY;
+ uint16 *zBufferLinePtr = zbuffer + 640 * frameY;
+
+ while (sliceLineIterator._currentY <= sliceLineIterator._endY) {
+ sliceLine = sliceLineIterator.line();
+
+ sliceRendererLights.calculateColorSlice(Vector3(_position.x, _position.y, _position.z + _frameBottomZ + sliceLine * _frameSliceHeight));
+
+ if (sliceLineIterator._currentY & 1) {
+ _setEffects->calculateColor(
+ _view._cameraPosition,
+ Vector3(_position.x, _position.y, _position.z + _frameBottomZ + sliceLine * _frameSliceHeight),
+ &setEffectsColorCoeficient,
+ &setEffectColor);
+ }
+
+ _lightsColor.r = setEffectsColorCoeficient * sliceRendererLights._finalColor.r * 65536.0f;
+ _lightsColor.g = setEffectsColorCoeficient * sliceRendererLights._finalColor.g * 65536.0f;
+ _lightsColor.b = setEffectsColorCoeficient * sliceRendererLights._finalColor.b * 65536.0f;
+
+ _setEffectColor.r = setEffectColor.r * 31.0f * 65536.0f;
+ _setEffectColor.g = setEffectColor.g * 31.0f * 65536.0f;
+ _setEffectColor.b = setEffectColor.b * 31.0f * 65536.0f;
+
+ if (frameY >= 0 && frameY < 480) {
+ drawSlice((int)sliceLine, true, frameLinePtr, zBufferLinePtr);
+ }
+
+ sliceLineIterator.advance();
+ frameY += 1;
+ frameLinePtr += 640;
+ zBufferLinePtr += 640;
+ }
+}
+
+void SliceRenderer::drawOnScreen(int animationId, int animationFrame, int screenX, int screenY, float facing, float scale, Graphics::Surface &surface, uint16 *zbuffer) {
+ if (scale == 0.0f) {
+ return;
+ }
+ _position.x = 0;
+ _position.y = 0;
+ _position.z = 0;
+ _facing = facing;
+
+ loadFrame(animationId, animationFrame);
+
+ float frameHeight = _frameSliceHeight * _frameSliceCount;
+ float frameSize = sqrtf(_frameScale.x * 255.0f * _frameScale.x * 255.0f + _frameScale.y * 255.0f * _frameScale.y * 255.0f);
+ float size = scale / MAX(frameSize, frameHeight);
+
+ float s = sinf(_facing);
+ float c = cosf(_facing);
+
+ Matrix3x2 m_rotation(c, -s, 0.0f,
+ s, c, 0.0f);
+
+ Matrix3x2 m_frame(_frameScale.x, 0.0f, _framePos.x,
+ 0.0f, _frameScale.y, _framePos.y);
+
+ Matrix3x2 m_scale_size_25_5(size, 0.0f, 0.0f,
+ 0.0f, 25.5f, 0.0f);
+
+ Matrix3x2 m_translate_x_32k(1.0f, 0.0f, screenX,
+ 0.0f, 1.0f, 32768.0f);
+
+ Matrix3x2 m_scale_64k_64(65536.0f, 0.0f, 0.0f,
+ 0.0f, 64.0f, 0.0f);
+
+ Matrix3x2 m = m_scale_64k_64 * (m_translate_x_32k * (m_scale_size_25_5 * (m_rotation * m_frame)));
+
+ setupLookupTable(_m11lookup, m(0, 0));
+ setupLookupTable(_m12lookup, m(0, 1));
+ _m13 = m(0, 2);
+ setupLookupTable(_m21lookup, m(1, 0));
+ setupLookupTable(_m22lookup, m(1, 1));
+ _m23 = m(1, 2);
+
+ int frameY = screenY + (size / 2.0f * frameHeight);
+ int currentY = frameY;
+
+ float currentSlice = 0;
+ float sliceStep = 1.0f / size / _frameSliceHeight;
+
+ uint16 *frameLinePtr = (uint16*)surface.getPixels() + 640 * frameY;
+ uint16 lineZbuffer[640];
+
+ while (currentSlice < _frameSliceCount) {
+ if (currentY >= 0 && currentY < 480) {
+ memset(lineZbuffer, 0xFF, 640 * 2);
+ drawSlice(currentSlice, false, frameLinePtr, lineZbuffer);
+ currentSlice += sliceStep;
+ currentY--;
+ frameLinePtr -= 640;
+ }
+ }
+}
+
+void SliceRenderer::drawSlice(int slice, bool advanced, uint16 *frameLinePtr, uint16 *zbufLinePtr) {
+ if (slice < 0 || (uint32)slice >= _frameSliceCount)
+ return;
+
+ SlicePalette &palette = _vm->_sliceAnimations->getPalette(_framePaletteIndex);
+
+ byte *p = (byte*)_sliceFramePtr + 0x20 + 4 * slice;
+
+ uint32 polyOffset = READ_LE_UINT32(p);
+
+ p = (byte*)_sliceFramePtr + polyOffset;
+
+ uint32 polyCount = READ_LE_UINT32(p);
+ p += 4;
+ while (polyCount--) {
+ uint32 vertexCount = READ_LE_UINT32(p);
+ p += 4;
+
+ if (vertexCount == 0)
+ continue;
+
+ uint32 lastVertex = vertexCount - 1;
+ int lastVertexX = MAX((_m11lookup[p[3 * lastVertex]] + _m12lookup[p[3 * lastVertex + 1]] + _m13) >> 16, 0);
+
+ int previousVertexX = lastVertexX;
+
+ while (vertexCount--) {
+ int vertexX = CLIP((_m11lookup[p[0]] + _m12lookup[p[1]] + _m13) >> 16, 0, 640);
+
+ if (vertexX > previousVertexX) {
+ int vertexZ = (_m21lookup[p[0]] + _m22lookup[p[1]] + _m23) >> 6;
+
+ if (vertexZ >= 0 && vertexZ < 65536) {
+ int color555 = palette.color555[p[2]];
+ if (advanced) {
+ Color256 color = palette.color[p[2]];
+
+ color.r = (int)(_setEffectColor.r + _lightsColor.r * color.r) >> 16;
+ color.g = (int)(_setEffectColor.g + _lightsColor.g * color.g) >> 16;
+ color.b = (int)(_setEffectColor.b + _lightsColor.b * color.b) >> 16;
+
+ int bladeToScummVmConstant = 256 / 32;
+
+ color555 = _pixelFormat.RGBToColor(CLIP(color.r * bladeToScummVmConstant, 0, 255), CLIP(color.g * bladeToScummVmConstant, 0, 255), CLIP(color.b * bladeToScummVmConstant, 0, 255));
+ }
+ for (int x = previousVertexX; x != vertexX; ++x) {
+ if (vertexZ < zbufLinePtr[x]) {
+ frameLinePtr[x] = color555;
+ zbufLinePtr[x] = (uint16)vertexZ;
+ }
+ }
+ }
+ }
+ p += 3;
+ previousVertexX = vertexX;
+ }
+ }
+}
+
+void SliceRenderer::preload(int animationId) {
+ int i;
+ int frameCount = _vm->_sliceAnimations->getFrameCount(animationId);
+ for (i = 0; i < frameCount; i++)
+ _vm->_sliceAnimations->getFramePtr(animationId, i);
+}
+
+void SliceRenderer::disableShadows(int animationsIdsList[], int listSize) {
+ int i;
+ for (i = 0; i < listSize; i++) {
+ _animationsShadowEnabled[animationsIdsList[i]] = false;
+ }
+}
+
+SliceRendererLights::SliceRendererLights(Lights *lights) {
+ _finalColor.r = 0.0f;
+ _finalColor.g = 0.0f;
+ _finalColor.b = 0.0f;
+
+ _lights = lights;
+
+ for (int i = 0; i < 20; i++) {
+ _colors[i].r = 0.0f;
+ _colors[i].g = 0.0f;
+ _colors[i].b = 0.0f;
+ }
+}
+
+void SliceRendererLights::calculateColorBase(Vector3 position1, Vector3 position2, float height) {
+ _finalColor.r = 0.0f;
+ _finalColor.g = 0.0f;
+ _finalColor.b = 0.0f;
+ _hmm3 = 0;
+ if (_lights) {
+ for (uint i = 0; i < _lights->_lights.size(); i++) {
+ Light *light = _lights->_lights[i];
+ if (i < 20) {
+ float v8 = light->calculate(position1, position2/*, height*/);
+
+ this->_hmm2[i] = v8;
+ this->_hmm[i] = v8;
+
+ Color v22;
+ light->calculateColor(&v22, position1);
+ _colors[i] = v22;
+ _finalColor.r += v22.r;
+ _finalColor.g += v22.g;
+ _finalColor.b += v22.b;
+ } else {
+ Color v23;
+ light->calculateColor(&v23, position1);
+ _finalColor.r += v23.r;
+ _finalColor.g += v23.g;
+ _finalColor.b += v23.b;
+ }
+ }
+
+ _finalColor.r += _lights->_ambientLightColor.r;
+ _finalColor.g += _lights->_ambientLightColor.g;
+ _finalColor.b += _lights->_ambientLightColor.b;
+ }
+}
+
+void SliceRendererLights::calculateColorSlice(Vector3 position) {
+ _finalColor.r = 0.0f;
+ _finalColor.g = 0.0f;
+ _finalColor.b = 0.0f;
+
+ if (_lights) {
+ for (uint i = 0; i < _lights->_lights.size(); i++) {
+ Light *light = _lights->_lights[i];
+ if (i < 20) {
+ _hmm[i] = _hmm[i] - 1.0f;
+
+ if (_hmm[i] <= 0.0f) {
+ do {
+ _hmm[i] = _hmm[i] + _hmm2[i];
+ } while (_hmm[i] <= 0.0f);
+ light->calculateColor(&_colors[i], position);
+ _hmm3++;
+ }
+ _finalColor.r += _colors[i].r;
+ _finalColor.g += _colors[i].g;
+ _finalColor.b += _colors[i].b;
+ } else {
+ Color color;
+ light->calculateColor(&color, position);
+ _hmm3++;
+ _finalColor.r += color.r;
+ _finalColor.g += color.g;
+ _finalColor.b += color.b;
+ }
+ }
+ _finalColor.r += _lights->_ambientLightColor.r;
+ _finalColor.g += _lights->_ambientLightColor.g;
+ _finalColor.b += _lights->_ambientLightColor.b;
+ }
+}
+
+} // End of namespace BladeRunner