73 lines
2.1 KiB
Lua
73 lines
2.1 KiB
Lua
local UGCValidationService = game:GetService("UGCValidationService")
|
|
|
|
local root = script.Parent.Parent
|
|
|
|
local Constants = require(root.Constants)
|
|
|
|
local DEFAULT_OFFSET = Vector3.new(0, 0, 0)
|
|
|
|
local function pointInBounds(worldPos, boundsCF, boundsSize)
|
|
local objectPos = boundsCF:pointToObjectSpace(worldPos)
|
|
return objectPos.X >= -boundsSize.X/2
|
|
and objectPos.X <= boundsSize.X/2
|
|
and objectPos.Y >= -boundsSize.Y/2
|
|
and objectPos.Y <= boundsSize.Y/2
|
|
and objectPos.Z >= -boundsSize.Z/2
|
|
and objectPos.Z <= boundsSize.Z/2
|
|
end
|
|
|
|
local function getAttachment(parent, names)
|
|
for _, name in pairs(names) do
|
|
local result = parent:FindFirstChild(name)
|
|
if result then
|
|
return result
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
local function validateMeshBounds(isAsync, instance, assetTypeEnum)
|
|
local assetInfo = Constants.ASSET_TYPE_INFO[assetTypeEnum]
|
|
|
|
-- these are guaranteed to exist thanks to validateInstanceTree being called beforehand
|
|
local handle = instance.Handle
|
|
local mesh = handle:FindFirstChildOfClass("SpecialMesh")
|
|
local attachment = getAttachment(handle, assetInfo.attachmentNames)
|
|
|
|
if mesh.MeshId == "" then
|
|
return false, { "Mesh must contain valid MeshId" }
|
|
end
|
|
|
|
local success, verts = pcall(function()
|
|
if isAsync then
|
|
return UGCValidationService:GetMeshVerts(mesh.MeshId)
|
|
else
|
|
return UGCValidationService:GetMeshVertsSync(mesh.MeshId)
|
|
end
|
|
end)
|
|
|
|
if not success then
|
|
return false, { "Failed to read mesh" }
|
|
end
|
|
|
|
local boundsInfo = assert(assetInfo.bounds[attachment.Name], "Could not find bounds for " .. attachment.Name)
|
|
local boundsSize = boundsInfo.size
|
|
local boundsOffset = boundsInfo.offset or DEFAULT_OFFSET
|
|
local boundsCF = handle.CFrame * attachment.CFrame * CFrame.new(boundsOffset)
|
|
|
|
for _, vertPos in pairs(verts) do
|
|
local worldPos = handle.CFrame:pointToWorldSpace(vertPos * mesh.Scale)
|
|
if not pointInBounds(worldPos, boundsCF, boundsSize) then
|
|
return false, {
|
|
"Mesh is too large!",
|
|
string.format("Max size for type %s is ( %s )", assetTypeEnum.Name, tostring(boundsSize)),
|
|
"Use SpecialMesh.Scale if needed"
|
|
}
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
return validateMeshBounds
|