Having Problems With Object Relative and Surface Normal CFrames

Hello DevForum,

So recently I’ve been working on something that can get the surface size of practically any object; however, I ran into an issue with getting the surface center rotated CFrame for rotated objects. I think that I am very close to figuring it out but I’ve been stuck on it for a couple days from working on it on and off. Another mind to help me with this would be very beneficial to save time. Let me provide some context…

Here is a video detailing my current progress:

Here is my code for this example:

local function GetSurfaceInfo(HitNormal, HitInstance)
	local Offset = HitInstance.Size.Magnitude * 2

	local BackRay = CFrame.new(HitInstance.Position) * CFrame.Angles(HitNormal:ToEulerAnglesXYZ())
	local LookDirection = BackRay * CFrame.new(0,0,-Offset)

	FaceCenterParams.FilterDescendantsInstances = {HitInstance}
	FaceCenterParams.FilterType = Enum.RaycastFilterType.Whitelist

	local RayResult = workspace:Raycast(LookDirection.Position, LookDirection.LookVector * -(Offset + 1), FaceCenterParams)
	if not RayResult then return end

	local SurfaceCenter = CFrame.new(RayResult.Position, RayResult.Position + RayResult.Normal)

	local SurfaceSize, SurfaceCFrame, CornerCFrame = GetSurfaceSize(SurfaceCenter, Offset, HitInstance.CFrame)

	Part.CFrame = SurfaceCenter --

	return SurfaceSize, SurfaceCFrame, CornerCFrame, LookDirection
end

From my hypothesis, I assume that I may be able to get the normal rotation from the object’s ObjectSpace given the HitNormal CFrame. Here is an example of that working:

While this does work, it does not give me the outward lookvector from the given raycast normal.

Here is my code for this example:

local function GetSurfaceInfo(HitNormal, HitInstance)
	local Offset = HitInstance.Size.Magnitude * 2

	local BackRay = CFrame.new(HitInstance.Position) * CFrame.Angles(HitNormal:ToEulerAnglesXYZ())
	local LookDirection = BackRay * CFrame.new(0,0,-Offset)

	FaceCenterParams.FilterDescendantsInstances = {HitInstance}
	FaceCenterParams.FilterType = Enum.RaycastFilterType.Whitelist

	local RayResult = workspace:Raycast(LookDirection.Position, LookDirection.LookVector * -(Offset + 1), FaceCenterParams)
	if not RayResult then return end

	local HitNormal2 = CFrame.new(RayResult.Position, RayResult.Position + RayResult.Normal)

	local ObjectRelativeRotatation  = HitInstance.CFrame:ToObjectSpace(HitNormal2)
	local SurfaceCenter = HitInstance.CFrame:ToWorldSpace(CFrame.new(ObjectRelativeRotatation.Position))

	local SurfaceSize, SurfaceCFrame, CornerCFrame = GetSurfaceSize(SurfaceCenter, Offset, HitInstance.CFrame)

	Part.CFrame = SurfaceCenter --

	return SurfaceSize, SurfaceCFrame, CornerCFrame, LookDirection
end

If you have any questions please ask, I plan on creating this as an open source once i get this part figured out.

Thanks,
Tave

Still having issues with no major progress

So the issue is the rotation right?

The issue here is the lack of information as you cannot construct the surface information with just the surface normal and surface position. You would also need to know the vertices of the surface if you want the rectangle to be parallel to the sides of the surface in order for it to match up.

image

For example according to the figure above you would need to know that the surface selected is the slanted surface (You should be able to do this using the point and plane formula). Then get the vectors for p1 → p2 and p1 → p3 to make it parallel with the edges.

ahh, vertices. That’s what I wasn’t thinking of. I’ll give this a try and let you know how it goes. I propose the best way to get these vertices is from raycasting

1 Like

I had an idea as to how I was going to get the edges and corners only to realize that I run into the same issue as raycasting for the edge doesnt make it relative to the rotation of the part. Do you have any ideas?

the red is where it was supposed to align with the edge but it doesnt know the rotation of the part which defeats my method of determining those points

image