sk-zk / TruckLib

create & modify ETS2 / ATS maps
https://sk-zk.github.io/trucklib/master/
GNU General Public License v2.0
18 stars 7 forks source link

Road.Append() InvalidOperationException #2

Closed gsus24 closed 5 months ago

gsus24 commented 5 months ago

Hi

i tried to read a table with given waypoints and append the new point to the road in a loop, but like you said if an item is attached it throws a exception.

Another try was to create new Roads and add it them the map in a loop, the roads segments are straight and does not link together.

Any suggestion on doing this with undefined number of points? Rather than hardcode and append the points behind each other.

sk-zk commented 5 months ago

If possible, sort your points so you can continuously Append them.

There's no method for attaching two separate polyline items to each other right now, but it's on my list of things I need to add. Until then, you can do it manually. Say you have two roads you'd like to connect:

var road1 = Road.Add(map, new(10, 0, 10), new(30, 0, 10), "ger1");
var road2 = Road.Add(map, new(32, 0, 12), new(50, 0, 30), "ger1");

You can replace the backward node of road2 with the forward node of road1 like this:

// set the forward item to road2
road1.ForwardNode.ForwardItem = road2;

// clear road2's old backward node so it gets ignored when saving the map
road2.Node.BackwardItem = null;
road2.Node.ForwardItem = null;

// replace road2's backward node
road2.Node = road1.ForwardNode;

// optional: recalculate default node rotations
road1.Recalculate();

The two road items are now connected.

sk-zk commented 5 months ago

You can now attach two polyline items with one method call, if they are attachable to each other. Here's the equivalent of the code above:

var road1 = Road.Add(map, new(10, 0, 10), new(30, 0, 10), "ger1");
var road2 = Road.Add(map, new(32, 0, 12), new(50, 0, 30), "ger1");

road1.ForwardNode.Merge(road2.Node);
gsus24 commented 5 months ago

It needs some distinction for road order to merge and exception for the first loop, but .Merge() works well for two road variables.

while (!csvParser.EndOfData)
{
    ...
    if(odd)
    {
        road1 = Road.Add(map, new(10, 0, 10), new(30, 0, 10), "ger1");

        if(!firstLoop)
        {
            road2.ForwardNode.Merge(road1.Node);
        }        
    }
    else
    {
        road2 = Road.Add(map, new(10, 0, 10), new(30, 0, 10), "ger1");
        road1.ForwardNode.Merge(road2.Node);        
    }
    ....
}
gsus24 commented 5 months ago

To come back to my issue for InvalidOperationException if append segment to road in loop

while (!csvParser.EndOfData)
{
    ...
    road.append(position);
    ...
}

By appending after each other it works

road.append(position0)
    .append(position1); 

Maybe you have a quick explanation why ForwardItem is not null in loop? And i need to debug myself for better understanding. Thanks

sk-zk commented 5 months ago

I think what you seem to be missing is that Append returns the appended segment, so you can append in a loop like this:

var road = Road.Add(map, points[0], points[1], "ger1");
for (int i = 2; i < points.Count; i++)
{
    road = road.Append(points[i]);
}

Remember that the Road class is not a collection; it's just one individual road item with one neighbor in either direction, so you can't append to it more than once because it's already connected to another item.

gsus24 commented 5 months ago

workaround to create route https://github.com/gsus24/TruckLib/tree/route/Samples/02-Route/