diff options
author | Weblate <42@minetest.ru> | 2013-03-30 19:49:52 +0100 |
---|---|---|
committer | Weblate <42@minetest.ru> | 2013-03-30 19:49:52 +0100 |
commit | a0566270d9fa075afa36a7e3e68c690b1b23ba90 (patch) | |
tree | 6bc88127ee67b7bf4d6a2d6f9d0a9e5f997d1dd1 /src/collision.cpp | |
parent | 0d83bdc3aa9f1077836aacb833ac4ad9bbb9a4f4 (diff) | |
parent | 1aa50b13622c1e264044839ecdf0152670dae6ce (diff) | |
download | minetest-a0566270d9fa075afa36a7e3e68c690b1b23ba90.tar.gz minetest-a0566270d9fa075afa36a7e3e68c690b1b23ba90.tar.bz2 minetest-a0566270d9fa075afa36a7e3e68c690b1b23ba90.zip |
Merge remote branch 'origin/master'
Diffstat (limited to 'src/collision.cpp')
-rw-r--r-- | src/collision.cpp | 72 |
1 files changed, 70 insertions, 2 deletions
diff --git a/src/collision.cpp b/src/collision.cpp index 58517b779..806a3b720 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -23,7 +23,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "nodedef.h" #include "gamedef.h" #include "log.h" +#include "environment.h" +#include "serverobject.h" #include <vector> +#include <set> #include "util/timetaker.h" #include "main.h" // g_profiler #include "profiler.h" @@ -186,11 +189,12 @@ bool wouldCollideWithCeiling( } -collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef, +collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, f32 pos_max_d, const aabb3f &box_0, f32 stepheight, f32 dtime, v3f &pos_f, v3f &speed_f, v3f &accel_f) { + Map *map = &env->getMap(); //TimeTaker tt("collisionMoveSimple"); ScopeProfiler sp(g_profiler, "collisionMoveSimple avg", SPT_AVG); @@ -215,6 +219,7 @@ collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef, std::vector<aabb3f> cboxes; std::vector<bool> is_unloaded; std::vector<bool> is_step_up; + std::vector<bool> is_object; std::vector<int> bouncy_values; std::vector<v3s16> node_positions; { @@ -256,6 +261,7 @@ collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef, is_step_up.push_back(false); bouncy_values.push_back(n_bouncy_value); node_positions.push_back(p); + is_object.push_back(false); } } catch(InvalidPositionException &e) @@ -267,14 +273,72 @@ collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef, is_step_up.push_back(false); bouncy_values.push_back(0); node_positions.push_back(p); + is_object.push_back(false); } } } // tt2 + { + ScopeProfiler sp(g_profiler, "collisionMoveSimple objects avg", SPT_AVG); + //TimeTaker tt3("collisionMoveSimple collect object boxes"); + + /* add object boxes to cboxes */ + + + std::list<ActiveObject*> objects; +#ifndef SERVER + ClientEnvironment *c_env = dynamic_cast<ClientEnvironment*>(env); + if (c_env != 0) + { + f32 distance = speed_f.getLength(); + std::vector<DistanceSortedActiveObject> clientobjects; + c_env->getActiveObjects(pos_f,distance * 1.5,clientobjects); + for (int i=0; i < clientobjects.size(); i++) + { + objects.push_back((ActiveObject*)clientobjects[i].obj); + } + } + else +#endif + { + ServerEnvironment *s_env = dynamic_cast<ServerEnvironment*>(env); + if (s_env != 0) + { + f32 distance = speed_f.getLength(); + std::set<u16> s_objects = s_env->getObjectsInsideRadius(pos_f,distance * 1.5); + for (std::set<u16>::iterator iter = s_objects.begin(); iter != s_objects.end(); iter++) + { + ServerActiveObject *current = s_env->getActiveObject(*iter); + objects.push_back((ActiveObject*)current); + } + } + } + + for (std::list<ActiveObject*>::const_iterator iter = objects.begin();iter != objects.end(); ++iter) + { + ActiveObject *object = *iter; + + if (object != NULL) + { + aabb3f object_collisionbox; + if (object->getCollisionBox(&object_collisionbox)) + { + cboxes.push_back(object_collisionbox); + is_unloaded.push_back(false); + is_step_up.push_back(false); + bouncy_values.push_back(0); + node_positions.push_back(v3s16(0,0,0)); + is_object.push_back(true); + } + } + } + } //tt3 + assert(cboxes.size() == is_unloaded.size()); assert(cboxes.size() == is_step_up.size()); assert(cboxes.size() == bouncy_values.size()); assert(cboxes.size() == node_positions.size()); + assert(cboxes.size() == is_object.size()); /* Collision detection @@ -386,7 +450,11 @@ collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef, is_collision = false; CollisionInfo info; - info.type = COLLISION_NODE; + if (is_object[nearest_boxindex]) { + info.type = COLLISION_OBJECT; + } + else + info.type = COLLISION_NODE; info.node_p = node_positions[nearest_boxindex]; info.bouncy = bouncy; info.old_speed = speed_f; |