private void UnloadOldTiles() { needUnloadTiles = false; #if !UNITY_WEBGL int count = 100; while (api.renderInThread && !allowUnloadTiles && count > 0) { #if !NETFX_CORE Thread.Sleep(1); #else OnlineMapsThreadWINRT.Sleep(1); #endif count--; } if (count == 0) { return; } #endif lock (OnlineMapsTile.tiles) { foreach (OnlineMapsTile tile in OnlineMapsTile.tiles) { if (!tile.used) { tile.Dispose(); } } } }
private void StartNextAction() { #if !UNITY_WEBGL while (isAlive) { bool actionInvoked = false; lock (threadActions) { if (threadActions.Count > 0) { Action action = threadActions[0]; threadActions.RemoveAt(0); action(); actionInvoked = true; } } if (!actionInvoked) { #if !NETFX_CORE Thread.Sleep(1); #else OnlineMapsThreadWINRT.Sleep(1); #endif } } threadActions = null; #endif }
private void ApplyNewTiles() { if (newTiles == null || newTiles.Count == 0) { return; } lock (newTiles) { foreach (OnlineMapsTile tile in newTiles) { if (disposed) { return; } if (tile.status == OnlineMapsTileStatus.disposed) { continue; } #if !UNITY_WEBGL int counter = 20; while (tile.colors.Length < OnlineMapsUtils.sqrTileSize && counter > 0) { #if !NETFX_CORE Thread.Sleep(1); #else OnlineMapsThreadWINRT.Sleep(1); #endif counter--; } #endif tile.ApplyColorsToChilds(); } if (newTiles.Count > 0) { newTiles.Clear(); } } }
private void UpdateRotatedBuffer() { _lastRotation = _rotation; _lastScale = _scale; if ((_rotation == 0 && scale == 1) || map.target == OnlineMapsTarget.tileset) { _width = _textureWidth; _height = _textureHeight; return; } #if !UNITY_WEBGL int maxLocked = 20; while (locked && maxLocked > 0) { #if !NETFX_CORE Thread.Sleep(1); #else OnlineMapsThreadWINRT.Sleep(1); #endif maxLocked--; } #endif locked = true; float angle = Mathf.Repeat(_rotation * 360, 360); Matrix4x4 matrix = new Matrix4x4(); matrix.SetTRS(Vector3.zero, Quaternion.Euler(0, angle, 0), new Vector3(scale, scale, scale)); Matrix4x4 inv = matrix.inverse; Vector3 p1 = matrix.MultiplyPoint3x4(new Vector3(_textureWidth, 0, 0)); Vector3 p2 = matrix.MultiplyPoint3x4(new Vector3(0, 0, _textureHeight)); Vector3 p3 = matrix.MultiplyPoint3x4(new Vector3(_textureWidth, 0, _textureHeight)); float minX = Mathf.Min(0, p1.x, p2.x, p3.x); float minZ = Mathf.Min(0, p1.z, p2.z, p3.z); float maxX = Mathf.Max(0, p1.x, p2.x, p3.x); float maxZ = Mathf.Max(0, p1.z, p2.z, p3.z); _width = Mathf.RoundToInt(maxX - minX + 0.5f); _height = Mathf.RoundToInt(maxZ - minZ + 0.5f); Color emptyColor = new Color(0, 0, 0, 0); if (_rotatedColors == null || _rotatedColors.Length != _width * _height) { _rotatedColors = new Color32[_width * _height]; } int tw = _textureWidth; int th = _textureHeight; for (int y = 0; y < _height; y++) { float ry = minZ + y; int cy = y * _width; for (int x = 0; x < _width; x++) { float rx = minX + x; Vector3 p = inv.MultiplyPoint3x4(new Vector3(rx, 0, ry)); int iz = (int)p.z; int ix = (int)p.x; float fx = p.x - ix; float fz = p.z - iz; if (ix + 1 >= 0 && ix < tw && iz + 1 >= 0 && iz < th) { Color[] clrs = { emptyColor, emptyColor, emptyColor, emptyColor }; if (ix >= 0 && iz >= 0) { clrs[0] = _colors[iz * tw + ix]; } if (ix + 1 < tw && iz >= 0) { clrs[1] = _colors[iz * tw + ix + 1]; } if (ix >= 0 && iz + 1 < th) { clrs[2] = _colors[(iz + 1) * tw + ix]; } if (ix + 1 < tw && iz + 1 < th) { clrs[3] = _colors[(iz + 1) * tw + ix + 1]; } clrs[0] = Color.Lerp(clrs[0], clrs[1], fx); clrs[2] = Color.Lerp(clrs[2], clrs[3], fx); _rotatedColors[cy + x] = Color.Lerp(clrs[0], clrs[2], fz); } else { _rotatedColors[cy + x] = emptyColor; } } } locked = false; }
private void SetMarkerToBuffer(OnlineMapsMarker marker, double sx, double sy, double ex, double ey) { const int s = OnlineMapsUtils.tileSize; double mx, my; marker.GetPosition(out mx, out my); if (!(((mx > sx && mx < ex) || (mx + 360 > sx && mx + 360 < ex) || (mx - 360 > sx && mx - 360 < ex)) && my < sy && my > ey)) { return; } #if !UNITY_WEBGL int maxCount = 20; while (marker.locked && maxCount > 0) { #if !NETFX_CORE Thread.Sleep(1); #else OnlineMapsThreadWINRT.Sleep(1); #endif maxCount--; } #endif marker.locked = true; double px, py; api.projection.CoordinatesToTile(mx, my, bufferZoom, out px, out py); px -= bufferPosition.x; py -= bufferPosition.y; int maxX = 1 << bufferZoom; if (px < 0) { px += maxX; } else if (px > maxX) { px -= maxX; } OnlineMapsVector2i ip = marker.GetAlignedPosition((int)(px * s), (int)(py * s)); Color32[] markerColors = marker.colors; if (markerColors == null || markerColors.Length == 0) { return; } int markerWidth = marker.width; int markerHeight = marker.height; for (int y = 0; y < marker.height; y++) { if (disposed) { return; } if (ip.y + y < 0 || ip.y + y >= height) { continue; } int cy = (markerHeight - y - 1) * markerWidth; for (int x = 0; x < marker.width; x++) { if (ip.x + x < 0 || ip.x + x >= width) { continue; } try { SetColorToBuffer(markerColors[cy + x], ip, y, x); } catch { } } } marker.locked = false; }
public void GenerateFrontBuffer() { try { api.GetPosition(out apiLongitude, out apiLatitude); apiZoom = api.zoom; while (!disposed) { #if !UNITY_WEBGL while (status != OnlineMapsBufferStatus.start && api.renderInThread) { if (disposed) { return; } #if NETFX_CORE OnlineMapsThreadWINRT.Sleep(1); #else Thread.Sleep(1); #endif } #endif status = OnlineMapsBufferStatus.working; double px = 0, py = 0; try { api.GetPosition(out px, out py); int zoom = api.zoom; bool fullRedraw = redrawType == OnlineMapsRedrawType.full; if (newTiles != null && api.target == OnlineMapsTarget.texture) { ApplyNewTiles(); } if (disposed) { return; } bool backBufferUpdated = UpdateBackBuffer(px, py, zoom, fullRedraw); if (disposed) { return; } if (api.target == OnlineMapsTarget.texture) { GetFrontBufferPosition(px, py, bufferPosition, zoom, api.width, api.height); if (backBufferUpdated) { for (int i = 0; i < api.drawingElements.Count; i++) { OnlineMapsDrawingElement element = api.drawingElements[i]; if (disposed) { return; } element.Draw(backBuffer, bufferPosition, width, height, zoom); } SetMarkersToBuffer(api.markers); } if (disposed) { return; } if (generateSmartBuffer && api.useSmartTexture) { UpdateSmartBuffer(api.width, api.height); } else { UpdateFrontBuffer(api.width, api.height); } } } catch (Exception exception) { if (disposed) { return; } Debug.Log(exception.Message + "\n" + exception.StackTrace); } status = OnlineMapsBufferStatus.complete; apiLongitude = px; apiLatitude = py; apiZoom = api.zoom; if (needUnloadTiles) { UnloadOldTiles(); } #if !UNITY_WEBGL if (!api.renderInThread) { break; } #else break; #endif } } catch { } }