Esempio n. 1
0
    public void CreateBuilding(OnlineMapsBuildingsNodeData data)
    {
        if (OnCreateBuilding != null && !OnCreateBuilding(data))
        {
            return;
        }
        if (buildings.ContainsKey(data.way.id) || unusedBuildings.ContainsKey(data.way.id))
        {
            return;
        }

        int initialZoom = map.buffer.renderState.zoom;

        OnlineMapsBuildingBase building = OnlineMapsBuildingBuiltIn.Create(this, data.way, data.nodes);

        if (building != null)
        {
            building.LoadMeta(data.way);
            if (OnBuildingCreated != null)
            {
                OnBuildingCreated(building);
            }
            unusedBuildings.Add(data.way.id, building);
            if (Math.Abs(map.buffer.lastState.floatZoom - initialZoom) > float.Epsilon)
            {
                UpdateBuildingScale(building);
            }
            building.transform.localScale.Scale(new Vector3(1, heightScale, 1));
        }
        else
        {
            //Debug.Log("Null building");
        }
    }
    public void CreateBuilding(OnlineMapsBuildingsNodeData data)
    {
        if (OnCreateBuilding != null && !OnCreateBuilding(data))
        {
            return;
        }
        if (buildings.ContainsKey(data.way.id) || unusedBuildings.ContainsKey(data.way.id))
        {
            return;
        }

        OnlineMapsBuildingBase building = null;

        building = OnlineMapsBuildingBuiltIn.Create(this, data.way, data.nodes);

        if (building != null)
        {
            building.LoadMeta(data.way);
            if (OnBuildingCreated != null)
            {
                OnBuildingCreated(building);
            }
            unusedBuildings.Add(data.way.id, building);
        }
    }
Esempio n. 3
0
    /// <summary>
    /// Creates a new building based on data
    /// </summary>
    /// <param name="data">Building data</param>
    public void CreateBuilding(OnlineMapsBuildingsNodeData data)
    {
        if (OnCreateBuilding != null && !OnCreateBuilding(data))
        {
            return;
        }
        if (buildings.ContainsKey(data.way.id) || unusedBuildings.ContainsKey(data.way.id))
        {
            return;
        }

        int initialZoom = map.buffer.apiZoom;

        OnlineMapsBuildingBase building = OnlineMapsBuildingBuiltIn.Create(this, data.way, data.nodes);

        if (building != null)
        {
            building.LoadMeta(data.way);
            if (OnBuildingCreated != null)
            {
                OnBuildingCreated(building);
            }
            unusedBuildings.Add(data.way.id, building);
            if (map.buffer.apiZoom != initialZoom)
            {
                UpdateBuildingScale(building);
            }
        }
        else
        {
            //Debug.Log("Null building");
        }
    }
Esempio n. 4
0
    private void GenerateBuildings()
    {
        long      startTicks = DateTime.Now.Ticks;
        const int maxTicks   = 500000;

        lock (newBuildingsData)
        {
            while (newBuildingsData.Count > 0)
            {
                if (maxBuilding > 0 && unusedBuildings.Count + buildings.Count >= maxBuilding)
                {
                    break;
                }

                OnlineMapsBuildingsNodeData data = newBuildingsData[0];
                newBuildingsData.RemoveAt(0);

                if (OnCreateBuilding != null && !OnCreateBuilding(data))
                {
                    data.Dispose();
                    continue;
                }

                if (buildings.ContainsKey(data.way.id) || unusedBuildings.ContainsKey(data.way.id))
                {
                    data.Dispose();
                    continue;
                }

                OnlineMapsBuildingBase building = OnlineMapsBuildingBuiltIn.Create(this, data.way, data.nodes);
                if (building != null)
                {
                    building.LoadMeta(data.way);
                    if (OnBuildingCreated != null)
                    {
                        OnBuildingCreated(building);
                    }
                    unusedBuildings.Add(data.way.id, building);
                }

                data.Dispose();

                if (DateTime.Now.Ticks - startTicks > maxTicks)
                {
                    break;
                }
            }
        }

        OnlineMapsBuildingBuiltIn.usedNodes   = null;
        OnlineMapsBuildingBuiltIn.roofIndices = null;
    }
Esempio n. 5
0
    /// <summary>
    /// Creates a new building, based on Open Street Map.
    /// </summary>
    /// <param name="container">Reference to OnlineMapsBuildings.</param>
    /// <param name="way">Way of building.</param>
    /// <param name="nodes">Nodes obtained from Open Street Maps.</param>
    /// <returns>Building instance.</returns>
    public static OnlineMapsBuildingBase Create(OnlineMapsBuildings container, OnlineMapsOSMWay way, Dictionary <string, OnlineMapsOSMNode> nodes)
    {
        if (CheckIgnoredBuildings(way))
        {
            return(null);
        }

        if (usedNodes == null)
        {
            usedNodes = new List <OnlineMapsOSMNode>(30);
        }
        else
        {
            usedNodes.Clear();
        }

        way.GetNodes(nodes, usedNodes);
        List <Vector3> points = GetLocalPoints(usedNodes);

        if (points.Count < 3)
        {
            return(null);
        }
        if (points[0] == points[points.Count - 1])
        {
            points.RemoveAt(points.Count - 1);
        }
        if (points.Count < 3)
        {
            return(null);
        }

        for (int i = 0; i < points.Count; i++)
        {
            int prev = i - 1;
            if (prev < 0)
            {
                prev = points.Count - 1;
            }

            int next = i + 1;
            if (next >= points.Count)
            {
                next = 0;
            }

            float a1 = OnlineMapsUtils.Angle2D(points[prev], points[i]);
            float a2 = OnlineMapsUtils.Angle2D(points[i], points[next]);

            if (Mathf.Abs(a1 - a2) < 5)
            {
                points.RemoveAt(i);
                i--;
            }
        }

        if (points.Count < 3)
        {
            return(null);
        }

        Vector4 cp = new Vector4(float.MaxValue, float.MaxValue, float.MinValue, float.MinValue);

        for (int i = 0; i < points.Count; i++)
        {
            Vector3 point = points[i];
            if (point.x < cp.x)
            {
                cp.x = point.x;
            }
            if (point.z < cp.y)
            {
                cp.y = point.z;
            }
            if (point.x > cp.z)
            {
                cp.z = point.x;
            }
            if (point.z > cp.w)
            {
                cp.w = point.z;
            }
        }

        Vector3 centerPoint = new Vector3((cp.z + cp.x) / 2, 0, (cp.y + cp.w) / 2);

        for (int i = 0; i < points.Count; i++)
        {
            points[i] -= centerPoint;
        }

        bool generateWall = true;

        if (way.HasTagKey("building"))
        {
            string buildingType = way.GetTagValue("building");
            if (buildingType == "roof")
            {
                generateWall = false;
            }
        }

        float baseHeight = 15;
        float roofHeight = 0;

        OnlineMapsBuildingMaterial material = GetRandomMaterial(container);
        Material wallMaterial;
        Material roofMaterial;
        Vector2  scale = Vector2.one;

        if (defaultShader == null)
        {
            defaultShader = Shader.Find("Diffuse");
        }

        if (material != null)
        {
            if (material.wall != null)
            {
                wallMaterial = Instantiate(material.wall) as Material;
            }
            else
            {
                wallMaterial = new Material(defaultShader);
            }

            if (material.roof != null)
            {
                roofMaterial = Instantiate(material.roof) as Material;
            }
            else
            {
                roofMaterial = new Material(defaultShader);
            }

            scale = material.scale;
        }
        else
        {
            if (defaultWallMaterial == null)
            {
                defaultWallMaterial = new Material(defaultShader);
            }
            if (defaultRoofMaterial == null)
            {
                defaultRoofMaterial = new Material(defaultShader);
            }
            wallMaterial = Instantiate(defaultWallMaterial) as Material;
            roofMaterial = Instantiate(defaultRoofMaterial) as Material;
        }

        RoofType roofType = RoofType.flat;

        AnalizeHouseTags(way, ref wallMaterial, ref roofMaterial, ref baseHeight);
        AnalizeHouseRoofType(way, ref baseHeight, ref roofType, ref roofHeight);

        GameObject   houseGO    = CreateGameObject(way.id);
        MeshRenderer renderer   = houseGO.AddComponent <MeshRenderer>();
        MeshFilter   meshFilter = houseGO.AddComponent <MeshFilter>();

        Mesh mesh = new Mesh {
            name = way.id
        };

        meshFilter.sharedMesh    = mesh;
        renderer.sharedMaterials = new []
        {
            wallMaterial,
            roofMaterial
        };

        OnlineMapsBuildingBuiltIn building = houseGO.AddComponent <OnlineMapsBuildingBuiltIn>();

        building.way   = way;
        building.nodes = usedNodes;
        houseGO.transform.localPosition = centerPoint;
        houseGO.transform.localRotation = Quaternion.Euler(Vector3.zero);
        houseGO.transform.localScale    = Vector3.one;

        Vector2 centerCoords = Vector2.zero;
        float   minCX = float.MaxValue, minCY = float.MaxValue, maxCX = float.MinValue, maxCY = float.MinValue;

        foreach (OnlineMapsOSMNode node in usedNodes)
        {
            Vector2 nodeCoords = node;
            centerCoords += nodeCoords;
            if (nodeCoords.x < minCX)
            {
                minCX = nodeCoords.x;
            }
            if (nodeCoords.y < minCY)
            {
                minCY = nodeCoords.y;
            }
            if (nodeCoords.x > maxCX)
            {
                maxCX = nodeCoords.x;
            }
            if (nodeCoords.y > maxCY)
            {
                maxCY = nodeCoords.y;
            }
        }

        building.id                = way.id;
        building.initialZoom       = OnlineMaps.instance.zoom;
        building.centerCoordinates = new Vector2((maxCX + minCX) / 2, (maxCY + minCY) / 2);
        building.boundsCoords      = new Bounds(building.centerCoordinates, new Vector3(maxCX - minCX, maxCY - minCY));

        int wallVerticesCount = (points.Count + 1) * 2;
        int roofVerticesCount = points.Count;
        int verticesCount     = wallVerticesCount + roofVerticesCount;
        int countTriangles    = wallVerticesCount * 3;

        if (vertices == null)
        {
            vertices = new List <Vector3>(verticesCount);
        }
        else
        {
            vertices.Clear();
        }

        if (uvs == null)
        {
            uvs = new List <Vector2>(verticesCount);
        }
        else
        {
            uvs.Clear();
        }

        if (wallTriangles == null)
        {
            wallTriangles = new List <int>(countTriangles);
        }
        else
        {
            wallTriangles.Clear();
        }

        if (roofTriangles == null)
        {
            roofTriangles = new List <int>();
        }
        else
        {
            roofTriangles.Clear();
        }

        if (generateWall)
        {
            building.CreateHouseWall(points, baseHeight, wallMaterial, scale);
        }
        building.CreateHouseRoof(points, baseHeight, roofHeight, roofType);

        if (building.hasErrors)
        {
            OnlineMapsUtils.DestroyImmediate(building.gameObject);
            return(null);
        }

        mesh.vertices     = vertices.ToArray();
        mesh.uv           = uvs.ToArray();
        mesh.subMeshCount = 2;
        mesh.SetTriangles(wallTriangles.ToArray(), 0);
        mesh.SetTriangles(roofTriangles.ToArray(), 1);

        mesh.RecalculateBounds();
        mesh.RecalculateNormals();

        building.buildingCollider = houseGO.AddComponent <MeshCollider>();
        (building.buildingCollider as MeshCollider).sharedMesh = mesh;

        return(building);
    }