mirror of
https://github.com/APercy/airutils.git
synced 2025-03-15 08:01:22 +00:00
improved phisics for floating planes
This commit is contained in:
parent
07a1d382c6
commit
08db96a114
3 changed files with 51 additions and 56 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue