local module = {} local function form_triangle(pa,pb,p1,p2,p3,s2) local s1 = pa.Size.X s2 = s2 or s1*0.5 local p12 = p2-p1 local p23 = p3-p2 local p13 = p3-p1 local p12l = p12.Magnitude local p23l = p23.Magnitude local p13l = p13.Magnitude local bottom local bot_len local totop local root local tip local far if p12l > p23l and p12l > p13l then -- TRUE: p12 largest FALSE: p12 smaller than p23l or p13l tip = p3 root = p1 far = p2 bottom = p12 bot_len = p12l totop = p13 s2 = -s2 elseif p23l > p13l then -- TRUE: p23 must be largest FALSE: p13 largest tip = p1 root = p2 far = p3 bottom = p23 bot_len = p23l totop = -p12 s2 = -s2 else -- p13 largest tip = p2 root = p1 far = p3 bottom = p13 bot_len = p13l totop = p12 end bottom = bottom.Unit local coeff = totop:Dot(bottom) local mid = root+coeff*bottom local cross = totop:Cross(bottom).Unit local top = (mid-tip) pa.Size = Vector3.new(s1,top.Magnitude,coeff) pb.Size = Vector3.new(s1,top.Magnitude,bot_len - coeff) top = top.Unit pa.CFrame = CFrame.fromMatrix(s2*cross+(root+tip)*0.5,cross,-top,bottom) pb.CFrame = CFrame.fromMatrix(s2*cross+(tip+far)*0.5,-cross,-top,-bottom) end local function form_normal(p,n) local part = Instance.new("Part") part.Anchored = true part.Size = Vector3.new(1,1,10) part.Parent = game.Workspace part.CFrame = CFrame.lookAlong(p,n) * CFrame.new(0,0,-5) end local w = 8 local grass = script.Grass local ter = workspace.Terrain function module.make_wedges(_,p) local part = grass:Clone() for _,item in pairs(part:GetChildren()) do for k,v in pairs(p) do item[k] = v end end return { make_quad = function(p1,p2,p3,p4,s,n1,n2,n3,n4,parent) local g = part:Clone() g.Parent = parent form_triangle(g.a,g.b,p1,p2,p3,s*(-w/2)) form_triangle(g.c,g.d,p1,p4,p3,s*(w/2)) --[[form_normal(p1,n1) form_normal(p2,n2) form_normal(p3,n3) form_normal(p4,n4)]] return g end, flush = function() end, } end local assets = game:GetService("AssetService") local s = 1 function module.make_mesh(_root,p) local mesh = assets:CreateEditableMesh() local empty = true local root = _root or Vector3.zero local mesh = mesh local topleft = mesh:AddUV(Vector2.new(0,0)) local topright = mesh:AddUV(Vector2.new(s,0)) local bottomright = mesh:AddUV(Vector2.new(s,s)) local bottomleft = mesh:AddUV(Vector2.new(0,s)) return { make_quad = function(p1,p2,p3,p4,s,n1,n2,n3,n4) empty = false n1 = mesh:AddNormal(n1) n2 = mesh:AddNormal(n2) n3 = mesh:AddNormal(n3) n4 = mesh:AddNormal(n4) p1 = mesh:AddVertex(p1 - root) p2 = mesh:AddVertex(p2 - root) p3 = mesh:AddVertex(p3 - root) p4 = mesh:AddVertex(p4 - root) local tri1,tri2 if s > 0 then tri1 = mesh:AddTriangle(p1,p2,p3) tri2 = mesh:AddTriangle(p3,p4,p1) mesh:SetFaceNormals(tri1,{n1,n2,n3}) mesh:SetFaceNormals(tri2,{n3,n4,n1}) mesh:SetFaceUVs(tri1,{topleft,topright,bottomright}) mesh:SetFaceUVs(tri2,{bottomright,bottomleft,topleft}) else tri1 = mesh:AddTriangle(p3,p2,p1) tri2 = mesh:AddTriangle(p1,p4,p3) mesh:SetFaceNormals(tri1,{n3,n2,n1}) mesh:SetFaceNormals(tri2,{n1,n4,n3}) mesh:SetFaceUVs(tri1,{bottomright,topright,topleft}) mesh:SetFaceUVs(tri2,{topleft,bottomleft,bottomright}) end end, flush = function() if not empty then local part = assets:CreateMeshPartAsync(Content.fromObject(mesh), { CollisionFidelity = Enum.CollisionFidelity.PreciseConvexDecomposition, RenderFidelity = Enum.RenderFidelity.Performance }) for index,item in pairs(p) do part[index] = item end part.Parent = workspace.Terrain part.Position = root part.Anchored = true end root = nil mesh = nil end, } end return module