Advertisement
Guest User

tobj.lua

a guest
Oct 7th, 2016
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.21 KB | None | 0 0
  1. --    OBJ model library 1.0
  2. --    ---------------------
  3. -- by Totoro (computercraft.ru)
  4. -- ---
  5. -- texture support by Xytabich
  6.  
  7. local png = require("PNGImage")
  8.  
  9. tobj = {}
  10.  
  11. local vertex = {}
  12. local faces = {}
  13.  
  14. local image
  15. local texCoords = {}
  16. local palette = {}
  17.  
  18. local color = {r = 1, g = 0, b = 0, a = 1}
  19. local position = {x = 0, y = 0, z = 0}
  20. local scale = 1.0
  21.  
  22. local paletteColors = true
  23.  
  24. local function getVT(data)
  25.   local v, t = data:match("(-?%d+)/(-?%d+)")
  26.   return tonumber(v), tonumber(t) or nil
  27. end
  28.  
  29. local function round(v)
  30.   local r = math.floor(v)
  31.   if v-0.5 > r then return math.ceil(v)
  32.   else return r end
  33. end
  34.  
  35. local function inBounds(u, v) -- trim the number to the borders of 0-1
  36.   if u > 1 then
  37.     local a, b = math.modf(u)
  38.     u = b
  39.   elseif u < 0 then
  40.     local a, b = math.modf(u)
  41.     u = 1+b
  42.   end
  43.   if v > 1 then
  44.     local a, b = math.modf(v)
  45.     v = b
  46.   elseif v < 0 then
  47.     local a, b = math.modf(v)
  48.     v = 1+b
  49.   end
  50.   return u, v
  51. end
  52.  
  53. local function getFaceColor(t1, t2, t3)
  54.   if (image == nil) or (t1 > #texCoords) or
  55.     (t2 > #texCoords) or (t3 > #texCoords) then return nil
  56.   else
  57.     local u,v = table.unpack(texCoords[t1])
  58.     local w,h = image:getSize()
  59.     w=w-1 h=h-1
  60.     if paletteColors then
  61.       local r,g,b,a = image:getPixel(round(u*w), round((1-v)*h))
  62.       if r == nil then return nil end
  63.       return r/255, g/255, b/255, a/255
  64.     else -- average color of 3 points - алгоритм для ленивых
  65.       local r1,g1,b1,a1 = image:getPixel(round(u*w), round((1-v)*h))
  66.       if r1 == nil then return nil end
  67.       u,v = table.unpack(texCoords[t2])
  68.       local r2,g2,b2,a2 = image:getPixel(round(u*w), round((1-v)*h))
  69.       if r2 == nil then return nil end
  70.       u,v = table.unpack(texCoords[t3])
  71.       local r3,g3,b3,a3 = image:getPixel(round(u*w), round((1-v)*h))
  72.       if r3 == nil then return nil end
  73.       return ((r1+r2+r3)/3)/255, ((g1+g2+g3)/3)/255, ((b1+b2+b3)/3)/255, ((a1+a2+a3)/3)/255
  74.     end
  75.   end
  76. end
  77.  
  78. local function getPaletteIndex(r,g,b,a)
  79.   for i=1, #palette do
  80.     local pr,pg,pb,pa = table.unpack(palette[i])
  81.     if (r==pr) and (g==pg) and (b==pb) and (a==pa) then
  82.       return i
  83.     end
  84.   end
  85.  
  86.   table.insert(palette, {r,g,b,a})
  87.   return #palette
  88. end
  89.  
  90. local function getPaletteColor(i)
  91.   if (i < 1) or (i > #palette) then return 1,1,1,1
  92.   else return table.unpack(palette[i]) end
  93. end
  94.  
  95. tobj.loadTexture = function(filename)
  96.   image = png.newFromFile(filename);
  97. end
  98.  
  99. tobj.load = function(filename)
  100.   file = io.open(filename, "r")
  101.   if file ~= nil then
  102.     vertex = {}
  103.    
  104.     for line in file:lines() do
  105.       if line ~= nil and line ~= '' then
  106.         local key, a, b, c, d = line:match("(%S+)%s+(%S+)%s+(%S+)%s+(%S+)%s*(%S*)")
  107.        
  108.         -- load vertex data / skip normals
  109.         if key == 'v' then
  110.           local x, y, z = tonumber(a), tonumber(b), tonumber(c)
  111.           table.insert(vertex, {x,y,z})
  112.        
  113.         -- load texture data
  114.         elseif key == "vt" then
  115.           local u, v = tonumber(a), tonumber(b)
  116.           table.insert(texCoords, table.pack(inBounds(u, v)))
  117.        
  118.         -- load faces data
  119.         elseif key == 'f' then
  120.           local v1, t1 = getVT(a)
  121.           local v2, t2 = getVT(b)
  122.           local v3, t3 = getVT(c)
  123.           if v1 < 0 then
  124.             local len = #vertex + 1
  125.             v1, v2, v3 = len + v1, len + v2, len + v3
  126.           end
  127.           local p = 0
  128.           if t1 ~= nil then
  129.             r,g,b,a = getFaceColor(t1, t2, t3)
  130.             if r ~= nil then
  131.               p = getPaletteIndex(r,g,b,a)
  132.             end
  133.           end
  134.           table.insert(faces, {vertex[v1], vertex[v2], vertex[v3], p})
  135.         end
  136.       end
  137.     end
  138.     file:close()
  139.   else
  140.     error("[OBJ.load] File not found!")
  141.   end
  142. end
  143.  
  144. tobj.setColor = function(r, g, b, a)
  145.   color.r = r; color.g = g; color.b = b; color.a = a or 1;
  146. end
  147. tobj.setPosition = function(x, y, z)
  148.   position.x = x; position.y = y; position.z = z
  149. end
  150. tobj.setScale = function(s)
  151.   scale = s
  152. end
  153.  
  154. tobj.getColor = function()
  155.   return {color.r, color.g, color.b, color.a}
  156. end
  157. tobj.getPosition = function()
  158.   return {position.x, position.y, position.z}
  159. end
  160. tobj.getScale = function()
  161.   return scale
  162. end
  163.  
  164. tobj.usePalette = function(use)
  165.   if use ~= nil then paletteColors = use
  166.   else return paletteColors end
  167. end
  168.  
  169. tobj.draw = function(glasses)
  170.   local count = 0
  171.   for n, face in pairs(faces) do
  172.     local triangle = glasses.addTriangle3D()
  173.     triangle.setVertex(1, face[1][1]*scale + position.x, face[1][2]*scale + position.y, face[1][3]*scale + position.z)
  174.     triangle.setVertex(2, face[2][1]*scale + position.x, face[2][2]*scale + position.y, face[2][3]*scale + position.z)
  175.     triangle.setVertex(3, face[3][1]*scale + position.x, face[3][2]*scale + position.y, face[3][3]*scale + position.z)
  176.     r,g,b,a = getPaletteColor(face[4])
  177.     triangle.setColor(color.r*r, color.g*g, color.b*b)
  178.     triangle.setAlpha(color.a*a)
  179.     triangle.setVisibleThroughObjects(false)
  180.     ---
  181.     count = count + 1
  182.     if count > 20 then count = 0; os.sleep(0.1) end
  183.   end
  184. end
  185.  
  186. tobj.getVertexNum = function()
  187.   return #vertex
  188. end
  189. tobj.getPolyNum = function()
  190.   return #faces
  191. end
  192.  
  193. return tobj
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement