Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- do
- local insert, remove = table.insert, table.remove
- local LODSpecs = {}
- local function bfind(t, v)
- local a, b = 1, #t
- while a <= b do
- local u = floor((a + b) * 0.5)
- local w = t[u].Sort
- if v > w then
- a = u + 1
- elseif v < w then
- b = u - 1
- else
- return u
- end
- end
- return a
- end
- local function CalculateCenter(m)
- local Center = v3b
- local Children = m:GetChildren()
- for _, Model in next, Children, nil do
- if Model.ClassName == "Model" then
- Center = Center + Model.PrimaryPart.Position
- else
- Center = Center + Model.Position
- end
- end
- Center = Center / #Children
- return Center
- end
- function LODSplitEach(m)
- local Groups = {}
- for _, Model in next, m:GetChildren() do
- local Group = Instance.new("Model")
- Model.Parent = Group
- table.insert(Groups, Group)
- end
- for _, Model in next, Groups, nil do
- Model.Parent = m
- end
- end
- function LODSplitModel(m, n)
- local w = floor(n ^ 0.5)
- local Size = m:GetExtentsSize()
- local Center = CalculateCenter(m)
- local wx = floor(Size.X / w + 0.5)
- local wz = floor(Size.Z / w + 0.5)
- local Groups = {}
- for _, Model in next, m:GetChildren() do
- local p = Model.ClassName == "Model" and Model.PrimaryPart.Position or Model.Position
- local rx = floor((p.X - Center.X) / wx) * wx
- local rz = floor((p.Z - Center.Z) / wz) * wz
- local v = ("%d/%d"):format(rx, rz)
- local Group = Groups[v]
- if not Group then
- Group = Instance.new("Model")
- Group.Parent = workspace
- Group.Name = v
- Groups[v] = Group
- end
- Model.Parent = Group
- end
- for _, Group in next, Groups, nil do
- Group.Parent = m
- end
- return 0.25 * (wx + wz) * 1.4142135623730951
- end
- function LODAddModel(m, d)
- local Parent = m.Parent
- assert(Parent)
- local Spec = {
- Model = m,
- Parent = Parent,
- Center = CalculateCenter(m),
- MinDist = d,
- Loaded = true,
- Locked = false
- }
- table.insert(LODSpecs, Spec)
- return Spec
- end
- function LODAddModels(m, d)
- local Specs = {}
- for _, v in next, m:GetChildren() do
- local Spec = LODAddModel(v, d)
- table.insert(Specs, Spec)
- end
- return Specs
- end
- function LODRemoveModel(m)
- for i = 1, #LODSpecs do
- local Spec = LODSpecs[i]
- if Spec.Model == m then
- LODForceLoad(Spec)
- Spec.Locked = true
- end
- end
- return false
- end
- function LODForceLoad(Spec)
- Spec.Model.Parent = Spec.Parent
- Spec.Loaded = true
- Spec.Locked = true
- end
- local LoadQueue = {}
- local UnloadQueue = {}
- function LODUpdateInterest(p)
- local GFX = UserSettings():GetService("UserGameSettings").SavedQualityLevel
- local Multiplier = GFX.Value > 0 and GFX.Value/2 or 2.5
- LoadQueue = {}
- UnloadQueue = {}
- for _, Spec in next, LODSpecs, nil do
- local d = (Spec.Center - p).magnitude
- Spec.Sort = d
- local ShouldBeLoaded = d < (Spec.MinDist*Multiplier)
- if Spec.Locked then
- ShouldBeLoaded = true
- end
- local Loaded = Spec.Loaded
- if ShouldBeLoaded and not Loaded then
- local i = bfind(LoadQueue, d)
- insert(LoadQueue, i, Spec)
- elseif not ShouldBeLoaded and Loaded then
- local i = bfind(UnloadQueue, d)
- insert(UnloadQueue, i, Spec)
- end
- end
- end
- local function ProcessQueue()
- if #LoadQueue > 0 then
- local Spec = remove(LoadQueue, 1)
- Spec.Model.Parent = Spec.Parent
- Spec.Loaded = true
- end
- if #UnloadQueue > 0 then
- local Spec = remove(UnloadQueue)
- Spec.Model.Parent = nil
- Spec.Loaded = false
- end
- end
- function LODStart(i)
- ThreadLoopAdd(i, ProcessQueue,"LOD Queue Processing")
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment