Figuring out how to render the roads correctly in OpenSAGE turned out to be a little more challenging than expected. This is the fifth post in a series describing the journey. In the last post, we rendered road segments for the first time, but they are still disconnected and overlap each other:
Ignoring the different curve types for now, let's consider angled connections. We have two overlapping rectangles (one for each edge) that have an intersection point at the common node position (End1 - Start2
). We want to modify the two corner points B1
and A2
so that they share the same position X
(and then do the same for the other corner).
So, how can we calculate X
? With the graph we created in part 3, we can easily find the neighbor segment and its start and end position. For both the current and the neighbor segment, we can calculate the direction vector's normal (directionNormal
and neighborDirectionNormal
). We can calculate the average of these two vectors, normalize it and get a direction vector toCornerDirection
pointing from the node position towards X
.
Now we need to multiply this direction vector with the correct length to get to X
. Considering the right-angled triangle End1 - Start2
, X
, B1
, we know that
cos α = (roadWidth / 2) / toCornerLength
.
cos α
can be calculated without actually knowing the angle by calculating the dot product of directionNormal
and toCornerDirection
.
This gives us
toCornerLength = (roadWidth / 2) / Vector3.Dot(directionNormal, toCornerDirection)
and finally the vector to X
:
toCorner = toCornerDirection * toCornerLength
Now we can calculate the new shared corner positions B1 - A2
and C1 - D2
by adding and subtracting the vector to the shared node position.
As we saw in the last post, it's also important to adjust the U texture coordinate accordingly to avoid distortions.
Next time, we'll take a first look at crossings.