summaryrefslogtreecommitdiff
path: root/src/collision.cpp
diff options
context:
space:
mode:
authorSmallJoker <SmallJoker@users.noreply.github.com>2018-08-05 22:28:41 +0200
committerParamat <paramat@users.noreply.github.com>2018-08-05 21:28:41 +0100
commitee63b94f2c9e176f549c4446391e4c59f5a5be53 (patch)
tree767f643bf1849b521646ed0ca41c323efd384a7a /src/collision.cpp
parent88efebdf864baeb422cbe4d992a44ff7c99373fb (diff)
downloadminetest-ee63b94f2c9e176f549c4446391e4c59f5a5be53.tar.gz
minetest-ee63b94f2c9e176f549c4446391e4c59f5a5be53.tar.bz2
minetest-ee63b94f2c9e176f549c4446391e4c59f5a5be53.zip
Prevent objects from colliding with own child attachments (#7610)
Also, use a better distance calculation for 'collide with objects'. Fixes the issue of a vehicle occasionally colliding with its own driver, causing one of the velocity components to be set to zero.
Diffstat (limited to 'src/collision.cpp')
-rw-r--r--src/collision.cpp22
1 files changed, 16 insertions, 6 deletions
diff --git a/src/collision.cpp b/src/collision.cpp
index 99874dbfd..48a681dca 100644
--- a/src/collision.cpp
+++ b/src/collision.cpp
@@ -360,11 +360,16 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
#ifndef SERVER
ClientEnvironment *c_env = dynamic_cast<ClientEnvironment*>(env);
if (c_env != 0) {
- f32 distance = speed_f->getLength();
+ // Calculate distance by speed, add own extent and 1.5m of tolerance
+ f32 distance = speed_f->getLength() * dtime +
+ box_0.getExtent().getLength() + 1.5f * BS;
std::vector<DistanceSortedActiveObject> clientobjects;
- c_env->getActiveObjects(*pos_f, distance * 1.5f, clientobjects);
+ c_env->getActiveObjects(*pos_f, distance, clientobjects);
+
for (auto &clientobject : clientobjects) {
- if (!self || (self != clientobject.obj)) {
+ // Do collide with everything but itself and the parent CAO
+ if (!self || (self != clientobject.obj &&
+ self != clientobject.obj->getParent())) {
objects.push_back((ActiveObject*) clientobject.obj);
}
}
@@ -374,12 +379,17 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
{
ServerEnvironment *s_env = dynamic_cast<ServerEnvironment*>(env);
if (s_env != NULL) {
- f32 distance = speed_f->getLength();
+ // Calculate distance by speed, add own extent and 1.5m of tolerance
+ f32 distance = speed_f->getLength() * dtime +
+ box_0.getExtent().getLength() + 1.5f * BS;
std::vector<u16> s_objects;
- s_env->getObjectsInsideRadius(s_objects, *pos_f, distance * 1.5f);
+ s_env->getObjectsInsideRadius(s_objects, *pos_f, distance);
+
for (u16 obj_id : s_objects) {
ServerActiveObject *current = s_env->getActiveObject(obj_id);
- if (!self || (self != current)) {
+
+ if (!self || (self != current &&
+ self != current->getParent())) {
objects.push_back((ActiveObject*)current);
}
}