Jump to content

2 posts in this topic Last Reply

Highlighted Posts

Posted:
Last Online:  
 

Hey there,

I'm trying to create my first mod for Cities Skylines. My idea is to generate a mesh from the NetworkManager and export it so I can essentially build a city in Cities: Skylines and port it to another game, (e.g. a racing game). As a quick and dirty POC, I tried to simply grab all the segments, collect them in a SVG and export the file. Most of the segments turned out fine but some were missing with some in weird random places where they clearly don't belong. See the attached SVG, output_corrupt_segments.svg (Note that the viewBox does not work correctly yet, I recommend using Inkscape to view the file. And yes, I'm aware that there is a mistake in the minimum/maximum search, I just didn't bother so far.)

Here is a code snippet so you can see exactly what I'm doing:

 

private void RetrieveData()
{

  NetManager nm = Singleton<NetManager>.instance;

  string svgBody = "";

  float minX = float.PositiveInfinity;
  float maxX = float.NegativeInfinity;

  float minY = float.PositiveInfinity;
  float maxY = float.NegativeInfinity;

  for (uint i = 0; i < FEATURE_COUNT; i++)
  {

    if ((nm.m_segments.m_buffer[i].m_flags & NetSegment.Flags.Created) != NetSegment.Flags.None)
    {
      ushort nodeIndex0 = nm.m_segments.m_buffer[i].m_startNode;
      ushort nodeIndex1 = nm.m_segments.m_buffer[i].m_endNode;

      if (!(nodeIndex0 == 0 || nodeIndex1 == 0))
      {

        Vector3 pos0 = nm.m_nodes.m_buffer[nodeIndex0].m_position;
        Vector3 pos1 = nm.m_nodes.m_buffer[nodeIndex1].m_position;

        minX = Mathf.Min(minX, pos0.z, pos1.x);
        maxX = Mathf.Max(maxX, pos0.z, pos1.z);

        minY = Mathf.Min(minY, pos0.x, pos1.z);
        maxY = Mathf.Max(maxY, pos0.x, pos1.x);

        bool plausible = IsPlausible(pos0.x, pos0.z, pos1.x, pos1.z);
        if (plausible)
        {
          svgBody += "  <line x1=\"" + pos0.z + "\" y1=\"" + pos0.x +
            "\" x2=\"" + pos1.z + "\" y2=\"" + pos1.x +
            "\" style=\"stroke:rgb(0, 0, 0);stroke-width:4\" />" + Environment.NewLine;
        }
      }
    }
  }

  string svg = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + Environment.NewLine +
    " <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"100%\" height=\"100%\" viewBox=\"" +
    minX + " " + minY + " " + maxX + " " + maxY + "\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">" +
    Environment.NewLine + svgBody + "</svg>";

  // export svg
  System.IO.File.WriteAllText(@"D:\Games\SteamLibrary\steamapps\common\Cities_Skylines\Files\output.svg", svg);


  ExceptionPanel panel2 = UIView.library.ShowModal<ExceptionPanel>("ExceptionPanel");
  panel2.SetMessage("PSDLExporter", "Wrote to file", false);
}

Just to be sure I don't accidentally skip any valid segments I have also tried to remove all conditions in the loop and just export all 32768 segments. I got the same result except for a load of extra segments with coordinates (0,0),(0,0). Any idea what I'm doing wrong and how to fix it? Could there be a refresh method I have to call before accessing the data?

Any suggestions? Thanks in advance!

Share this post


Link to post
Share on other sites
  • Original Poster
  • Posted:
    Last Online:  
     

    Well, turns out the problem was something rather trivial. I just copied the wrong segment count value from somewhere so I did actually not iterate over all segments. I do still have some weird segments flying around but I guess they define paths that are invisible to the player.

    Anyway, here is some progress if anyone cares:

    I have implemented an intersection calculation algorithm to determine how to connect all adjacent segments smoothly. I assume something similar exists somewhere in the game but it is inaccessible. There are still some improvements to be made though. Corners should be rounded and T-intersections should probably be handled differently.

    Using my pre-calculations, I can already generate some simple meshes for all segments. Right now, each segment is turned into two triangles and witdh is hard-coded. A higher level of detail, maybe even incorporating the in-game prefab mesh, will be supported in the future.

    Here is a preview of what I get. (z-depth is not correct right now!)

    output.png.47334dc52f4dec40afd1ad978acfb46f.png

    Note that I am not generating a mesh for intersections right now. You can still see the original segments in black where the intersections should be. But that should not be an issue since they are guaranteed to have a convex shape.

    Share this post


    Link to post
    Share on other sites

    Sign In or register to comment...

    To comment in reply, you must be a community member

    Sign In  

    Already have an account? Sign in here.

    Sign In Now

    Create an Account  

    Sign up to join our friendly community. It's easy!  

    Register a New Account


    ×

    Thank You for the Continued Support!

    Simtropolis depends on donations to fund site maintenance costs.
    Without your support, we just would not be in our 24th year online!  You really help make this a great community. *:thumb:

    But we still need your support to stay online. If you're able to, please consider a donation to help us stay up and running. This helps sustain a platform where we can share our community creations for years to come.

    Make a Donation, Get a Gift!

    Expand your city with the best from the Simtropolis Exchange.
    Make a Donation and get one or all three discs today!

    STEX Collections

    By way of a "Thank You" gift, we'd like to send you our STEX Collector's DVD. It's some of the best buildings, lots, maps and mods collected for you over the years. Check out the STEX Collections for more info.

    Each donation helps keep Simtropolis online, open and free!

    Thank you for reading and enjoy the site!

    More About STEX Collections