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 : 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