Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

Creating a Region3 around a model?

Asked by 7 years ago

How would I go about creating a Region3 around a model? Right now, I have this, but it doesn't go around the entire model:


local function getC(obj, t) if obj:IsA("Model") or obj:IsA("Folder") then return getC(obj:GetChildren()[1], t) end if obj:IsA("BasePart") then if t=="X" then if obj.Position.X >= 0 then return obj.Position.X + (obj.Size.X/2) else return obj.Position.X - (obj.Size.X/2) end elseif t=="Y" then if obj.Position.Y >= 0 then return obj.Position.Y + (obj.Size.Y/2) else return obj.Position.Y - (obj.Size.Y/2) end elseif t=="Z" then if obj.Position.Z >= 0 then return obj.Position.Z + (obj.Size.Z/2) else return obj.Position.Z - (obj.Size.Z/2) end end end return false end for _,v in pairs(model:GetChildren()) do local gX = 0 local gY = 0 local gZ = 0 local gXl = 1000000000 local gYl = 1000000000 local gZl = 1000000000 for _,q in pairs(v:GetChildren()) do x = getC(q, "X") y = getC(q, "Y") z = getC(q, "Z") if x then if x > gX then gX = x end if x < gXl then gXl = x end end if y then if y > gY then gY = y end if y < gYl then gYl = y end end if z then if z > gZ then gZ = z end if z < gZl then gZl = z end end end local uc = Vector3.new(gX+1000, gY+250, gZl+1000) --uppercorner local lc = Vector3.new(gXl-1000, gYl-250, gZl-1000) --lowercorner local tbl = { ["model"] = v, ["region3"] = Region3.new(uc,lc), ["upper"] = uc, ["lower"] = lc } table.insert(_G.rs, tbl) end

Any help is appreciated.

1 answer

Log in to vote
2
Answered by
XAXA 1569 Moderation Voter
7 years ago
Edited 7 years ago
function GetModelAABB(model)
    local modelMin = nil
    local modelMax = nil
    for _, v in pairs(model:GetChildren()) do
        if v:IsA("BasePart") then
            local cf = v.CFrame
            local size = v.Size
            local baseCf = cf * CFrame.new(-size/2)
            for x = 0, 1 do
                for y = 0, 1 do
                    for z = 0, 1 do
                        local testCorner = (baseCf * CFrame.new( size * Vector3.new(x, y, z))).p

                        if not modelMin then
                            modelMin = testCorner
                        end

                        if not modelMax then
                            modelMax = testCorner
                        end

                        modelMin = Vector3.new(
                            math.min(modelMin.x, testCorner.x),
                            math.min(modelMin.y, testCorner.y),
                            math.min(modelMin.z, testCorner.z)
                        )
                        modelMax = Vector3.new(
                            math.max(modelMax.x, testCorner.x),
                            math.max(modelMax.y, testCorner.y),
                            math.max(modelMax.z, testCorner.z)
                        )   
                    end
                end
            end
        end
    end

    return Region3.new(modelMin, modelMax)
end

This returns a Region3 that hugs the model.

Get each corner of each part in the model, and get the minimum/maximum in each dimension. Return a Region3 made out of these. I have not run this, but in theory this should work. Make sure model is actually a model, otherwise this will error.

EDIT: Also, parts are not examined recursively. You may want to modify this so that it does.

EDITEDIT: Tested and found a missing parenthesis. It works.

1
Thank you! If I had the reputation to upvote, I would. This was exactly what I was looking for. BreadyToCrumble 121 — 7y
0
I appreciate that you at least tried, though. XAXA 1569 — 7y
0
This is already a core function, model:GetExtentsSize(). It's not perfect, but yours is even less so. cabbler 1942 — 7y
1
@cabbler GetExtentsSize only gives me the size of the box around the model, it doesn't return the actual region. BreadyToCrumble 121 — 7y
View all comments (2 more)
0
"It's not perfect, but yours is even less so." I highly doubt that. Do you have any proof? My implementation covers the definition of an axis-aligned bounding box (it's as good as we're going to get in Roblox, anyway, without getting the vertices of a mesh). Moreover, GetExtentsSize() is dependent on the rotation of a model's PrimaryPart (which is arbitrary), and rotations are no good for Region3s XAXA 1569 — 7y
0
Excellent, thanks! I've been struggling for ages trying to line up models and non of the built in functions seem to be up to the task! Even just trying to put a 'car ON the road' is a nightmare! Spedley2142 0 — 6y
Ad

Answer this question