Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with coordinates/objects in wrong location with custom MeshModifier #1207

Closed
colin-young opened this issue Dec 29, 2018 · 2 comments

Comments

@colin-young
Copy link

commented Dec 29, 2018

I've created a custom MeshModifier to draw my roads. I'm using EasyRoads3D, but I don't think
that's relevant. I am using a custom tileset for my road data that was obtained from Open Street Maps' overpass API.

  1. If I use the built-in rendering for road (i.e. choose line as the primitive geometry type) I get the road exactly where I expect it. I modified LineMeshModifier to draw rays to each road segment point, but, while I've added a filter (name contains Iron Age Street), I'm getting a number of roads coming back that don't even have a name. In any case, those rays are not showing in the correct locations either. Although all the rays are pointing to the wrong locations, the road eventually shows up in the correct location on screen.

  2. If, instead, I use my custom code by adding as a Mesh Modifier to the AbstractMap features, the road, which is a single line entity in the GeoJSON file, gets split into 2 segments, each accurate relative to itself, but widely separated from each other with neither in the correct position. You can see that 6 rays are hitting the rendered road segments where they are rendered. Note that the rays are rendered from the mostly out-of-the-box Mapbox LineMeshModifier, a completely different code path, which makes me think there is some additional coordinate transformation occurring in the official code that I need to make use of. Because otherwise it just looks like magic.

This image should make it clearer:

unity_2018_3_0f2_personal_-_dataexplorer_unity_-_safety_harbor_building_height_demo_-_pc__mac___linux_standalone__personal___metal_

My MeshModifier and my modified LineMeshModifier.ExtureLine method

Here is the GeoJSON that defines the road in question:

{
  "type": "Feature",
  "properties": {
    "@id": "way/160849592",
    "highway": "34695",
    "name": "Iron Age Street"
  },
  "geometry": {
    "coordinates": [
      [-82.689281, 27.989707],
      [-82.689261, 27.989571],
      [-82.689231, 27.989508],
      [-82.689145, 27.989438],
      [-82.688813, 27.98919]
    ],
    "type": "LineString"
  }
}

Here's what I logged in the console (note the Z values):

Creating road 'Iron Age Street' - [way/160849592] from points (205.8, 3.9, -270.0), (204.9, 3.9, -267.7), (202.9, 4.3, -252.6)
Creating road 'Iron Age Street' - [way/160849592] from points (248.9, 1.7, 229.8), (207.8, 3.6, 265.2), (205.8, 3.8, 270.0)

Note: If this is a bug or support ticket, please provide the following information:

  • Unity version: 2018.3.0f2
    • Scripting Runtime Version: .Net 4.x Equivalent
    • Scripting Backend: IL2CPP
    • Api Compatibility Level: .Net 4.x
  • Mapbox SDK version: 2.0.0
  • The platform you're building to: built-in player
@colin-young

This comment has been minimized.

Copy link
Author

commented Dec 30, 2018

Based on this comment, I've modified my code to this, but I'm still not getting things right:

var tile = feature.Tile;
Vector2d tileOriginMeters = tile.Rect.Center - new Vector2d(tile.Rect.Size.x / 2, tile.Rect.Size.y / 2);
foreach (var roadSegment in feature.Points)
{
    var convertedSegments = roadSegment.Select(segment => {
        Vector2d diffVectorMeters = new Vector2d(segment.x, segment.y);
        Vector2d finalVectorMeters = tileOriginMeters + diffVectorMeters;
        var latLon = Conversions.MetersToLatLon(finalVectorMeters);
        var location = Conversions.GeoToWorldPosition(latLon, map.CenterMercator, map.WorldRelativeScale).ToVector3xz();
        location = new Vector3(location.x, segment.y, location.z);
        Debug.DrawRay(camera.position, location - camera.position, rayColor, 30, true);
        return location;
    });
    _roadNetwork.CreateRoad(roadName, convertedSegments.ToArray());
}

It makes sense that I'm getting 2 segments because they are coming from 2 tiles, but I'm still not able to get the roads in the correct location, although they are now in different wrong locations. Clearly I'm making some mistake in the conversions, but I don't see where.

@colin-young

This comment has been minimized.

Copy link
Author

commented Jan 4, 2019

Finally solved it. Sort of. Trashed the MeshModifier and I'm now processing the road data after the map visualizer is finished:

if (s == ModuleState.Finished)
{
  // build roads
  StartCoroutine(BuildRoads());
}

Then in the coroutine, I find all my roads (that I've added to a FeatureCollectionBase collection) and iterate through those, taking the GameObject.transform.position and adding to that the each of Feature.Points to come up with the Unity world space coordinates:

foreach (var road in (ListCollection)Collection)
{
    var feature = road.Feature;

    var roadName = feature.Properties.ContainsKey("name") ? feature.Properties["name"].ToString() : Guid.NewGuid().ToString();

    foreach (var pointList in road.Feature.Points)
    {
        var featureTransform = road.GameObject.transform.position;

        var adjustedPoints = pointList.Select(p =>
        {
            var adjustedPosition = p + featureTransform;
            return adjustedPosition;
        }).ToArray();

        roadNetwork.CreateRoad(roadName, adjustedPoints);

        // create 10 roads per frame. Slows initial framerate but finishes faster
        if (index++ % 10 == 0)
        {
            yield return null;
        }
    }
}

I don't know if this is the best way to do it, or if I'm going to run into issues if I ever change zoom, scale, etc., but for now it's got things working so I can get on to other things.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.