gpt4 book ai didi

ios - 如何使 SCNNode 面向 ARAnchor

转载 作者:搜寻专家 更新时间:2023-10-30 22:10:59 26 4
gpt4 key购买 nike

如何使 ARNode 指向 ARAnchor

我想使用 art.scnassets/ship.scn 显示在屏幕中央并指向我刚刚放置在场景中某处的对象。

/// ViewController Class
func placeObject() {
let screenCentre : CGPoint = CGPoint(x: self.sceneView.bounds.midX, y: self.sceneView.bounds.midY)
guard let hitTestResult = sceneView.hitTest(screenCentre, types: [.featurePoint]).first else { return }

// Place an anchor for a virtual character.
let anchor = ARAnchor(name: identifierString, transform: hitTestResult.worldTransform)
sceneView.session.add(anchor: anchor)
// add to item model
ItemModel.shared.anchors.append((identifierString, anchor)

}

func showDirection(of object: ARAnchor) { // object: saved anchor

if !Guide.shared.isExist {
let startPoint = SCNVector3(0, 0 , -1)
let targetPoint = SCNVector3(object.transform.columns.3.x, object.transform.columns.3.y, object.transform.columns.3.z)

let guideNode = Guide.shared.setPosition(from: startPoint, to: targetPoint)

// add the ship in the center of the view
sceneView.pointOfView?.addChildNode(guideNode)

}
}
/// Guide Class
func setPosition(from start: SCNVector3, to target: SCNVector3) -> SCNNode {
isExist = true
guideNode.position = start
targetPosition = target

// create target node from saved anchor
let desNode = SCNNode()
desNode.position = targetPosition

let lookAtConstraints = SCNLookAtConstraint(target: desNode)
guideNode.constraints = [lookAtConstraints]

return guideNode
}

// MARK: - ARSCNViewDelegate
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
if let name = anchor.name, name.hasPrefix(identifierString) {
// Create 3D Text
let textNode: SCNNode = createNewBubbleParentNode(identifierString)
node.addChildNode(textNode)
}

}

我试过 SCNLookAtConstraint 但它没有按预期工作,有什么建议吗?

demo

最佳答案

我不知道这对你的情况是否有帮助。 (如果不是我会删除我的答案)

所以我遇到了同样的问题。我在两个 SCNVector 对象之间画墙的地方。问题是墙壁是双面的,因此在某些情况下,相机可见的部分会翻转。

就像如果你从两个向量中绘制墙,然后添加另一个具有相同欧拉角的节点(平面节点),添加的节点(平面)是垂直翻转的。

我已经搜索了很多解决方案并尝试了很多东西,但这对我有用。

class func node(from:SCNVector3,
to:SCNVector3,height:Float,needToAlignToCamera:Bool) -> SCNNode {
let distance = MathHelper().getMeasurementBetween(vector1: from, and: to)

let wall = SCNPlane(width: CGFloat(distance),
height: CGFloat(height))
wall.firstMaterial = wallMaterial()
let node = SCNNode(geometry: wall)

// always render before the beachballs
node.renderingOrder = -10


// HERE IS MAGIC LINES
//============================================

let normalizedTO = to.normalized()
let normalizedFrom = from.normalized()
let angleBetweenTwoVectors = normalizedTO.cross(normalizedFrom)

var from = from
var to = to

if angleBetweenTwoVectors.y > 0 && needToAlignToCamera {
let temp = from
from = to
to = temp
}
//============================================


node.position = SCNVector3(from.x + (to.x - from.x) * 0.5,
from.y + height * 0.5,
from.z + (to.z - from.z) * 0.5)

// orientation of the wall is fairly simple. we only need to orient it around the y axis,
// and the angle is calculated with 2d math.. now this calculation does not factor in the position of the
// camera, and so if you move the cursor right relative to the starting position the
// wall will be oriented away from the camera (in this app the wall material is set as double sided so you will not notice)
// - obviously if you want to render something on the walls, this issue will need to be resolved.


node.eulerAngles = SCNVector3(0, -atan2(to.x - node.position.x, from.z - node.position.z) - Float.pi * 0.5, 0)


return node
}

扩展

func cross(_ vec: SCNVector3) -> SCNVector3 {
return SCNVector3(self.y * vec.z - self.z * vec.y, self.z * vec.x - self.x * vec.z, self.x * vec.y - self.y * vec.x)
}

func normalized() -> SCNVector3 {
if self.length() == 0 {
return self
}

return self / self.length()
}

关于ios - 如何使 SCNNode 面向 ARAnchor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53530244/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com