GRIM: Fix bounding box calculation. Fix #391
This commit is contained in:
parent
611a4ff086
commit
46a8d461e0
7 changed files with 79 additions and 48 deletions
|
@ -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)) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -72,9 +72,9 @@ void Rotation3D<T>::buildFromPitchYawRoll(const Angle &pitch, const Angle &yaw,
|
|||
|
||||
// at, around x-axis
|
||||
template<class T>
|
||||
void Rotation3D<T>::buildAroundRoll(const Angle &roll) {
|
||||
float cosa = roll.getCosine();
|
||||
float sina = roll.getSine();
|
||||
void Rotation3D<T>::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<T>::buildAroundRoll(const Angle &roll) {
|
|||
|
||||
// right
|
||||
template<class T>
|
||||
void Rotation3D<T>::buildAroundPitch(const Angle &pitch) {
|
||||
float cosa = pitch.getCosine();
|
||||
float sina = pitch.getSine();
|
||||
void Rotation3D<T>::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<T>::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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
*vec = this->getThis() * *vec;
|
||||
}
|
||||
|
||||
Matrix<dim, dim> operator=(float i);
|
||||
Matrix<dim, dim> &operator=(float i);
|
||||
|
||||
protected:
|
||||
MatrixType() : MatrixBase<dim, dim>() { setToIdentity(); }
|
||||
|
@ -52,7 +52,7 @@ protected:
|
|||
};
|
||||
|
||||
template<int dim>
|
||||
Matrix<dim, dim> MatrixType<dim, dim>::operator=(float i) {
|
||||
Matrix<dim, dim> &MatrixType<dim, dim>::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));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue