Advertisement
CloneTrooper1019

Roblox Mesh to OBJ

Sep 6th, 2017
1,512
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.13 KB | None | 0 0
  1. ---------------------------------------------------------------------------------------------------------------------------------------
  2. -- @CloneTrooper1019, 2017
  3. -- Mesh2obj.lua
  4. -- This script converts Roblox's mesh format into a .obj file
  5. -- Written for Dawgra, with the intent of recovering the meshes stored in this model:
  6. -- https://www.roblox.com/library/12468931/Reason-2-Die-Meshpack-2
  7. ---------------------------------------------------------------------------------------------------------------------------------------
  8. --[[
  9.  
  10. ~ CONTEXT OF CREATION ~
  11.  
  12. In 2009, Roblox used to have a "feature" (hack) where you could store a content file directly inside of their .rbxm format if you
  13. encoded the content into a base64 string, and put it inside of <binary></binary> tags. This was probably intended to be for
  14. debugging purposes, but some clever users at the time discovered this feature and utilized it to inject meshes into Roblox long before
  15. uploading meshes was even a feature. The problem here was that you could inject basically any arbitrary data into Roblox, which in turn
  16. allowed users to bypass moderation. Thus Roblox removed the feature and user meshes were no more (until mid 2016).
  17.  
  18. To recover those meshes with this script:
  19. 01: Save the model that contains the mesh binary data as a .rbxmx file
  20. 02: In a text editor, strip out all the XML text until you're just left with the base64 encoded string
  21. 03: Paste the base64 content onto a website that decodes base64 data into it's raw binary data
  22. 04: Copy the decoded file and paste it onto pastebin
  23. 05: Get the raw url for that paste and replace the meshDataUrl with that url.
  24. 06: Copy this code into a Script in Roblox Studio
  25. 07: Run the game and copy the contents of the output. Make sure you get rid of extra prints, such as the Auto-Save print.
  26. 08: Paste that into a new file and save it as a .obj file
  27. 09: Import the mesh into Blender or whatever mesh editing tool you use.
  28. 10: Save the mesh as a .FBX file
  29. 11: Add a MeshPart to the Workspace, and upload the .FBX mesh
  30.  
  31. Congratulations, you have recovered the mesh!
  32.  
  33. ]]--
  34. ---------------------------------------------------------------------------------------------------------------------------------------
  35.  
  36. local HttpService = game:GetService("HttpService")
  37. local meshDataUrl = "https://pastebin.com/raw/dH43Yvn7"
  38.  
  39. local meshData = HttpService:GetAsync(meshDataUrl)
  40. local readLine = meshData:gmatch("[^\r\n]+")
  41.  
  42. -- Read mesh file
  43. local version = readLine()
  44. assert(version:sub(1,9) == "version 1","Unsupported version " .. version)
  45.  
  46. local meshScale = 0.5
  47. if version == "version 1.01" then
  48.     meshScale = 1
  49. end
  50.  
  51. local numFaces = tonumber(readLine())
  52. assert(numFaces,"number of faces not specified!")
  53.  
  54. local data = readLine()
  55. local readChar = data:gmatch(".")
  56. local meshFaces = {}
  57.  
  58. local function seek(token)
  59.     local read = ""
  60.     while true do
  61.         local char = readChar()
  62.         if char == token then
  63.             break
  64.         elseif char == nil then
  65.             error("Reached end of data stream prematurely while seeking token: " .. token)
  66.         end
  67.         read = read .. char
  68.     end
  69.     return tonumber(read)
  70. end
  71.  
  72. local function readVector3(scale)
  73.     local scale = scale or 1
  74.     local x,y,z
  75.     seek("[")
  76.     x = seek(",")
  77.     y = seek(",")
  78.     z = seek("]")
  79.     return Vector3.new(x,y,z) * scale
  80. end
  81.  
  82. for faceId = 1,numFaces do
  83.     local face = {}
  84.     face.Vertices = {}
  85.     face.Normals = {}
  86.     face.UVs = {}
  87.     for i = 1,3 do
  88.         face.Vertices[i] = readVector3(meshScale)
  89.         face.Normals[i] = readVector3()
  90.         face.UVs[i] = readVector3()
  91.     end
  92.     meshFaces[faceId] = face
  93. end
  94.  
  95. -- Dump as .obj
  96.  
  97. local v3Format = "%s %s %s %s"
  98. local faceFormat = "\nf %s/%s/%s %s/%s/%s %s/%s/%s"
  99.  
  100. local function writeVector3(v3,tag)
  101.     print(v3Format:format(tag,v3.X,v3.Y,v3.Z))
  102. end
  103.  
  104. local function writeFace(faceIndex)
  105.     local r = (faceIndex-1)*3
  106.     local a,b,c = r+1,r+2,r+3
  107.     print(faceFormat:format(a,a,a,b,b,b,c,c,c))
  108. end
  109.  
  110. print("g Mesh")
  111.  
  112. for faceIndex,face in ipairs(meshFaces) do
  113.     for i = 1,3 do
  114.         print()
  115.         local v = face.Vertices[i]
  116.         writeVector3(v,"v")
  117.         local n = face.Normals[i]
  118.         writeVector3(n,"vn")
  119.         local t = face.UVs[i]
  120.         writeVector3(t,"vt")
  121.     end
  122.     writeFace(faceIndex)
  123. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement