Example #1
0
    private void Start()
    {
        buildings = OnlineMapsBuildings.instance;
        limits    = GetComponent <OnlineMapsLimits>();

        buildings.OnBuildingCreated += InitializeBuilding;
    }
Example #2
0
    private static void AnalizeHouseTags(OnlineMapsBuildings container, OnlineMapsOSMWay way, ref Material wallMaterial, ref Material roofMaterial, ref float baseHeight)
    {
        string heightStr = container.useHeightTag? way.GetTagValue("height"): null;
        bool   hasHeight = false;

        if (!string.IsNullOrEmpty(heightStr))
        {
            hasHeight = GetHeightFromString(heightStr, ref baseHeight);
        }

        if (!hasHeight && container.useHeightTag)
        {
            string levelsStr = way.GetTagValue("building:levels");
            if (!String.IsNullOrEmpty(levelsStr))
            {
                float countLevels;
                if (float.TryParse(levelsStr, NumberStyles.AllowDecimalPoint, OnlineMapsUtils.numberFormat, out countLevels))
                {
                    baseHeight = countLevels * OnlineMapsBuildings.instance.levelHeight;
                    hasHeight  = true;
                }
            }
        }

        if (!hasHeight)
        {
            if (OnlineMapsBuildings.instance.OnGenerateBuildingHeight != null)
            {
                baseHeight = OnlineMapsBuildings.instance.OnGenerateBuildingHeight(way);
            }
            else
            {
                string minHeightStr = container.useHeightTag? way.GetTagValue("min_height"): null;
                if (!string.IsNullOrEmpty(minHeightStr))
                {
                    GetHeightFromString(minHeightStr, ref baseHeight);
                }
                else
                {
                    baseHeight = Random.Range(OnlineMapsBuildings.instance.levelsRange.min, OnlineMapsBuildings.instance.levelsRange.max) * OnlineMapsBuildings.instance.levelHeight;
                }
            }
        }

        if (baseHeight < OnlineMapsBuildings.instance.minHeight)
        {
            baseHeight = OnlineMapsBuildings.instance.minHeight;
        }

        if (container.useColorTag)
        {
            string colorStr = way.GetTagValue("building:colour");
            if (!String.IsNullOrEmpty(colorStr))
            {
                wallMaterial.color = roofMaterial.color = StringToColor(colorStr);
            }
        }
    }
Example #3
0
    private static OnlineMapsBuildingMaterial GetRandomMaterial(OnlineMapsBuildings container)
    {
        if (container.materials == null || container.materials.Length == 0)
        {
            return(null);
        }

        return(container.materials[Random.Range(0, container.materials.Length)]);
    }
Example #4
0
    /// <summary>
    /// Creates a new child GameObject, with the specified name.
    /// </summary>
    /// <param name="container">Reference to OnlineMapsBuildings</param>
    /// <param name="id">Name of GameObject.</param>
    /// <returns></returns>
    protected static GameObject CreateGameObject(OnlineMapsBuildings container, string id)
    {
        GameObject buildingGameObject = new GameObject(id);

        buildingGameObject.SetActive(false);

        buildingGameObject.transform.parent = container.container.transform;
        buildingGameObject.layer            = container.gameObject.layer;
        return(buildingGameObject);
    }
    public void OnEnable()
    {
        buildings = target as OnlineMapsBuildings;
        if (buildings.materials == null)
        {
            buildings.materials = new OnlineMapsBuildingMaterial[0];
        }

        CacheSerializedProperties();
    }
    private void OnEnable()
    {
        _instance = this;

        buildings        = new Dictionary <string, OnlineMapsBuildingBase>();
        unusedBuildings  = new Dictionary <string, OnlineMapsBuildingBase>();
        newBuildingsData = new Queue <OnlineMapsBuildingsNodeData>();

        buildingContainer = new GameObject("Buildings");
        buildingContainer.transform.parent        = transform;
        buildingContainer.transform.localPosition = Vector3.zero;
        buildingContainer.transform.localRotation = Quaternion.Euler(Vector3.zero);
    }
Example #7
0
    /// <summary>
    /// Dispose of building.
    /// </summary>
    public virtual void Dispose()
    {
        if (OnDispose != null)
        {
            OnDispose(this);
        }

        OnClick   = null;
        OnDispose = null;
        OnPress   = null;
        OnRelease = null;

        buildingCollider = null;
        container        = null;
        metaInfo         = null;
    }
Example #8
0
    /// <summary>
    /// Converts a list of nodes into an list of points in Unity World Space
    /// </summary>
    /// <param name="nodes">List of nodes</param>
    /// <param name="container">Reference to OnlineMapsBuildings</param>
    /// <returns>List of points in Unity World Space</returns>
    protected static List <Vector3> GetLocalPoints(List <OnlineMapsOSMNode> nodes, OnlineMapsBuildings container)
    {
        Vector2 tl = container.map.buffer.topLeftPosition;

        double sx, sy;

        container.map.projection.CoordinatesToTile(tl.x, tl.y, container.map.buffer.renderState.zoom, out sx, out sy);

        List <Vector3> localPoints = new List <Vector3>(Mathf.Min(nodes.Count, 8));
        float          zoomCoof    = container.map.buffer.renderState.zoomCoof;

        float sw = OnlineMapsUtils.tileSize * container.control.sizeInScene.x / container.map.width / zoomCoof;
        float sh = OnlineMapsUtils.tileSize * container.control.sizeInScene.y / container.map.height / zoomCoof;

        for (int i = 0; i < nodes.Count; i++)
        {
            double px, py;
            container.map.projection.CoordinatesToTile(nodes[i].lon, nodes[i].lat, container.map.buffer.renderState.zoom, out px, out py);
            localPoints.Add(new Vector3((float)((sx - px) * sw), 0, (float)((py - sy) * sh)));
        }
        return(localPoints);
    }
Example #9
0
    private void OnEnable()
    {
        map     = GetComponent <OnlineMaps>();
        control = map.control as OnlineMapsControlBaseDynamicMesh;

        bool isFirstEnable = _instance == null;

        _instance = this;

        buildings        = new Dictionary <string, OnlineMapsBuildingBase>();
        unusedBuildings  = new Dictionary <string, OnlineMapsBuildingBase>();
        newBuildingsData = new Queue <OnlineMapsBuildingsNodeData>();

        container = new GameObject("Buildings");
        container.transform.parent        = transform;
        container.transform.localPosition = Vector3.zero;
        container.transform.localRotation = Quaternion.Euler(Vector3.zero);
        container.transform.localScale    = Vector3.one;

        if (!isFirstEnable)
        {
            Start();
        }
    }
 public void OnEnable()
 {
     buildings = target as OnlineMapsBuildings;
 }
Example #11
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);
    }
Example #12
0
 private void OnEnable()
 {
     _instance = this;
 }
Example #13
0
 void Start()
 {
     onlineMapsBuildings = gameObject.GetComponent <OnlineMapsBuildings>();
     onlineMapsBuildings.OnBuildingCreated += SetBuildingScale;
     onlineMapsBuildings.OnBuildingCreated += SetGameObjectScale;
 }
 public void OnEnable()
 {
     buildings = target as OnlineMapsBuildings;
 }
 private void OnEnable()
 {
     _instance = this;
 }
    /// <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;

        List<OnlineMapsOSMNode> usedNodes = way.GetNodes(nodes);
        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);
        foreach (Vector3 point in points)
        {
            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;
        }
        //centerPoint = points.Aggregate(centerPoint, (current, point) => current + point) / points.Count;
        Vector3 centerPoint = new Vector3((cp.z + cp.x) / 2, points.Min(p => p.y), (cp.y + cp.w) / 2);

        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 defWallMaterial = (material != null)? material.wall: null;
        Material defRoofMaterial = (material != null) ? material.roof : null;
        Vector2 scale = (material != null) ? material.scale : Vector2.one;

        if (defWallMaterial == null) defWallMaterial = new Material(Shader.Find("Diffuse"));
        if (defRoofMaterial == null) defRoofMaterial = new Material(Shader.Find("Diffuse"));

        Material wallMaterial = new Material(defWallMaterial);
        Material roofMaterial = new Material(defRoofMaterial);

        OnlineMapsBuildingRoofType roofType = OnlineMapsBuildingRoofType.flat;
        AnalizeHouseTags(way, ref wallMaterial, ref roofMaterial, ref baseHeight);
        AnalizeHouseRoofType(way, ref baseHeight, ref roofType, ref roofHeight);

        Vector3[] baseVerticles = points.Select(p => p - centerPoint).ToArray();

        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>();
        houseGO.transform.localPosition = centerPoint;
        houseGO.transform.localRotation = Quaternion.Euler(Vector3.zero);

        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));

        List<Vector3> vertices = new List<Vector3>();
        List<Vector2> uvs = new List<Vector2>();
        List<int> wallTriangles = new List<int>();
        List<int> roofTriangles = new List<int>();

        if (generateWall) building.CreateHouseWall(baseVerticles, baseHeight, wallMaterial, scale, ref vertices, ref uvs, ref wallTriangles);
        building.CreateHouseRoof(baseVerticles, baseHeight, roofHeight, roofType, ref vertices, ref uvs, ref roofTriangles);

        if (building.hasErrors)
        {
            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;
    }
    private static OnlineMapsBuildingMaterial GetRandomMaterial(OnlineMapsBuildings container)
    {
        if (container.materials == null || container.materials.Length == 0) return null;

        return container.materials[Random.Range(0, container.materials.Length)];
    }