Modified Track Path Editor + Tracks/Discussion

Nice :)
Ive been doing it manually where the arc tool can't & I normally use blocks of 5 or 10 shifting 2 at a time either way from the centre point. It can span from 50 to 100 points to make a really smooth curve & take a bit of time.

I used to do it manually as well, but it takes a lot of time and it's hard to make it good.
 
Hey guys, I'm wondering if anyone could to replicate the gunma cycle center / gunsai touge circuit from the hot version series
 
An update on the ted editor: got sidetracked by the beautiful math of biarcs, the curves used by the TPE to build the track outline.

A Biarc consists to two circular segments joined with tangent continuity. Given two points and two tangents at the points an interpolating biarc is a biarc that starts and ends at the points and whose circular segments match the tangents at the points. An interpolating biarc is not unique, in fact a whole family of interpolating biarcs can be found.
In the beginning i used the derivation of Ryan Juckett:

http://www.ryanjuckett.com/programming/biarc-interpolation/

He derives an equation for two parameters, and eliminates one to get a quadratic equation to be solved given a single parameter that defines the family of interpolating biarcs, the ratio of the distance of the tangent points of each circular segment to the end points. This works quite well, but the paramter isn't very intuitive as is ranges over all numbers and the geometric meaning of manipulating this ratio is not very clear. Plus the original TPE uses another parametrization and i couldn't reproduce the original circle segments from an original ted file.

Instead i used a different insight: The joint point where the two segments of a interpolating biarc meet is constrained to lie on a circle, in fact all joint points of an interpolating biarc family form this circle., see here:

http://www.ag.jku.at/pubs/2006sfj.pdf

Finding this circle isn't too hard: It's center is given as the center of the unique rotation transforming the start tangent from the start point into the end tangent to the end point. As i was using rational quadratic bezier circles for all circles already i only needed the tangent of the joint circle, not the center. The tangent of the circle at the start point is given by the angle bisector of the reflection of the end tangent at the chord (line between start and end point) and the start tangent, as the end tangent is just the reflection of the start tangent on a chord of the circle of rotation and the tangent to this circle must lie between the tangents bisecting the angles formed by both tangents.

This insight was worth all the puzzling, and now i can reproduce original ted layouts and i have added handles to move the joint point over the full circle range for full biarc design flexibility. Plus the joy of discovering beautiful mathematics! :dopey:

The little ted editor project has grown bigger and bigger, right now i plan to add road and decoration editing facilities. Basically they are given by a start and end track length, the roads have to cover the whole track, the decorations can be placed anywhere. They can be chosen out of a set of predefined "rail units" given in a XML file from the TPE APK. I have started the parsing and extraction of these units but the whole process is tedious and i can't think of a nice way to place the stuff on the track layout. Seems i got a coders block and on top of that i will be away for two weeks so i released all my stuff here:

https://github.com/tarnheld/ted-editor

Bildschirmfoto 2016-10-16 um 17.59.54.png Bildschirmfoto 2016-10-16 um 18.00.18.png

Download the whole repository and start the file ted-editor.py with python 3. Blue handles for control point movements, yellow handles for tangents, pink handles for joint points, you can move points and segments by dragging, insert a point by double clicking on a segment, remove a point by double clicking on it, reverse the track by pressing R, toggle open/closed by O and lots more. The mouse and key bindings can be looked up in the code, too lazy to describe them all here.

It's all alpha status, but the import and export followed by an import should work for Andalusia tracks. It's an Andalusia editor right now, but it's shouldn't be too hard to switch to a different scenery if you replace the files with the scenery information in the code. There is conversion code for the height maps and contour extraction in the folder hm and code for the rail definition xml files in the folder rd. Try it out, tinker with it, tell me what you think, have fun! :cheers:
 
An update on the ted editor: got sidetracked by the beautiful math of biarcs, the curves used by the TPE to build the track outline.

A Biarc consists to two circular segments joined with tangent continuity. Given two points and two tangents at the points an interpolating biarc is a biarc that starts and ends at the points and whose circular segments match the tangents at the points. An interpolating biarc is not unique, in fact a whole family of interpolating biarcs can be found.
In the beginning i used the derivation of Ryan Juckett:

http://www.ryanjuckett.com/programming/biarc-interpolation/

He derives an equation for two parameters, and eliminates one to get a quadratic equation to be solved given a single parameter that defines the family of interpolating biarcs, the ratio of the distance of the tangent points of each circular segment to the end points. This works quite well, but the paramter isn't very intuitive as is ranges over all numbers and the geometric meaning of manipulating this ratio is not very clear. Plus the original TPE uses another parametrization and i couldn't reproduce the original circle segments from an original ted file.

Instead i used a different insight: The joint point where the two segments of a interpolating biarc meet is constrained to lie on a circle, in fact all joint points of an interpolating biarc family form this circle., see here:

http://www.ag.jku.at/pubs/2006sfj.pdf

Finding this circle isn't too hard: It's center is given as the center of the unique rotation transforming the start tangent from the start point into the end tangent to the end point. As i was using rational quadratic bezier circles for all circles already i only needed the tangent of the joint circle, not the center. The tangent of the circle at the start point is given by the angle bisector of the reflection of the end tangent at the chord (line between start and end point) and the start tangent, as the end tangent is just the reflection of the start tangent on a chord of the circle of rotation and the tangent to this circle must lie between the tangents bisecting the angles formed by both tangents.

This insight was worth all the puzzling, and now i can reproduce original ted layouts and i have added handles to move the joint point over the full circle range for full biarc design flexibility. Plus the joy of discovering beautiful mathematics! :dopey:

The little ted editor project has grown bigger and bigger, right now i plan to add road and decoration editing facilities. Basically they are given by a start and end track length, the roads have to cover the whole track, the decorations can be placed anywhere. They can be chosen out of a set of predefined "rail units" given in a XML file from the TPE APK. I have started the parsing and extraction of these units but the whole process is tedious and i can't think of a nice way to place the stuff on the track layout. Seems i got a coders block and on top of that i will be away for two weeks so i released all my stuff here:

https://github.com/tarnheld/ted-editor

View attachment 596579 View attachment 596578

Download the whole repository and start the file ted-editor.py with python 3. Blue handles for control point movements, yellow handles for tangents, pink handles for joint points, you can move points and segments by dragging, insert a point by double clicking on a segment, remove a point by double clicking on it, reverse the track by pressing R, toggle open/closed by O and lots more. The mouse and key bindings can be looked up in the code, too lazy to describe them all here.

It's all alpha status, but the import and export followed by an import should work for Andalusia tracks. It's an Andalusia editor right now, but it's shouldn't be too hard to switch to a different scenery if you replace the files with the scenery information in the code. There is conversion code for the height maps and contour extraction in the folder hm and code for the rail definition xml files in the folder rd. Try it out, tinker with it, tell me what you think, have fun! :cheers:

I fully understood everything you said about the biarcs.......... honestly :)

Nice 1 tarnheld, this couldn't have dropped at a more convenient time. I'll give some feedback once I know what I'm doing with it lol.
 
An update on the ted editor: got sidetracked by the beautiful math of biarcs, the curves used by the TPE to build the track outline.

A Biarc consists to two circular segments joined with tangent continuity. Given two points and two tangents at the points an interpolating biarc is a biarc that starts and ends at the points and whose circular segments match the tangents at the points. An interpolating biarc is not unique, in fact a whole family of interpolating biarcs can be found.
In the beginning i used the derivation of Ryan Juckett:

http://www.ryanjuckett.com/programming/biarc-interpolation/

He derives an equation for two parameters, and eliminates one to get a quadratic equation to be solved given a single parameter that defines the family of interpolating biarcs, the ratio of the distance of the tangent points of each circular segment to the end points. This works quite well, but the paramter isn't very intuitive as is ranges over all numbers and the geometric meaning of manipulating this ratio is not very clear. Plus the original TPE uses another parametrization and i couldn't reproduce the original circle segments from an original ted file.

Instead i used a different insight: The joint point where the two segments of a interpolating biarc meet is constrained to lie on a circle, in fact all joint points of an interpolating biarc family form this circle., see here:

http://www.ag.jku.at/pubs/2006sfj.pdf

Finding this circle isn't too hard: It's center is given as the center of the unique rotation transforming the start tangent from the start point into the end tangent to the end point. As i was using rational quadratic bezier circles for all circles already i only needed the tangent of the joint circle, not the center. The tangent of the circle at the start point is given by the angle bisector of the reflection of the end tangent at the chord (line between start and end point) and the start tangent, as the end tangent is just the reflection of the start tangent on a chord of the circle of rotation and the tangent to this circle must lie between the tangents bisecting the angles formed by both tangents.

This insight was worth all the puzzling, and now i can reproduce original ted layouts and i have added handles to move the joint point over the full circle range for full biarc design flexibility. Plus the joy of discovering beautiful mathematics! :dopey:

The little ted editor project has grown bigger and bigger, right now i plan to add road and decoration editing facilities. Basically they are given by a start and end track length, the roads have to cover the whole track, the decorations can be placed anywhere. They can be chosen out of a set of predefined "rail units" given in a XML file from the TPE APK. I have started the parsing and extraction of these units but the whole process is tedious and i can't think of a nice way to place the stuff on the track layout. Seems i got a coders block and on top of that i will be away for two weeks so i released all my stuff here:

https://github.com/tarnheld/ted-editor

View attachment 596579 View attachment 596578

Download the whole repository and start the file ted-editor.py with python 3. Blue handles for control point movements, yellow handles for tangents, pink handles for joint points, you can move points and segments by dragging, insert a point by double clicking on a segment, remove a point by double clicking on it, reverse the track by pressing R, toggle open/closed by O and lots more. The mouse and key bindings can be looked up in the code, too lazy to describe them all here.

It's all alpha status, but the import and export followed by an import should work for Andalusia tracks. It's an Andalusia editor right now, but it's shouldn't be too hard to switch to a different scenery if you replace the files with the scenery information in the code. There is conversion code for the height maps and contour extraction in the folder hm and code for the rail definition xml files in the folder rd. Try it out, tinker with it, tell me what you think, have fun! :cheers:

:cheers:Absolutely Incredible @tarnheld!! :bowdown:
Well, suppose I'll just 'git' tinkering then.....
 
The thing I'm most excited about with this editor (once I get it working lol) is the scale function :)

Just think, all them small track's we couldn't build due to the S/F straight being 600m. Now we can build it in the TPE at any size & scale it down to size after.

Or increase it (which I plan to do with my Isle of Man track) to see how big I can get it :)
 
I added some batch files for easy installation of the required packages and to run the Ted Editor.

Download the repo again and execute the batch files pipinstall.bat once for installation and TedEditor.bat for starting the editor. Hope this helps. :)👍 Tell me if you have any problems getting it to run and i'll try to help.

I looked into the options to build a standalone executable with python runtime included and found out that the minor hassles for you to setup up a working python environment (download and install python 3.x and double click pipinstall.bat) do not outweigh the major hassles for me getting cx_freeze or py2exe up and running. :irked::sly: Any volunteers? :)
 
Those roads and decoration elements are driving me nuts! :banghead: Even for a "simple" track reversal you need to know the exact type of the elements as left and right curving roads and runoff areas are encoded in the uuids of the road elements in the ted file, so you have to get the right uuid to change a left runoff to a right runoff. :grumpy: You have to extract this information out of the raildef xml file and it requires some deep digging to find the left runoff uuid given a right runoff uuid. :rolleyes: Scaling is even more complicated as every road piece has an intrinsic length and you can scale it only a little bit, so simple scaling doesn't work, you need to insert extra road elements. Combined with the fact that for example a runoff area consists of start, end and repeated middle elements (all info neatly tugged away in the rail def file) means you have to consider the road pieces as groups of elements and take care to don't repeat the start and end pieces of a runoff area. That means no simple iteration over each element and some twiddling of a single element in isolation. :indiff: So for now i have to declare defeat and look after a whole new approach for the roads and decorations, maybe inspiration strikes after i get back from my holiday trip end of next week. :) I have switched back the TED export to simple scaling of the road without gaps and preserving the lengths of the decorations, so if you plan to scale your imported track try to be gentle. :P
 
Those roads and decoration elements are driving me nuts! :banghead: Even for a "simple" track reversal you need to know the exact type of the elements as left and right curving roads and runoff areas are encoded in the uuids of the road elements in the ted file, so you have to get the right uuid to change a left runoff to a right runoff. :grumpy: You have to extract this information out of the raildef xml file and it requires some deep digging to find the left runoff uuid given a right runoff uuid. :rolleyes: Scaling is even more complicated as every road piece has an intrinsic length and you can scale it only a little bit, so simple scaling doesn't work, you need to insert extra road elements. Combined with the fact that for example a runoff area consists of start, end and repeated middle elements (all info neatly tugged away in the rail def file) means you have to consider the road pieces as groups of elements and take care to don't repeat the start and end pieces of a runoff area. That means no simple iteration over each element and some twiddling of a single element in isolation. :indiff: So for now i have to declare defeat and look after a whole new approach for the roads and decorations, maybe inspiration strikes after i get back from my holiday trip end of next week. :) I have switched back the TED export to simple scaling of the road without gaps and preserving the lengths of the decorations, so if you plan to scale your imported track try to be gentle. :P

@Mr Grumpy has a list of most of the decorations.

As for the start-middle-end decorations, the middle part is often optional, so you can just use the start and the end parts if it would be too long to use all three.
 
As for the start-middle-end decorations, the middle part is often optional, so you can just use the start and the end parts if it would be too long to use all three.

What makes it difficult is that the information what parts make up a start-middle-end transition and if it's a left or right transition. This is all in the raildef files (you can find them in the rd directory in my repo) but inside a different section (search for RailGroup), the individual rail units (search for RailUnit in the raildef file, identified by uuid in the raildef and the ted file) have no information attached if they are part of a group or if they should be put on a left or right curve. That makes it difficult to handle them programmatically, you can't just iterate over them part by part and do something for each part only, you have to structure them using the information in the raildef file.
 
What makes it difficult is that the information what parts make up a start-middle-end transition and if it's a left or right transition. This is all in the raildef files (you can find them in the rd directory in my repo) but inside a different section (search for RailGroup), the individual rail units (search for RailUnit in the raildef file, identified by uuid in the raildef and the ted file) have no information attached if they are part of a group or if they should be put on a left or right curve. That makes it difficult to handle them programmatically, you can't just iterate over them part by part and do something for each part only, you have to structure them using the information in the raildef file.

It seems pretty straightforward. Create a dictionary with all the different decoration ID's and make it contain the following variables:

decor_dict = {someID : (type, isEnd),}

isEnd could be 0 for middle segments, 1 for start/end segments, and 2 for decorations that only has a single segment.

Then using the dictionary, reduce and abstract the data, starting with the first set of data:

decoration = [type, [start, end], side, number_of_segments, other important data?]

If the next set of data is of the same type, is on the same side, if it starts at the end of the previous set and if isEnd != 2 then you know that it is part of the same decoration, so you just add to the end data and to the number_of_segments data. If isEnd == 1 then after you have added its data you append the decoration to a list of decorations and start on a new decoration.

Once you have processed all the decorations it's easy to reverse the position and side, as each decoration is now just a single entity.

Finally, construct the decorations again, from the data in the decorations list.
 
It seems pretty straightforward.

Sounds like the right approach! :)👍 Want to volunteer? If you find the time while i'm away: there is the function getRailDict in raildefs.py that already contains code to parse the xml and to extract the information from the xml file and can be reworked to deliver your type of dictionary and used in exportTed while converting the roads and decorations like this:

Code:
# total_l is the new track length, self.hdr is the header of the imported ted file and contains
# the old track_length.
# sf is the linear scale factor for the lengths of road and decoration elements and others
sf = total_l/self.hdr.track_length

railroot = raildefs.getRailRoot("rd/andalusia.raildef")
types, uuids, content = raildefs.getRailDict(railroot) #rework this function to deliver useful information

roads = [] # holds new road elements, can be more or less than elements in self.road
for r in self.road: # all road elements in the imported ted file
  # do something useful with above data while converting the roads
  vs = r.vstart3d * sf
  ve = r.vend3d  * sf
  roads.append(TedRoad(uuid = r.uuid, flag=r.flag, vstart3d = vs, vend3d = ve))

EDIT: while writing this post i found an error in the decoration scaling. :eek: Fixed it and incorporated above code and comments for reference. 👍
 
Last edited:
Sounds like the right approach! :)👍 Want to volunteer? If you find the time while i'm away: there is the function getRailDict in raildefs.py that already contains code to parse the xml and to extract the information from the xml file and can be reworked to deliver your type of dictionary and used in exportTed while converting the roads and decorations like this:

Code:
# total_l is the new track length, self.hdr is the header of the imported ted file and contains
# the old track_length.
# sf is the linear scale factor for the lengths of road and decoration elements and others
sf = total_l/self.hdr.track_length

railroot = raildefs.getRailRoot("rd/andalusia.raildef")
types, uuids, content = raildefs.getRailDict(railroot) #rework this function to deliver useful information

roads = [] # holds new road elements, can be more or less than elements in self.road
for r in self.road: # all road elements in the imported ted file
  # do something useful with above data while converting the roads
  vs = r.vstart3d * sf
  ve = r.vend3d  * sf
  roads.append(TedRoad(uuid = r.uuid, flag=r.flag, vstart3d = vs, vend3d = ve))

EDIT: while writing this post i found an error in the decoration scaling. :eek: Fixed it and incorporated above code and comments for reference. 👍

I can give it a shot :)
 
I managed a successful scale of my Okutama track :)

Working on a blank canvas is alot simpler. So no elevation, no banking, no scenery, I can add that later.

Anyways old track length = 10.600km
New track length = the correct 6.3km :)

It took me 10mins to re-adjust the track structure in the other editor & BOOM.

The recreation of Grid autosport's Okutama has begun :)

Edit: how easy/hard would it be to incorporate a little box so we could just type in the desired length ? As the scaling isn't that smooth it can be a pain to get the new measurement spot on.
 
Last edited:
Edit: how easy/hard would it be to incorporate a little box so we could just type in the desired length ?
Shouldn't be too hard, will tackle that when i get back end of next week. If you're feeling adventurous, you can take the code from onSelScaleUpdate and add a function like that to the class CCManip:

Code:
def scaleTrack(self)
      desired_length = 12345
      scale = desired_length/self.hdr.track_length
      scale_origin = (0,0) point that stays fixed while scaling
      xform = la.identity()
      xform = la.mul(xform,la.translate(scale_origin[0],scale_origin[1]))
      xform = la.mul(xform,la.scale(a,a,a))
      xform = la.mul(xform,la.translate(-scale_origin[0],-scale_origin[1]))
      self.selection = self.cc.point # all control points
      self.applySelXForm(xform)
      self.selection = []

Then add a keyboard binding in this table here to call your function with a key press:

Code:
(s.Idle,   None,   "<Key-t>")      : (s.Idle,   self.scaleTrack),

Hope this helps! :cheers: (BTW, github makes it really easy to get pointers into your code... :D:tup:)
 
I managed a successful scale of my Okutama track :)

Working on a blank canvas is alot simpler. So no elevation, no banking, no scenery, I can add that later.

Anyways old track length = 10.600km
New track length = the correct 6.3km :)

It took me 10mins to re-adjust the track structure in the other editor & BOOM.

The recreation of Grid autosport's Okutama has begun :)

Edit: how easy/hard would it be to incorporate a little box so we could just type in the desired length ? As the scaling isn't that smooth it can be a pain to get the new measurement spot on.
I do wait on that Okutama. one of the most fun tracks on GRID. Pity that the online on grid is now only around 15-20 people. 50 in a good day
 
Last edited:
Played around with your Red Rock Valley RM track, love it. I really like what you did with that "tunnel".

I'd love to play around with the TED editor, but i don't even understand how it works. xD

Also had a "track" (if we can call it like that) idea: Put the start line in a high place, then a long downhill and a loop. Always wanted to know if this was doable with the hacked editors.
 
Played around with your Red Rock Valley RM track, love it. I really like what you did with that "tunnel".

I'd love to play around with the TED editor, but i don't even understand how it works. xD

Also had a "track" (if we can call it like that) idea: Put the start line in a high place, then a long downhill and a loop. Always wanted to know if this was doable with the hacked editors.
As in loop da loop ? I don't think it's possible sadly. I have however though about an inverted wall of death where only the cars with extreme df will be able to stick to the road lol.

Another idea I've been testing is a spiral like in cape ring but 10 rings high going up or down :)

Edit: hey Pink & P_eMmO send us a PSN friend request :)
 
As in loop da loop ? I don't think it's possible sadly. I have however though about an inverted wall of death where only the cars with extreme df will be able to stick to the road lol.

A barrel roll should be possible, a 360 degree banking should do the trick. Just make sure to add a lot of height points for that section, as they also seem to determine how smooth the banking becomes.

Might have to create a second barrel roll in the opposite direction as well, because I suspect you can't just flip from 360 to 0 without creating a nasty artefact of very painful death :scared:
 
A barrel roll should be possible, a 360 degree banking should do the trick. Just make sure to add a lot of height points for that section, as they also seem to determine how smooth the banking becomes.

Might have to create a second barrel roll in the opposite direction as well, because I suspect you can't just flip from 360 to 0 without creating a nasty artefact of very painful death :scared:

I presumed anything over 90 would cause the floor to fold in on itself. Hmm must try.
 
There is any modified TPE with the possibility straight start/finish line less than 600 meters? ...personally I haven't found a modified tpe with this option.... i want to make a real local circuit in my country with 450m straigth, and the standard 600 m straigth line and this big facilities and buildings in the inside part of track is an issue, with stock TPE is impossible to make, LoL sorry for my bad english, and thanks for any help.
 
Back