GeometricObject Class |
Namespace: DigitalRune.Geometry
The GeometricObject type exposes the following members.
Name | Description | |
---|---|---|
GeometricObject |
Initializes a new instance of the GeometricObject class.
| |
GeometricObject(Shape) |
Initializes a new instance of the GeometricObject class with a shape.
| |
GeometricObject(Shape, Pose) |
Initializes a new instance of the GeometricObject class with shape and pose
(position and orientation).
| |
GeometricObject(Shape, Vector3F) |
Initializes a new instance of the GeometricObject class with shape and scale.
| |
GeometricObject(Shape, Vector3F, Pose) |
Initializes a new instance of the GeometricObject class with shape, scale and
pose (position and orientation).
|
Name | Description | |
---|---|---|
Clone |
Creates a new GeometricObject that is a clone (deep copy) of the current
instance.
| |
CloneCore |
Makes the instance a clone (deep copy) of the specified GeometricObject.
| |
CreateInstanceCore |
When implemented in a derived class, creates a new instance of the
GeometricObject derived class.
| |
Equals | (Inherited from Object.) | |
Finalize | Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection. (Inherited from Object.) | |
GetHashCode | Serves as a hash function for a particular type. (Inherited from Object.) | |
GetType | Gets the Type of the current instance. (Inherited from Object.) | |
MemberwiseClone | Creates a shallow copy of the current Object. (Inherited from Object.) | |
OnPoseChanged |
Raises the PoseChanged event.
| |
OnShapeChanged |
Raises the ShapeChanged event.
| |
ToString | Returns a string that represents the current object. (Inherited from Object.) |
Name | Description | |
---|---|---|
Aabb |
Gets the axis-aligned bounding box (AABB).
| |
Pose |
Gets or sets the pose (position and orientation).
| |
Scale |
Gets or sets the scale.
| |
Shape |
Gets or sets the shape.
|
Name | Description | |
---|---|---|
PoseChanged |
Occurs when the Pose was changed.
| |
ShapeChanged |
Name | Description | |
---|---|---|
IGeometricObjectClone |
Creates a new IGeometricObject that is a clone (deep copy) of the current
instance.
|
Classes that need to implement IGeometricObject can derive from GeometricObject.
Important: An IGeometricObject instance registers event handlers for the Changed event of the contained Shape. Therefore, a Shape will have an indirect reference to the IGeometricObject. This is no problem if the geometric object exclusively owns the shape. However, this could lead to problems ("life extension bugs" a.k.a. "memory leaks") when multiple geometric objects share the same shape: One geometric object is no longer used but it cannot be collected by the garbage collector because the shape still holds a reference to the object.
Therefore, when Shapes are shared between multiple IGeometricObjects: Always set the property Shape to Empty when the IGeometricObject is no longer used. Empty is a special immutable shape that never raises any Changed events. Setting Shape to Empty ensures that the internal event handlers are unregistered and the object can be garbage-collected properly.
Cloning: Geometric objects are cloneable. The method Clone creates a deep copy of the geometric object - except when documented otherwise (see description of implementing classes).
Notes to Inheritors: The support for cloning of geometric objects is built-in in DigitalRune Geometry because several applications built upon the library rely on the cloning mechanism. The DigitalRune Geometry library internally does not use the cloning mechanism. So, if you need to write your own type that implements IGeometricObject and your own application does not require to clone geometric objects, you can simply omit the implementation of Clone - just throw a NotImplementedException.
using System; using DigitalRune.Geometry.Shapes; using DigitalRune.Mathematics.Algebra; namespace DigitalRune.Geometry { [Serializable] public class GeometricObject : IGeometricObject { //-------------------------------------------------------------- #region Properties & Events //-------------------------------------------------------------- public Aabb Aabb { get { if (_aabbIsValid == false) { _aabb = Shape.GetAabb(Scale, Pose); _aabbIsValid = true; } return _aabb; } } private Aabb _aabb; private bool _aabbIsValid; public Pose Pose { get { return _pose; } set { if (_pose != value) { _pose = value; OnPoseChanged(EventArgs.Empty); } } } private Pose _pose; public Shape Shape { get { return _shape; } set { if (value == null) throw new ArgumentNullException("value"); if (_shape != null) _shape.Changed -= OnShapeChanged; _shape = value; _shape.Changed += OnShapeChanged; OnShapeChanged(ShapeChangedEventArgs.Empty); } } private Shape _shape; public Vector3F Scale { get { return _scale; } set { if (_scale != value) { _scale = value; OnShapeChanged(ShapeChangedEventArgs.Empty); } } } private Vector3F _scale; public event EventHandler<EventArgs> PoseChanged; public event EventHandler<ShapeChangedEventArgs> ShapeChanged; #endregion //-------------------------------------------------------------- #region Creation & Cleanup //-------------------------------------------------------------- public GeometricObject() { _shape = Shape.Empty; _scale = Vector3F.One; _pose = Pose.Identity; } #endregion //-------------------------------------------------------------- #region Methods //-------------------------------------------------------------- IGeometricObject IGeometricObject.Clone() { return Clone(); } public GeometricObject Clone() { GeometricObject clone = CreateInstance(); clone.CloneCore(this); return clone; } private GeometricObject CreateInstance() { GeometricObject newInstance = CreateInstanceCore(); if (GetType() != newInstance.GetType()) { string message = String.Format( "Cannot clone shape. The derived class {0} does not implement CreateInstanceCore().", GetType()); throw new InvalidOperationException(message); } return newInstance; } protected virtual GeometricObject CreateInstanceCore() { return new GeometricObject(); } protected virtual void CloneCore(GeometricObject sourceShape) { Pose = sourceShape.Pose; Shape = sourceShape.Shape.Clone(); Scale = sourceShape.Scale; } private void OnShapeChanged(object sender, ShapeChangedEventArgs eventArgs) { OnShapeChanged(eventArgs); } protected virtual void OnPoseChanged(EventArgs eventArgs) { _aabbIsValid = false; var handler = PoseChanged; if (handler != null) handler(this, eventArgs); } protected virtual void OnShapeChanged(ShapeChangedEventArgs eventArgs) { _aabbIsValid = false; var handler = ShapeChanged; if (handler != null) handler(this, eventArgs); } #endregion } }