diff options
author | SmallJoker <SmallJoker@users.noreply.github.com> | 2018-08-05 22:28:41 +0200 |
---|---|---|
committer | Paramat <paramat@users.noreply.github.com> | 2018-08-05 21:28:41 +0100 |
commit | ee63b94f2c9e176f549c4446391e4c59f5a5be53 (patch) | |
tree | 767f643bf1849b521646ed0ca41c323efd384a7a /src/collision.cpp | |
parent | 88efebdf864baeb422cbe4d992a44ff7c99373fb (diff) | |
download | minetest-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.cpp | 22 |
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); } } |