Scenekit Pan 2D仅水平翻译为正交3D

菲尔·尼德斯切德

我在3D编程方面遇到了一些数学问题,希望您能为我提供帮助!

我正在尝试使用带有等距角度的Scenekit创建3D游戏。

这段代码创建了我的正交摄影机:

var cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.name = "Camera"
cameraNode.position = SCNVector3Make(-5.0, -5.0, 10.0)
cameraNode.eulerAngles = SCNVector3Make(PI / 3.0, 0.0, -PI / 4.0)
cameraNode.camera?.usesOrthographicProjection = true
cameraNode.camera?.orthographicScale = 7.0
scene.rootNode.addChildNode(cameraNode)

现在,我想使用平移手势移动相机,从而产生滚动感。为此,相机不应垂直移动,而只能水平移动。屏幕上的触摸位置和3D世界中未投影的位置在移动时应保持不变。

我考虑过将2D转换为3D差异并忽略垂直分量。该代码实际上有效,几乎可以产生所需的结果,但是速度不正确。如果平移,相机似乎会加速并且无法正确反应:

var previousTranslation = CGPointMake(0.0, 0.0)

func pan(gesture: UIPanGestureRecognizer)
{
    let view = self.view as SCNView
    let translation = gesture.translationInView(view)
    let location = gesture.locationInView(view)

    let diffTrans = translation - previousTranslation
    previousTranslation = translation

    let cameraNode = scene.rootNode.childNodeWithName("Camera", recursively: false)

    let worldPointTrans = view.unprojectPoint(SCNVector3Make(-Float(diffTrans.x), -Float(diffTrans.y), 0.0))
    let worldPoint0 = view.unprojectPoint(SCNVector3Make(0.0, 0.0, 0.0))

    var diff = worldPointTrans - worldPoint0
    diff.x = diff.x / Float(cameraNode!.camera!.orthographicScale)
    diff.y = diff.y / Float(cameraNode!.camera!.orthographicScale)
    diff.z = 0
    cameraNode?.position += diff
}

有人知道忽略垂直轴的将屏幕平移计算为水平3D平移的复杂方法吗?

先感谢您 :)

编辑:平移现在可以进行水平平移了。但不是垂直的,因为我将z轴上的差异设置为零。

菲尔·尼德斯切德

我找到了自己的解决方案。

我正在计算手势开始位置(P1-P2)处的光线和平移位置(Q1-Q2)处的光线。现在,我有两条光线,让它们都与XY平面相交以接收点P0和Q0

P0和Q0的差是未投影的平移。

这项技术也应该适用于非正交相机,但我尚未对此进行测试。

在我看来,它是可行的,但如果有人能数学上证实这一假设,我将很高兴读到:)

这是代码:

 var previousLocation = SCNVector3(x: 0, y: 0, z: 0)

func pan(gesture: UIPanGestureRecognizer)
{
    let view = self.view as SCNView
    let translation = gesture.translationInView(view)

    let location = gesture.locationInView(view)
    let secLocation = location + translation

    let P1 = view.unprojectPoint(SCNVector3(x: Float(location.x), y: Float(location.y), z: 0.0))
    let P2 = view.unprojectPoint(SCNVector3(x: Float(location.x), y: Float(location.y), z: 1.0))

    let Q1 = view.unprojectPoint(SCNVector3(x: Float(secLocation.x), y: Float(secLocation.y), z: 0.0))
    let Q2 = view.unprojectPoint(SCNVector3(x: Float(secLocation.x), y: Float(secLocation.y), z: 1.0))

    let t1 = -P1.z / (P2.z - P1.z)
    let t2 = -Q1.z / (Q2.z - Q1.z)

    let x1 = P1.x + t1 * (P2.x - P1.x)
    let y1 = P1.y + t1 * (P2.y - P1.y)

    let P0 = SCNVector3Make(x1, y1,0)

    let x2 = Q1.x + t1 * (Q2.x - Q1.x)
    let y2 = Q1.y + t1 * (Q2.y - Q1.y)

    let Q0 = SCNVector3Make(x2, y2, 0)

    var diffR = Q0 - P0
    diffR *= -1

    let cameraNode = view.scene!.rootNode.childNodeWithName("Camera", recursively: false)

    switch gesture.state {
    case .Began:
        previousLocation = cameraNode!.position
        break;
    case .Changed:
        cameraNode?.position = previousLocation + diffR
        break;
    default:
        break;
    }
}

红色是屏幕翻译,蓝色是世界翻译

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

SceneKit –在3D对象上绘图

来自分类Dev

SceneKit –在3D对象上绘图

来自分类Dev

将SpriteKit SKScene overlaySKScene中的2D点映射到SceneKit SCNScene中的3D点

来自分类Dev

Swift 3 - SceneKit 获取 3d 模型比例值

来自分类Dev

使用SceneKit在3D空间中旋转SCNode对象

来自分类Dev

如何在Scenekit中使用3D模型?

来自分类Dev

iPad Air 2上的SceneKit崩溃

来自分类Dev

Openlayers 3 ol.animation.pan是否超时?

来自分类Dev

Openlayers 3 ol.animation.pan是否超时?

来自分类Dev

如何使angular2同时收听pinchmove和pan事件

来自分类Dev

在SceneKit中绘制3D弧线和螺旋线

来自分类Dev

我可以为SceneKit使用哪些3D建模程序?

来自分类Dev

使用粒子系统爆炸3D文本(Swift-SceneKit)

来自分类Dev

Scenekit节点在3D空间中的旋转和移动

来自分类Dev

在SceneKit中加载巨大的动画3D模型会导致内存问题

来自分类Dev

SceneKit和Swift的3D地球大小调整和缩放问题

来自分类Dev

如何根据SceneKit中的某些变量控制3D对象的位置(或旋转)?

来自分类Dev

如何只允许3D模型的X轴旋转?(SceneKit)

来自分类Dev

如何在 iOS 中使用 Scenekit 保存 3D 场景?

来自分类Dev

SceneKit中的正交相机和缩放控件

来自分类Dev

Accelerate / Scenekit框架:: 3d和4d向量的数学矩阵/向量库在哪里?

来自分类Dev

Scenekit的SCNAction仅执行一次操作

来自分类Dev

SceneKit 仅部分显示了一个大的旋转 SCNPlane

来自分类Dev

SceneKit Swift3 编译器错误

来自分类Dev

SceneKit基础

来自分类Dev

SceneKit纹理

来自分类Dev

SceneKit SCNTransformConstraint

来自分类Dev

SceneKit:SCNRenderingAPI

来自分类Dev

当更新父组件的状态时,Pan Responder仅触发一次?

Related 相关文章

热门标签

归档