Exemple #1
0
    public static float[,] GetInterpolatedTerrain(OSMBoundingBox boundingBox, out float height)
    {
        float[,] result = new float[257, 257];

        float minHeight = float.MaxValue;
        float maxHeight = float.MinValue;

        for (int i = 0; i < 257; i++)
        {
            for (int j = 0; j < 257; j++)
            {
                result[i, j] = SRTMHeightProvider.GetInterpolatedHeight(boundingBox.MinLatitude + ((double)i / 257) * (boundingBox.MaxLatitude - boundingBox.MinLatitude),
                                                                        boundingBox.MinLongitude + ((double)j / 257) * (boundingBox.MaxLongitude - boundingBox.MinLongitude));
                if (result[i, j] < -32767)
                {
                    continue;
                }

                minHeight = Mathf.Min(result[i, j], minHeight);
                maxHeight = Mathf.Max(result[i, j], maxHeight);
            }
        }

        for (int i = 0; i < 257; i++)
        {
            for (int j = 0; j < 257; j++)
            {
                if (result[i, j] < -32767)
                {
                    result[i, j] = minHeight;
                }
                else
                {
                    result[i, j] = result[i, j] / maxHeight;
                }
            }
        }

        // Prevent zerodivision by TerrainComponent
        if (maxHeight > 0f)
        {
            height = maxHeight;
        }
        else
        {
            height = 1f;
        }

        TerrainLayer.MinTerrainHeight = minHeight;
        TerrainLayer.MaxTerrainHeight = maxHeight;

        return(result);
    }
Exemple #2
0
    public Building(OSMWay way, OSMData osm)
    {
        if (way.Tags.ContainsKey("building:height"))
        {
            float.TryParse(way.Tags["building:height"], out height);
        }
        else
        {
            height = Random.Range(20f, 40f);
        }

        layout = new Polygon();

        OSMNode node;

        //Discard last waynode if its the same as first
        if (way.WayNodes[0] == way.WayNodes[way.WayNodes.Count - 1])
        {
            for (int i = 0; i < way.WayNodes.Count - 1; i++)
            {
                if (osm.nodes.TryGetValue(way.WayNodes[i], out node))
                {
                    Vector3 pos = new Vector3(node.X, SRTMHeightProvider.GetInterpolatedHeight(node.Latitude, node.Longitude), node.Z);
                    layout.Add(new Vertex(pos));
                }
            }
        }
        else
        {
            for (int i = 0; i < way.WayNodes.Count; i++)
            {
                if (osm.nodes.TryGetValue(way.WayNodes[i], out node))
                {
                    Vector3 pos = new Vector3(node.X, SRTMHeightProvider.GetInterpolatedHeight(node.Latitude, node.Longitude), node.Z);
                    layout.Add(new Vertex(pos));
                }
            }
        }

        layout.MakeClockwise();
    }
Exemple #3
0
    public void CreateMesh(ModularMesh mesh)
    {
        layout = new Polygon();

        OSMNode node;

        //Discard last waynode if its the same as first
        if (way.WayNodes[0] == way.WayNodes[way.WayNodes.Count - 1])
        {
            for (int i = 0; i < way.WayNodes.Count - 1; i++)
            {
                if (osm.nodes.TryGetValue(way.WayNodes[i], out node))
                {
                    Vector3 pos = new Vector3(node.X, SRTMHeightProvider.GetInterpolatedHeight(node.Latitude, node.Longitude), node.Z);
                    layout.Add(new Vertex(pos));
                }
            }
        }
        else
        {
            for (int i = 0; i < way.WayNodes.Count; i++)
            {
                if (osm.nodes.TryGetValue(way.WayNodes[i], out node))
                {
                    Vector3 pos = new Vector3(node.X, SRTMHeightProvider.GetInterpolatedHeight(node.Latitude, node.Longitude), node.Z);
                    layout.Add(new Vertex(pos));
                }
            }
        }

        layout.MakeClockwise();

        leveledLayout = layout.LevelUp();

        area = leveledLayout.Triangulate(mesh, MaterialManager.GetMaterial("diffuseBlue"));
    }
Exemple #4
0
    //public float GetInterpolatedHeight(double latitude, double longitude)
    //{
    //    int pixelIndexX = (int)Math.Floor((latitude - latIndex) * 1201);
    //    int pixelIndexY = (int)Math.Floor((longitude - longIndex) * 1201);

    //    float x = (float)(((latitude - latIndex) * 1201) % 1);
    //    float y = (float)(((longitude - longIndex) * 1201) % 1);

    //    float f00 = Data[pixelIndexX, pixelIndexY];
    //    float f01 = Data[pixelIndexX, pixelIndexY + 1];
    //    float f10 = Data[pixelIndexX + 1, pixelIndexY];
    //    float f11 = Data[pixelIndexX + 1, pixelIndexY + 1];

    //    //Bilinear Interpolation
    //    //return f00 * (1f - x) * (1f - y) + f10 * x * (1f - y) + f01 * (1 - x) * y + f11 * x * y;
    //    return BilinearInterpolation(f00, f01, f10, f11, x, y);
    //}

    //private float BilinearInterpolation(float f00, float f01, float f10, float f11, float u, float w)
    //{
    //    return f00 * (1 - u) * (1 - w) + f01 * (1 - u) * w + f10 * u * (1 - w) + f11 * u * w;
    //}

    public float GetInterpolatedHeight(double latitude, double longitude)
    {
        int pixelIndexX = (int)Math.Floor((latitude - latIndex) * 1200);
        int pixelIndexY = (int)Math.Floor((longitude - longIndex) * 1200);

        float xParam = (float)(((latitude - latIndex) * 1200) % 1);
        float yParam = (float)(((longitude - longIndex) * 1200) % 1);

        float[,] controlPoints = new float[4, 4];

        int counterX = 0;
        int counterY = 0;

        for (int x = pixelIndexX - 1; x <= pixelIndexX + 2; x++)
        {
            counterY = 0;
            for (int y = pixelIndexY - 1; y <= pixelIndexY + 2; y++)
            {
                if (x == -1)
                {
                    //       |
                    //     * * * *
                    //     * * * *
                    // ----*-*-*-*-----
                    //     X * * *
                    //       |
                    if (y == -1)
                    {
                        SRTMDataCell cell = SRTMHeightProvider.GetSRTMDataCell(latIndex - 1, longIndex - 1);
                        controlPoints[counterX, counterY] = cell.Data[1199, 1199];

                        if (xParam >= 0.5f || yParam >= 0.5f)
                        {
                            Debug.Log("Parameter: " + x + ", " + y);
                        }
                    }
                    //       |
                    //     X * * *
                    // ----*-*-*-*-----
                    //     * * * *
                    //     * * * *
                    //       |
                    else if (y == 1201)
                    {
                        SRTMDataCell cell = SRTMHeightProvider.GetSRTMDataCell(latIndex - 1, longIndex + 1);
                        controlPoints[counterX, counterY] = cell.Data[1199, 1];
                    }
                    //       |
                    //     X * * *
                    //     * * * *
                    // ----*-*-*-*-----
                    //     * * * *
                    //       |
                    else if (y == 1202)
                    {
                        SRTMDataCell cell = SRTMHeightProvider.GetSRTMDataCell(latIndex - 1, longIndex + 1);
                        controlPoints[counterX, counterY] = cell.Data[1199, 2];
                    }
                    //  |
                    //X * **
                    //X * **
                    //X * **
                    //X * **
                    //  |
                    else
                    {
                        SRTMDataCell cell = SRTMHeightProvider.GetSRTMDataCell(latIndex - 1, longIndex);
                        controlPoints[counterX, counterY] = cell.Data[1199, y];
                    }
                }
                else if (x == 1201)
                {
                    //         |
                    //     * * * *
                    //     * * * *
                    // ----*-*-*-*-----
                    //     * * * X
                    //         |
                    if (y == -1)
                    {
                        SRTMDataCell cell = SRTMHeightProvider.GetSRTMDataCell(latIndex + 1, longIndex - 1);
                        controlPoints[counterX, counterY] = cell.Data[1, 1199];
                    }
                    //         |
                    //     * * * x
                    // ----*-*-*-*-----
                    //     * * * *
                    //     * * * *
                    //         |
                    else if (y == 1201)
                    {
                        SRTMDataCell cell = SRTMHeightProvider.GetSRTMDataCell(latIndex + 1, longIndex + 1);
                        controlPoints[counterX, counterY] = cell.Data[1, 1];
                    }
                    ////         |
                    ////     * * * x
                    ////     * * * *
                    //// ----*-*-*-*-----
                    ////     * * * *
                    ////         |
                    //else if (y == 1202)
                    //{
                    //    SRTMDataCell cell = SRTMHeightProvider.GetSRTMDataCell(latIndex + 1, longIndex + 1);
                    //    controlPoints[counterX, counterY] = cell.Data[1, 2];
                    //}
                    //         |
                    //     * * * x
                    //     * * * x
                    //     * * * x
                    //     * * * x
                    //         |
                    else
                    {
                        SRTMDataCell cell = SRTMHeightProvider.GetSRTMDataCell(latIndex + 1, longIndex);
                        controlPoints[counterX, counterY] = Data[1, y];
                    }
                }
                //else if (x == 1202)
                //{
                //    //       |
                //    //     * * * *
                //    //     * * * *
                //    // ----*-*-*-*-----
                //    //     * * * X
                //    //       |
                //    if (y == -1)
                //    {
                //        SRTMDataCell cell = SRTMHeightProvider.GetSRTMDataCell(latIndex + 1, longIndex - 1);
                //        controlPoints[counterX, counterY] = cell.Data[2, 1199];
                //    }
                //    //       |
                //    //     * * * x
                //    // ----*-*-*-*-----
                //    //     * * * *
                //    //     * * * *
                //    //       |
                //    else if (y == 1201)
                //    {
                //        SRTMDataCell cell = SRTMHeightProvider.GetSRTMDataCell(latIndex + 1, longIndex + 1);
                //        controlPoints[counterX, counterY] = cell.Data[2, 1];
                //    }
                //    //       |
                //    //     * * * x
                //    //     * * * *
                //    // ----*-*-*-*-----
                //    //     * * * *
                //    //       |
                //    else if (y == 1202)
                //    {
                //        SRTMDataCell cell = SRTMHeightProvider.GetSRTMDataCell(latIndex + 1, longIndex + 1);
                //        controlPoints[counterX, counterY] = cell.Data[2, 2];
                //    }
                //    //       |
                //    //     * * * x
                //    //     * * * x
                //    //     * * * x
                //    //     * * * x
                //    //       |
                //    else
                //    {
                //        SRTMDataCell cell = SRTMHeightProvider.GetSRTMDataCell(latIndex + 1, longIndex);
                //        controlPoints[counterX, counterY] = Data[2, y];
                //    }
                //}
                else
                {
                    //
                    //     * * * *
                    //     * * * *
                    // ----*-*-*-*-----
                    //     X X X X
                    //
                    if (y == -1)
                    {
                        SRTMDataCell cell = SRTMHeightProvider.GetSRTMDataCell(latIndex, longIndex - 1);
                        controlPoints[counterX, counterY] = cell.Data[x, 1199];
                    }
                    //
                    //     X X X X
                    // ----*-*-*-*-----
                    //     * * * *
                    //     * * * *
                    //
                    else if (y == 1201)
                    {
                        SRTMDataCell cell = SRTMHeightProvider.GetSRTMDataCell(latIndex, longIndex + 1);
                        controlPoints[counterX, counterY] = cell.Data[x, 1];
                    }
                    ////
                    ////     X X X X
                    ////     * * * *
                    //// ----*-*-*-*-----
                    ////     * * * *
                    ////
                    //else if (y == 1202)
                    //{
                    //    SRTMDataCell cell = SRTMHeightProvider.GetSRTMDataCell(latIndex, longIndex + 1);
                    //    controlPoints[counterX, counterY] = cell.Data[x, 1];
                    //}
                    //
                    //     X X X X
                    //     X X X X
                    //     X X X X
                    //     X X X X
                    //
                    else
                    {
                        controlPoints[counterX, counterY] = Data[x, y];
                    }
                }
                counterY++;
            }
            counterX++;
        }



        //Bilinear Interpolation
        //return f00 * (1f - x) * (1f - y) + f10 * x * (1f - y) + f01 * (1 - x) * y + f11 * x * y;
        return(CardinalSplinePatchPoint(controlPoints, xParam, yParam));
    }
Exemple #5
0
    IEnumerator ProceduralLocal()
    {
        msg.Stop(Job.StartProcedural);
        msg.Start(Job.ProceduralPreparation);
        SimpleClient.jobStatus[jobNumber] = msg;

        this.transform.position = TilePosition - new Vector3((float)TileManager.TileWidth * (float)TileManager.Scaling / 2f, 0f, (float)TileManager.TileWidth * (float)TileManager.Scaling / 2f);
        terrain = this.gameObject.GetOrAddComponent <Terrain>();
        tC      = this.gameObject.GetOrAddComponent <TerrainCollider>();

        Building.Clear();
        Intersection.Clear();
        Street.Clear();
        Water.Clear();
        River.Clear();
        Bridge.Clear();

        unusedWays.Clear();
        streets.Clear();

        streetPolygons.Clear();

        msg.Stop(Job.ProceduralPreparation);

        #region LOD0
        if (lOD == 0)
        {
            Console.AddMessage("Procedural lod 0");
            Debug.Log("Procedural lod 0");
            #region terrain
            TerrainData terrainData = new TerrainData();

            //HeightMap
            terrainData.heightmapResolution = 257;
            float[,] heights = new float[257, 257];
            for (int x = 0; x < heights.GetLength(0); x++)
            {
                for (int y = 0; y < heights.GetLength(1); y++)
                {
                    heights[x, y] = 1f;
                }
            }

            terrainData.SetHeights(0, 0, heights);
            terrainData.size = new Vector3((float)TileManager.TileWidth * (float)TileManager.Scaling, 10f, (float)TileManager.TileWidth * (float)TileManager.Scaling);

            ////SplatPrototypes
            //SplatPrototype[] splatPrototypes = new SplatPrototype[1];
            //splatPrototypes[0] = new SplatPrototype();
            ////splatPrototypes[0].texture = (Texture2D)Resources.Load("Textures/White1px");
            //splatPrototypes[0].texture = (Texture2D)Resources.Load("Textures/Terrain/Grass (Hill)");

            //terrainData.splatPrototypes = splatPrototypes;

            terrain.terrainData = terrainData;
            tC.terrainData      = terrainData;
            #endregion terrain
            #region mesh
            TileMesh.Clear();

            Vertex[] tileQuadVertices = new Vertex[4];
            tileQuadVertices[0] = new Vertex(new Vector3((float)(-TileManager.TileWidth * TileManager.Scaling / 2d), 0f, (float)(-TileManager.TileWidth * TileManager.Scaling / 2d)) + TilePosition);
            tileQuadVertices[1] = new Vertex(new Vector3((float)(-TileManager.TileWidth * TileManager.Scaling / 2d), 0f, (float)(TileManager.TileWidth * TileManager.Scaling / 2d)) + TilePosition);
            tileQuadVertices[2] = new Vertex(new Vector3((float)(TileManager.TileWidth * TileManager.Scaling / 2d), 0f, (float)(TileManager.TileWidth * TileManager.Scaling / 2d)) + TilePosition);
            tileQuadVertices[3] = new Vertex(new Vector3((float)(TileManager.TileWidth * TileManager.Scaling / 2d), 0f, (float)(-TileManager.TileWidth * TileManager.Scaling / 2d)) + TilePosition);

            new Quad(tileQuadVertices, TileMesh, MaterialManager.GetMaterial("diffuseBrown"));

            TileMesh.FillMeshDivideMaterialsKeepMeshStructure(transform, true);
            #endregion
            Debug.Log("Procedural lod 0 - Done");
        }
        #endregion

        #region LOD5
        if (lOD == 5)
        {
            msg.Start(Job.CreateTerrain);
            SimpleClient.jobStatus[jobNumber] = msg;

            #region terrain
            if (terrain.terrainData == null)
            {
                terrain.terrainData = new TerrainData();
            }
            //HeightMap
            terrain.terrainData.heightmapResolution = 257;
            terrain.terrainData.alphamapResolution  = 257;

            float height = 0f;

            terrain.terrainData.SetHeights(0, 0, SRTMHeightProvider.GetInterpolatedTerrain(this.Query.BoundingBox, out height));
            terrain.terrainData.size = new Vector3((float)TileManager.TileWidth * (float)TileManager.Scaling, height, (float)TileManager.TileWidth * (float)TileManager.Scaling);

            tC.terrainData = terrain.terrainData;

            msg.Stop(Job.CreateTerrain);
            #endregion terrain
            #region mesh
            msg.Start(Job.MeshPreparation);
            SimpleClient.jobStatus[jobNumber] = msg;
            TileMesh.Clear();

            if (BackgroundMesh != null)
            {
                BackgroundMesh.Clear();
            }
            else
            {
                BackgroundMesh = new ModularMesh(TileMesh, "BackgroundMesh");
            }

            if (BuildingMesh != null)
            {
                BuildingMesh.Clear();
            }
            else
            {
                BuildingMesh = new ModularMesh(TileMesh, "BuildingMesh");
            }

            if (StreetMesh != null)
            {
                StreetMesh.Clear();
            }
            else
            {
                StreetMesh = new ModularMesh(TileMesh, "StreetMesh");
            }

            if (OtherMesh != null)
            {
                OtherMesh.Clear();
            }
            else
            {
                OtherMesh = new ModularMesh(TileMesh, "OtherMesh");
            }

            msg.Stop(Job.MeshPreparation);

            msg.Start(Job.TileQuad);
            SimpleClient.jobStatus[jobNumber] = msg;

            Vertex[] tileQuadVertices = new Vertex[4];
            tileQuadVertices[0] = new Vertex(new Vector3((float)(-TileManager.TileWidth * TileManager.Scaling / 2d), 0f, (float)(-TileManager.TileWidth * TileManager.Scaling / 2d)) + TilePosition);
            tileQuadVertices[1] = new Vertex(new Vector3((float)(-TileManager.TileWidth * TileManager.Scaling / 2d), 0f, (float)(TileManager.TileWidth * TileManager.Scaling / 2d)) + TilePosition);
            tileQuadVertices[2] = new Vertex(new Vector3((float)(TileManager.TileWidth * TileManager.Scaling / 2d), 0f, (float)(TileManager.TileWidth * TileManager.Scaling / 2d)) + TilePosition);
            tileQuadVertices[3] = new Vertex(new Vector3((float)(TileManager.TileWidth * TileManager.Scaling / 2d), 0f, (float)(-TileManager.TileWidth * TileManager.Scaling / 2d)) + TilePosition);

            new Quad(tileQuadVertices, BackgroundMesh, MaterialManager.GetMaterial("diffuseBlack"));
            msg.Stop(Job.TileQuad);


            yield return(null);

            msg.Start(Job.River);
            SimpleClient.jobStatus[jobNumber] = msg;

            //Create Domain Objects
            ///Relations
            foreach (KeyValuePair <long, OSMRelation> kV in Query.OSM.relations)
            {
                OSMRelation relation = kV.Value;

                River.TryCreateFromOSM(relation, this);
                yield return(null);
            }
            msg.Stop(Job.River);

            msg.Start(Job.Ways);
            SimpleClient.jobStatus[jobNumber] = msg;

            ///Ways
            foreach (KeyValuePair <long, OSMWay> kV in Query.OSM.ways)
            {
                OSMWay way = kV.Value;

                if (!way.FirstInBounds(Query.BoundingBox, Query.OSM))
                {
                    continue;
                }

                if (!Building.TryCreateFromOSM(way, this))
                {
                    if (!Intersection.TryCreateFromOSM(way, this))
                    {
                        if (!Water.TryCreateFromOSM(way, this))
                        {
                        }
                    }
                }

                yield return(null);
            }
            msg.Stop(Job.Ways);

            //Nodes!?
            //foreach (KeyValuePair<long, OSMNode> kV in Query.OSM.nodes)
            //{
            //    OSMNode node = kV.Value;
            //    TrafficSignal.TryCreateFromOSM(node, this);
            //}

            //Debug.Log("CreateStreets");
            ////Create Streets (and Bridges)
            //Street.CreateStreets(this);



            //CreateTheMeshes
            //Debug.Log("CreateAllMeshes StreetMesh");
            //Street.CreateAllMeshes(StreetMesh);

            //Debug.Log("CreateAllMeshes StreetMesh Bridge");
            //Bridge.CreateAllMeshes(StreetMesh);
            //Debug.Log("CreateAllMeshes StreetMesh Intersection");
            //Intersection.CreateAllMeshes(StreetMesh);

            //Debug.Log("CreateAllMeshes StreetMesh Street");
            //Street.CreateAllMeshes(StreetMesh); // A second time, cause Intersections change streetproperties
            msg.Start(Job.CreateBuildingMesh);
            SimpleClient.jobStatus[jobNumber] = msg;

            Building.CreateAllMeshes(BuildingMesh);
            msg.Stop(Job.CreateBuildingMesh);
            //Debug.Log("CreateAllMeshes Water");
            //Water.CreateAllMeshes(OtherMesh);
            //Debug.Log("CreateAllMeshes TrafficSignal");
            //TrafficSignal.CreateAllMeshes(OtherMesh);

            //StreetPolygon currentStreetPolygon;
            //bool hasLeftPolygon = false;
            //bool hasRightPolygon = false;
            //for (int i = 0; i < streets.Count; i++)
            //{
            //    for (int j = 0; j < streetPolygons.Count; j++)
            //    {
            //        hasLeftPolygon = streetPolygons[j].IsLefthandPolygonOf(streets[i]);
            //        hasRightPolygon = streetPolygons[j].IsRighthandPolygonOf(streets[i]);
            //    }
            //    if (!hasLeftPolygon)
            //    {
            //        if (StreetPolygon.GetLefthandStreetPolygon(streets[i], out currentStreetPolygon))
            //            streetPolygons.Add(currentStreetPolygon);
            //    }
            //    if (!hasRightPolygon)
            //    {
            //        if (StreetPolygon.GetRighthandStreetPolygon(streets[i], out currentStreetPolygon))
            //            streetPolygons.Add(currentStreetPolygon);
            //    }

            //    hasLeftPolygon = false;
            //    hasRightPolygon = false;
            //}

            //for (int i = 0; i < streetPolygons.Count; i++)
            //{
            //    streetPolygons[i].Triangulate(StreetMesh , MaterialManager.GetMaterial("error"));
            //}


            msg.Start(Job.FillMeshDivideMaterials);
            SimpleClient.jobStatus[jobNumber] = msg;
            TileMesh.FillMeshDivideMaterialsKeepMeshStructure(transform, true);
            msg.Stop(Job.FillMeshDivideMaterials);
            #endregion
        }
        #endregion

        msg.Start(Job.GarbageCollection);
        SimpleClient.jobStatus[jobNumber] = msg;
        System.GC.Collect();
        msg.Stop(Job.GarbageCollection);

        yield return(null);

        msg.Start(Job.ProceduralDone);
        SimpleClient.jobStatus[jobNumber] = msg;
        OnProceduralDoneLocal();
        msg.Stop(Job.Worker);
        msg.Stop();

        yield return(true);
    }