gpt4 book ai didi

swift - ARKIT - 如何粘贴两个物体

转载 作者:行者123 更新时间:2023-11-30 11:37:18 27 4
gpt4 key购买 nike

我有两个对象(两个立方体)。首先,我将第一个立方体添加到场景中。然后我想添加第二个,我希望它粘在第一个上,在第一个的一侧 - 我将通过单击它来选择哪一侧(如下图所示)。是否可以只单击第一个立方体和第二个立方体的一个面来自动出现在场景中并粘在第一个立方体上?我不知道该怎么做。

Photo

最佳答案

当您创建 SCNBoxGeometry 时:

The SCNBox class automatically creates SCNGeometryElement objects as needed to handle the number of materials.

因此,为了访问这些元素,您需要为盒子的每个面创建一个 SCNMaterial。然后您可以执行 SCNHitTest 来检测已检测到哪张脸:

When you perform a hit-test search, SceneKit looks for SCNGeometry objects along the ray you specify. For each intersection between the ray and and a geometry, SceneKit creates a hit-test result to provide information about both the SCNNode object containing the geometry and the location of the intersection on the geometry’s surface.

那么我们该如何解决这个问题呢?

假设您已经创建了名为:

的 SCNNodes
var cubeOne = SCNNode()
var cubeTwo = SCNNode()

它们都分配了 6 个不同的 SCNMaterials(每个面一个),如下所示:

override func viewDidLoad() {
super.viewDidLoad()

cubeOne.geometry = cubeGeometry()
cubeOne.position = SCNVector3(0, -0.5, -1.5)
cubeOne.name = "Cube One"

cubeTwo.geometry = cubeGeometry2()
cubeTwo.position = SCNVector3(30, 0, -1.5)
cubeTwo.name = "Cube Two"

self.augmentedRealityView.scene.rootNode.addChildNode(cubeOne)
self.augmentedRealityView.scene.rootNode.addChildNode(cubeTwo)

}

/// Returns The 6 Faces Of An SCNBox
///
/// - Returns: SCNGeometry
func cubeGeometry() -> SCNGeometry{

var colours: [UIColor] = [.red, .green, .cyan, .yellow, .purple, .blue]
var faces = [SCNMaterial] ()
let cubeGeometry = SCNBox(width: 0.2, height: 0.2, length: 0.2, chamferRadius: 0)

for faceIndex in 0..<5{

let material = SCNMaterial()
material.diffuse.contents = colours[faceIndex]
faces.append(material)

}

cubeGeometry.materials = faces

return cubeGeometry
}

现在您已经为面指定了 6 种 Material ,您将拥有对应于 SCNBox 每一侧的 6 个几何元素。

现在完成此操作后,我们可以快速创建一个与面孔顺序相对应的枚举:

enum BoxFaces: Int{

case Front, Right, Back, Left, Top, Botton
}

现在,当我们执行 hitTest 时,我们可以记录命中的位置,例如:

/// Detects Which Cube Was Detected & Logs The Geometry Index
///
/// - Parameter gesture: UITapGestureRecognizer
@IBAction func cubeTapped(_ gesture: UITapGestureRecognizer){

//1. Get The Current Touch Location
let currentTouchLocation = gesture.location(in: self.augmentedRealityView)

//2. Perform An SCNHitTest
guard let hitTest = self.augmentedRealityView.hitTest(currentTouchLocation, options: nil).first else { return }

//3. If The Node In Cube One Then Get The Index Of The Touched Material
if let namedNode = hitTest.node.name{

if namedNode == "Cube One"{

//4. Get The Geometry Index
if let faceIndex = BoxFaces(rawValue: hitTest.geometryIndex){
print("User Has Hit \(faceIndex)")

//5. Position The Second Cube
positionStickyNode(faceIndex)
}

}

}
}

在第 5 部分中,您会注意到对函数 positionStickyNode 的调用,它将第二个立方体放置在第一个立方体的相应位置:

/// Position The Second Cube Based On The Face Tapped
///
/// - Parameter index: BoxFaces
func positionStickyNode(_ index: BoxFaces){

let (min, max) = cubeTwo.boundingBox

let cubeTwoWidth = max.x - min.x
let cubeTwoHeight = max.y - min.y

switch index {

case .Front:
cubeTwo.simdPosition = float3(cubeOne.position.x, cubeOne.position.y, cubeOne.position.z + cubeTwoWidth)
case .Right:
cubeTwo.simdPosition = float3(cubeOne.position.x + cubeTwoWidth, cubeOne.position.y, cubeOne.position.z)
case .Back:
cubeTwo.simdPosition = float3(cubeOne.position.x, cubeOne.position.y, cubeOne.position.z - cubeTwoWidth)
case .Left:
cubeTwo.simdPosition = float3(cubeOne.position.x - cubeTwoWidth, cubeOne.position.y, cubeOne.position.z)
case .Top:
cubeTwo.simdPosition = float3(cubeOne.position.x, cubeOne.position.y + cubeTwoHeight, cubeOne.position.z)
case .Botton:
cubeTwo.simdPosition = float3(cubeOne.position.x, cubeOne.position.y - cubeTwoHeight, cubeOne.position.z)
}

这是一个非常粗略的例子,当你的立方体大小相同时就可以工作......但是你已经足够了,现在要弄清楚这对于不同的大小等是如何工作的。

希望对你有帮助...

关于swift - ARKIT - 如何粘贴两个物体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49608649/

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