private void Update3DMarkers()
    {
        if (OnlineMapsMarker3DManager.instance == null)
        {
            return;
        }
        if (control.cl == null)
        {
            return;
        }

        int zoom = map.zoom;

        double tlx, tly, brx, bry;

        map.GetCorners(out tlx, out tly, out brx, out bry);

        double ttlx, ttly, tbrx, tbry;

        map.projection.CoordinatesToTile(tlx, tly, zoom, out ttlx, out ttly);
        map.projection.CoordinatesToTile(brx, bry, zoom, out tbrx, out tbry);

        Bounds bounds     = control.cl.bounds;
        float  bestYScale = OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry);

        foreach (OnlineMapsMarker3D marker in OnlineMapsMarker3DManager.instance)
        {
            marker.Update(map, control, bounds, tlx, tly, brx, bry, zoom, ttlx, ttly, tbrx, tbry, bestYScale);
        }
    }
Example #2
0
    public float GetUnscaledElevationValue(double x, double z)
    {
        double tlx, tly, brx, bry;

        map.GetCorners(out tlx, out tly, out brx, out bry);
        return(OnlineMapsElevationManagerBase.GetUnscaledElevation(x, z, tlx, tly, brx, bry));
    }
Example #3
0
    /// <summary>
    /// Updates marker instance.
    /// </summary>
    /// <param name="tlx">Longitude of top-left corner of the map</param>
    /// <param name="tly">Latitude of top-left corner of the map</param>
    /// <param name="brx">Longitude of bottom-right corner of the map</param>
    /// <param name="bry">Latitude of bottom-right corner of the map</param>
    /// <param name="zoom">Zoom of the map</param>
    public override void Update(double tlx, double tly, double brx, double bry, int zoom)
    {
        double ttlx, ttly, tbrx, tbry;

        map.GetTileCorners(out ttlx, out ttly, out tbrx, out tbry, zoom);
        float bestYScale = OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry);

        Update(control.meshFilter.sharedMesh.bounds, tlx, tly, brx, bry, zoom, ttlx, ttly, tbrx, tbry, bestYScale);
    }
Example #4
0
    /// <summary>
    /// Updates marker instance.
    /// </summary>
    /// <param name="tlx">Longitude of top-left corner of the map</param>
    /// <param name="tly">Latitude of top-left corner of the map</param>
    /// <param name="brx">Longitude of bottom-right corner of the map</param>
    /// <param name="bry">Latitude of bottom-right corner of the map</param>
    /// <param name="zoom">Zoom of the map</param>
    public override void Update(double tlx, double tly, double brx, double bry, int zoom)
    {
        double ttlx, ttly, tbrx, tbry;

        map.GetTileCorners(out ttlx, out ttly, out tbrx, out tbry, zoom);
        float bestYScale = OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry);

        Update(OnlineMaps.instance, OnlineMapsControlBase3D.instance, OnlineMapsControlBase3D.instance.cl.bounds, tlx, tly, brx, bry, zoom, ttlx, ttly, tbrx, tbry, bestYScale);
    }
Example #5
0
    private void UpdateCameraPosition()
    {
        if (rotation.x > maxRotationX)
        {
            rotation.x = maxRotationX;
        }
        else if (rotation.x < 0)
        {
            rotation.x = 0;
        }

        float rx = 90 - rotation.x;

        if (rx > 89.9)
        {
            rx = 89.9f;
        }

        double px = Math.Cos(rx * Mathf.Deg2Rad) * distance;
        double py = Math.Sin(rx * Mathf.Deg2Rad) * distance;
        double pz = Math.Cos(rotation.y * Mathf.Deg2Rad) * px;

        px = Math.Sin(rotation.y * Mathf.Deg2Rad) * px;

        Vector3 targetPosition = transform.position;
        Vector3 offset         = new Vector3(sizeInScene.x / -2, 0, sizeInScene.y / 2);

        if (OnlineMapsElevationManagerBase.useElevation)
        {
            double tlx, tly, brx, bry;
            map.GetCorners(out tlx, out tly, out brx, out bry);
            float yScale = OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry);
            if (adjustTo == OnlineMapsCameraAdjust.maxElevationInArea)
            {
                offset.y = OnlineMapsElevationManagerBase.instance.GetMaxElevation(yScale);
            }
            else
            {
                offset.y = OnlineMapsElevationManagerBase.GetElevation(targetPosition.x, targetPosition.z, yScale, tlx, tly, brx, bry);
            }
        }

        offset.Scale(transform.lossyScale);
        targetPosition += transform.rotation * offset;

        Vector3 oldPosition = activeCamera.transform.position;
        Vector3 newPosition = transform.rotation * new Vector3((float)px, (float)py, (float)pz) + targetPosition;

        activeCamera.transform.position = newPosition;
        activeCamera.transform.LookAt(targetPosition);

        if (oldPosition != newPosition && OnCameraControl != null)
        {
            OnCameraControl();
        }
    }
Example #6
0
    private void Update3DMarkers()
    {
        OnlineMapsMarker3DManager manager = control.marker3DManager;

        if (manager == null || !manager.enabled)
        {
            return;
        }
        if (control.cl == null)
        {
            return;
        }

        int zoom = map.zoom;

        double tlx, tly, brx, bry;

        map.GetCorners(out tlx, out tly, out brx, out bry);

        double ttlx, ttly, tbrx, tbry;

        map.projection.CoordinatesToTile(tlx, tly, zoom, out ttlx, out ttly);
        map.projection.CoordinatesToTile(brx, bry, zoom, out tbrx, out tbry);

        int maxX = 1 << zoom;

        bool isEntireWorld = map.buffer.renderState.width == maxX * OnlineMapsUtils.tileSize;

        if (isEntireWorld && Math.Abs(tlx - brx) < 180)
        {
            if (tlx < 0)
            {
                brx  += 360;
                tbrx += maxX;
            }
            else
            {
                tlx  -= 360;
                ttlx -= maxX;
            }
        }

        Bounds bounds     = control.meshFilter.sharedMesh.bounds;
        float  bestYScale = OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry);

        for (int i = manager.Count - 1; i >= 0; i--)
        {
            OnlineMapsMarker3D marker = manager[i];
            if (marker.manager == null)
            {
                marker.manager = manager;
            }
            marker.Update(bounds, tlx, tly, brx, bry, zoom, ttlx, ttly, tbrx, tbry, bestYScale);
        }
    }
Example #7
0
        private void Update()
        {
            double lookProgress = progress + 0.001;
            double tiltProgress = progress + 0.001;

            Point position     = GetPointByProgress(progress);
            Point lookPosition = GetPointByProgress(lookProgress);
            Point tiltPosition = GetPointByProgress(tiltProgress);

            speed += accelerationCurve.Evaluate(speed / maxSpeed) * Time.deltaTime;
            if (speed > lookPosition.relativeSpeed * maxSpeed)
            {
                speed = lookPosition.relativeSpeed * maxSpeed;
            }
            double offset = Time.deltaTime * speed / 3600;

            progress += offset / totalDistance;

            double p1x, p1y, p2x, p2y;

            map.projection.CoordinatesToTile(position.longitude, position.latitude, map.zoom, out p1x, out p1y);
            map.projection.CoordinatesToTile(lookPosition.longitude, lookPosition.latitude, map.zoom, out p2x, out p2y);
            targetRotation = (float)OnlineMapsUtils.Angle2D(p1x, p1y, p2x, p2y);

            map.projection.CoordinatesToTile(tiltPosition.longitude, tiltPosition.latitude, map.zoom, out p2x, out p2y);
            float tiltRotation = (float)OnlineMapsUtils.Angle2D(p1x, p1y, p2x, p2y);

            tilt = tiltRotation - airplane.transform.rotation.eulerAngles.y;

            Vector3 p = OnlineMapsTileSetControl.instance.GetWorldPosition(position.longitude, position.latitude);

            altitude = position.relativeAltitude * maxAltitude;
            float elevation = OnlineMapsElevationManagerBase.GetUnscaledElevation(p.x, p.z);

            p.x = -1024;
            float zoom = altitudeZoomCurve.Evaluate(altitude / maxAltitude);

            p.y = Mathf.Max(altitude, elevation) * OnlineMapsElevationManagerBase.GetBestElevationYScale();
            p.z = 1024;
            airplane.transform.position = p;
            airplane.transform.rotation = Quaternion.Euler(0, Mathf.LerpAngle(airplane.transform.rotation.eulerAngles.y, targetRotation, Time.deltaTime), 0);
            float s = 1 / Mathf.Pow(2, 15 - map.floatZoom);

            transform.localScale = new Vector3(s, s, s);
            internalGO.transform.localRotation = Quaternion.Euler(tilt, 0, 0);
            map.SetPositionAndZoom(position.longitude, position.latitude, zoom);
            OnlineMapsCameraOrbit.instance.rotation = new Vector2(OnlineMapsCameraOrbit.instance.rotation.x, airplane.transform.rotation.eulerAngles.y + 90);
        }
Example #8
0
    /// <summary>
    /// Converts geographical coordinates to position in world space with elevation.
    /// </summary>
    /// <param name="lng">Longitude</param>
    /// <param name="lat">Laatitude</param>
    /// <param name="tlx">Top-left longitude.</param>
    /// <param name="tly">Top-left latitude.</param>
    /// <param name="brx">Bottom-right longitude.</param>
    /// <param name="bry">Bottom-right latitude.</param>
    /// <returns>Position in world space.</returns>
    public Vector3 GetWorldPositionWithElevation(double lng, double lat, double tlx, double tly, double brx, double bry)
    {
        double mx, my;

        GetPosition(lng, lat, out mx, out my);

        mx = -mx / map.width * sizeInScene.x;
        my = my / map.height * sizeInScene.y;

        float y = OnlineMapsElevationManagerBase.GetElevation(mx, my, OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry), tlx, tly, brx, bry);

        Vector3 offset = transform.rotation * new Vector3((float)mx, y, (float)my);

        offset.Scale(map.transform.lossyScale);

        return(map.transform.position + offset);
    }
Example #9
0
    private void UpdateSimpleMeshCollider(float yScale, double tlx, double tly, double brx, double bry)
    {
        int res = OnlineMapsElevationManagerBase.useElevation ? 6 : 1;
        int r2  = res + 1;

        Vector3[] vertices = new Vector3[r2 * r2];
        float     sx       = -sizeInScene.x / res;
        float     sy       = sizeInScene.y / res;

        int[] triangles = new int[res * res * 6];
        int   ti        = 0;

        for (int y = 0; y < r2; y++)
        {
            for (int x = 0; x < r2; x++)
            {
                float px = sx * x;
                float pz = sy * y;
                float py = OnlineMapsElevationManagerBase.GetElevation(px, pz, yScale, tlx, tly, brx, bry);
                vertices[y * r2 + x] = new Vector3(sx * x, py, sy * y);

                if (x != 0 && y != 0)
                {
                    int p4 = y * r2 + x;
                    int p3 = p4 - 1;
                    int p2 = p4 - r2;
                    int p1 = p2 - 1;

                    triangles[ti++] = p1;
                    triangles[ti++] = p2;
                    triangles[ti++] = p4;
                    triangles[ti++] = p1;
                    triangles[ti++] = p4;
                    triangles[ti++] = p3;
                }
            }
        }

        Mesh mesh = meshCollider.sharedMesh;

        mesh.Clear();
        mesh.vertices = vertices;
        mesh.SetTriangles(triangles, 0);
        mesh.RecalculateBounds();
        meshCollider.sharedMesh = mesh;
    }
Example #10
0
        private void Start()
        {
            map              = OnlineMaps.instance;
            control          = OnlineMapsTileSetControl.instance;
            elevationManager = OnlineMapsElevationManagerBase.instance;

            double tlx, tly, brx, bry;

            map.GetCorners(out tlx, out tly, out brx, out bry);

            Vector3 position = control.GetWorldPosition(map.position);

            position.y = altitude;
            if (elevationManager != null)
            {
                position.y *= OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry) * elevationManager.scale;
            }

            gameObject.transform.position = position;
            map.GetPosition(out px, out py);
        }
Example #11
0
    public override Vector2 GetScreenPosition(double lng, double lat)
    {
        double px, py;

        GetPosition(lng, lat, out px, out py);
        px /= map.buffer.renderState.width;
        py /= map.buffer.renderState.height;

        double cpx = -sizeInScene.x * px;
        double cpy = sizeInScene.y * py;

        double tlx, tly, brx, bry;

        map.GetCorners(out tlx, out tly, out brx, out bry);
        float   elevationScale = OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry);
        float   elevation      = OnlineMapsElevationManagerBase.GetElevation(cpx, cpy, elevationScale, tlx, tly, brx, bry);
        Vector3 worldPos       = transform.position + transform.rotation * new Vector3((float)(cpx * transform.lossyScale.x), elevation * transform.lossyScale.y, (float)(cpy * transform.lossyScale.z));

        Camera cam = activeCamera != null? activeCamera: Camera.main;

        return(cam.WorldToScreenPoint(worldPos));
    }
Example #12
0
 public float GetElevationValue(double x, double z, float yScale, double tlx, double tly, double brx, double bry)
 {
     return(OnlineMapsElevationManagerBase.GetElevation(x, z, yScale, tlx, tly, brx, bry));
 }
Example #13
0
 public float GetElevationValue(double x, double z, float yScale, Vector2 topLeftPosition, Vector2 bottomRightPosition)
 {
     return(OnlineMapsElevationManagerBase.GetElevation(x, z, yScale, topLeftPosition.x, topLeftPosition.y, bottomRightPosition.x, bottomRightPosition.y));
 }
Example #14
0
 public float GetBestElevationYScale(double tlx, double tly, double brx, double bry)
 {
     return(OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry));
 }
Example #15
0
 public float GetBestElevationYScale(Vector2 topLeftPosition, Vector2 bottomRightPosition)
 {
     return(OnlineMapsElevationManagerBase.GetBestElevationYScale(topLeftPosition.x, topLeftPosition.y, bottomRightPosition.x, bottomRightPosition.y));
 }
Example #16
0
    private void UpdateMapMesh()
    {
        int zoom = map.buffer.renderState.zoom;

        int w1 = map.buffer.renderState.width / OnlineMapsUtils.tileSize;
        int h1 = map.buffer.renderState.height / OnlineMapsUtils.tileSize;

        int subMeshVX = 1;
        int subMeshVZ = 1;

        if (OnlineMapsElevationManagerBase.isActive)
        {
            if (w1 < elevationResolution)
            {
                subMeshVX = elevationResolution % w1 == 0 ? elevationResolution / w1 : elevationResolution / w1 + 1;
            }
            if (h1 < elevationResolution)
            {
                subMeshVZ = elevationResolution % h1 == 0 ? elevationResolution / h1 : elevationResolution / h1 + 1;
            }
        }

        float zoomScale = 1 - map.buffer.renderState.zoomScale / 2;

        double subMeshSizeX = sizeInScene.x / w1;
        double subMeshSizeY = sizeInScene.y / h1;

        double tlx, tly, brx, bry;

        map.buffer.GetCorners(out tlx, out tly, out brx, out bry);
        double px = map.buffer.renderState.longitude;
        double py = map.buffer.renderState.latitude;
        //map.GetPosition(out px, out py);

        double tlpx, tlpy;

        map.projection.CoordinatesToTile(px, py, zoom, out tlpx, out tlpy);
        double posX = tlpx - bufferPosition.x;
        double posY = tlpy - bufferPosition.y;

        posX -= w1 / 2d * zoomScale;
        posY -= h1 / 2d * zoomScale;

        int maxX = 1 << zoom;

        if (posX >= maxX)
        {
            posX -= maxX;
        }
        else if (posX < 0)
        {
            posX += maxX;
        }

        subMeshSizeX /= zoomScale;
        subMeshSizeY /= zoomScale;

        double startPosX = subMeshSizeX * posX;
        double startPosZ = -subMeshSizeY * posY;

        float yScale = OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry);

        int w = w1 + 2;
        int h = h1 + 2;

        Material[] materials = rendererInstance.materials;

        if (vertices.Length != w * h * (subMeshVX + 1) * (subMeshVZ + 1))
        {
            ReinitMapMesh();
            materials = rendererInstance.materials;
        }

        Material fMaterial = materials[0];

        bool hasTraffic           = fMaterial.HasProperty("_TrafficTex");
        bool hasOverlayBack       = fMaterial.HasProperty("_OverlayBackTex");
        bool hasOverlayBackAlpha  = fMaterial.HasProperty("_OverlayBackAlpha");
        bool hasOverlayFront      = fMaterial.HasProperty("_OverlayFrontTex");
        bool hasOverlayFrontAlpha = fMaterial.HasProperty("_OverlayFrontAlpha");

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

        for (int y = 0; y < h; y++)
        {
            for (int x = 0; x < w; x++)
            {
                UpdateMapSubMesh(
                    x, y, w, h, subMeshSizeX, subMeshSizeY, subMeshVX, subMeshVZ, startPosX, startPosZ, yScale,
                    tlx, tly, brx, bry, materials, ref minY, ref maxY,
                    hasTraffic, hasOverlayBack, hasOverlayBackAlpha, hasOverlayFront, hasOverlayFrontAlpha
                    );
            }
        }

        tilesetMesh.vertices = vertices;
        tilesetMesh.uv       = uv;

        tilesetMesh.RecalculateBounds();

        if (OnlineMapsElevationManagerBase.isActive || firstUpdate)
        {
            if (meshCollider != null)
            {
                if (firstUpdate || elevationManager.zoomRange.InRange(zoom))
                {
                    colliderWithElevation = true;
                    if (colliderType == OnlineMapsColliderType.fullMesh)
                    {
                        if (meshCollider.sharedMesh != null)
                        {
                            OnlineMapsUtils.Destroy(meshCollider.sharedMesh);
                        }
                        meshCollider.sharedMesh = Instantiate(tilesetMesh) as Mesh;
                    }
                    else
                    {
                        UpdateSimpleMeshCollider(yScale, tlx, tly, brx, bry);
                    }
                }
                else if (colliderWithElevation)
                {
                    colliderWithElevation = false;
                    if (colliderType == OnlineMapsColliderType.fullMesh)
                    {
                        if (meshCollider.sharedMesh != null)
                        {
                            OnlineMapsUtils.Destroy(meshCollider.sharedMesh);
                        }
                        meshCollider.sharedMesh = Instantiate(tilesetMesh) as Mesh;
                    }
                    else
                    {
                        UpdateSimpleMeshCollider(yScale, tlx, tly, brx, bry);
                    }
                }
            }
            else if (boxCollider != null)
            {
                boxCollider.center = new Vector3(-sizeInScene.x / 2, (minY + maxY) / 2, sizeInScene.y / 2);
                boxCollider.size   = new Vector3(sizeInScene.x, colliderType == OnlineMapsColliderType.box ? maxY - minY : 0, sizeInScene.y);
            }

            firstUpdate = false;
        }

        if (OnMeshUpdated != null)
        {
            OnMeshUpdated();
        }
    }
    protected void DrawActivePoints(OnlineMapsTileSetControl control, ref List <Vector2> activePoints, ref List <Vector3> vertices, ref List <Vector3> normals, ref List <int> triangles, ref List <Vector2> uv, float width)
    {
        if (activePoints.Count < 2)
        {
            activePoints.Clear();
            return;
        }

        float w2 = width * 2;

        Vector3 prevS1 = Vector3.zero;
        Vector3 prevS2 = Vector3.zero;

        int  c = activePoints.Count - 1;
        bool extraPointAdded = false;

        for (int i = 0; i < activePoints.Count; i++)
        {
            float px = -activePoints[i].x;
            float pz = activePoints[i].y;

            Vector3 s1;
            Vector3 s2;

            if (i == 0 || i == c)
            {
                float p1x, p1z, p2x, p2z;

                if (i == 0)
                {
                    p1x = px;
                    p1z = pz;
                    p2x = -activePoints[i + 1].x;
                    p2z = activePoints[i + 1].y;
                }
                else
                {
                    p1x = -activePoints[i - 1].x;
                    p1z = activePoints[i - 1].y;
                    p2x = px;
                    p2z = pz;
                }

                float a = OnlineMapsUtils.Angle2DRad(p1x, p1z, p2x, p2z, 90);

                float offX = Mathf.Cos(a) * width;
                float offZ = Mathf.Sin(a) * width;

                float s1x = px + offX;
                float s1z = pz + offZ;
                float s2x = px - offX;
                float s2z = pz - offZ;

                float s1y = OnlineMapsElevationManagerBase.GetElevation(s1x, s1z, bestElevationYScale, tlx, tly, brx, bry);
                float s2y = OnlineMapsElevationManagerBase.GetElevation(s2x, s2z, bestElevationYScale, tlx, tly, brx, bry);

                s1 = new Vector3(s1x, s1y, s1z);
                s2 = new Vector3(s2x, s2y, s2z);
            }
            else
            {
                float p1x = -activePoints[i - 1].x;
                float p1z = activePoints[i - 1].y;
                float p2x = -activePoints[i + 1].x;
                float p2z = activePoints[i + 1].y;

                float a1 = OnlineMapsUtils.Angle2DRad(p1x, p1z, px, pz, 90);
                float a3 = OnlineMapsUtils.AngleOfTriangle(activePoints[i - 1], activePoints[i + 1], activePoints[i]) * Mathf.Rad2Deg;
                if (a3 < 60 && !extraPointAdded)
                {
                    activePoints.Insert(i + 1, Vector2.Lerp(activePoints[i], activePoints[i + 1], 0.001f));
                    activePoints[i] = Vector2.Lerp(activePoints[i], activePoints[i - 1], 0.001f);
                    c++;
                    i--;
                    extraPointAdded = true;
                    continue;
                }

                extraPointAdded = false;
                float a2 = OnlineMapsUtils.Angle2DRad(px, pz, p2x, p2z, 90);

                float off1x = Mathf.Cos(a1) * width;
                float off1z = Mathf.Sin(a1) * width;
                float off2x = Mathf.Cos(a2) * width;
                float off2z = Mathf.Sin(a2) * width;

                float p21x = px + off1x;
                float p21z = pz + off1z;
                float p22x = px - off1x;
                float p22z = pz - off1z;
                float p31x = px + off2x;
                float p31z = pz + off2z;
                float p32x = px - off2x;
                float p32z = pz - off2z;

                float is1x, is1z, is2x, is2z;

                int state1 = OnlineMapsUtils.GetIntersectionPointOfTwoLines(p1x + off1x, p1z + off1z, p21x, p21z, p31x, p31z, p2x + off2x, p2z + off2z, out is1x, out is1z);
                int state2 = OnlineMapsUtils.GetIntersectionPointOfTwoLines(p1x - off1x, p1z - off1z, p22x, p22z, p32x, p32z, p2x - off2x, p2z - off2z, out is2x, out is2z);

                if (state1 == 1 && state2 == 1)
                {
                    float o1x = is1x - px;
                    float o1z = is1z - pz;
                    float o2x = is2x - px;
                    float o2z = is2z - pz;

                    float m1 = Mathf.Sqrt(o1x * o1x + o1z * o1z);
                    float m2 = Mathf.Sqrt(o2x * o2x + o2z * o2z);

                    if (m1 > w2)
                    {
                        is1x = o1x / m1 * w2 + px;
                        is1z = o1z / m1 * w2 + pz;
                    }
                    if (m2 > w2)
                    {
                        is2x = o2x / m2 * w2 + px;
                        is2z = o2z / m2 * w2 + pz;
                    }

                    s1 = new Vector3(is1x, OnlineMapsElevationManagerBase.GetElevation(is1x, is1z, bestElevationYScale, tlx, tly, brx, bry), is1z);
                    s2 = new Vector3(is2x, OnlineMapsElevationManagerBase.GetElevation(is2x, is2z, bestElevationYScale, tlx, tly, brx, bry), is2z);
                }
                else
                {
                    float po1x = p1x + off1x;
                    float po1z = p1z + off1z;
                    float po2x = p2x - off1x;
                    float po2z = p2z - off1z;

                    s1 = new Vector3(po1x, OnlineMapsElevationManagerBase.GetElevation(po1x, po1z, bestElevationYScale, tlx, tly, brx, bry), po1z);
                    s2 = new Vector3(po2x, OnlineMapsElevationManagerBase.GetElevation(po2x, po2z, bestElevationYScale, tlx, tly, brx, bry), po2z);
                }
            }

            if (i > 0)
            {
                AddLineSegment(vertices, normals, triangles, uv, s1, s2, prevS1, prevS2);
            }

            prevS1 = s1;
            prevS2 = s2;
        }

        activePoints.Clear();
    }
Example #18
0
    /// <summary>
    /// Updates camera position
    /// </summary>
    public void UpdateCameraPosition()
    {
        if (rotation.x > maxRotationX)
        {
            rotation.x = maxRotationX;
        }
        else if (rotation.x < 0)
        {
            rotation.x = 0;
        }

        float rx = 90 - rotation.x;

        if (rx > 89.9)
        {
            rx = 89.9f;
        }

        double px = Math.Cos(rx * Mathf.Deg2Rad) * distance;
        double py = Math.Sin(rx * Mathf.Deg2Rad) * distance;
        double pz = Math.Cos(rotation.y * Mathf.Deg2Rad) * px;

        px = Math.Sin(rotation.y * Mathf.Deg2Rad) * px;

        Vector3 targetPosition;

        if (adjustTo == OnlineMapsCameraAdjust.gameObject && adjustToGameObject != null)
        {
            targetPosition = adjustToGameObject.transform.position;
        }
        else
        {
            targetPosition = map.transform.position;
            Vector3 offset = new Vector3(sizeInScene.x / -2, 0, sizeInScene.y / 2);

            if (OnlineMapsElevationManagerBase.useElevation)
            {
                double tlx, tly, brx, bry;
                map.GetCorners(out tlx, out tly, out brx, out bry);
                float yScale = OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry);

                if (adjustTo == OnlineMapsCameraAdjust.maxElevationInArea)
                {
                    offset.y = OnlineMapsElevationManagerBase.instance.GetMaxElevation(yScale);
                }
                else if (adjustTo == OnlineMapsCameraAdjust.averageCenter)
                {
                    float ox = sizeInScene.x / 64;
                    float oz = sizeInScene.y / 64;
                    offset.y = OnlineMapsElevationManagerBase.GetElevation(targetPosition.x, targetPosition.z, yScale, tlx, tly, brx, bry) * 3;

                    offset.y += OnlineMapsElevationManagerBase.GetElevation(targetPosition.x - ox, targetPosition.z - oz, yScale, tlx, tly, brx, bry) * 2;
                    offset.y += OnlineMapsElevationManagerBase.GetElevation(targetPosition.x, targetPosition.z - oz, yScale, tlx, tly, brx, bry) * 2;
                    offset.y += OnlineMapsElevationManagerBase.GetElevation(targetPosition.x + ox, targetPosition.z - oz, yScale, tlx, tly, brx, bry) * 2;
                    offset.y += OnlineMapsElevationManagerBase.GetElevation(targetPosition.x + ox, targetPosition.z, yScale, tlx, tly, brx, bry) * 2;
                    offset.y += OnlineMapsElevationManagerBase.GetElevation(targetPosition.x + ox, targetPosition.z + oz, yScale, tlx, tly, brx, bry) * 2;
                    offset.y += OnlineMapsElevationManagerBase.GetElevation(targetPosition.x, targetPosition.z + oz, yScale, tlx, tly, brx, bry) * 2;
                    offset.y += OnlineMapsElevationManagerBase.GetElevation(targetPosition.x - ox, targetPosition.z + oz, yScale, tlx, tly, brx, bry) * 2;
                    offset.y += OnlineMapsElevationManagerBase.GetElevation(targetPosition.x - ox, targetPosition.z, yScale, tlx, tly, brx, bry) * 2;

                    ox *= 2;
                    oz *= 2;

                    offset.y += OnlineMapsElevationManagerBase.GetElevation(targetPosition.x - ox, targetPosition.z - oz, yScale, tlx, tly, brx, bry);
                    offset.y += OnlineMapsElevationManagerBase.GetElevation(targetPosition.x, targetPosition.z - oz, yScale, tlx, tly, brx, bry);
                    offset.y += OnlineMapsElevationManagerBase.GetElevation(targetPosition.x + ox, targetPosition.z - oz, yScale, tlx, tly, brx, bry);
                    offset.y += OnlineMapsElevationManagerBase.GetElevation(targetPosition.x + ox, targetPosition.z, yScale, tlx, tly, brx, bry);
                    offset.y += OnlineMapsElevationManagerBase.GetElevation(targetPosition.x + ox, targetPosition.z + oz, yScale, tlx, tly, brx, bry);
                    offset.y += OnlineMapsElevationManagerBase.GetElevation(targetPosition.x, targetPosition.z + oz, yScale, tlx, tly, brx, bry);
                    offset.y += OnlineMapsElevationManagerBase.GetElevation(targetPosition.x - ox, targetPosition.z + oz, yScale, tlx, tly, brx, bry);
                    offset.y += OnlineMapsElevationManagerBase.GetElevation(targetPosition.x - ox, targetPosition.z, yScale, tlx, tly, brx, bry);

                    offset.y /= 27;
                }
                else
                {
                    offset.y = OnlineMapsElevationManagerBase.GetElevation(targetPosition.x, targetPosition.z, yScale, tlx, tly, brx, bry);
                }
            }

            offset.Scale(map.transform.lossyScale);

            targetPosition += map.transform.rotation * offset;
        }

        Vector3 oldPosition = activeCamera.transform.position;
        Vector3 newPosition = map.transform.rotation * new Vector3((float)px, (float)py, (float)pz) + targetPosition;

        activeCamera.transform.position = newPosition;
        activeCamera.transform.LookAt(targetPosition);

        if (control.isMapDrag)
        {
            control.UpdateLastPosition();
        }

        if (oldPosition != newPosition && OnCameraControl != null)
        {
            OnCameraControl();
        }
    }
Example #19
0
        void Update()
        {
            const float maxTilt = 50;

            if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.A))
            {
                tilt -= Time.deltaTime * tiltSpeed * maxTilt;
            }
            else if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D))
            {
                tilt += Time.deltaTime * tiltSpeed * maxTilt;
            }
            else if (tilt != 0)
            {
                float tiltOffset = Time.deltaTime * tiltSpeed * maxTilt;
                if (Mathf.Abs(tilt) > tiltOffset)
                {
                    tilt -= tiltOffset * Mathf.Sign(tilt);
                }
                else
                {
                    tilt = 0;
                }
            }

            tilt = Mathf.Clamp(tilt, -maxTilt, maxTilt);
            container.transform.localRotation = Quaternion.Euler(tilt, 0, 0);

            if (Math.Abs(tilt) > float.Epsilon)
            {
                transform.Rotate(Vector3.up, tilt * rotateSpeed * Time.deltaTime);
            }

            double tlx, tly, brx, bry, dx, dy;

            map.GetTopLeftPosition(out tlx, out tly);
            map.GetBottomRightPosition(out brx, out bry);

            OnlineMapsUtils.DistanceBetweenPoints(tlx, tly, brx, bry, out dx, out dy);

            double mx = (brx - tlx) / dx;
            double my = (tly - bry) / dy;

            double v = (double)speed * Time.deltaTime / 3600.0;

            double ox = mx * v * Math.Cos(transform.rotation.eulerAngles.y * OnlineMapsUtils.Deg2Rad);
            double oy = my * v * Math.Sin((360 - transform.rotation.eulerAngles.y) * OnlineMapsUtils.Deg2Rad);

            px += ox;
            py += oy;

            map.SetPosition(px, py);

            Vector3 pos = transform.position;

            pos.y = altitude;
            if (elevationManager != null)
            {
                pos.y *= OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry) * elevationManager.scale;
            }
            transform.position = pos;

            Camera.main.transform.position = transform.position - transform.rotation * cameraOffset;
            Camera.main.transform.LookAt(transform);
        }
Example #20
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>(32);
        }
        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);
        Vector2 scale = Vector2.one;

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

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

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

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

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

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

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

        RoofType roofType = RoofType.flat;

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

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

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

        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.buffer.lastState.floatZoom;
        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();
        }

        double tlx, tly, brx, bry;

        OnlineMaps.instance.buffer.GetCorners(out tlx, out tly, out brx, out bry);
        baseHeight *= OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry) * OnlineMapsBuildings.instance.heightScale;

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

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

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

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

        if (container.generateColliders)
        {
            building.buildingCollider = houseGO.AddComponent <MeshCollider>();
            (building.buildingCollider as MeshCollider).sharedMesh = building.mesh;
        }

        return(building);
    }
Example #21
0
    /// <summary>
    /// Updates marker instance.
    /// </summary>
    /// <param name="map">Reference to the map</param>
    /// <param name="control">Reference to the control</param>
    /// <param name="bounds">Bounds of the map mesh</param>
    /// <param name="tlx">Longitude of top-left corner of the map</param>
    /// <param name="tly">Latitude of top-left corner of the map</param>
    /// <param name="brx">Longitude of bottom-right corner of the map</param>
    /// <param name="bry">Latitude of bottom-right corner of the map</param>
    /// <param name="zoom">Zoom of the map</param>
    /// <param name="ttlx">Tile X of top-left corner of the map</param>
    /// <param name="ttly">Tile Y of top-left corner of the map</param>
    /// <param name="tbrx">Tile X of bottom-right corner of the map</param>
    /// <param name="tbry">Tile Y of bottom-right corner of the map</param>
    /// <param name="bestYScale">Best y scale for current map view</param>
    public void Update(OnlineMaps map, OnlineMapsControlBase3D control, Bounds bounds, double tlx, double tly, double brx, double bry, int zoom, double ttlx, double ttly, double tbrx, double tbry, float bestYScale)
    {
        if (!enabled)
        {
            return;
        }
        if (instance == null)
        {
            Init(map.transform);
        }

        if (!range.InRange(zoom))
        {
            visible = false;
        }
        else if (OnCheckMapBoundaries != null)
        {
            visible = OnCheckMapBoundaries();
        }
        else if (checkMapBoundaries)
        {
            if (latitude > tly || latitude < bry)
            {
                visible = false;
            }
            else if (tlx < brx && (longitude < tlx || longitude > brx))
            {
                visible = false;
            }
            else if (tlx > brx && longitude < tlx && longitude > brx)
            {
                visible = false;
            }
            else
            {
                visible = true;
            }
        }
        else
        {
            visible = true;
        }

        if (!visible)
        {
            return;
        }

        if (_prefab != prefab)
        {
            Reinit(tlx, tly, brx, bry, zoom);
        }

        double mx, my;

        map.projection.CoordinatesToTile(longitude, latitude, zoom, out mx, out my);

        int maxX = 1 << zoom;

        double sx  = tbrx - ttlx;
        double mpx = mx - ttlx;

        if (sx < 0)
        {
            sx += maxX;
        }

        if (checkMapBoundaries)
        {
            if (mpx < 0)
            {
                mpx += maxX;
            }
            else if (mpx > maxX)
            {
                mpx -= maxX;
            }
        }
        else
        {
            double dx1 = Math.Abs(mpx - ttlx);
            double dx2 = Math.Abs(mpx - tbrx);
            double dx3 = Math.Abs(mpx - tbrx + maxX);
            if (dx1 > dx2 && dx1 > dx3)
            {
                mpx += maxX;
            }
        }

        double px = mpx / sx;
        double pz = (ttly - my) / (ttly - tbry);

        _relativePosition = new Vector3((float)px, 0, (float)pz);

        OnlineMapsTileSetControl tsControl = control as OnlineMapsTileSetControl;

        if (tsControl != null)
        {
            px = -tsControl.sizeInScene.x / 2 - (px - 0.5) * tsControl.sizeInScene.x;
            pz = tsControl.sizeInScene.y / 2 + (pz - 0.5) * tsControl.sizeInScene.y;
        }
        else
        {
            Vector3 center = bounds.center;
            Vector3 size   = bounds.size;
            px = center.x - (px - 0.5) * size.x / map.transform.lossyScale.x - map.transform.position.x;
            pz = center.z + (pz - 0.5) * size.z / map.transform.lossyScale.z - map.transform.position.z;
        }

        Vector3 oldPosition = instance.transform.localPosition;
        float   y           = 0;

        if (altitude.HasValue)
        {
            float yScale = OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry);
            y = altitude.Value;
            if (altitudeType == OnlineMapsAltitudeType.relative && tsControl != null)
            {
                y += OnlineMapsElevationManagerBase.GetUnscaledElevation(px, pz, tlx, tly, brx, bry);
            }
            y *= yScale;

            if (tsControl != null)
            {
                if (OnlineMapsElevationManagerBase.instance.bottomMode == OnlineMapsElevationBottomMode.minValue)
                {
                    y -= OnlineMapsElevationManagerBase.instance.minValue * bestYScale;
                }
                y *= OnlineMapsElevationManagerBase.instance.scale;
            }
        }
        else if (tsControl != null)
        {
            y = OnlineMapsElevationManagerBase.GetElevation(px, pz, bestYScale, tlx, tly, brx, bry);
        }

        Vector3 newPosition = new Vector3((float)px, y, (float)pz);

        if (sizeType == SizeType.meters)
        {
            double dx, dy;
            OnlineMapsUtils.DistanceBetweenPoints(tlx, tly, brx, bry, out dx, out dy);
            dx = tsControl.sizeInScene.x / dx / 1000;
            dy = tsControl.sizeInScene.y / dy / 1000;

            double d  = (dx + dy) / 2 * scale;
            float  fd = (float)d;

            instance.transform.localScale = new Vector3(fd, fd, fd);
        }

        if (oldPosition != newPosition)
        {
            instance.transform.localPosition = newPosition;
        }
    }
    private void OnDrawMarkers()
    {
        if (markersGameObjects == null)
        {
            InitMarkersMesh(0);
        }

        double tlx, tly, brx, bry;

        map.GetCorners(out tlx, out tly, out brx, out bry);
        if (brx < tlx)
        {
            brx += 360;
        }

        int zoom = map.buffer.renderState.zoom;
        int maxX = 1 << zoom;

        double tx, ty;

        map.projection.CoordinatesToTile(tlx, tly, zoom, out tx, out ty);

        float yScale = OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry);

        OnlineMapsControlBaseDynamicMesh tileset = control as OnlineMapsControlBaseDynamicMesh;

        float cx = -tileset.sizeInScene.x / map.buffer.renderState.width;
        float cy = tileset.sizeInScene.y / map.buffer.renderState.height;

        if (usedMarkers == null)
        {
            usedMarkers = new List <FlatMarker>(32);
        }
        else
        {
            for (int i = 0; i < usedMarkers.Count; i++)
            {
                usedMarkers[i].Dispose();
            }
            usedMarkers.Clear();
        }

        List <Texture> usedTextures = new List <Texture>(32)
        {
            OnlineMapsMarkerManager.instance.defaultTexture
        };
        List <List <int> > usedTexturesMarkerIndex = new List <List <int> >(32)
        {
            new List <int>(32)
        };

        int usedMarkersCount = 0;

        Bounds tilesetBounds = new Bounds(
            new Vector3(tileset.sizeInScene.x / -2, 0, tileset.sizeInScene.y / 2),
            new Vector3(tileset.sizeInScene.x, 0, tileset.sizeInScene.y));

        IEnumerable <OnlineMapsMarker> markers = OnlineMapsMarkerManager.instance.Where(delegate(OnlineMapsMarker marker)
        {
            if (!marker.enabled || !marker.range.InRange(zoom))
            {
                return(false);
            }

            if (OnCheckMarker2DVisibility != null)
            {
                if (!OnCheckMarker2DVisibility(marker))
                {
                    return(false);
                }
            }
            else if (control.checkMarker2DVisibility == OnlineMapsTilesetCheckMarker2DVisibility.pivot)
            {
                double mx, my;
                marker.GetPosition(out mx, out my);

                bool a = my > tly ||
                         my < bry ||
                         (
                    (mx <tlx || mx> brx) &&
                    (mx + 360 < tlx || mx + 360 > brx) &&
                    (mx - 360 < tlx || mx - 360 > brx)
                         );
                if (a)
                {
                    return(false);
                }
            }

            return(true);
        });

        float[] offsets    = null;
        bool    useOffsetY = false;

        int index = 0;

        if (markerComparer != null)
        {
            markers = markers.OrderBy(m => m, markerComparer);
        }
        else
        {
            markers = markers.OrderBy(m =>
            {
                double mx, my;
                m.GetPosition(out mx, out my);
                return(90 - my);
            });
            useOffsetY = OnGetFlatMarkerOffsetY != null;

            if (useOffsetY)
            {
                int countMarkers = markers.Count();

                SortedMarker[] sortedMarkers = new SortedMarker[countMarkers];
                foreach (OnlineMapsMarker marker in markers)
                {
                    sortedMarkers[index++] = new SortedMarker
                    {
                        marker = marker,
                        offset = OnGetFlatMarkerOffsetY(marker)
                    };
                }

                offsets = new float[countMarkers];
                OnlineMapsMarker[] nMarkers = new OnlineMapsMarker[countMarkers];
                int i = 0;
                foreach (SortedMarker sm in sortedMarkers.OrderBy(m => m.offset))
                {
                    nMarkers[i] = sm.marker;
                    offsets[i]  = sm.offset;
                    i++;
                    sm.Dispose();
                }
                markers = nMarkers;
            }
        }

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

        Vector3 tpos = control.transform.position;

        foreach (Mesh mesh in markersMeshes)
        {
            mesh.Clear();
        }

        float zoomCoof = map.buffer.renderState.zoomCoof;

        Matrix4x4 matrix    = new Matrix4x4();
        int       meshIndex = 0;

        index = -1;
        foreach (OnlineMapsMarker marker in markers)
        {
            index++;
            double fx, fy;
            marker.GetTilePosition(out fx, out fy);

            Vector2 offset = marker.GetAlignOffset();
            offset *= marker.scale;

            fx = (fx - tx) / zoomCoof;

            if (fx < 0)
            {
                fx += maxX;
            }
            else if (fx > maxX)
            {
                fx -= maxX;
            }

            fx = fx * OnlineMapsUtils.tileSize - offset.x;
            fy = (fy - ty) / zoomCoof * OnlineMapsUtils.tileSize - offset.y;

            if (marker.texture == null)
            {
                marker.texture = OnlineMapsMarkerManager.instance.defaultTexture;
                marker.Init();
            }

            float markerWidth  = marker.texture.width * marker.scale;
            float markerHeight = marker.texture.height * marker.scale;

            float rx1 = (float)(fx * cx);
            float ry1 = (float)(fy * cy);
            float rx2 = (float)((fx + markerWidth) * cx);
            float ry2 = (float)((fy + markerHeight) * cy);

            Vector3 center = new Vector3((float)((fx + offset.x) * cx), 0, (float)((fy + offset.y) * cy));

            Vector3 p1 = new Vector3(rx1 - center.x, 0, ry1 - center.z);
            Vector3 p2 = new Vector3(rx2 - center.x, 0, ry1 - center.z);
            Vector3 p3 = new Vector3(rx2 - center.x, 0, ry2 - center.z);
            Vector3 p4 = new Vector3(rx1 - center.x, 0, ry2 - center.z);

            float angle = Mathf.Repeat(marker.rotation, 1) * 360;

            if (Math.Abs(angle) > float.Epsilon)
            {
                matrix.SetTRS(Vector3.zero, Quaternion.Euler(0, angle, 0), Vector3.one);

                p1 = matrix.MultiplyPoint(p1) + center;
                p2 = matrix.MultiplyPoint(p2) + center;
                p3 = matrix.MultiplyPoint(p3) + center;
                p4 = matrix.MultiplyPoint(p4) + center;
            }
            else
            {
                p1 += center;
                p2 += center;
                p3 += center;
                p4 += center;
            }

            if (control.checkMarker2DVisibility == OnlineMapsTilesetCheckMarker2DVisibility.bounds)
            {
                Vector3 markerCenter = (p2 + p4) / 2;
                Vector3 markerSize   = p4 - p2;
                if (!tilesetBounds.Intersects(new Bounds(markerCenter, markerSize)))
                {
                    continue;
                }
            }

            float y       = OnlineMapsElevationManagerBase.GetElevation((rx1 + rx2) / 2, (ry1 + ry2) / 2, yScale, tlx, tly, brx, bry);
            float yOffset = useOffsetY ? offsets[index] : 0;

            p1.y = p2.y = p3.y = p4.y = y + yOffset;

            int vIndex = markersVertices.Count;

            markersVertices.Add(p1);
            markersVertices.Add(p2);
            markersVertices.Add(p3);
            markersVertices.Add(p4);

            usedMarkers.Add(new FlatMarker(marker, p1 + tpos, p2 + tpos, p3 + tpos, p4 + tpos));

            if (OnGenerateMarkerVertices != null)
            {
                OnGenerateMarkerVertices(marker, markersVertices, vIndex);
            }

            if (marker.texture == OnlineMapsMarkerManager.instance.defaultTexture)
            {
                usedTexturesMarkerIndex[0].Add(usedMarkersCount);
            }
            else
            {
                int textureIndex = usedTextures.IndexOf(marker.texture);
                if (textureIndex != -1)
                {
                    usedTexturesMarkerIndex[textureIndex].Add(usedMarkersCount);
                }
                else
                {
                    usedTextures.Add(marker.texture);
                    usedTexturesMarkerIndex.Add(new List <int>(32));
                    usedTexturesMarkerIndex[usedTexturesMarkerIndex.Count - 1].Add(usedMarkersCount);
                }
            }

            usedMarkersCount++;

            if (usedMarkersCount == 16250)
            {
                SetMarkersMesh(usedMarkersCount, usedTextures, usedTexturesMarkerIndex, meshIndex);
                meshIndex++;
                markersVertices.Clear();
                usedMarkersCount = 0;
                usedTextures.Clear();
                usedTextures.Add(OnlineMapsMarkerManager.instance.defaultTexture);
                usedTexturesMarkerIndex.Clear();
                usedTexturesMarkerIndex.Add(new List <int>(32));
            }
        }

        SetMarkersMesh(usedMarkersCount, usedTextures, usedTexturesMarkerIndex, meshIndex);
    }
    protected void InitLineMesh(IEnumerable points, OnlineMapsTileSetControl control, ref List <Vector3> vertices, ref List <Vector3> normals, ref List <int> triangles, ref List <Vector2> uv, float width, bool closed = false, bool optimize = true)
    {
        map.buffer.GetCorners(out tlx, out tly, out brx, out bry);
        if (brx < tlx)
        {
            brx += 360;
        }

        float zoomCoof = map.zoomCoof;

        List <Vector2> localPoints  = GetLocalPoints(points, closed, optimize);
        List <Vector2> activePoints = new List <Vector2>(localPoints.Count);

        int   maxX     = 1 << map.zoom;
        float maxSize  = maxX * OnlineMapsUtils.tileSize * control.sizeInScene.x / map.width;
        float halfSize = maxSize / 2;

        float lastPointX = 0;
        float lastPointY = 0;

        float sizeX = control.sizeInScene.x / zoomCoof;
        float sizeY = control.sizeInScene.y / zoomCoof;

        bestElevationYScale = OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry);

        if (vertices == null)
        {
            vertices = new List <Vector3>(Mathf.Max(Mathf.NextPowerOfTwo(localPoints.Count * 4), 32));
        }
        else
        {
            vertices.Clear();
        }

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

        if (triangles == null)
        {
            triangles = new List <int>(Mathf.Max(Mathf.NextPowerOfTwo(localPoints.Count * 6), 32));
        }
        else
        {
            triangles.Clear();
        }

        if (uv == null)
        {
            uv = new List <Vector2>(vertices.Capacity);
        }
        else
        {
            uv.Clear();
        }

        Vector2[] intersections = new Vector2[4];
        bool      needExtraPoint = false;
        float     extraX = 0, extraY = 0;

        for (int i = 0; i < localPoints.Count; i++)
        {
            Vector2 p  = localPoints[i];
            float   px = p.x;
            float   py = p.y;

            if (needExtraPoint)
            {
                activePoints.Add(new Vector2(extraX, extraY));

                float ox = extraX - lastPointX;
                if (ox > halfSize)
                {
                    lastPointX += maxSize;
                }
                else if (ox < -halfSize)
                {
                    lastPointX -= maxSize;
                }

                activePoints.Add(new Vector2(lastPointX, lastPointY));

                needExtraPoint = false;
            }

            if (i > 0 && checkMapBoundaries)
            {
                int countIntersections = 0;

                float ox = px - lastPointX;
                while (Math.Abs(ox) > halfSize)
                {
                    if (ox < 0)
                    {
                        px += maxSize;
                        ox += maxSize;
                    }
                    else if (ox > 0)
                    {
                        px -= maxSize;
                        ox -= maxSize;
                    }
                }

                float crossTopX, crossTopY, crossLeftX, crossLeftY, crossBottomX, crossBottomY, crossRightX, crossRightY;

                bool hasCrossTop    = OnlineMapsUtils.LineIntersection(lastPointX, lastPointY, px, py, 0, 0, sizeX, 0, out crossTopX, out crossTopY);
                bool hasCrossBottom = OnlineMapsUtils.LineIntersection(lastPointX, lastPointY, px, py, 0, sizeY, sizeX, sizeY, out crossBottomX, out crossBottomY);
                bool hasCrossLeft   = OnlineMapsUtils.LineIntersection(lastPointX, lastPointY, px, py, 0, 0, 0, sizeY, out crossLeftX, out crossLeftY);
                bool hasCrossRight  = OnlineMapsUtils.LineIntersection(lastPointX, lastPointY, px, py, sizeX, 0, sizeX, sizeY, out crossRightX, out crossRightY);

                if (hasCrossTop)
                {
                    intersections[0] = new Vector2(crossTopX, crossTopY);
                    countIntersections++;
                }
                if (hasCrossBottom)
                {
                    intersections[countIntersections] = new Vector2(crossBottomX, crossBottomY);
                    countIntersections++;
                }
                if (hasCrossLeft)
                {
                    intersections[countIntersections] = new Vector2(crossLeftX, crossLeftY);
                    countIntersections++;
                }
                if (hasCrossRight)
                {
                    intersections[countIntersections] = new Vector2(crossRightX, crossRightY);
                    countIntersections++;
                }

                if (countIntersections == 1)
                {
                    activePoints.Add(intersections[0]);
                }
                else if (countIntersections == 2)
                {
                    Vector2 lastPoint = new Vector2(lastPointX, lastPointY);
                    int     minIndex  = (lastPoint - intersections[0]).sqrMagnitude < (lastPoint - intersections[1]).sqrMagnitude? 0: 1;
                    activePoints.Add(intersections[minIndex]);
                    activePoints.Add(intersections[1 - minIndex]);
                }

                if (hasCrossLeft)
                {
                    needExtraPoint = OnlineMapsUtils.LineIntersection(lastPointX + maxSize, lastPointY, px + maxSize, py, sizeX, 0, sizeX, sizeY, out extraX, out extraY);
                }
                else if (hasCrossRight)
                {
                    needExtraPoint = OnlineMapsUtils.LineIntersection(lastPointX - maxSize, lastPointY, px - maxSize, py, 0, 0, 0, sizeY, out extraX, out extraY);
                }
            }

            if (!checkMapBoundaries || px >= 0 && py >= 0 && px <= sizeX && py <= sizeY)
            {
                activePoints.Add(new Vector2(px, py));
            }
            else if (activePoints.Count > 0)
            {
                DrawActivePoints(control, ref activePoints, ref vertices, ref normals, ref triangles, ref uv, width);
            }

            lastPointX = px;
            lastPointY = py;
        }

        if (needExtraPoint)
        {
            activePoints.Add(new Vector2(extraX, extraY));

            float ox = extraX - lastPointX;
            if (ox > halfSize)
            {
                lastPointX += maxSize;
            }
            else if (ox < -halfSize)
            {
                lastPointX -= maxSize;
            }

            activePoints.Add(new Vector2(lastPointX, lastPointY));
        }
        if (activePoints.Count > 0)
        {
            DrawActivePoints(control, ref activePoints, ref vertices, ref normals, ref triangles, ref uv, width);
        }
    }
    public override void DrawOnTileset(OnlineMapsTileSetControl control, int index)
    {
        if (points == null)
        {
            return;
        }

        base.DrawOnTileset(control, index);

        if (!visible)
        {
            active = false;
            return;
        }

        if (range != null && !range.InRange(control.map.floatZoom))
        {
            active = false;
            return;
        }

        InitMesh(control, borderColor, backgroundColor);
        InitLineMesh(points, control, ref vertices, ref normals, ref triangles, ref uv, borderWidth, true, false);

        mesh.Clear();

        if (vertices.Count < 4)
        {
            return;
        }

        active = true;

        Vector3 v1 = (vertices[0] + vertices[3]) / 2;
        Vector3 v2 = (vertices[vertices.Count - 3] + vertices[vertices.Count - 2]) / 2;

        if ((v1.x - v2.x) * (v1.x - v2.x) + (v1.z - v2.z) * (v1.z - v2.z) < float.Epsilon)
        {
            int     s1, s2;
            Vector3 v0 = vertices[0];
            v1 = vertices[1];
            v2 = vertices[2];
            Vector3 v3 = vertices[3];
            Vector3 vs1 = vertices[vertices.Count - 1];
            Vector3 vs2 = vertices[vertices.Count - 2];
            Vector3 vs3 = vertices[vertices.Count - 3];
            Vector3 vs4 = vertices[vertices.Count - 4];
            Vector3 nv1 = Vector3.zero, nv2 = Vector3.zero;
            s1 = OnlineMapsUtils.GetIntersectionPointOfTwoLines(v0.x, v0.z, v1.x, v1.z, vs4.x, vs4.z, vs3.x, vs3.z, out nv1.x, out nv1.z);
            s2 = OnlineMapsUtils.GetIntersectionPointOfTwoLines(v3.x, v3.z, v2.x, v2.z, vs1.x, vs1.z, vs2.x, vs2.z, out nv2.x, out nv2.z);

            if (s1 == 1 && s2 == 1)
            {
                nv1.y       = OnlineMapsElevationManagerBase.GetElevation(nv1.x, nv1.z, bestElevationYScale, tlx, tly, brx, bry);
                nv2.y       = OnlineMapsElevationManagerBase.GetElevation(nv2.x, nv2.z, bestElevationYScale, tlx, tly, brx, bry);
                vertices[0] = vertices[vertices.Count - 3] = nv1;
                vertices[3] = vertices[vertices.Count - 2] = nv2;
            }
            else
            {
                vertices[0] = vertices[vertices.Count - 3] = (vertices[0] + vertices[vertices.Count - 3]) / 2;
                vertices[3] = vertices[vertices.Count - 2] = (vertices[3] + vertices[vertices.Count - 2]) / 2;
            }
        }

        int[] fillTriangles = null;

        if (!checkMapBoundaries && backgroundColor.a > 0 && vertices.Count > 0)
        {
            float l1 = 0;
            float l2 = 0;

            for (int i = 0; i < vertices.Count / 4 - 1; i++)
            {
                Vector3 p11 = vertices[i * 4];
                Vector3 p12 = vertices[(i + 1) * 4];

                Vector3 p21 = vertices[i * 4 + 3];
                Vector3 p22 = vertices[(i + 1) * 4 + 3];

                l1 += (p11 - p12).magnitude;
                l2 += (p21 - p22).magnitude;
            }

            bool side = l2 < l1;
            int  off1 = side ? 3 : 0;
            int  off2 = side ? 2 : 1;

            Vector2        lastPoint       = Vector2.zero;
            List <int>     internalIndices = new List <int>(vertices.Count / 4);
            List <Vector2> internalPoints  = new List <Vector2>(vertices.Count / 4);
            float          w = borderWidth / 2;
            w *= w;
            for (int i = 0, j = 0; i < vertices.Count / 4; i++, j += 4)
            {
                Vector3 p  = vertices[j + off1];
                Vector2 p2 = new Vector2(p.x, p.z);
                if (i > 0)
                {
                    if ((lastPoint - p2).sqrMagnitude > w)
                    {
                        internalIndices.Add(j + off1);
                        internalPoints.Add(p2);
                        lastPoint = p2;
                    }
                }
                else
                {
                    internalIndices.Add(j + off1);
                    internalPoints.Add(p2);
                    lastPoint = p2;
                }
                p  = vertices[j + off2];
                p2 = new Vector2(p.x, p.z);
                if ((lastPoint - p2).sqrMagnitude > w)
                {
                    internalIndices.Add(j + off2);
                    internalPoints.Add(p2);
                    lastPoint = p2;
                }
            }

            if (internalPoints[0] == internalPoints[internalPoints.Count - 1])
            {
                internalPoints.RemoveAt(internalPoints.Count - 1);
            }

            fillTriangles = OnlineMapsUtils.Triangulate(internalPoints).ToArray();
            //fillTriangles = OMTriangulator.Triangulate(internalPoints);


            if (fillTriangles.Length > 2)
            {
                for (int i = 0; i < fillTriangles.Length; i++)
                {
                    fillTriangles[i] = internalIndices[fillTriangles[i]];
                }

                Vector3 side1 = vertices[fillTriangles[1]] - vertices[fillTriangles[0]];
                Vector3 side2 = vertices[fillTriangles[2]] - vertices[fillTriangles[0]];
                Vector3 perp  = Vector3.Cross(side1, side2);

                bool reversed = perp.y < 0;
                if (reversed)
                {
                    fillTriangles = fillTriangles.Reverse().ToArray();
                }
            }
            else
            {
                fillTriangles = null;
            }
        }

        mesh.subMeshCount = 2;

        mesh.SetVertices(vertices);
        mesh.SetNormals(normals);
        mesh.SetUVs(0, uv);

        mesh.SetTriangles(triangles.ToArray(), 0);
        if (fillTriangles != null)
        {
            mesh.SetTriangles(fillTriangles.ToArray(), 1);
        }

        UpdateMaterialsQuote(control, index);
    }
    private void OnDrawMarkers()
    {
        if (markersGameObjects == null)
        {
            InitMarkersMesh(0);
        }
        if (markerBillboards == null)
        {
            markerBillboards = new Dictionary <int, OnlineMapsMarkerBillboard>();
        }

        double tlx, tly, brx, bry;

        map.GetCorners(out tlx, out tly, out brx, out bry);
        if (brx < tlx)
        {
            brx += 360;
        }

        int maxX = 1 << map.buffer.renderState.zoom;

        double px, py;

        map.projection.CoordinatesToTile(tlx, tly, map.zoom, out px, out py);

        float yScale = OnlineMapsElevationManagerBase.GetBestElevationYScale(tlx, tly, brx, bry);

        Bounds  mapBounds      = control.cl.bounds;
        Vector3 positionOffset = control.transform.position - mapBounds.min;
        Vector3 size           = mapBounds.size;

        size = control.transform.rotation * size;
        if (!control.resultIsTexture)
        {
            positionOffset.x -= size.x;
        }

        float zoomCoof = map.buffer.renderState.zoomCoof;

        foreach (KeyValuePair <int, OnlineMapsMarkerBillboard> billboard in markerBillboards)
        {
            billboard.Value.used = false;
        }

        foreach (OnlineMapsMarker marker in OnlineMapsMarkerManager.instance)
        {
            if (!marker.enabled || !marker.range.InRange(map.zoom))
            {
                continue;
            }

            double mx, my;
            marker.GetPosition(out mx, out my);

            if (!((mx > tlx && mx < brx || mx + 360 > tlx && mx + 360 < brx ||
                   mx - 360 > tlx && mx - 360 < brx) &&
                  my < tly && my > bry))
            {
                continue;
            }

            int markerHashCode = marker.GetHashCode();
            OnlineMapsMarkerBillboard markerBillboard;

            if (!markerBillboards.ContainsKey(markerHashCode))
            {
                markerBillboard = OnlineMapsMarkerBillboard.Create(marker);
                markerBillboard.transform.parent = markersGameObjects[0].transform;
                markerBillboard.gameObject.layer = markersGameObjects[0].layer;

                markerBillboards.Add(markerHashCode, markerBillboard);
            }
            else
            {
                markerBillboard = markerBillboards[markerHashCode];
            }

            if (markerBillboard == null)
            {
                continue;
            }

            float sx = size.x / map.buffer.renderState.width * marker2DSize * marker.scale;
            float sz = size.z / map.buffer.renderState.height * marker2DSize * marker.scale;
            float s  = Mathf.Max(sx, sz);

#if UNITY_5_2
            markerBillboard.transform.localScale = new Vector3(-s, s, s);
#else
            markerBillboard.transform.localScale = new Vector3(s, s, s);
#endif

            double mpx, mpy;
            map.projection.CoordinatesToTile(mx, my, map.buffer.renderState.zoom, out mpx, out mpy);

            mpx  = OnlineMapsUtils.Repeat(mpx - px, 0, maxX);
            mpy -= py;

            float x = (float)(-mpx / map.width * OnlineMapsUtils.tileSize * size.x / zoomCoof + positionOffset.x);
            float z = (float)(mpy / map.height * OnlineMapsUtils.tileSize * size.z / zoomCoof - positionOffset.z);

            float y = OnlineMapsElevationManagerBase.instance != null?OnlineMapsElevationManagerBase.GetElevation(x, z, yScale, tlx, tly, brx, bry) : 0;

            markerBillboard.transform.localPosition = control.transform.rotation * new Vector3(x, y, z);
            markerBillboard.used = true;
        }

        List <int> keysForRemove = new List <int>();

        foreach (KeyValuePair <int, OnlineMapsMarkerBillboard> billboard in markerBillboards)
        {
            if (!billboard.Value.used)
            {
                billboard.Value.Dispose();
                keysForRemove.Add(billboard.Key);
            }
        }

        foreach (int key in keysForRemove)
        {
            markerBillboards.Remove(key);
        }
    }
Example #26
0
    private void UpdateMapSubMesh(int x, int y, int w, int h, double subMeshSizeX, double subMeshSizeY, int subMeshVX, int subMeshVZ, double startPosX, double startPosZ, float yScale, double tlx, double tly, double brx, double bry, Material[] materials, ref float minY, ref float maxY, bool hasTraffic, bool hasOverlayBack, bool hasOverlayBackAlpha, bool hasOverlayFront, bool hasOverlayFrontAlpha)
    {
        int mi = x + y * w;
        int i  = mi * (subMeshVX + 1) * (subMeshVZ + 1);

        double cellSizeX = subMeshSizeX / subMeshVX;
        double cellSizeY = subMeshSizeY / subMeshVZ;

        double uvX = 1.0 / subMeshVX;
        double uvZ = 1.0 / subMeshVZ;

        int bx = x + bufferPosition.x;
        int by = y + bufferPosition.y;

        int zoom = map.buffer.renderState.zoom;
        int maxX = 1 << zoom;

        if (bx >= maxX)
        {
            bx -= maxX;
        }
        if (bx < 0)
        {
            bx += maxX;
        }

        OnlineMapsTile tile;

        map.tileManager.GetTile(zoom, bx, by, out tile);

        OnlineMapsTile currentTile = tile;

        if (currentTile != null && currentTile.status != OnlineMapsTileStatus.loaded)
        {
            currentTile = null;
        }
        Vector2 offset = Vector2.zero;
        float   scale  = 1;
        int     z      = zoom;

        Texture tileTexture = currentTile != null ? currentTile.texture : null;
        bool    sendEvent   = true;

        while ((currentTile == null || tileTexture == null) && z > 2)
        {
            z--;

            int            s   = 1 << (zoom - z);
            int            ctx = bx / s;
            int            cty = by / s;
            OnlineMapsTile t;
            map.tileManager.GetTile(z, ctx, cty, out t);
            if (t != null && t.status == OnlineMapsTileStatus.loaded)
            {
                currentTile = t;
                tileTexture = t.texture;
                scale       = 1f / s;
                offset.x    = bx % s * scale;
                offset.y    = (s - by % s - 1) * scale;
                sendEvent   = false;
                break;
            }
        }

        bool needGetElevation = OnlineMapsElevationManagerBase.useElevation;

        float  fy        = 0;
        double spx       = startPosX - x * subMeshSizeX;
        double spz       = startPosZ + y * subMeshSizeY;
        float  tilesizeX = sizeInScene.x;
        float  tilesizeZ = sizeInScene.y;

        for (int ty = 0; ty <= subMeshVZ; ty++)
        {
            double uvy = 1 - uvZ * ty;
            double pz  = spz + ty * cellSizeY;

            if (pz < 0)
            {
                uvy = uvZ * ((pz + cellSizeY) / cellSizeY - 1) + uvy;
                pz  = 0;
            }
            else if (pz > tilesizeZ)
            {
                uvy = uvZ * ((pz - tilesizeZ) / cellSizeY) + uvy;
                pz  = tilesizeZ;
            }

            for (int tx = 0; tx <= subMeshVX; tx++)
            {
                double uvx = uvX * tx;
                double px  = spx - tx * cellSizeX;

                if (px > 0)
                {
                    uvx = uvX * (px - cellSizeX) / cellSizeX + uvx + uvX;
                    px  = 0;
                }
                else if (px < -tilesizeX)
                {
                    uvx = uvX * ((px + tilesizeX) / cellSizeX - 1) + uvx + uvX;
                    px  = -tilesizeX;
                }

                if (needGetElevation)
                {
                    fy = OnlineMapsElevationManagerBase.GetElevation(px, pz, yScale, tlx, tly, brx, bry);
                }

                float fx = (float)px;
                float fz = (float)pz;

                float f*x = (float)uvx;
                float fuy = (float)uvy;

                if (fy < minY)
                {
                    minY = fy;
                }
                if (fy > maxY)
                {
                    maxY = fy;
                }

                if (f*x < 0)
                {
                    f*x = 0;
                }
                else if (f*x > 1)
                {
                    f*x = 1;
                }

                if (fuy < 0)
                {
                    fuy = 0;
                }
                else if (fuy > 1)
                {
                    fuy = 1;
                }

                vertices[i] = new Vector3(fx, fy, fz);
                uv[i++]     = new Vector2(f*x, fuy);
            }
        }

        Material material = materials[mi];

        material.hideFlags = HideFlags.HideInInspector;

        if (currentTile != null)
        {
            bool hasTileTexture = tileTexture != null;
            if (!hasTileTexture)
            {
                if (map.defaultTileTexture != null)
                {
                    tileTexture = map.defaultTileTexture;
                }
                else if (OnlineMapsRasterTile.emptyColorTexture != null)
                {
                    tileTexture = OnlineMapsRasterTile.emptyColorTexture;
                }
                else
                {
                    tileTexture      = OnlineMapsRasterTile.emptyColorTexture = new Texture2D(1, 1, TextureFormat.ARGB32, mipmapForTiles);
                    tileTexture.name = "Empty Texture";
                    OnlineMapsRasterTile.emptyColorTexture.SetPixel(0, 0, map.emptyColor);
                    OnlineMapsRasterTile.emptyColorTexture.Apply(false);
                }

                sendEvent = false;
            }

            material.mainTextureOffset = offset;
            material.mainTextureScale  = new Vector2(scale, scale);

            if (material.mainTexture != tileTexture)
            {
                material.mainTexture = tileTexture;
                if (sendEvent && OnChangeMaterialTexture != null)
                {
                    OnChangeMaterialTexture(currentTile, material);
                }
            }

            if (hasTraffic)
            {
                material.SetTexture("_TrafficTex", (currentTile as OnlineMapsRasterTile).trafficTexture);
                material.SetTextureOffset("_TrafficTex", material.mainTextureOffset);
                material.SetTextureScale("_TrafficTex", material.mainTextureScale);
            }
            if (hasOverlayBack)
            {
                material.SetTexture("_OverlayBackTex", currentTile.overlayBackTexture);
                material.SetTextureOffset("_OverlayBackTex", material.mainTextureOffset);
                material.SetTextureScale("_OverlayBackTex", material.mainTextureScale);
            }
            if (hasOverlayBackAlpha)
            {
                material.SetFloat("_OverlayBackAlpha", currentTile.overlayBackAlpha);
            }
            if (hasOverlayFront)
            {
                if (drawingMode == OnlineMapsTilesetDrawingMode.overlay)
                {
                    if (currentTile.status == OnlineMapsTileStatus.loaded && (currentTile.drawingChanged || currentTile.overlayFrontTexture == null))
                    {
                        if (overlayFrontBuffer == null)
                        {
                            overlayFrontBuffer = new Color32[OnlineMapsUtils.sqrTileSize];
                        }
                        else
                        {
                            for (int k = 0; k < OnlineMapsUtils.sqrTileSize; k++)
                            {
                                overlayFrontBuffer[k] = new Color32();
                            }
                        }
                        foreach (OnlineMapsDrawingElement drawingElement in drawingElementManager)
                        {
                            drawingElement.Draw(overlayFrontBuffer, new OnlineMapsVector2i(currentTile.x, currentTile.y), OnlineMapsUtils.tileSize, OnlineMapsUtils.tileSize, currentTile.zoom, true);
                        }
                        if (currentTile.overlayFrontTexture == null)
                        {
                            currentTile.overlayFrontTexture          = new Texture2D(OnlineMapsUtils.tileSize, OnlineMapsUtils.tileSize, TextureFormat.ARGB32, mipmapForTiles);
                            currentTile.overlayFrontTexture.wrapMode = TextureWrapMode.Clamp;
                        }
                        currentTile.overlayFrontTexture.SetPixels32(overlayFrontBuffer);
                        currentTile.overlayFrontTexture.Apply(false);
                    }
                }

                material.SetTexture("_OverlayFrontTex", currentTile.overlayFrontTexture);
                material.SetTextureOffset("_OverlayFrontTex", material.mainTextureOffset);
                material.SetTextureScale("_OverlayFrontTex", material.mainTextureScale);
            }
            if (hasOverlayFrontAlpha)
            {
                material.SetFloat("_OverlayFrontAlpha", currentTile.overlayFrontAlpha);
            }
            if (OnDrawTile != null)
            {
                OnDrawTile(currentTile, material);
            }
        }
        else
        {
            if (map.defaultTileTexture != null)
            {
                material.mainTexture = map.defaultTileTexture;
            }
            else
            {
                if (OnlineMapsRasterTile.emptyColorTexture == null)
                {
                    OnlineMapsRasterTile.emptyColorTexture      = new Texture2D(1, 1, TextureFormat.ARGB32, mipmapForTiles);
                    OnlineMapsRasterTile.emptyColorTexture.name = "Empty Texture";
                    OnlineMapsRasterTile.emptyColorTexture.SetPixel(0, 0, map.emptyColor);
                    OnlineMapsRasterTile.emptyColorTexture.Apply(false);
                }

                material.mainTexture = OnlineMapsRasterTile.emptyColorTexture;
            }

            if (hasTraffic)
            {
                material.SetTexture("_TrafficTex", null);
            }
            if (hasOverlayBack)
            {
                material.SetTexture("_OverlayBackTex", null);
            }
            if (hasOverlayFront)
            {
                material.SetTexture("_OverlayFrontTex", null);
            }
        }
    }