Jump to content

Josh

Staff
  • Posts

    24,155
  • Joined

  • Last visited

Everything posted by Josh

  1. Yeah, I'll have some examples soon. I have to rearrange some of the script stuff right now.
  2. 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.
  3. 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
  4. 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
  5. 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
  6. 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.
  7. 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
  8. Josh

    Programming Poll

    My resources are finite.
  9. That file contains a type that declares all the procedural functions, since they aren't part of a class.
  10. Josh

    Single-state Lua

    Lua script: referencetable={} reference={} referencetable[3]=reference function reference:test() print("hello") end Now how would you call reference:test() from the main program?: lua_getglobal("referencetable") lua_getfield()? //Need to find the table for the value "3". lua_getfield("test") //okay Now we have to push the reference table for the test function to use. How? You cannot get the global variable "reference" because it is just one of many tables the routine will create. lua_getfield uses a string to find the value, so if I use an object as the index it doesn't work: function CreateClass(modelreference) class={} classtable[modelreference]=class end
  11. for model in iterate(CurrentWorld().entities) do Print("Entity name = "..model:GetKey("name")) end
  12. Josh

    Programming Poll

    Well, the number of BlitzMax programmers in the world is pretty much static. The number of C++ programmers is infinite. So who do I want to sell to?
  13. Import framewerk and do what I did. It will automatically detect the exposed types.
  14. The Lua command dofile is used so that compiled script files can be run.
  15. The value parameter is the value that is stored for the key. The Lua function can be used to override that value. Normally the Lua GetKey() function just returns the value it receives. When any of those special keys are encountered, the return value is something else. You can retrieve keys from any entity at any time in Lua like this: entity:GetKey("mykey") Internally this will first look up the key for "mykey", then run it through the "GetKey()" script function and return whatever value that returns.
  16. I did something kind of dumb when attempting to implement a separate raycast algorithm for thick raycasts.
  17. Josh

    Loading A Scene

    Then you are in the same boat as before. The problem is getting Lua and C++ to interact. Right now you have limited means to do this. This can be improved if I add the following: -Add a command to retrieve the Lua state (virtual machine) from a world. -Expose the entire Lua command set in the DLL. Then you can call framewerk and your own C++ commands from Lua.
  18. Particles are a good choice for localized fog.
  19. Josh

    Lua work

    I've been revising the Lua design a bit. Ideally this should have been done six months ago, but I did not realize how popular it would be. During beta testing there wasn't much interest in it. That's understandable, because no one likes using beta software. As soon as it was released, suddenly there was some very advanced stuff being implemented immediately. This is great, and I can see my thoughts about how it would benefit us were correct. It also made me want to implement a single-state system so that we could really use Lua to its full potential. I spent all day on it, and I think it's done. I just have to finish making the changes to the class scripts. This wasn't my ideal way to develop, but if changes are to be made, they should be made now, not in three months.
  20. Josh

    Single-state Lua

    Well, I started reading, and even if I can make sense of it, if it isn't immediately obvious my users won't get it. And the whole point of Lua is to be easy. With a single-state system, here is what the directional light script looks like: require("scripts/base") --Initially set all the functions we might want, so we --don't have to keep track of which ones we actually declare. light_directional_InitDialog=base_InitDialog light_directional_Spawn=base_Spawn light_directional_GetKey=GetKey light_directional_SetKey=SetKey light_directional_ReceiveMessage=base_ReceiveMessage light_directional_Kill=base_Kill function light_directional_InitDialog(grid) base_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 light_directional_Spawn(model) local entity=base_Spawn(model) entity.model:SetKey("resolution","2") entity.light=CreateDirectionalLight(entity.model) return entity end function light_directional_Kill(model) local entity=entitytable[model] if entity~=nil then if entity.light~=nil then entity.light:Free() entity.light=nil end end base_Kill(model) end function light_directional_GetKey(model,key,value) local entity=entitytable[model] if entity==nil then return value end if entity.model==nil then return end if entity.light==nil then return base_GetKey(model,key,value) else if key=="linearoffset" then return entity.light:GetShadowOffset(0,0)..","..entity.light:GetShadowOffset(0,1)..","..entity.light:GetShadowOffset(0,2) elseif key=="shadowdistance" then return entity.light:GetShadowDistance(0)..","..entity.light:GetShadowDistance(1)..","..entity.light:GetShadowDistance(2) elseif key=="range" then return entity.light:GetRange() elseif key=="shadowresolution" then resolution=entity.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 base_GetKey(model,key,value) end end end function light_directional_SetKey(model,key,value) local entity=entitytable[model] if entity==nil then return 1 end if entity.model==nil then return 1 end if entity.light==nil then return base_SetKey(model,key,value) else if key=="resolution" then if value=="0" then entity.light:SetShadowmapSize(256) elseif value=="1" then entity.light:SetShadowmapSize(512) elseif value=="2" then entity.light:SetShadowmapSize(1024) elseif value=="3" then entity.light:SetShadowmapSize(2048) end elseif key=="range" then entity.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 entity.light:SetShadowDistance(x,0) entity.light:SetShadowDistance(y,1) entity.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 entity.light:SetShadowOffset(x,1.0,0) entity.light:SetShadowOffset(y,1.0,1) entity.light:SetShadowOffset(z,1.0,2) else return base_SetKey(model,key,value) end end return 1 end
  21. I have no idea what a kg is. I know it's 1000 grams, but I don't know how much that weighs.
  22. If you want framewerk to be a C++ source code you will have to work with it and Lua. There is a way to expose your C++ classes to Lua, which could make this work very nice and seamlessly, but we need to take one step at a time.
  23. Josh

    Loading A Scene

    2.3 is the same as 2.28, with extra features. There isn't a new way to render water because it hasn't changed.
  24. Brucey on the BlitzMax forum would be the best person to talk to. I think compiling in BMX would be best because then I could add this functionality into the editor. I don't know enough about how it works yet, so your experimentations are really helpful.
×
×
  • Create New...