Пример #1
0
        /// <summary>
        /// Converts and fills the surface vertex buffer to another vertex full.
        /// The default vertex format is VertexPositionColorNormalTexture.
        /// This method must be called immediately after the surface is created.
        /// </summary>
        public void ConvertVertexType <T>(SurfaceVertexConverter <T> fillVertex) where T : struct, IVertexType
        {
            if (fillVertex == null)
            {
                throw new ArgumentNullException("fillVertex");
            }

            if (vertexType != typeof(T) || patches == null)
            {
                vertexType = typeof(T);
                if (patches != null)
                {
                    foreach (SurfacePatch patch in patches)
                    {
                        if (removed != null)
                        {
                            removed(patch);
                        }
                        patch.Dispose();
                    }
                }

                var i          = 0;
                var patchArray = new SurfacePatch[patchCountX * patchCountZ];

                for (int z = 0; z < patchCountZ; z++)
                {
                    for (int x = 0; x < patchCountX; ++x)
                    {
                        patchArray[i++] = new SurfacePatch <T>(this, x, z);
                    }
                }
                patches = new SurfacePatchCollection(this, patchArray);

                if (added != null)
                {
                    foreach (SurfacePatch patch in patches)
                    {
                        added(patch);
                    }
                }
            }

            foreach (SurfacePatch <T> patch in patches)
            {
                patch.FillVertex = fillVertex;
            }

            Invalidate(null);
        }
Пример #2
0
        /// <summary>
        /// This method is called either when the surface is batch initialized using ISupportInitialize interface
        /// or when a property has modified that needs the surface to be re-initialized.
        /// </summary>
        private void OnInitialized()
        {
            var removedPatches = patches;

            if (heightmap == null)
            {
                localBounds   = new BoundingBox();
                patchCountX   = patchCountZ = 0;
                segmentCountX = segmentCountZ = 0;
                patches       = null;

                if (removed != null && removedPatches != null)
                {
                    foreach (var patch in removedPatches)
                    {
                        removed(patch);
                    }
                }
                return;
            }

            if (patchSegmentCount < 2 || patchSegmentCount % 2 != 0 ||
                heightmap.Width % patchSegmentCount != 0 ||
                heightmap.Height % patchSegmentCount != 0)
            {
                throw new ArgumentOutOfRangeException(
                          "patchSegmentCount must be a even number, " +
                          "segmentCountX/segmentCountY must be a multiple of patchSegmentCount.");
            }

            // Create patches
            var newPatchCountX = heightmap.Width / patchSegmentCount;
            var newPatchCountZ = heightmap.Height / patchSegmentCount;

            // Invalid patches when patch count has changed
            if (newPatchCountX != patchCountX || newPatchCountZ != patchCountZ)
            {
                patches = null;
                if (removed != null && removedPatches != null)
                {
                    foreach (var patch in removedPatches)
                    {
                        removed(patch);
                    }
                }
            }

            patchCountX = newPatchCountX;
            patchCountZ = newPatchCountZ;

            // Store these values in case they change
            segmentCountX = heightmap.Width;
            segmentCountZ = heightmap.Height;

            step = heightmap.Step;
            size = new Vector3(heightmap.Width * step, 0, heightmap.Height * step);

            // Initialize geometry
            Geometry = SurfaceGeometry.GetInstance(GraphicsDevice, patchSegmentCount, topology);
            if (lodEnabled)
            {
                Geometry.EnableLevelOfDetail();
            }

            // Convert vertex type
            if (vertexType == null || vertexType == typeof(VertexPositionNormalTexture))
            {
                ConvertVertexType <VertexPositionNormalTexture>(PopulateVertex);
            }
            else if (vertexType == typeof(VertexPositionColor))
            {
                ConvertVertexType <VertexPositionColor>(PopulateVertex);
            }
            else if (vertexType == typeof(VertexPositionTexture))
            {
                ConvertVertexType <VertexPositionTexture>(PopulateVertex);
            }
            else if (vertexType == typeof(VertexPositionNormal))
            {
                ConvertVertexType <VertexPositionNormal>(PopulateVertex);
            }
            else if (vertexType == typeof(VertexPositionNormalDualTexture))
            {
                ConvertVertexType <VertexPositionNormalDualTexture>(PopulateVertex);
            }
            else if (vertexType == typeof(VertexPositionNormalTangentBinormalTexture))
            {
                ConvertVertexType <VertexPositionNormalTangentBinormalTexture>(PopulateVertex);
            }
            else if (vertexType == typeof(VertexPositionColorNormalTexture))
            {
                ConvertVertexType <VertexPositionColorNormalTexture>(PopulateVertex);
            }
            else
            {
                throw new NotSupportedException("Vertex type not supported. Try using Surface.ConvertVertexType<T> instead.");
            }
        }