7
$\begingroup$

i'm trying to create a street generator which positions the right street part's relative to the count of the vertex neighbours. I got it more or less working for every important part: normal streets, street corners and street crossings. (Yes i know the corners are still not completely right, which is a later point of concern.) Street parts instanced on a simple mesh

All my attempts boil down to one problem: how do i rotate the single parts so they fit together accordingly? Here is the simple form of the geometry nodes: Geo-nodes of street gen

My idea would be to check every vertex if it has neighbours on the x and y axis and rotate the instances according to that, but i am running against a wall trying to solve it that way.

Does anybody have an idea how to tackle the problem? Cheers

$\endgroup$
2
  • $\begingroup$ i think this is a very interesting but not an easy to solve problem....i think you underestimate the complexity $\endgroup$
    – Chris
    Mar 19, 2022 at 13:04
  • $\begingroup$ My approach is similar to yours, except I instance from four shapes, (cross, elbow, straight, and tee). I think it comes down to how to determine the angle that two edges make at a vertex. I'm also starting to think that this might be better solved with a Python script than geometry nodes. $\endgroup$ Mar 19, 2022 at 13:48

2 Answers 2

11
$\begingroup$

I suspect I went about this in a bit of a roundabout way (especially with the boolean math nodes—I basically brute forced my way through those because they hurt to think about) but I got something working:

Like you, I have three pieces: straight (—), middle (+), and corner (L). I noticed that you need at least one more (a T for 3-vertex-neighbor points) but I didn't bother with that for now. Middle pieces are easy, since they have no chance of being mis-assigned. Same for straight pieces with only one neighbouring vertex. For the other two variations, I figured I needed to check the normals of the vertices; however, vertices and edges can a bit unpredictable when it comes to normals, so I usually like to extrude the neighbouring edges to "force" the orientations and get my normals after that:

Once I have the "walls", the question is how to use them to differentiate between the tiles. I started by asking two questions: 1. Does it face any cardinal directions? and 2. Does it have two neighbours? If both is true, it's a mid-point straight piece. If only one is true, it's a corner piece. After picking out the straight pieces, I checked them a second time to see if they face either north or south. If yes, i.e. horizontal, rotate them 90 degrees; if not, do nothing.

enter image description here

Now we're left with the corners. How can I use the walls to determine their orientation? I don't know if this is stupid or grossly inefficient, but I noticed that if I cast two short rays from towards the top left part of each piece, one straight in the +X axis, and the other directly in the -Y direction, I could differentiate all 4 possible orientations by checking which combination of "hit"s I can get, then rotate them accordingly:

enter image description here

enter image description here


Edit in response to question about how to implement the raycasting check with Tee tiles (3 neighbours):

enter image description here

$\endgroup$
11
  • 1
    $\begingroup$ This solution works perfectly! Thank you very much. I went ahead and created the building generation around the street generation. It might be worth sharing: Example Grid creation based on bounding box Pointcloud boolean and building instancing $\endgroup$
    – wavezz
    Mar 20, 2022 at 13:52
  • 1
    $\begingroup$ You're welcome. Can you mark this as an answer then? Oh, and do let me know when your generator is finished if you can remember, I'd love to see the final result! $\endgroup$
    – Kuboå
    Mar 20, 2022 at 14:01
  • $\begingroup$ While i've got everything working right now, i couldn't implement the T-parts. They are at the right position, but i still can't get the right rotation, mostly because i can't exactly wrap my head around your raycast/check method. Would you mind explaining how you would incorporate them with your node structure? It's literally the last "missing piece". Also, this is my progress as of now: CityGen I also tried to implement a LOD based approach, because if you create a big city, it can get a bit slow. $\endgroup$
    – wavezz
    Mar 21, 2022 at 9:29
  • 1
    $\begingroup$ @wavezz Since it has 3 walls, 2 rays wouldn't be enough, you'd need to cast a 3rd one: i.imgur.com/agYeeNo.png (I'm assumin tile 1 is the default) Hope this helps. It looks great, btw! $\endgroup$
    – Kuboå
    Mar 21, 2022 at 10:12
  • 2
    $\begingroup$ Well done. I try to answer questions here not because I know so much, but because it's a very good way to learn. Your question was a really interesting prompt, and I learned a lot trying to solve it so I should thank you as well. $\endgroup$
    – Kuboå
    Mar 21, 2022 at 20:58
3
$\begingroup$

Here's an other option, just looked back at it after a few days and added the missing element... maybe it's not a direct answer as it uses more tiles and does not rotate them.

node setup

It encodes grid intersections as a binary number, checking clockwise if there is any segment going up, right, down or left... this result in one from sixteen posible tiles, then it converts it to an instance index number to pick that mesh from a collection.

here's the blend file

I've just seen in the comments RobinBetts had a similar idea, guess it can be better implemented... I had it half baked but I was using vertices and it would close segments where it shouldn't, checking against 1/2 edges works better.

16 tiles

$\endgroup$
3
  • $\begingroup$ a very dumb tool for drawing, just snapping verts $\endgroup$
    – alambre
    Mar 24, 2022 at 3:41
  • $\begingroup$ Beautiful. I never used Geometry Proximity before so it didn't occur to me you could utilize it for checking to see if there's an edge. I think this is the way to go to build it, and you don't really have to use 16 tiles either if you don't want, you could use these direction checks after vertex neighbor elimination to pick your tiles instead of index number assignment—fewer tiles, and you can name them freely. $\endgroup$
    – Kuboå
    Mar 24, 2022 at 9:16
  • $\begingroup$ thanks @Kuboå, I liked that there are 16 possible variations, that's what led to the binary idea $\endgroup$
    – alambre
    Mar 24, 2022 at 19:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .