private static bool TraverseAndStream(QtNode <GrassPatch> node, TraversalData data) { Vector3 position = To3D(node.GetCenter()); position.y = node.Value.Height; bool isInRange = Vector3.SqrMagnitude(data.SubjectPosition - position) <= data.LodRanges[node.Depth]; // Todo: save memory by only assigning values to nodes that will actually carry a payload; the leaves if (!node.HasChildren) { if (isInRange) { data.LoadRequests.Add(node); } else { data.UnloadRequests.Add(node); } } bool stateChange = node.Value.WasInRange != isInRange; node.Value.WasInRange = isInRange; return(isInRange || stateChange); }
private static bool TraverseAndDrawGizmos(QtNode <GrassPatch> node, TraversalData data) { if (node.Value.State != NodeState.Unloaded) { Vector3 position = To3D(node.GetCenter()); position.y = node.Value.Height; Gizmos.color = NodeStateColors[(int)node.Value.State]; Gizmos.DrawWireCube(position, new Vector3(node.Size, 1f, node.Size)); } return(node.Value.WasInRange); }
private void SetupQuadTree() { Vector2 bottomLeft = Vector2.one * (_terrain.Config.TotalTerrainSize * -0.5f); _tree = QuadTreeUtils.Create <GrassPatch>( _terrain.Config.TotalTerrainSize, _terrain.Config.PatchSize, bottomLeft, (node) => { // Construct a node, lookup and cache its center terrain height Vector2 center = node.GetCenter(); Vector3 position = To3D(center); TerrainTile tile = _terrain.GetTile(position); Vector2 terrainCoord = new Vector2( (center.x - tile.transform.position.x) / _terrain.Config.TileSize, (center.y - tile.transform.position.z) / _terrain.Config.TileSize); float height = tile.Terrain.terrainData.GetInterpolatedHeight(terrainCoord.x, terrainCoord.y); var patch = new GrassPatch(node.Coord, height); return(patch); }); _traversalData = new TraversalData(_tree.MaxDepth, _terrain.Config.PatchSize, _config.StreamRadius); }