projects
/
oweals
/
minetest.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Mapgens: Rename m_emerge to prevent name collisions
[oweals/minetest.git]
/
src
/
collision.cpp
diff --git
a/src/collision.cpp
b/src/collision.cpp
index 806a3b7203278cdd43a821c869e8a5848672e622..9e0c85531cf4ced2cf987e17f4bcb9eca17e8d0a 100644
(file)
--- a/
src/collision.cpp
+++ b/
src/collision.cpp
@@
-31,6
+31,10
@@
with this program; if not, write to the Free Software Foundation, Inc.,
#include "main.h" // g_profiler
#include "profiler.h"
#include "main.h" // g_profiler
#include "profiler.h"
+// float error is 10 - 9.96875 = 0.03125
+//#define COLL_ZERO 0.032 // broken unit tests
+#define COLL_ZERO 0
+
// Helper function:
// Checks for collision of a moving aabbox with a static aabbox
// Returns -1 if no collision, 0 if X collision, 1 if Y collision, 2 if Z collision
// Helper function:
// Checks for collision of a moving aabbox with a static aabbox
// Returns -1 if no collision, 0 if X collision, 1 if Y collision, 2 if Z collision
@@
-41,9
+45,9
@@
int axisAlignedCollision(
{
//TimeTaker tt("axisAlignedCollision");
{
//TimeTaker tt("axisAlignedCollision");
- f32 xsize = (staticbox.MaxEdge.X - staticbox.MinEdge.X)
;
- f32 ysize = (staticbox.MaxEdge.Y - staticbox.MinEdge.Y);
- f32 zsize = (staticbox.MaxEdge.Z - staticbox.MinEdge.Z);
+ f32 xsize = (staticbox.MaxEdge.X - staticbox.MinEdge.X)
- COLL_ZERO; // reduce box size for solve collision stuck (flying sand)
+ f32 ysize = (staticbox.MaxEdge.Y - staticbox.MinEdge.Y);
// - COLL_ZERO; // Y - no sense for falling, but maybe try later
+ f32 zsize = (staticbox.MaxEdge.Z - staticbox.MinEdge.Z)
- COLL_ZERO
;
aabb3f relbox(
movingbox.MinEdge.X - staticbox.MinEdge.X,
aabb3f relbox(
movingbox.MinEdge.X - staticbox.MinEdge.X,
@@
-60,9
+64,9
@@
int axisAlignedCollision(
{
dtime = - relbox.MaxEdge.X / speed.X;
if((relbox.MinEdge.Y + speed.Y * dtime < ysize) &&
{
dtime = - relbox.MaxEdge.X / speed.X;
if((relbox.MinEdge.Y + speed.Y * dtime < ysize) &&
- (relbox.MaxEdge.Y + speed.Y * dtime >
0
) &&
+ (relbox.MaxEdge.Y + speed.Y * dtime >
COLL_ZERO
) &&
(relbox.MinEdge.Z + speed.Z * dtime < zsize) &&
(relbox.MinEdge.Z + speed.Z * dtime < zsize) &&
- (relbox.MaxEdge.Z + speed.Z * dtime >
0
))
+ (relbox.MaxEdge.Z + speed.Z * dtime >
COLL_ZERO
))
return 0;
}
else if(relbox.MinEdge.X > xsize)
return 0;
}
else if(relbox.MinEdge.X > xsize)
@@
-76,9
+80,9
@@
int axisAlignedCollision(
{
dtime = (xsize - relbox.MinEdge.X) / speed.X;
if((relbox.MinEdge.Y + speed.Y * dtime < ysize) &&
{
dtime = (xsize - relbox.MinEdge.X) / speed.X;
if((relbox.MinEdge.Y + speed.Y * dtime < ysize) &&
- (relbox.MaxEdge.Y + speed.Y * dtime >
0
) &&
+ (relbox.MaxEdge.Y + speed.Y * dtime >
COLL_ZERO
) &&
(relbox.MinEdge.Z + speed.Z * dtime < zsize) &&
(relbox.MinEdge.Z + speed.Z * dtime < zsize) &&
- (relbox.MaxEdge.Z + speed.Z * dtime >
0
))
+ (relbox.MaxEdge.Z + speed.Z * dtime >
COLL_ZERO
))
return 0;
}
else if(relbox.MaxEdge.X < 0)
return 0;
}
else if(relbox.MaxEdge.X < 0)
@@
-95,9
+99,9
@@
int axisAlignedCollision(
{
dtime = - relbox.MaxEdge.Y / speed.Y;
if((relbox.MinEdge.X + speed.X * dtime < xsize) &&
{
dtime = - relbox.MaxEdge.Y / speed.Y;
if((relbox.MinEdge.X + speed.X * dtime < xsize) &&
- (relbox.MaxEdge.X + speed.X * dtime >
0
) &&
+ (relbox.MaxEdge.X + speed.X * dtime >
COLL_ZERO
) &&
(relbox.MinEdge.Z + speed.Z * dtime < zsize) &&
(relbox.MinEdge.Z + speed.Z * dtime < zsize) &&
- (relbox.MaxEdge.Z + speed.Z * dtime >
0
))
+ (relbox.MaxEdge.Z + speed.Z * dtime >
COLL_ZERO
))
return 1;
}
else if(relbox.MinEdge.Y > ysize)
return 1;
}
else if(relbox.MinEdge.Y > ysize)
@@
-111,9
+115,9
@@
int axisAlignedCollision(
{
dtime = (ysize - relbox.MinEdge.Y) / speed.Y;
if((relbox.MinEdge.X + speed.X * dtime < xsize) &&
{
dtime = (ysize - relbox.MinEdge.Y) / speed.Y;
if((relbox.MinEdge.X + speed.X * dtime < xsize) &&
- (relbox.MaxEdge.X + speed.X * dtime >
0
) &&
+ (relbox.MaxEdge.X + speed.X * dtime >
COLL_ZERO
) &&
(relbox.MinEdge.Z + speed.Z * dtime < zsize) &&
(relbox.MinEdge.Z + speed.Z * dtime < zsize) &&
- (relbox.MaxEdge.Z + speed.Z * dtime >
0
))
+ (relbox.MaxEdge.Z + speed.Z * dtime >
COLL_ZERO
))
return 1;
}
else if(relbox.MaxEdge.Y < 0)
return 1;
}
else if(relbox.MaxEdge.Y < 0)
@@
-130,9
+134,9
@@
int axisAlignedCollision(
{
dtime = - relbox.MaxEdge.Z / speed.Z;
if((relbox.MinEdge.X + speed.X * dtime < xsize) &&
{
dtime = - relbox.MaxEdge.Z / speed.Z;
if((relbox.MinEdge.X + speed.X * dtime < xsize) &&
- (relbox.MaxEdge.X + speed.X * dtime >
0
) &&
+ (relbox.MaxEdge.X + speed.X * dtime >
COLL_ZERO
) &&
(relbox.MinEdge.Y + speed.Y * dtime < ysize) &&
(relbox.MinEdge.Y + speed.Y * dtime < ysize) &&
- (relbox.MaxEdge.Y + speed.Y * dtime >
0
))
+ (relbox.MaxEdge.Y + speed.Y * dtime >
COLL_ZERO
))
return 2;
}
//else if(relbox.MinEdge.Z > zsize)
return 2;
}
//else if(relbox.MinEdge.Z > zsize)
@@
-146,9
+150,9
@@
int axisAlignedCollision(
{
dtime = (zsize - relbox.MinEdge.Z) / speed.Z;
if((relbox.MinEdge.X + speed.X * dtime < xsize) &&
{
dtime = (zsize - relbox.MinEdge.Z) / speed.Z;
if((relbox.MinEdge.X + speed.X * dtime < xsize) &&
- (relbox.MaxEdge.X + speed.X * dtime >
0
) &&
+ (relbox.MaxEdge.X + speed.X * dtime >
COLL_ZERO
) &&
(relbox.MinEdge.Y + speed.Y * dtime < ysize) &&
(relbox.MinEdge.Y + speed.Y * dtime < ysize) &&
- (relbox.MaxEdge.Y + speed.Y * dtime >
0
))
+ (relbox.MaxEdge.Y + speed.Y * dtime >
COLL_ZERO
))
return 2;
}
//else if(relbox.MaxEdge.Z < 0)
return 2;
}
//else if(relbox.MaxEdge.Z < 0)
@@
-192,7
+196,9
@@
bool wouldCollideWithCeiling(
collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
f32 pos_max_d, const aabb3f &box_0,
f32 stepheight, f32 dtime,
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)
+ v3f &pos_f, v3f &speed_f,
+ v3f &accel_f,ActiveObject* self,
+ bool collideWithObjects)
{
Map *map = &env->getMap();
//TimeTaker tt("collisionMoveSimple");
{
Map *map = &env->getMap();
//TimeTaker tt("collisionMoveSimple");
@@
-209,10
+215,15
@@
collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
}
speed_f += accel_f * dtime;
}
speed_f += accel_f * dtime;
- // If there is no speed, there are no collisions
+
// If there is no speed, there are no collisions
if(speed_f.getLength() == 0)
return result;
if(speed_f.getLength() == 0)
return result;
+ // Limit speed for avoiding hangs
+ speed_f.Y=rangelim(speed_f.Y,-5000,5000);
+ speed_f.X=rangelim(speed_f.X,-5000,5000);
+ speed_f.Z=rangelim(speed_f.Z,-5000,5000);
+
/*
Collect node boxes in movement range
*/
/*
Collect node boxes in movement range
*/
@@
-240,15
+251,19
@@
collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
for(s16 z = min_z; z <= max_z; z++)
{
v3s16 p(x,y,z);
for(s16 z = min_z; z <= max_z; z++)
{
v3s16 p(x,y,z);
- try{
+
+ bool is_position_valid;
+ MapNode n = map->getNodeNoEx(p, &is_position_valid);
+
+ if (is_position_valid) {
// Object collides into walkable nodes
// Object collides into walkable nodes
- MapNode n = map->getNode(p);
+
const ContentFeatures &f = gamedef->getNodeDefManager()->get(n);
if(f.walkable == false)
continue;
int n_bouncy_value = itemgroup_get(f.groups, "bouncy");
const ContentFeatures &f = gamedef->getNodeDefManager()->get(n);
if(f.walkable == false)
continue;
int n_bouncy_value = itemgroup_get(f.groups, "bouncy");
- std::vector<aabb3f> nodeboxes = n.get
Node
Boxes(gamedef->ndef());
+ std::vector<aabb3f> nodeboxes = n.get
Collision
Boxes(gamedef->ndef());
for(std::vector<aabb3f>::iterator
i = nodeboxes.begin();
i != nodeboxes.end(); i++)
for(std::vector<aabb3f>::iterator
i = nodeboxes.begin();
i != nodeboxes.end(); i++)
@@
-264,8
+279,7
@@
collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
is_object.push_back(false);
}
}
is_object.push_back(false);
}
}
- catch(InvalidPositionException &e)
- {
+ else {
// Collide with unloaded nodes
aabb3f box = getNodeBox(p, BS);
cboxes.push_back(box);
// Collide with unloaded nodes
aabb3f box = getNodeBox(p, BS);
cboxes.push_back(box);
@@
-278,6
+292,7
@@
collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
}
} // tt2
}
} // tt2
+ if(collideWithObjects)
{
ScopeProfiler sp(g_profiler, "collisionMoveSimple objects avg", SPT_AVG);
//TimeTaker tt3("collisionMoveSimple collect object boxes");
{
ScopeProfiler sp(g_profiler, "collisionMoveSimple objects avg", SPT_AVG);
//TimeTaker tt3("collisionMoveSimple collect object boxes");
@@
-293,9
+308,11
@@
collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
f32 distance = speed_f.getLength();
std::vector<DistanceSortedActiveObject> clientobjects;
c_env->getActiveObjects(pos_f,distance * 1.5,clientobjects);
f32 distance = speed_f.getLength();
std::vector<DistanceSortedActiveObject> clientobjects;
c_env->getActiveObjects(pos_f,distance * 1.5,clientobjects);
- for (
in
t i=0; i < clientobjects.size(); i++)
+ for (
size_
t i=0; i < clientobjects.size(); i++)
{
{
- objects.push_back((ActiveObject*)clientobjects[i].obj);
+ if ((self == 0) || (self != clientobjects[i].obj)) {
+ objects.push_back((ActiveObject*)clientobjects[i].obj);
+ }
}
}
else
}
}
else
@@
-309,7
+326,9
@@
collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
for (std::set<u16>::iterator iter = s_objects.begin(); iter != s_objects.end(); iter++)
{
ServerActiveObject *current = s_env->getActiveObject(*iter);
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);
+ if ((self == 0) || (self != current)) {
+ objects.push_back((ActiveObject*)current);
+ }
}
}
}
}
}
}
@@
-321,7
+340,8
@@
collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
if (object != NULL)
{
aabb3f object_collisionbox;
if (object != NULL)
{
aabb3f object_collisionbox;
- if (object->getCollisionBox(&object_collisionbox))
+ if (object->getCollisionBox(&object_collisionbox) &&
+ object->collideWithObjects())
{
cboxes.push_back(object_collisionbox);
is_unloaded.push_back(false);
{
cboxes.push_back(object_collisionbox);
is_unloaded.push_back(false);
@@
-453,8
+473,9
@@
collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
if (is_object[nearest_boxindex]) {
info.type = COLLISION_OBJECT;
}
if (is_object[nearest_boxindex]) {
info.type = COLLISION_OBJECT;
}
- else
+ else
{
info.type = COLLISION_NODE;
info.type = COLLISION_NODE;
+ }
info.node_p = node_positions[nearest_boxindex];
info.bouncy = bouncy;
info.old_speed = speed_f;
info.node_p = node_positions[nearest_boxindex];
info.bouncy = bouncy;
info.old_speed = speed_f;