10-22-2020, 10:36 AM
Hm, maybe you could use 3D hit testing for that job. I have not tried that before but maybe this will work.
So, if you do a ray hit testing of a 3D object that has some volume (is not a plane), then you should get an even number of hit results (2, 4, 6, ...). On the first hit, the ray enters the object, on the second hit the ray exits the object. If there are more results, then on third the object is entered again and then exits.
So if you construct the 3D ray in such a way that the 3D positions that you want to test lies on the ray, then you can check if it on that part of the ray that is inside the object (is between the first and second, or third or fourth, etc. hit test result).
If you are using DXEngine that you can get all the hit results with (testPosition is a Vector3 with the position that you need to check):
If you are using only Ab3d.PowerToys then you first need to convert your testPosition into screen position - use Camera1.Point3DTo2D method for that. Then do a standard WPF hit testing that will collect all the hit positions. This is done with calling the VisualTreeHelper.HitTest method and providing a HitTestResultHandler method that will always return HitTestResultBehavior.Continue. Before calling the method create a List<RayMeshGeometry3DHitTestResult> that will store all results. Then in the HitTestResultHandler add a result to the created list. This way the list will be filled when the HitTest is complete.
So when you have all the hit test results, then calculate the distance from the testPosition to the camera. Then go through all the hit results and mark when you are inside the 3D object (see the first paragraph) and check where your testPosition lies (based on the distance to the camera).
Note that the DXEngine position works for any possible testPosition because you can create any possible ray (you can also create some other ray - for example vertical, the important thing is that your testPosition lies on the ray). But with WPF you can only do hit testing with providing screen space coordinates so your testPosition needs to be visible on screen.
So, if you do a ray hit testing of a 3D object that has some volume (is not a plane), then you should get an even number of hit results (2, 4, 6, ...). On the first hit, the ray enters the object, on the second hit the ray exits the object. If there are more results, then on third the object is entered again and then exits.
So if you construct the 3D ray in such a way that the 3D positions that you want to test lies on the ray, then you can check if it on that part of the ray that is inside the object (is between the first and second, or third or fourth, etc. hit test result).
If you are using DXEngine that you can get all the hit results with (testPosition is a Vector3 with the position that you need to check):
Code:
var ray = new SharpDX.Ray(Camera1.GetCameraPosition().ToVector3(), testPosition);
var allHitResults = _mainDXViewportView.DXScene.GetAllHitObjects(ray, _mainDXViewportView.DXScene.RootNode);If you are using only Ab3d.PowerToys then you first need to convert your testPosition into screen position - use Camera1.Point3DTo2D method for that. Then do a standard WPF hit testing that will collect all the hit positions. This is done with calling the VisualTreeHelper.HitTest method and providing a HitTestResultHandler method that will always return HitTestResultBehavior.Continue. Before calling the method create a List<RayMeshGeometry3DHitTestResult> that will store all results. Then in the HitTestResultHandler add a result to the created list. This way the list will be filled when the HitTest is complete.
So when you have all the hit test results, then calculate the distance from the testPosition to the camera. Then go through all the hit results and mark when you are inside the 3D object (see the first paragraph) and check where your testPosition lies (based on the distance to the camera).
Note that the DXEngine position works for any possible testPosition because you can create any possible ray (you can also create some other ray - for example vertical, the important thing is that your testPosition lies on the ray). But with WPF you can only do hit testing with providing screen space coordinates so your testPosition needs to be visible on screen.
Andrej Benedik

