mirror of
https://github.com/luanti-org/luanti.git
synced 2025-08-11 17:51:04 +00:00
implemented rats in new system to verify that it works
This commit is contained in:
parent
08bbf96877
commit
5a4d8ffad3
14 changed files with 974 additions and 85 deletions
184
src/collision.cpp
Normal file
184
src/collision.cpp
Normal file
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
Minetest-c55
|
||||
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "collision.h"
|
||||
#include "mapblock.h"
|
||||
#include "map.h"
|
||||
|
||||
collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
|
||||
const core::aabbox3d<f32> &box_0,
|
||||
f32 dtime, v3f &pos_f, v3f &speed_f)
|
||||
{
|
||||
collisionMoveResult result;
|
||||
|
||||
v3f oldpos_f = pos_f;
|
||||
v3s16 oldpos_i = floatToInt(oldpos_f, BS);
|
||||
|
||||
/*
|
||||
Calculate new position
|
||||
*/
|
||||
pos_f += speed_f * dtime;
|
||||
|
||||
/*
|
||||
Collision detection
|
||||
*/
|
||||
|
||||
// position in nodes
|
||||
v3s16 pos_i = floatToInt(pos_f, BS);
|
||||
|
||||
/*
|
||||
Collision uncertainty radius
|
||||
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);
|
||||
|
||||
/*
|
||||
Calculate collision box
|
||||
*/
|
||||
core::aabbox3d<f32> box = box_0;
|
||||
box.MaxEdge += pos_f;
|
||||
box.MinEdge += pos_f;
|
||||
core::aabbox3d<f32> oldbox = box_0;
|
||||
oldbox.MaxEdge += oldpos_f;
|
||||
oldbox.MinEdge += oldpos_f;
|
||||
|
||||
/*
|
||||
If the object lies on a walkable node, this is set to true.
|
||||
*/
|
||||
result.touching_ground = false;
|
||||
|
||||
/*
|
||||
Go through every node around the object
|
||||
*/
|
||||
for(s16 y = oldpos_i.Y - 1; y <= oldpos_i.Y + 2; y++)
|
||||
for(s16 z = oldpos_i.Z - 1; z <= oldpos_i.Z + 1; z++)
|
||||
for(s16 x = oldpos_i.X - 1; x <= oldpos_i.X + 1; x++)
|
||||
{
|
||||
try{
|
||||
// Object collides into walkable nodes
|
||||
if(content_walkable(map->getNode(v3s16(x,y,z)).d) == false)
|
||||
continue;
|
||||
}
|
||||
catch(InvalidPositionException &e)
|
||||
{
|
||||
// Doing nothing here will block the object from
|
||||
// walking over map borders
|
||||
}
|
||||
|
||||
core::aabbox3d<f32> nodebox = getNodeBox(v3s16(x,y,z), BS);
|
||||
|
||||
/*
|
||||
See if the object is touching ground.
|
||||
|
||||
Object touches ground if object's minimum Y is near node's
|
||||
maximum Y and object's X-Z-area overlaps with the node's
|
||||
X-Z-area.
|
||||
|
||||
Use 0.15*BS so that it is easier to get on a node.
|
||||
*/
|
||||
if(
|
||||
//fabs(nodebox.MaxEdge.Y-box.MinEdge.Y) < d
|
||||
fabs(nodebox.MaxEdge.Y-box.MinEdge.Y) < 0.15*BS
|
||||
&& nodebox.MaxEdge.X-d > box.MinEdge.X
|
||||
&& nodebox.MinEdge.X+d < box.MaxEdge.X
|
||||
&& nodebox.MaxEdge.Z-d > box.MinEdge.Z
|
||||
&& nodebox.MinEdge.Z+d < box.MaxEdge.Z
|
||||
){
|
||||
result.touching_ground = true;
|
||||
}
|
||||
|
||||
// If object doesn't intersect with node, ignore node.
|
||||
if(box.intersectsWithBox(nodebox) == false)
|
||||
continue;
|
||||
|
||||
/*
|
||||
Go through every axis
|
||||
*/
|
||||
v3f dirs[3] = {
|
||||
v3f(0,0,1), // back-front
|
||||
v3f(0,1,0), // top-bottom
|
||||
v3f(1,0,0), // right-left
|
||||
};
|
||||
for(u16 i=0; i<3; i++)
|
||||
{
|
||||
/*
|
||||
Calculate values along the axis
|
||||
*/
|
||||
f32 nodemax = nodebox.MaxEdge.dotProduct(dirs[i]);
|
||||
f32 nodemin = nodebox.MinEdge.dotProduct(dirs[i]);
|
||||
f32 objectmax = box.MaxEdge.dotProduct(dirs[i]);
|
||||
f32 objectmin = box.MinEdge.dotProduct(dirs[i]);
|
||||
f32 objectmax_old = oldbox.MaxEdge.dotProduct(dirs[i]);
|
||||
f32 objectmin_old = oldbox.MinEdge.dotProduct(dirs[i]);
|
||||
|
||||
/*
|
||||
Check collision for the axis.
|
||||
Collision happens when object is going through a surface.
|
||||
*/
|
||||
bool negative_axis_collides =
|
||||
(nodemax > objectmin && nodemax <= objectmin_old + d
|
||||
&& speed_f.dotProduct(dirs[i]) < 0);
|
||||
bool positive_axis_collides =
|
||||
(nodemin < objectmax && nodemin >= objectmax_old - d
|
||||
&& speed_f.dotProduct(dirs[i]) > 0);
|
||||
bool main_axis_collides =
|
||||
negative_axis_collides || positive_axis_collides;
|
||||
|
||||
/*
|
||||
Check overlap of object and node in other axes
|
||||
*/
|
||||
bool other_axes_overlap = true;
|
||||
for(u16 j=0; j<3; j++)
|
||||
{
|
||||
if(j == i)
|
||||
continue;
|
||||
f32 nodemax = nodebox.MaxEdge.dotProduct(dirs[j]);
|
||||
f32 nodemin = nodebox.MinEdge.dotProduct(dirs[j]);
|
||||
f32 objectmax = box.MaxEdge.dotProduct(dirs[j]);
|
||||
f32 objectmin = box.MinEdge.dotProduct(dirs[j]);
|
||||
if(!(nodemax - d > objectmin && nodemin + d < objectmax))
|
||||
{
|
||||
other_axes_overlap = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
If this is a collision, revert the pos_f in the main
|
||||
direction.
|
||||
*/
|
||||
if(other_axes_overlap && main_axis_collides)
|
||||
{
|
||||
speed_f -= speed_f.dotProduct(dirs[i]) * dirs[i];
|
||||
pos_f -= pos_f.dotProduct(dirs[i]) * dirs[i];
|
||||
pos_f += oldpos_f.dotProduct(dirs[i]) * dirs[i];
|
||||
}
|
||||
|
||||
}
|
||||
} // xyz
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue