/// <summary>
        /// Gets a static instance of SurfaceGeometry.
        /// </summary>
        public static SurfaceGeometry GetInstance(GraphicsDevice graphics, int patchSegmentCount, SurfaceTopology topology)
        {
            SurfaceGeometry result = null;
            WeakReference <SurfaceGeometry> value;

            if (resourceDictionary.TryGetValue(new SurfaceGeometryKey(graphics, patchSegmentCount, topology), out value))
            {
                if (value.TryGetTarget(out result))
                {
                    return(result);
                }
                resourceDictionary.Remove(new SurfaceGeometryKey(graphics, patchSegmentCount, topology));
            }

            result = new SurfaceGeometry(graphics, patchSegmentCount, topology);
            value  = new WeakReference <SurfaceGeometry>(result);
            resourceDictionary.Add(new SurfaceGeometryKey(graphics, patchSegmentCount, topology), value);

            return(result);
        }
Exemple #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.");
            }
        }