2017-09-13 95 views
7

我使用ARKit来显示3D对象。我设法将节点放置在用户面前的真实世界中(也就是相机)。但是,当我放下它们时,我无法让它们面对相机。ARKit将SCNNode面向相机

let tap_point=CGPoint(x: x, y: y) 
let results=arscn_view.hitTest(tap_point, types: .estimatedHorizontalPlane) 
guard results.count>0 else{ 
    return 
} 
guard let r=results.first else{ 
    return 
} 

let hit_tf=SCNMatrix4(r.worldTransform) 
let new_pos=SCNVector3Make(hit_tf.m41, hit_tf.m42+Float(0.2), hit_tf.m43) 

guard let scene=SCNScene(named: file_name) else{ 
    return 
} 
guard let node=scene.rootNode.childNode(withName: "Mesh", recursively: true) else{ 
    return 
} 
node.position=new_pos 
arscn_view.scene.rootNode.addChildNode(node) 

节点位于摄像机前方的平面上。但他们都在朝着同一个方向看。我想我应该轮换SCNNode但我没有设法做到这一点。

回答

0

即使照相机移动,您是否希望节点始终面向相机?这就是SceneKit constraints的用途。 SCNLookAtConstraintSCNBillboardConstraint可以让节点始终指向摄像头。

你想让节点在放置时面对相机,但是保持不动(这样你可以移动相机并看到它的背面)?有几种方法可以做到这一点。一些涉及有趣的数学,但更简单的方法来处理它可能只是设计你的3D资产,使“前”总是在正Z轴方向。根据相机变换设置放置对象的变换,其初始方向将与相机匹配。

+0

第二个:)当我放置它时,我希望节点面对相机,然后将它保留在此处(并且可以移动)。 –

+0

当你说>设计你的3D资产时,我不明白你的意思,所以“前”总是在正Z轴方向。我有一个dae文件,我将其转换为xCode中的scn。节点位置是(0,0,0)。但我也把相机放在(0,0,0,0.9),以便将物体放在我面前。确定相机是否在节点层次结构中(我猜可能是一个子节点)可能很重要。 –

+0

当我放下它们时,节点总是位于相机的正前方,它们是可见的(没有在相机后面)。如果我在房间中移动并放下几个节点,它们都是相似的。当我放下第一个节点时,它正在“看着我”。但不是下一个。我不知道我说的是否清楚...:/ –

1

首先,让相机的旋转矩阵:

let rotate = simd_float4x4(SCNMatrix4MakeRotation(sceneView.session.currentFrame!.camera.eulerAngles.y, 0, 1, 0)) 

然后,结合矩阵:

let rotateTransform = simd_mul(r.worldTransform, rotate) 

最后,应用转换到您的节点,铸塑SCNMatrix4:

node.transform = SCNMatrix4(rotateTransform) 

希望有帮助

+0

什么是“r.worldTransform”指的是什么?我没有看看它可能是什么 –

+0

“r”只是TC的变量result.first,意思是用户在屏幕上的第一个触摸点(我假设在他们的touchesBegan方法中),文档最好解释它,worldTransform是“The转换矩阵,它定义了交点的旋转,相对于世界的平移和缩放。“ – modium

+0

啊,好的,我得到了世界变换是/的,只是不是从哪里来的,谢谢! –