Part Orientation Relative Grid Snap Confusion | Placement System

Hey, how’s it going? Today I have an issue that I have not been able to solve for the past 3 days surprisingly and am running out of patience to solve it on my own and so now that we are all caught up lol here is my issue…

The goal to this is to add local part relative snapping with the object still being able to be reflected with the normal face of any object with even or odd whole numbers ( I can do that part) but the snapping as been an issue for parts other than the standard basepart.

Alrighty, now here is a video prieview of the grid snap video “working” and another video of it just reflecting off the normal face

grid:

no grid:

Current code without implementation of grid:

local function RoundTo(n, to)
	local to = to or 1
	if to == 0 then return n end
	return math.floor(n/to + 0.5) * to
end

local function SnapToGrid(vector3)
	return CFrame.new(
		RoundTo(vector3.X, GridSize),
		RoundTo(vector3.Y, GridSize),
		RoundTo(vector3.Z, GridSize)
	)
end

function NearestAxis(Direction)
	local Axis = math.max(math.abs(Direction.X), math.abs(Direction.Y), math.abs(Direction.Z))
	
	if Axis == Direction.X then
		return Enum.Axis.X
	elseif Axis == Direction.Y then
		return Enum.Axis.Y
	end
	
	return Enum.Axis.Z
end


function NormalOffset(NormalCFrame, Normal)
	local FilterAxis = Vector3.FromAxis(NearestAxis(Model.CFrame:VectorToObjectSpace(Normal)))
	local RelativeOffset = (Model.Size * FilterAxis).Magnitude * 0.5
	return NormalCFrame + (Normal * RelativeOffset)
end


local function GetMousePlacementCFrame(HitNormal, Normal, HitCFrame, NewInstance)
	local RelativeOffset = NormalOffset(HitNormal, Normal)
	
	--local HitInstanceRelative = HitCFrame:ToObjectSpace(RelativeOffset)
	--local MouseHitWorldSnap =  HitCFrame * SnapToGrid(HitInstanceRelative)
	
	--local HitInstanceRelative2 = HitNormal:ToObjectSpace(RelativeOffset)
	--local MouseHitWorldSnap2 = HitNormal * SnapToGrid(HitInstanceRelative2)
	
	local Combine = RelativeOffset --+ (MouseHitWorldSnap.Position - MouseHitWorldSnap2.Position)
	
	Model.CFrame = Combine * orientation

end

I am nearing the end of ideas on how to solve this so if anyone could push me in the right direction or even supply a small example it would be very much appreciated, thank you.

3 Likes

The grid system you’re using appears to be global rather than relative. It will only snap to points of the entire world itself. What you would want to do is create an unique grid for each object, one that is rotated to match the surface normal.

1 Like

I have tried doing this before where the grid was relative but got completely different results, it seems simple which is weird. Get the cframe and add the grid snap with giving it the normal face but i got completely different results which threw me right off and so i removed it all because there was no way to fix it to work with normal face snapping, I have no clue how to do it any other way i have tried endlessly for hours on end and its driving me up the wall, is there any chance you could give me an example?

1 Like

What do you mean by “completely different results”? Because the grid for each surface normal is unique, they would all be different from each other. Because the grid size is constant yet the actual area changes for each surface, they would never match up.

This is how I would imagine the process if optimization didn’t matter:

  • Create a CFrame with the matching rotation right on the surface of the part in question
  • Create a grid organized into a table by multiplying that CFrame with different offsets (which are also CFrames)
  • Iterate through the table to find the point that is closest to ray.Position, that’s the position to round to

What i meant was it would rarely ever work for any of the faces and wouldnt match the part to the face

this could work but i am working towards a method that is optimized. another solution i was thinking of is since the code that i currently have works perfectly with basepart bricks, i could create a fake face that overlaps the one the mouse points at and keeps the rotation of the face reflection and since I already showed the gridsnap for baseparts working it should work nicely, what do you think?

Sounds like it would work, although I’m still not entirely sure about the method of snapping it to the grid like that since they’re all rotated. Depending on the size of the grid, it can be really slow when using the table iteration method.

Edit: perhaps K-D tree k-d tree - Wikipedia

2 Likes

Ah i see where you are coming from but it seems like that would still be needing to use points for the K-D tree, I’ll do a bit of experimenting with this in mind so thank you, i will message you again if i have any more questions

I fixed the issue a couple days ago and forgot to comment, the placement system is finished though which is nice, as for now I am going to be open sourcing this soon in the future because it is a bit complicating to explain

heres the vid of all of it together

1 Like