AB4D Forum

Full Version: Hitdetection problem
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi,

I got next problem (I will explain it by an example):

I got 2 models generated by next code:

Code:
var model1 = Line3DFactory.CreateMultiLine3D(model1Edges, 0.5, Color, LineCap.Flat, LineCap.Flat, ViewPort);

Code:
var model2 = Line3DFactory.CreateMultiLine3D(model1Edges, 0.5, Color, LineCap.Flat, LineCap.Flat, ViewPort);

In the sceneControl I add these models to the Children collection of the ViewPort

Code:
SceneControl.MainViewport.Children.Add(model1);
SceneControl.MainViewport.Children.Add(model2);

As I register events on my objects to perform hitdection:

Code:
var eventSource = new MultiModelEventSource3D();
            eventSource.MouseMove += EventSourceOnMouseMove;
            eventSource.MouseEnter += EventSourceMouseEnter;
            eventSource.MouseLeave += EventSourceMouseLeave;
            eventSource.MouseClick += EventSourceMouseClick;

            eventSource.IsDragSurface = false;
            eventSource.CustomData = sceneObject;
            eventSource.TargetModelNames = sceneObject.Key;

I also keep these objects at the namedObjects collection of the EventManager:

Code:
_eventManager = new EventManager3D(MainViewport);
_eventManager.NamedObjects.Add(sceneObject1.Key, sceneObject1.Model3D.Content);
_eventManager.NamedObjects.Add(sceneObject2.Key, sceneObject2.Model3D.Content);

I got a treeControl where I select my active model.
As I select the active model ONLY this model his eventSource is registered on the eventManager.

Now my problem is the next:
As model2 lays in model1.
If model2 is active and so only model2 his eventSource is registered, this event will never be triggered if model1 is still drawn in the scene.

Sample image:

http://s28.postimg.org/56z4lnsi5/example.png

How to fix this?

Thanks in advance!
I suspect that something is wrong with registering the EventSources to EventManager3D (you have not posted the code that does that).

With MultiModelEventSource3D it is very easy to change the selected objects. All you need to do is:

- first add object names to _eventManager.NamedObjects (you already do that).

- than register the MultiModelEventSource3D with EventManager3D.RegisterEventSource3D method

After that you only need to change the TargetModelNames on MultiModelEventSource3D and set it to the name of the selected object (you can also specify more objects with separating the names with ,; or space). After that the events will be triggered only on the objects whose names are specified in TargetModelNames.
As I set the Active model I do the following:

Reset the events on the eventManager
Code:
_eventManager.ResetEventSources3D();

Get the event from the Active model and register it.
Code:
var eventSourceToRegister = _dictionarySceneObjectToEventSource[sceneObject.Key];
_eventManager.RegisterEventSource3D(eventSourceToRegister);

Thanks in advance!

PS: I have to say this:

If I draw the "Wireframe" I also draw A solid TransparentMesh with it to do Polygon hit detection with some of my own code.

This is how to Model is realy build:

Code:
var myModel3DGroup = new Model3DGroup();

                    //Solid
                    _solidModel = new GeometryModel3D
                    {
                        Geometry = GetMeshGeometry(roughModel.MeshBoundary.TriangleMesh),
                        Material = new DiffuseMaterial(Brushes.Transparent)
                    };
                    myModel3DGroup.Children.Add(_solidModel);

                    //WireFrame
                    _edges = model.MeshBoundary.PolygonMesh.GetEdgeList();
                    
                    _wireframeModelGroup = new Model3DGroup();
                    var model1 = Line3DFactory.CreateMultiLine3D(model1Edges, 0.5, Color, LineCap.Flat, LineCap.Flat, ViewPort);
                    _wireframeModelGroup.Children.Add(model1);

                    myModel3DGroup.Children.Add(_wireframeModelGroup);
I understand now.

You need to use the RegisterExcludedVisual3D method on EventManager3D to add a Visual3D from blocking hit testing. Currently it is not possible to register Model3D for exclusion, so you will need to create a Visual3D that will hold you transparent and wireframe models.

This can be seen in the EventManagerDragSample sample where object can be moves behind the semi-transparent plane.
I think if I do this I will have next problem:

I was drawing my solid transparentMesh to do the detection on. And If I exclude this one my detection would fall away ?

---------

Cause I'm working with the e.RayHitResult of the solid transparentMesh

Thanks in advance!
I was thinking that you would define 2 ModelVisual3D objects - each would have wireframe and transparent mesh. This would require using VisualEventSource3D instead of MultiModelEventSource3D (I would create two VisualEventSource3D - one for each ModelVisual3D).

So when you would change selected object, you would register the VisualEventSource3D of the selected objects and add other Visuals to exclusion list with RegisterExcludedVisual3D (note that you can use RemoveExcludedVisual3D method to remove the Visual3D from exclusion list).


Another option:
What if you would only add one transparentMesh to the Viewport3D - one the one that you would like to be detected. The other transparentMeshes would be removed from Viewport3D?
Ok It clearly worked out thanks!

I got only one question left now:

As I detect my model2 now I'm drawing a "WireFrame" on the polygon of Model2 which I'm hitting.

As this is under the TransparentMesh of Model1 (which we talked about) it doesn't shows my "WireFrame" on the polygon I hit on Model2.

This is a transparency problem I think?

How can I fix this?

example:

http://s22.postimg.org/rjecjm3yp/example2.png

Thanks for the support!
The transparent objects must be drawn after the solid objects - WPF is drawing objects in the same order as they are added to Viewport3D Childrent. And if you have more transparent objects, you need to sort them by camera distance - those that are farther away must be drawn first.

If you have "packed" the wireframe and transparentMesh into ModelVisual3D objects, you will have to "unpack" them so that all wireframe objects will be rendered first and than the transparentMesh (I should have predicted the transparency problems before, but I am working on stg. else and do not take enough time to solve your problems).

I hope this will solve you problems.