1

我是 SceneKit 的新手,所以我尝试做的事情完全有可能/很可能不是正确的方法。所以这是我的一般意图:

我正在建造一个玩家穿越的“隧道”。这是一个程序生成的隧道。我正在确定代表隧道网格的点的位置,然后将点与三角形连接在一起以对其进行蒙皮。我正在使用以下方法来生成我的三角形:

func addTriangleFromPositions(scene: SCNScene, point1: SCNVector3, point2: SCNVector3, point3: SCNVector3)
{   
    let vector12 = GLKVector3Make(point1.x - point2.x, point1.y - point2.y, point1.z - point2.z)
    let vector32 = GLKVector3Make(point3.x - point2.x, point3.y - point2.y, point3.z - point2.z)
    let normalVector = SCNVector3FromGLKVector3(GLKVector3CrossProduct(vector12, vector32))


    let positions: [SCNVector3] = [point1, point2, point3]
    let normals: [SCNVector3] = [normalVector, normalVector, normalVector]
    let indices: [Int32] = [0, 2, 1]
    let vertexSource = SCNGeometrySource(vertices: positions, count: positions.count)
    let normalSource = SCNGeometrySource(normals: normals, count: normals.count)
    let indexData = NSData(bytes: indices, length: sizeof(Int32) * indices.count)

    let element = SCNGeometryElement(data: indexData, primitiveType: .Triangles, primitiveCount: indices.count, bytesPerIndex: sizeof(Int32))
    let geometry = SCNGeometry(sources: [vertexSource, normalSource], elements: [element])

    let material = SCNMaterial()
    material.diffuse.contents = UIColor(red: 41.0 / 256.0, green: 16.0 / 256.0, blue: 0, alpha: 1 )

    geometry.materials = [material]
    let node = SCNNode(geometry: geometry)
    scene.rootNode.addChildNode( node )
}

这工作正常,我的隧道看起来像一个隧道。但是,当我开始尝试将 PhysicsBody 添加到我的节点以使其成为静态主体时(物体应该能够撞入隧道,但隧道壁不会移动),我的应用程序开始崩溃并出现 EXC_BAD_ADDRESS。在我添加前几个三角形后它实际上崩溃了,所以我怀疑以这种方式添加几个三角形时会出现一些问题。

因此,为了对此进行测试,我创建了一个测试项目并仅添加了一个三角形,并将其 PhysicsBody 设置为静态主体。它不会崩溃,但物理体似乎是原点的一个点,而不是采用我的三角形的形状。

所以,一些问题:

  1. 一般来说,这是生成自定义几何图形的坏方法吗?如果我真的想要一个有点不规则的形状,并且我希望它有一个 PhysicsBody,除了创建三角形来连接点之外,还有其他方法吗?
  2. 关于为什么为我的三角形创建物理体不起作用的任何想法?

谢谢。

4

1 回答 1

5

请务必注意,SceneKit 将为您的自定义几何体创建物理形状。此物理形状不会与您创建的网格具有相同的几何形状,而是默认在网格外部构建一个凸包。我的猜测是凸包算法可能不适用于法线朝内的隧道网格(?)。但是,即使它确实有效,您最终也会在隧道外部周围形成一个网格,阻止您飞过它。

一种可能的解决方案可能是SCNPhysicsShapeTypeKey在创建 时使用SCNPhysicsShape来指定SCNPhysicsShapeTypeConcavePolyhedron。如果采用这种方法,我还建议您将隧道沿其圆周和长度分成几段。

管分割

有许多的原因; 它应该有助于渲染性能,因为当在视锥体之外时,SceneKit 将剔除整个片段(节点),它应该有助于碰撞检测性能(SceneKit 可能会在检查基于网格的碰撞之前进行边界框检查),最后是物理形状生成算法应该可以工作。

另一种方法是生成许多代表隧道的几何图元(SCNSphereSCNBox等)并创建SCNPhysicsShape由多个形状组成的隧道。这是我在程序生成的岛屿周围构建形状所采用的方法,每个灰色框都是一个SCNBox.

在此处输入图像描述

SceneKit 将通过打开适当的调试选项(可能仅限金属)来帮助显示所有物理形状。例如; scenekitView.debugOptions = SCNDebugOptions.ShowPhysicsShapes.

我应该补充一点,您生成 SCNGeometry 的方式没有任何问题。您需要牢记一些注意事项,尤其是当网格具有大量三角形时。

希望能帮助到你。

于 2016-05-17T03:05:23.170 回答