util={} --- Create a string representation of a table --- @param o table function util.dumpTable(o) if type(o) == 'table' then local s = '{ ' local first_loop=true for k,v in pairs(o) do if not first_loop then s = s .. ', ' end first_loop=false if type(k) ~= 'number' then k = '"'..k..'"' end s = s .. '['..k..'] = ' .. dumpTable(v) end return s .. '} ' else return tostring(o) end end do local function format_any_value(obj, buffer) local _type = type(obj) if _type == "table" then buffer[#buffer + 1] = '{"' for key, value in next, obj, nil do buffer[#buffer + 1] = tostring(key) .. '":' format_any_value(value, buffer) buffer[#buffer + 1] = ',"' end buffer[#buffer] = '}' -- note the overwrite elseif _type == "string" then buffer[#buffer + 1] = '"' .. obj .. '"' elseif _type == "boolean" or _type == "number" then buffer[#buffer + 1] = tostring(obj) else buffer[#buffer + 1] = '"???' .. _type .. '???"' end end --- Dumps object as UNSAFE json, i stole this from stackoverflow so i could -- use json.tool to format it so it's easier to read -- TL;DR, do NOT use this as an actual JSON implementation function util.dumpJSON(obj) if obj == nil then return "null" else local buffer = {} format_any_value(obj, buffer) return table.concat(buffer) end end end -- TODO: accept model part to determine texture width and height ---@param uv table function util.UV(uv) return vec( uv[1]/TEXTURE_WIDTH, uv[2]/TEXTURE_HEIGHT ) end ---@param inputstr string ---@param sep string function util.splitstring (inputstr, sep) if sep == nil then sep = "%s" end local t={} for str in string.gmatch(inputstr, "([^"..sep.."]+)") do table.insert(t, str) end return t end ---@param input string function util.parse(input) if input=="nil" then return nil elseif input == "true" or input == "false" then return input=="true" elseif tonumber(input) ~= nil then return tonumber(input) else return input end end ---@param func function ---@param table table function util.map(func, table) local t={} for k, v in pairs(table) do t[k]=func(v) end return t end ---@param func function ---@param table table function util.filter(func, table) local t={} for k, v in pairs(table) do if func(v) then t[k]=v end end return t end ---@param tbl table ---@param val any function util.has_value(tbl, val) for _, v in pairs(tbl) do if v==val then return true end end return false end --- Unordered reduction, only use when working with dictionaries and --- execution order does not matter ---@param tbl table Table to reduce ---@param func function Function used to reduce table ---@param init any Initial operand for reduce function function util.reduce(func, tbl, init) local result = init local first_loop = true for _, v in pairs(tbl) do if first_loop and init == nil then result=v else result = func(result, v) end first_loop=false end return result end --- Ordered reduction, does not work with dictionaries ---@param tbl table Table to reduce ---@param func function Function used to reduce table ---@param init any Initial operand for reduce function function util.ireduce(func, tbl, init) local result = init local first_loop = true for _, v in ipairs(tbl) do if first_loop and init == nil then result=v else result = func(result, v) end first_loop=false end return result end --- Merge two tables. First table value takes precedence when conflict occurs. ---@param tb1 table ---@param tb2 table function util.mergeTable(tb1, tb2) local t={} for k, v in pairs(tb1) do t[k]=v end for k, v in pairs(tb2) do if type(k)=="number" then table.insert(t, v) else if t[k]==nil then t[k]=v end end end return t end function util.debugPrint(var) print(var) return var end function util.debugPrintTable(var) printTable(var) return var end --- Recursively walk a model tree and return a table containing the group and each of its sub-groups --- @param group table The group to recurse --- @return table Resulting table local function recurseModelGroup(group) local t={} table.insert(t, group) if group:getType()=="GROUP" then for k, v in pairs(group:getChildren()) do for _, v2 in pairs(recurseModelGroup(v)) do table.insert(t, v2) end end end return t end util.recurseModelGroup=recurseModelGroup return util