Josh Posted August 20, 2022 Share Posted August 20, 2022 This example shows how you can create two different navigation meshes and mix them together to handle characters of different sizes. The big navagent gets manually positioned on the smaller navmesh, so the small agent naturally gets out of his way. You can also position and rotate navigation meshes! For a small/medium terrain you could probably use a single navmesh, but for a very big game you would probably want to create separate navmeshes for each village or "area of interest", connecting the different navmeshes with some kind of waypoint system. Requires a new build of the library, which I am about to upload... #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, 1280, 720, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); //Create a world auto world = CreateWorld(); //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Create a camera auto camera = CreateCamera(world); camera->SetClearColor(0.125); camera->SetRotation(45,0,0); camera->Move(0, 0, -10); camera->SetFOV(70); camera->SetDebugNavigationMode(true); //Create light auto light = CreateLight(world, LIGHT_DIRECTIONAL); light->SetRotation(65, 35, 0); //Create the scene auto ground = CreateBox(world, 100, 1, 100); ground->SetPosition(0, -0.5, 0); ground->Staticize(); auto block = CreateBox(world, 1, 2, 4); block->SetPosition(0, 1, 0); //Create navigation mesh auto navmesh = CreateNavMesh(world, 20, 10, 10, 8, 4); navmesh->Build(); //Create the player auto player = CreatePivot(world); auto model = CreateCylinder(world, 0.5, 1.8); model->SetPosition(0, 0.9, 0); model->SetParent(player); auto agent = CreateNavAgent(navmesh, 0.5, 1.8); agent->SetPosition(2, 0, 0); player->Attach(agent); //Create navigation mesh auto navmesh2 = CreateNavMesh(world, 20, 10, 10, 8, 4, 0.25, 1); navmesh2->Build(); //Create big player auto player2 = CreatePivot(world); auto model2 = CreateCylinder(world, 1, 4); model2->SetPosition(0, 2, 0); model2->SetParent(player2); auto agent2 = CreateNavAgent(navmesh2, 1, 4); agent2->SetPosition(-3, 0, 0); player2->Attach(agent2); //Create dummy player for small navmesh to act as an obstacle auto agent3 = CreateNavAgent(navmesh, 1, 4); /* block->Translate(10, 0, 10); navmesh->SetPosition(Vec3(10, 0, 10)); navmesh->SetPosition(Vec3(10, 0, 10)); agent->SetPosition(10 + 2, 0, 10); agent2->SetPosition(10 - 2, 0, 10); */ //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { //Move dummy obstacle agent3->SetPosition(player2->position); if (window->MouseHit(MOUSE_LEFT)) { iVec3 pos = window->GetMousePosition(); auto raycast = camera->Raycast(framebuffer, Vec2(pos.x, pos.y)); if (raycast.success) { agent->Navigate(raycast.position); agent2->Navigate(raycast.position); } } camera->UpdateControls(window); world->Update(); world->Render(framebuffer); } return 0; } Here's an earlier example of this feature: 3 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Josh Posted August 22, 2022 Author Share Posted August 22, 2022 I've got dynamically recalculating navmeshes working with terrain now. Terrain was the big reason dynamic navmeshes were scrapped in Leadwerks, but with a little more care I was able to make it work in Ultra: This is my list of things to do now: Terrain collision Terrain get normal at point Terrain navmesh GI for dynamic objects Directional light shadows Motion blur 2 2 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Josh Posted August 23, 2022 Author Share Posted August 23, 2022 Proof it is working.. #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, 1280, 720, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR); //Create a world auto world = CreateWorld(); //Create a framebuffer auto framebuffer = CreateFramebuffer(window); //Create a camera auto camera = CreateCamera(world); camera->SetClearColor(0.125); camera->SetRotation(45,0,0); camera->Move(0, 0, -10); camera->SetFOV(70); //Create light auto light = CreateLight(world, LIGHT_DIRECTIONAL); light->SetRotation(65, 35, 0); //Create the scene //auto ground = CreateBox(world, 100, 1, 100); //ground->SetPosition(0, -0.5, 0); //ground->Staticize(); auto block = CreateBox(world, 4, 500, 1); block->SetPosition(0, 1, 0); //Create navigation mesh auto navmesh = CreateNavMesh(world, 200, 1000, 200, 20, 20); navmesh->SetPosition(0, 500, 0); //Create the player auto player = CreatePivot(world); auto model = CreateCylinder(world, 0.5, 1.8); model->SetPosition(0, 0.9, 0); model->SetParent(player); auto agent = CreateNavAgent(navmesh, 0.5, 1.8); agent->SetPosition(2, 0, 0); player->Attach(agent); float d = 0; block->Translate(d, 0, 0); //navmesh->SetPosition(Vec3(d, navmesh->matrix.t.y, 0)); auto terrain = CreateTerrain(world, 1024); terrain->LoadHeightmap("https://raw.githubusercontent.com/Leadwerks/Documentation/private/Assets/Terrain/1024.r16"); terrain->SetScale(1, 200, 1); navmesh->Build(); agent->SetPosition(d + 2, terrain->GetElevation(Vec3(d + 2, 0, 0)), 0); camera->SetPosition(0, 150, 0); //Main loop while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { navmesh->SetDebugging(window->KeyDown(KEY_F)); //Move dummy obstacle //agent3->SetPosition(player2->position); if (window->KeyDown(KEY_RIGHT)) block->Translate(0.1, 0, 0); if (window->KeyDown(KEY_LEFT)) block->Translate(-0.1, 0, 0); if (window->MouseHit(MOUSE_LEFT)) { iVec3 pos = window->GetMousePosition(); auto raycast = camera->Raycast(framebuffer, Vec2(pos.x, pos.y), 0, true); if (raycast.success) { agent->Navigate(raycast.position); //agent2->Navigate(raycast.position); } } camera->UpdateControls(window); world->Update(); world->Render(framebuffer); } return 0; } Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.