diff --git a/engines/grim/actor.cpp b/engines/grim/actor.cpp index 6da4ed38fa4..f8c113c4054 100644 --- a/engines/grim/actor.cpp +++ b/engines/grim/actor.cpp @@ -1445,6 +1445,7 @@ bool Actor::collidesWith(Actor *actor, Math::Vector3d *vec) const { Math::Vector3d bboxPos; Math::Vector3d size; + float scale; Math::Vector3d pos; Math::Vector3d circlePos; Math::Angle yaw; @@ -1455,7 +1456,8 @@ bool Actor::collidesWith(Actor *actor, Math::Vector3d *vec) const { if (mode1 == CollisionBox) { pos = p1 + *vec; bboxPos = pos + model1->_bboxPos; - size = model1->_bboxSize * _collisionScale; + size = model1->_bboxSize; + scale = _collisionScale; yaw = _yaw; circle.setX(p2.x()); @@ -1465,7 +1467,8 @@ bool Actor::collidesWith(Actor *actor, Math::Vector3d *vec) const { } else { pos = p2; bboxPos = p2 + model2->_bboxPos; - size = model2->_bboxSize * actor->_collisionScale; + size = model2->_bboxSize; + scale = actor->_collisionScale; yaw = actor->_yaw; circle.setX(p1.x() + vec->x()); @@ -1478,6 +1481,8 @@ bool Actor::collidesWith(Actor *actor, Math::Vector3d *vec) const { rect._topRight = Math::Vector2d(bboxPos.x() + size.x(), bboxPos.y() + size.y()); rect._bottomLeft = Math::Vector2d(bboxPos.x(), bboxPos.y()); rect._bottomRight = Math::Vector2d(bboxPos.x() + size.x(), bboxPos.y()); + + rect.scale(scale); rect.rotateAround(Math::Vector2d(pos.x(), pos.y()), yaw); if (rect.intersectsCircle(circle, radius)) { diff --git a/engines/grim/model.cpp b/engines/grim/model.cpp index b1169ae8b25..3fc7112ac77 100644 --- a/engines/grim/model.cpp +++ b/engines/grim/model.cpp @@ -65,28 +65,23 @@ Model::Model(const Common::String &filename, const char *data, int len, CMap *cm ModelNode &node = _rootHierNode[i]; if (node._mesh) { Mesh &mesh = *node._mesh; - //NOTE: Setting p to mesh._matrix._pos seems more similar to original - // but, as in original, it also stops manny quite far away from the - // bone wagon when approaching it from behind in set sg. - // Using the node position looks instead more realistic, but, on the - // other hand, it may not work right in all cases. - Math::Vector3d p = node._matrix.getPosition(); + Math::Vector3d p = mesh._matrix.getPosition(); float x = p.x(); float y = p.y(); float z = p.z(); for (int k = 0; k < mesh._numVertices * 3; k += 3) { if (first || mesh._vertices[k] + x < _bboxPos.x()) _bboxPos.x() = mesh._vertices[k] + x; - if (mesh._vertices[k + 1] + y < _bboxPos.y()) + if (first || mesh._vertices[k + 1] + y < _bboxPos.y()) _bboxPos.y() = mesh._vertices[k + 1] + y; - if (mesh._vertices[k + 2] + z < _bboxPos.z()) + if (first || mesh._vertices[k + 2] + z < _bboxPos.z()) _bboxPos.z() = mesh._vertices[k + 2] + z; if (first || mesh._vertices[k] + x > max.x()) max.x() = mesh._vertices[k] + x; - if (mesh._vertices[k + 1] + y > max.y()) + if (first || mesh._vertices[k + 1] + y > max.y()) max.y() = mesh._vertices[k + 1] + y; - if (mesh._vertices[k + 2] + z > max.z()) + if (first || mesh._vertices[k + 2] + z > max.z()) max.z() = mesh._vertices[k + 2] + z; first = false; @@ -653,36 +648,40 @@ void ModelNode::removeChild(ModelNode *child) { void ModelNode::setMatrix(Math::Matrix4 matrix) { _matrix = matrix; + if (_sibling) + _sibling->setMatrix(matrix); } void ModelNode::update() { if (!_initialized) return; - Math::Vector3d animPos = _pos + _animPos; - Math::Angle animPitch = _pitch + _animPitch; - Math::Angle animYaw = _yaw + _animYaw; - Math::Angle animRoll = _roll + _animRoll; + if (_hierVisible) { + Math::Vector3d animPos = _pos + _animPos; + Math::Angle animPitch = _pitch + _animPitch; + Math::Angle animYaw = _yaw + _animYaw; + Math::Angle animRoll = _roll + _animRoll; - _localMatrix.setPosition(animPos); - _localMatrix.buildFromPitchYawRoll(animPitch, animYaw, animRoll); + _localMatrix.setPosition(animPos); + _localMatrix.buildFromPitchYawRoll(animPitch, animYaw, animRoll); - _matrix = _localMatrix * _matrix; + _matrix = _matrix * _localMatrix; - _pivotMatrix = _matrix; + _pivotMatrix = _matrix; + _pivotMatrix.translate(_pivot); - _pivotMatrix.translate(_pivot); + if (_mesh) { + _mesh->_matrix = _pivotMatrix; + } - if (_mesh) { - _mesh->_matrix = _pivotMatrix; + if (_child) { + _child->setMatrix(_matrix); + _child->update(); + } } - ModelNode *child = _child; - while (child) { - child->setMatrix(_matrix); - child->update(); - - child = child->_sibling; + if (_sibling) { + _sibling->update(); } } diff --git a/math/matrix4.cpp b/math/matrix4.cpp index 0b4571b677c..84767418820 100644 --- a/math/matrix4.cpp +++ b/math/matrix4.cpp @@ -49,22 +49,22 @@ void Matrix<4, 4>::transform(Vector3d *v, bool trans) const { } Vector3d Matrix<4, 4>::getPosition() const { - return Vector3d(getValue(3, 0), getValue(3, 1), getValue(3, 2)); + return Vector3d(getValue(0, 3), getValue(1, 3), getValue(2, 3)); } void Matrix<4, 4>::setPosition(const Vector3d &v) { - setValue(3, 0, v.x()); - setValue(3, 1, v.y()); - setValue(3, 2, v.z()); + setValue(0, 3, v.x()); + setValue(1, 3, v.y()); + setValue(2, 3, v.z()); } void Matrix<4, 4>::translate(const Vector3d &vec) { Vector3d v(vec); transform(&v, false); - operator()(3, 0) += v.x(); - operator()(3, 1) += v.y(); - operator()(3, 2) += v.z(); + operator()(0, 3) += v.x(); + operator()(1, 3) += v.y(); + operator()(2, 3) += v.z(); } } // end of namespace Math diff --git a/math/rect2d.cpp b/math/rect2d.cpp index 26db47fbe15..77985afad9b 100644 --- a/math/rect2d.cpp +++ b/math/rect2d.cpp @@ -64,6 +64,30 @@ void Rect2d::rotateAroundCenter(const Angle &angle) { rotateAround(center, angle); } +void Rect2d::moveCenterTo(const Vector2d &pos) { + Vector2d vec(pos - getCenter()); + translate(vec); +} + +void Rect2d::scale(float amount) { + Vector2d c = getCenter(); + moveCenterTo(Vector2d(0, 0)); + + _topLeft *= amount; + _topRight *= amount; + _bottomLeft *= amount; + _bottomRight *= amount; + + moveCenterTo(c); +} + +void Rect2d::translate(const Vector2d &vec) { + _topLeft += vec; + _topRight += vec; + _bottomLeft += vec; + _bottomRight += vec; +} + bool Rect2d::intersectsRect(const Rect2d &rect) const { // TODO: implement this; error("Rect2d::intersectsRect not implemented"); diff --git a/math/rect2d.h b/math/rect2d.h index b4f911a6c27..a9facdeeade 100644 --- a/math/rect2d.h +++ b/math/rect2d.h @@ -41,6 +41,9 @@ public: void rotateAround(const Vector2d &point, const Angle &angle); void rotateAroundCenter(const Angle &angle); + void moveCenterTo(const Vector2d &pos); + void scale(float amount); + void translate(const Vector2d &vec); bool intersectsRect(const Rect2d &rect) const; bool intersectsCircle(const Vector2d ¢er, float radius) const; bool containsPoint(const Vector2d &point) const; diff --git a/math/rotation3d.h b/math/rotation3d.h index 795965bd8e8..186c3bd44fa 100644 --- a/math/rotation3d.h +++ b/math/rotation3d.h @@ -72,9 +72,9 @@ void Rotation3D::buildFromPitchYawRoll(const Angle &pitch, const Angle &yaw, // at, around x-axis template -void Rotation3D::buildAroundRoll(const Angle &roll) { - float cosa = roll.getCosine(); - float sina = roll.getSine(); +void Rotation3D::buildAroundPitch(const Angle &pitch) { + float cosa = pitch.getCosine(); + float sina = pitch.getSine(); this->getMatrix().getRow(0) << 1.f << 0.f << 0.f; this->getMatrix().getRow(1) << 0.f << cosa << -sina; @@ -83,9 +83,9 @@ void Rotation3D::buildAroundRoll(const Angle &roll) { // right template -void Rotation3D::buildAroundPitch(const Angle &pitch) { - float cosa = pitch.getCosine(); - float sina = pitch.getSine(); +void Rotation3D::buildAroundRoll(const Angle &roll) { + float cosa = roll.getCosine(); + float sina = roll.getSine(); this->getMatrix().getRow(0) << cosa << 0.f << sina; this->getMatrix().getRow(1) << 0.f << 1.f << 0.f; @@ -111,15 +111,15 @@ void Rotation3D::getPitchYawRoll(Angle *pPitch, Angle *pYaw, Angle *pRoll) co this->getMatrix().getValue(0, 0)); } - if (pPitch) { + if (pRoll) { float a = this->getMatrix().getValue(2, 1); float b = this->getMatrix().getValue(2, 2); float mag = sqrt(a * a + b * b); - *pPitch = Angle::arcTangent2(-this->getMatrix().getValue(2, 0), mag); + *pRoll = Angle::arcTangent2(-this->getMatrix().getValue(2, 0), mag); } - if (pRoll) { - *pRoll = Angle::arcTangent2(this->getMatrix().getValue(2, 1), + if (pPitch) { + *pPitch = Angle::arcTangent2(this->getMatrix().getValue(2, 1), this->getMatrix().getValue(2, 2)); } } diff --git a/math/squarematrix.h b/math/squarematrix.h index 6c0d43f3443..a3cd8b4cc40 100644 --- a/math/squarematrix.h +++ b/math/squarematrix.h @@ -43,7 +43,7 @@ public: *vec = this->getThis() * *vec; } - Matrix operator=(float i); + Matrix &operator=(float i); protected: MatrixType() : MatrixBase() { setToIdentity(); } @@ -52,7 +52,7 @@ protected: }; template -Matrix MatrixType::operator=(float i) { +Matrix &MatrixType::operator=(float i) { for (int row = 0; row < dim; ++row) { for (int col = 0; col < dim; ++col) { this->setValue(row, col, (row == col ? i : 0.f));