Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[--
- BEFORE YOU START:
- Please realize:
- 1) Models may not seem as they do in the viewer. Reason: Texture mapping can change the appearance of a model
- 2) Certain models may not render 100% -- If this happens, message me and I will get right to work. (Though I think I fixed this)
- --]]--
- scale = 50 --Sets how big the model is. 1 is default (but rather small)
- incre = 25 -- Sets how many triangles it generates before waiting a bit.
- Type = "Articulated" -- If it's a normal model, put this. If it is a character, put "Character", if it is a skybox (i.e. the skydome), put "Skybox"
- --THE ABOVE IS VERY IMPORTANT FOR PROPER RENDERING!
- TestAnyway = false --If true, it will enable "beta-mode" and allow the unfinished functions to run
- Collision = true --If true, triangles will collide. HOWEVER: Scales below 10 may appear malformed.
- print("Waiting for XML.")
- repeat wait() until _G.XML
- local Main = require(script.MainHandle)
- local xml = _G.XML
- st = 0
- print("Got XML.")
- wait(1)
- local tim = 0
- coroutine.resume(coroutine.create(function ()
- while wait(0.1) do
- tim = tim + 0.1
- end
- end))
- local f = {}
- local bones = {}
- local tris = {}
- local array = {}
- _, CountOfFaces1 = string.gsub(xml, "<v1>", "<v1>")
- _, CountOfFaces2 = string.gsub(xml, "<v2>", "<v2>")
- _, CountOfFaces3 = string.gsub(xml, "<v3>", "<v3>")
- CountOfFaces = CountOfFaces1+CountOfFaces2+CountOfFaces3
- print("Vertex count = "..CountOfFaces)
- print("Face count = "..CountOfFaces/3)
- function GetIndex(strt)
- --print("Getting indices (order of vertecies)")
- local str = "<indices>"
- local estr = "</indices>"
- local stp = xml:find(str, strt)
- if not stp then return end
- local st = stp+str:len()
- local fn = xml:find(estr, strt)-1
- local ind = {}
- --loadstring("ind = {"..xml:sub(st, fn).."}")()
- local txt = xml:sub(st, fn)
- local c = 0
- for i, _ in string.gmatch(txt, ", ") do
- if c == 0 then
- ff = txt:find(", ")-1
- tt = txt:sub(1, ff)
- table.insert(ind, tt)
- else
- local nff = ff+2
- local ff2 = txt:find(", ", nff)-1
- local tt = txt:sub(nff+1, ff2)
- ff = ff2
- table.insert(ind, tt)
- end
- c = c + 1
- if c%500 == 0 then wait() end
- end
- --Now, using this EASY shortcut, I get a table from the set of indices
- --[[--
- NOTE:
- index count = vertex count / 2
- --]]--
- --IND WILL SHOW NIL! IT IS NOT NIL!
- --print("Got indices. Applying to three-group format...")
- for i = 1, #ind do
- if i % 3 == 0 then
- local a = i-2
- local b = i-1
- local c = i
- local A = tonumber(ind[a])+1
- local B = tonumber(ind[b])+1
- local C = tonumber(ind[c])+1
- table.insert(f, {A, B, C})
- end
- end
- --print("Index groups complete!")
- end
- function GetTriangles()
- repeat
- if not st2 then
- st2 = 0
- end
- v1, v2, v3, st = Main:FindTriangles(st2, xml)
- st2 = st
- table.insert(tris, {v1*scale, v2*scale, v3*scale, tostring(st2)})
- until not string.find(xml, "<v1>", st)
- end
- function GetOffsetsAndTriangles()
- ofst = {}
- repeat
- if not st2 then
- st2 = 0
- end
- if not st4 then
- st4 = 0
- end
- local v1, st, bone, count = Main:GetSkyBoneOffsets(st2, xml)
- st2 = st
- GetIndex(st)
- if count > 0 and bone and v1 then
- for i = 1, count do
- table.insert(ofst, v1)
- end
- end
- until not string.find(xml, "<v1>", st)
- print("Got all bone data chains")
- local r = 0
- st2 = 0
- repeat
- r = r + 1
- if not ofst[r] then
- warn("Broke loop! ofst[r] = nil")
- break
- end
- local v1, v2, v3, st = Main:FindTrianglesWithOffset(st2, xml, ofst[r])
- st2 = st
- table.insert(tris, {v1*scale, v2*scale, v3*scale})
- until not string.find(xml, "<triangle>", st)
- end
- if Type:lower():find("articulated") then
- GetTriangles()
- GetIndex(0)
- elseif Type:lower():find("skybox") then
- warn("Skybox not ready.")
- if not TestAnyway then
- GetTriangles()
- GetIndex(0)
- else
- warn("Beta mode active! Running unfinished function for SkyBox")
- GetOffsetsAndTriangles()
- end
- elseif Type:lower():find("character") then
- warn("Character not ready.")
- GetTriangles()
- GetIndex(0)
- end
- local Tri = {}
- mesh2 = Instance.new("Model", workspace)
- mesh2.Name = "Triangles"
- function Tri.new(a, b, c, color)
- local this = {}
- local mPart1 = Instance.new('WedgePart')
- setupPart(mPart1)
- local mPart2 = Instance.new('WedgePart')
- setupPart(mPart2)
- function this:Set(a, b, c)
- local ab, bc, ca = b-a, c-b, a-c
- local abm, bcm, cam = ab.magnitude, bc.magnitude, ca.magnitude
- local edg1 = math.abs(0.5 + ca:Dot(ab)/(abm*abm))
- local edg2 = math.abs(0.5 + ab:Dot(bc)/(bcm*bcm))
- local edg3 = math.abs(0.5 + bc:Dot(ca)/(cam*cam))
- -- Idea: Find the edge onto which the vertex opposite that
- -- edge has the projection closest to 1/2 of the way along that
- -- edge. That is the edge thatwe want to split on in order to
- -- avoid ending up with small "sliver" triangles with one very
- -- small dimension relative to the other one.
- if edg1 < edg2 then
- if edg1 < edg3 then
- -- min is edg1: less than both
- -- nothing to change - All good!
- else
- -- min is edg3: edg3 < edg1 < edg2
- -- "rotate" verts twice counterclockwise to get edg1 < edg2 < edg3
- a, b, c = c, a, b
- ab, bc, ca = ca, ab, bc
- abm = cam
- end
- else
- if edg2 < edg3 then
- -- min is edg2: less than both
- -- "rotate" verts once counterclockwise - same as above else statement
- a, b, c = b, c, a
- ab, bc, ca = bc, ca, ab
- abm = bcm
- else
- -- min is edg3: edg3 < edg2 < edg1
- -- "rotate" verts twice counterclockwise:
- a, b, c = c, a, b
- ab, bc, ca = ca, ab, bc
- abm = cam
- end
- end
- --calculate lengths
- local len1 = -ca:Dot(ab)/abm
- local len2 = abm - len1
- local width = (ca + ab.unit*len1).magnitude
- --calculate "base" CFrame to pasition parts by
- local maincf = CFrameFromTopBack(a, ab:Cross(bc).unit, -ab.unit)
- --make parts
- color = nil
- if not Collision then
- mPart1.Parent = mesh2
- mPart1.Size = Vector3.new(0.2, 0.2, 0.2)
- mPart1.Mesh.Scale = Vector3.new(0, width, len1)/0.2
- mPart1.CFrame = maincf*CFrame.Angles(math.pi,0,math.pi/2)*CFrame.new(0,width/2,len1/2)
- mPart1.BrickColor = BrickColor.Gray()
- mPart2.Parent = mesh2
- mPart2.Size = Vector3.new(0.2, 0.2, 0.2)
- mPart2.Mesh.Scale = Vector3.new(0, width, len2)/0.2
- mPart2.CFrame = maincf*CFrame.Angles(math.pi,math.pi,-math.pi/2)*CFrame.new(0,width/2,-len1 - len2/2)
- mPart2.BrickColor = BrickColor.Gray()
- else
- mPart1.Parent = mesh2
- mPart1.Size = Vector3.new(0.2, width, len1)
- mPart1.Mesh.Scale = Vector3.new(0, 1, 1)
- mPart1.CFrame = maincf*CFrame.Angles(math.pi,0,math.pi/2)*CFrame.new(0,width/2,len1/2)
- mPart1.BrickColor = BrickColor.Gray()
- mPart2.Parent = mesh2
- mPart2.Size = Vector3.new(0.2, width, len2)
- mPart2.Mesh.Scale = Vector3.new(0, 1, 1)
- mPart2.CFrame = maincf*CFrame.Angles(math.pi,math.pi,-math.pi/2)*CFrame.new(0,width/2,-len1 - len2/2)
- mPart2.BrickColor = BrickColor.Gray()
- end
- return mPart1, mPart2
- end
- function this:SetProperty(prop, value)
- mPart1[prop] = value
- mPart2[prop] = value
- end
- function this:Destroy()
- mPart1:Destroy()
- mPart2:Destroy()
- end
- --this:Set(a, b, c)
- return this:Set(a, b, c) --return this
- end
- function CFrameFromTopBack(at, top, back)
- local right = top:Cross(back)
- return CFrame.new(at.x, at.y, at.z,
- right.x, top.x, back.x,
- right.y, top.y, back.y,
- right.z, top.z, back.z)
- end
- function setupPart(part)
- part.Anchored = true
- part.FormFactor = 'Custom'
- part.CanCollide = true
- part.BrickColor = BrickColor.Black()
- part.TopSurface = 'SmoothNoOutlines'
- part.BottomSurface = 'SmoothNoOutlines'
- part.LeftSurface = 'SmoothNoOutlines'
- part.RightSurface = 'SmoothNoOutlines'
- part.FrontSurface = 'SmoothNoOutlines'
- part.BackSurface = 'SmoothNoOutlines'
- local mesh = Instance.new("SpecialMesh", part)
- mesh.MeshType = "Wedge"
- mesh.Scale = Vector3.new(0,1,1)
- end
- print("Mapping triangles")
- for _,v in ipairs(tris) do
- local face = f[_]
- if face and face[1] and face[2] and face[3] and tris[a] and tris[b] and tris[c] then
- a = face[1]
- b = face[2]
- c = face[3]
- local x1 = tris[a][1]
- local y1 = tris[a][2]
- local z1 = tris[a][3]
- local x2 = tris[b][1]
- local y2 = tris[b][2]
- local z2 = tris[b][3]
- local x3 = tris[c][1]
- local y3 = tris[c][2]
- local z3 = tris[c][3]
- local t1, t1a = Tri.new(x1, y1, z1)
- local t2, t2a = Tri.new(x2, y2, z2)
- local t3, t3a = Tri.new(x3, y3, z3)
- if tris[a][4] and tris[b][4] and tris[c][4] then
- t1.Name = tris[a][4]
- t1a.Name = tris[a][4]
- t2.Name = tris[b][4]
- t2a.Name = tris[b][4]
- t3.Name = tris[c][4]
- t3a.Name = tris[c][4]
- end
- else
- Tri.new(v[1], v[2], v[3])
- end
- if _%incre == 0 then wait() end
- end
- print("Rendered "..#tris.." triangles")
- print("Done! ("..tim.." seconds)")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement