public void UnloadOldTiles() { needUnloadTiles = false; #if !UNITY_WEBGL int count = 100; while (map.renderInThread && !allowUnloadTiles && count > 0) { OnlineMapsUtils.ThreadSleep(1); count--; } if (count == 0) { return; } #endif lock (OnlineMapsTile.lockTiles) { foreach (OnlineMapsTile tile in OnlineMapsTile.tiles) { if (!tile.used && !tile.isBlocked) { tile.Dispose(); } } } }
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; } OnlineMapsRasterTile rTile = tile as OnlineMapsRasterTile; #if !UNITY_WEBGL int counter = 20; while (rTile.colors.Length < OnlineMapsUtils.sqrTileSize && counter > 0) { OnlineMapsUtils.ThreadSleep(1); counter--; } #endif rTile.ApplyColorsToChilds(); } if (newTiles.Count > 0) { newTiles.Clear(); } } }
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) { OnlineMapsUtils.ThreadSleep(1); } } threadActions = null; #endif }
private void SetMarkerToBuffer(OnlineMapsMarker marker, OnlineMapsVector2i bufferPosition, int bufferZoom, OnlineMapsVector2i frontBufferPosition, double sx, double sy, double ex, double ey) { const int s = OnlineMapsUtils.tileSize; double mx, my; marker.GetPosition(out mx, out my); int maxX = 1 << bufferZoom; bool isEntireWorld = map.buffer.renderState.width == maxX * s; bool isBiggestThatBuffer = map.buffer.renderState.width + 512 == maxX * s; if (isEntireWorld || isBiggestThatBuffer) { } else 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) { OnlineMapsUtils.ThreadSleep(1); maxCount--; } #endif marker.locked = true; double px, py; map.projection.CoordinatesToTile(mx, my, bufferZoom, out px, out py); px -= bufferPosition.x; py -= bufferPosition.y; if (isEntireWorld) { double tx, ty; map.projection.CoordinatesToTile(map.buffer.renderState.longitude, map.buffer.renderState.latitude, bufferZoom, out tx, out ty); tx -= map.buffer.renderState.width / s / 2; if (px < tx) { px += maxX; } } else { if (px < 0) { px += maxX; } else if (px > maxX) { px -= maxX; } } float zoomCoof = map.buffer.renderState.zoomCoof; px *= s; py *= s; int ipx = (int)((px - frontBufferPosition.x) / zoomCoof); int ipy = (int)((py - frontBufferPosition.y) / zoomCoof); OnlineMapsVector2i ip = marker.GetAlignedPosition(ipx, ipy); Color32[] markerColors = marker.colors; if (markerColors == null || markerColors.Length == 0) { return; } int markerWidth = marker.width; int markerHeight = marker.height; OnlineMapsBuffer buffer = map.buffer; for (int y = 0; y < marker.height; y++) { if (ip.y + y < 0 || ip.y + y >= map.height) { continue; } int cy = (markerHeight - y - 1) * markerWidth; for (int x = 0; x < marker.width; x++) { if (ip.x + x < 0 || ip.x + x >= map.buffer.renderState.width) { continue; } try { buffer.SetColorToBuffer(markerColors[cy + x], ip, y, x); } catch { } } } if (isEntireWorld) { ip.x -= (int)(buffer.renderState.width / zoomCoof); for (int y = 0; y < marker.height; y++) { if (ip.y + y < 0 || ip.y + y >= map.height) { continue; } int cy = (markerHeight - y - 1) * markerWidth; for (int x = 0; x < marker.width; x++) { if (ip.x + x < 0 || ip.x + x >= map.buffer.renderState.width) { continue; } try { buffer.SetColorToBuffer(markerColors[cy + x], ip, y, x); } catch { } } } ip.x += (int)(buffer.renderState.width * 2 / zoomCoof); for (int y = 0; y < marker.height; y++) { if (ip.y + y < 0 || ip.y + y >= map.height) { continue; } int cy = (markerHeight - y - 1) * markerWidth; for (int x = 0; x < marker.width; x++) { if (ip.x + x < 0 || ip.x + x >= map.buffer.renderState.width) { continue; } try { buffer.SetColorToBuffer(markerColors[cy + x], ip, y, x); } catch { } } } } marker.locked = false; }
private void UpdateRotatedBuffer() { _lastRotation = _rotation; _lastScale = _scale; if (map.target == OnlineMapsTarget.tileset || (Math.Abs(_rotation) < float.Epsilon && Math.Abs(scale - 1) < float.Epsilon)) { _width = _textureWidth; _height = _textureHeight; return; } #if !UNITY_WEBGL int maxLocked = 20; while (locked && maxLocked > 0) { OnlineMapsUtils.ThreadSleep(1); 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); Color32 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; Color32 c1, c2, c3, c4; 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) { if (ix >= 0 && iz >= 0) { c1 = _colors[iz * tw + ix]; } else { c1 = emptyColor; } if (ix + 1 < tw && iz >= 0) { c2 = _colors[iz * tw + ix + 1]; } else { c2 = emptyColor; } if (ix >= 0 && iz + 1 < th) { c3 = _colors[(iz + 1) * tw + ix]; } else { c3 = emptyColor; } if (ix + 1 < tw && iz + 1 < th) { c4 = _colors[(iz + 1) * tw + ix + 1]; } else { c4 = emptyColor; } c1 = Color32.Lerp(c1, c2, fx); c3 = Color32.Lerp(c3, c4, fx); _rotatedColors[cy + x] = Color32.Lerp(c1, c3, fz); } else { _rotatedColors[cy + x] = emptyColor; } } } locked = false; }
public void GenerateFrontBuffer() { try { lastState = new StateProps { floatZoom = map.floatZoom, width = map.width, height = map.height }; map.GetPosition(out lastState.longitude, out lastState.latitude); map.GetCorners(out lastState.leftLongitude, out lastState.topLatitude, out lastState.rightLongitude, out lastState.bottomLatitude); while (!disposed) { #if !UNITY_WEBGL while (status != OnlineMapsBufferStatus.start && map.renderInThread) { if (disposed) { return; } OnlineMapsUtils.ThreadSleep(1); } #endif status = OnlineMapsBufferStatus.working; renderState = new StateProps { floatZoom = map.floatZoom, width = map.width, height = map.height }; try { map.GetPosition(out renderState.longitude, out renderState.latitude); map.GetCorners(out renderState.leftLongitude, out renderState.topLatitude, out renderState.rightLongitude, out renderState.bottomLatitude); if (newTiles != null && map.control.resultIsTexture) { ApplyNewTiles(); } if (disposed) { return; } UpdateBackBuffer(renderState.longitude, renderState.latitude, renderState.zoom); if (disposed) { return; } if (map.control.resultIsTexture) { GetFrontBufferPosition(renderState.longitude, renderState.latitude, bufferPosition, renderState.floatZoom, renderState.width, renderState.height); UpdateFrontBuffer(renderState.width, renderState.height, renderState.floatZoom); if (disposed) { return; } foreach (OnlineMapsDrawingElement element in OnlineMapsDrawingElementManager.instance) { if (disposed) { return; } element.Draw(frontBuffer, new Vector2(bufferPosition.x + (float)frontBufferPosition.x / OnlineMapsUtils.tileSize, bufferPosition.y + (float)frontBufferPosition.y / OnlineMapsUtils.tileSize), renderState.width, renderState.height, renderState.floatZoom); } if (map.control.OnDrawMarkers != null) { map.control.OnDrawMarkers(); } } } catch (Exception exception) { if (disposed) { return; } Debug.Log(exception.Message + "\n" + exception.StackTrace); } status = OnlineMapsBufferStatus.complete; lastState = renderState; #if !UNITY_WEBGL if (!map.renderInThread) { break; } #else break; #endif } } catch { } }
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) { OnlineMapsUtils.ThreadSleep(1); 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; } OnlineMapsUtils.ThreadSleep(1); } #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 { } }