Jump to content

Josh

Staff
  • Posts

    25,019
  • Joined

  • Last visited

Everything posted by Josh

  1. It's 12:30 in the morning, but I have the model scripts working the way I want. Thanks to "Nilium" for his tips, and to everyone who gave their feedback. I am confident in this revision. I have a lot of scripts that need to be slightly altered, but it's just a matter of adjusting the function structure, not really changing any existing code. Here's the light_ambient script: require("scripts/class") require("scripts/linkedlist") local class=CreateClass(...) function class:Spawn(model) local object=self.super:Spawn(model) function object:Update() AmbientLight(self.model.color) end function object:SetKey(key,value) if key=="color" then local returnvalue=self.super:SetKey(key,value) self:Update() return returnvalue elseif key=="intensity" then local returnvalue=self.super:SetKey(key,value) self:Update() return returnvalue else return self.super:SetKey(key,value) end return 1 end function object:Kill(model) local model,object --Iterate through all instances of this class. --If any instances are found, use them to set --the ambient light value. for model,object in pairs(self.class.instances) do if object~=self then object:Update() break end end self.super:Kill() end object.model:SetKey("intensity","0.5") --Call the update function before finishing. --This can only be called after the function is declared. --We don't actually need to call it here since setting the intensity key --will do that for us, but it's still a good idea as a general rule. object:Update() end function class:Cleanup() --Restore default ambient light setting. AmbientLight(Vec3(0.5,0.5,0.5)) self.super:Cleanup() end
  2. Josh

    Single-state Lua

    It's like calling base_whatever().
  3. Josh

    Single-state Lua

    I've got it working now. Here's what it looks like: require("scripts/class") local class=CreateClass(...) function class:InitDialog(grid) self.super:InitDialog(grid) group=grid:AddGroup("Light") group:AddProperty("Resolution",PROPERTY_CHOICE,"256,512,1024,2048") group:AddProperty("linearoffset",PROPERTY_VEC3,"0,1,2","Linear offset" ) group:AddProperty("shadowdistance",PROPERTY_VEC3,"","Shadow distance" ) group:AddProperty("Range",PROPERTY_FLOAT) group:Expand(1) end function class:Spawn(model) local object=self.super:Spawn(model) object.model:SetKey("resolution","2") object.light=CreateDirectionalLight(object.model) function object:SetKey(key,value) if key=="resolution" then if value=="0" then self.light:SetShadowmapSize(256) elseif value=="1" then self.light:SetShadowmapSize(512) elseif value=="2" then self.light:SetShadowmapSize(1024) elseif value=="3" then self.light:SetShadowmapSize(2048) end elseif key=="range" then self.light:SetRange(value) elseif key=="shadowdistance" then local offset=string.Explode(value,",") x=tonumber(offset[1]) y=tonumber(offset[2]) z=tonumber(offset[3]) if x==nil then x=0 end if y==nil then y=0 end if z==nil then z=0 end self.light:SetShadowDistance(x,0) self.light:SetShadowDistance(y,1) self.light:SetShadowDistance(z,2) elseif key=="linearoffset" then local offset=string.Explode(value,",") x=tonumber(offset[1]) y=tonumber(offset[2]) z=tonumber(offset[3]) if x==nil then x=0 end if y==nil then y=0 end if z==nil then z=0 end self.light:SetShadowOffset(x,1.0,0) self.light:SetShadowOffset(y,1.0,1) self.light:SetShadowOffset(z,1.0,2) else return self.super:SetKey(key,value) end end function object:GetKey(key,value) if key=="linearoffset" then return self.light:GetShadowOffset(0,0)..","..self.light:GetShadowOffset(0,1)..","..self.light:GetShadowOffset(0,2) elseif key=="shadowdistance" then return self.light:GetShadowDistance(0)..","..self.light:GetShadowDistance(1)..","..self.light:GetShadowDistance(2) elseif key=="range" then return self.light:GetRange() elseif key=="shadowresolution" then resolution=self.light:GetShadowmapSize() if resolution==256 then return 0 elseif resolution==512 then return 1 elseif resolution==1024 then return 2 elseif resolution==2048 then return 3 else return -1 end else return self.super:GetKey(key,value) end end function object:Kill(model) if self.light~=nil then self.light:Free() self.light=nil end self.super:Kill() end return object end
  4. I think the main point is C# has memory management which can make complex apps a lot easier. However, most third party libraries you will find are written in C++, so I am not sure what the point of using C# is. There are easier languages that are cross-platform compatible like Java and BlitzMax. I think C# is still Windows-only. There might be some workarounds, but since it is MS you know they are probably never going to put real effort into Linux and Mac. There are other people who know a lot more about C# than me, so take that with a grain of salt.
  5. Josh

    Scripted GUI

    File Name: Scripted GUI File Submitter: Josh File Submitted: 06 Dec 2009 File Category: Lua Scripts Here's a GUI system with support for windows, panels, drop down boxes, buttons, sliders, labels, and checkboxes. It could still use some improvement, but it's pretty functional and provides a good base to work with. Click here to download this file
  6. That post is referring to textures that have partial mipmaps. Mipmaps should not be required, but if they are present, the texture should have all of them down to 1x1.
  7. Josh

    Single-state Lua

    I have something else wrong here...
  8. Josh

    Single-state Lua

    require("scripts/class") local modelreference=... local class = CreateClass(modelreference) function class:InitDialog(grid) self.super:InitDialog(grid) group=grid:AddGroup("Light") group:AddProperty("Resolution",PROPERTY_CHOICE,"256,512,1024,2048") group:AddProperty("linearoffset",PROPERTY_VEC3,"0,1,2","Linear offset" ) group:AddProperty("shadowdistance",PROPERTY_VEC3,"","Shadow distance" ) group:AddProperty("Range",PROPERTY_FLOAT) group:Expand(1) end function class:Spawn(model) local object=self.super:Spawn(model) object.model:SetKey("resolution","2") object.light=CreateDirectionalLight(object.model) function object:SetKey(key,value) if key=="resolution" then if value=="0" then self.light:SetShadowmapSize(256) elseif value=="1" then self.light:SetShadowmapSize(512) elseif value=="2" then self.light:SetShadowmapSize(1024) elseif value=="3" then self.light:SetShadowmapSize(2048) end elseif key=="range" then self.light:SetRange(value) elseif key=="shadowdistance" then local offset=string.Explode(value,",") x=tonumber(offset[1]) y=tonumber(offset[2]) z=tonumber(offset[3]) if x==nil then x=0 end if y==nil then y=0 end if z==nil then z=0 end self.light:SetShadowDistance(x,0) self.light:SetShadowDistance(y,1) self.light:SetShadowDistance(z,2) elseif key=="linearoffset" then local offset=string.Explode(value,",") x=tonumber(offset[1]) y=tonumber(offset[2]) z=tonumber(offset[3]) if x==nil then x=0 end if y==nil then y=0 end if z==nil then z=0 end self.light:SetShadowOffset(x,1.0,0) self.light:SetShadowOffset(y,1.0,1) self.light:SetShadowOffset(z,1.0,2) else return self.super:SetKey(key,value) end end function object:GetKey(key,value) if key=="linearoffset" then return self.light:GetShadowOffset(0,0)..","..self.light:GetShadowOffset(0,1)..","..self.light:GetShadowOffset(0,2) elseif key=="shadowdistance" then return self.light:GetShadowDistance(0)..","..self.light:GetShadowDistance(1)..","..self.light:GetShadowDistance(2) elseif key=="range" then return self.light:GetRange() elseif key=="shadowresolution" then resolution=self.light:GetShadowmapSize() if resolution==256 then return 0 elseif resolution==512 then return 1 elseif resolution==1024 then return 2 elseif resolution==2048 then return 3 else return -1 end else return self.super:GetKey(key,value) end end function object:Kill(model) if self.light~=nil then self.light:Free() self.light=nil end self.super:Kill() end return object end return class
  9. Josh

    Single-state Lua

    My loadfile() method returns 1 if luaL_loadfile() returns 0. I'm now getting "attempt to call a string value".
  10. If you change materials on one instance of the mesh, all instances of the mesh will be changed. The entity color is a unique value we can use to store information on a per-instance level. The switch has a special shader that uses the entity color value to display the different appearances of the switch.
  11. Josh

    Single-state Lua

    And the application end is like this? It doesn't look like modelreference is being passed correctly: Local result:Int Local size:Int=modelref.lua.StackSize() lua_pushstring(modelref.lua.L,modelref.prefix+"CreateClass") result=modelref.lua.loadfile(StripExt(modelref.path)+".lua") If result lua_settable(modelref.lua.L,LUA_GLOBALSINDEX) EndIf modelref.lua.SetStackSize(size) If result size=modelref.lua.StackSize() lua_getglobal(modelref.lua.L,modelref.prefix+"CreateClass") If lua_isfunction(modelref.lua.L,-1) modelref.lua.pushobject(modelref) modelref.lua.invoke(1,0) EndIf modelref.lua.SetStackSize(size) EndIf
  12. Josh

    entity name

    You are always returning 1 from SetKey. I experienced this same problem and realized you don't want to actually set the position, rotation, scale keys. If you open base.lua you will see that when those values are set, the functions positions them, then returns 0. Your function should say this: return base_SetKey(model,key,value) Instead of this: return 1
  13. Josh

    Single-state Lua

    There is no preprocessor. How would light_directional_CreateClass() be a class? If you have any ideas tell me. I could eliminate the big class function and just set the value of modelreference directly from the engine before the script is run. That gets rid of one layer of nesting: require("scripts/class") local class=CreateClass(modelreference) function class:InitDialog(grid) self.super:InitDialog(grid) group=grid:AddGroup("Light") group:AddProperty("Resolution",PROPERTY_CHOICE,"256,512,1024,2048") group:AddProperty("linearoffset",PROPERTY_VEC3,"0,1,2","Linear offset" ) group:AddProperty("shadowdistance",PROPERTY_VEC3,"","Shadow distance" ) group:AddProperty("Range",PROPERTY_FLOAT) group:Expand(1) end function class:Spawn(model) local object=self.super:Spawn(model) object.model:SetKey("resolution","2") object.light=CreateDirectionalLight(object.model) function object:SetKey(key,value) if key=="resolution" then if value=="0" then self.light:SetShadowmapSize(256) elseif value=="1" then self.light:SetShadowmapSize(512) elseif value=="2" then self.light:SetShadowmapSize(1024) elseif value=="3" then self.light:SetShadowmapSize(2048) end else return self.super:SetKey(key,value) end end function object:GetKey(key,value) if key=="linearoffset" then return self.light:GetShadowOffset(0,0)..","..self.light:GetShadowOffset(0,1)..","..self.light:GetShadowOffset(0,2) elseif key=="shadowdistance" then return self.light:GetShadowDistance(0)..","..self.light:GetShadowDistance(1)..","..self.light:GetShadowDistance(2) else return self.super:GetKey(key,value) end end function object:Kill(model) if self.light~=nil then self.light:Free() self.light=nil end self.super:Kill() end return object end class=nil
  14. Josh

    entity name

    Post your script.
  15. Josh

    Single-state Lua

    Well, there's the easy way and the powerful way. The multistate approach is very procedural and easy on the eyes, but the single state approach has to have things contained within the class table. You can't just declare a bunch of variables and not worry about them interfering with other scripts. I think if I tried to move the object functions to another file or another part of the code, it would be more confusing. If I tried to muddle it up and make it prettier I think I would just be obfuscating what is really happening. I'm pretty satisfied because it's object-oriented and still pretty simple. I am pretty optimistic about this design so I will document it extensively.
  16. Yeah, I'll have some examples soon. I have to rearrange some of the script stuff right now.
  17. Josh

    Looping entities

    The world the Update function is being called for might be a world that has nothing in it. Remember, framewerk has three different worlds going.
  18. Josh

    Looping entities

    I don't think init automatically equals false. It equals nil by default: local p if p==false then Notify("false") end if p==nil then Notify("nil") end
  19. Josh

    Lua work

    It's working out well now: http://leadwerks.com/werkspace/index.php?/topic/243-single-state-lua/page__st__20__gopid__2299entry2299
  20. Josh

    Single-state Lua

    I'm getting some good results now. -The only special function name is the the class creation function, i.e. light_directional_CreateClass(). -I started using "object" instead of "entity" to avoid confusing Lua tables with engine entities. -You can call functions like object.super:Kill() in the object:Kill() method. -The commands are all OO and contained in the class table. -Objects can call each others' commands like player.enemy.weapon:shoot() Here's a look at the light_directional script: require("scripts/class") function light_directional_CreateClass(modelreference) local class=CreateClass(modelreference) function class:InitDialog(grid) self.super:InitDialog(grid) group=grid:AddGroup("Light") group:AddProperty("Resolution",PROPERTY_CHOICE,"256,512,1024,2048") group:AddProperty("linearoffset",PROPERTY_VEC3,"0,1,2","Linear offset" ) group:AddProperty("shadowdistance",PROPERTY_VEC3,"","Shadow distance" ) group:AddProperty("Range",PROPERTY_FLOAT) group:Expand(1) end function class:Spawn(model) local object=self.super:Spawn(model) object.model:SetKey("resolution","2") object.light=CreateDirectionalLight(object.model) function object:SetKey(key,value) if key=="resolution" then if value=="0" then self.light:SetShadowmapSize(256) elseif value=="1" then self.light:SetShadowmapSize(512) elseif value=="2" then self.light:SetShadowmapSize(1024) elseif value=="3" then self.light:SetShadowmapSize(2048) end else return self.super:SetKey(key,value) end end function object:GetKey(key,value) if key=="linearoffset" then return self.light:GetShadowOffset(0,0)..","..self.light:GetShadowOffset(0,1)..","..self.light:GetShadowOffset(0,2) elseif key=="shadowdistance" then return self.light:GetShadowDistance(0)..","..self.light:GetShadowDistance(1)..","..self.light:GetShadowDistance(2) else return self.super:GetKey(key,value) end end function object:Kill(model) if self.light~=nil then self.light:Free() self.light=nil end self.super:Kill() end return object end return class end
  21. Josh

    Single-state Lua

    Yeah, the highlighting is for C and I haven't found a way to change it yet. This makes more sense now. Still confusing, but if I follow it carefully it should work.
  22. Josh

    Single-state Lua

    Yep. I am not sure why lua_createtable() is being called above. Here's how I would like it to work: classtable={} entitytable={} function CreateClass(modelreference) local class={} classtable[modelreference]=class class.instances={} function class:Spawn(model) local entity={} entitytable[model]=entity entity.class=self self.instances[model]=entity function entity:SetKey(key,value) return 1 end return entity end return class end The lua table "entity" corresponds to a BlitzMax model. The lua table "class" corresponds to a BlitzMax modelreference. Just as the BlitzMax modelreference has a list of all instances of that object, the Lua class table has an "instances" table listing all the Lua entities of that class. All shared data that the entities use would get stored in the class table. When all instances of the model are deleted, the engine calls a cleanup function, removing the class for that modelreference from the table. At that time, any sounds or other stuff loaded for the class will be freed. Each "entity" table is also stored in a global table along with the BlitzMax model it corresponds to, so the engine can quickly find the entity table associated with any model. Now let's say I wanted to call the SetKey() function on a specific model from the main program. The Lua tables for the class and entity are already set up, and I am ready to call a function: lua_getglobal(L,"entitytable") if lua_istable(L,-1) lua_pushbmaxobject(L, model) ...? EndIf
×
×
  • Create New...