/// <summary> /// Releases the unmanaged resources used by an instance of the <see cref="SceneNode" /> class /// and optionally releases the managed resources. /// </summary> /// <param name="disposing"> /// <see langword="true" /> to release both managed and unmanaged resources; /// <see langword="false" /> to release only unmanaged resources. /// </param> /// <param name="disposeData"> /// <see langword="true"/> to dispose scene nodes including data objects; /// <see langword="false"/> to dispose only scene nodes but preserve the data objects. /// </param> /// <remarks> /// Scene nodes can share data objects. The parameter <paramref name="disposeData"/> determines /// whether data objects are disposed or preserved when the scene node is disposed. For example, /// multiple <see cref="MeshNode"/>s can share the same <see cref="Mesh"/>. When a /// <see cref="MeshNode"/> is disposed and <paramref name="disposeData"/> is /// <see langword="true"/> the <see cref="Mesh"/> is disposed. All resources (vertex buffers, /// index buffers, etc.) are released and the mesh is no longer usable. /// </remarks> protected virtual void Dispose(bool disposing, bool disposeData) { if (!IsDisposed) { if (disposing) { // Unregister event handlers to prevent "memory leak". _shape.Changed -= OnShapeChanged; // Dispose additional data. RenderData.SafeDispose(); SceneData.SafeDispose(); UserData.SafeDispose(); // Remove any view-dependent information from cameras. CameraNode.RemoveViewDependentData(this); if (_children != null) { foreach (var child in _children) { child.Dispose(disposeData); } } } IsDisposed = true; } }
private void OnClipChanged(object sender, EventArgs eventArgs) { RenderData.SafeDispose(); }
private void Update(bool invalidateRenderData) { if (invalidateRenderData) { RenderData.SafeDispose(); } // Update shape. if (Volume == null) { // Use a PlaneShape for an infinite ocean. var planeShape = Shape as PlaneShape; if (planeShape != null) { planeShape.Normal = new Vector3F(0, 1, 0); planeShape.DistanceFromOrigin = ExtraHeight; } else { Shape = new PlaneShape(new Vector3F(0, 1, 0), ExtraHeight); } return; } // Check if we have a valid AABB. var aabb = Volume.GetAabb(); if (!Numeric.IsZeroOrPositiveFinite(aabb.Extent.LengthSquared)) { throw new GraphicsException("Invalid water volume. The water volume must be a finite shape or null."); } // Apply ExtraHeight. We also apply it horizontally because choppy waves // move vertices horizontally too. aabb.Minimum.X -= ExtraHeight; // Minimum y should be at least max y - ExtraHeight. aabb.Minimum.Y = Math.Min(aabb.Minimum.Y, aabb.Maximum.Y - ExtraHeight); aabb.Minimum.Z -= ExtraHeight; aabb.Maximum.X += ExtraHeight; aabb.Maximum.Y += ExtraHeight; aabb.Maximum.Z += ExtraHeight; // Create shape from volume AABB. if (aabb.Center.IsNumericallyZero) { // Use BoxShape. var boxShape = Shape as BoxShape; if (boxShape != null) { boxShape.Extent = aabb.Extent; } else { Shape = new BoxShape(aabb.Extent); } } else { BoxShape boxShape = null; var transformedShape = Shape as TransformedShape; if (transformedShape != null) { boxShape = transformedShape.Child.Shape as BoxShape; } if (boxShape != null) { boxShape.Extent = aabb.Extent; ((GeometricObject)transformedShape.Child).Pose = new Pose(aabb.Center); } else { Shape = new TransformedShape( new GeometricObject(new BoxShape(aabb.Extent), new Pose(aabb.Center))); } } }