一个基本的旋转问题 - 如何耦合 2 个数字(一个盒子/立方体,其中有一个球体,在立方体的任何地方,但在中心),以便这 2 个旋转耦合(这就是为什么我不希望球体在立方体的中心)透视。
换句话说,当我用鼠标旋转立方体并将球体“带”到更靠近前面(例如,旋转 180 度)时,视角会相应改变,球体在视觉上会变大(与背部)?
问了几位 ScalaFX 专家 - 他们都说这是一个非常好的问题,并建议在此处发布。
干杯:
扎尔
>
我不完全确定您要做什么,但是您可以通过对包含所有这些对象的变换应用Rotate
变换来旋转多个对象。Group
如果您只想旋转一些对象,而不是所有对象,则必须构建场景,使被旋转的对象有一个共同的父对象Group
- 没有任何非旋转对象属于它。Rotate
对该父对象应用变换Group
也会旋转其所有子对象。旋转将围绕该 parent 的起源Group
。
更新:我忘了提到如何解决透视问题。场景中的 3D 对象不受透视图的直接影响,因为透视图是场景渲染方式的属性。此渲染由Camera
对象执行。要使用透视渲染场景(与JavaFX / ScalaFX中提到的正交或平行相反),请将 a 添加到场景并使用该相机查看场景。有关这方面的更多信息,请参阅以下内容:JavaFX 3D 图形入门:相机PerspectiveCamera
更新 2:我在 GitHub 上创建了一个要点,其中包含一个完整的程序来执行此操作。
更新 3:使盒子透明并在盒子内移动球体。现在鼠标左键/主键在拖动时旋转框+球体;鼠标右键/辅助鼠标按钮将相机小车移向/远离盒子,相应地改变视角。
更新 4:所以,如果我理解正确的话,您希望转换 3D 场景中的形状,使它们看起来好像已应用透视。我有这个权利吗?
如果是这样,这不是“内置”功能的原因如下所述。如果您已经知道所有这些,请原谅我,顺便说一句 - 我只是想提供一个全面的答案。:-)
简而言之,将场景本身变形以显示透视的样子是一个非常不寻常的要求。这就是我所知道的任何 3D 系统都没有内置功能的原因。
假设您希望继续 - 使用JavaFX - 请记住以下几点:
Box
& Sphere
)Cylinder
可以变形以表示它们的透视图。您必须使用TriangleMesh
和MeshView
对象构建形状(前者捕获形状的几何形状,后者允许将其视为 3D 形状)。TriangleMesh
实例中的顶点以适当地变形场景。如果您需要能够更改视点或旋转盒子和球体,那么这些更改需要是动态的,以便计算的顶点坐标对变化的视点和/或旋转做出反应。由于高水平透视膨胀的鱼眼效应,您可能需要比预期更多的顶点。PerspectiveCamera
渲染场景,否则它会将场景视为未调整并应用第二级透视,从而破坏您精心计算的变形。然后,您将需要使用ParallelCamera
来生成场景的正交视图。ParallelCamera
3D 场景的支持还很不成熟。(ParallelCamera
主要用于渲染 2D 场景,例如对话框、按钮、菜单、滑块等。)您可能会发现在实践中很难使用。PerspectiveCamera
(您可以通过使用非常窄的视野并将相机从场景中移开一段距离来近似正交投影。您还需要调整剪切平面以避免图像消失。)总之,我想说你打算做的事情远非微不足道,而且实现远远超出了StackOverflow答案的范围。祝你好运!
麦克风:
抱歉耽搁了,我正在为一个完全不同的应用领域的客户完成一些事情,并从我的“教学视角”玩具中抽离出来......
刚刚收到新答案的通知并快速查看 - 我立即注意到的一件事是球体在透明框的外部而不是内部(尚未查看代码)。
我实际上期望的是一个“内置”透视“参数”(在旋转变换中,或在场景定义中,或独立功能 - 在一种方式中是另一种方式),它允许根据不同的方式渲染不同的透视图例如,在底部的 2 个(最初)平行的相对边缘之间的角度上。我当然理解,实际上它取决于视点位置,您不能“允许”强行改变这个角度,但这里的目标只是 3D 场景中的“因果”玩具。
控制相机不会允许这样做,因为它非常平滑地施加透视(就像在现实生活中一样),而不是让孩子直接控制边缘并立即看到她的动作如何改变透视,而不是玩弄观点。
正如原始问题中提到的,我希望有一个如下所示的功能(我希望它内置在一个明智的 3D 产品中,因为它是如此基本,而不是强迫我或你手动制作一些从一开始就应该存在的代码 - 透视图只是一个基本的基础,希望在下一个版本中以某种形式呈现):
def doPersepctive( myBox: MyBoxContainer, angle: Int, viewPoint: Point): Int = {
// 以一种由 myBoxContainer (最初)平行边缘之间的“角度”定义的方式呈现透视外观,从 viewPoint Point (3D)。// 旋转 MyBoxContainer 边界内的所有内容。// 当然,角度越大,后面的球体就越小。// 在 mouseEvent 之后返回 rotateAngle 以便稍后启用自动重播,因此 // 孩子可以检查她的动作并查看这些动作的效果。}
Tnx 再次为您输入,我一定会看一下代码,并回复 - 但您看到上面的一般图片。再次抱歉延迟:
Z
>
麦克风:
这更像是原意——虽然我在第一次尝试中也发现了优点,实际上。
我使球体(在第一个版本中)透明(通过diffuseColor = Color.web("#ffff0080")),所以现在她可以同时使用这两个版本,从孩子的角度来看,两者都非常相似(意味着其中一个对象是透明的,而且这些版本中的对象不同)。
现在 - 我试图让 BOX 透明(球体在外面)但我失败了 - 有没有理由?换句话说,试图使通过“后面”的对象可见?一个透明物体在另一个透明物体后面经过,可以这么说吗?
在第二个版本中,我也看不到“物体后面”,这意味着我看不到盒子的边缘在球体后面经过。不仅如此——即使它不在球体后面(但只能在盒子的正面后面),我也看不到后面的边缘!
从某种意义上说,我的问题是“可以使两个对象都透明”-我想这与我要问的问题最接近。可能具有不同的“透明度百分比”,但仍然是透明的……</p>
再次Tnx:
扎尔
>
是的,迈克 - 你的回答是完全相关的,我确实接受了当前 ScalaFX 实现的深思熟虑解释的缺点。如果我需要“点击”某个地方正式标记这个,请告诉我 - 我是这个组的新手,真的不知道手续。
再次Tnx:
扎尔
> 顺便说一句,如果可以将 Sphere 添加为 Box 的子项,那么您... <
这是不可能的,但我可以在运行时而不是在编译时添加球体吗?换句话说,是否有一个“addObject”在孩子玩盒子 1 分钟后添加球体,在运行程序 1 分钟后,球体出现。在这里看不到类似的东西:
http://www.scalafx.org/api/8.0/index.html#package
可能是我错过了什么?
扎尔
>
我预计在旋转变换期间有一个参数可以控制透视,但找不到。示例问题已明确定义 - 您有一个 BOX/CUBE 和一个较小的球体;现在,当您旋转 BOX 时,球体将随它旋转,但“透视”,这意味着如果您将球体放在前面,它会随着“透视”相应地看起来(绘制)更大。
扎尔
>