Reminds me of oldschool feel of Gametek's Quarantine.
Recent community posts
Are the scale ruler settings really 100% accruate true to life? I find it may be a bit small at times or is it just me? For the 3D visualiser, did you use the actual scale rule settings used in the SVG? What scale values did you use, if it wasn't the case?
So no sub g nodes within g districts it seems...means i'd have to read off 2 svgs instead. I guess what would consider "meaningful" group can be subjective, no doubt.
For the city generator, would it be then advisable to host in a different url, particularly for major change releases? That way older versions can still be kept/archived.
I think the major update is the one that will involve curved streets?
Hmm... okay, so it looks like each <polygon> Block is actually a sub neighbourhood under the <g> Ward. BUt that would mean I'd need to export out 2 SVGs, i guess. Then, if I do need to determine which buildings in the individual polygon buildings list (in the 2nd detailed SVG) belong to which <polygon> Block , I'd check if their centroids (actually, any corner point would do..) lie within the Block polygon. Since they are chunked-listed together, I need to only check against last matching Block polygon until the candidate building centroid breaks out of it, then scan all Blocks again under that given <g> Ward group of Block polygons to update the current ward polygon region
For the road map analysis, I guess the Block-only SVG has to be used then, moving forward.
But I did wish Watabou would include sub-group neighborhood information within the <g> ward as that was avialable in the previous version and now this version lost it and now I'd have to refer to 2 svgs (and do point in polygon checks to get back the group the buildings of polygons...bleh).
Regarding how i analyse roads, i'm still doing a WIP tool that actually intends to do a lot more though (note: older version SVG):
Currently, the code is long and messy and I haven't organised everything yet but is mainly testing out various features only so i'm just highlighting parts of the svg for trace . I'm actually using this to further expand the city out into a multi-storey-themed city, by scanning the exported SVG and using it as a procedural base for expansion/sub-generation. THat is why I differentitate different road hierachies for the purpose fo having certain road types appear at higher altitudes compared to others. But this would also mean in order to access lower level roads at junctions, certain buildings at the corners of those junctions ( or merged buildings with other Neighbourng bsp tree cells from sibling nodes ) would need to be converted to stair-ramp-landings, ( to form a basis for like zig zagging flight of stairs) to provide some form of pedestrian walking access to lower levels of the city. I'm working on this part atm.
ANyway, there are 3 road hierachies. The highway (thick road spaces in orange), the ward streets (roads around wards spaces in purple), and the inner neighborhood lanes ( narrow grooves within <g> ward due to BSP tree lanes in turquoise). THe highway ramps down just outside the City wall exits (note lighter shade of orange), otherwise, without a CIty Wall, the intention si to have them at the last-outlying wards. I managed to calculate Ward distance costs to City Wall or from Ward region to Ward region, via some navmesh generation + graph navigation routines.
I decided to use node/JS because of some libraries already available in JS, and didn't take the Haxe route here though.
Basically, to analyse the roads and seperate them out, here's how I do it in summary:
Anyway, here's how i sort of reverse engineer the SVG to get more "information" from it
For ward level roads (main highways and roads adjacient to Wards..) You simply form a CDT (constrained delaunay triangulation) of the entire set of Wards' convex hulls by defining the Ward's convex hulls as edges of holes (onto the entire square map canvas (also defined as an exteriour edge at first)) from the entire set of vertices of all Ward's convex hulls. I use cdt2d library for this. The vertices that belong to a Ward's convex hull, is given an integer ID that matches the ward's integer ID.
After applying CDT, I filter off the polygons that contain vertices at the 4 corners of the map canvas and this leaves behind the road parts (more or less..).s. Then, i form a navmesh out of the CDT set of triangules using Yuka library's navmesh to form a navmesh out of those roads. After that, i scan each navmesh's regions' connecting portal edges to see if the left vertex and right vertex of the portal edge is belonging to 2 different Ward, if it is, then that region will be given an assositated ID assosiating that region with those adjacient/incident Wards. This is done for all portal edges of every navmesh region. (I also do a perpendicular width check along the portal edge to get the opposite edge across, then find perpendicular distance to measure the width of the road and determine if it's a valid road region or not). After that, i combine the set of IDs into an array, sort them, then join them to a consistently ordered string concatenated with "_" to give each raod section a unique ID. Road sections that are assosiated to to the exact similar set of adjacient Wards, will end up receiving the same ID due to the sorting. (So yes, T junctions or crossroad junctions will have different IDs compared to the main road that only lies between 2 wards, etc. and can therefore be potentially named differently).
BTW, Is there a way to view the older version of the city generator. The newer version's SVG output flattens each Ward into a flat array of POlygons and no longer uses multiple <path> nodes per neighborhood within each ward . I can no longer retrieve each sub Neighborhood's convex hulls within each Ward anymore. Hierachy should support 2 parent levels as before:
Ward -> Neighborhood -> Buildings
Now, the new version has all building polygons are flattened into a single Ward level, Ward g -> polygon*,
so i can't get back clean convex hulls for each secondary neighborhood
I actually like the new version that uses <polygons> somewhat instead of <path> instead for the buildings. But , a secondary <g> parent node for each neighboorhood within each ward would be useful to maintain back hierarchical information that was available before, and makes the job of setting up a hierachy of collision volumes a lot more easier already (especially since BSP splitters may also be easily identified from them), further reducing collision tests down to a few buildings and additional props within each neighborhood. This is important because the bsp tree cell subdivion allows one to determiisticaly determine good places to place doors ( facing the roads of a certain level, and thus the actual front of the building). HAving the cell-split information (fo rthe bsp tree formation is important to identify the secondary streets/alleyways, etc. within each Ward itself), allowing me to deterministic-ally place doors that face the main road or at a side road, etc. It makes it super fast to identify the closest occluding building for raycast tests as well when on the ground.
Above (as seen from the turuoise marked roads within the ward's roads that are in purple) is an example of what my reader was able to easily do in the older version because all the Ward's buildings within a neighborhood are arranged together in a single <path> node, and I am able to get a quick convex hulls that group all neighborhood's buildings from the old version's SVG output. In the new version's SVG output, my tool can no longer identify buildings within the same neighborhood...and thus can't identify roads for specific neighborhoods.
Because the source code on Github isn't updated to the latest generator one, i had no choice but to use the exported SVGs itself and analyse it myself via my own converter tool as well via some jquery like selectors, d3-delaunay /voronoi analysis, cdt2d triangulation, and yuka navmeshing/graphs.. Though my own purposes is not for GeoJSON usage but more for AI to analyse the SVG, and re-identify the exact curtain wall boundary (ordered points), inside/out wall wards, neighborhood BSP tree alleyway splitters, identify individual street/road section IDs (using Set of of adjacient wards' integer Ids for the key, convert Set to array, order sort ascending numeric, then .join("_") for street region string ID key), highways vs roads, highway/road exit points, empty regions within neighborhoods, ward adjaciency among wards, street/ward distances between them, and street/ward distances towards curtain wall or citadel, etc.
(oh mine, you updated the Medieval City generator just now, and now my default SVG jquery selectors aren't likely to match the new ones now.. :() ) I did notice you are now using <polygon> instead of <path> now for the ward's buildings., which means i'll have to adjust my converter to match the new version now...unless there's an older version out there? I'd likely include a variable setting to support legacy version.
One thing you need to take note of regarding Building outlines. The BSP Cell subdivision algorithm causes extra collinear points to be formed along the edges of buildings. My converter cleans up those collinear points/edges via a threshold setting, to avoid excess redundant vertices and to re-get a clean convex hull per building. (or for complex non-convex buildings, multiple convex hulls..)
I noticed the SVG export has a lot of empty `<g>` tags likely due to empty wards. It would quite useful if you included metadata attributes like `data-hull="..."` for those wards , whether they lack buildings or not. My converter has no way to retrieve back a reasonably sized convex hull based on those "empty" wards. Also, the convex hull i reverse-get back from an occupied ward cell may not be 100% accruate as well unless i view the SVG option without buildings to get clean convex hull cells.
One thing with overworld integration though, the roads and coastlines don't tally exactly with the overworld. So it hard to do seamless transition from overworld to actual city as a single world in itself.
You should consider having an export data open standard file format (like in json) or something that developers can use to load the map and add their own "enhancements" over it. The voronoi structure/neighbours, etc.
Though i think re-coding stuff to Unity asset would be better for Unity users as well, since it comes bundled with all the physics and such. Can try the C# export in haxe for the engine-agnostic codebase.
For a 3d collision detection , Bounding Volume hierachies (BVH) would be a good approach to narrow down on specific potential geometry to test against instead of testing against the entire 3d model (ie. narrow down to specific bounding box leaf which a conservative coarse sweep velocity volume intersects with..).
But of course, the scene graph woud still be generally 1 combined single model... (seperating it out to seperate meshes will add to draw calls which isn't good for performance.)
I have a 2D version of BVH ported over from original wonderfl source http://fl.corge.net/c/jA37
https://github.com/Glidias/Asharena/blob/master/src/alternativa/a3d/cullers/BVHC... (scroll down to BVHCulling
I didn't convert it to a HAxe generic yet though. Woudl likely need to replace the proxy:T to a generic data type, and converting it to haxe should be pretty trivial.