130 lines
4.0 KiB
Lua
130 lines
4.0 KiB
Lua
-- AvatarAnimation V 1.0.3
|
|
-- Creates a thumbnail from the middle Keyframe of an animation.
|
|
|
|
-- Example arguments:
|
|
-- https://www.sitetest3.robloxlabs.com/Asset/AvatarAccoutrements.ashx?AvatarHash=80dcfa39a8e90f690d2be0e56239abbe&AssetIDs=42900214,32357663,32357631,32357619,32357584,32357558&ResolvedAvatarType=R15,
|
|
-- http://www.sitetest3.robloxlabs.com/,
|
|
-- Png,
|
|
-- 600,
|
|
-- 600,
|
|
-- http://www.sitetest3.robloxlabs.com/Asset/?hash=ca005a9e83ac95bd5068029afdc65496
|
|
|
|
local characterAppearanceUrl, baseUrl, fileExtension, x, y, animationUrl = ...
|
|
|
|
local ThumbnailGenerator = game:GetService("ThumbnailGenerator")
|
|
ThumbnailGenerator:AddProfilingCheckpoint("ThumbnailScriptStarted")
|
|
|
|
pcall(function() game:GetService("ContentProvider"):SetBaseUrl(baseUrl) end)
|
|
game:GetService("ScriptContext").ScriptsDisabled = true
|
|
game:GetService("UserInputService").MouseIconEnabled = false
|
|
|
|
local player = game:GetService("Players"):CreateLocalPlayer(0)
|
|
player.CharacterAppearance = characterAppearanceUrl
|
|
player:LoadCharacterBlocking()
|
|
|
|
ThumbnailGenerator:AddProfilingCheckpoint("PlayerCharacterLoaded")
|
|
|
|
local function getJointBetween(part0, part1)
|
|
for _, obj in pairs(part1:GetChildren()) do
|
|
if obj:IsA("Motor6D") and obj.Part0 == part0 then
|
|
return obj
|
|
end
|
|
end
|
|
end
|
|
|
|
local function applyR15Pose(character, poseKeyframe)
|
|
local function recurApplyPoses(parentPose, poseObject)
|
|
if parentPose then
|
|
local joint = getJointBetween(character[parentPose.Name], character[poseObject.Name])
|
|
joint.C1 = joint.C1 * poseObject.CFrame:inverse()
|
|
end
|
|
for _, subPose in pairs(poseObject:GetSubPoses()) do
|
|
recurApplyPoses(poseObject, subPose)
|
|
end
|
|
end
|
|
|
|
for _, poseObj in pairs(poseKeyframe:GetPoses()) do
|
|
recurApplyPoses(nil, poseObj)
|
|
end
|
|
end
|
|
|
|
local animationObjects = game:GetObjects(animationUrl)
|
|
|
|
local poseAnimation = nil
|
|
local animations = {}
|
|
local rotateCharacter = false
|
|
local thumbnailCamera = nil
|
|
|
|
local function getAnimations(model)
|
|
for _, child in pairs(model:GetChildren()) do
|
|
if child:IsA("Animation") then
|
|
if string.lower(model.Name) == "pose" then
|
|
poseAnimation = child
|
|
else
|
|
table.insert(animations, child)
|
|
end
|
|
else
|
|
getAnimations(child)
|
|
end
|
|
|
|
if child:IsA("Camera") and child.Name == "ThumbnailCamera" then
|
|
thumbnailCamera = child:Clone()
|
|
end
|
|
|
|
if child:IsA("StringValue") and child.Name == "swim" then
|
|
rotateCharacter = true
|
|
end
|
|
end
|
|
end
|
|
|
|
for _, animationModel in pairs(animationObjects) do
|
|
getAnimations(animationModel)
|
|
end
|
|
|
|
local KeyframeSequenceProvider = game:GetService("KeyframeSequenceProvider")
|
|
local keyframes = {}
|
|
|
|
if poseAnimation then
|
|
local kfs = KeyframeSequenceProvider:GetKeyframeSequence(poseAnimation.AnimationId)
|
|
local animKeyframes = kfs:GetKeyframes()
|
|
for _, keyframe in pairs(animKeyframes) do
|
|
table.insert(keyframes, keyframe)
|
|
end
|
|
else
|
|
for _, animation in pairs(animations) do
|
|
local kfs = KeyframeSequenceProvider:GetKeyframeSequence(animation.AnimationId)
|
|
local animKeyframes = kfs:GetKeyframes()
|
|
for _, keyframe in pairs(animKeyframes) do
|
|
table.insert(keyframes, keyframe)
|
|
end
|
|
end
|
|
end
|
|
|
|
ThumbnailGenerator:AddProfilingCheckpoint("AnimationsLoaded")
|
|
|
|
local keyframe = keyframes[math.max(1, math.floor(#keyframes/2))]
|
|
applyR15Pose(player.Character, keyframe)
|
|
|
|
if rotateCharacter then
|
|
local rootPart = player.Character:FindFirstChild("HumanoidRootPart")
|
|
if rootPart then
|
|
rootPart.CFrame = rootPart.CFrame * CFrame.Angles(math.rad(-90), 0, 0)
|
|
if not thumbnailCamera then
|
|
local camera = Instance.new("Camera")
|
|
camera.Name = "ThumbnailCamera"
|
|
|
|
local rotatedCameraOffset = Vector3.new(6, 5, 7) * .7
|
|
camera.CFrame = CFrame.new(Vector3.new(rootPart.Position.X, rootPart.Position.Y, rootPart.Position.Z) - rotatedCameraOffset, rootPart.Position)
|
|
camera.Parent = player.Character
|
|
end
|
|
end
|
|
end
|
|
|
|
if thumbnailCamera then
|
|
thumbnailCamera.Parent = player.Character
|
|
end
|
|
|
|
local result, requestedUrls = game:GetService("ThumbnailGenerator"):Click(fileExtension, x, y, --[[hideSky = ]] true)
|
|
ThumbnailGenerator:AddProfilingCheckpoint("ThumbnailGenerated")
|
|
|
|
return result, requestedUrls |