Jump to content

Charrua

Developers
  • Posts

    247
  • Joined

  • Last visited

Everything posted by Charrua

  1. don't know it it's a bug, but this afternoon happens to me that i minimized the leadwerks editor, left the laptop alone for a while and it goes to sleep. After wake up, i couldn't maximize the editor. I close and start again and i goes minimized. i take a look at the .cfg file and found the "MainWindowShape" parameter with this: MainWindowShape="-25600","-25600","136","47","0" i look on other .cfg files posted here and simply replace this line for something like MainWindowShape="236","27","1186","768","0" and start leadwerks again and looking as spected. i simply report this issue, and a solution i found. Juan
  2. great! thank's for sharing just a small note (happens to me : in: function Script:Record_Mode_Toggle() FileSystem:WriteFile retutn null if lua sandboxing is enabled a check for a null and an advice would be nice Juan
  3. the "someValue" should be dependent of the distance from the player and the camera, probably the angle (camera x angle) and naturally the camera FOV
  4. if you want the bar over the head in 2d space project the head, and then use the 2D x axis as the center of the bar, and use the 2D Y axis minus some value to rise up (in 2D space) the bar. isn't it?
  5. hi, here there are some notes i wrote about c++ lua bindings http://www.leadwerks.com/werkspace/blog/183/entry-1612-lua-cpp-bindings-how-to-tutorial-17/ once yo compile your c++ code, that one is used from the Leadwearks editor when you press paly/debug on the editor.
  6. every day i felt a couple of month outdated about almost everything! thinking it twice that's a good signature to use
  7. i tested the opposite, change a key in cpp and test it on lua side.. i realize how i forgot how to code in lua.. --simply to pass data to c++ Script.AnInt=0 --int "anInt" Script.AString="Hola" --string "string" function Script:Start() self.entity:SetKeyValue("anInt", self.AnInt) self.entity:SetKeyValue("aString", self.AString) end function Script:UpdateWorld() if self.entity:GetKeyValue("anInt") ~= self.AnInt then self.AnInt = self.entity:GetKeyValue("anInt") System:Print("AnInt changed: "..self.AnInt) end end and in cpp, after found "theEnt" (as i named the entity with this script attached) and storend on a Entity* pointer.. i delared a glogal int int anInt=0; in main loop: somewhere: if (window->KeyHit(Key::G)) { anInt++; theEnt->SetKeyValue("anInt", String(anInt)); }
  8. found a script i used ... when testing set/get key value its called EntData.lua --simply to pass data to c++ Script.AnInt=5--int "anInt" Script.AString="Hola"--string "string" function Script:Start() self.entity:SetKeyValue("anInt", self.AnInt) self.entity:SetKeyValue("aString", self.AString) end if you attach this script to an entity in the editor, you may set the values you want and at startup, keys are asigned to the entity i'm sure i used that to then read the keys from cpp side, i only found the lua side other thing i used to use... just because name is safe, was use the "name" as a csv, with something like name=theentty, customval1=34, customval2=hola, and so.. then whit a utiliti function like getNthCsvFromString(string s, int nth) i get the "name" key and get the individual csv items with the previous function... i know that this kind of names are a mess, but was what i used before knowing better ones jio
  9. this is from when? last year i passed via keyvalues data from cpp to lua and back to cpp using an entity as a placeholder. this is not working at present?, i don't tested recently
  10. but if you find the "block" entity, then GetKeyValue("name") is working. "name" is a key already implemented, so it allways work, you have a textbox on the editor for the name. if i'm not wrong, then the problem is with keys created by you, isn't it? probably your problem is on the SetKeyValue command, which i suppose you are setting in the lua script.
  11. where is world created? if in lua, then cpp world should be empty (or NULL)
  12. these both are very handy, or if you named the object properly then you can search it inside the world->Entities list see: http://www.leadwerks.com/werkspace/blog/183/entry-1613-lua-cpp-how-to-27/
  13. it there is a better place, no problem just updated the post with the link to a zip file with allincluded
  14. 6) How to expose a Cpp Class to LUA using tolua++ At a glance: A way to create instances of objects defined in Cpp from LUA scripts, so functions created in Cpp side should be called from LUA side. Somewhat the opposite direction of items 4, 5 and 6 of this series. The way is not so difficult once you travelled it, as always! First you have to write a header with your class declaration, then you have to use tolua++ application to translate it to LUA I'll started a new cpp empty project, so i have only: Main.cpp, App.h and App.cpp Added: cToLuaTest.h declaration of the class cToLuaTest.cpp implementation of the class cToLua translation to lua generated by tolua++ cToLua.cpp si generated by tolua++ with the following command line: (on a terminal good great and legendary DOS window.. haa those times!) tolua++ -o cToLua cToLuaTest.h the command line explained: a) first parameter -o nomGeneratedFile :desired name of outputfile b) second parameter cToLuaTest.h :name of input file this generates a long.. more than expected file, that at the end has a function: https://dl.dropboxusercontent.com/u/78894295/leadwerks/cToLua.cpp note: you will have to include as source this file, so name it differently than the cToLuaTest.cpp which implements the class. If you do not especify -o, then the same name as input is assumend, becarefull inside the cToLua.cpp generated by tolua++, almost at the end there is a special function: /* Open function */ TOLUA_API int tolua_cToLua_open(lua_State* tolua_S) { ... } which is used to bind the class to lua. as a helper (from one of the threads cited on first tut) i adopted to write another header to declare the above function. lua_gluecode.h #pragma once #include "Leadwerks.h" using namespace Leadwerks; /* Exported function */ TOLUA_API int tolua_clasetolua_open(lua_State* tolua_S); Following the class declaration and the implementation class cToLuaTest { public: cToLuaTest(void){}; ~cToLuaTest(void){}; void luaCalling(void); float average(void); float aFloat; int intA, intB, intC; }; #include "cToLuaTest.h" //prototypes #include "Leadwerks.h" //uso System de leadwerks por eso la inclusion using namespace Leadwerks; void cToLuaTest::luaCalling(void){ System::Print("lua is calling me!"); } float cToLuaTest::average(void){ return (float)(intA+intB+intC)/3.0f; } Did you expected something more elaborated? sorry then Now the bind part, in Main.app: 1) include the file lua_gluecode.h 2) the following couple of sentences (before app->start) #include "lua_gluecode.h" ... int main(int argc,const char *argv[]) { ... many many lines away of default main.cpp main function ... else { if (Interpreter::L == NULL) Interpreter::Reset(); //--- this line tolua_cToLua_open(Interpreter::L); // and this line //Execute mobile-style App script App* app = new App; if (app->Start()) { while (app->Loop()) {} ... rest of main.cpp } build and voila!, you have all done cpp side! now, go LUA side. as a test, in App.lua, function Start: function App:Start() ... --Load a map local mapfile = System:GetProperty("map","Maps/start.map") if Map:Load(mapfile)==false then return false end System:Print("app.lua start") -- cToLuaTest object created in lua c2luaTest = cToLuaTest:new() --create an instance of cToLuaTest class object if c2luaTest ~= nil then --test if ok System:Print("c2luaTest not nil") c2luaTest:luaCalling() --use one of it's methods, just print "lua is calling me!" on the cpp side end --set some properties c2luaTest.intA = 10 c2luaTest.intA = 35 c2luaTest.intA = 15 --call average an print out the result System:Print(c2luaTest:average()) return true end --of App:Start so easy, isn't it? the end Home, Previous
  15. have to admit that i learn it that yesterday! now i'm cleaning the app before post the "allincluded" one with tolua++ examples also. i'm very happy with the new knowledge so i decided to post it, before it get lost on my mind... and my machine!
  16. 5) How to receive returned parameters from LUA functions (yes one or more) come on, every time i edit the post, code /code get bad formatted and have to manually (again) correct it (really don't like to see un-indented code). So, with an example will see how to receive parameters from LUA function scripts. The example is basically the same as the one exposed in the previous tut (5/7) the only difference is that the function called has a Return sentence so is sending us something, and following the Invoke method, we have to catch that value. It's good to test if the kind of value received is of the correct type and if so, then we have to convert it from LUA type to Cpp type, here an example: LUA function declared on a script attached to the entity used next function Script:average(intA, intB, intC) System:Print("executing average") return (intA + intB + intC)/3 end float call_average(Entity* e, string funcName, int a, int b, int c) { if (e->component == NULL) return false; bool success = false; //Get the component table int stacksize = Interpreter::GetStackSize(); //Get the global error handler function int errorfunctionindex = 0; #ifdef DEBUG Interpreter::GetGlobal("LuaErrorHandler"); errorfunctionindex = Interpreter::GetStackSize(); #endif e->Push(); Interpreter::GetField("script"); if (Interpreter::IsTable()) { System::Print(" entity has script"); Interpreter::GetField(funcName); if (Interpreter::IsFunction()) { System::Print(" " + funcName + " defined"); Interpreter::PushValue(-2);//Push script table onto stack Interpreter::PushInt(a); Interpreter::PushInt(b); Interpreter::PushInt(c); #ifdef DEBUG errorfunctionindex = -(Interpreter::GetStackSize() - errorfunctionindex + 1); #endif success = Interpreter::Invoke(4, 1, errorfunctionindex); //in=4, out=1 // //---------------------------- here the receiving part ******NEW****** // if (success) { if (Interpreter::IsNumber()) { float retValue = Interpreter::ToNumber(); System::Print(retValue); return retValue; } } /* //how to retrieve more than one returned parameter: //if function returns two or more parameters, they are poped in inverse order //so be careful to ask for them in reverse order (from right to left) Interpreter::Pop(); //pop it if (Interpreter::IsNumber()) { float retValue = Interpreter::ToNumber(); System::Print(retValue); } */ } } Interpreter::SetStackSize(stacksize); } Types that can be tested: Interpreter::isBool, isFunction, isBreakpoint, isNumber, isConnected, isString, isObject, isTable Types that can be converted to: Interpreter::toNumber, toString, toBool o toObject not so easy but with a recipe all things are made easy, no? just in case you missed it on the code... if you like you may return more than one value from LUA LUA admit Return to give a list of comma separated values Return value1, value1, ... they are pushed and when popped, came in reverse order you have to use Interpreter::pop() or retrieving each value and then testing it's type and converting back from lua type to c++ type next tut is more long and perhaps i'll post later... Next, Home, Previous
  17. 4) How to call an entity's script LUA function passing parameters following code is some what weird but you only have to pay attention on a few things the idea is Push the parameters in the order they are declared in the lua function (from left to right) and pay attention in the Interpreter:Invoke method. You have to set the first parameter (number of staked values) one more of the amount of parameters passed. consider the following LUA function: function Script:turnMe(turn) System:Print("calling me from C") self.entity:Turn(turn.x,turn.y,turn.z,true) end note that "turn" is a Vec3 variable so you have to push the correct type of variable to lua stack and then tell Interpreter::Invoke that there are 2 things on the stack (as the code explains, one is always present: thank's Josh for that beautiful piece of code!) here is a generic function to call any LUA script function that has one parameter of type Vec3: bool call_turnMe(Entity* e, string funcName, Vec3 vec3){ if (e->component == NULL) return false; bool success = false; //Get the component table int stacksize = Interpreter::GetStackSize(); //Get the global error handler function int errorfunctionindex = 0; #ifdef DEBUG Interpreter::GetGlobal("LuaErrorHandler"); errorfunctionindex = Interpreter::GetStackSize(); #endif e->Push(); Interpreter::GetField("script"); //test if entity has a script if (Interpreter::IsTable()) { System::Print(" entity has script"); Interpreter::GetField(funcName); if (Interpreter::IsFunction()) //test if funcName is a function { System::Print(" " + funcName + " defined"); Interpreter::PushValue(-2); //Push script table onto stack Interpreter::PushVec3(vec3); //we only pass one variable but stack has one more #ifdef DEBUG errorfunctionindex = -(Interpreter::GetStackSize() - errorfunctionindex + 1); #endif success = Interpreter::Invoke(2, 0, errorfunctionindex); // send 2 params, receive none (next tut for receive parameters) } } Interpreter::SetStackSize(stacksize); //keep stack under control } Interpreter has a nice amount of pushes: pushAABB, pushFloat, pushInt, pushString, pushCObject, pushObject, pushBool, pushNull, pushMat3, pushMat4, pushVec2, pushVec3, pushVec4, pushValue just remember: push parameters with the correct type and in order in which they was declared in the LUA function. next tut, show how to pass 3 ints and receive a float, and also show how to receive more than one value from a lua script, because Return in lua may contain a list of values. that's it Next, Home, Previous
  18. 3) How to call an entity's script LUA function easely (without parameters) That's really easy. Suppose you have an entity in your scene with a script attached in which a function "noParams" has been declared function Script:noParams() System:Print("executing noParams") end using the loop exposed on tut 2/7 of this series, you can find that entity and then, to call one of their functions you only have to do: entity->CallFunction("noParams"); // yes only the name also you may check if the entity has a script at all: this is a more generic function to call functions with no parameters: void call_noParams(Entity* e, string funcName){ if (e->script != NULL) e->CallFunction(funcName); // CallFunction only if entity has a script attached } that's it! Next, Home, Previous
  19. 2) How to send objects created by Cpp code to LUA Here is a way of sendign CPP created objects to LUA scripts as GLobal Variables, so any LUA script on you map can simply use it. I create on cpp: window, world and context and pass them this way: System::Print("sending objects...."); stacksize = Interpreter::GetStackSize(); Interpreter::PushObject(window); Interpreter::SetGlobal("window"); Interpreter::PushObject(context); Interpreter::SetGlobal("context"); Interpreter::PushObject(world); Interpreter::SetGlobal("world"); Interpreter::SetStackSize(stacksize); so simple, only after knowing it! i modify App.lua to: not define window, world and context and use them as: if window:Closed() or window:KeyDown(Key.Escape) then --logFile:Release() return false end --Update the app timing Time:Update() --Update the world world:Update() --Render the world world:Render() note : that's a fragment of App.lua main loop (function App:Loop() ) instead of the default: if self.window:Closed() or self.window:KeyDown(Key.Escape) then --logFile:Release() return false end --Update the app timing Time:Update() --Update the world self.world:Update() --Render the world self.world:Render() with tuts 1 and 2 we has ways of sending Leadwerks objects (any Leadwerk's object) to LUA and retrieving LUA objects. Objects sent to lua, will be global to any function on any LUA scritp. Next, Home, Previous
  20. 1) How to get objects created on the editor from Cpp Easy as it seems, getting an editor created object from cpp code is done basically looping on the entities collection, but there are some things that is good to know. First one simple way of doing it: System::Print("start scanning...."); for (auto iter = world->entities.begin(); iter != world->entities.end(); iter++) { Entity* entity = *iter; System::Print(entity->GetKeyValue("name")); if (entity->GetKeyValue("name") == "findMe"){ System::Print(" found entity findMe !!!"); if (entity->script != NULL){ foundEntity = entity; } } } It's supposed that you have a map with an entity named "findMe" if you like you can use: SetKeyValue to give some "custom" attributes to your entities and then instead of testing by a already existing key like name you may test by any custom key of your's if (entity->GetKeyValue("room_number") == "8"){ System::Print(" entity of room 8"+entity->GetKeyValue("name")); if (entity->script != NULL){ foundEntity = entity; } } entities collection has all of them, cameras, lights, models, etc but in some particular situations searching for specific class is necessary: cameras, light has special methods and to work properly it's better to use the correct object. for example to get a camera created on the editor you may: //now look for the editor camera: for (Camera* e : world->cameras) { System::Print(e->GetKeyValue("name")); if (e->GetKeyValue("name") == "EditorCamera"){ camera = e; System::Print("found editor camera"); } } note "camera" is declared on app.h as: Camera* camera; so it's a global already defined that's it, so simple, he? Next, Back
  21. Thnigs i will cover: 1) How to get objects created on the editor from Cpp 2) How to send objects created by Cpp code to LUA 3) How to call an entity's script LUA function easely (without parameters) 4) How to call an entity's script LUA function passing parameters 5) How to receive returned parameters from LUA functions (yes one or more) 6) How to expose a Cpp Class to LUA using tolua++ I will split this post acordingly to the items listed above for easy referencing/reading Here a complete Leadwerks app: cpp source, map and scripts of a working example of the all above. //no longer valid! https://dl.dropboxusercontent.com/u/78894295/leadwerks/cppLuaBindings.zip //2021/12/14 update https://drive.google.com/file/d/1JdewNls8joRJygZ5zkNnuHrnCqNqDl_S/view?usp=sharing (see description of what executable does and how to operate it on a note at the end of this post) I'm not English native, so apologies if i do linguistic mistakes, and i'm not a so experienced cpp programmer (ok i'm not a programmer, I'm a technician in electronics, so for any inconsistency or semantic error/mistake pm me and i'll edit/modify the post, thank's) This site has many topics about this subject but for someone like me many of them has almost all, but normally there are some or too much details which are not exposed. Normally it takes a while to get to the point: do try, pray, try again, reread until ok OR tooLate My intention is to give "allincluded" for new Leadwerks cpp users which is asumed that if they are cpp programmers normally are advanced ones, but being new to Leadwerks normally the learning curve is shorten with material like i'll expose. Here some interesting links on the subject (not all of them) http://www.leadwerks.com/werkspace/topic/11007-calling-lua-script-function-from-c-with-arguments/page__hl__callfunction http://www.leadwerks.com/werkspace/topic/7548-access-cpp-global-via-lua/page__hl__tolua#entry60531 http://www.leadwerks.com/werkspace/topic/8802-tolua-exposure-problems/ http://www.leadwerks.com/werkspace/topic/7866-lua-version-in-30/ http://www.leadwerks.com/werkspace/blog/138/entry-1288-pushing-complex-lua-tables-from-c/ there are many references to: http://www.leadwerks.com/werkspace/files/file/216-tolua/ but this just display: sorry we couldn't find that! so, here is the tolua++ source https://github.com/LuaDist/toluapp documentation https://www8.cs.umu.se/kurser/TDBD12/VT04/lab/lua/tolua%2B%2B.html precompiled http://www.codereactor.net/tolua-windows-precompiled-binary-exe-file-download-and-more-instructions-on-tolua/ (note, the link addressed by autors to download: tolua++ can be downloaded from the sites below: http://www.codenix.com/~tolua/ is broken! ) How hard is to get all the links up to date! isn't it? Items coming soon... jio --------------------------------------------------------------- Notes about the executable: In the terminal window, each Lua function and cpp method throws some info, so move the main window a little to the right, so you can see the terminal window. You'll se something like that, without my comments in italic: app.lua start //things that happens LUA side App.lua Start c2luaTest not nil //instance of object form c created and not nil lua is calling me! //calling an object's method from lua OK 3.3561e+008 //calling average: (10+35+15)/3 :(WRONG! see bellow) start scanning.... //this is cpp side on App.cpp, App::Start //list of objets from the map (world) Directional Light 4 EditorCamera findMe //objet searched found entity findMe !!! // find OK, set a pointer to it for future use. Directional Light 4 EditorCamera //now searching only for cameras found editor camera //found editor camera, got camera from editor! now, put manin window on focus. Press a, s, d, f a: calls average(10, 15, 25) and print the results on the terminal window s: calls average( 5, 10, 4) and print the results on the terminal window d: calls turnMe(vec3) with a default value of: turn.x=10; turn.y = 20; turn.z = 30; if ok, you see the red cube turn this amount per axis on each keyhit. f: calls noParams() and print "executing noParams" As you press each letter, new messages appear on the terminal window confirming functions of lua correctly called from c++ code. if you press a, s, d, f in this sequence, you should see entity has script average defined executing average 16.6667 entity has script average defined executing average 6.33333 entity has script turnMe defined calling me from C executin noParams WRONG display in calling average cpp method from LUA, guess what? a bug. in Start function inside App.lua i do: c2luaTest.intA = 10 c2luaTest.intA = 35 c2luaTest.intA = 15 System:Print(c2luaTest:average()) so I only initialize intA, leaving intB and intC with garbage, so, expect to see any number on each run! Please edit the App.lua for me!
  22. thxs agrror is back again!, i thought he stopped flowgui dev, seems that an update is coming jio
  23. Hi As the subject says. Last forum thread about cegui is about 5 years, I spent last weekend without success. i like to know if currently someone get it working with leadwerks and if it worth the effort. I need a gui for leadwerks, so any advice about some other gui would be appreciated I was testing awesomium but it´s just an interface for a html generated web page/form/dialog and so you have to start codign html, javascript... jquery, jquery UI... i do like a gui that has a layout editor and/or create windows, controls etc, by code. thank's in advance jio
  24. Hi I need 5 cameras and show what each is seeing in separate views. the description of the function SetRenderTarget says: so, i create the cameras, create the textures and set them as render target but textures don't get updated as i guessed. so textures can be drawn on screen but don't get updated. Searching i found this thread http://www.leadwerks.com/werkspace/topic/13211-trouble-with-render-targets/page__hl__setrendertarget#entry93400 and seems that SetRenderTarget can't be used as i supposed it should be. I started to use buffers but seems that i have to do one render world per camera/buffer to get what i want. is it possible to do the same thing without 5 renders? in a smart way which i don't imagine here is the code i get working #include "App.h" using namespace Leadwerks; App::App() : window(NULL), context(NULL), world(NULL), camera(NULL) {} App::~App() { delete world; delete window; } Model* models[5]; //just to show something Camera *cams[5]; // five cameras one for each view Buffer *buffs[5]; // one buffer per view const int numViews = 5; bool App::Start() { window = Window::Create(); context = Context::Create(window); world = World::Create(); Light* light = DirectionalLight::Create(); light->SetRotation(35, 35, 0); // create one object per view models[0] = Model::Box(); models[0]->SetColor(1.0, 0.0, 0.0); models[0]->SetPosition(-4, 0, 0); models[1] = Model::Cylinder(); models[1]->SetColor(0.0, 1.0, 0.0); models[1]->SetPosition(-2, 0, 0); models[2] = Model::Cone(); models[2]->SetColor(0.0, 0.0, 1.0); models[2]->SetPosition(0, 0, 0); models[3] = Model::Cylinder(); models[3]->SetColor(0.0, 1.0, 1.0); models[3]->SetPosition(2, 0, 0); models[4] = Model::Box(); models[4]->SetColor(1.0, 0.0, 1.0); models[4]->SetPosition(4, 0, 0); //create each camera and buffer for (int i = 0; i < numViews; i++){ cams[i] = Camera::Create(); cams[i]->Move(-4 + i * 2, 0, -6); cams[i]->Hide(); buffs[i] = Buffer::Create(context->GetWidth() / numViews, context->GetHeight()); } return true; } bool App::Loop() { if (window->Closed() || window->KeyDown(Key::Escape)) return false; for (int i = 0; i < numViews; i++){ models[i]->Turn(Time::GetSpeed()*0.2*(i+1), 0, 0); } Time::Update(); world->Update(); for (int i = 0; i < numViews; i++){ buffs[i]->Enable(); cams[i]->Show(); world->Render(); //is it neccesary to do 5 world renders? cams[i]->Hide(); buffs[i]->Disable(); } context->Enable(); //draw each buffer for (int i = 0; i < numViews; i++){ context->DrawImage(buffs[i]->GetColorTexture(), i*context->GetWidth()/numViews, 0); context->DrawLine(i*context->GetWidth() / numViews, 0, i*context->GetWidth() / numViews, context->GetHeight()); } context->Sync(); return true; } thank's in advance jio
  25. find a way to send keystrokes! i'm using something like: WebKeyboardEvent keyEvent; char chr; for (int i=1; i<256; i++){ char chr=i; keyEvent.type = WebKeyboardEvent::kTypeKeyDown; keyEvent.native_key_code = chr; webView->InjectKeyboardEvent(keyEvent); keyEvent.type = WebKeyboardEvent::kTypeChar; keyEvent.text[0] = chr; webView->InjectKeyboardEvent(keyEvent); keyEvent.type = Awesomium::WebKeyboardEvent::kTypeKeyUp; keyEvent.native_key_code = chr; webView->InjectKeyboardEvent(keyEvent); } with this code, there are no A/a upper/lower so some key mapping will be necessary
×
×
  • Create New...