1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-08-01 17:38:41 +00:00

Relatively snappy object-ground collision detection

This commit is contained in:
Perttu Ahola 2011-11-21 14:36:21 +02:00
parent 94feb62b08
commit 290e921920
9 changed files with 81 additions and 31 deletions

View file

@ -177,6 +177,7 @@ collisionMoveResult collisionMoveSimple(Map *map, IGameDef *gamedef,
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];
result.collides = true;
}
}
@ -232,6 +233,8 @@ collisionMoveResult collisionMovePrecise(Map *map, IGameDef *gamedef,
if(result.touching_ground)
final_result.touching_ground = true;
if(result.collides)
final_result.collides = true;
}
while(dtime_downcount > 0.001);

View file

@ -28,9 +28,11 @@ class IGameDef;
struct collisionMoveResult
{
bool touching_ground;
bool collides;
collisionMoveResult():
touching_ground(false)
touching_ground(false),
collides(false)
{}
};

View file

@ -1457,11 +1457,34 @@ void LuaEntityCAO::updateNodePos()
void LuaEntityCAO::step(float dtime, ClientEnvironment *env)
{
m_position += dtime * m_velocity + 0.5 * dtime * dtime * m_acceleration;
m_velocity += dtime * m_acceleration;
pos_translator.update(m_position, pos_translator.aim_is_end, pos_translator.anim_time);
pos_translator.translate(dtime);
updateNodePos();
if(m_prop->physical){
core::aabbox3d<f32> box = m_prop->collisionbox;
box.MinEdge *= BS;
box.MaxEdge *= BS;
collisionMoveResult moveresult;
f32 pos_max_d = BS*0.25; // Distance per iteration
v3f p_pos = m_position;
v3f p_velocity = m_velocity;
IGameDef *gamedef = env->getGameDef();
moveresult = collisionMovePrecise(&env->getMap(), gamedef,
pos_max_d, box, dtime, p_pos, p_velocity);
// Apply results
m_position = p_pos;
m_velocity = p_velocity;
bool is_end_position = moveresult.collides;
pos_translator.update(m_position, is_end_position, dtime);
pos_translator.translate(dtime);
updateNodePos();
m_velocity += dtime * m_acceleration;
} else {
m_position += dtime * m_velocity + 0.5 * dtime * dtime * m_acceleration;
m_velocity += dtime * m_acceleration;
pos_translator.update(m_position, pos_translator.aim_is_end, pos_translator.anim_time);
pos_translator.translate(dtime);
updateNodePos();
}
}
void LuaEntityCAO::processMessage(const std::string &data)
@ -1487,10 +1510,12 @@ void LuaEntityCAO::processMessage(const std::string &data)
// update_interval
float update_interval = readF1000(is);
if(do_interpolate)
pos_translator.update(m_position, is_end_position, update_interval);
else
if(do_interpolate){
if(!m_prop->physical)
pos_translator.update(m_position, is_end_position, update_interval);
} else {
pos_translator.init(m_position);
}
updateNodePos();
}
}

View file

@ -92,7 +92,7 @@ struct SmoothTranslator
if(anim_time > 0.001)
moveratio = anim_time_counter / anim_time;
// Move a bit less than should, to avoid oscillation
moveratio = moveratio * 0.5;
moveratio = moveratio * 0.8;
float move_end = 1.5;
if(aim_is_end)
move_end = 1.0;

View file

@ -1555,6 +1555,7 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos,
m_yaw(0),
m_last_sent_yaw(0),
m_last_sent_position(0,0,0),
m_last_sent_velocity(0,0,0),
m_last_sent_position_timer(0),
m_last_sent_move_precision(0)
{
@ -1612,8 +1613,27 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
{
m_last_sent_position_timer += dtime;
m_base_position += dtime * m_velocity + 0.5 * dtime * dtime * m_acceleration;
m_velocity += dtime * m_acceleration;
if(m_prop->physical){
core::aabbox3d<f32> box = m_prop->collisionbox;
box.MinEdge *= BS;
box.MaxEdge *= BS;
collisionMoveResult moveresult;
f32 pos_max_d = BS*0.25; // Distance per iteration
v3f p_pos = getBasePosition();
v3f p_velocity = m_velocity;
IGameDef *gamedef = m_env->getGameDef();
moveresult = collisionMovePrecise(&m_env->getMap(), gamedef,
pos_max_d, box, dtime, p_pos, p_velocity);
// Apply results
setBasePosition(p_pos);
m_velocity = p_velocity;
m_velocity += dtime * m_acceleration;
} else {
m_base_position += dtime * m_velocity + 0.5 * dtime
* dtime * m_acceleration;
m_velocity += dtime * m_acceleration;
}
if(m_registered){
lua_State *L = m_env->getLua();
@ -1623,7 +1643,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
if(send_recommended == false)
return;
// TODO: force send when velocity/acceleration changes enough
// TODO: force send when acceleration changes enough?
float minchange = 0.2*BS;
if(m_last_sent_position_timer > 1.0){
minchange = 0.01*BS;
@ -1632,7 +1652,9 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
}
float move_d = m_base_position.getDistanceFrom(m_last_sent_position);
move_d += m_last_sent_move_precision;
if(move_d > minchange || fabs(m_yaw - m_last_sent_yaw) > 1.0){
float vel_d = m_velocity.getDistanceFrom(m_last_sent_velocity);
if(move_d > minchange || vel_d > minchange ||
fabs(m_yaw - m_last_sent_yaw) > 1.0){
sendPosition(true, false);
}
}
@ -1675,6 +1697,7 @@ std::string LuaEntitySAO::getStaticData()
InventoryItem* LuaEntitySAO::createPickedUpItem()
{
// TODO: Ask item from scriptapi
std::istringstream is("CraftItem testobject1 1", std::ios_base::binary);
IGameDef *gamedef = m_env->getGameDef();
InventoryItem *item = InventoryItem::deSerialize(is, gamedef);
@ -1732,7 +1755,7 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
m_last_sent_position_timer = 0;
m_last_sent_yaw = m_yaw;
m_last_sent_position = m_base_position;
//m_last_sent_velocity = m_velocity;
m_last_sent_velocity = m_velocity;
//m_last_sent_acceleration = m_acceleration;
float update_interval = m_env->getSendRecommendedInterval();

View file

@ -231,6 +231,7 @@ private:
float m_yaw;
float m_last_sent_yaw;
v3f m_last_sent_position;
v3f m_last_sent_velocity;
float m_last_sent_position_timer;
float m_last_sent_move_precision;
};

View file

@ -362,14 +362,13 @@ public:
~ClientEnvironment();
Map & getMap()
{
return *m_map;
}
{ return *m_map; }
ClientMap & getClientMap()
{
return *m_map;
}
{ return *m_map; }
IGameDef *getGameDef()
{ return m_gamedef; }
void step(f32 dtime);

View file

@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
LuaEntityProperties::LuaEntityProperties():
physical(true),
physical(false),
weight(5),
collisionbox(-0.5,-0.5,-0.5, 0.5,0.5,0.5),
visual("single_sprite")