aboutsummaryrefslogtreecommitdiff
path: root/engines/titanic
diff options
context:
space:
mode:
Diffstat (limited to 'engines/titanic')
-rw-r--r--engines/titanic/star_control/camera_auto_mover.cpp13
-rw-r--r--engines/titanic/star_control/camera_auto_mover.h16
-rw-r--r--engines/titanic/star_control/camera_mover.cpp59
-rw-r--r--engines/titanic/star_control/camera_mover.h36
-rw-r--r--engines/titanic/star_control/daffine.cpp31
-rw-r--r--engines/titanic/star_control/dvector.cpp2
-rw-r--r--engines/titanic/star_control/dvector.h4
-rw-r--r--engines/titanic/star_control/marked_auto_mover.cpp16
-rw-r--r--engines/titanic/star_control/marked_auto_mover.h8
-rw-r--r--engines/titanic/star_control/marked_camera_mover.cpp12
-rw-r--r--engines/titanic/star_control/marked_camera_mover.h9
-rw-r--r--engines/titanic/star_control/matrix_inv.h189
-rw-r--r--engines/titanic/star_control/star_camera.cpp145
-rw-r--r--engines/titanic/star_control/star_camera.h10
-rw-r--r--engines/titanic/star_control/unmarked_auto_mover.cpp20
-rw-r--r--engines/titanic/star_control/unmarked_auto_mover.h4
-rw-r--r--engines/titanic/star_control/unmarked_camera_mover.cpp14
-rw-r--r--engines/titanic/star_control/unmarked_camera_mover.h5
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