InTesting

Mesh Editor Importable Demonstration (VSB)

Oct 4th, 2021 (edited)
290
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.42 KB | None | 0 0
  1. --[[
  2. Mesh Editor:
  3.     Original: https://www.roblox.com/catalog/3076076256/
  4.     CHL's Fork: https://www.roblox.com/catalog/7612497706
  5.  
  6. Note: this whole thing is a fork
  7. ]]
  8.  
  9. local importableMeshEditorV2 = {}
  10. local util = {}
  11. local constants = {}
  12.  
  13.  
  14.  
  15. function util:flipTable(t)
  16.     assert(type(t) == 'table')
  17.  
  18.     local nT = {}
  19.  
  20.     for i, v in next, t do
  21.         nT[v] = i
  22.     end
  23.  
  24.     return nT
  25. end
  26.  
  27. function util:characterSplitifyAndFlip(str)
  28.     return util:flipTable(str:split(''))
  29. end
  30.  
  31. function util:getCharactersInRange(a, b)
  32.     local t = {}
  33.  
  34.     for byte = a:byte(), b:byte() do
  35.         table.insert(t, string.char(byte))
  36.     end
  37.  
  38.     return t
  39. end
  40.  
  41. function util:getCharactersInRangeToString(a, b)
  42.     local t = util:getCharactersInRange(a, b)
  43.     return table.concat(t)
  44. end
  45.  
  46. function util:PositionTriangle(triangle, position1, position2, position3)
  47.     local magnitude1 = (position1 - position2).Magnitude
  48.     local magnitude2 = (position2 - position3).Magnitude
  49.     local magnitude3 = (position3 - position1).Magnitude
  50.     if magnitude1 > magnitude2 and magnitude1 > magnitude3 then
  51.         position1, position2, position3 = position2, position3, position1
  52.     elseif magnitude2 > magnitude3 then
  53.         position1, position2, position3 = position3, position1, position2
  54.     end
  55.     local vectorZ = position2 - position1
  56.     local vectorY = position3 - position1
  57.     local vectorX = vectorY:Cross(vectorZ)
  58.     if vectorX.Magnitude == 0 then return end
  59.     local width = vectorY:Dot(vectorZ)/vectorY.Magnitude
  60.     local height = math.sqrt(vectorZ.Magnitude * vectorZ.Magnitude - width * width)
  61.     local child = triangle:GetChildren()
  62.     child[1].CFrame = CFrame.fromMatrix((position1 + position2)/2, vectorX, -vectorY, -vectorZ)
  63.     child[1].Size = Vector3.new(child[1].Size.X, width, height)
  64.     child[2].CFrame = CFrame.fromMatrix((position3 + position2)/2, -vectorX, vectorY, -vectorZ)
  65.     child[2].Size = Vector3.new(child[2].Size.X, vectorY.Magnitude - width, height)
  66. end
  67.  
  68. function util:CreateTriangle(parent, position1, position2, position3, thickness, properties)
  69.     local instance = Instance.new("Folder")
  70.  
  71.     instance.Name = "Triangle"
  72.  
  73.     local part1 = Instance.new("WedgePart")
  74.     local part2 = Instance.new("WedgePart")
  75.  
  76.     part1.BottomSurface = Enum.SurfaceType.Smooth
  77.     part2.BottomSurface = Enum.SurfaceType.Smooth
  78.  
  79.     part1.Size = Vector3.new(thickness, thickness, thickness)
  80.     part2.Size = part1.Size
  81.  
  82.     for option, value in pairs(properties) do
  83.         part1[option] = value
  84.         part2[option] = value
  85.     end
  86.  
  87.     part1.Parent = instance
  88.     part2.Parent = instance
  89.  
  90.     instance.Parent = parent
  91.  
  92.     util:PositionTriangle(instance, position1, position2, position3)
  93. end
  94.  
  95.  
  96. -- this function is the one you want, note, str is your export
  97. --[[
  98.     Legend:
  99.         O/M = Mandatory or optional
  100. .___________________________________________________________________________________________________________.
  101. |Order|O/M|Default|Type              |Description                                                           |
  102. [-----------------------------------------------------------------------------------------------------------]
  103. |1    |M  |       |String            |Export result from the plugin                                         |
  104. |2    |O  |.001   |Number            |Size on the X axis of the triangles                                   |
  105. |3    |O  |{}     |Table (Dictionary)|A dictionary where the index is the property and the value is the new |
  106. |     |   |       |                  |value. Thus, for each iteration of the triangle, this set is applied. |
  107. '-----------------------------------------------------------------------------------------------------------'
  108. ]]
  109.  
  110. function importableMeshEditorV2:Import(str, thickess, properties)
  111.     thickess = thickess or .001
  112.     properties = properties or {}
  113.  
  114.     assert(
  115.         type(str) == 'string' and
  116.             type(thickess) == 'number'and
  117.             type(properties) == 'table'
  118.     )
  119.  
  120.     local v = {}
  121.     local f = {}
  122.  
  123.     local modelPosition = Vector3.new()
  124.  
  125.     local mode = 'NotBegan'
  126.  
  127.     local p = 1
  128.  
  129.     local function getStr(a, b)
  130.         return str:sub(a or p, b or p)
  131.     end
  132.  
  133.     local beginP, endP = 1, 1
  134.  
  135.     local args = {}
  136.  
  137.     -- compile string
  138.     while true do
  139.         local char = getStr()
  140.  
  141.  
  142.         if mode=='NotBegan'then
  143.             if getStr(p, p + 6) == '|BEGIN|'then
  144.                 mode = 'Vertex'
  145.                 p += 6
  146.             end
  147.         elseif mode == 'Vertex'then
  148.             -- vertex
  149.  
  150.             if char == '|'then
  151.                 mode = 'Face'
  152.             elseif constants.exportAllowedDigits[char]then
  153.                 beginP = p
  154.  
  155.                 while char ~= ' ' do
  156.                     p += 1
  157.                     char = getStr()
  158.                 end
  159.  
  160.                 endP = p - 1
  161.  
  162.                 local StrNum = getStr(beginP, endP)
  163.  
  164.                 table.insert(args, tonumber(StrNum))
  165.  
  166.                 if #args >= 3 then
  167.                     table.insert(v, Vector3.new(unpack(args)))
  168.  
  169.                     args = {}
  170.                 end
  171.             else
  172.                 error('MODE: VERTEX | Expected " ", a valid digit character or "|", got ' .. char )
  173.             end
  174.         elseif mode == 'Face'then
  175.             -- face
  176.  
  177.             local num = constants.newBaseStrToNum[char]
  178.  
  179.             if char == ''then
  180.                 break
  181.             elseif char == '|' and getStr(p + 1, p + 1) == '|' then
  182.                 break
  183.             elseif char == '|' or num then
  184.                 if char == '|' then
  185.                     num = 0
  186.                     repeat
  187.                         p += 1;
  188.                         char = getStr()
  189.  
  190.                         local tempNum = constants.newBaseStrToNum[char]
  191.                         if tempNum then
  192.                             num += tempNum
  193.                         end
  194.                     until char == '|'
  195.  
  196.  
  197.                 end
  198.  
  199.                 table.insert(args, num)
  200.  
  201.                 if #args >= 3 then
  202.                     table.insert(f, args)
  203.  
  204.                     args = {}
  205.                 end
  206.             else
  207.                 error('MODE: FACE | Expected valid character, got "' .. char .. '"')
  208.             end
  209.         else
  210.             error('undefined mode: ' .. mode)
  211.         end
  212.  
  213.         p += 1
  214.     end
  215.  
  216.  
  217.     local t = {}
  218.     if #f > 0 then
  219.         local model = Instance.new("Model")
  220.         model.Parent = workspace
  221.  
  222.         for i, data in ipairs(f) do
  223.             local count = #data
  224.             for j = 3, count do
  225.                 local v1, v2, v3 = f[i][1], f[i][j-1], f[i][j]
  226.                 local found = false
  227.                 if t[v1.." "..v2.." "..v3] then found = true
  228.                 elseif t[v1.." "..v3.." "..v2] then found = true
  229.                 elseif t[v2.." "..v3.." "..v1] then found = true
  230.                 elseif t[v2.." "..v1.." "..v3] then found = true
  231.                 elseif t[v3.." "..v1.." "..v2] then found = true
  232.                 elseif t[v3.." "..v2.." "..v1] then found = true
  233.                 end
  234.  
  235.                 if not found then
  236.                     t[v1.." "..v2.." "..v3] = true
  237.                     util:CreateTriangle(
  238.                         model,
  239.                         v[v1],
  240.                         v[v2],
  241.                         v[v3],
  242.                         thickess,
  243.                         properties
  244.                     )
  245.                 end
  246.             end
  247.         end
  248.  
  249.         return model
  250.     end
  251. end
  252.  
  253. constants.digitString = util:getCharactersInRangeToString('0', '9')
  254.  
  255. constants.alphabet = util:getCharactersInRangeToString('a', 'z')
  256.  
  257. constants.exportAllowedDigits = util:characterSplitifyAndFlip('-.e' .. constants.digitString)
  258.  
  259. constants.newBaseNumToStr = (constants.digitString .. constants.alphabet .. constants.alphabet:upper() .. ',./<>?;:\'"[]{}\\-=_+!@#$%^&*()`~'):split('')
  260.  
  261. constants.newBaseStrToNum = util:flipTable(constants.newBaseNumToStr)
  262.  
  263. local exportStr = [[Mesh Editor:
  264.     Original: https://www.roblox.com/catalog/3076076256/
  265.     CHL's Fork: https://www.roblox.com/catalog/7612497706
  266.  
  267. Note: anything before "the |begin" is considered a comment and thus the script won't
  268. run over it.
  269.  
  270. This is so that yall can put your credits here and stuff.
  271.  
  272. |BEGIN|68.910163879395 -1.0974895954132 -55.423545837402 68.910171508789 .72284317016602 -55.423542022705 67.089828491211 -1.0974895954132 -55.423545837402 67.089828491211 .72284311056137 -58.576457977295 66.179672241211 .72284317016602 -57.000003814697 67.089828491211 -1.0974895954132 -58.576457977295 69.820327758789 -1.0974895954132 -57 69.820327758789 .72284311056137 -57.000003814697 66.179672241211 -1.0974895954132 -57 68.910171508789 .72284317016602 -58.576454162598 68.910163879395 -1.0974895954132 -58.576454162598 67.089828491211 .72284311056137 -55.423545837402 |012021345354016061716761842824796769845854a96a69a95a59b42b24395359b12b21||]]
  273.  
  274. local ref = CFrame.new(68, 1.18, -57)
  275.  
  276. local hexagonModel = importableMeshEditorV2:Import(exportStr, nil, {Anchored = true; CanCollide = false})
  277.  
  278. local owner = getfenv().owner
  279.  
  280. assert(typeof(owner) == 'Instance' and owner:IsA('Player'))
  281. local character = owner.Character
  282.  
  283. for _, descendant in next, hexagonModel:GetDescendants() do
  284.     assert(typeof(descendant) == 'Instance')
  285.    
  286.     if descendant:IsA('BasePart')then
  287.         local weld = Instance.new('Weld')
  288.        
  289.         weld.C0 = ref:Inverse() * descendant.CFrame
  290.         weld.Parent = descendant
  291.         weld.Part1 = descendant
  292.         weld.Part0 = owner.Character.HumanoidRootPart
  293.        
  294.         descendant.Anchored = false
  295.         descendant.CanCollide = false
  296.         descendant.Massless = true
  297.     end
  298. end
  299.  
  300. hexagonModel.Parent = owner.Character
Add Comment
Please, Sign In to add comment