improved phisics for floating planes

This commit is contained in:
Alexsandro Percy 2023-07-16 20:37:23 -03:00
parent 07a1d382c6
commit 08db96a114
3 changed files with 51 additions and 56 deletions

View file

@ -1,19 +1,8 @@
local min = math.min
local abs = math.abs
--local deg = math.deg
function airutils.physics(self)
local friction = 0.99
local vel=self.object:get_velocity()
-- dumb friction
if self.isonground and not self.isinliquid then
vel = {x=vel.x*friction,
y=vel.y,
z=vel.z*friction}
self.object:set_velocity(vel)
end
local new_velocity = vel
--buoyancy
local surface = nil
local surfnodename = nil
@ -30,56 +19,59 @@ function airutils.physics(self)
surfnode = airutils.nodeatpos(snodepos)
end
local new_velocity = nil
self.isinliquid = surfnodename
if surface then -- standing in liquid
self.isinliquid = true
end
local accell = {x=0, y=0, z=0}
self.water_drag = 0.1
if self.isinliquid then
local accell = {x=0, y=0, z=0}
self.water_drag = 0.1
local height = self.height
local submergence = min(surface-spos.y,height)/height
local submergence = math.min(surface-spos.y,height)/height
-- local balance = self.buoyancy*self.height
local buoyacc = airutils.gravity*(self.buoyancy-submergence)
--[[airutils.set_acceleration(self.object,
{x=-vel.x*self.water_drag,y=buoyacc-vel.y*abs(vel.y)*0.4,z=-vel.z*self.water_drag})]]--
accell = {x=-vel.x*self.water_drag,y=buoyacc-(vel.y*abs(vel.y)*0.4),z=-vel.z*self.water_drag}
--local v_accell = {x=0,y=buoyacc-(vel.y*abs(vel.y)*0.4),z=0}
--airutils.set_acceleration(self.object,v_accell)
new_velocity = vector.add(vel, vector.multiply(accell, self.dtime))
--minetest.chat_send_all(buoyacc)
accell = {x=-new_velocity.x*self.water_drag,y=buoyacc-(new_velocity.y*math.abs(new_velocity.y)*5.4),z=-new_velocity.z*self.water_drag}
if self.buoyancy >= 1 then self._engine_running = false end
new_velocity = vector.add(new_velocity, vector.multiply(accell, self.dtime))
else
airutils.set_acceleration(self.object,{x=0,y=0,z=0})
self.isinliquid = false
new_velocity = vector.add(vel, {x=0,y=airutils.gravity * self.dtime,z=0})
--self.object:set_velocity(new_velocity)
new_velocity = vector.add(new_velocity, {x=0,y=airutils.gravity * self.dtime,z=0})
end
-- bounciness
if self.springiness and self.springiness > 0 then
local vnew = vector.new(vel)
if not self.collided then -- ugly workaround for inconsistent collisions
for _,k in ipairs({'y','z','x'}) do
if vel[k]==0 and abs(self.lastvelocity[k])> 0.1 then
vnew[k]=-self.lastvelocity[k]*self.springiness
end
end
end
if not vector.equals(vel,vnew) then
self.collided = true
else
if self.collided then
vnew = vector.new(self.lastvelocity)
end
self.collided = false
end
self.object:set_velocity(vnew)
end
if self.isonground and not self.isinliquid then
--dumb friction
new_velocity = {x=new_velocity.x*friction,
y=new_velocity.y,
z=new_velocity.z*friction}
-- bounciness
if self.springiness and self.springiness > 0 and self.buoyancy >= 1 then
local vnew = vector.new(new_velocity)
if not self.collided then -- ugly workaround for inconsistent collisions
for _,k in ipairs({'y','z','x'}) do
if new_velocity[k]==0 and math.abs(self.lastvelocity[k])> 0.1 then
vnew[k]=-self.lastvelocity[k]*self.springiness
end
end
end
if not vector.equals(new_velocity,vnew) then
self.collided = true
else
if self.collided then
vnew = vector.new(self.lastvelocity)
end
self.collided = false
end
new_velocity = vnew
end
end
self.object:set_velocity(new_velocity)
self.object:set_acceleration({x=0,y=airutils.gravity,z=0})
end

View file

@ -400,13 +400,16 @@ function airutils.logic(self)
--lets apply some bob in water
if self.isinliquid then
self._engine_running = false
local bob = airutils.minmax(airutils.dot(accel,hull_direction),0.2) -- vertical bobbing
local bob = airutils.minmax(airutils.dot(accel,hull_direction),0.5) -- vertical bobbing
if bob < 0 then bob = 0 end
accel.y = accel.y + bob
local max_pitch = 6
local h_vel_compensation = (((longit_speed * 2) * 100)/max_pitch)/100
local ref_speed = longit_speed * 20
if ref_speed < 0 then ref_speed = 0 end
local h_vel_compensation = ((ref_speed * 100)/max_pitch)/100
if h_vel_compensation < 0 then h_vel_compensation = 0 end
if h_vel_compensation > max_pitch then h_vel_compensation = max_pitch end
--minetest.chat_send_all(h_vel_compensation)
newpitch = newpitch + (velocity.y * math.rad(max_pitch - h_vel_compensation))
end

View file

@ -321,10 +321,10 @@ function airutils.testImpact(self, velocity, position)
if self._last_water_touch == nil then self._last_water_touch = 3 end
if self._last_water_touch <= 3 then self._last_water_touch = self._last_water_touch + self.dtime end
if impact > 0.2 and self._longit_speed > 0.6 and self._last_water_touch >=3 then
self._last_water_touch = 0
local noded = airutils.nodeatpos(airutils.pos_shift(p,{y=touch_point}))
if (noded and noded.drawtype ~= 'airlike') then
if noded.drawtype == 'liquid' then
self._last_water_touch = 0
minetest.sound_play("airutils_touch_water", {
--to_player = self.driver_name,
object = self.object,
@ -341,9 +341,9 @@ function airutils.testImpact(self, velocity, position)
if self._last_touch == nil then self._last_touch = 1 end
if self._last_touch <= 1 then self._last_touch = self._last_touch + self.dtime end
if vertical_impact > 1.0 and self._longit_speed > self._min_speed/2 and self._last_touch >= 1 then
self._last_touch = 0
local noded = airutils.nodeatpos(airutils.pos_shift(p,{y=touch_point}))
if (noded and noded.drawtype ~= 'airlike') then
if (noded and noded.drawtype ~= 'airlike') and (noded.drawtype ~= 'liquid') then
self._last_touch = 0
minetest.sound_play("airutils_touch", {
--to_player = self.driver_name,
object = self.object,