Can a 3D object that is totally enveloped by another trigger mouse events?
#1
I have a requirement to handle mouse events of an object that is visible inside of a semitransparent enclosure. I have some ideas on how to tackle this, but thought I would ask here to see if I have missed a simpler more elegant solution.
#2
If you want to use EventManager3D for handling the mouse events, then you can exclude some object from being processed in hit testing with using RegisterExcludedVisual3D method.

This is used in the EventManagerDragSample where the semi-transparent plane is excluded from hit testing with the following line:
_eventManager.RegisterExcludedVisual3D(TransparentPlaneVisual3D);


If you are using standard WPF hit testing, then you can use the VisualTreeHelper.HitTest method that takes HitTestFilterCallback and HitTestResultCallback delegates as parameter - in HitTestFilterCallback you can filter which objects are hit tested, in HitTestResultCallback you can return HitTestResultBehavior.Continue from the delegate method to continue hit testing along the ray.


When using the hit testing in Ab3d.DXEngine, you can set the DXScene.DXHitTestOptions.HitTestFilterCallback delegate to filter which objects are hit tested.
Andrej Benedik
#3
[quote pid='5306' dateline='1553501352']
Thank you for your prompt reply. I realize now that I failed to mention that I need the enclosing object to also react to mouse events.

I have attached an image as an example. What I need is that the pyramid can handle mouse events and also if the mouse happens to be over the sphere is there anyway to detect the sphere as an object that is internal to the pyramid?

   

[/quote]
#4
You can call the VisualTreeHelper.HitTest method and specify the HitTestResultCallback parameter - there cast the HitTestResult to RayMeshGeometry3DHitTestResult and you will be able to get all the hit Visual3D and Model3D objects that are under the mouse.

If you are using Ab3d.DXEngine you can also call the DXViewportView.GetAllHitObjects method and get all the objects behind the mouse (if you have a complex scene with a lot of 3D objects or with many triangles, then this is much faster then the WPF code above)
Andrej Benedik
#5
Here is a code snippet that you can use:

Code:
private void CheckHitObjects(Point mousePosition)
{
    var pointParams = new PointHitTestParameters(mousePosition);

    VisualTreeHelper.HitTest(MainViewport3D, null, HitTestResultHandler, pointParams); // no filer delegate is used

    // if you stored the hit visuals or models (in the HitTestResultHandler), you can check them here
}

private HitTestResultBehavior HitTestResultHandler(HitTestResult result)
{
    hitResult = result as RayMeshGeometry3DHitTestResult;

    if (hitResult == null)
        return HitTestResultBehavior.Stop;
        
    // You can check (or store for later check) the hit Visual3D or GeometryModel3D
    var visualHit = lastRayHitResult.VisualHit;
    var hitModel3D = lastRayHitResult.ModelHit as GeometryModel3D;
    
    // ...
    
    if (continueHitTesting)
        return HitTestResultBehavior.Continue;
        
    return HitTestResultBehavior.Stop;
}
Andrej Benedik
#6
I cannot thank you enough for fast tracking my learning. I am well on my way to meeting my requirements.
  


Forum Jump:


Users browsing this thread:
1 Guest(s)