local W={ClassName="\084\114\105\097\110\103\108\101\051\068"}W.__index=W local U={ZERO=Vector3.new(0,0,0)}local V=script.TriangleMesh local function H(V,H,M,x)local S={}if typeof(V)=="\116\097\098\108\101"then S.Vertices=V x=H else S.Vertices={V or U.ZERO,H or U.ZERO,M or U.ZERO}end S.Preset=x setmetatable(S,W)if typeof(x)=="\116\097\098\108\101"then if x.render then S:Render()end if x.build then S:Build()if x.draw and x.render then S:Draw()end if x.parent then S:Parent(x.parent)end end end return S end function W.Build(W)local U=Instance.new("\077\111\100\101\108")U.Name="\084\114\105\097\110\103\108\101\077\111\100\101\108"local H=V:Clone()H.CastShadow=false H.Anchored=true H.TopSurface=Enum.SurfaceType.Smooth H.BottomSurface=Enum.SurfaceType.Smooth H.Locked=true local M=Instance.new("\087\101\108\100\067\111\110\115\116\114\097\105\110\116")M.Part0=H M.Parent=H W.Model=U W.Wedge1=H W.Wedge2=H:Clone()W.Wedge1.WeldConstraint.Part1=W.Wedge2 W.Wedge2.WeldConstraint.Part1=W.Wedge1 end function W.Set(V,W,U)V.Wedge1[W]=U V.Wedge2[W]=U end function W.BulkSet(U,W)for W,V in pairs(W)do U:Set(W,V)end end function W.Parent(U,W)U:Set("\080\097\114\101\110\116",U.Model)U.Model.Parent=W end function W.Color(U,W)if typeof(W)=="\066\114\105\099\107\067\111\108\111\114"then U:Set("\066\114\105\099\107\067\111\108\111\114",W)else U:Set("\067\111\108\111\114",W)end end function W.Reflectance(U,W)U:Set("\082\101\102\108\101\099\116\097\110\099\101",W)end function W.Transparency(U,W)U:Set("\084\114\097\110\115\112\097\114\101\110\099\121",W)end function W.Render(W)local U=W.Vertices local V=U[1]local H=U[2]local M=U[3]local x,S,v=H-V,M-V,M-H local j,c,d=x:Dot(x),S:Dot(S),v:Dot(v)if j>c and j>d then M,V=V,M elseif c>d and c>j then V,H=H,V end x,S,v=H-V,M-V,M-H local G=(S:Cross(x)).unit local a=(v:Cross(G)).unit local s=v.unit local b=math.abs(x:Dot(a))W.RenderInfo={Vector3.new(0,b,math.abs(x:Dot(s)));CFrame.fromMatrix((V+H)/2,G,a,s);Vector3.new(0,b,math.abs(S:Dot(s)));CFrame.fromMatrix((V+M)/2,-G,a,-s)}end function W.Draw(W)local U=W.RenderInfo local V=W.Wedge1 local H=W.Wedge2 V.Size=U[1]V.CFrame=U[2]H.Size=U[3]H.CFrame=U[4]end function W.Animate(W)W:Render()W:Draw()end function W.SetVertices(H,W,U,V)if typeof(W)=="\116\097\098\108\101"then H.Vertices=W else H.Vertices={W;U;V}end end function W.AnimateVertices(H,W,U,V)H:SetVertices(W,U,V)H:Animate()end function W.RenderVertices(H,W,U,V)H:SetVertices(W,U,V)H:Render()end function W.Clone(V,U)local H=W.new(V.Vertices,U or V.Preset)return H end function W.Destroy(W)W.Model:Destroy()for U,V in pairs(W)do W[U]=nil end W=nil end W.new=H return W
--[[

	Made by Codes Otaku
	Tutorial:
		https://youtu.be/KGYBckh3lUA
	Credits:
		EgoMoose (Render function)

]]

local Triangle3D = {ClassName = "Triangle3D"}
Triangle3D.__index = Triangle3D

local vec3 = {
	ZERO = Vector3.new(0,0,0)
}

local TriangleMesh = script.TriangleMesh

-- [Constructor] Make a triangle out of 3 positions a,b and c (Vector3's)  and a preset
-- new(a, b, c, preset)
-- new({a, b, c}, preset)
-- preset example
--[[
local DrawPreset = {
	build = true, -- Build?
	render = true, -- Render?
	draw = true, -- Draw? requires "build" and "render"
	parent = workspace -- Parent? requires "build"
}
]]

local function new(a, b, c, preset)
	local self = {}

	
	if typeof(a) == "table"	 then
		self.Vertices = a
		preset = b
	else
		self.Vertices = {a or vec3.ZERO, b or vec3.ZERO, c or vec3.ZERO}
	end
	
	self.Preset = preset
	
	setmetatable(self, Triangle3D)
	
	if typeof(preset) == "table" then
		if preset.render then
			self:Render()
		end
		
		if preset.build then		
			self:Build()
			
			if preset.draw and preset.render then
				self:Draw()
			end
			
			if preset.parent then
				self:Parent(preset.parent)
			end
		end
	end
	
	return self
end

-- Call this to create the necessary wedges.
function Triangle3D:Build()
	local Model = Instance.new("Model")
	Model.Name = "TriangleModel"
	
	local wedge1 = TriangleMesh:Clone()
	wedge1.CastShadow = false
	wedge1.Anchored = true
	wedge1.TopSurface = Enum.SurfaceType.Smooth
	wedge1.BottomSurface = Enum.SurfaceType.Smooth
	wedge1.Locked = true--wedge1.Parent = Model

	local WeldConstraint = Instance.new("WeldConstraint")
	WeldConstraint.Part0 = wedge1
	WeldConstraint.Parent = wedge1

	self.Model = Model
	self.Wedge1 = wedge1
	self.Wedge2 = wedge1:Clone()

	self.Wedge1.WeldConstraint.Part1 = self.Wedge2
	self.Wedge2.WeldConstraint.Part1 = self.Wedge1
end

-- Set properties of the drawn triangle (Wedge1, Wedge2)
function Triangle3D:Set(property, value)
	self.Wedge1[property] = value
	self.Wedge2[property] = value
end

-- Set a lot of properties of the triangle at once
function Triangle3D:BulkSet(Table)
	for i,v in pairs(Table) do
		self:Set(i, v)
	end
end

-- Call this to parent the wedges to the specified parent
function Triangle3D:Parent(parent)
	self:Set("Parent", self.Model)
	self.Model.Parent = parent
end

-- Call this to color the triangle
function Triangle3D:Color(color)
	if typeof(color) == "BrickColor" then
		self:Set("BrickColor", color)
	else
		self:Set("Color", color)
	end
end

-- Call this to change the Reflectance of the triangle
function Triangle3D:Reflectance(value)
	self:Set("Reflectance", value)
end

-- Call this to change the transparency of the triangle
function Triangle3D:Transparency(value)
	self:Set("Transparency", value)
end

-- Call this to calculate RenderInfo (Wedges size and CFrames)
-- Credits to EgoMoose for the render function (Edited)

function Triangle3D:Render()
	local vertices = self.Vertices

	local a = vertices[1]
	local b = vertices[2]
	local c = vertices[3]

	local ab, ac, bc = b - a, c - a, c - b
	local abd, acd, bcd = ab:Dot(ab), ac:Dot(ac), bc:Dot(bc)

	if (abd > acd and abd > bcd) then
		c, a = a, c
	elseif (acd > bcd and acd > abd) then
		a, b = b, a
	end

	ab, ac, bc = b - a, c - a, c - b

	local right = ac:Cross(ab).unit
	local up = bc:Cross(right).unit
	local back = bc.unit

	local height = math.abs(ab:Dot(up))
	
	self.RenderInfo = {
		Vector3.new(0, height, math.abs(ab:Dot(back))),
		CFrame.fromMatrix((a + b)/2, right, up, back),
		Vector3.new(0, height, math.abs(ac:Dot(back))),
		CFrame.fromMatrix((a + c)/2, -right, up, -back)
	}
end

-- Call this to apply the render info (resulted from Render)
function Triangle3D:Draw()
	local render_info = self.RenderInfo
	
	local wedge1 = self.Wedge1
	local wedge2 = self.Wedge2

	wedge1.Size = render_info[1]
	wedge1.CFrame = render_info[2]

	wedge2.Size = render_info[3]
	wedge2.CFrame = render_info[4]
end

-- Call this to render and draw at the same time
function Triangle3D:Animate()
	self:Render()
	self:Draw()
end

-- Call this to change the vertices only
function Triangle3D:SetVertices(a, b, c)
	if typeof(a) == "table" then
		self.Vertices = a
	else
		self.Vertices = {a, b, c}
	end
end

-- Call this to change the vertices and render and draw at the same time
function Triangle3D:AnimateVertices(a, b, c)
	self:SetVertices(a, b, c)
	self:Animate()
end

-- Call this to change the vertices and render the calculations without drawing
function Triangle3D:RenderVertices(a, b, c)
	self:SetVertices(a, b, c)
	self:Render()
end

-- Call this to get a new triangle with the same contrustor you used for the original.
-- Same vertices and same preset
function Triangle3D:Clone(preset)
	local s = Triangle3D.new(self.Vertices, preset or self.Preset)
	return s
end

-- Call this to destroy the triangle if you no longer need it
function Triangle3D:Destroy()
	self.Model:Destroy()
	
	for i,v in pairs(self) do
		self[i] = nil
	end
	
	self = nil
end

Triangle3D.new = new
return Triangle3D