Mic*_*hop 13 opengl 3d mouse-picking scenekit
我在SceneKit中设置了一个场景,并发出了一个命中测试来选择一个项目.但是,我希望能够在场景中沿着平面移动该项目.我继续接收鼠标拖动事件,但不知道如何将这些2D坐标转换为场景中的3D坐标.
我的情况很简单.摄像机位于0,0,50并指向0,0,0.我只想沿z平面拖动我的对象,其z值为0.
命中测试就像魅力一样,但是如何将拖动事件中的鼠标点转换为我拖动的3D对象的场景中的新位置?
ric*_*ter 22
您不需要使用不可见的几何体 - Scene Kit可以执行您需要的所有坐标转换,而无需点击测试不可见的对象.基本上,您需要在2D绘图应用程序中执行与移动对象相同的操作:找到mouseDown:位置和对象位置之间的偏移量,然后对于每个mouseMoved:,将该偏移量添加到新鼠标位置以设置对象的新位置.
这是你可以使用的方法......
按照您正在进行的方式测试初始点击位置.这会为您提供一个SCNHitTestResult标识您要移动的节点的对象,对吧?
检查该worldCoordinates命中测试结果的属性.如果要移动的节点是场景的子节点rootNode,则这些是您想要查找偏移的矢量.(否则,您需要将其转换为要移动的节点的父节点的坐标系 - 请参阅convertPosition:toNode:或convertPosition:fromNode:.)
您将需要此点的参考深度,以便您可以比较mouseMoved:它的位置.使用projectPoint:你在步骤2(在3D场景中的一个点)返回到画面的空间得到了向量转换-这让你一个三维向量,其x和y坐标是屏幕空间点而z坐标告诉你该点相对于剪切平面的深度(0.0位于近平面上,1.0位于远平面上).保持此z坐标以供使用mouseMoved:.
position从步骤2中获得的鼠标位置向量中减去要移动的节点.这将获得鼠标单击对象位置的偏移量.抓住这个向量 - 你需要它直到拖动结束.
在mouseMoved:,从新鼠标位置的屏幕坐标和在步骤3中获得的深度值构建新的3D矢量.然后,使用unprojectPoint:- 这是场景的3D空间中的鼠标位置(相当于你从命中测试得到的,但不需要"击中"场景几何).
将步骤3中获得的偏移量添加到步骤5中获得的新位置 - 这是position将节点移动到的新位置.(注意:对于实时拖动看起来正确,你应该确保这个位置变化没有动画.默认情况下,当前的持续时间SCNTransaction是零,所以你不必担心这个,除非你已经改变它. )
(这有点偏离我的头脑,所以你应该仔细检查相关的文档和标题.你可以通过一些数学来简化这一点.)