Files
PlaneBuilding/scripts/modules/objects/Aero.lua
T

127 lines
4.0 KiB
Lua

local module = {}
local debugWings = game.Workspace.DebugWings.Value
local space = game.Workspace.Objects
local dens = game.Workspace.AirDensity * -game.Workspace.CompensateDensity.Value
local ndelta = 1/60
local function drag(v,r)
return v * r
end
local rnd = function(vec) return Vector3.new(math.round(vec.X),math.round(vec.Y),math.round(vec.Z)) end
local a = math.abs
local ln = math.log
local debwings = {}
local function deb(wing,force)
local part = debwings[wing]
if not part then
part = Instance.new("Part")
part.Name = "WingDebug"
part.Parent = game.Workspace.Hidden
part.Color = Color3.new(0.152941, 0.764706, 0.0588235)
part.Material = Enum.Material.Neon
part.Anchored = true
part.CanCollide = false
part.Transparency = 0.8
part.Size = Vector3.new(0.25,0.25,2) -- we determine the wing's strength and do math by its size, the bigger, the more lift
debwings[wing] = part
end
part.Transparency = 0.5
part.CFrame = CFrame.lookAt(wing.Position,wing.Position+force)
part.Size = Vector3.new(0.25,0.25,force.Magnitude)
part.CFrame = part.CFrame + part.CFrame.LookVector * part.Size.Z * 0.5
end
require(game.ReplicatedFirst.ReadyModule)("WingCommands")
local process = true
game.Workspace.DebugWings.Changed:Connect(function()
debugWings = game.Workspace.DebugWings.Value
if not debugWings then
for _,item in pairs(debwings) do
item:Destroy()
end
debwings = {}
end
end)
game.Workspace.CompensateDensity.Changed:Connect(function()
dens = game.Workspace.AirDensity * -game.Workspace.CompensateDensity.Value
end)
function module.new(this,wing,context)
--local mul = wing:GetAttribute("AeroMultiplier") or 1
this.bounds = {}
this.volume = {}
if wing:IsA("Model") then
this.aero = {}
for _,part in pairs(wing:GetChildren()) do
if part:HasTag("IsAerodynamic") then
table.insert(this.aero,part)
end
end
else
this.aero = {wing}
end
for _,part in pairs(this.aero) do
local s = part.Size
this.bounds[part] = Vector3.new(s.Y*s.Z,s.X*s.Z,s.Y*s.X)-- * mul
this.volume[part] = s.X*s.Y*s.Z
end
return this
end
local visc = 0.75
local commands = require(_G.Modules.CommandsModule)
commands.new("viscosity (.+)","viscosity <number>: change air viscosity coefficient",function(n)
visc = tonumber(n)
end)
module.run = @native
function(this,wing,context)
local bounds = this.bounds
local volume = this.volume
if not process then return true end
if not this.aero then print(this,wing) end -- BECAUSE WHAT THE BLOODY HELL IS THIS!?!??
for _,wing in pairs(this.aero) do
--if not (wing.Parent == space or wing.Parent.Parent == space) and v.player then return end
local s = bounds[wing]
if not s then print(this.aero,bounds,wing,s) end
local p = wing.Position
local v = wing:GetVelocityAtPosition(p) -- velocity of wing
local d = dens * 20
local fmass = 2 -- mass of air generally
--[[if p.Y < 0 then
d = d * 5
fmass = 100 -- mass of water
end]]
v = v - Vector3.new(0,
0--0.15 * v.Magnitude -- implement upthrust due to pressure difference across an airfoil (lift)
,0)
local lv = wing.CFrame.Rotation:PointToObjectSpace(v) -- velocity for each wing face
--mv = lv.Magnitude + 0.0001 -- small number to stop zero error
-- "math", YEAH REALLY? i didnt REALISE! I don't even know what this does...
--lp = Vector3.new(lv.X/(a(scale.X*d*lv.X)+1)-lv.X,lv.Y/(a(scale.Y*d*lv.Y)+1)-lv.Y,lv.Z/(a(scale.Z*d*lv.Z)+1)-lv.Z) -- math
local drag = Vector3.new(lv.X*s.X,lv.Y*s.Y,lv.Z*s.Z)
-- implement anti-viscosity (may the riemann sum gods be with the low end machines
local lp = (drag) * context.delta*d*math.tanh(v.Magnitude*0.0075)
local r = (wing.CFrame.Rotation:PointToWorldSpace(lp))
r = r + Vector3.yAxis * fmass * volume[wing] * 2 * context.delta -- implement upthrust due to pressure difference in a fluid column (floating)
wing:ApplyImpulseAtPosition(r,wing.Position)
if debugWings then deb(wing,r) end
end
return true
end
module.manifest = {
predicate = function(instance)
return instance:HasTag("IsAerodynamic") or instance.Name:match("Sheet") -- LAST CONDITION IS NOT NEEDED
end,
}
return module