The UtilFunctions class is a collection of miscellanous useful lua functions.
This function provides a system to check table keys for values. This is useful if a functions is taking a table containing various "named" function arguments. The return value of this function is a table which provides sophisticated functionalities. If the table is called with a string as argument, it expects that a key in the table is to be checked and returns a table with possible value checking functions:
local x,y,vx,vy,type = UtilFunctions.checkargtable(info) "x":type "number" "y":type "number" "vx":optional(0) "vy":optional(0) "type":oneofthis{["player"]=true, ["AI"]=true} :finish()
tries out if the given file exists. This is not very clean since it only trys to open and close the file and if it doesn't throw an error it is assumed that the file exists.
Creates a geom trimeshdata from the given model. Optionally transforms vertices.
tableBase : {data = dgeomtrimeshdata, aabox = {min{x,y,z},max{x,y,z}, center = {x,y,z}}
tableHit : {table similar to base, but for every "hitmesh" = meshes that contain "hitzone" in the material name
tableRaw : { inds = indices{}, verts = vertices{}, tris = tridata{{mesh=meshid,orig=original index}...} }, table with all indices/vertices and a table with the tridata for every face in the model
retrieves the filename of a luafunction, if possible. The level is the functioncallerstack and should be >=1 returns filename and level of the found path.
for key,value in UtilFunctions.pairsByKeys({cde=1, abc=2}) do print(key,value) end
abc 2 cde 3
This function will test the given space with a ray and returns, if a hit was generated, the geom, the coordinate of the nearest hit and the hitnormal. The ray is in line with the x,y pair (or the mouse coordinates if not given) on the camera projection plane and through the last known camera worldposition (this worldposition can be one frame behind, so you might have to call camera:forceupdate() to update to the currently set position if this is important, which is not in most cases). The maxlength can be optionally set and is per default set to 1000000. If no camera is specified, the default camera is used.
This function handles also orthogonal camera fovs, which requires a different raysetting code.
UtilFunctions.simplerenderqueue()input.showmouse(true) -- so we can see the mouse space = dspacehash.new() -- our space with our objects box = actornode.new("box") -- our box location box.geom = dgeombox.new(1,1,1,space) -- the geom, placed in 0,0,0 box.geom.l3d = l3dprimitive.newbox("box",1,1,1) -- the l3d for our box box.geom.l3d:linkinterface(box) -- link it cam = actornode.new("cam",5,4,3) -- our cameranode so we can view l3dcamera.default():linkinterface(cam) -- link it with defaultcamera cam:lookat(0,0,0,0,0,1) -- and look at 0,0,0 (the box location)
highlight = actornode.new("highlight") -- a simple highlighter highlight.l3d = l3dprimitive.newsphere("hightlight",0.05) highlight.l3d:color(1,0,0,1) -- make sphere red highlight.l3d:linkinterface(highlight) -- link it
local function test () -- our testing function local g,pos = UtilFunctions.picktest(space) -- test it highlight.l3d:rfNodraw(not pos) -- don't highlight if no hit
if pos then -- if we have a hit highlight:pos(pos[1],pos[2],pos[3]) -- move the highlighter g.l3d:color(1,math.sin(os.clock()*5)/2+.5,1,1) -- ^^ make the hit object do something end end
Timer.set("picker", test,20) -- run the test every 20ms
Serializes a given table into a string that allows the reconstruction of the given table. It returns a string that describes the table's content with lua code. To deserialize the string, it must only be executed:
mytable = {1,2,3} serial = UtilFunctions.serialize(mytable) mytable = nil reconstructed = loadstring(serial)() for i,v in ipairs(reconstructed) do print(v) end -- prints out 1,2,3 - converted first to string and then -- to a table again successfullyThe table may contain self cycles:
mytable = {1,2,3} mytable.self = mytable mytable[mytable] = "self index" serial = UtilFunctions.serialize(mytable) mytable = nil reconstructed = loadstring(serial)() print(reconstructed[reconstructed]) for i,v in ipairs(reconstructed.self) do print(v) end -- prints out "self index" \n 1,2,3If the table contains function, the serilizing function will try to compile the function in its binary representation using string.dump - which may fail if the function is using local values from outside.
If the table has a metatable function entry named __serialize, this function is being called and the return value is further serialized if it is a table value. However, if the function returns a string, the string is directly written in the place where the serialisation takes place! You can inject lua code this way:
mytable = {} setmetatable(mytable, {__serialize = function (self, idx) return "function () return true end" end end }) print (UtilFunctions.serialize({ mytable }))Output result:
local refs = {} local fns = {} for i=1,1 do refs[i] = {} end refs[1][1] = function () return true end return refs[1]Important: don't serialize tables with __serialize metatables directly! Include them in a table instead, like in the example above.
The serialisation function receives two arguments: the own table as argument 1 and an index value as argument 2. The indexvalue represents the id where the table data is stored (the refs table includes all required values and other values must reference them as well, building the cyclic tables and so on). The serialize function can return a second value which tells the serializer how many reference table you require - i.e. if you return 1 as second argument, an additional table is stored in refs.
You could also return a table, which is then serialized too, or a string of a serialisation included in a function that is executed:
(function () UtilFunctions.serialize({1,2,3}) end)() -- creates a table {1,2,3}Since you can modify the output result, you can write inject any code you want to save, meaning loops, functions and so on.
The way the serialisation is stored is given in the output result above: A list of tables stored in refs is used to fill the data of the tables one after another without breaking the consistence due to cyclic references. The fns table contains functions that are created with the string.dump functions. The loop creates all required tables so we can easily use them later. After this initialisation, the tables in refs are filled with all values. At last, the first table value (which was passed to the serialize function) is returned. You can either write this string in a file or make a lua function of it by prepending "function serializedstuff () " and adding "end" to the string returned by the serializing function.
sets up a standard renderqueue for the view (which is also returned).
The l3dview has equivalent rcmds in its table. The order is: rClear,rDepth,rDrawbg,rLayers[1..16].
Each rLayer contains: stencil,drawlayer,drawprt for the equivalent l3dlayerids-1. Sorting is enabled and material-based.
ignorelayers should contain 'true' at layer+1 field. Ie {true,true} will disable layer 0 & 1.
Sets the position of the small Luxinia Logo at one of the four corners (whatever you like more). Topright = 1, rightbottom = 2, bottomleft = 3, topleft = 4.