Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local verlet = {} verlet.step_time = 1 / 50 verlet.gravity = Vector3.new(0, -8, 0) local char = game.Players.LocalPlayer.Character local torso = char:WaitForChild("Torso") local parts = {} local render = game:GetService("RunService").RenderStepped wait(2) local point = {} local link = {} local rope = {} local function ccw(A,B,C) return (C.y-A.y) * (B.x-A.x) > (B.y-A.y) * (C.x-A.x) end local function intersect(A,B,C,D) return ccw(A,C,D) ~= ccw(B,C,D) and ccw(A,B,C) ~= ccw(A,B,D) end local function vec2(v) return Vector2.new(v.x, v.z) end function point:step() if not self.fixed then local derivative = (self.position - self.last_position) * 0.95 self.last_position = self.position self.position = self.position + derivative + (self.velocity * verlet.step_time ^ 2) --[[local torsoP = torso.CFrame * CFrame.new(-1, 0, 0.5) local torsoE = torso.CFrame * CFrame.new(1, 0, 0.5) local pointE = self.position + torso.CFrame.lookVector * 100 local doIntersect = intersect(vec2(torsoP.p), vec2(torsoE.p), vec2(self.position), vec2(pointE)) if not doIntersect then self.postition = self.position - torso.CFrame.lookVector * 10 end]] end end function link:step() for i = 1, 1 do local distance = self.point1.position - self.point2.position local magnitude = distance.magnitude local differance = (self.length - magnitude) / magnitude local translation = ((self.point1.fixed or self.point2.fixed) and 1 or 0.6) * distance * differance if not self.point1.fixed then self.point1.position = self.point1.position + translation end if not self.point2.fixed then self.point2.position = self.point2.position - translation end end end function verlet.new(class, a, b, c) if class == "Point" then local new = {} setmetatable(new, {__index = point}) new.class = class new.position = a or Vector3.new() new.last_position = new.position new.velocity = verlet.gravity new.fixed = false return new elseif class == "Link" then local new = {} setmetatable(new, {__index = link}) new.class = class new.point1 = a new.point2 = b new.length = c or (a.position - b.position).magnitude return new elseif class == "Rope" then local new = {} setmetatable(new, {__index = link}) new.class = class new.start_point = a new.finish_point = b new.points = {} new.links = {} local inc = (b - a) / 10 for i = 0, 10 do table.insert(new.points, verlet.new("Point", a + (i * inc))) end for i = 2, #new.points do table.insert(new.links, verlet.new("Link", new.points[i - 1], new.points[i])) end return new end end local tris = {} local triParts = {} local function GetDiscoColor(hue) local section = hue % 1 * 3 local secondary = 0.5 * math.pi * (section % 1) if section < 1 then return Color3.new(1, 1 - math.cos(secondary), 1 - math.sin(secondary)) elseif section < 2 then return Color3.new(1 - math.sin(secondary), 1, 1 - math.cos(secondary)) else return Color3.new(1 - math.cos(secondary), 1 - math.sin(secondary), 1) end end local function setupPart(part) part.Anchored = true part.FormFactor = 3 part.CanCollide = false part.TopSurface = 10 part.BottomSurface = 10 part.LeftSurface = 10 part.RightSurface = 10 part.FrontSurface = 10 part.BackSurface = 10 part.Material = "Sand" local m = Instance.new("SpecialMesh", part) m.MeshType = "Wedge" m.Scale = Vector3.new(0.2, 1, 1) return part end local function CFrameFromTopBack(at, top, back) local right = top:Cross(back) return CFrame.new(at.x, at.y, at.z, right.x, top.x, back.x, right.y, top.y, back.y, right.z, top.z, back.z) end local function drawTri(parent, a, b, c) local this = {} local mPart1 = table.remove(triParts, 1) or setupPart(Instance.new("Part")) local mPart2 = table.remove(triParts, 1) or setupPart(Instance.new("Part")) function this:Set(a, b, c) local ab, bc, ca = b-a, c-b, a-c local abm, bcm, cam = ab.magnitude, bc.magnitude, ca.magnitude local edg1 = math.abs(0.5 + ca:Dot(ab)/(abm*abm)) local edg2 = math.abs(0.5 + ab:Dot(bc)/(bcm*bcm)) local edg3 = math.abs(0.5 + bc:Dot(ca)/(cam*cam)) if edg1 < edg2 then if edg1 >= edg3 then a, b, c = c, a, b ab, bc, ca = ca, ab, bc abm = cam end else if edg2 < edg3 then a, b, c = b, c, a ab, bc, ca = bc, ca, ab abm = bcm else a, b, c = c, a, b ab, bc, ca = ca, ab, bc abm = cam end end local len1 = -ca:Dot(ab)/abm local len2 = abm - len1 local width = (ca + ab.unit*len1).magnitude local maincf = CFrameFromTopBack(a, ab:Cross(bc).unit, -ab.unit) if len1 > 0.2 then mPart1.Parent = parent mPart1.Size = Vector3.new(0.2, width, len1) mPart1.CFrame = maincf*CFrame.Angles(math.pi,0,math.pi/2)*CFrame.new(0,width/2,len1/2) else mPart1.Parent = nil end if len2 > 0.2 then mPart2.Parent = parent mPart2.Size = Vector3.new(0.2, width, len2) mPart2.CFrame = maincf*CFrame.Angles(math.pi,math.pi,-math.pi/2)*CFrame.new(0,width/2,-len1 - len2/2) else mPart2.Parent = nil end end function this:SetProperty(prop, value) mPart1[prop] = value mPart2[prop] = value end this:Set(a, b, c) function this:Destroy() mPart1:Destroy() mPart2:Destroy() end this.p1 = mPart1 this.p2 = mPart2 this.p1.BrickColor = BrickColor.new(GetDiscoColor(math.noise(0.5, 0.5, this.p1.CFrame.Y * 0.5 + time()))) this.p2.BrickColor = BrickColor.new(GetDiscoColor(math.noise(0.5, 0.5, this.p2.CFrame.Y * 0.5 + time()))) return this end function verlet.draw(object, id) if object.class == "Point" then local part = parts[id] part.BrickColor = BrickColor.new(1, 1, 1) part.Transparency = 0 part.formFactor = 3 part.Anchored = true part.CanCollide = false part.TopSurface = 0 part.BottomSurface = 0 part.Size = Vector3.new(0.35, 0.35, 0.35) part.Material = "Neon" part.CFrame = CFrame.new(object.position) part.Parent = torso return part elseif object.class == "Link" then local part = parts[id] local dist = (object.point1.position - object.point2.position).magnitude part.Size = Vector3.new(0.2, 0.2, dist) part.CFrame = CFrame.new(object.point1.position, object.point2.position) * CFrame.new(0, 0, dist * -0.5) part.Parent = torso return part end end function verlet.clear() for _, v in pairs(workspace:GetChildren()) do if v.Name == "Part" then v:Destroy() end end end local points = {} local links = {} for x = 0, 2 do points[x] = {} for y = 0, 3 do points[x][y] = verlet.new("Point", torso.Position + Vector3.new(x * 0.8 - 2, 2 - y * 0.8, 5 + y * 0.4)) points[x][y].fixed = y == 0 end end for x = 1, 2 do for y = 0, 3 do links[#links + 1] = verlet.new("Link", points[x][y], points[x - 1][y], 1 + y * 0.08) end end for x = 0, 2 do for y = 1, 3 do links[#links + 1] = verlet.new("Link", points[x][y], points[x][y - 1], 1.2 + y * 0.03) end end render:connect(function() for x = 0, 2 do for y = 0, 3 do if y == 0 then points[x][y].position = (torso.CFrame * CFrame.new(x * 1 - 1, 1, 0.5)).p else points[x][y]:step() end end end for i = 1, #links do links[i]:step() end for i = 1, #tris do triParts[#triParts + 1] = tris[i].p1 triParts[#triParts + 1] = tris[i].p2 end tris = {} for x = 1, 2 do for y = 1, 3 do tris[#tris + 1] = drawTri(torso, points[x - 1][y - 1].position, points[x - 1][y].position, points[x][y - 1].position) tris[#tris + 1] = drawTri(torso, points[x][y].position, points[x - 1][y].position, points[x][y - 1].position) end end end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement