private bool Traverse_CanDescend(ref TraversalInfo info, ref TraverseSettings settings) { if (!settings.AllowDescend) { return(false); } if (!info.ContainsChildren) { return(false); } if (!settings.AllowDescendIfDisabled && !info.Control.Enabled) { return(false); } // FIXME: Optimize this check if (!settings.AllowDescendIfInvisible && Control.IsRecursivelyTransparent(info.Control, true)) { return(false); } return(true); }
public bool Step(out float2 poi, out bool hit) { hit = false; poi = float2.zero; //check if the tree is not empty if (InfoStack.Count == 0) { //Return if tree is empty return(true); } //POP //if we are in a terminal tree / leaf node //or we visited all children in that tree //pop current tree from stack //next child ==4 means all children visited; next child 0-3 are quadrants 0-3 if (InfoStack.Peek().nextChild == 4) { InfoStack.Pop(); return(false); } //check if tree is leaf node if (InfoStack.Peek().tree.IsLeaf()) { TraversalInfo tempInfo = InfoStack.Pop(); //try to find ray collision with colliders in leaf node foreach (AABB aabb in tempInfo.tree.AABBs) { if (RayAABBIntersection.Intersection(ray.Origin, ray.Direction, aabb, out poi)) { hit = true; return(true); } } return(false); } //PUSH //get info TraversalInfo info = InfoStack.Peek(); //rewrite variables for readability double2 t0 = info.t0; double2 t1 = info.t1; double2 tm = info.tm; //check if quadrant has already been visited //if visiting quadrant for the first time the next child has not been determined & set to -1 if (InfoStack.Peek().nextChild == -1) { //find the firstQuadrant && store it InfoStack.Peek().nextChild = firstNode(t0.x, t0.y, tm.x, tm.y); } //ADVANCE //find next child in voxel to advance to //define variables QuadTree getTree; TraversalInfo newInfo; //switch case to determine what to do for each quadrant switch (InfoStack.Peek().nextChild) { case (0): //get next child InfoStack.Peek().nextChild = NewNode(tm.x, 1, tm.y, 2); //get current child getTree = InfoStack.Peek().tree.GetChild(0 ^ a); //create new info newInfo = GenerateInfo(t0.x, tm.x, t0.y, tm.y, getTree); //push new info to stack InfoStack.Push(newInfo); break; case (1): InfoStack.Peek().nextChild = NewNode(t1.x, 4, tm.y, 3); getTree = InfoStack.Peek().tree.GetChild(1 ^ a); newInfo = GenerateInfo(tm.x, t1.x, t0.y, tm.y, getTree); InfoStack.Push(newInfo); break; case (2): InfoStack.Peek().nextChild = NewNode(tm.x, 3, t1.y, 4); getTree = InfoStack.Peek().tree.GetChild(2 ^ a); newInfo = GenerateInfo(t0.x, tm.x, tm.y, t1.y, getTree); InfoStack.Push(newInfo); break; case (3): InfoStack.Peek().nextChild = NewNode(tm.x, 4, tm.y, 4); getTree = InfoStack.Peek().tree.GetChild(3 ^ a); newInfo = GenerateInfo(tm.x, t1.x, tm.y, t1.y, getTree); InfoStack.Push(newInfo); break; } return(false); }
void DetermineTiles() { var ms = CurrentMapSource; //var d = Math.Log((camera.CameraDistance - camera.EarthRadius) * 1000.0, 2.0); double lod = lowestLod; if (camera.Viewport.Width != 0) { int closestZoom = lowestLod; double closestRadius = 100; for (int zoom = 3; zoom <= ms.MaxZoom; zoom++) { var dis = GetLevelScreenSpaceError(zoom, camera.CameraDistance - camera.EarthRadius); if (dis < closestRadius && dis >= 0.0f) { closestRadius = dis; closestZoom = zoom; } } lod = closestZoom; } var maxLod = ms.MaxZoom; lowestLod = (int)lod; if (lowestLod > maxLod.Value) lowestLod = maxLod.Value; CurrentLevel = lowestLod; if (CurrentLevel < 3) CurrentLevel = 3; // Get camera mercator position var lonLat = camera.GetCameraLonLat(); lonLat.X = DMathUtil.RadiansToDegrees(lonLat.X); lonLat.Y = DMathUtil.RadiansToDegrees(lonLat.Y); if (updateTiles) { foreach (var tile in tilesToRender) { tilesFree.Add(tile.Key, tile.Value); } updateTiles = false; } else { foreach (var tile in tilesToRender) { tilesOld.Add(tile.Key, tile.Value); } } tilesToRender.Clear(); var info = new TraversalInfo[2]; var centralNode = new Node { Z = CurrentLevel - 2 }; var tileUpper = ms.Projection.WorldToTilePos(lonLat.X, lonLat.Y, centralNode.Z); centralNode.X = (int)tileUpper.X; centralNode.Y = (int)tileUpper.Y; //GetTileIndexByMerc(merc, centralNode.Z, out centralNode.X, out centralNode.Y); info[0].CentralNode = new Node { X = centralNode.X - 7, Y = centralNode.Y - 7, Z = centralNode.Z }; info[0].Offset = 4; info[0].Length = 7; var offNode = new Node { X = info[0].CentralNode.X + info[0].Offset, Y = info[0].CentralNode.Y + info[0].Offset, Z = info[0].CentralNode.Z }; GetChilds(ref offNode); info[1].CentralNode = offNode.Childs[0]; info[1].Offset = 3; info[1].Length = 8; int tilesNum = 1 << info[0].CentralNode.Z; for (int i = 0; i < 15; i++) { for (int j = 0; j < 15; j++) { var nodeX = info[0].CentralNode.X + i; var nodeY = info[0].CentralNode.Y + j; nodeX = nodeX % tilesNum; if (nodeX < 0) nodeX = tilesNum + nodeX; if (nodeY < 0 || nodeY >= tilesNum) continue; var currNode = new Node { X = nodeX, Y = nodeY, Z = info[0].CentralNode.Z }; QuadTreeTraversalDownTop(info, currNode, 0); } } foreach (var tile in tilesOld) { tilesFree.Add(tile.Key, tile.Value); } tilesOld.Clear(); }
void QuadTreeTraversalDownTop(TraversalInfo[] info, Node node, int step) { int maxLevel = CurrentMapSource.MaxZoom.Value; if (node.Z > maxLevel) return; if (step >= info.Length) { AddTileToRenderList(node.X, node.Y, node.Z); return; } GetChilds(ref node); int offX = node.X - info[step].CentralNode.X; int offY = node.Y - info[step].CentralNode.Y; CurrentMapSource.GetTile(node.X, node.Y, node.Z); if (offX >= info[step].Offset && offX < info[step].Offset + info[step].Length && offY >= info[step].Offset && offY < info[step].Offset + info[step].Length) { if (CheckTiles(node)) { foreach (var child in node.Childs) { QuadTreeTraversalDownTop(info, child, step + 1); } } else { AddTileToRenderList(node.X, node.Y, node.Z); } } else { AddTileToRenderList(node.X, node.Y, node.Z); } }
/// <summary> /// /// </summary> void DetermineTiles() { //SetCurrentLevel(); var ms = Game.GetService<LayerService>().MapLayer.CurrentMapSource; var d = Math.Log((Config.CameraDistance - Config.earthRadius) * 1000.0, 2.0); double lod = 28.3 - d; var maxLod = ms.MaxZoom; lowestLod = (int)lod; if (lowestLod > maxLod.Value) lowestLod = maxLod.Value; CurrentLevel = lowestLod; if (CurrentLevel < 3) CurrentLevel = 3; // Get camera mercator position var lonLat = GetCameraLonLat(); lonLat.X = DMathUtil.RadiansToDegrees(lonLat.X); lonLat.Y = DMathUtil.RadiansToDegrees(lonLat.Y); //var merc = GeoHelper.WorldToTilePos(lonLat.X, lonLat.Y); var merc = ms.Projection.WorldToTilePos(lonLat.X, lonLat.Y, CurrentLevel); // Get tile index under camera int x, y; //GetTileIndexByMerc(merc, CurrentLevel, out x, out y); x = (int)merc.X; y = (int)merc.Y; var key = GenerateKey(x, y, CurrentLevel); //if (key == centerTile) return; centerTile = key; if (updateTiles) { foreach (var tile in tilesToRender) { tilesFree.Add(tile.Key, tile.Value); } updateTiles = false; } else { foreach (var tile in tilesToRender) { tilesOld.Add(tile.Key, tile.Value); } } tilesToRender.Clear(); var info = new TraversalInfo[2]; var centralNode = new Node { Z = CurrentLevel - 2 }; var tileUpper = ms.Projection.WorldToTilePos(lonLat.X, lonLat.Y, centralNode.Z); centralNode.X = (int)tileUpper.X; centralNode.Y = (int)tileUpper.Y; //GetTileIndexByMerc(merc, centralNode.Z, out centralNode.X, out centralNode.Y); info[0].CentralNode = new Node { X = centralNode.X - 7, Y = centralNode.Y - 7, Z = centralNode.Z }; info[0].Offset = 4; info[0].Length = 7; var offNode = new Node { X = info[0].CentralNode.X + info[0].Offset, Y = info[0].CentralNode.Y + info[0].Offset, Z = info[0].CentralNode.Z }; GetChilds(offNode); info[1].CentralNode = offNode.Childs[0]; info[1].Offset = 3; info[1].Length = 8; int tilesNum = 1 << info[0].CentralNode.Z; for (int i = 0; i < 15; i++) { for (int j = 0; j < 15; j++) { var nodeX = info[0].CentralNode.X + i; var nodeY = info[0].CentralNode.Y + j; nodeX = nodeX % tilesNum; if (nodeX < 0) nodeX = tilesNum + nodeX; if (nodeY < 0 || nodeY >= tilesNum) continue; var currNode = new Node {X = nodeX, Y = nodeY, Z = info[0].CentralNode.Z }; QuadTreeTraversalDownTop(info, currNode, 0); } } foreach (var tile in tilesOld) { tilesFree.Add(tile.Key, tile.Value); } tilesOld.Clear(); }
/// <summary> /// /// </summary> void DetermineTiles() { //SetCurrentLevel(); var ms = Game.GetService <LayerService>().MapLayer.CurrentMapSource; var d = Math.Log((Config.CameraDistance - Config.earthRadius) * 1000.0, 2.0); double lod = 28.3 - d; var maxLod = ms.MaxZoom; lowestLod = (int)lod; if (lowestLod > maxLod.Value) { lowestLod = maxLod.Value; } CurrentLevel = lowestLod; if (CurrentLevel < 3) { CurrentLevel = 3; } // Get camera mercator position var lonLat = GetCameraLonLat(); lonLat.X = DMathUtil.RadiansToDegrees(lonLat.X); lonLat.Y = DMathUtil.RadiansToDegrees(lonLat.Y); //var merc = GeoHelper.WorldToTilePos(lonLat.X, lonLat.Y); var merc = ms.Projection.WorldToTilePos(lonLat.X, lonLat.Y, CurrentLevel); // Get tile index under camera int x, y; //GetTileIndexByMerc(merc, CurrentLevel, out x, out y); x = (int)merc.X; y = (int)merc.Y; var key = GenerateKey(x, y, CurrentLevel); //if (key == centerTile) return; centerTile = key; if (updateTiles) { foreach (var tile in tilesToRender) { tilesFree.Add(tile.Key, tile.Value); } updateTiles = false; } else { foreach (var tile in tilesToRender) { tilesOld.Add(tile.Key, tile.Value); } } tilesToRender.Clear(); var info = new TraversalInfo[2]; var centralNode = new Node { Z = CurrentLevel - 2 }; var tileUpper = ms.Projection.WorldToTilePos(lonLat.X, lonLat.Y, centralNode.Z); centralNode.X = (int)tileUpper.X; centralNode.Y = (int)tileUpper.Y; //GetTileIndexByMerc(merc, centralNode.Z, out centralNode.X, out centralNode.Y); info[0].CentralNode = new Node { X = centralNode.X - 7, Y = centralNode.Y - 7, Z = centralNode.Z }; info[0].Offset = 4; info[0].Length = 7; var offNode = new Node { X = info[0].CentralNode.X + info[0].Offset, Y = info[0].CentralNode.Y + info[0].Offset, Z = info[0].CentralNode.Z }; GetChilds(offNode); info[1].CentralNode = offNode.Childs[0]; info[1].Offset = 3; info[1].Length = 8; int tilesNum = 1 << info[0].CentralNode.Z; for (int i = 0; i < 15; i++) { for (int j = 0; j < 15; j++) { var nodeX = info[0].CentralNode.X + i; var nodeY = info[0].CentralNode.Y + j; nodeX = nodeX % tilesNum; if (nodeX < 0) { nodeX = tilesNum + nodeX; } if (nodeY < 0 || nodeY >= tilesNum) { continue; } var currNode = new Node { X = nodeX, Y = nodeY, Z = info[0].CentralNode.Z }; QuadTreeTraversalDownTop(info, currNode, 0); } } foreach (var tile in tilesOld) { tilesFree.Add(tile.Key, tile.Value); } tilesOld.Clear(); }