/// <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); }
/// <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."); } }