示例#1
0
        private void UpdateHoleTexture()
        {
            // Hole information could be loaded from a texture. Here, we procedurally create a pattern of
            // holes.
            // The hole buffer is array with 1 where there is no hole and 0 where there is a hole.
            // (This is similar to an alpha mask: 1 = opaque, 0 = transparent.)
            int numberOfSamples = _terrainObject.TerrainNode.Terrain.Tiles.First().HeightTexture.Width;

            float[] holes = new float[numberOfSamples * numberOfSamples];

            // Fill hole buffer with 1.
            for (int i = 0; i < holes.Length; i++)
            {
                holes[i] = 1;
            }

            if (_holeSize > 0)
            {
                // Add some 0 elements to create holes.
                int counterY = _holeSize;
                for (int y = 0; y < numberOfSamples - 1; y++)
                {
                    int counterX = _holeSize;
                    for (int x = 0; x < numberOfSamples - 1; x++)
                    {
                        holes[y * numberOfSamples + x] = 0;

                        counterX--;
                        if (counterX <= 0)
                        {
                            counterX = _holeSize;
                            x       += _holeSize * 2;
                        }
                    }

                    counterY--;
                    if (counterY <= 0)
                    {
                        counterY = _holeSize;
                        y       += _holeSize * 2;
                    }
                }
            }

            // Copy hole buffer to a texture.
            TerrainHelper.CreateHoleTexture(
                GraphicsService.GraphicsDevice,
                holes,
                numberOfSamples,
                numberOfSamples,
                false,
                ref _holeTexture);

            foreach (var tile in _terrainObject.TerrainNode.Terrain.Tiles)
            {
                // Assign the hole texture to all terrain tiles. (Normally, each tile would have a
                // different hole texture or no hole texture at all.)
                tile.HoleTexture = _holeTexture;

                // We also have to add the holes to the collision detection height fields.
                // Get rigid body that represents this tile.
                var rigidBody   = Simulation.RigidBodies.First(body => body.UserData == tile);
                var heightField = (HeightField)rigidBody.Shape;

                // Update the height values of the collision detection height field.
                float[] heights = TerrainHelper.GetTextureLevelSingle(tile.HeightTexture, 0);
                for (int z = 0; z < numberOfSamples; z++)
                {
                    for (int x = 0; x < numberOfSamples; x++)
                    {
                        if ((!(holes[z * numberOfSamples + x] > 0.5f)))
                        {
                            // The HeightField class treats NaN as holes.
                            heights[z * numberOfSamples + x] = float.NaN;
                        }
                    }
                }
                heightField.SetSamples(heights, numberOfSamples, numberOfSamples);
                heightField.Invalidate();
            }

            _terrainObject.TerrainNode.Terrain.Invalidate();
        }