summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2011-11-21 14:36:21 +0200
committerPerttu Ahola <celeron55@gmail.com>2011-11-29 19:13:50 +0200
commit290e9219208fd904807bded7ccdb7109a4f92bc6 (patch)
tree1bad6c56620e007c4177284e42386e4b0cea8b8f
parent94feb62b087d61d0c211645970a36e6752d1c732 (diff)
downloadminetest-290e9219208fd904807bded7ccdb7109a4f92bc6.tar.gz
minetest-290e9219208fd904807bded7ccdb7109a4f92bc6.tar.bz2
minetest-290e9219208fd904807bded7ccdb7109a4f92bc6.zip
Relatively snappy object-ground collision detection
-rw-r--r--data/mods/default/init.lua15
-rw-r--r--src/collision.cpp3
-rw-r--r--src/collision.h4
-rw-r--r--src/content_cao.cpp41
-rw-r--r--src/content_cao.h2
-rw-r--r--src/content_sao.cpp33
-rw-r--r--src/content_sao.h1
-rw-r--r--src/environment.h11
-rw-r--r--src/luaentity_common.cpp2
9 files changed, 81 insertions, 31 deletions
diff --git a/data/mods/default/init.lua b/data/mods/default/init.lua
index a8a1d08f4..4f825626d 100644
--- a/data/mods/default/init.lua
+++ b/data/mods/default/init.lua
@@ -651,8 +651,7 @@ end
local TNT = {
-- Static definition
- -- Maybe handle gravity and collision this way? dunno
- -- physical = true,
+ physical = true, -- Collides with things
-- weight = 5,
collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
visual = "cube",
@@ -662,17 +661,14 @@ local TNT = {
-- Initial value for our timer
timer = 0,
-- Number of punches required to defuse
- health = 3,
- -- List names of state variables, for serializing object state
- -- (NOTE: not implemented and implementation will not be like this)
- -- state_variables = {"timer"},
+ health = 1,
}
-- Called when a TNT object is created
function TNT:on_activate(staticdata)
print("TNT:on_activate()")
- self.object:setvelocity({x=0, y=1, z=0})
- self.object:setacceleration({x=0, y=-5, z=0})
+ self.object:setvelocity({x=0, y=2, z=0})
+ self.object:setacceleration({x=0, y=-10, z=0})
end
-- Called periodically
@@ -709,6 +705,7 @@ minetest.register_entity("TNT", TNT)
function register_falling_node(nodename, texture)
minetest.register_entity("falling_"..nodename, {
-- Static definition
+ physical = true,
collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
visual = "cube",
textures = {texture,texture,texture,texture,texture,texture},
@@ -719,7 +716,7 @@ function register_falling_node(nodename, texture)
self.object:setacceleration({x=0, y=-10, z=0})
-- Turn to actual sand when collides to ground or just move
pos = self.object:getpos()
- bcp = {x=pos.x, y=pos.y-0.5, z=pos.z} -- Position of bottom center point
+ bcp = {x=pos.x, y=pos.y-0.6, z=pos.z} -- Position of bottom center point
bcn = minetest.env:get_node(bcp)
if bcn.name ~= "air" then
-- Turn to a sand node
diff --git a/src/collision.cpp b/src/collision.cpp
index 674cf4ed4..24f1e9d18 100644
--- a/src/collision.cpp
+++ b/src/collision.cpp
@@ -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);
diff --git a/src/collision.h b/src/collision.h
index 3354ea09a..e823a08fe 100644
--- a/src/collision.h
+++ b/src/collision.h
@@ -28,9 +28,11 @@ class IGameDef;
struct collisionMoveResult
{
bool touching_ground;
+ bool collides;
collisionMoveResult():
- touching_ground(false)
+ touching_ground(false),
+ collides(false)
{}
};
diff --git a/src/content_cao.cpp b/src/content_cao.cpp
index f5ef3fb07..213de554b 100644
--- a/src/content_cao.cpp
+++ b/src/content_cao.cpp
@@ -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();
}
}
diff --git a/src/content_cao.h b/src/content_cao.h
index 3f6b9d877..fa7a0cb4c 100644
--- a/src/content_cao.h
+++ b/src/content_cao.h
@@ -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;
diff --git a/src/content_sao.cpp b/src/content_sao.cpp
index 986e3f15f..5d63b295e 100644
--- a/src/content_sao.cpp
+++ b/src/content_sao.cpp
@@ -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();
diff --git a/src/content_sao.h b/src/content_sao.h
index 04d33647e..17d87e342 100644
--- a/src/content_sao.h
+++ b/src/content_sao.h
@@ -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;
};
diff --git a/src/environment.h b/src/environment.h
index a8213ea6d..1abf73867 100644
--- a/src/environment.h
+++ b/src/environment.h
@@ -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);
diff --git a/src/luaentity_common.cpp b/src/luaentity_common.cpp
index 138e72dcb..503083d0b 100644
--- a/src/luaentity_common.cpp
+++ b/src/luaentity_common.cpp
@@ -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")