So the issues is I’m trying generate gable roofs like this:
And that works fine, assuming all the nodes for the roof being generated are in a particular order and aligned to the axis. However I need to be able to handle rotated buildings, I can calculate the angle the parts need to be at just fine, but I’m struggling actually adjusting the part into the rotation because of the relative nature of CFrame rotations.
Whenever I add it in, what seems to happen is it is rotated relative to its current position, but I want to rotate it on a global axis.
Here is my current code:
roofPart.CFrame = CFrame.new((m0+roofPeak)/2) --position it
* CFrame.Angles(theta, 0, 0) -- add the incline
* CFrame.new(Vector3.new(0, 0, -OVER_HANG/2))--add the overhang
To get it to work right, I just want to add in somewhere * CFrame.Angles(0, phi, 0).
My only stipulation is crucial that the overhang is removed after the incline is set, as in effect what is happening is the part is sliding down a stud in that direction.
The full function for those wanting to poke about:
function GableRoof:Generate(nodes)
local p0, p1, p2, p3 = nodes[1].Vector3, nodes[2].Vector3, nodes[3].Vector3, nodes[4].Vector3
local m0, m1 = (p1+p0)/2, (p3+p2)/2
local roofCenter = ((m0+m1)/2)-- + Vector3.new(0, 3, 0)
local vec = roofCenter - m0
local theta = -math.atan2(ROOF_HEIGHT, vec.magnitude)-- the incline of the roof
local phi = math.atan2(vec.z, vec.x) -- the direction the roof thingys are pointed
local roofPart = Instance.new("Part")
local roofPeak = roofCenter + Vector3.new(0, ROOF_HEIGHT, 0)
roofPart.Size = Vector3.new((p1-p0).magnitude+OVER_HANG, .5, (m0-roofPeak).magnitude + OVER_HANG)
roofPart.Anchored = true
roofPart.Material = Enum.Material.SmoothPlastic
roofPart.CFrame = CFrame.new((m0+roofPeak)/2) --position it
* CFrame.Angles(theta, 0, 0) -- add the incline
* CFrame.new(Vector3.new(0, 0, -OVER_HANG/2))--add the overhang
local otherPart = roofPart:Clone()
otherPart.CFrame = CFrame.new((m1+roofPeak)/2) --position it
-- * CFrame.Angles(0,-phi, 0) --rotate it to face the center
* CFrame.Angles(-theta, 0, 0) --add incline
* CFrame.new(Vector3.new(0, 0, OVER_HANG/2)) --remove the overhang
roofPart.Parent = workspace
otherPart.Parent = workspace
local p1p2Middle = (p1+p2)/2
local triangle0 = Triangle:Clone()
triangle0.Size = Vector3.new(0.2, ROOF_HEIGHT, (p1-p2).magnitude/2)
triangle0.CFrame = CFrame.new(((p1p2Middle+p1)/2) + Vector3.new(0, ROOF_HEIGHT/2, 0))
local triangle1 = triangle0:Clone()
triangle1.CFrame = CFrame.new(((p1p2Middle+p2)/2) + Vector3.new(0, ROOF_HEIGHT/2, 0)) * CFrame.Angles(0, math.pi, 0)
local triangle2 = triangle0:Clone()
triangle2.CFrame = triangle2.CFrame * CFrame.new(Vector3.new(-(p1-p0).magnitude, 0, 0))
local triangle3 = triangle1:Clone()
triangle3.CFrame = triangle3.CFrame * CFrame.new(Vector3.new((p1-p0).magnitude, 0, 0))
triangle1.Parent = workspace
triangle0.Parent = workspace
triangle2.Parent = workspace
triangle3.Parent = workspace
local centerPart = Instance.new("Part")
local vec = p1-p0
centerPart.Size = Vector3.new(1, 1, (p1-p0).magnitude + OVER_HANG)
centerPart.CFrame = CFrame.new(roofPeak) * CFrame.Angles(0, math.atan2(vec.z, vec.x) + math.pi*.5, 0)
centerPart.Anchored = true
centerPart.Material = Enum.Material.SmoothPlastic
centerPart.Parent = workspace
end
