我的目标是在包含SCNPlane的另一个SCNNode的中间生成一个SCNNode。
SCNPlane是在渲染器函数中生成的,如下所示:
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let planeAnchor = anchor as? ARPlaneAnchor else { return }
let width = CGFloat(planeAnchor.extent.x)
let height = CGFloat(planeAnchor.extent.z)
let plane = SCNPlane(width: width, height: height)
plane.materials.first?.diffuse.contents = UIColor.orange
let planeNode = SCNNode(geometry: plane)
let x = CGFloat(planeAnchor.center.x)
let y = CGFloat(planeAnchor.center.y)
let z = CGFloat(planeAnchor.center.z)
planeNode.position = SCNVector3(x,y,z)
planeNode.eulerAngles.x = -.pi / 2
node.addChildNode(planeNode)
node.name = "plane"
loadSphere(x:x, y:y, z:z)
我试图将球体正确地放在飞机中间:
func loadSphere (x:CGFloat, y:CGFloat, z:CGFloat) {
let idleScene = SCNScene(named: "art.scnassets/bounceFixed.dae")!
// This node will be parent of all the animation models
let node = SCNNode()
for child in idleScene.rootNode.childNodes {
node.addChildNode(child)
}
// Set up some properties
node.name = "Sphere"
node.position = SCNVector3(x, y, z)
node.scale = SCNVector3(0.001, 0.001, 0.001)
...
但问题是每当我运行它时,x,y,z都会变为零。我尝试了sceneView.scene.rootNode.childNodes[3].worldPosition
或node.worldPosition
之类的东西,但总是最终在相机视图中生成球体而不是在平面中间。
我在这里附上一张照片,告诉你我对“中间人”的意思。
请告诉我如何解决这个问题。
编辑:这篇文章的目标是尝试获取平面节点的x,y,z(中心)而不将球体作为子项附加。最佳。
答案 0 :(得分:2)
如果没有真正看到您的模型,或者您正在添加Sphere的确切方式,我会冒险猜测,您要么将模型添加到正确的SCNNode
,要么{{1}你的模型没有居中。
如果您想在SCNNode上集中放置平面几何图形,可以将其设置在pivot
或完全忽略它。
SCNVector3Zero
你可以在/// Loads An SCNSphere On A Generated SCNNode
///
/// - Parameter plane: SCNNode
func loadSphereOnPlane(_ plane: SCNNode) {
let sphereNode = SCNNode()
let sphereNodeGeometry = SCNSphere(radius: 0.01)
sphereNodeGeometry.firstMaterial?.diffuse.contents = UIColor.cyan
sphereNode.geometry = sphereNodeGeometry
plane.addChildNode(sphereNode)
}
委托回调的末尾称之为:
rendererDidAddNode
如果模型的枢轴不居中,您可以使用类似的东西来改变它:
loadSphereOnPlane(planeNode)
示例用法可能如此:
/// Changes The Pivot To The Center Of The Model
///
/// - Parameter model: SCNNode
func createCentralPivotFor(_ model: SCNNode){
let (min, max) = model.boundingBox
let dx = min.x + 0.5 * (max.x - min.x)
let dy = min.y + 0.5 * (max.y - min.y)
let dz = min.z + 0.5 * (max.z - min.z)
model.pivot = SCNMatrix4MakeTranslation(dx, dy, dz)
}
您还可以在rendererDidAddNode委托回调的末尾调用,例如:
两种方法都会产生如下结果:
更新:
既然你现在已经改变了你的问题,你可以尝试这样的事情:
/// Loads Our Little Scatterbug
func loadScatterBugOnPlane(_ node: SCNNode) {
let modelPath = "ARModels.scnassets/Scatterbug.scn"
//1. Get The Reference To Our SCNScene & Get The Model Root Node
guard let model = SCNScene(named: modelPath),
let pokemonModel = model.rootNode.childNode(withName: "RootNode", recursively: false) else { return }
let scatterBug = pokemonModel
//2. Scale The Scatterbug
scatterBug.scale = SCNVector3(0.002, 0.002, 0.002)
//3. Set The Pivot
createCentralPivotFor(scatterBug)
//4. Add It To The Plane
node.addChildNode(scatterBug)
}
希望它有所帮助...