Angle interpolation for placement system

Hello! I am currently working on updating my fully customization placement module v3 to include a feature that the placement handler v2 that tunicus created includes. The feature I am working on is the angle lerp, where depending on how you move the model, it alters the models angle on X and Z coordinates.

robloxapp-20200624-2320088.wmv (411.6 KB)

Currently the public version of my module does not carry this feature, but I do want to include something similar to it.

I did try to implement this is and did end up getting somewhere, though it didn’t work great.

-- Calculates the position of the object
local function calculateItemLocation()
	x, z = mouse.Hit.X, mouse.Hit.Z
	
	if moveByGrid then
		if x % grid < grid / 2 then
			posX = round(x - (x % grid))
		else
			posX = round(x + (grid - (x % grid)))
		end
		
		if z % grid < grid / 2 then
			posZ = round(z - (z % grid))
		else
			posZ = round(z + (grid - (z % grid)))
		end
		
		if currentRot then
			cx = primary.Size.X / 2
			cz = primary.Size.Z / 2
		else
			cx = primary.Size.Z / 2
			cz = primary.Size.X / 2
		end
	else
		posX = x
		posZ = z
	end
	
	-- HERE
	if interpolation then
		--disX = (posX - round(primary.Position.X)) - primary.Size.X / 2
		disZ = (posZ - round(primary.Position.Z)) + primary.Size.Z / 2
	end
	
	if stackable and mouse.Target then
		posY = calculateYPos(mouse.Target.Position.Y, mouse.Target.Size.Y, primary.Size.Y)
	end
	
	posY = clamp(posY, initialY, maxHeight + initialY)
	
	bounds()
end

local function translateObj()
	if currentState ~= 4 then
		calculateItemLocation() -- this is where disZ is set
		checkHitbox()
		editHitboxColor()
		
		object:SetPrimaryPartCFrame(primary.CFrame:Lerp(cframe(posX, posY, posZ) * cframe(cx, 0, cz) * anglesXYZ(round(sin(disZ * pi / 180) * 8), rot * pi / 180, 0), speed)) 	
		--																											here
	end
end 

It works fine on one axis but as soon as I use add the other axis (z) it constantly rotates the model in a strange way. Here is the code if your interested on how I implemented the other axis here is that code:

-- Calculates the position of the object
local function calculateItemLocation()
	x, z = mouse.Hit.X, mouse.Hit.Z
	
	if moveByGrid then
		if x % grid < grid / 2 then
			posX = round(x - (x % grid))
		else
			posX = round(x + (grid - (x % grid)))
		end
		
		if z % grid < grid / 2 then
			posZ = round(z - (z % grid))
		else
			posZ = round(z + (grid - (z % grid)))
		end
		
		if currentRot then
			cx = primary.Size.X / 2
			cz = primary.Size.Z / 2
			
			if interpolation then
				disX = (floor(posX) - round(primary.Position.X))
				disZ = (floor(posZ) - round(primary.Position.Z))
			end
		else
			cx = primary.Size.Z / 2
			cz = primary.Size.X / 2
		end
	else
		posX = x
		posZ = z
	end
	
	if stackable and mouse.Target then
		posY = calculateYPos(mouse.Target.Position.Y, mouse.Target.Size.Y, primary.Size.Y)
	end
	
	posY = clamp(posY, initialY, maxHeight + initialY)
	
	bounds()
end

-- Sets the position of the object
local function translateObj()
	if currentState ~= 4 then
		calculateItemLocation() -- this is where disZ and disX are set
		checkHitbox()
		editHitboxColor()
		
		object:SetPrimaryPartCFrame(primary.CFrame:Lerp(cframe(posX, posY, posZ) * cframe(cx, 0, cz) * anglesXYZ(round(sin(disZ * pi / 180) * 8), rot * pi / 180, round(sin(disX * pi / 180) * 8)), speed)) 	
		--																											here												here
	end
end

robloxapp-20200625-0021521.wmv (1.0 MB)

It also completely breaks when the model is rotated on the Y axis. My thought was depending on how far the mouse was from the model, it would change the rotation.

If someone understands how this works, could they explain it, or correct my code/math, and or give some resources on this.

Here is the link to my module if you want to test stuff with the rest of the code (it’s not updated to this version though).

Thanks!