public void Select(Selection selection) { for (int y = 0; y < topNodeCountY; y++) { for (int x = 0; x < topNodeCountX; x++) { topNodes[x, y].Select(selection, false, false); } } }
public void Select(Selection selection) { // Prepare selection's state per a terrain. selection.ClearSelectedNodes(); // Select visible nodes. quadTree.Select(selection); // Set the height map texture to render. selection.HeightMapTexture = heightMapTexture; }
bool PreSelect(Selection selection, bool parentCompletelyInFrustum) { BoundingBox boundingBox; GetBoundingBox(ref selection.TerrainOffset, selection.PatchScale, selection.HeightScale, out boundingBox); // do not check the intersection between AABB and the view frustum. BoundingSphere sphere; selection.GetVisibilitySphere(level, out sphere); if (!boundingBox.Intersects(sphere)) return false; return true; }
public bool Select(Selection selection, bool parentCompletelyInFrustum, bool ignoreVisibilityCheck) { BoundingBox boundingBox; GetBoundingBox(ref selection.TerrainOffset, selection.PatchScale, selection.HeightScale, out boundingBox); ContainmentType containmentType = ContainmentType.Contains; if (!parentCompletelyInFrustum) { selection.Frustum.Contains(ref boundingBox, out containmentType); } BoundingSphere sphere; bool intersected = true; if (!ignoreVisibilityCheck) { selection.GetVisibilitySphere(level, out sphere); boundingBox.Intersects(ref sphere, out intersected); if (!intersected) return false; } if (level == 0) { // we reach a leaf node. if (containmentType != ContainmentType.Disjoint) selection.AddSelectedNode(this); return true; } // If this node is out of the next visibility, we do not need to check children. selection.GetVisibilitySphere(level - 1, out sphere); boundingBox.Intersects(ref sphere, out intersected); if (!intersected) { if (containmentType != ContainmentType.Disjoint) selection.AddSelectedNode(this); return true; } bool weAreCompletelyInFrustum = (containmentType == ContainmentType.Contains); // Check a child node's visibility on ahead. var someChildrenSelected = false; someChildrenSelected |= childTopLeft.PreSelect(selection, weAreCompletelyInFrustum); if (childTopRight != null) someChildrenSelected |= childTopRight.PreSelect(selection, weAreCompletelyInFrustum); if (childBottomLeft != null) someChildrenSelected |= childBottomLeft.PreSelect(selection, weAreCompletelyInFrustum); if (childBottomRight != null) someChildrenSelected |= childBottomRight.PreSelect(selection, weAreCompletelyInFrustum); if (someChildrenSelected) { // Select all children to avoid T-junctions by ignoring a visibiliy range check // if can select at least one. // The original code tries to select finer nodes as far as possible, // and hides parts of a coaser node overlapped by them at render time. // But using HW instancing, we must use a same mesh, so can not use such a overlap. childTopLeft.Select(selection, weAreCompletelyInFrustum, true); if (childTopRight != null) childTopRight.Select(selection, weAreCompletelyInFrustum, true); if (childBottomLeft != null) childBottomLeft.Select(selection, weAreCompletelyInFrustum, true); if (childBottomRight != null) childBottomRight.Select(selection, weAreCompletelyInFrustum, true); } else { if (containmentType != ContainmentType.Disjoint) selection.AddSelectedNode(this); } return true; }
protected override void LoadContent() { // create a height map. var noiseMap = new NoiseMap(); noiseMap.GetValue2 = (x, y) => { return sumFractal.GetValue(x, 0, y); }; noiseMap.Width = noiseMapWidth; noiseMap.Height = noiseMapHeight; noiseMap.SetBounds(noiseSampleX, noiseSampleY, noiseSampleWidth, noiseSampleHeight); noiseMap.Build(); var heightMap = new DefaultHeightMapSource(noiseMap.Values, noiseMap.Width, noiseMap.Height); settings.LevelCount = levelCount; settings.LeafNodeSize = leafNodeSize; settings.PatchScale = patchScale; settings.HeightScale = heightScale; visibleRanges = new DefaultVisibleRanges(settings); //visibleRanges.MostDetailRange = DefaultVisibleRanges.DefaultMostDetailRange; visibleRanges.FinestNodeSize = 3; visibleRanges.DetailBalance = 2; visibleRanges.Initialize(); terrain = new Terrain(GraphicsDevice, settings); terrain.Initialize(heightMap); renderer = new TerrainRenderer(GraphicsDevice, Content, settings); renderer.InitializeMorphConsts(visibleRanges); renderer.WireframeGap = wireframeGap; selection = new Selection(settings, visibleRanges); spriteBatch = new SpriteBatch(GraphicsDevice); font = Content.Load<SpriteFont>("Fonts/Debug"); fillTexture = Texture2DHelper.CreateFillTexture(GraphicsDevice); helpMessageFontSize = font.MeasureString(helpMessage); BuildInformationMessage(9999); informationTextFontSize = font.MeasureString(stringBuilder); }
public void Draw(GameTime gameTime, Selection selection) { if (selection.SelectedNodeCount == 0) return; // create instances for (int i = 0; i < selection.SelectedNodeCount; i++) selection.GetPatchInstanceVertex(i, out instances[i]); var offset = instanceVertexBuffer.SetData(instances, 0, selection.SelectedNodeCount); vertexBufferBindings[0] = new VertexBufferBinding(patchMesh.VertexBuffer, 0); vertexBufferBindings[1] = new VertexBufferBinding(instanceVertexBuffer.VertexBuffer, offset, 1); GraphicsDevice.SetVertexBuffers(vertexBufferBindings); GraphicsDevice.Indices = patchMesh.IndexBuffer; GraphicsDevice.DepthStencilState = DepthStencilState.Default; // Prepare effect parameters. // per a selection (a terrain). effect.TerrainOffset = selection.TerrainOffset; effect.TerrainScale = selection.TerrainScale; effect.HeightMap = selection.HeightMapTexture; effect.View = selection.View; effect.Projection = selection.Projection; // render settings. effect.AmbientLightColor = ambientLightColor; effect.LightDirection = lightDirection; effect.DiffuseLightColor = diffuseLightColor; effect.LightEnabled = LightEnabled; // WhiteSolid tequnique if (WhiteSolidVisible) DrawPatchInstances(effect.WhiteSolidTequnique, selection.SelectedNodeCount); // HeightColor tequnique if (HeightColorVisible) DrawPatchInstances(effect.HeightColorTequnique, selection.SelectedNodeCount); // Wireframe tequnique if (WireframeVisible) { var wireframeTerrainOffset = selection.TerrainOffset; wireframeTerrainOffset.Y += WireframeGap; effect.TerrainOffset = wireframeTerrainOffset; DrawPatchInstances(effect.WireframeTequnique, selection.SelectedNodeCount); effect.TerrainOffset = selection.TerrainOffset; } if (NodeBoundingBoxVisible) { debugEffect.View = selection.View; debugEffect.Projection = selection.Projection; SelectedNode selectedNode; BoundingBox box; for (int i = 0; i < selection.SelectedNodeCount; i++) { selection.GetSelectedNode(i, out selectedNode); selectedNode.GetBoundingBox( ref selection.TerrainOffset, settings.PatchScale, settings.HeightScale, out box); var level = selectedNode.Level; level %= 4; boundingBoxDrawer.Draw(ref box, debugEffect, ref debugLevelColors[level]); } } }