forked from minetest/minetest_game
boats: Improve physics by implementing drag and friction forces
Implement drag force according to the equation: drag_force = drag_coefficient * speed ^2 Also add a small constant force to implement friction force.
This commit is contained in:
parent
f9a9e87af6
commit
dd71dcbcf6
|
@ -12,7 +12,9 @@ read_globals = {
|
||||||
"Settings",
|
"Settings",
|
||||||
"unpack",
|
"unpack",
|
||||||
-- Silence errors about custom table methods.
|
-- Silence errors about custom table methods.
|
||||||
table = { fields = { "copy", "indexof" } }
|
table = { fields = { "copy", "indexof" } },
|
||||||
|
-- Silence warnings about accessing undefined fields of global 'math'
|
||||||
|
math = { fields = { "sign" } }
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Overwrites minetest.handle_node_drops
|
-- Overwrites minetest.handle_node_drops
|
||||||
|
|
|
@ -13,15 +13,6 @@ local function is_water(pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function get_sign(i)
|
|
||||||
if i == 0 then
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
return i / math.abs(i)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local function get_velocity(v, yaw, y)
|
local function get_velocity(v, yaw, y)
|
||||||
local x = -math.sin(yaw) * v
|
local x = -math.sin(yaw) * v
|
||||||
local z = math.cos(yaw) * v
|
local z = math.cos(yaw) * v
|
||||||
|
@ -146,7 +137,7 @@ end
|
||||||
|
|
||||||
|
|
||||||
function boat.on_step(self, dtime)
|
function boat.on_step(self, dtime)
|
||||||
self.v = get_v(self.object:get_velocity()) * get_sign(self.v)
|
self.v = get_v(self.object:get_velocity()) * math.sign(self.v)
|
||||||
if self.driver then
|
if self.driver then
|
||||||
local driver_objref = minetest.get_player_by_name(self.driver)
|
local driver_objref = minetest.get_player_by_name(self.driver)
|
||||||
if driver_objref then
|
if driver_objref then
|
||||||
|
@ -157,13 +148,13 @@ function boat.on_step(self, dtime)
|
||||||
minetest.chat_send_player(self.driver, S("Boat cruise mode on"))
|
minetest.chat_send_player(self.driver, S("Boat cruise mode on"))
|
||||||
end
|
end
|
||||||
elseif ctrl.down then
|
elseif ctrl.down then
|
||||||
self.v = self.v - dtime * 1.8
|
self.v = self.v - dtime * 2.0
|
||||||
if self.auto then
|
if self.auto then
|
||||||
self.auto = false
|
self.auto = false
|
||||||
minetest.chat_send_player(self.driver, S("Boat cruise mode off"))
|
minetest.chat_send_player(self.driver, S("Boat cruise mode off"))
|
||||||
end
|
end
|
||||||
elseif ctrl.up or self.auto then
|
elseif ctrl.up or self.auto then
|
||||||
self.v = self.v + dtime * 1.8
|
self.v = self.v + dtime * 2.0
|
||||||
end
|
end
|
||||||
if ctrl.left then
|
if ctrl.left then
|
||||||
if self.v < -0.001 then
|
if self.v < -0.001 then
|
||||||
|
@ -185,15 +176,14 @@ function boat.on_step(self, dtime)
|
||||||
self.object:set_pos(self.object:get_pos())
|
self.object:set_pos(self.object:get_pos())
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local s = get_sign(self.v)
|
-- We need to preserve velocity sign to properly apply drag force
|
||||||
self.v = self.v - dtime * 0.6 * s
|
-- while moving backward
|
||||||
if s ~= get_sign(self.v) then
|
local drag = dtime * math.sign(self.v) * (0.01 + 0.0796 * self.v * self.v)
|
||||||
self.object:set_velocity({x = 0, y = 0, z = 0})
|
-- If drag is larger than velocity, then stop horizontal movement
|
||||||
|
if math.abs(self.v) <= math.abs(drag) then
|
||||||
self.v = 0
|
self.v = 0
|
||||||
return
|
else
|
||||||
end
|
self.v = self.v - drag
|
||||||
if math.abs(self.v) > 5 then
|
|
||||||
self.v = 5 * get_sign(self.v)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local p = self.object:get_pos()
|
local p = self.object:get_pos()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user