//****************************************************************************// //*************** Path Networks (cont.) - January 23rd, 2019 ****************// //**************************************************************************// - I seem to be approaching completion of the physics homework...alas, I have not reached the threshold of victory's gate as yet - Also, Riedl has nearly killed us with microphone squeals. All the pain. -------------------------------------------------------------------------- - Okay, today we're going to be talking about automatic path networks: we want to take a map we don't know stuff about, figure out where to put the path networks, and then connect them all up - "I've posted a tutorial covering some of this on Piazza, so please use that as a reference!" - Sadly, this is something that SOUNDS really simple, but that actually has many, many pitfalls for you to discover - They're also kind of a pain to debug, so there's a utility that lets you click on your navmesh stuff to highlight the polygons - Right: PATH NODE PLACEMENT! - As we said last time (forever-ago), many games choose to have designers put down the pathnodes manually, but placing them automatically can save time during the design phase - Placing the nodes automatically also lets you put path networks in dynamic environments - To do this, we'll go over a version of the path node algorithm: the "greedy navmesh algorithm" - First up, though: what IS a navigation mesh? - Well, it's "a set of convex polygons such that each polygon is an unobstructed space" - And remember, a convex polygon is one where the (exterior) angle between any 3 points is greater than 180 degrees - "This is really useful, since it means that we can go anywhere inside the polygon without encountering any obstacles, as well as travel to adjacent convex polygons" - So, convex polygons are our friends, but how do we create them? Well, here's the GREEDY NAVMESH ALGORITHM to do it - Here's what we're going to do: 1) Find a triangle - "Triangles are lovely - they're always convex, and they're the simplest shape" - To do THIS, we'll randomly pick a starting point on some obstacle - From there, we'll find 2 SUCCESSOR points such that they are successors of each other - For our purposes here, a "successor" is any point we find by either moving along the edge of the obstacle, or by moving through "freespace" (i.e. we can draw a straight line to it) - By "successors of each other," we mean that the starting point can see the successor, and the successor can see the starting point - And with that, we have 3 points - bingo! We've found a triangle! 2) Find a second triangle, from that same starting point - We do this using the same algorithm as last time - "But how do we avoid overlapping triangles?" Ideally, the triangle we created should block our raycasts from the start point - "Anytime you make a new triangle, just pretend you made a new obstacle" - ...annoyingly, this means You can't save the successors you found. For this algorithm, you have to find them from scratch for each step - Another edge case: how do we avoid creating a BIG triangle that has an obstacle inside? Or another triangle? - (my current idea: somehow check that there are no points inside our triangle?) - ...you'll find out there's a lot of these edge cases in the homework 3) Continue finding triangles until we can't make any more new ones from our starting point 4) Pick a new starting point; go back to 2/3 for this new point 5) Continue until we've tried to use every obstacle point as a starting point - After we run this (assuming we handled all the edge cases correctly), every single free space should be filled in with a triangle! Cool! - ...buuuuuut this algorithm tends to create a LOT of small triangles, which is less efficient for our algorithm - So what'll we do? We MERGE our triangles! - So, we'll look for any 2 adjacent triangles, check if the resulting merger is still convex, and if so, merge it! - "I think I gave you a function to check concavity, but really, you just walk around the edges and check their angles" - From there, we can merge a triangle onto ANY other convex shape, so we just keep doing that - for any shape, we check the adjacent triangles, then merge - One thing to keep track of: make sure your newly-merged polygons preserve the ORDER of your points - If you mess up the order, it'll be drawn incorrectly and "twist", and that's no fun (for you or the autograder) - So, that's part 1 of this homework: we've created our navmesh, and hopefully it's all stitched together nicely (don't worry, it'll probably be a mess anyway) - NOW, we've got to determine where we're actually putting our path nodes - Because these shapes are convex, we can use them to our advantage - but there are MULTIPLE ways of placing these down, all of them valid (well, if you do them correctly) - "So, I'll list some of the options, and then you get to decide" - OPTION #1 - Place a waypoint in the center of every convex polygon - This is simple, but it's NOT guaranteed to give you a fully connected path network, since it's possible for the points to be put too close to an obstacle if the navmesh is a skinny triangle - So, if you're dealing with weird spaces (*cough* your homework), this might not be the best option - OPTION #2 - Place a waypoint between the edges of adjacent navmesh polygons - Because these are convex polygons, we KNOW we can move to these points, so the graph'll be fully connected! - "You CAN still end up too close to obstacles here, but you'll usually have other options to move around them" - The issue, though, is that this tends to create more points/paths to search through, which can slow down your actual search algorithms - OPTION #3 - Put waypoints at the corners of obstacles! - This will lead to the agent hugging the corners of obstacles (much like Freshman Jake) - The difficulty here is that you have to offset your waypoints from the corners, so your agent doesn't try to actually run inside the obstacle - OPTION #4 - Hybrid schemes - For instance, you can do corners AND edges - "this'll lead to a LOT of lines in your path network" - Center and edges is Professor Riedl's favorite - "this is a good mix between giving you plenty of options, and not creating too many points" - In general, you want the simplest path network that's still fully connected, striking a balance between your agent being able to reach everywhere and your search algorithms still being performant - So, that's that - solutions up to about O(N^4) should still run in just a few seconds, but any more than that and it'll start to be strained - Now, this is all well and good for a static environment, but this is 2019 we're talking about (this statement will sound very outdated pretty soon) - games are dynamic with explodey and breaky things! How can we deal with this? - Well, if our environment is drastically changing in ways we can't predict until runtime, we have to start worrying about REPATHING: - Say, for instance, that a giant boulder falls down onto our navmesh - now the agent's assumption they can move anywhere on the mesh without obstruction isn't true! - To deal with this, we'll re-run our navmesh generator INSIDE the affected polygon, rebuilding the mesh around the obstacle so that our agent now knows how to get around the obstacle - The hope is that this is a fairly small polygon, so we can run the algorithm pretty quickly, even at runtime - "I don't know of many games that're actually dynamic in this way - it's not that we can't do it, it's just that it's a whole new can of development worms to deal with, and most games don't need it" - Alright - you've got the goods to do your homework now, so go forth! We'll meet again next week!