Clamping rotated objects to bounds

I’m making a placing system and I created a clamping system, the problem comes when I add rotation because the clamping system ignores rotation, I got a kind of solution from here, it apparently works but I found a bug that I can’t figure out how to fix

Bug video:

Basically if the part it’s rotated, the bigger side( in this case X ) doesn’t fit with the bounds, I think it thinks it’s still the Z side because it’s rotated but I don’t know how to add the offset that the position needs, I don’t will use any “bad habit” like using a boolean to detect because I want it to work with all settings without editing the script to fit my needs.

This is the code

local function getModelBounds()
    local primary = model.PrimaryPart:Clone()
    primary.Name = "fake_primary"
    primary.Parent = model
    
    local originalCF = model:GetPrimaryPartCFrame()
    primary.CFrame = CFrame.new(originalCF.Position) * CFrame.Angles(0, pi, 0)
    local ori, siz = model:GetBoundingBox()
    primary:Destroy()
    
    return siz
end

local function snapToGrid(vector, size, plotSize, snap)
    local x = math.floor((vector.X / snap) + 0.5) * snap
    x = math.clamp(
        x,
        (-plotSize / 2) + (size.X / 2),
        (plotSize / 2) - (size.X / 2)
    )
    
    --
    
    local y = math.clamp(
        vector.Y,
        (canvas.Position.Y + (size.Y + canvas.Size.Y) / 2),
        huge
    )
    
    --
    
    local z = math.floor((vector.Z / snap) + 0.5) * snap
    
    z = math.clamp(
        z,
        (-plotSize / 2) + (size.Z / 2),
        (plotSize / 2) - (size.Z / 2)
    )

    --
    
    local newVector = Vector3.new(
        x,
        y,
        z
    )
    
    return newVector
end

By the way, my math knowledge isn’t very advanced so I think that’s why I can’t figure out a solution.

u could instead get the front and *that by size.Z/2 i think, just do that for front and right since that would be like the size X and Z that works for rotation i think? im not sure i’m not really thinking too much about this im sorry if i coulden’t help thank you for reading

1 Like

I wonder if it’s because your fake_primary is too big, so it’s being included in the bounds. Try changing the fake_primary’s size to 0,0,0 and see what happens.

As you can see in the code, the fake primary it’s just a clone of the main PrimaryPart, and if I change its size to 0,0,0 I won’t be able to get the real size(rotated offset).

(the blue line is the bounding box that the fake primarypart helps to find)
jeje

Also, it only happens on rectangles, cube-shaped models do not have that specific problem because both sides have the same size.

keke

I figured out how to inverse the size for the rotation, if is searching for something similar, here is the solution :slight_smile:

Note: this works with X and Z side (doesn’t matter which is the bigger side, it will work)

local function getModelBounds()
    local primary = model.PrimaryPart:Clone()
    primary.Name = "fake_primary"
    primary.Transparency = 1
    primary.Parent = model
    
    local originalCF = model:GetPrimaryPartCFrame()
    primary.CFrame = CFrame.new(originalCF.Position)
    
    local cf, siz = model:GetBoundingBox()
    local cx,cy,cz = cf:ToEulerAnglesXYZ() -- Gets the first bounding box orientation
    
    local result
    result = siz -- Sets to the first result
    
    if (abs(round(cy)) == 2) then -- If the object is positioned without any visible rotation will throw 2 and -2 but we are using math.abs and math.round
        primary.CFrame = CFrame.new(originalCF.Position) * CFrame.Angles(0, -math.rad(90), 0) -- Inverses the CFrame "pivot"
        local _, s = model:GetBoundingBox() -- gets the new bounding box (size)
        result = vector3( -- We rotated it, so the "Z" is now the "X" and the "Z" is the "X".
            s.Z,
            s.Y,
            s.X
        )
    end
    
    primary:Destroy()
    
    return result
end

I was referring to the fake primary part. I think l, because it’s a clone of the existing part but sits in a different orientation, it is pushing out your boundary further than it should be.

In other words, the real part and fake primary part are orientated in such a way that they create a “t” shape when viewed from above.

If you shrunk the fake part down (while leaving the real part the same), but kept everything else the same, I think it might work without the hack of swapping dimensions.

1 Like

The fake part gives the real bounds of the model to make it fit even if the object it’s rotated but don’t worry, I solved it without doing that, thanks. :slight_smile: