{"id":25664517,"url":"https://github.com/dahie/gpx2obj-ruby","last_synced_at":"2025-10-04T05:26:03.351Z","repository":{"id":278344336,"uuid":"934670913","full_name":"Dahie/gpx2obj-ruby","owner":"Dahie","description":"Conversion script to read GP2 Careditor SHP files and convert them to OBJ","archived":false,"fork":false,"pushed_at":"2025-03-02T17:10:46.000Z","size":396,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-02T18:24:55.293Z","etag":null,"topics":["gp2","grandprix2","simracing"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Dahie.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"License.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-02-18T08:09:44.000Z","updated_at":"2025-03-02T17:10:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"8ad9164c-1e83-4f46-82d5-d47d3d2558d1","html_url":"https://github.com/Dahie/gpx2obj-ruby","commit_stats":null,"previous_names":["dahie/gpx2obj-ruby"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Dahie/gpx2obj-ruby","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dahie%2Fgpx2obj-ruby","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dahie%2Fgpx2obj-ruby/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dahie%2Fgpx2obj-ruby/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dahie%2Fgpx2obj-ruby/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dahie","download_url":"https://codeload.github.com/Dahie/gpx2obj-ruby/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dahie%2Fgpx2obj-ruby/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278267339,"owners_count":25958828,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-04T02:00:05.491Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gp2","grandprix2","simracing"],"created_at":"2025-02-24T06:19:50.002Z","updated_at":"2025-10-04T05:26:03.346Z","avatar_url":"https://github.com/Dahie.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Gpx2Obj\n\nWelcome to my little 2025 rabbit-hole. Gpx2Obj is a ruby implementation the the [GP2 Careditor Carshape import by Paul Hoad](https://github.com/paulhoad/gp2careditor/) for GrandPrix2. The original editor does not provide an export of the model to OBJ to import it into other 3D tools. So I sat down a few weekends and reverse engineered his code, worked through [his carshape tutorials](https://grandprix2.de/Anleitung/tutus/carshape/carshape.html) and ported his code to Ruby. Why ruby? Simple because it's my main language and simple to read.\n\n![GP2 carshape imported in Blender](assets/preview_car2.jpg)\n\nFeatures in this scripts:\n\n- Read SHP GP2careditor carshape file\n- Export both models: car 1 (low nose) and car 2 (raised nose)\n- Assign UV-Mapping from YAML, CFG or SVG to OBJ model\n- Export GP2careditor `Texture.cfg` to SVG\n\n## Background\n\nIn 1995 Paul Hoad released his famous GP2careditor that allowed editing and sharing of GP2 car models. This was very much limited by how the game has the car model data embedded in the executable.\nThe careditor exports the original carshape by copying the binary data from the `GP2.exe` and then parsing the data structure to fetch the verticies, edges and faces. \n\nWith the goal to export an ideally clean GP2 car to OBJ. It requires to:\n\n1. Read the binary format SHP load the original vertex and face data.\n2. Map this face data to a UV map.\n\nThe original UV mapping is also somewhere included in the original executable, but it has never been discovered.\nGP2careditor helps itself by introducing a `texture.cfg` to assign all faces an UV mapping.\nPaul included an attempt at a `texture.cfg` in the editor source code he released in 2020. However this is incomplete and includes mistakes. To fix this, I wrote a conversion to SVG and back, that allows editing the car's UV map.\nRealistically, you'll never use this, as the mapping in GP2 can not be changed and thus, if the modding was done right once, there is no need to touch it again. \n\n## Project structure\n\n- `assets/` basic assets for conversation:\n    - `00-RC-44.png` example car texture\n    - `carshape.shp` original carshape experted through [GP2careditor](https://github.com/paulhoad/gp2careditor/)\n    - `model.mtl` shader settings for the OBJ model\n    - `texture.cfg` improved texture uv mapping for use in GP2careditor\n    - `uv_mapping.svg` SVG export of the UV map\n- `lib/` Ruby source code\n- `spec/` Ruby spec tests\n- `Rakefile` describes the executable features\n\n\n## Attention on wording\n  \nCareditor uses a language that mixes up todays common 3D terminology. \n\n- GP2careditor: Points -\u003e Verticies\n- GP2careditor: Verticies -\u003e Edges\n- GP2careditor: Texture -\u003e Face\n\nI'm using modern 2025 wording terms and will refer to verticies, edges and faces. Only within `Gpx2Obj::ShpReader` I will use the original terminology.\n\n## Setup\n\nCheckout this repository, make sure to have Ruby 3.4+ installed and run\n\n    bundle install\n\n## Usage\n\n    rake gpx2obj:convert [input=assets/carshape.shp] [uv=assets/texture.cfg] [output=out/]\n\nRun a conversion on a given model. By default it'll convert the standard GP2 shape.\n\n\n## Development\n\n    rake kaitai:recompile\n\nRecompiles the `carshape.ksy`. The tool uses [Kaitai] to build binary readers from a description file. See [Kaitai Struct documentation](https://doc.kaitai.io/user_guide.html). This creates a ruby code to read the basic binary data of the carshape file. As the data format was highly optimized for performance, more data trickery is required to get the final data structure. This is done in ruby code only.\n\n### Open Issues\n\nThe mapping is close to the original, but not perfect. All carbon parts are only mapped to one surface, while ingame you can draw eg on the suspensions.\nAlso I couldn't figure out if the textures map on the edge off a pixel or on the center of a pixel. I mapped to pixel center.\nAll of this can be adjusted to your needs by using your own uv mapping.\n\n## Credits\n\n- Thanks to [Paul Hoad](https://github.com/paulhoad/) for the leg-work 30 years ago. It was a pleasure to reverse-engineer your code and learn about binary formats from the 90s.\n- [Boxy SVG](https://boxy-svg.com/) - an amazing little SVG editor. Contrary to other svg editors, it keeps the basic SVG intact after editing. So updating the UV-mapping became much much easier.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdahie%2Fgpx2obj-ruby","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdahie%2Fgpx2obj-ruby","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdahie%2Fgpx2obj-ruby/lists"}