Click or drag to resize
AB4D logo

EventManager3D Class

EventManager3D class is a helper class that enables user to simply subscribe to mouse and touch events on 3D objects.
Inheritance Hierarchy
SystemObject
  Ab3d.UtilitiesEventManager3D

Namespace:  Ab3d.Utilities
Assembly:  Ab3d.PowerToys (in Ab3d.PowerToys.dll) Version: 10.1.8147.1045
Syntax
C#
public class EventManager3D

The EventManager3D type exposes the following members.

Constructors
Properties
  NameDescription
Public propertyCustomEventsSourceElement
Gets or sets a FrameworkElement that can be used instead of TargetViewport3D to get the mouse events (MouseMove, MouseEnter, MouseLeave). If null (default) than TargetViewport3D is used as event source.
Public propertyDragMouseDistance
Gets or sets the distance mouse must make when the move is considered as mouse drag. The default value is 5.
Public propertyIsEnabled
Gets or sets a boolean value that specifies if the EventManager3D is enabled.
Public propertyIsManipulationEnabled
Gets or sets a boolean that specifies if Manipulation (touch based) events are enabled by this EventManager3D (this works only when .Net 4 or higher version of the library is used). Default valus is false.
Public propertyNamedObjects
Gets or sets a Dictionary<string, object> that is can be used to specify object names in the registered EventSource3D objects.
Public propertyTargetViewport3D
Gets or sets a Viewport3D that contains the Model3D and Visual3D objects that are used by this EventManager3D.
Public propertyUsePreviewEvents
Gets or sets a boolean that specifies if EventManager3D subscribed to Preview moouse and touch events instead of standard events - for example PreviewMouseUp event instead of MouseUp event. Default value is false;
Top
Methods
  NameDescription
Protected methodCheckMouseOverElement
CheckMouseOverElement method sets protected lastHitEventSource3D and lastRayHitResult with the hit event source data.
Public methodRegisterEventSource3D
Registers the eventSource to the EventManager3D
Public methodRegisterExcludedVisual3D(Visual3D)
Registers a visual3D that will be excluded from hit testing - the ray from the mouse will "travel" through that Visual and will hit the objects behind.
Public methodRegisterExcludedVisual3D(Visual3D)
Registers a list of visual3D objects that will be excluded from hit testing - the ray from the mouse will "travel" through that Visual and will hit the objects behind.
Public methodRemoveEventSource3D
Removes the eventSource from the EventManager3D
Public methodRemoveExcludedVisual3D
Removed the visual3D from the excluded visuals list. To remove all excluded visuals it is also possible to call ResetEventSources3D method.
Public methodResetEventSources3D
Clears all the registered EventSource3D objects. This also removes all registered Visuals that are not hit visible.
Public methodUpdateHitObjects
UpdateHitObjects method can be called to manually update the 3D objects that are behind the current mouse position. This is useful when the camera is changed without moving the mouse. In this case the 3D objects behind the mouse position can change. If this happens the MouseEnter, MouseLeave and other event handlers will be called from the UpdateHitObjects method. It is possible to specify the MouseEventArgs that is passed to triggered event handlers (if mouseEventArgs is not specified, then null is passed).
Top
Fields
  NameDescription
Protected fieldlastHitEventSource3D
Last hit EventSource3D
Protected fieldlastRayHitResult
RayMeshGeometry3DHitTestResult of the last hit EventSource3D
Top
Remarks

Some mouse events support is already available with WPF's ModelUIElement3D class, but it only support some of the mouse events and provide only limited information about the hit objects. Its usage also requires breaking the 3D objects that are grouped with Model3DGroup into individual ModelUIElement3D objects. Using EventManager3D provides much better events support and does not require any change in the 3D objects organization.

The following mouse events are supported:
MouseEnter
MouseLeave,
MouseMove,
MouseDown,
MouseUp,
MouseClick,
MouseDoubleClick,
MouseWheel,
BeginMouseDrag,
MouseDrag,
EndMouseDrag.

When a .Net 4 version of Ab3d.PowerToys library is used, EventManager3D also supports the following touch events:
TouchEnter,
TouchDown,
TouchMove,
TouchUp,
TouchLeave.

It is also possible to use touch manipulations events (pinch scale and rotate). To use manipulation events, first set IsManipulationEnabled to true (some mouse events will not happen after that) and than you can subscribe to the following events:
ManipulationStarted,
ManipulationDelta,
ManipulationCompleted.

This way you do not need to do the complicated 3D hit testing any more. You can simply subscribe to mouse events. This way you the code is much simpler and better organized.

It is also possible to exclude some Visual3D objects from hit testing with RegisterExcludedVisual3D(Visual3D) method. This means that when the ray from the mouse will hit the excluded Visual3D, it will not produce a hit test but will continue with checking if there are any objects behind. To remove the Visual3D form exclusion list, call the RemoveExcludedVisual3D(Visual3D) method (exclusion list is also cleared when called ResetEventSources3D method).

This can be very useful for example when we are drawing an object or 3D line at the position of mouse hit. Without an option to exclude the drawn object or 3d line, we would get many MouseEnter and MouseLeave events because mouse will sometimes hit the back object and sometimes the drawn object or 3D line.

Important:
It is highly recommended not to have more than one EventManager3D object per Viewport3D. Having multiple EventManager3D object can greatly reduce the performance because each time the Viewport3D camera is changed, each EventManager3D must perform a full 3D hit testing from the current mouse position. This operation is very CPU intensive and can affect performance when there are many 3D objects in the scene. When multiple EventManager3D object are defined, then the 3D hit testing is performed multiple times. Therefore it is recommended to have only one EventManager3D object per Viewport3D.

It is also recommended to remove registered event sources after they are not used any more. This can be done with RemoveEventSource3D(BaseEventSource3D) method.

UpdateHitObjects(MouseEventArgs) method can be called to manually update the 3D objects that are behind the current mouse position. This is useful when the camera is changed without moving the mouse. In this case the 3D objects behind the mouse position can change. If this happens the MouseEnter, MouseLeave and other event handlers will be called from the UpdateHitObjects method.

Usage:

To use EventManager3D create an instance of EventManager3D class and pass TargetViewport3D as constructor parameter.

Than if you need to subscribe events on Model3D create ModelEventSource3D and set its TargetModel3D to the Model3D. Now you can subscribe to the events on the created ModelEventSource3D. The last thing to do is to register the ModelEventSource3D to the EventManager3D with the RegisterEventSource3D(BaseEventSource3D) method on the EventManager3D.

If you need to subscribe to events on Visual3D use VisualEventSource3D instead of ModelEventSource3D.

It is also possible to subscribe the same events on more Model3D or Visual3D objects. In this case use MultiModelEventSource3D or MultiVisualEventSource3D.

If you have read 3D objects with Ab3d.Reader3ds or have the 3D objects already organized in a Dictionary with name object pairs, you can define the objects or visuals by their name. In this case the NamedObjects dictionary must be set on EventManager3D.

Examples

The following sample shows how to subscribe to click event on MyBoxVisual3D object and change the material on the object.

private bool _isSelected;
Ab3d.Utilities.EventManager3D _eventManager;

private void SubscribeEvents()
{
    Ab3d.Utilities.VisualEventSource3D eventSource3D;

    _eventManager = new Ab3d.Utilities.EventManager3D(MyViewport3D);

    eventSource3D = new Ab3d.Utilities.VisualEventSource3D();
    eventSource3D.TargetVisual3D = MyBoxVisual3D;
    eventSource3D.MouseClick += new Ab3d.Common.EventManager3D.MouseButton3DEventHandler(eventSource3D_MouseClick);

    _eventManager.RegisterEventSource3D(eventSource3D);
}

void eventSource3D_MouseClick(object sender, Ab3d.Common.EventManager3D.MouseButton3DEventArgs e)
{
    Material newMaterial;

    if (_isSelected)
        newMaterial = new DiffuseMaterial(Brushes.Blue);
    else
        newMaterial = new DiffuseMaterial(Brushes.Red);

    MyBoxVisual3D.Material = newMaterial;

    _isSelected = !_isSelected;
}
See Also