Advertisement
Guest User

model.lua

a guest
Feb 27th, 2016
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.55 KB | None | 0 0
  1. -- Deals with the model file, and some common operations on it
  2. --[[
  3. NOTE: models are described as a series of "fenced" shapes, eg a
  4. shape going from X=4 to X=6 takes up voxels 4 and 5.
  5.  
  6. The range in all 3 dimensions is 0-16: 16 voxels in total (0-1,
  7. 1-2, 2-3, etc).
  8. ]]
  9.  
  10. local table = require("table")
  11. local s11n = require("serialization")
  12.  
  13. local Model = {}
  14. Model.__index = Model
  15.  
  16. local Textures = {}
  17. Textures.__index = Textures
  18.  
  19. -- Load a model from a file (returns Model or nil, string or nil, in case of error)
  20. function Model.load(filename)
  21.   local file, reason = io.open(filename, "r")
  22.   if not file then
  23.     return nil, reason
  24.   end
  25.   local rawdata = file:read("*all")
  26.   file:close()
  27.  
  28.   local data, reason = load("return " .. rawdata)
  29.   if not data then
  30.     return nil, reason
  31.   end
  32.  
  33.   return setmetatable(data(), Model)
  34. end
  35.  
  36. -- Create a new, empty model
  37. function Model.new()
  38.   local self = setmetatable({}, Model)
  39.  
  40.   -- Initialize fields
  41.   self.label = nil  -- String
  42.   self.tooltip = nil  -- String
  43.   self.lightlevel = nil  -- int 0-8
  44.   self.emitRedstone = nil  -- bool or int 0-15
  45.   self.buttonMode = nil  -- bool
  46.   self.collidable = {true, true}
  47.   self.shapes = {}
  48.   return self
  49. end
  50.  
  51.  
  52. -- Iterate over the shapes, transforming them into {x,y,z,...}
  53. -- The resulting voxels are indexed; coords are [1,16]
  54. function Model:voxels()
  55.   if #self.shapes == 0 then
  56.     -- Empty shapes, dump out
  57.     return function() end
  58.   end
  59.  
  60.   -- We have to unravel a triply-nested loop, also known as masochism
  61.   local s = 1
  62.   local x = self.shapes[s][1] - 1
  63.   local y = self.shapes[s][2]
  64.   local z = self.shapes[s][3]
  65.   return function()
  66.     x = x + 1
  67.     if x >= self.shapes[s][4] then
  68.       y = y + 1
  69.       x = self.shapes[s][1]
  70.     end
  71.     if y >= self.shapes[s][5] then
  72.       z = z + 1
  73.       -- X rolled over
  74.       y = self.shapes[s][2]
  75.     end
  76.     if z >= self.shapes[s][6] then
  77.       s = s + 1
  78.       if s > #self.shapes then
  79.         return nil
  80.       end
  81.  
  82.       -- X, Y rolled over on the wrong shape
  83.       x = self.shapes[s][1]
  84.       y = self.shapes[s][2]
  85.       z = self.shapes[s][3]
  86.     end
  87.    
  88.     return {x+1,y+1,z+1, state=self.shapes[s].state, texture=self.shapes[s].texture, tint=self.shapes[s].tint}
  89.   end
  90. end
  91.  
  92. -- Same as voxels, but loads a texture db and maps it to RGB
  93. -- Items are in the form {x,y,z,state=state,rgb=rgb}
  94. function Model:voxels_rgb(txtdb)
  95.   if txtdb == nil then
  96.     txtdb = Textures.load()
  97.   end
  98.   local voxels = self:voxels()
  99.   return function()
  100.     local v = voxels()
  101.     if v == nil then
  102.       return nil
  103.     end
  104.    
  105.     return {v[1], v[2], v[3], state=v.state, rgb=txtdb:rgb(v)}
  106.   end
  107. end
  108.  
  109. -- Saves out the file. Makes an attempt at pretty-printing. Returns nil or reason
  110. function Model:save(filename)
  111.   local f, r = io.open(filename, "w")
  112.   if not f then
  113.     return r
  114.   end
  115.   local raw = s11n.serialize(self, 1e99)
  116.   f:write(raw)
  117.   f:close()
  118. end
  119.  
  120.  
  121. -- Swallows errors, opting to return {} instead
  122. -- Dunno if this is right
  123. function Textures.load()
  124.   local file, reasion = io.open("/usr/share/textures", "r")
  125.   if not file then
  126.     return setmetatable({}, Textures)
  127.   end
  128.  
  129.   local rawdata = file:read("*all")
  130.   file:close()
  131.  
  132.   local txtdb, reason = s11n.unserialize(rawdata)
  133.   if not txtdb then
  134.     txtdb = {}
  135.   end
  136.  
  137.   return setmetatable(txtdb, Textures)
  138. end
  139.  
  140. -- Takes a Model shape and guesses an RGB for it
  141. function Textures:rgb(shape)
  142.   local base = self[shape.texture]
  143.   if base == nil or base < 0 then
  144.     return shape.tint or 0xFF0000
  145.   elseif not shape.tint then
  146.     return base
  147.   else
  148.     -- TODO: average base and tint
  149.     return base
  150.   end
  151. end
  152.  
  153. return {
  154.   Model=Model,
  155.   Textures=Textures,
  156. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement