fiddling with collision detection

This commit is contained in:
darkrose 2015-07-02 00:41:55 +10:00
parent e7d8d22dc6
commit 11fd2a7d34
2 changed files with 77 additions and 90 deletions

View File

@ -237,10 +237,9 @@ collisionMoveResult collisionMoveSimple(Map *map,
s16 max_y = MYMAX(oldpos_i.Y, newpos_i.Y) + (box_0.MaxEdge.Y / BS) + 1;
s16 max_z = MYMAX(oldpos_i.Z, newpos_i.Z) + (box_0.MaxEdge.Z / BS) + 1;
for(s16 x = min_x; x <= max_x; x++)
for(s16 y = min_y; y <= max_y; y++)
for(s16 z = min_z; z <= max_z; z++)
{
for (s16 x = min_x; x <= max_x; x++) {
for (s16 y = min_y; y <= max_y; y++) {
for (s16 z = min_z; z <= max_z; z++) {
v3s16 p(x,y,z);
bool pos_ok;
// Object collides into walkable nodes
@ -337,6 +336,8 @@ collisionMoveResult collisionMoveSimple(Map *map,
nodeboxes.clear();
}
}
}
}
} // tt2
assert(cboxes.size() == is_unloaded.size());
@ -353,23 +354,19 @@ collisionMoveResult collisionMoveSimple(Map *map,
Make it a bit larger than the maximum distance of movement
*/
f32 d = pos_max_d * 1.1;
// A fairly large value in here makes moving smoother
//f32 d = 0.15*BS;
// This should always apply, otherwise there are glitches
assert(d > pos_max_d);
int loopcount = 0;
while(dtime > BS*1e-10)
{
while (dtime > BS*1e-10) {
//TimeTaker tt3("collisionMoveSimple dtime loop");
ScopeProfiler sp(g_profiler, "collisionMoveSimple dtime loop avg", SPT_AVG);
// Avoid infinite loop
loopcount++;
if(loopcount >= 100)
{
if (loopcount >= 100) {
infostream<<"collisionMoveSimple: WARNING: Loop count exceeded, aborting to avoid infiniite loop"<<std::endl;
dtime = 0;
break;
@ -386,8 +383,7 @@ collisionMoveResult collisionMoveSimple(Map *map,
/*
Go through every nodebox, find nearest collision
*/
for(u32 boxindex = 0; boxindex < cboxes.size(); boxindex++)
{
for (u32 boxindex = 0; boxindex < cboxes.size(); boxindex++) {
// Ignore if already stepped up this nodebox.
if (is_step_up[boxindex])
continue;
@ -395,7 +391,12 @@ collisionMoveResult collisionMoveSimple(Map *map,
// Find nearest collision of the two boxes (raytracing-like)
f32 dtime_tmp;
int collided = axisAlignedCollision(
cboxes[boxindex], movingbox, speed_f, d, dtime_tmp);
cboxes[boxindex],
movingbox,
speed_f,
d,
dtime_tmp
);
if (collided == -1 || dtime_tmp >= nearest_dtime)
continue;
@ -405,14 +406,11 @@ collisionMoveResult collisionMoveSimple(Map *map,
nearest_boxindex = boxindex;
}
if(nearest_collided == -1)
{
if (nearest_collided == -1) {
// No collision with any collision box.
pos_f += speed_f * dtime;
dtime = 0; // Set to 0 to avoid "infinite" loop due to small FP numbers
}
else
{
}else{
// Otherwise, a collision occurred.
const aabb3f& cbox = cboxes[nearest_boxindex];
@ -426,11 +424,9 @@ collisionMoveResult collisionMoveSimple(Map *map,
d));
// Move to the point of collision and reduce dtime by nearest_dtime
if(nearest_dtime < 0)
{
if (nearest_dtime < 0) {
// Handle negative nearest_dtime (can be caused by the d allowance)
if(!step_up)
{
if (!step_up) {
if (nearest_collided == 0)
pos_f.X += speed_f.X * nearest_dtime;
if (nearest_collided == 1)
@ -438,9 +434,7 @@ collisionMoveResult collisionMoveSimple(Map *map,
if (nearest_collided == 2)
pos_f.Z += speed_f.Z * nearest_dtime;
}
}
else
{
}else{
pos_f += speed_f * nearest_dtime;
dtime -= nearest_dtime;
}
@ -454,35 +448,31 @@ collisionMoveResult collisionMoveSimple(Map *map,
info.old_speed = speed_f;
// Set the speed component that caused the collision to zero
if(step_up)
{
if (step_up) {
// Special case: Handle stairs
is_step_up[nearest_boxindex] = true;
is_collision = false;
}
else if(nearest_collided == 0) // X
{
}else{
switch (nearest_collided) {
case 0:
speed_f.X = 0;
result.collides = true;
result.collides_xz = true;
}
else if(nearest_collided == 1) // Y
{
break;
case 1:
speed_f.Y = 0;
result.collides = true;
}
else if(nearest_collided == 2) // Z
{
break;
case 2:
speed_f.Z = 0;
result.collides = true;
result.collides_xz = true;
break;
default:;
}
info.new_speed = speed_f;
if(info.new_speed.getDistanceFrom(info.old_speed) < 0.1*BS)
is_collision = false;
if(is_collision){
if (is_collision && info.new_speed.getDistanceFrom(info.old_speed) >= 0.1*BS)
result.collisions.push_back(info);
}
}
@ -494,8 +484,7 @@ collisionMoveResult collisionMoveSimple(Map *map,
aabb3f box = box_0;
box.MinEdge += pos_f;
box.MaxEdge += pos_f;
for(u32 boxindex = 0; boxindex < cboxes.size(); boxindex++)
{
for (u32 boxindex = 0; boxindex < cboxes.size(); boxindex++) {
const aabb3f& cbox = cboxes[boxindex];
/*
@ -513,15 +502,13 @@ collisionMoveResult collisionMoveSimple(Map *map,
cbox.MaxEdge.Z-d > box.MinEdge.Z &&
cbox.MinEdge.Z+d < box.MaxEdge.Z
) {
if(is_step_up[boxindex])
{
if (is_step_up[boxindex]) {
pos_f.Y += (cbox.MaxEdge.Y - box.MinEdge.Y);
box = box_0;
box.MinEdge += pos_f;
box.MaxEdge += pos_f;
}
if(fabs(cbox.MaxEdge.Y-box.MinEdge.Y) < 0.15*BS)
{
if (fabs(cbox.MaxEdge.Y-box.MinEdge.Y) < 0.15*BS) {
result.touching_ground = true;
if (is_unloaded[boxindex])
result.standing_on_unloaded = true;

View File

@ -3405,7 +3405,7 @@ void ClientEnvironment::step(float dtime)
//f32 tolerance = BS*10; // 2 without damage
f32 tolerance = BS*12; // 3 without damage
f32 factor = 1;
if (info.speed > tolerance/2.0)
if (info.speed > BS*4)
m_client->playStepSound(0);
if (info.speed > tolerance) {
f32 damage_f = (info.speed - tolerance)/BS*factor;