diff options
author | Paul Gilbert | 2017-08-31 19:59:33 -0400 |
---|---|---|
committer | GitHub | 2017-08-31 19:59:33 -0400 |
commit | bdabf32bea451b94dcb239af5c574dd94d6789ac (patch) | |
tree | 588d905f1d8ef6aa1e07c6dc716df8b0a2409daa | |
parent | d1325e2d12ec2b7f9e12381f3e62e94897d5b57c (diff) | |
parent | 4dbfc3595e459a8c51dcdbfada812e525218758f (diff) | |
download | scummvm-rg350-bdabf32bea451b94dcb239af5c574dd94d6789ac.tar.gz scummvm-rg350-bdabf32bea451b94dcb239af5c574dd94d6789ac.tar.bz2 scummvm-rg350-bdabf32bea451b94dcb239af5c574dd94d6789ac.zip |
Merge pull request #1003 from dafioram/fix9961
TITANIC: Star_Control cleanup and Fix bug #9961
18 files changed, 419 insertions, 174 deletions
diff --git a/engines/titanic/star_control/camera_auto_mover.cpp b/engines/titanic/star_control/camera_auto_mover.cpp index 201cd9440a..9fe5e15e7e 100644 --- a/engines/titanic/star_control/camera_auto_mover.cpp +++ b/engines/titanic/star_control/camera_auto_mover.cpp @@ -41,7 +41,8 @@ CCameraAutoMover::CCameraAutoMover() : _srcPos(0.0, 1000000.0, 0.0) { _transitionPercentInc = 0.0; } -void CCameraAutoMover::proc2(const FVector &oldPos, const FVector &newPos, +// TODO: same as setPath also orientations are not used +void CCameraAutoMover::setPath2(const FVector &oldPos, const FVector &newPos, const FMatrix &oldOrientation, const FMatrix &newOrientation) { _srcPos = oldPos; _destPos = newPos; @@ -59,7 +60,8 @@ void CCameraAutoMover::proc2(const FVector &oldPos, const FVector &newPos, _field4C = 0; } -void CCameraAutoMover::proc3(const FMatrix &srcOrient, const FMatrix &destOrient) { +// TODO: same as proc2 also orientations are not used +void CCameraAutoMover::setOrientations(const FMatrix &srcOrient, const FMatrix &destOrient) { _srcPos.clear(); _destPos.clear(); _transitionPercent = 1.0; @@ -68,6 +70,7 @@ void CCameraAutoMover::proc3(const FMatrix &srcOrient, const FMatrix &destOrient _field34 = false; } +// TODO: same as setPath2 also orientations are not used void CCameraAutoMover::setPath(const FVector &srcV, const FVector &destV, const FMatrix &orientation) { _srcPos = srcV; _destPos = destV; @@ -93,8 +96,8 @@ void CCameraAutoMover::setPath(const FVector &srcV, const FVector &destV, const void CCameraAutoMover::calcSpeeds(int val1, int val2, float distance) { // Usually val1 and val2 are small where as distance can be large _field44 = val1; - _field4C = val1 + 2 * nMoverTransitions; // For _nMoverTransitions = 32 this second value was 64, - // should it always be x2 _nMoverTransitions? + _field4C = val1 + 2 * (nMoverTransitions - 1); // For _nMoverTransitions = 32 this second value was 62, + // should it always be x2 (_nMoverTransitions - 1)? _field38 = distance / (double)(val1 + val2 * 2); _field40 = nMoverTransitions-1; _field48 = nMoverTransitions-1; @@ -113,4 +116,4 @@ void CCameraAutoMover::calcSpeeds(int val1, int val2, float distance) { } } -} // End of namespace Titanic +} // End of namespace Titanic
\ No newline at end of file diff --git a/engines/titanic/star_control/camera_auto_mover.h b/engines/titanic/star_control/camera_auto_mover.h index 210bd74091..25384632fa 100644 --- a/engines/titanic/star_control/camera_auto_mover.h +++ b/engines/titanic/star_control/camera_auto_mover.h @@ -32,7 +32,7 @@ namespace Titanic { class CErrorCode; class FMatrix; const int nMoverTransitions = 32; // The number of vector transitions when doing a mover change is fixed - +enum MoverState {NOT_ACTIVE=0,MOVING=1,DONE_MOVING=2}; /** * Base class for automatic movement of the starview camera */ @@ -59,11 +59,19 @@ public: CCameraAutoMover(); virtual ~CCameraAutoMover() {} - virtual void proc2(const FVector &oldPos, const FVector &newPos, + virtual void setPath2(const FVector &oldPos, const FVector &newPos, const FMatrix &oldOrientation, const FMatrix &newOrientation); - virtual void proc3(const FMatrix &srcOrient, const FMatrix &destOrient); + + /** + * Clear src and dest orientation and set some default values for other fields + */ + virtual void setOrientations(const FMatrix &srcOrient, const FMatrix &destOrient); virtual void setPath(const FVector &srcV, const FVector &destV, const FMatrix &orientation); - virtual int proc5(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) { return 2; } + + /** + * Applys speeds to the mover. More than one application is usually done for several transitions + */ + virtual MoverState move(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) { return DONE_MOVING; } /** * Given a distance to cover, determines a bunch of speeds for a gradual transition * from one position to another (the mover). The speeds go from fast to slow diff --git a/engines/titanic/star_control/camera_mover.cpp b/engines/titanic/star_control/camera_mover.cpp index 95981a951c..09e7ed72ba 100644 --- a/engines/titanic/star_control/camera_mover.cpp +++ b/engines/titanic/star_control/camera_mover.cpp @@ -23,7 +23,6 @@ #include "titanic/star_control/camera_mover.h" #include "titanic/star_control/base_stars.h" // includes class CStarVector #include "titanic/star_control/error_code.h" -#include "titanic/star_control/fmatrix.h" // Also has class FVector #include "titanic/support/simple_file.h" // Not currently being used: #include "common/textconsole.h" @@ -36,14 +35,7 @@ CCameraMover::CCameraMover(const CNavigationInfo *src) { if (src) { copyFrom(src); } else { - _speed = 0.0; - _speedChangeCtr = 0.0; - _speedChangeInc = 20.0; - _unused = 0.0; - _maxSpeed = 50000.0; - _unusedX = 1.0; - _unusedY = 1.0; - _unusedZ = 0.0; + reset(); } } @@ -51,6 +43,29 @@ CCameraMover::~CCameraMover() { clear(); } +void CCameraMover::clear() { + if (_starVector) { + delete _starVector; + _starVector = nullptr; + } +} + +void CCameraMover::reset() { + _speed = 0.0; + _speedChangeCtr = 0.0; + _speedChangeInc = 20.0; + _unused = 0.0; + _maxSpeed = 50000.0; + _unusedX = 1.0; + _unusedY = 1.0; + _unusedZ = 0.0; +} + +void CCameraMover::setVector(CStarVector *sv) { + clear(); + _starVector = sv; +} + void CCameraMover::copyFrom(const CNavigationInfo *src) { _speed = src->_speed; _unused = src->_speedChangeCtr; @@ -99,28 +114,7 @@ void CCameraMover::stop() { } } -void CCameraMover::updatePosition(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) { - if (_speed > 0.0) { - pos._x += orientation._row3._x * _speed; - pos._y += orientation._row3._y * _speed; - pos._z += orientation._row3._z * _speed; - - errorCode.set(); - } -} - -void CCameraMover::setVector(CStarVector *sv) { - clear(); - _starVector = sv; -} - -void CCameraMover::clear() { - if (_starVector) { - delete _starVector; - _starVector = nullptr; - } -} - +// TODO: this is confusing to negate the val value void CCameraMover::load(SimpleFile *file, int val) { if (!val) { _speed = file->readFloat(); @@ -146,6 +140,7 @@ void CCameraMover::save(SimpleFile *file, int indent) { } void CCameraMover::incLockCount() { + if (_lockCounter < 3) ++_lockCounter; } @@ -154,4 +149,4 @@ void CCameraMover::decLockCount() { --_lockCounter; } -} // End of namespace Titanic +} // End of namespace Titanic
\ No newline at end of file diff --git a/engines/titanic/star_control/camera_mover.h b/engines/titanic/star_control/camera_mover.h index 9bd9d48700..3d72e01c8c 100644 --- a/engines/titanic/star_control/camera_mover.h +++ b/engines/titanic/star_control/camera_mover.h @@ -23,10 +23,6 @@ #ifndef TITANIC_CAMERA_MOVER_H #define TITANIC_CAMERA_MOVER_H -//#include "titanic/support/simple_file.h" -//#include "titanic/star_control/error_code.h" -//#include "titanic/star_control/fmatrix.h" // class FVector - namespace Titanic { class CErrorCode; @@ -58,6 +54,19 @@ public: virtual void copyTo(CNavigationInfo *dest); /** + * delete _starVector + */ + virtual void clear(); + /** + * Set default values for CNavigationInfo + */ + virtual void reset(); + + /** + * Sets this CStarVector + */ + virtual void setVector(CStarVector *sv); + /** * Increases movement speed in forward direction */ virtual void increaseForwardSpeed(); @@ -77,7 +86,11 @@ public: */ virtual void stop(); - virtual void proc8(const FVector &oldPos, const FVector &newPos, + /** + * Move the mover from an old position and orientation to a new + * position and orientation + */ + virtual void transitionBetweenPosOrients(const FVector &oldPos, const FVector &newPos, const FMatrix &oldOrientation, const FMatrix &newOrientation) {} /** @@ -85,19 +98,16 @@ public: */ virtual void moveTo(const FVector &srcV, const FVector &destV, const FMatrix &orientation) {} - virtual void proc10(const FVector &v1, const FVector &v2, const FVector &v3, const FMatrix &m) {} - /** - * Update the passed position and orientation matrix + * First two vectors are used to form a new orientation that gets transitioned to from the old + * orientation m. */ - virtual void updatePosition(CErrorCode &errorCode, FVector &pos, FMatrix &orientation); - - virtual void setVector(CStarVector *sv); + virtual void transitionBetweenOrientations(const FVector &v1, const FVector &v2, const FVector &v3, const FMatrix &m) {} /** - * Clear the class + * Update the passed position and orientation matrix */ - virtual void clear(); + virtual void updatePosition(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) {} /** * Load the class diff --git a/engines/titanic/star_control/daffine.cpp b/engines/titanic/star_control/daffine.cpp index 5b935838fa..616042d715 100644 --- a/engines/titanic/star_control/daffine.cpp +++ b/engines/titanic/star_control/daffine.cpp @@ -22,6 +22,7 @@ #include "titanic/star_control/daffine.h" #include "titanic/star_control/fmatrix.h" // includes FVector +#include "titanic/star_control/matrix_inv.h" #include "titanic/star_control/matrix_transform.h" namespace Titanic { @@ -115,11 +116,26 @@ void DAffine::setRotationMatrix(Axis axis, double angleDeg) { } } -//TODO: Check column 4 math DAffine DAffine::inverseTransform() const { DAffine m; + // Create a 4x4 matrix so that the column 4 + // for the inverse can be obtained, + // it is not simply -inv(R)*_col4 + // Load input matrix + double A[16]={_col1._x,_col1._y,_col1._z, 0.0, + _col2._x,_col2._y,_col2._z, 0.0, + _col3._x,_col3._y,_col3._z, 0.0, + _col4._x,_col4._y,_col4._z, 1.0}; + // Inverse matrix + double B[16]={}; + + // B contains inverse of A + matrix4Inverse(A,B); + // Inverse of rotation matrix is the transpose + // While B contains the inverse of the rotation + // this method is more numerically accurate m._col1._x = _col1._x; m._col2._x = _col1._y; m._col3._x = _col1._z; @@ -130,15 +146,10 @@ DAffine DAffine::inverseTransform() const { m._col2._z = _col3._y; m._col3._z = _col3._z; - m._col4._x = -(_col4._x * m._col1._x - + _col4._y * m._col2._x - + _col4._z * m._col3._x); - m._col4._y = -(_col4._x * m._col1._y - + _col4._y * m._col2._y - + _col4._z * m._col3._y); - m._col4._z = -(_col4._x * m._col1._z - + _col4._y * m._col2._z - + _col4._z * m._col3._z); + m._col4._x = B[12]; + m._col4._y = B[13]; + m._col4._z = B[14]; + return m; } diff --git a/engines/titanic/star_control/dvector.cpp b/engines/titanic/star_control/dvector.cpp index 88390ebc3f..73ffd5be54 100644 --- a/engines/titanic/star_control/dvector.cpp +++ b/engines/titanic/star_control/dvector.cpp @@ -102,7 +102,7 @@ DAffine DVector::getFrameTransform(const DVector &v) { return matrix4.compose(matrix3); } -DAffine DVector::rotXY() const { +DAffine DVector::formRotXY() const { DVector v1 = getAnglesAsVect(); DAffine m1, m2; m1.setRotationMatrix(X_AXIS, v1._y * Rad2Deg); diff --git a/engines/titanic/star_control/dvector.h b/engines/titanic/star_control/dvector.h index e9ca257498..a1c67d7382 100644 --- a/engines/titanic/star_control/dvector.h +++ b/engines/titanic/star_control/dvector.h @@ -83,10 +83,10 @@ public: DAffine getFrameTransform(const DVector &v); /** - * Returns a affine matrix that does a x then a y axis frame rotation + * Constructs an affine matrix that does a x then a y axis frame rotation * based on the orientation of this vector */ - DAffine rotXY() const; + DAffine formRotXY() const; /** * Returns true if the passed vector equals this one diff --git a/engines/titanic/star_control/marked_auto_mover.cpp b/engines/titanic/star_control/marked_auto_mover.cpp index a154bfddf2..0787c48de3 100644 --- a/engines/titanic/star_control/marked_auto_mover.cpp +++ b/engines/titanic/star_control/marked_auto_mover.cpp @@ -26,9 +26,9 @@ namespace Titanic { -void CMarkedAutoMover::proc2(const FVector &oldPos, const FVector &newPos, +void CMarkedAutoMover::setPath2(const FVector &oldPos, const FVector &newPos, const FMatrix &oldOrientation, const FMatrix &newOrientation) { - CCameraAutoMover::proc2(oldPos, newPos, oldOrientation, newOrientation); + CCameraAutoMover::setPath2(oldPos, newPos, oldOrientation, newOrientation); double distance = _distance; _active = true; @@ -49,9 +49,9 @@ void CMarkedAutoMover::proc2(const FVector &oldPos, const FVector &newPos, } -int CMarkedAutoMover::proc5(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) { +MoverState CMarkedAutoMover::move(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) { if (!_active) - return 0; + return NOT_ACTIVE; _transitionPercent += _transitionPercentInc; orientation = _orientationChanger.getOrientation(_transitionPercent); @@ -64,14 +64,14 @@ int CMarkedAutoMover::proc5(CErrorCode &errorCode, FVector &pos, FMatrix &orient --_field40; errorCode.set(); - return 1; + return MOVING; } else if (_field44 > 0) { pos += _posDelta * _field38; getVectorOnPath(pos); --_field44; errorCode.set(); - return 1; + return MOVING; } else if (_field48 >= 0) { double speedVal = _speeds[nMoverTransitions - 1 - _field48]; pos += _posDelta * speedVal; @@ -79,10 +79,10 @@ int CMarkedAutoMover::proc5(CErrorCode &errorCode, FVector &pos, FMatrix &orient --_field48; errorCode.set(); - return 1; + return MOVING; } else { _active = false; - return 2; + return DONE_MOVING; } } diff --git a/engines/titanic/star_control/marked_auto_mover.h b/engines/titanic/star_control/marked_auto_mover.h index 5127496241..856df99c03 100644 --- a/engines/titanic/star_control/marked_auto_mover.h +++ b/engines/titanic/star_control/marked_auto_mover.h @@ -41,9 +41,13 @@ private: public: virtual ~CMarkedAutoMover() {} - virtual void proc2(const FVector &oldPos, const FVector &newPos, + virtual void setPath2(const FVector &oldPos, const FVector &newPos, const FMatrix &oldOrientation, const FMatrix &newOrientation); - virtual int proc5(CErrorCode &errorCode, FVector &pos, FMatrix &orientation); + + /** + * Applys speeds to the mover. More than one application is usually done for several transitions + */ + virtual MoverState move(CErrorCode &errorCode, FVector &pos, FMatrix &orientation); }; } // End of namespace Titanic diff --git a/engines/titanic/star_control/marked_camera_mover.cpp b/engines/titanic/star_control/marked_camera_mover.cpp index 79e74cdd05..ff9c055abb 100644 --- a/engines/titanic/star_control/marked_camera_mover.cpp +++ b/engines/titanic/star_control/marked_camera_mover.cpp @@ -23,6 +23,7 @@ #include "titanic/star_control/marked_camera_mover.h" #include "titanic/star_control/base_stars.h" // includes class CStarVector #include "titanic/star_control/error_code.h" +#include "titanic/star_control/fmatrix.h" // includes class FVector // Not currently being used: #include "common/textconsole.h" namespace Titanic { @@ -31,22 +32,23 @@ CMarkedCameraMover::CMarkedCameraMover(const CNavigationInfo *src) : CCameraMover(src) { } -void CMarkedCameraMover::proc8(const FVector &oldPos, const FVector &newPos, + +void CMarkedCameraMover::transitionBetweenPosOrients(const FVector &oldPos, const FVector &newPos, const FMatrix &oldOrientation, const FMatrix &newOrientation) { if (isLocked()) decLockCount(); - _autoMover.proc2(oldPos, newPos, oldOrientation, newOrientation); + _autoMover.setPath2(oldPos, newPos, oldOrientation, newOrientation); incLockCount(); } void CMarkedCameraMover::updatePosition(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) { if (_autoMover.isActive()) { decLockCount(); - int val = _autoMover.proc5(errorCode, pos, orientation); - if (val == 1) + MoverState moveState = _autoMover.move(errorCode, pos, orientation); + if (moveState == MOVING) incLockCount(); - if (val == 2) { + if (moveState == DONE_MOVING) { stop(); if (_starVector) _starVector->apply(); diff --git a/engines/titanic/star_control/marked_camera_mover.h b/engines/titanic/star_control/marked_camera_mover.h index 7706db1098..2e971615dc 100644 --- a/engines/titanic/star_control/marked_camera_mover.h +++ b/engines/titanic/star_control/marked_camera_mover.h @@ -28,6 +28,9 @@ namespace Titanic { +class FMatrix; +class FVector; + class CMarkedCameraMover : public CCameraMover { private: CMarkedAutoMover _autoMover; @@ -35,7 +38,11 @@ public: CMarkedCameraMover(const CNavigationInfo *src); virtual ~CMarkedCameraMover() {} - virtual void proc8(const FVector &oldPos, const FVector &newPos, + /** + * Move the mover from an old position and orientation to a new + * position and orientation + */ + virtual void transitionBetweenPosOrients(const FVector &oldPos, const FVector &newPos, const FMatrix &oldOrientation, const FMatrix &newOrientation); /** diff --git a/engines/titanic/star_control/matrix_inv.h b/engines/titanic/star_control/matrix_inv.h new file mode 100644 index 0000000000..21eb1d3a6f --- /dev/null +++ b/engines/titanic/star_control/matrix_inv.h @@ -0,0 +1,189 @@ +/* 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. + * + */ + +/* +* Files matrix_inv.h are a part of the MESA 3D Library (MIT License) +* +* Copyright (C) 1999-2007 Brian Paul All Rights Reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +*/ + +#ifndef TITANIC_MATRIX_INV_H +#define TITANIC_MATRIX_INV_H + +namespace Titanic { + +// 4x4 Matrix m is column major, e.x., m[3] is the row 4 column 1 element +// Modified version of MESA 3D library function (MIT license) +bool matrix4Inverse(const double m[16], double invOut[16]) +{ + double temp_inv[16]; + double determinant; + double determinant_inv; + int i; + + temp_inv[0] = m[5] * m[10] * m[15] - + m[5] * m[11] * m[14] - + m[9] * m[6] * m[15] + + m[9] * m[7] * m[14] + + m[13] * m[6] * m[11] - + m[13] * m[7] * m[10]; + + temp_inv[4] = -m[4] * m[10] * m[15] + + m[4] * m[11] * m[14] + + m[8] * m[6] * m[15] - + m[8] * m[7] * m[14] - + m[12] * m[6] * m[11] + + m[12] * m[7] * m[10]; + + temp_inv[8] = m[4] * m[9] * m[15] - + m[4] * m[11] * m[13] - + m[8] * m[5] * m[15] + + m[8] * m[7] * m[13] + + m[12] * m[5] * m[11] - + m[12] * m[7] * m[9]; + + temp_inv[12] = -m[4] * m[9] * m[14] + + m[4] * m[10] * m[13] + + m[8] * m[5] * m[14] - + m[8] * m[6] * m[13] - + m[12] * m[5] * m[10] + + m[12] * m[6] * m[9]; + + temp_inv[1] = -m[1] * m[10] * m[15] + + m[1] * m[11] * m[14] + + m[9] * m[2] * m[15] - + m[9] * m[3] * m[14] - + m[13] * m[2] * m[11] + + m[13] * m[3] * m[10]; + + temp_inv[5] = m[0] * m[10] * m[15] - + m[0] * m[11] * m[14] - + m[8] * m[2] * m[15] + + m[8] * m[3] * m[14] + + m[12] * m[2] * m[11] - + m[12] * m[3] * m[10]; + + temp_inv[9] = -m[0] * m[9] * m[15] + + m[0] * m[11] * m[13] + + m[8] * m[1] * m[15] - + m[8] * m[3] * m[13] - + m[12] * m[1] * m[11] + + m[12] * m[3] * m[9]; + + temp_inv[13] = m[0] * m[9] * m[14] - + m[0] * m[10] * m[13] - + m[8] * m[1] * m[14] + + m[8] * m[2] * m[13] + + m[12] * m[1] * m[10] - + m[12] * m[2] * m[9]; + + temp_inv[2] = m[1] * m[6] * m[15] - + m[1] * m[7] * m[14] - + m[5] * m[2] * m[15] + + m[5] * m[3] * m[14] + + m[13] * m[2] * m[7] - + m[13] * m[3] * m[6]; + + temp_inv[6] = -m[0] * m[6] * m[15] + + m[0] * m[7] * m[14] + + m[4] * m[2] * m[15] - + m[4] * m[3] * m[14] - + m[12] * m[2] * m[7] + + m[12] * m[3] * m[6]; + + temp_inv[10] = m[0] * m[5] * m[15] - + m[0] * m[7] * m[13] - + m[4] * m[1] * m[15] + + m[4] * m[3] * m[13] + + m[12] * m[1] * m[7] - + m[12] * m[3] * m[5]; + + temp_inv[14] = -m[0] * m[5] * m[14] + + m[0] * m[6] * m[13] + + m[4] * m[1] * m[14] - + m[4] * m[2] * m[13] - + m[12] * m[1] * m[6] + + m[12] * m[2] * m[5]; + + temp_inv[3] = -m[1] * m[6] * m[11] + + m[1] * m[7] * m[10] + + m[5] * m[2] * m[11] - + m[5] * m[3] * m[10] - + m[9] * m[2] * m[7] + + m[9] * m[3] * m[6]; + + temp_inv[7] = m[0] * m[6] * m[11] - + m[0] * m[7] * m[10] - + m[4] * m[2] * m[11] + + m[4] * m[3] * m[10] + + m[8] * m[2] * m[7] - + m[8] * m[3] * m[6]; + + temp_inv[11] = -m[0] * m[5] * m[11] + + m[0] * m[7] * m[9] + + m[4] * m[1] * m[11] - + m[4] * m[3] * m[9] - + m[8] * m[1] * m[7] + + m[8] * m[3] * m[5]; + + temp_inv[15] = m[0] * m[5] * m[10] - + m[0] * m[6] * m[9] - + m[4] * m[1] * m[10] + + m[4] * m[2] * m[9] + + m[8] * m[1] * m[6] - + m[8] * m[2] * m[5]; + + determinant = m[0] * temp_inv[0] + m[1] * temp_inv[4] + m[2] * temp_inv[8] + m[3] * temp_inv[12]; + + if (determinant == 0) + return false; + + determinant_inv = 1.0 / determinant; + + for (i = 0; i < 16; i++) + invOut[i] = temp_inv[i] * determinant_inv; + + return true; +} + +} // End of namespace Titanic + +#endif /* TITANIC_MATRIX_INV_H */ diff --git a/engines/titanic/star_control/star_camera.cpp b/engines/titanic/star_control/star_camera.cpp index f7cedf4d22..d1e233906b 100644 --- a/engines/titanic/star_control/star_camera.cpp +++ b/engines/titanic/star_control/star_camera.cpp @@ -34,6 +34,9 @@ namespace Titanic { +const double rowScale1 = 100000.0; +const double rowScale2 = 1000000.0; + FMatrix *CStarCamera::_priorOrientation; FMatrix *CStarCamera::_newOrientation; @@ -260,19 +263,19 @@ void CStarCamera::setViewportAngle(const FPoint &angles) { } case ONE_LOCKED: { - FVector row1 = _matrix._row1; + FVector row1 = _lockedStarsPos._row1; FPose poseX(X_AXIS, angles._y); FPose poseY(Y_AXIS, -angles._x); // needs to be negative or looking left will cause the view to go right FPose pose(poseX, poseY); FMatrix m1 = _viewport.getOrientation(); FVector tempV1 = _viewport._position; - FVector tempV2 = m1._row1 * 100000; + FVector tempV2 = m1._row1 * rowScale1; FVector tempV3 = tempV2 + tempV1; FVector tempV4 = tempV3; - tempV2 = m1._row2 * 100000; - FVector tempV5 = m1._row3 * 100000; + tempV2 = m1._row2 * rowScale1; + FVector tempV5 = m1._row3 * rowScale1; FVector tempV6 = tempV2 + tempV1; FVector tempV7 = tempV5 + tempV1; @@ -317,25 +320,25 @@ void CStarCamera::setViewportAngle(const FPoint &angles) { DVector tempV8, tempV9, tempV10, tempV11, tempV12; DVector tempV13, tempV14, tempV15, tempV16; - DAffine subX(0, _matrix._row1); + DAffine subX(0, _lockedStarsPos._row1); DAffine subY(Y_AXIS, angles._y); - tempV1 = _matrix._row2 - _matrix._row1; + tempV1 = _lockedStarsPos._row2 - _lockedStarsPos._row1; diffV = tempV1; - m1 = diffV.rotXY(); + m1 = diffV.formRotXY(); m1 = m1.compose(subX); subX = m1.inverseTransform(); subX = subX.compose(subY); FMatrix m3 = _viewport.getOrientation(); tempV2 = _viewport._position; - multV._x = m3._row1._x * 1000000.0; - multV._y = m3._row1._y * 1000000.0; - multV._z = m3._row1._z * 1000000.0; + multV._x = m3._row1._x * rowScale2; + multV._y = m3._row1._y * rowScale2; + multV._z = m3._row1._z * rowScale2; tempV3._x = tempV2._x; tempV3._y = tempV2._y; tempV3._z = tempV2._z; - multV2._z = m3._row2._z * 1000000.0; + multV2._z = m3._row2._z * rowScale2; tempV1._x = multV._x + tempV3._x; tempV1._y = multV._y + tempV3._y; @@ -343,15 +346,15 @@ void CStarCamera::setViewportAngle(const FPoint &angles) { mrow3._z = 0.0; mrow3._y = 0.0; mrow3._x = 0.0; - multV2._x = m3._row2._x * 1000000.0; - multV2._y = m3._row2._y * 1000000.0; + multV2._x = m3._row2._x * rowScale2; + multV2._y = m3._row2._y * rowScale2; mrow1 = tempV1; multV = multV2 + tempV3; mrow2 = multV; - tempV7._z = m3._row3._z * 1000000.0 + tempV3._z; - tempV7._y = m3._row3._y * 1000000.0 + tempV3._y; - tempV7._x = m3._row3._x * 1000000.0 + tempV3._x; + tempV7._z = m3._row3._z * rowScale2 + tempV3._z; + tempV7._y = m3._row3._y * rowScale2 + tempV3._y; + tempV7._x = m3._row3._x * rowScale2 + tempV3._x; mrow3 = tempV8 = tempV7; tempV3 = tempV3.dAffMatrixProdVec(subX); @@ -399,7 +402,7 @@ bool CStarCamera::addLockedStar(const FVector v) { _mover->copyTo(&data); deleteHandler(); - FVector &row = _matrix[(int)_starLockState]; + FVector &row = _lockedStarsPos[(int)_starLockState]; _starLockState = StarLockState((int)_starLockState + 1); row = v; setupHandler(&data); @@ -465,7 +468,7 @@ void CStarCamera::deleteHandler() { } } -bool CStarCamera::lockMarker1(FVector v1, FVector v2, FVector v3) { +bool CStarCamera::lockMarker1(FVector v1, FVector firstStarPosition, FVector v3) { if (_starLockState != ZERO_LOCKED) return true; @@ -498,39 +501,39 @@ bool CStarCamera::lockMarker1(FVector v1, FVector v2, FVector v3) { FMatrix matrix = _viewport.getOrientation(); const FVector &pos = _viewport._position; - _mover->proc10(v3, tempV, pos, matrix); + _mover->transitionBetweenOrientations(v3, tempV, pos, matrix); // TODO: pos does not get used in this function - CStarVector *sv = new CStarVector(this, v2); + CStarVector *sv = new CStarVector(this, firstStarPosition); _mover->setVector(sv); return true; } -bool CStarCamera::lockMarker2(CViewport *viewport, const FVector &v) { +bool CStarCamera::lockMarker2(CViewport *viewport, const FVector &secondStarPosition) { if (_starLockState != ONE_LOCKED) return true; - - DAffine m2(X_AXIS, _matrix._row1); - DVector tempV1 = v - _matrix._row1; - DAffine m1 = tempV1.rotXY(); + FVector firstStarPosition = _lockedStarsPos._row1; + DAffine m2(0, firstStarPosition); // Identity matrix and col4 as the 1st stars position + DVector starDelta = secondStarPosition - firstStarPosition; + DAffine m1 = starDelta.formRotXY(); m1 = m1.compose(m2); m2 = m1.inverseTransform(); - DVector tempV2 = _viewport._position; + DVector oldPos = _viewport._position; DAffine m4; m4._col1 = viewport->_position; m4._col2 = DVector(0.0, 0.0, 0.0); m4._col3 = DVector(0.0, 0.0, 0.0); m4._col4 = DVector(0.0, 0.0, 0.0); - FMatrix m5 = viewport->getOrientation(); - double yVal1 = m5._row1._y * 1000000.0; - double zVal1 = m5._row1._z * 1000000.0; - double xVal1 = m5._row2._x * 1000000.0; - double yVal2 = m5._row2._y * 1000000.0; - double zVal2 = m5._row2._z * 1000000.0; + FMatrix newOr = viewport->getOrientation(); + double yVal1 = newOr._row1._y * rowScale2; + double zVal1 = newOr._row1._z * rowScale2; + double xVal1 = newOr._row2._x * rowScale2; + double yVal2 = newOr._row2._y * rowScale2; + double zVal2 = newOr._row2._z * rowScale2; double zVal3 = zVal1 + m4._col1._z; double yVal3 = yVal1 + m4._col1._y; - double xVal2 = m5._row1._x * 1000000.0 + m4._col1._x; + double xVal2 = newOr._row1._x * rowScale2 + m4._col1._x; double zVal4 = zVal2 + m4._col1._z; double yVal4 = yVal2 + m4._col1._y; double xVal3 = xVal1 + m4._col1._x; @@ -540,35 +543,24 @@ bool CStarCamera::lockMarker2(CViewport *viewport, const FVector &v) { m4._col3 = tempV4; FVector tempV5; - tempV5._x = m5._row3._x * 1000000.0; - tempV5._y = m5._row3._y * 1000000.0; + tempV5._x = newOr._row3._x * rowScale2; + tempV5._y = newOr._row3._y * rowScale2; m4._col2 = tempV3; tempV3._x = tempV5._x + m4._col1._x; tempV3._y = tempV5._y + m4._col1._y; - tempV3._z = m5._row3._z * 1000000.0 + m4._col1._z; + tempV3._z = newOr._row3._z * rowScale2 + m4._col1._z; m4._col4 = tempV3; - tempV2 = tempV2.dAffMatrixProdVec(m2); + DVector viewPosition = oldPos.dAffMatrixProdVec(m2); m4._col1 = m4._col1.dAffMatrixProdVec(m2); m4._col3 = m4._col3.dAffMatrixProdVec(m2); m4._col2 = m4._col2.dAffMatrixProdVec(m2); m4._col4 = m4._col4.dAffMatrixProdVec(m2); - // Find the angle that gives the minimum distance - DVector tempPos; - double minDistance = 1.0e20; - int minDegree = 0; - for (int degree = 0; degree < 360; ++degree) { - tempPos = m4._col1; - tempPos.rotVectAxisY((double)degree); - double distance = tempV2.getDistance(tempPos); - - if (distance < minDistance) { - minDistance = distance; - minDegree = degree; - } - } + double minDistance; + // Find the angle of rotation for m4._col1 that gives the minimum distance to viewPosition + double minDegree = calcAngleForMinDist(viewPosition,m4._col1,minDistance); m4._col1.rotVectAxisY((double)minDegree); m4._col2.rotVectAxisY((double)minDegree); @@ -594,29 +586,21 @@ bool CStarCamera::lockMarker2(CViewport *viewport, const FVector &v) { assert(unusedScale); } - m5.set(m4._col3, m4._col2, m4._col4); + newOr.set(m4._col3, m4._col2, m4._col4); FVector newPos = m4._col1; - FMatrix m6 = _viewport.getOrientation(); - - if (minDistance > 1.0e8) { - // The transition will do poorly in this case. - //removeLockedStar(); // undo locking 2nd star - _mover->proc8(_viewport._position, _viewport._position, m6, m6); - //CStarVector *sv = new CStarVector(this, v); - //_mover->setVector(sv); - return false; - } - else { - _mover->proc8(_viewport._position, newPos, m6, m5); - CStarVector *sv = new CStarVector(this, v); - _mover->setVector(sv); - - } + FMatrix oldOr = _viewport.getOrientation(); + + // WORKAROUND: set old position to new position (1st argument), this prevents + // locking issues when locking the 2nd star. Fixes #9961. + _mover->transitionBetweenPosOrients(newPos, newPos, oldOr, newOr); + CStarVector *sv = new CStarVector(this, secondStarPosition); + _mover->setVector(sv); + return true; } -bool CStarCamera::lockMarker3(CViewport *viewport, const FVector &v) { +bool CStarCamera::lockMarker3(CViewport *viewport, const FVector &thirdStarPosition) { if (_starLockState != TWO_LOCKED) return true; @@ -625,11 +609,30 @@ bool CStarCamera::lockMarker3(CViewport *viewport, const FVector &v) { FVector newPos = viewport->_position; FVector oldPos = _viewport._position; - _mover->proc8(oldPos, newPos, oldOr, newOr); + _mover->transitionBetweenPosOrients(oldPos, newPos, oldOr, newOr); - CStarVector *sv = new CStarVector(this, v); + CStarVector *sv = new CStarVector(this, thirdStarPosition); _mover->setVector(sv); return true; } +double CStarCamera::calcAngleForMinDist(DVector &x, DVector &y, double &minDistance) { + DVector tempPos; + minDistance = 1.0e20; + double minDegree = 0.0; + double degInc = 1.0; // one degree steps + int nDegrees = floor(360.0/degInc); + for (int i = 0; i < nDegrees; ++i) { + tempPos = y; + tempPos.rotVectAxisY((double)degInc*i); + double distance = x.getDistance(tempPos); + + if (distance < minDistance) { + minDistance = distance; + minDegree = (double) degInc*i; + } + } + return minDegree; +} + } // End of namespace Titanic diff --git a/engines/titanic/star_control/star_camera.h b/engines/titanic/star_control/star_camera.h index b22abe6eff..71be90d345 100644 --- a/engines/titanic/star_control/star_camera.h +++ b/engines/titanic/star_control/star_camera.h @@ -46,7 +46,7 @@ private: static FMatrix *_newOrientation; private: StarLockState _starLockState; - FMatrix _matrix; + FMatrix _lockedStarsPos; // Each row represents the location of a locked star CCameraMover *_mover; CViewport _viewport; bool _isMoved; @@ -198,6 +198,14 @@ public: virtual void save(SimpleFile *file, int indent); /** + * Calculates the angle of rotation of y that achieves + * the minimum distance to x. + * The angle is in degrees. + * Also returns the minimum distance calculated + */ + double calcAngleForMinDist(DVector &x, DVector &y, double &minDistance); + + /** * Returns true for whether the camera has been moved */ bool isMoved() const { return _isMoved; } diff --git a/engines/titanic/star_control/unmarked_auto_mover.cpp b/engines/titanic/star_control/unmarked_auto_mover.cpp index 1a5d886796..c84fbbab00 100644 --- a/engines/titanic/star_control/unmarked_auto_mover.cpp +++ b/engines/titanic/star_control/unmarked_auto_mover.cpp @@ -27,8 +27,8 @@ namespace Titanic { -void CUnmarkedAutoMover::proc3(const FMatrix &srcOrient, const FMatrix &destOrient) { - CCameraAutoMover::proc3(srcOrient, destOrient); +void CUnmarkedAutoMover::setOrientations(const FMatrix &srcOrient, const FMatrix &destOrient) { + CCameraAutoMover::setOrientations(srcOrient, destOrient); _orientationChanger.load(srcOrient, destOrient); _transitionPercentInc = 0.1; _transitionPercent = 0.0; @@ -75,11 +75,11 @@ void CUnmarkedAutoMover::setPath(const FVector &srcV, const FVector &destV, cons } } -int CUnmarkedAutoMover::proc5(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) { +MoverState CUnmarkedAutoMover::move(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) { FVector v1, v2, v3, v4; if (!_active) - return 0; + return NOT_ACTIVE; // Firstly we have to do a transition of the camera orientation from // it's current position to one where the destination star is centered @@ -87,13 +87,13 @@ int CUnmarkedAutoMover::proc5(CErrorCode &errorCode, FVector &pos, FMatrix &orie _transitionPercent += _transitionPercentInc; orientation = _orientationChanger.getOrientation(_transitionPercent); errorCode.set(); - return 1; + return MOVING; } // From here on, we handle the movement to the given destination if (!_field34) { _active = false; - return 2; + return DONE_MOVING; } v2 = orientation._row3; @@ -133,7 +133,7 @@ int CUnmarkedAutoMover::proc5(CErrorCode &errorCode, FVector &pos, FMatrix &orie --_field40; errorCode.set(); - return 1; + return MOVING; } if (_field44 > 0) { @@ -145,7 +145,7 @@ int CUnmarkedAutoMover::proc5(CErrorCode &errorCode, FVector &pos, FMatrix &orie --_field44; errorCode.set(); - return 1; + return MOVING; } if (_field48 >= 0) { @@ -159,11 +159,11 @@ int CUnmarkedAutoMover::proc5(CErrorCode &errorCode, FVector &pos, FMatrix &orie --_field48; errorCode.set(); - return 1; + return MOVING; } _active = false; - return 2; + return DONE_MOVING; } } // End of namespace Titanic diff --git a/engines/titanic/star_control/unmarked_auto_mover.h b/engines/titanic/star_control/unmarked_auto_mover.h index fa1aa95140..b7fb4e3c66 100644 --- a/engines/titanic/star_control/unmarked_auto_mover.h +++ b/engines/titanic/star_control/unmarked_auto_mover.h @@ -34,14 +34,14 @@ class CUnmarkedAutoMover : public CCameraAutoMover { public: virtual ~CUnmarkedAutoMover() {} - virtual void proc3(const FMatrix &srcOrient, const FMatrix &destOrient); + virtual void setOrientations(const FMatrix &srcOrient, const FMatrix &destOrient); /** * Sets the path to animate movement between */ virtual void setPath(const FVector &srcV, const FVector &destV, const FMatrix &orientation); - virtual int proc5(CErrorCode &errorCode, FVector &pos, FMatrix &orientation); + virtual MoverState move(CErrorCode &errorCode, FVector &pos, FMatrix &orientation); }; } // End of namespace Titanic diff --git a/engines/titanic/star_control/unmarked_camera_mover.cpp b/engines/titanic/star_control/unmarked_camera_mover.cpp index bba49e925b..c1459ec372 100644 --- a/engines/titanic/star_control/unmarked_camera_mover.cpp +++ b/engines/titanic/star_control/unmarked_camera_mover.cpp @@ -26,6 +26,7 @@ #include "titanic/star_control/dvector.h" #include "titanic/star_control/daffine.h" #include "titanic/star_control/error_code.h" +#include "titanic/star_control/fmatrix.h" // includes class FVector #include "titanic/titanic.h" // Not currently being used: #include "common/textconsole.h" @@ -44,26 +45,27 @@ void CUnmarkedCameraMover::moveTo(const FVector &srcV, const FVector &destV, con _autoMover.setPath(srcV, destV, orientation); } -void CUnmarkedCameraMover::proc10(const FVector &v1, const FVector &v2, const FVector &v3, const FMatrix &m) { +// TODO: v3 is unused +void CUnmarkedCameraMover::transitionBetweenOrientations(const FVector &v1, const FVector &v2, const FVector &v3, const FMatrix &m) { if (isLocked()) decLockCount(); - //TODO: v3 is unused + DVector vector1 = v1; DVector vector2 = v2; DAffine matrix1 = vector2.getFrameTransform(vector1); DAffine matrix2 = matrix1.compose(m); - _autoMover.proc3(m, matrix2); + _autoMover.setOrientations(m, matrix2); incLockCount(); } void CUnmarkedCameraMover::updatePosition(CErrorCode &errorCode, FVector &pos, FMatrix &orientation) { if (_autoMover.isActive()) { decLockCount(); - int val = _autoMover.proc5(errorCode, pos, orientation); - if (val == 1) + MoverState moverState = _autoMover.move(errorCode, pos, orientation); + if (moverState == MOVING) incLockCount(); - if (val == 2) { + if (moverState == DONE_MOVING) { stop(); if (_starVector) _starVector->apply(); diff --git a/engines/titanic/star_control/unmarked_camera_mover.h b/engines/titanic/star_control/unmarked_camera_mover.h index bcf904684f..cb606b96dd 100644 --- a/engines/titanic/star_control/unmarked_camera_mover.h +++ b/engines/titanic/star_control/unmarked_camera_mover.h @@ -28,6 +28,9 @@ namespace Titanic { +class FMatrix; +class FVector; + class CUnmarkedCameraMover : public CCameraMover { private: CUnmarkedAutoMover _autoMover; @@ -40,7 +43,7 @@ public: */ virtual void moveTo(const FVector &srcV, const FVector &destV, const FMatrix &orientation); - virtual void proc10(const FVector &v1, const FVector &v2, const FVector &v3, const FMatrix &m); + virtual void transitionBetweenOrientations(const FVector &v1, const FVector &v2, const FVector &v3, const FMatrix &m); /** * Update the passed position and orientation matrix |