[Scummvm-git-logs] scummvm master -> 4af3e8ee79508a2e74d49f73da4e5b07d0c0e4c0
neuromancer
noreply at scummvm.org
Sun Nov 13 23:07:20 UTC 2022
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
4af3e8ee79 FREESCAPE: check collision now executes the conditions in each object collided, instead of the smaller one
Commit: 4af3e8ee79508a2e74d49f73da4e5b07d0c0e4c0
https://github.com/scummvm/scummvm/commit/4af3e8ee79508a2e74d49f73da4e5b07d0c0e4c0
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2022-11-14T00:06:31+01:00
Commit Message:
FREESCAPE: check collision now executes the conditions in each object collided, instead of the smaller one
Changed paths:
engines/freescape/area.cpp
engines/freescape/area.h
engines/freescape/games/driller.cpp
engines/freescape/movement.cpp
diff --git a/engines/freescape/area.cpp b/engines/freescape/area.cpp
index 100db3d1320..6642e68b129 100644
--- a/engines/freescape/area.cpp
+++ b/engines/freescape/area.cpp
@@ -178,16 +178,13 @@ Object *Area::shootRay(const Math::Ray &ray) {
return collided;
}
-Object *Area::checkCollisions(const Math::AABB &boundingBox) {
- float size = 3.0 * 8192.0 * 8192.0; // TODO: check if this is max size
- Object *collided = nullptr;
+ObjectArray Area::checkCollisions(const Math::AABB &boundingBox) {
+ ObjectArray collided;
for (auto &obj : _drawableObjects) {
if (!obj->isDestroyed() && !obj->isInvisible()) {
GeometricObject *gobj = (GeometricObject *)obj;
- float objSize = gobj->getSize().length();
- if (gobj->collides(boundingBox) && size > objSize) {
- collided = gobj;
- size = objSize;
+ if (gobj->collides(boundingBox)) {
+ collided.push_back(gobj);
}
}
}
diff --git a/engines/freescape/area.h b/engines/freescape/area.h
index 3053736bb45..d4af67b095d 100644
--- a/engines/freescape/area.h
+++ b/engines/freescape/area.h
@@ -34,7 +34,7 @@
namespace Freescape {
typedef Common::HashMap<uint16, Object *> ObjectMap;
-
+typedef Common::Array<Object *> ObjectArray;
class Area {
public:
Area(uint16 areaID, uint16 areaFlags, ObjectMap *objectsByID, ObjectMap *entrancesByID);
@@ -50,7 +50,7 @@ public:
void show();
Object *shootRay(const Math::Ray &ray);
- Object *checkCollisions(const Math::AABB &boundingBox);
+ ObjectArray checkCollisions(const Math::AABB &boundingBox);
void addObjectFromArea(int16 id, Area *global);
void addObject(Object *obj);
void addStructure(Area *global);
@@ -76,7 +76,7 @@ private:
uint16 _areaFlags;
ObjectMap *_objectsByID;
ObjectMap *_entrancesByID;
- Common::Array<Object *> _drawableObjects;
+ ObjectArray _drawableObjects;
ObjectMap _addedObjects;
Object *objectWithIDFromMap(ObjectMap *map, uint16 objectID);
};
diff --git a/engines/freescape/games/driller.cpp b/engines/freescape/games/driller.cpp
index 2c6ddb9e37b..194f806befe 100644
--- a/engines/freescape/games/driller.cpp
+++ b/engines/freescape/games/driller.cpp
@@ -551,7 +551,7 @@ bool DrillerEngine::checkDrill(const Math::Vector3d position) {
obj = (GeometricObject *)obj->duplicate();
obj->setOrigin(origin);
- if (_currentArea->checkCollisions(obj->_boundingBox))
+ if (!_currentArea->checkCollisions(obj->_boundingBox).empty())
return false;
// Undo offset
@@ -571,7 +571,7 @@ bool DrillerEngine::checkDrill(const Math::Vector3d position) {
origin.setValue(2, origin.z() + obj->getSize().z() / 5);
obj->setOrigin(origin);
- if (_currentArea->checkCollisions(obj->_boundingBox))
+ if (!_currentArea->checkCollisions(obj->_boundingBox).empty())
return false;
// Undo offset
@@ -589,7 +589,7 @@ bool DrillerEngine::checkDrill(const Math::Vector3d position) {
obj->setOrigin(origin);
assert(obj);
- if (_currentArea->checkCollisions(obj->_boundingBox))
+ if (!_currentArea->checkCollisions(obj->_boundingBox).empty())
return false;
delete obj;
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index 3753991e539..6338c4770f3 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -290,23 +290,34 @@ bool FreescapeEngine::checkCollisions(bool executeCode) {
return false;
Math::AABB boundingBox(_lastPosition, _lastPosition);
- Math::Vector3d v1(_position.x() - 1, _position.y() - _playerHeight, _position.z() - 1);
- Math::Vector3d v2(_position.x() + 1, _position.y() + 1, _position.z() + 1);
+ Math::Vector3d v1(_position.x() + 1, _position.y() + 1, _position.z() + 1);
+ Math::Vector3d v2(_position.x() - 1, _position.y() - _playerHeight, _position.z() - 1);
boundingBox.expand(v1);
boundingBox.expand(v2);
- Object *obj = _currentArea->checkCollisions(boundingBox);
+ ObjectArray objs = _currentArea->checkCollisions(boundingBox);
+ bool collided = !objs.empty();
- if (obj != nullptr) {
- debugC(1, kFreescapeDebugMove, "Collided with object id %d of size %f %f %f", obj->getObjectID(), obj->getSize().x(), obj->getSize().y(), obj->getSize().z());
- GeometricObject *gobj = (GeometricObject *)obj;
- if (!executeCode) // Avoid executing code
- return true;
+ // If we don't need to execute code, we can finish here
+ if (!executeCode) {
+ return collided;
+ }
+
+ // If we need to execute code, we need to make sure the bounding box touches the floor
+ // so we will expand it and re-run the collision checking
+ uint tolerance = 1;
+ Math::Vector3d v3(_position.x() - 1, _position.y() - _playerHeight - tolerance, _position.z() - 1);
+ boundingBox.expand(v3);
+ objs = _currentArea->checkCollisions(boundingBox);
+ for (auto &obj : objs) {
+ GeometricObject *gobj = (GeometricObject *)obj;
+ debugC(1, kFreescapeDebugMove, "Collided with object id %d of size %f %f %f", gobj->getObjectID(), gobj->getSize().x(), gobj->getSize().y(), gobj->getSize().z());
executeObjectConditions(gobj, false, true);
- return true;
}
- return false;
+ // We still need to return the original result, not the collision using the expanded bounding box
+ // This will avoid detecting the floor constantly
+ return collided;
}
} // namespace Freescape
More information about the Scummvm-git-logs
mailing list