local w={}w.__index=w w.ClassName="\067\070\114\097\109\101\077\105\114\114\111\114"function w.new()local z=setmetatable({},w)return z end function w.SetCFrame(z,w)z._reflectOver=w end function w.Reflect(z,w)local g=z._reflectOver or error("\078\111 \114\101\102\108\101\099\116 \111\118\101\114")local H=g:toObjectSpace(w)local C,x,Q,h,V,q,N,f,S,P,i,Y=H:components()local t=CFrame.new(-C,x,Q,h,-V,-q,-N,f,S,-P,i,Y)return g:toWorldSpace(t)end function w.ReflectVector(z,w)local g=z._reflectOver local H=z._reflectOver:vectorToObjectSpace(w)local C=Vector3.new(-H.x,H.y,H.z)return g:vectorToWorldSpace(C)end function w.ReflectPoint(z,w)local g=z._reflectOver local H=g:pointToObjectSpace(w)local C=Vector3.new(-H.x,H.y,H.z)return g:pointToWorldSpace(C)end function w.ReflectRay(z,w)local g=z:ReflectPoint(w.Origin)local H=z:ReflectVector(w.Direction)return Ray.new(g,H)end return w
--- Mirrors cframe across plane
-- @classmod CFrameMirror

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

function CFrameMirror.new()
	local self = setmetatable({}, CFrameMirror)

	return self
end

--- This is the CFrame that things are reflected over. Reflects over the
-- x axis.
function CFrameMirror:SetCFrame(reflectOver)
	self._reflectOver = reflectOver
end

function CFrameMirror:Reflect(cframe)
	local reflectOver = self._reflectOver or error("No reflect over")

	local relativeCFrame = reflectOver:toObjectSpace(cframe) -- Move to object space.
	local x, y, z,
		r00, r01, r02,
		r10, r11, r12,
		r20, r21, r22 = relativeCFrame:components()

	-- Reflect over the x axis.
	local mirror = CFrame.new(-x, y, z,
		r00,  -r01, -r02,
		-r10, r11,  r12,
		-r20, r21,  r22)

	return reflectOver:toWorldSpace(mirror)
end

function CFrameMirror:ReflectVector(vector)
	local reflectOver = self._reflectOver

	local relative = self._reflectOver:vectorToObjectSpace(vector)
	local mirror = Vector3.new(-relative.x, relative.y, relative.z)

	return reflectOver:vectorToWorldSpace(mirror)
end

function CFrameMirror:ReflectPoint(point)
	local reflectOver = self._reflectOver

	local relative = reflectOver:pointToObjectSpace(point)
	local mirror = Vector3.new(-relative.x, relative.y, relative.z)

	return reflectOver:pointToWorldSpace(mirror)
end

function CFrameMirror:ReflectRay(ray)
	local origin = self:ReflectPoint(ray.Origin)
	local direction = self:ReflectVector(ray.Direction)

	return Ray.new(origin, direction)
end

return CFrameMirror