Search the Community
Showing results for tags 'C++'.
-
This component generates a Mouse Movement Controller featuring a free-look mode. Typically, such character controllers find application in ARPG (Action Role-Playing Game) or RTS (Real-Time Strategy) games. In this setup, you observe the character from a top-down perspective and direct their movement to a specified position by clicking the left mouse button. The Component itself need the terrain name and the name for the walk animation. Also your character needs an idle animation. You can switch into the "free look mode" by pressing the tab key. Within the "free look mode" you are able to move the camera with "W" "A" "S" "D" free around. If you press tab again you switch the mode back to the character. 1. C++ Header #pragma once #include "UltraEngine.h" #include "GatherWaterTask.h" using namespace UltraEngine; class MouseMovementController : public Component { private: shared_ptr<Map> scene; shared_ptr<NavMesh> nav_mesh; bool freeLook = false; public: string terrainName; string animationName; Vec3 destination; shared_ptr<NavAgent> agent; shared_ptr<Terrain> terrain; shared_ptr<Camera> camera; MouseMovementController(); void Start(); void Update(); bool Load(table& properties, shared_ptr<Stream> binstream, shared_ptr<Map> scene, const LoadFlags flags); bool Save(table& properties, shared_ptr<Stream> binstream, shared_ptr<Map> scene, const SaveFlags flags); shared_ptr<Component> Copy(); }; 2. C++ Source File #include "UltraEngine.h" #include "MouseMovementController.h" MouseMovementController::MouseMovementController() { this->name = "MouseMovementController"; } /// <summary> /// Setup the Controller /// </summary> void MouseMovementController::Start() { auto entity = GetEntity(); ///Create the camera and attach them to the player character this->camera = CreateCamera(entity->GetWorld()); Vec3 currentcameraposition = TransformPoint(0, 15, 5, entity, nullptr); //this->camera->SetParent(entity); this->camera->SetPosition(currentcameraposition, true); this->camera->SetRotation(Vec3(45, 0, 0)); this->camera->SetFov(40); this->camera->Point(entity); ///Creates a navmesh ToDo: Has to changed when the NavMesh bug is fixed this->nav_mesh = CreateNavMesh(entity->GetWorld(), 5, 8, 8); this->nav_mesh->SetPosition(0, 0, 0); this->nav_mesh->Build(); ///Create a new NavAgent for the player character this->agent = CreateNavAgent(this->nav_mesh); entity->Attach(agent); } //Update method, called once per loop void MouseMovementController::Update() { auto entity = GetEntity(); auto window = ActiveWindow(); auto world = entity->GetWorld(); if (window) { ///Set the destination if the player hits the left mouse button if (window->MouseHit(MOUSE_LEFT)) { auto mousePosition = window->GetMousePosition(); auto pick = this->camera->Pick(window->GetFramebuffer(), mousePosition.x, mousePosition.y, 0, true); if (pick.success) { auto pos = pick.position; if (pick.entity->name == this->terrainName) { this->destination = pos; } } } ///Move to the destination if the destination is not null if (this->destination != NULL) { if (entity->position.DistanceToPoint(this->destination) > 1.0f) { this->agent->Navigate(this->destination); auto model = entity->As<Model>(); model->Animate(this->animationName); } else { this->agent->Stop(); auto model = entity->As<Model>(); model->Animate("idle"); this->destination == NULL; } } ///Toggle the freelook mode if (window->KeyHit(KEY_TAB)) { if (this->freeLook) { this->freeLook = false; } else { this->freeLook = true; Vec3 currentcameraposition = TransformPoint(0, 15, 0, GetEntity(), nullptr); this->camera->SetPosition(currentcameraposition, true); this->camera->SetRotation(Vec3(90, 0, 0)); } } ///Position the camera according to the selected mode if (!this->freeLook) { Vec3 currentcameraposition = TransformPoint(0, 15, 5, GetEntity(), nullptr); this->camera->SetPosition(currentcameraposition, true); this->camera->Point(entity); } else { Vec3 camPos = this->camera->GetPosition(); if (window->KeyDown(KEY_W)) { camPos.z += 0.5f; } else if (window->KeyDown(KEY_S)) { camPos.z -= 0.5f; } else if (window->KeyDown(KEY_A)) { camPos.x -= 0.5f; } else if (window->KeyDown(KEY_D)) { camPos.x += 0.5f; } this->camera->SetPosition(camPos); } } } bool MouseMovementController::Load(table& properties, shared_ptr<Stream> binstream, shared_ptr<Map> scene, const LoadFlags flags) { this->scene = scene; this->terrainName = (String)properties["terrainName"]; this->animationName = (String)properties["animationName"]; for (auto e : scene->entities) { if (e->name == terrainName) { this->terrain = std::static_pointer_cast<Terrain>(e); } } return true; } bool MouseMovementController::Save(table& properties, shared_ptr<Stream> binstream, shared_ptr<Map> scene, const SaveFlags flags) { properties["terrainName"] = (String)terrain->name; properties["animationName"] = (String)this->animationName; return true; } shared_ptr<Component> MouseMovementController::Copy() { return std::make_shared<MouseMovementController>(*this); } 3. JSON File { "component": { "properties": [ { "name": "terrainName", "label": "Terrain Name", "value": "" }, { "name": "animationName", "label": "Animation Name", "value": "" } ] } }
-
I've been spending the past few days trying to figure out how to add SDL2 to Leadwerks, as it has an additional Lua binding that would be nice to have. Not to mention the gamepad support (which is the main reason because just adding XInput only would give support for XBox 360 and Dualshock 3 controllers). Not having any experience with an engine like Leadwerks, application building, or libraries has severely impacted my ability to figure out what to do in my current situation. I know I need to include the library and expose it to Lua, but I don't know how to do that, and I don't know how to actually add it to the engine either. I've taken a look at some resources online, such as lazyfoo, and it hasn't really helped me understand. Any help or other resources that could be passed along to me would be greatly appreciated. Thanks!
- 4 replies
-
- programing
- lua
-
(and 2 more)
Tagged with:
-
Version 1.0.0
13 downloads
This small component makes it possible to play and stop animations for models. Various settings are available: AutoPlay: Actually self-explanatory. If this option is activated, the animation is played directly at startup. Loop: If activated, the animation is played in a loop. Name: The name of the animation. Speed: The speed of the animation. Bleed (255): Animation bleeding. In addition, there are two inputs for the Nodegraph: "PlayAnimation" and "StopAnimation". These functions can also be called via C++. -
Wanted to get a start on these after today's discussion. Here is the first draft of the logic components. I'm kind of limited on what I can do without any argument support. I've made the following: Auto - Used to start things on Start or Level Load. (Inspired by logic_auto) Relay - Used as a switch or a delay between connections. You can toggle the component to cut or rejoin connections. (Inspired by logic_relay) RelayTimer - Fires outputs on every interval. (Inspired by logic_timer) PrintMessage - Simply prints whatever to console. This is only my first draft to continue the discussion! Logic.zip
-
This component will copy the rotation of another entity, with adjustable smoothing. MatchRotation.zip
-
Hello I have just got Ultra Engine and have not got it to compile yet. I added missing ATL modules inside visual studio installer, made a new c++ project multiple times and set the optimization to disabled in the project settings. Need help at fixing these errors. The Project is called StereoWindow and i have the exact same problem with another project.
-
I am working my way through some of the sample code and making slight modifications. I am stuck with a very simple problem. I cannot manage to get a model to successfully render a texture. I am using slightly modified code from the leadwerks docs and a stock material. Any insight to my challenged code/thought process is appreciated. #include "App.h" using namespace Leadwerks; App::App() : window(NULL), context(NULL), world(NULL), camera(NULL) {} App::~App() { delete world; delete window; } bool App::Start() { window = Window::Create(); context = Context::Create(window); world = World::Create(); camera = Camera::Create(); camera->SetRotation(5, 0, 0); camera->Move(0, 0, -6); Light* light = DirectionalLight::Create(); light->SetRotation(35, 35, 0); Model* model = NULL; model = Model::Create(); model->SetColor(1.0, 0.0, 1.0); model->SetPosition(0, 0, 0); material = Material::Load("Materials/Concrete/concrete_dirty.mat"); Surface* surface = model->AddSurface(); surface->AddVertex(-0.5, -0.5, 0, 0, 0, -1); surface->AddVertex(0.5, -0.5, 0, 0, 0, -1); surface->AddVertex(0.5, 0.5, 0, 0, 0, -1); surface->AddVertex(-0.5, 0.5, 0, 0, 0, -1); surface->AddTriangle(2, 1, 0); surface->AddTriangle(0, 3, 2); surface->UpdateAABB(); model->SetMaterial(material,1); model->UpdateAABB(Entity::LocalAABB | Entity::GlobalAABB); return true; } bool App::Loop() { if (window->Closed() || window->KeyDown(Key::Escape)) return false; Time::Update(); world->Update(); world->Render(); context->Sync(); return true; }
-
-
Over the past 2 months or so, I was given an assignment to create a program as a part of a college assignment, I chose to use this API As it was recently recommend to me by a friend, I went with an app to help people play dungeons and dragons, as someone who has been playing it for a while I constantly found myself forgetting things or misplaying for various reasons. Included in the app so far, is a character tab that keeps track of everything needed by a player , a pop out dice roller, a spell search engine that can pop out and display more information about a given spell I am currently working on a way to incorporate stat blocks to allow for a greater utility to the user. Would love to hear some feedback.
-
Since this was a hot topic recently, I've written code to preload model files from a map and display a progress bar. Then, when you load the map, it should load much faster since you already "preloaded" the models and the ones in the map will be instances (copies) of existing ones. This is an alternative to Map::Load's hook, which may be a better way to go about this. #include "Leadwerks.h" using namespace Leadwerks; std::string mapfile = "maps/map.map"; string model_file[100]; // Stores list of model files in map Model *preload_model[100]; // Array to preload model files to int modelcount=0; // Counts total number of models found in map file int main(int argc, const char *argv[]) { Leadwerks::Window* window = Leadwerks::Window::Create(); Context* context = Context::Create(window); // Load map as just a file Stream* stream = FileSystem::ReadFile(mapfile); if(stream==NULL) { cout << "Could not open map file to read." << endl; exit(1); } // Put MDL paths/files in a list and get count while(!stream->EOF()) { string line = stream->ReadLine(); // If what we read is a model line (ends with .mdl) if(line.size()>3 && line.compare(line.size() - 4, 4, ".mdl") == 0) model_file[modelcount++]=line; } stream->Release(); cout << "Number of model files in map: " << modelcount << endl; for(int i=0; i<modelcount; i++) { cout << "Preloading file #" << i << ":" << model_file[i] << endl << endl; preload_model[i]=NULL; preload_model[i]=Model::Load(model_file[i]); // You can check if model was properly loaded here (should not be NULL) preload_model[i]->Hide(); // Preload model should not be seen // Draw progress bar context->SetColor(0.0, 0.0, 0.0); context->Clear(); context->SetColor(1.0, 0.0, 0.0); float barwidth = (float)(context->GetWidth())-20.0; barwidth *= (float)(i+1); barwidth /= (float)modelcount; context->DrawRect(10, 10, (int)barwidth, 20); // Remove the below delay line. It's put in just to show progress bar effect Sleep(500); context->Sync(); } // You can then load the map here and it should be much faster // since you already loaded the models in it above // Map::Load(mapfile); // Game code here return 0; }
-
I'm working on a little project where I need to make some simple image processing such as rotation, brightness, contrast and so on. FreeImage is a nice lib for those things and I noticed that it's already included in the FITextueLoader Plugin so that's nice. Is there a way to access the pixel-data in Pixmap so it an be used with the FreeImage functions? Actually something like this: FIBITMAP* Pixmap2FreeImage( std::shared_ptr<Pixmap> pixmap ) { FIBITMAP* bmp = //??? pixmap->???? // ???? return bmp; } std::shared_ptr<UltraEngine::Pixmap> FreeImage2Pixmap(FIBITMAP* source) { std::shared_ptr<UltraEngine::Pixmap> pixmap = std::make_shared<UltraEngine::Pixmap>( ); // ??? return pixmap; }
- 1 reply
-
- c++
- ultra app kit
-
(and 1 more)
Tagged with:
-
My program is working fine in Windows when I use '\n' in a c++ string to get a newline in the text of a label. I have now compiled it on Linux and the newline character is displayed as a character block as if the character cannot be displayed. Is there a way to get Linux to execute the same way as Windows. Here is sample code (a slightly modified version of the label sample code)? #include "UltraEngine.h" using namespace UltraEngine; int main(int argc, const char* argv[]) { //Get the displays auto displays = GetDisplays(); //Create a window auto window = CreateWindow("Ultra Engine", 0, 0, 800, 600, displays[0]); //Create User Interface auto ui = CreateInterface(window); //Create widget auto label1 = CreateLabel("Label", 20, 20, 120, 30, ui->root); auto label2 = CreateLabel("Border\nLabel", 20, 50, 120, 60, ui->root, LABEL_BORDER | LABEL_CENTER | LABEL_MIDDLE); while (window->Closed() == false) { WaitEvent(); } return 0; }
-
Hi, I have encountered a problem using threads with the help of classes. I have been using sample codes so far as well as browsing the forum, but unfortunately I cannot find an answer to this problem. Following the guide about threads I got something like this Unfortunately I don't understand why a function of void type not belonging to a class passes in the compilation without any problem, but in the other direction it doesn't. I apologize for bothering you with probably simple problems and for my poor English Thanks
-
Built to power a new generation of game development tools, Ultra App Kit provides an easy-to-use C++ programming SDK for creating desktop GUI applications. Unlike other alternatives like Dear ImGui, the Ultra App Kit GUI renders in retained mode rather than immediate mode, and is specifically designed for desktop GUI applications. This makes applications snappy and responsive when resizing or refreshing a window. DPI scaling is baked into the design for resolution-independent graphics on any screen. The GUI can be combined with an embedded OpenGL viewport, or combined with a 3D game engine to make custom editors and game development tools. Check out the video tutorials and read the documentation to learn more. Ultra App Kit can be purchased in our store. API Design C++ shared pointers everywhere Extensible widgets system Extensive documentation with examples for each command UI Features Resolution independent for any DPI scale Load SVG vector images Set widget icons Change mouse cursor Custom color schemes stored in JSON files Supported Widgets Label Button (push, checkbox, radio, and toggle styles) ProgressBar TextField TextArea ComboBox ListBox Slider (scrollbar, trackbar, and stepper styles) Draggable multi-select TreeView Create your own custom widgets Additional Features File I/O File system watcher Memory allocation and management Image loading, saving, processing Package system for loading files from compressed / encrypted archives Plugin system Thread management String manipulation (split, search, conversion, etc.) Message boxes and file / folder requester
-
This will create a "spinner" widget like in 3ds max. You can use SetRange() to control the min and max values. Download: Spinner.h Example: #include "UltraEngine.h" #include "Spinner.h" using namespace UltraEngine; int main(int argc, const char* argv[]) { //Get displays auto displays = GetDisplays(); //Create window auto mainwindow = CreateWindow("Spinner", 0, 0, 800, 600, displays[0]); //Create user interface auto ui = CreateInterface(mainwindow); iVec2 sz = ui->root->ClientSize(); //Create spinners auto ispinner = CreateSpinner(20, 20, 100, 30, ui->root, SPINNER_INTEGER); auto fspinner = CreateSpinner(20, 60, 100, 30, ui->root, SPINNER_FLOAT); auto nspinner = CreateSpinner(20, 100, 100, 30, ui->root, SPINNER_FLOAT | SPINNER_NORMALIZE); //Show the window mainwindow->Show(); mainwindow->Activate(); //Easier to work with: ui->SetScale(2); while (true) { const Event event = WaitEvent(); switch (event.id) { case EVENT_WIDGETACTION: if (event.source == ispinner) Print(event.data); if (event.source == fspinner or event.source == nspinner) { Print(event.source->As<Widget>()->GetProgress()); } break; case EVENT_WINDOWCLOSE: if (event.source == mainwindow) return 0; break; } } return 0; }
-
I worked the half day on that problem and I think I give the information to everyone who also has this problem with fog. In the Editor fog looks a little bit like fog. Without implementig fog in C++ source, no fog is visible in C++. Loading a map after craeting a camera only a touch of a color is visible in the very far, and fog is not working as it should. I mean with map not a terrain, I loaded a map with only a plattform and some prefabs. I have not tested with terrain. So load a map before creating a camera. Nothing works correct if you not do that.
-
First step C++ First Player game start
Bytecroc posted a blog entry in [C++] First Player game start
Since 3 years I have not programmed anything with Leadwerks, that has nothing to do with Leadwerks it was a real life thing. So I must learn the stuff from the beginning. My natural language is not English, I hope you can forgive me a mistake or two . If you want test the code you make a new project and a map. I made some test objects to see if climbing fails or not and under which steps I can crouch and on which step I can jump. I make this blog for me to save the source code. Two times in my life I lost nearly all my source I programmed by HardDrive crashes. So it is a nice thing to have that online. And for beginnes to have a start code. In your project folder, by me in "documents/Leadwerks/Projects/.... <-- here are my Projects" you have a subfolder also named projects: "documents/Leadwerks/Projects/ProjectName/projects/" by me in the folder windows is the VisualStudio 17 project: "ProjectName.sln" << Start this with Doubleclick, but first install VisualStudio. I delete all the stuff inside main.cpp, App.cpp and app.h and put the following code in main.cpp change your mapname > "YouMapName.map" from your project and compile. I can not say whats the menu names in english because I have the german GUI. For VisualStudio tutorials look in the Web or YouTube, I am sure there are dozens of them. #include "Leadwerks.h" #include <string> using namespace Leadwerks; int screenwidth = GetSystemMetrics(0); int screenheight = GetSystemMetrics(1); Window* window; Context* context; World* world; Model* thePlayer; Camera* theCam; // declare functions that we need, they are used once so I made them inline for faster code. inline void Start(); inline void loop(); inline void DrawInfo(); //crouch, crawl, jog, run // used for mouse handling Vec3 mausdata = Vec3(0, 0, 0); float mausx = 0.0; float mausy = 0.0; // used for player movement Vec3 mdat = Vec3(0, 0, 0); Vec3 ppos = Vec3(0, 0, 0); Vec3 velo = Vec3(0, 0, 0); float walk = 0.0; float strafe = 0.0; float jump = 0.0; float crouch = 0.0; float strafespeed = 2.0; float movespeed = 2.4; float jumpspeed = 5.0; bool cdown = 0; bool sdown = 0; // used for mainloop bool mainloop = true; // mainfunction int main(int argc,const char *argv[]) { // hold the mainfuntion small and insert what we need with an inline function. Start(); // mainloop while (mainloop) { loop(); // Here is the most mailoop stuff if (window->Closed() || window->KeyDown(Key::Escape)) mainloop = false; //Quit if ESC is pressed Leadwerks::Time::Update(); world->Update(); world->Render(); // For holding the mainloop small put all drawing stuff inside an inline function. DrawInfo(); context->Sync(true); } return 0; } // Inline functions we use only once. inline void DrawInfo() { // For the first, all the drawing stuff in this funtion. context->SetBlendMode(Blend::Alpha); context->SetColor(1.0, 1.0, 1.0); context->DrawText("Camera Rotation: " + theCam->GetRotation().ToString(), 2, 2); context->DrawText("Player Position: " + thePlayer->GetPosition().ToString(), 2, 40); context->DrawText("Player Position: " + std::to_string(ppos[0]), 2, 70); context->DrawText("Player Position: " + std::to_string(ppos[1]), 2, 100); context->DrawText("Player Position: " + std::to_string(ppos[2]), 2, 130); context->DrawText("UPS: " + String(Time::UPS()), 2, 160); context->DrawText("Velocity: " + thePlayer->GetVelocity().ToString(), 2, 190); // a way to check if the player is not on ground, for possibly later use. if (thePlayer->GetAirborne()) { context->DrawText("In the air", 2, 220); } context->SetBlendMode(Blend::Solid); } inline void Start() { // Window //window = Window::Create("",0,0, 2560, 1440, Window::Fullscreen); //window = Window::Create("", 0, 0, screenwidth, screenheight, Window::Fullscreen); window = Window::Create("", 0, 0, screenwidth, screenheight); context = Context::Create(window); window->Maximize(); // The world world = World::Create(); // The player that we need for "First Player Sight" thePlayer = Model::Create(); thePlayer->SetPhysicsMode(Entity::CharacterPhysics); thePlayer->SetPosition(0, 5, 0); thePlayer->SetMass(1); // Put the camera as a child to the player, so we can move and look up and down separately theCam = Camera::Create(thePlayer); theCam->SetPosition(0,1.65,0); // Font we use for drawing operations Font* font = Font::Load("Fonts/Arial.ttf", 12); context->SetFont(font); // Map //Map::Load("Maps/TheWorld.map"); Map::Load("Maps/BetonMap.map"); // <<<<----- put here your mapname ............................................. } inline void loop() { ppos = thePlayer->GetPosition(); mausdata = window->GetMousePosition(); mausx += (mausdata[0] - window->GetWidth() / 2) * 0.1; mausy += (mausdata[1] - window->GetHeight() / 2) * 0.1; window->SetMousePosition(window->GetWidth() / 2, window->GetHeight() / 2); // not Shift: walk if (!window->KeyDown(Key::Shift) && sdown == 1) { sdown = 0; movespeed = 2.4; } //Shift: run if (window->KeyDown(Key::Shift) && sdown == 0) { sdown = 1; movespeed = 5.0; } // not CTRL: stay if (!window->KeyDown(Key::ControlKey) && cdown == 1) { cdown = 0; movespeed = 3.0; ppos = thePlayer->GetPosition(); theCam->SetPosition(0,1.65, 0); crouch = 0; } // CTRL: crouch if (window->KeyDown(Key::ControlKey) && cdown == 0) { cdown = 1; movespeed = 1.0; crouch = 1; ppos = thePlayer->GetPosition(); theCam->SetPosition(0,0.95,0); } // Walk with movespeed when press Key W walk = (window->KeyDown(Key::W) - window->KeyDown(Key::S)) * movespeed; strafe = (window->KeyDown(Key::D) - window->KeyDown(Key::A)) * strafespeed; // check if player is on ground, this means velo[1] = "y direction" has no velocity = 0 // in this way the player kann not jump if he is already in the air. velo = thePlayer->GetVelocity(); if (velo[1] == 0.0) { jump = window->KeyHit(Key::Space) * jumpspeed; } else { jump = window->KeyHit(Key::Space) * 0.0; } if (mausy > 50.0) mausy = 50.0; if (mausy < -90.0 ) mausy = -90.0; thePlayer->SetInput(mausx, walk, strafe, jump, crouch); //void SetInput(float angle, float move, float strafe = 0, float jump = 0, const bool crouch = false, const float maxaccel = 1, const float maxdecel = 0.5, const bool detailed = false, const float maxrotationspeed = 5.0) theCam->SetRotation(mausy, 0, 0); mdat = theCam->GetRotation(); } The next step I will made is to put the code into a class. Use the C Key for toggle crouching and use the CTRL for faster runnig, the I have walk with Key W, jogging with Shift+W and running with CTRL and W. -
Leadwerks C++ Noob here... So I'm programmatically creating a bunch of floor tiles out of PolyMesh for my player to walk around on, and it works great except for one strange behavior. When I call Translate() on my tile Model class it slowly erodes/squishes the PolyMesh data until it is gone completely, and then my player just falls through. If I don't translate, no problem. I looked into the docs a bit and I see that PolyMesh isn't recommended for moving objects. However when I try the same with ConvexHull() I am getting no collision data at all. My tiles are basically small flat planes created from 2 triangles to make a rectangle. On create... /* * Generate a cTile * ofs of entire tile position from center * dim is width and length|depth */ Model* make_ctile(Vec3 ofs, Vec3 dim) { Model* cmodel = Model::Create(); cmodel->SetColor(1., 1., 1.); Surface* csurface = cmodel->AddSurface();//Surface::Create();// Vec3 dn = Vec3(0, 1, 0); // up csurface->AddVertex(-dim.x, 0, -dim.y, dn.x, dn.y, dn.z); // bl csurface->AddVertex(dim.x, 0, -dim.y, dn.x, dn.y, dn.z); // br csurface->AddVertex(dim.x, 0, dim.y, dn.x, dn.y, dn.z); // tr csurface->AddVertex(-dim.x, 0, dim.y, dn.x, dn.y, dn.z); // tl // CW csurface->AddTriangle(2, 1, 0); // tr, br, bl csurface->AddTriangle(0, 3, 2); // bl, tl, tr csurface->Update(); csurface->UpdateNormals(); ; Shape* cshape = Shape::PolyMesh(csurface); cmodel->SetShape(cshape); cshape->Release(); cmodel->SetPhysicsMode(Entity::RigidBodyPhysics); cmodel->SetCollisionType(Collision::Prop); ; cmodel->Translate(ofs); return cmodel; } On update... for (int i = 0; i < tilex; i++) { // Pull tiles tiles[i].tile->Translate(0, 0, tile_speed); } Included is a view of the collision working when there is no translation, and also a view of the collision failing after translation has started. I also included a screenshot of the output when I use ConvexHull to generate the shape, which seems to not have any collision data whatsoever. Shape* cshape = Shape::ConvexHull(csurface);// PolyMesh(csurface); I'm not really sure what to try next.
-
Hello community, long time no see. I am working on my own graphical user interface, for my super duper rpg game :). The use separate textures for each button state, etc. I consider it not effective! It is better to load the texture with the atlas of the whole GUI once. And use her. In order to draw a texture from the atlas, we need to slightly modify the standard shader (drawimage), and save it under a different name (drawimagerect). Shader #version 400 uniform vec4 drawcolor; uniform sampler2D texture0; uniform vec4 rect; in vec2 vTexCoords0; out vec4 fragData0; void main(void) { ivec2 ts = textureSize(texture0, 0); vec4 coord = vec4(rect.x / ts.x, rect.y / ts.y, rect.z / ts.x, rect.w / ts.y); vec2 uv = coord.xy + (vTexCoords0 * coord.zw); fragData0 = drawcolor * texture(texture0,uv); } Now we can draw a texture from the atlas: void drawImageRect(Texture* texture, float x, float y, Vec4 rect) { Context* context = Context::GetCurrent(); context->SetShader(Shader::Load("Shaders/Drawing/drawimagerect.shader")); context->GetShader()->SetVec4("rect", rect); context->DrawImage(texture, x, y, rect.z, rect.w); context->SetShader(NULL); } void drawImageRect(Texture* texture, float x, float y, float width, float height, Vec4 rect) { Context* context = Context::GetCurrent(); context->SetShader(Shader::Load("Shaders/Drawing/drawimagerect.shader")); context->GetShader()->SetVec4("rect", rect); context->DrawImage(texture, x, y, width, height); context->SetShader(NULL); } Animation To play the animation we need to get the coordinates of all the frames in the atlas. Naturally, we won't do this manually, will write a small algorithm. bool isEmptyFrame(char* pixels, int textureWidth, iVec2 position, iVec2 frameSize, const bool alpha=true, const iVec3 colorBg=iVec3()) { unsigned char r, g, b, a; int level = 0; for (int y = position.y; y < position.y + frameSize.y; y++) { for (int x = position.x; x < position.x + frameSize.x; x++) { int p = (y * textureWidth + x) * 4; memcpy(&r, pixels + p + 0, 1); memcpy(&g, pixels + p + 1, 1); memcpy(&b, pixels + p + 2, 1); memcpy(&a, pixels + p + 3, 1); if (!alpha) { if ((int)r == colorBg.r && (int)g == colorBg.g && (int)b == colorBg.b) { level++; } else { return false; } } else { if ((int)a == 0) { level++; } else { return false; } } } } float percent = (float)((float)level / (float)(frameSize.x * frameSize.y)) * 100.0f; if (percent >= 100.0f) { return true; } return false; } void getFrames(Texture* texture, iVec2 framesize, std::vector<Vec4> &frames) { if (texture == nullptr) return; int horizontLine = texture->GetWidth() / framesize.x; int verticalLine = texture->GetHeight() / framesize.y; int frameCount = horizontLine * verticalLine; int currentHorizont = 0; int currentVertical = 0; iVec2 framePosition = iVec2(); iVec2 frameSize = framesize; char* pixels = (char*)malloc(texture->GetMipmapSize(0) * 8); texture->GetPixels(pixels); System::Print((std::string)"Get frames from texture atlas \"" + texture->GetPath() + "\"..."); // Push first frame int skipCount = 0; if (!isEmptyFrame(pixels, texture->GetWidth(), framePosition, frameSize)) { frames.push_back(Vec4((float)framePosition.x, (float)framePosition.y, (float)frameSize.x, (float)frameSize.y)); } else { skipCount++; System::Print((std::string)"Frame #0" + " is empty. (skip)"); } for (int i = 1; i < frameCount; i++) { if (currentHorizont < horizontLine - 1) { currentHorizont++; framePosition.x = frameSize.x * currentHorizont; } else { if (currentVertical < verticalLine - 1) { currentVertical++; framePosition.x = 0; framePosition.y = frameSize.y * currentVertical; currentHorizont = 0; } } if (!isEmptyFrame(pixels, texture->GetWidth(), framePosition, frameSize)) { frames.push_back(Vec4((float)framePosition.x, (float)framePosition.y, (float)frameSize.x, (float)frameSize.y)); } else { skipCount++; System::Print((std::string)"Frame #" + std::to_string(i) + " is empty. (skip)"); } } System::Print((std::string)"Frame count: " + std::to_string(frames.size()) + ", skip: " + std::to_string(skipCount)); free(pixels); } Now that we have all the frames, we can play the animation. Texture* atlas = Texture::Load("Textures/atlas.tex"); std::vector<Vec4> frames; getFrames(atlas, iVec2(96, 96), frames); float frame = 0.0f; float frameend = frames.size(); float framebegin = 0.0f; float speed = 0.1f; //Loop frame += Time::GetSpeed() * speed; frame = fmodf(frame, frameend - framebegin) + framebegin; //Draw drawImageRect(atlas, 25.0f, 25.0f, frames[(int)frame]); Updates: [04.04.2020] [+] Added check for empty frames.
-
Hello again. Implemented UTF8 support for LE4. Works fine?. context->SetBlendMode(Blend::Alpha); context->DrawText(u8"Привет мир! Hello world!", 25.0f, 25.0f); context->SetBlendMode(Blend::Solid); Add yours symbols to "familychars" and make own "family" in Font.cpp if (family==Font::English) { familychars = L"abcdefghijklmnopqrstuvwxyzабвгдеёжзийклмнопрстуфхцчшщъыьэюя АБВГДЕЁЖЗИКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-=!@#$%^&*()_+[]\\{}|;':\",./<>? `~"; } Update: #include <codecvt> std::string WideStringToString(const std::wstring & str) { std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv; return myconv.to_bytes(str); } std::wstring StringToWideString(const std::string & str) { std::wstring_convert<std::codecvt_utf8<wchar_t>> convert; return convert.from_bytes(str); } Gud luck?️! FontSrc.zip
-
Actually it is very simple. As usual, we need to export the functions we are interested in to the Dynamic Library (DLL), and then import them into our C# program. Let's start. C++ DLL The first thing we need is to create a project in C++ for our future DLL, and of course configure it for the Leadwerks engine Configuration for Release Right-click on the project and select Property. In the window that appears, go to the tab "С/C++" / "General". Copy and Paste to a "Additional Include Directories" this: $(LeadwerksHeaderPath)\Libraries\NewtonDynamics\sdk\dgCore;$(LeadwerksHeaderPath)\Libraries\NewtonDynamics\sdk\dgNewton;$(LeadwerksHeaderPath)\Libraries\libvorbis\include;$(LeadwerksHeaderPath)\Libraries\libogg\include;$(LeadwerksHeaderPath)\Libraries\openssl\include;$(LeadwerksHeaderPath);$(LeadwerksHeaderPath)\Libraries\VHACD\src\VHACD_Lib\inc;$(LeadwerksHeaderPath)\Libraries\glslang;$(LeadwerksHeaderPath)\Libraries\freetype-2.4.7\include;$(LeadwerksHeaderPath)\Libraries\OpenAL\include;$(LeadwerksHeaderPath)\Libraries\NewtonDynamics\sdk\dMath;$(LeadwerksHeaderPath)\Libraries\NewtonDynamics\sdk\dgTimeTracker;$(LeadwerksHeaderPath)\Libraries\NewtonDynamics\sdk\dContainers;$(LeadwerksHeaderPath)\Libraries\NewtonDynamics\sdk\dCustomJoints;$(LeadwerksHeaderPath)\Libraries\RecastNavigation\RecastDemo\Include;$(LeadwerksHeaderPath)\Libraries\RecastNavigation\DetourCrowd\Include;$(LeadwerksHeaderPath)\Libraries\RecastNavigation\DetourTileCache\Include;$(LeadwerksHeaderPath)\Libraries\RecastNavigation\DebugUtils\Include;$(LeadwerksHeaderPath)\Libraries\RecastNavigation\Recast\Include;$(LeadwerksHeaderPath)\Libraries\RecastNavigation\Detour\Include;$(LeadwerksHeaderPath)\Libraries\tolua++-1.0.93\include;$(LeadwerksHeaderPath)\Libraries/lua-5.1.4;$(LeadwerksHeaderPath)\Libraries/glew-1.6.0/include/GL;$(LeadwerksHeaderPath)\Libraries\glew-1.6.0\include;$(LeadwerksHeaderPath)\Libraries\enet-1.3.1\include;$(LeadwerksHeaderPath)\Libraries\zlib-1.2.5;$(LeadwerksHeaderPath)\Libraries\freetype-2.4.3\include;%(AdditionalIncludeDirectories) Go to "Preprocessor", in "Preprocessor Definitions" copy and paste this: WIN32;NDEBUG;LEADWERKS_EXPORTS;_WINDOWS;_USRDLL;PSAPI_VERSION=1;__STEAM__;_CUSTOM_JOINTS_STATIC_LIB;FT2_BUILD_LIBRARY;LEADWERKS_3_1;DG_DISABLE_ASSERT;WINDOWS;OS_WINDOWS;OPENGL;PLATFORM_WINDOWS;_WIN_32_VER;_NEWTON_USE_LIB;PTW32_STATIC_LIB;PTW32_BUILD;_NEWTON_STATIC_LIB;_LIB;DG_USE_NORMAL_PRIORITY_THREAD;GLEW_STATIC;_STATICLIB;%(PreprocessorDefinitions) Go to "Code Generation". Set these values: Enable Minimal Rebuild = Yes(/Gm) Runtime Library = Multi-threaded (/MT) Enable Function-Level-Linking = Yes (/Gy) Go to "Precompiled Header" and set: "Not Using Precompiled Headers" Now go to the "Linker" / "General" tab, then in "Additional Library Directories" copy and paste this: $(LeadwerksLibPath)\Windows\x86;$(LeadwerksLibPath)\Windows\x86\Release;C:/Leadwerks\Engine\Source\Libraries\OpenAL/libs/Win32/EFX-Util_MT;C:/Leadwerks\Engine\Source\Libraries\OpenAL/libs/Win32;%(AdditionalLibraryDirectories) Go to "Input", in "Additional Dependencies" copy and paste this: newton.lib;dContainers.lib;dCustomJoints.lib;libcryptoMT.lib;libsslMT.lib;Rpcrt4.lib;crypt32.lib;libcurl.lib;Leadwerks.lib;msimg32.lib;lua51.lib;steam_api.lib;OpenAL32.lib;ws2_32.lib;libovr.lib;newton.lib;dContainers.lib;dCustomJoints.lib;OpenGL32.lib;Glu32.lib;winmm.lib;Psapi.lib;%(AdditionalDependencies) Propery Sheet Right-click on the project and select "Add \ New Item \ Property Sheets \ Property Sheet" click Add button. Open it and paste this text: Warning! Keep in mind that the paths may be different, check them out. <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ImportGroup Label="PropertySheets" /> <PropertyGroup Label="UserMacros"> <LeadwerksHeaderPath>C:/Program Files (x86)/Steam/steamapps/common/Leadwerks\Include</LeadwerksHeaderPath> <LeadwerksLibPath>C:/Program Files (x86)/Steam/steamapps/common/Leadwerks\Library</LeadwerksLibPath> </PropertyGroup> <PropertyGroup /> <ItemDefinitionGroup /> <ItemGroup> <BuildMacro Include="LeadwerksHeaderPath"> <Value>$(LeadwerksHeaderPath)</Value> <EnvironmentVariable>true</EnvironmentVariable> </BuildMacro> <BuildMacro Include="LeadwerksLibPath"> <Value>$(LeadwerksLibPath)</Value> <EnvironmentVariable>true</EnvironmentVariable> </BuildMacro> </ItemGroup> </Project> If all the paths match, you can import it into the project. Go to menu "VIEW / Other Windows / Property Manager" Click button "Add Existing Property Sheet". On this with the project settings everything =). Now we can go directly to the code. This is part of the functions required for a simple program; you can add other functions yourself. // Leadwerks.cpp : Defines the exported functions for the DLL application. // #include "Leadwerks.h" using namespace Leadwerks; #define EXPORT extern "C" __declspec(dllexport) // ---------------------------------------------------------------------------------- // SYSTEM // ---------------------------------------------------------------------------------- EXPORT void LE_System_Initialize() { System::Initialize(); } EXPORT void LE_System_Shutdown() { System::Shutdown(); } EXPORT void LE_System_SetAppName(const char* name) { System::AppName = name; } EXPORT void LE_System_SetAppPath(const char* path) { System::AppPath = path; } // ---------------------------------------------------------------------------------- // WINDOW // ---------------------------------------------------------------------------------- EXPORT Window* LE_Window_Create(HWND hwnd) { return Window::Create(hwnd); } EXPORT void LE_Window_Free(Window* window) { delete window; } EXPORT bool LE_Window_Closed(Window* window) { return window->Closed(); } EXPORT bool LE_Window_KeyHit(Window* window, int keycode) { return window->KeyHit(keycode); } // ---------------------------------------------------------------------------------- // CONTEXT // ---------------------------------------------------------------------------------- EXPORT Context* LE_Context_Create(Window* window) { return Context::Create(window); } EXPORT void LE_Context_Free(Context* context) { delete context; } EXPORT void LE_Context_Sync(Context* context, bool sync) { context->Sync(sync); } // ---------------------------------------------------------------------------------- // WORLD // ---------------------------------------------------------------------------------- EXPORT World* LE_World_Create() { return World::Create(); } EXPORT void LE_World_Free(World* world) { delete world; } EXPORT void LE_World_Update(World* world) { world->Update(); } EXPORT void LE_World_Render(World* world) { world->Render(); } // ---------------------------------------------------------------------------------- // CAMERA // ---------------------------------------------------------------------------------- EXPORT Camera* LE_Camera_Create() { return Camera::Create(); } EXPORT void LE_Camera_SetClearColor(Camera* camera, float r, float g, float b, float a) { camera->SetClearColor(r, g, b, a); } Press "Ctrl+Shift+B" C# After a successful build, let's move on to C#. Let's create a new project "Windows Forms App" Here is the program code for an example: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace LETest { public partial class Form1 : Form { const string LEDLL = "Leadwerks.dll"; [DllImport(LEDLL)] public static extern void LE_System_Initialize(); [DllImport(LEDLL)] public static extern void LE_System_Shutdown(); [DllImport(LEDLL)] public static extern void LE_System_SetAppName(String name); [DllImport(LEDLL)] public static extern void LE_System_SetAppPath(String path); IntPtr window; [DllImport(LEDLL)] public static extern IntPtr LE_Window_Create(IntPtr hwnd); [DllImport(LEDLL)] public static extern void LE_Window_Free(IntPtr window); IntPtr context; [DllImport(LEDLL)] public static extern IntPtr LE_Context_Create(IntPtr window); [DllImport(LEDLL)] public static extern void LE_Context_Free(IntPtr context); [DllImport(LEDLL)] public static extern void LE_Context_Sync(IntPtr context, bool sync); IntPtr world; [DllImport(LEDLL)] public static extern IntPtr LE_World_Create(); [DllImport(LEDLL)] public static extern void LE_World_Free(IntPtr world); [DllImport(LEDLL)] public static extern void LE_World_Update(IntPtr world); [DllImport(LEDLL)] public static extern void LE_World_Render(IntPtr world); IntPtr camera; [DllImport(LEDLL)] public static extern IntPtr LE_Camera_Create(); [DllImport(LEDLL)] public static extern void LE_Camera_SetClearColor(IntPtr camera, float r, float g, float b, float a); Thread loopThread; bool isAppWork; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { isAppWork = true; loopThread = new Thread(EngineUpdate); loopThread.IsBackground = true; loopThread.Start(); } private void EngineUpdate() { //Initialize LE_System_Initialize(); window = LE_Window_Create(panel1.Handle); context = LE_Context_Create(window); world = LE_World_Create(); camera = LE_Camera_Create(); LE_Camera_SetClearColor(camera, 0.0f, 0.0f, 1.0f, 1.0f); //Main loop while (isAppWork) { LE_World_Update(world); LE_World_Render(world); LE_Context_Sync(context, true); } //Free LE_World_Free(world); LE_Context_Free(context); LE_Window_Free(window); LE_System_Shutdown(); } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { //isAppWork = false; loopThread.Abort(); loopThread = null; } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { isAppWork = false; } } } Copy you'r "DLL" to bin folder. UPDATE: Copy these file from you'r leadwekrs project to c# bin folder: Shaders folder dContainers.dll dContainers_d.dll dCustomJoints.dll dCustomJoints_d.dll libcurl.dll lua51.dll newton.dll newton_d.dll openvr_api.dll steam_api.dll
-
-
Can i create a fracture sim based with voronoi in Leadwerks that control over on vertices or edges ? is it possible ? Lua or C++?
-
Hi. I want to load the player entity position from an object in the editor. It works very well but; I want to spawn in the center of the scene when there is no object named "info_player_start". When I remove the comment lines, it always spawns at the center of the scene. I don't understand why. Here is my code... #include "Game.h" Game::Game() { loadMap(); loadEntities(); player = new Player(playerStartPosition); } Game::~Game() { delete player; } void Game::loadMap() { std::string mapname = System::GetProperty("map", "Maps/start.map"); if (!Map::Load(mapname)) Debug::Error("Failed to load map \"" + mapname + "\"."); } void Game::loadEntities() { for (const auto e : World::GetCurrent()->entities) { if (e->GetKeyValue("name") == "info_player_start") { playerStartPosition = e->GetPosition(); } /*else { playerStartPosition = Vec3(0.0f, 0.0f, 0.0f); }*/ } } void Game::Update() { player->Update(); }