1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- local function isOutside(bounds, controlPoint)
- local relativePosition = bounds.CFrame:PointToObjectSpace(controlPoint)
- local xDist = math.abs(relativePosition.X)
- local yDist = math.abs(relativePosition.Y)
- local zDist = math.abs(relativePosition.Z)
-
- if xDist > bounds.Size.X/2 then
- return true
- elseif yDist > bounds.Size.Y/2 then
- return true
- elseif zDist > bounds.Size.Z/2 then
- return true
- end
-
- return false
- end
- local function clampPointToBounds(bounds, controlPoint)
- local relativePosition = bounds.CFrame:PointToObjectSpace(controlPoint)
-
- local clampedPosition = Vector3.new(
- math.clamp(relativePosition.X, -bounds.Size.X/2, bounds.Size.X/2),
- math.clamp(relativePosition.Y, -bounds.Size.Y/2, bounds.Size.Y/2),
- math.clamp(relativePosition.Z, -bounds.Size.Z/2, bounds.Size.Z/2)
- )
-
- return bounds.CFrame * CFrame.new(clampedPosition)
- end
- local function getClosestEdgePointXZ(board, controlPoint)
- local relativeControlPos = board.CFrame:PointToObjectSpace(controlPoint) * Vector3.new(1,0,1)
- local boardSize = board.Size
-
- local xzConstrained = (board.CFrame * CFrame.new(relativeControlPos)).Position
-
- if isOutside(board,xzConstrained) then
- return clampPointToBounds(board, xzConstrained) * CFrame.new(0,boardSize.Y/2,0)
- end
-
- -- get the positions on x axis of left and right edges
- local leftEdgePos = -(boardSize.X/2)
- local rightEdgePos = (boardSize.X/2)
- -- do the same for top and bottom but on z axis
- local frontEdgePos = -(boardSize.Z/2)
- local backEdgePos = (boardSize.Z/2)
-
- -- get all edge distances
- local leftDist = math.abs(leftEdgePos - relativeControlPos.X)
- local rightDist = math.abs(rightEdgePos - relativeControlPos.X)
- local frontDist = math.abs(frontEdgePos - relativeControlPos.Z)
- local backDist = math.abs(backEdgePos - relativeControlPos.Z)
-
- -- get distance to closest edge
- local xDist = leftDist < rightDist and leftDist or rightDist
- local zDist = frontDist < backDist and frontDist or backDist
-
- -- get local position of closest edge
- local closestXEdge = leftDist < rightDist and leftEdgePos or rightEdgePos
- local closestZEdge = frontDist < backDist and frontEdgePos or backEdgePos
-
- if xDist < zDist then
- -- x edge is closest
- return board.CFrame * CFrame.new(closestXEdge, boardSize.Y/2, relativeControlPos.Z)
- elseif zDist < xDist then
- -- z edge is closest
- return board.CFrame * CFrame.new(relativeControlPos.X, boardSize.Y/2, closestZEdge)
- elseif xDist == zDist then
- -- both equal distance, use corner
- return board.CFrame * CFrame.new(closestXEdge, boardSize.Y/2, closestZEdge)
- end
- end
|