Pathfinding in isometric game with autotiles: How to modify NavigationMesh - path-finding

Im generating a map proceduraly with isometric autotiles. Each tile has its navigation poligon defined in the Tilemap editor. The Navigationmesh is working fine. The thing is that the map I generate is bigger than the actually playable area. I dont want the human player to see the borders of the map, the "black background". So I'm limiting the camera view movement. Therefore, the navigationmesh goes outside of the playable area, like in this image:
I'm using pathfinding to move the player character. Since the map is generated proceduraly, sometimes it generates a map where the path to a point goes outside the playable area an then comes back in order to reach its destination. Like this:
A player in O would go outside the playable are to reach X. In X could be a point of interest, so if this kind of map is generated, I would simply regenerate it until i get a feasible one.
I'm using GODOT 3.51.
I have think about:
Carving a hole in the navigation mesh on the borders of the playable area using clip_polygons(). BUT since im using autotile navigation, it is very hard to get the navigationpoligoninstance. I have tried this but failed miserably.
-Adding NavigationObstacles on the borders: Hadn't tried this, but as far as i understand from my research, this will not avoid the agent to generate the path to the destination.
My idea is to achieve that no path goes out of the playable area and then check is the map is feasible by checking if all points of interest (randomly spawned) are reacheable. This is done by cheking the last point of every path to interest points from the starting point an seeing if it is equal to the point of interest position.
I hope this is understandable. Sometimes I dont understand myself.

What comes to mind is to use two versions of the tiles. One that is not passable which will be used to generate the areas that the players should not be able to reach. And the regular one used for the playable area.

Related

Procedural Road Generation, Unity

Im developing 2d isometric game. You driving car on city, thats all.
The issue is generating random maps with connected roads.
I would like to write script - i think i will be able to - but i cant find an idea for alghoritm itself.
Lets say i have 100x100 map, and i would like to build boolean table 1 is road 0 is not road.
As far i have solution that is drawing random number of lines (4-8 for ex) in horizontal and same vertical. But this road map is straight.
Can u share some ideas? Any will help
the question is too broad for a simple answer. theres plenty of ways in various degrees of complexity.
but as tip, consider the problem from a different perspective. sure in the end you want roads, but why are the roads there in the first place?
in your case its a city. a city consists of city blocks wich usually are rectangular. so one way would be to find a way to fill the map with rectangular shapes and consider the edges roads (or only some).
or you could look into triangulation algorithms and triangulate your map with a bunch of random points. then combine some triangles and use those edges as roads.
or even only use a random walk set up so it doesnt turn around completely.
or ...
... seriously though, the options and possible solutions are manifold and dependent on your skill level (as well as how you want to look your city in the end).
dont search for your specific problem, try to adapt some other algorithm for your need. theres plenty of tutorials on random dungeon generation for roguelike games.
also in the end there probably wont be a single generation algorithm giving you the best result, but a combination of many.

Create directions on a map based on custom data

So what I'm trying to do is the following:
Have a map (such as Google Maps or questMaps). It doesn't matter at all which API I need to use.
On that map have an overlay on the streets. So say (for example) the street has bad lightning at night, it will be colored red. If it has good lightning it will have a green overlay.
Based on the overlay the map creates a custom route (for example the user only wants to walk on the green/well lit streets).
I have no idea how to accomplish this (especially step 3).
First, you'll have to decide what data you need. How do you categorize certain streets as lit or unlit? What if some parts of a street are well lit and some have no lights? Do you need to know the location of every streetlight in your area? What if lights burn out?
After figuring out what data you need, you need to build your dataset. I'd be VERY surprised if this data already exists, so you will probably need to gather it yourself. Either go around town and take notes, or crowdsource the project, or figure out some other way.
Once you have gathered your data, learn the drawing API of whatever mapping tool you wish to use. They all should have functions in their API for drawing colored lines (for streets) or points (for streetlights) on top of an existing map.
Finally, learn the navigational API of the mapping tool you chose. You're right, this is a hard step. I know Google Maps lets you specify certain waypoints when requesting directions; maybe your app can calculate well-lit waypoints and feed them to Google Maps' Directions service to influence the route it generates.
Good luck!
For custom routing, you need to read up on "Graph Theory". This ignores the geography of the street map, and considers it as a set of junctions (nodes or vertices in the graph theory jargon) connected by edges. You can assign weights to edges - these could be lengths, travel times, ones and zeroes etc. Anything. They can have no relation to the position on the map.
So for your application, you'd assign a large weight to unlit streets, and a small weight to lit streets, then use a standard minimum-weight algorithm to get a route from one node to another.

How to map 2D coordinates from store image to the actual shelves of the store?

We need to build a model of the shop floor in which we can relate pixel coordinates(x, y) from
camera images to the actual objects in the 3D space of the store. The camera images, which will act as sources for generating such a model, suffer from fish-eye distortions. Hence straight lines actually appear as curves in the camera images and the walls appear to meet each other at not exactly right angles.
We are sub-dividing the region into polygons. Each polygon on the image refers to a particular region such as a shelf, display area, checkout counter etc. By mapping the pixels that fall in each polygon, we want to relate it as belonging to the shelf corresponding to that region.
Any ideas how to go about it?
Following is a sample image of the store with some polygons marked:
EDIT:
We are not looking to find out the 3D coordinates, we just need to know which shelf is any polygon mapped to. So if the user clicks on a polygon, we can say he clicked on which shelf.
We are able to manage the above for big polygons like the ones shown in the image, but the shelves away from the camera can be as small as a few pixels so we need some kind of a probabilistic result saying if the user clicked at (x,y) what is the probability that he was trying to click on Shelf-A or what is the probability that he was trying to click on Shelf-B and so on.
Basically, what we are looking for is a probability function which would return the probabilities of click on nearby objects when a small polygon(or a pixel) is clicked on the 2D image.
EDIT2:
One thing which is not apparent from the sample image is that the polygon size could be really small(as small as a few pixels) and polygons in turn could be really close to each other.
Moreover, the use case is that a customer in the store picks a product from one of the shelves. The application user would click on a point in the image from which he thinks the products is picked up. Now since the polygons are so small and so close, the user can only guess the exact point of pickup, so we can only know at best that it could be any one of the 3-4 polygons close to the point of click. So the question is how to calculate probabilities for these 3-4 polygons given the click?
As suggested here distance of the click from the center of polygon and its area could be parameters in calculation of this probability, what I am wondering is if there is algorithm to do so.
We are not looking to find out the 3D coordinates, we just need to know which shelf is any polygon mapped to. So if the user clicks on a polygon, we can say he clicked on which shelf.
I assume you have a mapping from polygon to shelf name. For example, as a list of pairs (polygon, shelf name). You can make it by hand once, if the cameras are fixed and don't move. Then your problem is only finding which polygon does a point belong to.
If you use OpenCV, then you can use its PointPolygonTest function. Otherwise you may write a similar function yourself. See, for example, a Ray casting algorithm. Then look through the list until you find a polygon which the point lies withing.
To further optimize the program you may precalculate polygons' extents. An extents allows you to quickly say when the point is definitely not inside the polygon, and consider only the remaining polygons. But with so few polygons as you have in the image, I would not bother.
Basically, what we are looking for is a probability function which would return the probabilities of click on nearby objects when a small polygon(or a pixel) is clicked on the 2D image.
Just run an experiment, try to click a single highlighted pixel, accumulate some statistics on where the operator does actually clicks. Once you have this, it's easy to predict the number of out-of-object clicks and how far they are likely to be off.
Without such experiment with exactly the same kind of person, the same usage conditions and the same pointing device you are going to use, you cannot really tell how much off the clicks are going to be. I believe that many people are sniper clickers if the mouse is good and they can see the image well. If they are forced to use touch interface or some other pointing device, the precision may be lower.
Few comments
fish eye can be corrected by applying some transformations to the image, see for example this page for some resources including panotools
to get the 3D coordinates only and image from one camera is not enough, additional info is necessary
marking a same point on two images of the same scene from different cameras can give you full 3D info (you do need to know position of each camera relative to each other)
if you are looking for tools to do it, see https://superuser.com/questions/30053/is-there-any-free-open-source-software-that-converts-photos-to-3d-models
EDIT
After update to the question, assuming there already exist a set of polygons and you want to eliminate user errors (or improve precision) you might
try to guess the desired click polygon by calculating distance to centre of weight of polygons close to click
use visual cues (flash the polygon selected and require second click)
collect statistics on errors and for certain polygons require validation
What you want is a space-filling-curce for example a Z-Curce or a Hilbert-Curve. A space-filling-curve sub-divide the plane into smaller tiles and reduce the complexity of 2-Dimensions into 1-Dimension in a way that each tile get's a new order. What might interessting for your problem is that the Hilber-Curve traverse the plane not in binary order but it use a gray code so that every tile is different in 1-Bit from the other tiles. That makes it easy to decide whether the user has clicked this or that object.

Need guidance on a Google Map application that has to show 250 000 polylines

I am looking for advice for an application I am developing that uses Google Map.
Summary:
A user has a list of criteria for searching a street segment that fulfills the criteria. The street segments will be colored with 3 colors for showing those below average, average and over average. Then the user clicks on the street segment to see an information window showing the properties of that specific segment hiding those not selected until he/she closes the window and other polyline becomes visible again. This looks quite like the Monopoly City Streets game Hasbro made some month ago the difference being I do not use Flash, I can’t use Open Street Map because it doesn’t list street segment (if it does the IDs won’t be the same anyway) and I do not have to show Google sketch building over.
Information:
I have a database of street segments with IDs, polyline points and centroid.
The database has 6,000,000 street segment records in it. To narrow the generated data a bit we focus on city. The largest city we must show has 250,000 street segments. This means 250,000 line segment polyline to show.
Our longest polyline uses 9600 characters which is stored in two 8000 varchar columns in SQL Server 2008.
We need to use the API v3 because it is faster than the API v2 and the application will be ported to iPhone. For now it's an ASP.NET 3.5 with SQl Server 2008 application.
Performance is a priority.
Problems:
Most of the demo projects that do this are made with API v2. So besides tutorial on the Google API v3 reference page I have nothing to compare performance or technology use to achieve my goal.
There is no available .NET wrapper for the API v3 yet.
Generating a 250,000 line segment polyline creates a heavy file which takes time to transfer and parse. (I have found a demo of one polyline of 390,000 points. I think the encoder would be far less efficient with more polylines with less points since there will be less rounding.)
Since streets segments are shown based on criteria, polylines must be dynamically created and cache can't be used.
Some thoughts:
KML/KMZ:
Pros:
Since it is a standard we can easily load Bing maps, Yahoo! maps, Google maps, Google Earth, with the same KML file. The data generation would be the same.
Cons:
LineString in KML cannot be encoded polyline like the Google map API can handle. So it would probably be bigger and slower to display. Zipping the file at the size it will take more processing time and require the client side to uncompress the data and I am not quite sure with 250,000 data how an iPhone would handle this and how a server would handle 40 users browsing at the same time.
JavaScript file:
Pros:
JavaScript file can have encoded polyline and would significantly reduce the file to transfer.
Cons:
Have to create my own stripped version of API v3 to add overlays, create polyline, etc. It is more complex than just create a KML file and point to the source.
GeoRSS:
This option isn't adapted for my needs I think, but I could be wrong.
MapServer:
I saw some post suggesting using MapServer to generate overlays. Not quite sure for the connection with our database and the performance it would give. Plus it requires a plugin for generating KML. It seems to me that it wouldn't allow me to do better than creating my own KML or JavaScript file. Maintenance would be simpler without.
Monopoly City Streets:
The game is now over, but for those who know what I am talking about Monopoly City Streets was showing at max zoom level only the streets that the centroid was inside the Bounds of the window. Moving the map was sending request to the server for the new streets to show. While I think this was ingenious, I have no idea how to implement something similar. The only thing I thought about was to compare if the long was inside the bound of map area X and same with Y. While this could improve performance significantly at high zoom level, this would give nothing when showing a whole city.
Clustering:
While cluster is awesome for marker, it seems we cannot cluster polylines. I would have liked something like MarkerClusterer for polylines and be able to cluster by my 3 polyline colors. This will probably stay as a “would have been freaking awesome but forget it”.
Arrow:
I will have in a future version to show a direction for the polyline and will have to show an arrow at the centroid. Loading an image or marker will only double my data so creating a custom overlay will probably be my only option. I have found that demo for something similar I would like to achieve. Unfortunately, the demo is very slow, but I only wish to show 1 arrow per polyline and not multiple like the demo. This functionality will depend on the format of data since I don't think KML support custom overlays.
Criteria:
While the application is done with ASP.NET 3.5, the port to the iPhone won't use the web to show the application and be limited in screen size for selecting the criteria. This is why I was more orienting on a service or page generating the file based on criteria passed in parameters. The service would than generate the file I need to display the polylines on the map. I could also create an aspx page that does this. The aspx page is more documented than the service way. There should be a reason.
Questions:
Should I create a web service to returns the street segments file or create an aspx page that return the file?
Should I create a JavaScript file with encoded polyline or a KML with longitude/latitude based on the fact that maximum longitude/latitude polyline have 9600 characters and I have to render maximum 250,000 line segment polyline. Or should I go with a MapServer that generate the overlay?
Will I be able to display simple arrow on the polyline on the next version.
In case of KML generation is it faster to create the file with XDocument, XmlDocument, XmlWriter and this manually or just serialize the street segment in the stream?
This is more a brainstorming Stack Overflow question than an actual code problem. Any answer helping narrow the possibilities is as good as someone having all the knowledge to point me out a better choice.
Large numbers of short GPolylines run massively slower than small numbers of long GPolylines.
The speed difference between Google Maps v2 and Google Maps v3 is not going to be significant, because most of the CPU time will be taken up by the actual graphics system of the browser. Google Maps uses the VML, SVG or Canvas graphics systems, depending on the browser. Of these, VML is by far the slowest, and that gets used whenever the browser is MSIE.
Before embarking on tackling 250,000 line segments, I suggest you take a look at this quick speed test of 200 random polylines. Try zooming and paning that map in MSIE.
Then, also consider the amount of data that needs to be sent from the server to the client to specify 250,000 line segments. The amount of data will vary depending on whether you choose KML or JSON or GeoRSS, but if you end up with 20 bytes per line segment that would take 50 seconds to fetch on a 1 megabit broadband connection. Consider whether your users would be prepared to sit around for 50 seconds.
The only solution that really makes sense is to do what Google do for their traffic overlay, and draw the lines onto tiles in the server, and have those tiles be displayed as a GTileLayerOverlay in the client.
What you need is a spatially aware database, and a server-side graphics library like gd or ImageMagik. The client asks for a tile from the server. If the zoom is above a certain level the server scans the database for line segments that have bounding boxes that overlap the bounding box of the requested tile and use the graphics library to draw them.
The zoom level limit is there to limit the amount of work that your database and server needs to do. You don't want to end up drawing 250,000 line segments onto a single zoomed out tile because that's an awful lot of hard work for the server, and isn't going to mean very much to the user.
Regarding click handling:
The easy thing to do is to listen for clicks on the map, rather than on the objects, and send the click details to a server. The server then uses the click location to search the spatially aware database and returns the details of the clicked object if there is one. The client code does this:
GEvent.addListener(map,"click",function(overlay,point) {
var url="clickserver.php?lat=" + point.lat() + "&lng=" +point.lng();
GDownloadUrl(url, function(html) {
if (html.length) {
map.openInfoWindow(html)
}
});
});
The harder thing to do is to handle the changing of the cursor when the pointer is over the polylines. There's a known technique for doing cursor changes for small markers, which works like this:
Whenever a tile is fetched, the .getTileUrl() also makes a call to a server that returns a list of hotspot boxes for that tile. As the mouse moves, the client constantly calculates which tile the mouse is over, and then scans the corresponding list of hotspot boxes.
Google themselves, in their GLayer() code, add the sophistication of performing a quadtree search to speed up the search for hotspots within a tile, but other people who have implemented this strategy in their own code reckon that's not necessary, and a linear scan of the hotspot list is fast enough.
I've no idea how to extend that to handling cursor over polyline detection.

Custom Map With Directions

I want to make a map program that gives directions around a campus (residence halls, football field, etc), and within buildings (to offices, cafeteria, etc). Is there anything existing that would help facilitate that?
The alternative seems to be that I would have to create my own map of points and paths around campus and do path-finding for directions.
EDIT: To clarify, I'm wanting to know about how to add spatial awareness to a pathfinding program, in order to generate walking directions for the path. Example: for a hallway full of offices that has two nodes that allow a path to enter the hallway, how do you know if a certain office is on the left from one node and on the right from another?
If I use polygons for the nodes instead of waypoints, I can create a navigation mesh that can be used for pathfinding and directions. For directions and using a rectangle node, if I give the rectangle numbers for its sides from 1 to 4 going clockwise from the top, I know that if I enter side 2 and leave side 1, it's a right hand turn. Or, if I enter side 3 (say, the bottom) and leave side 4, it's a left.
This is pretty hard to answer without knowing what sort of interface you want. Is it supposed to be a Google Maps-type application? Or something simpler? No matter what you're probably going to have to define paths - what things are impassable.
You could do a lot of work and define what's impassable and then use a path-finding algorithm to walk across lawns; but that'd be more work than the simple approach:
Make a map of campus with all the routes greyed out
Define the points and paths in PHP/Perl/Ruby/Python/Coldfusion/ASP.Net/Whatever
Get the Start and Destination from the user
Run Dijkstra's Algorithm
Display the map of campus with overlays highlighting the route segments to light up their path.

Resources