From b1ffc112b625b69cc797dc3e3de17a758c581abf Mon Sep 17 00:00:00 2001 From: Lewin Kelly Date: Fri, 22 Mar 2024 23:03:37 +0000 Subject: [PATCH] Refactor renderscripts, begin rendering for meshes, models, and hats --- Modules/Render.luau | 75 --------------------------------- Modules/Render/SetupAvatar.luau | 24 +++++++++++ Modules/Render/init.luau | 46 ++++++++++++++++++++ defs.d.lua | 5 ++- luau/join.luau | 2 +- luau/renderAvatar.luau | 17 +++++--- luau/renderClothing.luau | 13 ++++-- luau/renderMesh.luau | 22 ++++++++++ luau/renderModel.luau | 20 +++++++++ 9 files changed, 137 insertions(+), 87 deletions(-) delete mode 100644 Modules/Render.luau create mode 100644 Modules/Render/SetupAvatar.luau create mode 100644 Modules/Render/init.luau create mode 100644 luau/renderMesh.luau create mode 100644 luau/renderModel.luau diff --git a/Modules/Render.luau b/Modules/Render.luau deleted file mode 100644 index 5e64bb9..0000000 --- a/Modules/Render.luau +++ /dev/null @@ -1,75 +0,0 @@ -local HttpService = game:GetService "HttpService" -local ScriptContext = game:GetService "ScriptContext" -local Players = game:GetService "Players" -local ContentProvider = game:GetService "ContentProvider" -local InsertService = game:GetService "InsertService" - -local function post(url: string, body: string) - -- We have to lie about the contentType to avoid being nuked by CORS from the website - game:HttpPost(url, body, true, "text/json") -end - -return function(baseUrl: string, pingUrl: string, thumbnailKey: string) - local Render = {} - - function Render.SetupAvatar( - renderType: string, - assetId: string, - characterAppearance: string - ) - pcall(function() - ContentProvider:SetBaseUrl(baseUrl) - InsertService:SetAssetUrl(`{baseUrl}/asset?id=%d`) - InsertService:SetAssetVersionUrl( - `{baseUrl}/asset?assetversionid=%d` - ) - end) - - HttpService.HttpEnabled = true - ScriptContext.ScriptsDisabled = true - - print( - `[{game.JobId}] Starting new render for {renderType} ID {assetId}` - ) - post( - `{pingUrl}/{game.JobId}?apiKey={thumbnailKey}`, - "Rendering" - ) - - local player = Players:CreateLocalPlayer(0) - player.CharacterAppearance = baseUrl .. characterAppearance .. assetId - player:LoadCharacter(false) - - -- Raise up the character's arm if they have gear. - local gear = player.Backpack:GetChildren()[1] - if gear then - gear.Parent = player.Character - player.Character.Torso["Right Shoulder"].CurrentAngle = math.rad(90) - end - - return player - end - - function Render.Upload(result: string) - for i = 1, 3 do - local ok, err = pcall(function() - post( - `{pingUrl}/{game.JobId}?apiKey={thumbnailKey}`, - result - ) - end) - if ok then - print(`[{game.JobId}] Upload successful! Moving on...`) - break - elseif i == 3 then - print(`[{game.JobId}] An error occurred! ({err}). Giving up...`) - break - end - print( - `[{game.JobId}] An error occurred! ({err}). Uploading again...` - ) - end - end - - return Render -end diff --git a/Modules/Render/SetupAvatar.luau b/Modules/Render/SetupAvatar.luau new file mode 100644 index 0000000..5ee20a9 --- /dev/null +++ b/Modules/Render/SetupAvatar.luau @@ -0,0 +1,24 @@ +--!strict + +local Players = game:GetService "Players" + +return function( + baseUrl: string, + renderType: string, + assetId: number, + characterAppearance: string +) + print(`[{game.JobId}] Starting new render for {renderType} Id {assetId}`) + local player = Players:CreateLocalPlayer(0) + player.CharacterAppearance = baseUrl .. characterAppearance .. assetId + player:LoadCharacter(false) + + -- Raise up the character's arm if they have gear. + local gear = player.Backpack:GetChildren()[1] + if gear then + gear.Parent = player.Character + player.Character.Torso["Right Shoulder"].CurrentAngle = math.rad(90) + end + + return player +end diff --git a/Modules/Render/init.luau b/Modules/Render/init.luau new file mode 100644 index 0000000..d4cdb1a --- /dev/null +++ b/Modules/Render/init.luau @@ -0,0 +1,46 @@ +--!strict + +local HttpService = game:GetService "HttpService" +local ScriptContext = game:GetService "ScriptContext" +local ContentProvider = game:GetService "ContentProvider" +local InsertService = game:GetService "InsertService" + +local function post(url: string, body: string) + -- We have to lie about the contentType to avoid being nuked by CORS from the website + game:HttpPost(url, body, true, "text/json") +end + +return function(baseUrl: string, pingUrl: string, thumbnailKey: string) + local Render = {} + + pcall(function() + ContentProvider:SetBaseUrl(baseUrl) + InsertService:SetAssetUrl(`{baseUrl}/asset?id=%d`) + InsertService:SetAssetVersionUrl(`{baseUrl}/asset?assetversionid=%d`) + end) + + HttpService.HttpEnabled = true + ScriptContext.ScriptsDisabled = true + + post(`{pingUrl}/{game.JobId}?apiKey={thumbnailKey}`, "Rendering") + + function Render.Upload(result: string) + for i = 1, 3 do + local ok, err = pcall(function() + post(`{pingUrl}/{game.JobId}?apiKey={thumbnailKey}`, result) + end) + if ok then + print(`[{game.JobId}] Upload successful! Moving on...`) + break + elseif i == 3 then + print(`[{game.JobId}] An error occurred! ({err}). Giving up...`) + break + end + print( + `[{game.JobId}] An error occurred! ({err}). Uploading again...` + ) + end + end + + return Render +end diff --git a/defs.d.lua b/defs.d.lua index c0db1c2..13df79b 100644 --- a/defs.d.lua +++ b/defs.d.lua @@ -6551,6 +6551,7 @@ declare class Player extends Instance CanLoadCharacterAppearance: boolean Character: Model? CharacterAdded: RBXScriptSignal + CharacterAppearance: string CharacterAppearanceId: number CharacterAppearanceLoaded: RBXScriptSignal CharacterRemoving: RBXScriptSignal @@ -6611,7 +6612,7 @@ declare class Player extends Instance function IsInGroup(self, groupId: number): boolean function IsVerified(self): boolean function Kick(self, message: string?): nil - function LoadCharacter(self): nil + function LoadCharacter(self, inGame: boolean): nil function LoadCharacterBlocking(self): nil function Move(self, walkDirection: Vector3, relativeToCamera: boolean?): nil function RemoveCharacter(self): nil @@ -7131,7 +7132,7 @@ declare class ServerStorage extends Instance end declare class ThumbnailGenerator extends Instance - function Click(self, format: string, x: number, y: number, hideSky: boolean): string + function Click(self, format: "PNG" | "OBJ", x: number, y: number, hideSky: boolean, crop: boolean?): string end declare class ServiceProvider extends Instance diff --git a/luau/join.luau b/luau/join.luau index a94d201..b3c49b3 100644 --- a/luau/join.luau +++ b/luau/join.luau @@ -265,7 +265,7 @@ if not success then end -- TODO: Async get? -loadfile ""("", -1, 0) +-- loadfile ""("", -1, 0) -- wtf pcall(function() game:SetScreenshotInfo "" diff --git a/luau/renderAvatar.luau b/luau/renderAvatar.luau index 4eb0a15..8c63d8d 100644 --- a/luau/renderAvatar.luau +++ b/luau/renderAvatar.luau @@ -1,12 +1,18 @@ +--!strict -- Render script for R6 avatars local ThumbnailGenerator = game:GetService "ThumbnailGenerator" -local RenderModule = require "../Modules/Render.luau" -local New = (require "../Modules/New").New +local RenderModule = require "../Modules/Render" +local SetupAvatar = require "../Modules/Render/SetupAvatar" local Render = RenderModule(_BASE_URL, _PING_URL, _THUMBNAIL_KEY) -- avoid ambiguous syntax after compilation +local New = (require "../Modules/New").New -local player = - Render.SetupAvatar(_RENDER_TYPE, _ASSET_ID, `/asset/characterfetch?userID=`) +local player = SetupAvatar( + _BASE_URL, + _RENDER_TYPE, + _ASSET_ID, + "/asset/characterfetch?userID=" +) local clickBody = ThumbnailGenerator:Click("PNG", 1680, 1680, true) @@ -19,14 +25,13 @@ local CameraAngle = player.Character.Head.CFrame local CameraPosition = CameraAngle + CFrame.Angles(0, math.pi, 0).lookVector.unit * 2.75 -local Camera = New "Camera" { +workspace.CurrentCamera = New "Camera" { Name = "ThumbnailCamera", CameraType = Enum.CameraType.Scriptable, CoordinateFrame = CFrame.new(CameraPosition.p, CameraAngle.p), FieldOfView = 52.5, Parent = player.Character, } -workspace.CurrentCamera = Camera local clickHead = ThumbnailGenerator:Click("PNG", 300, 300, true) diff --git a/luau/renderClothing.luau b/luau/renderClothing.luau index 2a225b7..bad85b7 100644 --- a/luau/renderClothing.luau +++ b/luau/renderClothing.luau @@ -1,13 +1,20 @@ +--!strict -- Render script for R6 clothing local ThumbnailGenerator = game:GetService "ThumbnailGenerator" -local RenderModule = require "../Modules/Render.luau" +local RenderModule = require "../Modules/Render" +local SetupAvatar = require "../Modules/Render/SetupAvatar" local Render = RenderModule(_BASE_URL, _PING_URL, _THUMBNAIL_KEY) -- avoid ambiguous syntax after compilation -Render.SetupAvatar(_RENDER_TYPE, _ASSET_ID, `/api/render/characterasset?id=`) +SetupAvatar( + _BASE_URL, + _RENDER_TYPE, + _ASSET_ID, + "/api/render/characterasset?id=" +) local click = ThumbnailGenerator:Click("PNG", 1680, 1680, true) -print(`[{game.JobId}] Successfully rendered, moving on...`) +print(`[{game.JobId}] Successfully rendered clothing`) Render.Upload(`Completed\n{click}`) diff --git a/luau/renderMesh.luau b/luau/renderMesh.luau new file mode 100644 index 0000000..b1d7590 --- /dev/null +++ b/luau/renderMesh.luau @@ -0,0 +1,22 @@ +--!strict +-- Render script for meshes + +local ThumbnailGenerator = game:GetService "ThumbnailGenerator" +local RenderModule = require "../Modules/Render" +local Render = RenderModule(_BASE_URL, _PING_URL, _THUMBNAIL_KEY) -- avoid ambiguous syntax after compilation +local New = (require "../Modules/New").New + +print(`[{game.JobId}] Starting new render for {_RENDER_TYPE} Id {_ASSET_ID}`) + +New "Part" { + Parent = workspace, + New "SpecialMesh" { + MeshId = `{_BASE_URL}/asset?id={_ASSET_ID}`, + }, +} + +local click = ThumbnailGenerator:Click("PNG", 1024, 1024, true) + +print(`[{game.JobId}] Successfully rendered mesh`) + +Render.Upload(`Completed\n{click}`) diff --git a/luau/renderModel.luau b/luau/renderModel.luau new file mode 100644 index 0000000..e08d6be --- /dev/null +++ b/luau/renderModel.luau @@ -0,0 +1,20 @@ +--!strict +-- Render script for models (and hats) + +local ThumbnailGenerator = game:GetService "ThumbnailGenerator" +local RenderModule = require "../Modules/Render" +local Render = RenderModule(_BASE_URL, _PING_URL, _THUMBNAIL_KEY) -- avoid ambiguous syntax after compilation + +print(`[{game.JobId}] Starting new render for {_RENDER_TYPE} Id {_ASSET_ID}`) + +for _, object in pairs(game:GetObjects(`{_BASE_URL}/asset?id={_ASSET_ID}`)) do + pcall(function() + object.Parent = workspace + end) +end + +local click = ThumbnailGenerator:Click("PNG", 1024, 1024, true) + +print(`[{game.JobId}] Rendered model`) + +Render.Upload(`Completed\n{click}`)