简体   繁体   English

WPF:查找部分位于 2D 矩形内的 3D 视觉效果

[英]WPF: Finding 3D-visuals that are partially inside a 2D rectangle

I am making a WPF program with the possibility to modify data graphically in 3D.我正在制作一个 WPF 程序,可以在 3D 中以图形方式修改数据。 In order to give the user the option to select multiple graphical objects at the same time, I want to implement a selection rectangle.为了让用户可以同时选择 select 多个图形对象,我想实现一个选择矩形。 (Just like the one in windows explorer.) A common functionality in programs like this one is to have 2 different functions for the selection rectangle, and that the user can somehow choose which of the methods should be used. (就像 windows 资源管理器中的那个。)像这样的程序中的一个常见功能是为选择矩形提供 2 个不同的功能,并且用户可以以某种方式选择应该使用哪种方法。

  1. Any object that is partially or completely inside the rectangle is selected.任何部分或完全位于矩形内的 object 都会被选中。
  2. Only objects that are completely inside the rectangle are selected.仅选择完全位于矩形内的对象。

The 2nd method is straight forward by using the bounding box of each object, and check if it is inside the rectangle.第二种方法是直接使用每个 object 的边界框,并检查它是否在矩形内。 The 1st one on the other hand, seems to be quite some work.另一方面,第一个似乎是相当多的工作。 All my graphical objects are complicated 3D figures, and can be rotated by the user in any way.我所有的图形对象都是复杂的 3D 图形,并且可以由用户以任何方式旋转。 At the moment I am unable to find any other way than checking if any of the triangles in the mesh of any of the objects cross my 2D rectangle, and that can be quite time consuming.目前,除了检查任何对象的网格中的任何三角形是否穿过我的 2D 矩形之外,我找不到任何其他方法,这可能非常耗时。

I have little experience with WPF 3D, but I have done this before in OpenGL.我对 WPF 3D 几乎没有经验,但我之前在 OpenGL 中做过这个。 Then I could tell OpenGL to draw a specific area of the screen, and the collect a list of objects that was visible in the specific area.然后我可以告诉 OpenGL 绘制屏幕的特定区域,并收集在特定区域中可见的对象列表。 All I needed to get the functionality I wanted was about 5 lines of code.获得所需功能所需的只是大约 5 行代码。

I guess my question is this:我想我的问题是这样的:

  1. Is there a way to do this with WPF 3D, similar to the OpenGL approach?有没有办法用 WPF 3D 来做到这一点,类似于 OpenGL 方法?
  2. If not, is there any other smart way to find all objects (Visual3D) in a viewport that is partially behind a 2D rectangle?如果没有,是否有任何其他智能方法可以在部分位于 2D 矩形后面的视口中查找所有对象(Visual3D)?

I refuse to believe I am the only one with this kind of problem, so I hope a clever mind can point me in the right direction.我拒绝相信我是唯一一个有这种问题的人,所以我希望聪明的头脑能给我指明正确的方向。

Regards, Sverre问候, 斯韦雷


Thank you for your answer!谢谢您的回答!

The 2D-rectangle is just in front of the camera and extending infinitely forward.二维矩形就在相机的前面,并无限向前延伸。 I want to get any object that is partially or completely inside that frustum.我想获得部分或完全位于该截锥体内的任何 object。

The camera we are using is an orthographic or perspective projection camera ( System.Windows.Media.Media3D.ProjectionCamera ).我们使用的相机是正交或透视投影相机( System.Windows.Media.Media3D.ProjectionCamera )。 The reason we are not using the matrix camera is that we are using a 3rd party tool that does not support the matrix camera.我们不使用矩阵相机的原因是我们使用了不支持矩阵相机的第三方工具。 But I am sure there is a way to get the matrix from a projection camera as well, so that is hopefully not the problem.但我确信也有一种方法可以从投影相机中获取矩阵,所以希望这不是问题。

In theory your solution sounds like just what we need, but I am not sure how to proceed.从理论上讲,您的解决方案听起来正是我们所需要的,但我不确定如何进行。 Do you have any links to sample-code, or can you give some more hints on how to actually implement this?您是否有任何指向示例代码的链接,或者您能否就如何实际实现这一点提供更多提示?

Btw: Since we are working with WPF, we do not have direct access to DirectX.顺便说一句:由于我们正在使用 WPF,因此我们无法直接访问 DirectX。 At least that's what we have concluded after some research.至少这是我们经过一些研究得出的结论。 You mention use of the z-buffer, which we haven't been able to access through WPF.您提到使用 z 缓冲区,我们无法通过 WPF 访问它。 If you know a way to access the z-buffer, it's greatly appreciated, This is of-topic, but we have struggled to disable the z-buffer for some time, but have given up…如果您知道访问 z-buffer 的方法,非常感谢,这是主题,但我们一直在努力禁用 z-buffer,但已经放弃了……

Best regards, Sverre最好的问候, 斯韦雷

Is your intersection region a 2d rectangle or a frustrum based at a 2d rectangle and extending infinitely forward (or perhaps to some clipping limit)?您的相交区域是二维矩形还是基于二维矩形并无限向前延伸(或者可能到某个剪切限制)的截锥体? If it can be construed as a viewing frustrum, then you can leverage the existing capabilities of the graphics system to render the scene using a Camera View and Projection that corresponds to your originating rectangle, with all lighting and shading disabled and colors chosen specifically to 'tag' the different objects in your scene.如果它可以被解释为视锥体,那么您可以利用图形系统的现有功能使用与您的原始矩形相对应的相机视图和投影来渲染场景,禁用所有照明和阴影,并专门选择 colors标记'场景中的不同对象。 This means you can use the graphics hardware to perform the clipping/projection as a 'rendering' operation, then simply enumerate the pixel values as 'tags' to determine the objects present in the rectangular view.这意味着您可以使用图形硬件将剪切/投影作为“渲染”操作执行,然后简单地将像素值枚举为“标签”以确定矩形视图中存在的对象。

If you need to restrict selection to an actual 2d slice (or a very shallow frustrum), you can use the Z-buffer (if you can get access to it) to exclude tagged pixels that are outside the Z range of your desired selection frustrum.如果您需要将选择限制为实际的 2d 切片(或非常浅的平截头体),您可以使用 Z 缓冲区(如果可以访问它)来排除在所需选择平截头体的 Z 范围之外的标记像素.

The nice thing about this approach is that you probably already have the Camera matrix (it's the same matrix used for your window for selection) and only need to change the Projection matrix to be a sub-set of the viewing window.这种方法的好处是您可能已经有了相机矩阵(它与用于选择的 window 的矩阵相同)并且只需将投影矩阵更改为查看 window 的子集。

A 'smart' way would be to transform the rectangle into a box using the Camera's matrix一种“聪明”的方法是使用相机的矩阵将矩形转换为一个盒子

And then do a intersection of all the objects and the box.然后做一个所有对象和盒子的交集。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM