Skip to content
Permalink
Browse files

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.
  • Loading branch information
gang65 authored and paramat committed Oct 24, 2019
1 parent f9a9e87 commit dd71dcbcf6bc40195334383f1cadc69f780abaeb
Showing with 13 additions and 21 deletions.
  1. +3 −1 .luacheckrc
  2. +10 −20 mods/boats/init.lua
@@ -12,7 +12,9 @@ read_globals = {
"Settings",
"unpack",
-- 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
@@ -13,15 +13,6 @@ local function is_water(pos)
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 x = -math.sin(yaw) * v
local z = math.cos(yaw) * v
@@ -146,7 +137,7 @@ end


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
local driver_objref = minetest.get_player_by_name(self.driver)
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"))
end
elseif ctrl.down then
self.v = self.v - dtime * 1.8
self.v = self.v - dtime * 2.0
if self.auto then
self.auto = false
minetest.chat_send_player(self.driver, S("Boat cruise mode off"))
end
elseif ctrl.up or self.auto then
self.v = self.v + dtime * 1.8
self.v = self.v + dtime * 2.0
end
if ctrl.left 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())
return
end
local s = get_sign(self.v)
self.v = self.v - dtime * 0.6 * s
if s ~= get_sign(self.v) then
self.object:set_velocity({x = 0, y = 0, z = 0})
-- We need to preserve velocity sign to properly apply drag force
-- while moving backward
local drag = dtime * math.sign(self.v) * (0.01 + 0.0796 * self.v * self.v)
-- If drag is larger than velocity, then stop horizontal movement
if math.abs(self.v) <= math.abs(drag) then
self.v = 0
return
end
if math.abs(self.v) > 5 then
self.v = 5 * get_sign(self.v)
else
self.v = self.v - drag
end

local p = self.object:get_pos()

0 comments on commit dd71dcb

Please sign in to comment.
You can’t perform that action at this time.