[Scummvm-git-logs] scummvm master -> 087e58ba48171a856544987ded99c5886ca8f048
neuromancer
noreply at scummvm.org
Sat Nov 18 16:32:20 UTC 2023
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
1df2cfddbe FREESCAPE: improved shooted object detection and moved sweepAABB implementation to its own file
087e58ba48 NEWS: updated with Freescape recent changes
Commit: 1df2cfddbe1ce1cb803632e39f8765265590c0d3
https://github.com/scummvm/scummvm/commit/1df2cfddbe1ce1cb803632e39f8765265590c0d3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-11-18T17:32:14+01:00
Commit Message:
FREESCAPE: improved shooted object detection and moved sweepAABB implementation to its own file
Changed paths:
A engines/freescape/sweepAABB.cpp
A engines/freescape/sweepAABB.h
engines/freescape/area.cpp
engines/freescape/module.mk
diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index c31451defa9..abcb8b25d5c 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -27,6 +27,7 @@
#include "freescape/freescape.h"
#include "freescape/area.h"
#include "freescape/objects/global.h"
+#include "freescape/sweepAABB.h"
namespace Freescape {
@@ -248,14 +249,21 @@ void Area::drawGroup(Freescape::Renderer *gfx, Group* group, bool runAnimation)
}
Object *Area::shootRay(const Math::Ray &ray) {
- float size = 16.0 * 8192.0; // TODO: check if this is max size
+ float distance = 16.0 * 8192.0; // TODO: check if this is max distance
+ float size = 16.0 * 8192.0; // TODO: check if this is the max size
+ Math::AABB boundingBox(ray.getOrigin(), ray.getOrigin());
Object *collided = nullptr;
for (auto &obj : _drawableObjects) {
- float objSize = obj->getSize().length();
- if (!obj->isDestroyed() && !obj->isInvisible() && obj->_boundingBox.isValid() && ray.intersectAABB(obj->_boundingBox) && size >= objSize) {
- debugC(1, kFreescapeDebugMove, "shot obj id: %d", obj->getObjectID());
- collided = obj;
- size = objSize;
+ if (!obj->isDestroyed() && !obj->isInvisible()) {
+ GeometricObject *gobj = (GeometricObject *)obj;
+ Math::Vector3d collidedNormal;
+ float collidedDistance = sweepAABB(boundingBox, gobj->_boundingBox, 8192 * ray.getDirection(), collidedNormal);
+ debug("shot obj id: %d with distance %f", obj->getObjectID(), collidedDistance);
+ if (collidedDistance < distance || (collidedDistance == distance && gobj->getSize().length() < size)) {
+ collided = obj;
+ size = gobj->getSize().length();
+ distance = collidedDistance;
+ }
}
}
return collided;
@@ -274,78 +282,6 @@ ObjectArray Area::checkCollisions(const Math::AABB &boundingBox) {
return collided;
}
-float lineToPlane(Math::Vector3d const &p, Math::Vector3d const &u, Math::Vector3d const &v, Math::Vector3d const &n) {
- float NdotU = n.dotProduct(u);
- if (NdotU == 0)
- return INFINITY;
-
- return n.dotProduct(v - p) / NdotU;
-}
-
-bool between(float x, float a, float b) {
- return x >= a && x <= b;
-}
-
-float sweepAABB(Math::AABB const &a, Math::AABB const &b, Math::Vector3d const &direction, Math::Vector3d &normal) {
- Math::Vector3d m = b.getMin() - a.getMax();
- Math::Vector3d mh = a.getSize() + b.getSize();
-
- float h = 1.0;
- float s = 0.0;
- Math::Vector3d zero;
-
- // X min
- s = lineToPlane(zero, direction, m, Math::Vector3d(-1, 0, 0));
- if (s >= 0 && direction.x() > 0 && s < h && between(s * direction.y(), m.y(), m.y()+mh.y()) && between(s * direction.z(), m.z(), m.z() + mh.z())) {
- h = s;
- normal = Math::Vector3d(-1, 0, 0);
- }
-
- // X max
- m.x() = m.x() + mh.x();
- s = lineToPlane(zero, direction, m, Math::Vector3d(1, 0, 0));
- if (s >= 0 && direction.x() < 0 && s < h && between(s * direction.y(), m.y(), m.y() + mh.y()) && between(s * direction.z(), m.z(), m.z() + mh.z())) {
- h = s;
- normal = Math::Vector3d(1, 0, 0);
- }
-
- m.x() = m.x() - mh.x();
- // Y min
- s = lineToPlane(zero, direction, m, Math::Vector3d(0, -1, 0));
- if (s >= 0 && direction.y() > 0 && s < h && between(s * direction.x(), m.x(), m.x() + mh.x()) && between(s * direction.z(), m.z(), m.z() + mh.z())) {
- h = s;
- normal = Math::Vector3d(0, -1, 0);
- }
-
- // Y max
- m.y() = m.y() + mh.y();
- s = lineToPlane(zero, direction, m, Math::Vector3d(0, 1, 0));
- if (s >= 0 && direction.y() < 0 && s < h && between(s * direction.x(), m.x(), m.x() + mh.x()) && between(s * direction.z(), m.z(), m.z() + mh.z())) {
- h = s;
- normal = Math::Vector3d(0, 1, 0);
- }
-
- m.y() = m.y() - mh.y();
-
- // Z min
- s = lineToPlane(zero, direction, m, Math::Vector3d(0, 0, -1));
- if (s >= 0 && direction.z() > 0 && s < h && between(s * direction.x(), m.x() , m.x() + mh.x()) && between(s * direction.y(), m.y(), m.y() + mh.y())) {
- h = s;
- normal = Math::Vector3d(0, 0, -1);
- }
-
- // Z max
- m.z() = m.z() + mh.z();
- s = lineToPlane(zero, direction, m, Math::Vector3d(0, 0, 1));
- if (s >= 0 && direction.z() < 0 && s < h && between(s * direction.x(), m.x(), m.x() + mh.x()) && between(s * direction.y(), m.y(), m.y() + mh.y())) {
- h = s;
- normal = Math::Vector3d(0, 0, 1);
- }
-
- //debug("%f", h);
- return h;
-}
-
extern Math::AABB createPlayerAABB(Math::Vector3d const position, int playerHeight);
Math::Vector3d Area::resolveCollisions(const Math::Vector3d &lastPosition_, const Math::Vector3d &newPosition_, int playerHeight) {
diff --git a/engines/freescape/module.mk b/engines/freescape/module.mk
index c1c7fa3bf49..d6fb3bb9e1e 100644
--- a/engines/freescape/module.mk
+++ b/engines/freescape/module.mk
@@ -35,6 +35,7 @@ MODULE_OBJS := \
objects/group.o \
objects/sensor.o \
scr.o \
+ sweepAABB.o \
sound.o \
ui.o
diff --git a/engines/freescape/sweepAABB.cpp b/engines/freescape/sweepAABB.cpp
new file mode 100644
index 00000000000..a28502d7ab7
--- /dev/null
+++ b/engines/freescape/sweepAABB.cpp
@@ -0,0 +1,102 @@
+/* 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "freescape/freescape.h"
+
+namespace Freescape {
+
+/*
+This code is inspired by the Luis Eduard Reis implementation:
+https://luisreis.net/blog/aabb_collision_handling/
+*/
+
+float lineToPlane(Math::Vector3d const &p, Math::Vector3d const &u, Math::Vector3d const &v, Math::Vector3d const &n) {
+ float NdotU = n.dotProduct(u);
+ if (NdotU == 0)
+ return INFINITY;
+
+ return n.dotProduct(v - p) / NdotU;
+}
+
+bool between(float x, float a, float b) {
+ return x >= a && x <= b;
+}
+
+float sweepAABB(Math::AABB const &a, Math::AABB const &b, Math::Vector3d const &direction, Math::Vector3d &normal) {
+ Math::Vector3d m = b.getMin() - a.getMax();
+ Math::Vector3d mh = a.getSize() + b.getSize();
+
+ float h = 1.0;
+ float s = 0.0;
+ Math::Vector3d zero;
+
+ // X min
+ s = lineToPlane(zero, direction, m, Math::Vector3d(-1, 0, 0));
+ if (s >= 0 && direction.x() > 0 && s < h && between(s * direction.y(), m.y(), m.y()+mh.y()) && between(s * direction.z(), m.z(), m.z() + mh.z())) {
+ h = s;
+ normal = Math::Vector3d(-1, 0, 0);
+ }
+
+ // X max
+ m.x() = m.x() + mh.x();
+ s = lineToPlane(zero, direction, m, Math::Vector3d(1, 0, 0));
+ if (s >= 0 && direction.x() < 0 && s < h && between(s * direction.y(), m.y(), m.y() + mh.y()) && between(s * direction.z(), m.z(), m.z() + mh.z())) {
+ h = s;
+ normal = Math::Vector3d(1, 0, 0);
+ }
+
+ // Y min
+ m.x() = m.x() - mh.x();
+ s = lineToPlane(zero, direction, m, Math::Vector3d(0, -1, 0));
+ if (s >= 0 && direction.y() > 0 && s < h && between(s * direction.x(), m.x(), m.x() + mh.x()) && between(s * direction.z(), m.z(), m.z() + mh.z())) {
+ h = s;
+ normal = Math::Vector3d(0, -1, 0);
+ }
+
+ // Y max
+ m.y() = m.y() + mh.y();
+ s = lineToPlane(zero, direction, m, Math::Vector3d(0, 1, 0));
+ if (s >= 0 && direction.y() < 0 && s < h && between(s * direction.x(), m.x(), m.x() + mh.x()) && between(s * direction.z(), m.z(), m.z() + mh.z())) {
+ h = s;
+ normal = Math::Vector3d(0, 1, 0);
+ }
+
+
+ // Z min
+ m.y() = m.y() - mh.y();
+ s = lineToPlane(zero, direction, m, Math::Vector3d(0, 0, -1));
+ if (s >= 0 && direction.z() > 0 && s < h && between(s * direction.x(), m.x() , m.x() + mh.x()) && between(s * direction.y(), m.y(), m.y() + mh.y())) {
+ h = s;
+ normal = Math::Vector3d(0, 0, -1);
+ }
+
+ // Z max
+ m.z() = m.z() + mh.z();
+ s = lineToPlane(zero, direction, m, Math::Vector3d(0, 0, 1));
+ if (s >= 0 && direction.z() < 0 && s < h && between(s * direction.x(), m.x(), m.x() + mh.x()) && between(s * direction.y(), m.y(), m.y() + mh.y())) {
+ h = s;
+ normal = Math::Vector3d(0, 0, 1);
+ }
+
+ return h;
+}
+
+}
\ No newline at end of file
diff --git a/engines/freescape/sweepAABB.h b/engines/freescape/sweepAABB.h
new file mode 100644
index 00000000000..71110740b6d
--- /dev/null
+++ b/engines/freescape/sweepAABB.h
@@ -0,0 +1,33 @@
+/* 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef FREESCAPE_SWEEPAABB_H
+#define FREESCAPE_SWEEPAABB_H
+
+namespace Freescape {
+
+extern float sweepAABB(Math::AABB const &a, Math::AABB const &b, Math::Vector3d const &direction, Math::Vector3d &normal);
+
+}
+
+// End of namespace Freescape
+
+#endif // FREESCAPE_SWEEPAABB_H
\ No newline at end of file
Commit: 087e58ba48171a856544987ded99c5886ca8f048
https://github.com/scummvm/scummvm/commit/087e58ba48171a856544987ded99c5886ca8f048
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-11-18T17:32:14+01:00
Commit Message:
NEWS: updated with Freescape recent changes
Changed paths:
NEWS.md
diff --git a/NEWS.md b/NEWS.md
index bffb4a51042..a68979aa188 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -40,6 +40,9 @@ For a more comprehensive changelog of the latest experimental code, see:
Dragons:
- Implemented localizations for the copyright screen and main menu.
+ Freescape:
+ - Improved collision and projectile detection using sweepAABB
+
GrimE:
- Added support for Chinese Grim Fandango.
- Added support for Russian Grim Fandango translations from Fargus,
More information about the Scummvm-git-logs
mailing list