Пример #1
0
        /// <summary>
        /// Populate the quad tree quadrants in the given bounds from the bit map data.
        /// <para />
        /// This function will be recursively called the on the four sub-quadrants of this quadrant. If all of the sub-
        /// quandrants share the same material, then no data is added to the quad tree and the material is returned.
        /// The data will be set at a higher level in the quad tree hierarchy. The reason for this is because if the
        /// parent quadrant is also fully uniform, then any quadrants below it (this one) would have be removed,
        /// wasting processor time.
        /// <para />
        /// If any of the sub-quadrants are of a fully uniform material (yet not *all* sub-quadrants like in the above
        /// case) then the data for those sub-quadrants is set in the quad tree here, making those sub-quadrants leaf
        /// nodes (an example of this could be Q1 and Q2 returning TerrainMaterial.None, Q3 returning
        /// TerrainMaterial.Mud, and Q4 returning null since it is a 'mixed' quadrant and the data is set at a lower
        /// level. In this situation Q1, Q2 and Q3 would have their data set at this level).
        /// </summary>
        /// <param name="quadTree">The quad tree to populate.</param>
        /// <param name="bounds">The bounds of the quadrant whose sub-quandrants are being populated.</param>
        /// <param name="bitmapData">The bit map color data.</param>
        /// <param name="bitmapWidth">The width in pixels of the bitmap image.</param>
        /// <param name="currentTime">The current time used as the terrain creation time.</param>
        /// <returns>The material value if all sub-quadrants in this bound are filled with the same material; Null if
        /// the sub-quadrants have various materials.</returns>
        private TerrainMaterial? PopulateQuadrants(
            ClipQuadTree<TerrainData> quadTree,
            Square bounds,
            Color[] bitmapData,
            int bitmapWidth,
            TimeSpan currentTime)
        {
            if (bounds.Length > 1)
            {
                // Get the sub-quadrant bounds of this quadrant
                Square topLeftBounds = bounds.GetTopLeftQuadrant();
                Square topRightBounds = bounds.GetTopRightQuadrant();
                Square bottomLeftBounds = bounds.GetBottomLeftQuadrant();
                Square bottomRightBounds = bounds.GetBottomRightQuadrant();

                // Populate the sub quadrants or if they are uniform get the single material they contain
                TerrainMaterial? topLeftTerrain =
                    this.PopulateQuadrants(quadTree, topLeftBounds, bitmapData, bitmapWidth, currentTime);
                TerrainMaterial? topRightTerrain =
                    this.PopulateQuadrants(quadTree, topRightBounds, bitmapData, bitmapWidth, currentTime);
                TerrainMaterial? bottomLeftTerrain =
                    this.PopulateQuadrants(quadTree, bottomLeftBounds, bitmapData, bitmapWidth, currentTime);
                TerrainMaterial? bottomRightTerrain =
                    this.PopulateQuadrants(quadTree, bottomRightBounds, bitmapData, bitmapWidth, currentTime);

                // Check if all of the quadrants are uniform and all have the same material
                if (topLeftTerrain.HasValue &&
                    topLeftTerrain == topRightTerrain &&
                    topRightTerrain == bottomLeftTerrain &&
                    bottomLeftTerrain == bottomRightTerrain)
                {
                    // All quadrants have the same material. Return this to create the quadrant at a higher level
                    return topLeftTerrain;
                }
                else
                {
                    // The quadrants do not all share the same material. However, they may themselves be uniform in
                    // which case their quadrant values need to be set in the quad tree
                    if (topLeftTerrain.HasValue)
                    {
                        // Quadrant has a uniform color
                        quadTree.SetData(
                            new TerrainData(topLeftTerrain.Value, currentTime), topLeftBounds, null);
                    }

                    if (topRightTerrain.HasValue)
                    {
                        // Quadrant has a uniform color
                        quadTree.SetData(
                            new TerrainData(topRightTerrain.Value, currentTime), topRightBounds, null);
                    }

                    if (bottomLeftTerrain.HasValue)
                    {
                        // Quadrant has a uniform color
                        quadTree.SetData(
                            new TerrainData(bottomLeftTerrain.Value, currentTime), bottomLeftBounds, null);
                    }

                    if (bottomRightTerrain.HasValue)
                    {
                        // Quadrant has a uniform color
                        quadTree.SetData(
                            new TerrainData(bottomRightTerrain.Value, currentTime), bottomRightBounds, null);
                    }

                    // Return null since there isnt a single color shared between all the quadrants
                    return null;
                }
            }
            else
            {
                // Get the terrain material at this pixel
                if (bounds.X < bitmapWidth)
                {
                    int dataIndex = bounds.X + (bounds.Y * bitmapWidth);
                    if (dataIndex < bitmapData.Length)
                    {
                        return TerrainMaterialConverter.GetValue(bitmapData[dataIndex]);
                    }
                    else
                    {
                        // The index is out of bounds for this quadrant. This will happen if the bitmap image is not a
                        // square with a power-of-2 length. Just return TerrainMaterial.None
                        return TerrainMaterial.None;
                    }
                }
                else
                {
                    // The index is out of bounds for this quadrant. This will happen if the bitmap image is not a
                    // square with a power-of-2 length. Just return TerrainMaterial.None
                    return TerrainMaterial.None;
                }
            }
        }