我是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设置为静态体。它并没有崩溃,但是物理体看起来是原点上的一个点,而不是我的三角形。
所以,有些问题:
感谢。
答案 0 :(得分:4)
注意SceneKit会为您的自定义几何体创建physics shape,这一点非常重要。此物理形状不与您创建的网格具有相同的几何形状,而是默认为在网格外部构建凸包。我的猜测是,凸包算法可能不适用于法线面向内(?)的隧道网格。但是,即使它确实有效,你最终也会在隧道外围设置网状物,防止你飞过它。
一种可能的解决方案可能是在创建SCNPhysicsShape
时使用SCNPhysicsShapeTypeKey
来指定SCNPhysicsShapeTypeConcavePolyhedron
。如果采用这种方法,我还建议将隧道绕其圆周及其长度分段。
这有很多原因;它应该有助于渲染性能,因为当在视锥体外面时,SceneKit将剔除整个片段(节点),它应该有助于碰撞检测性能(SceneKit可能会在检查基于网格的碰撞之前进行边界框检查),最后是物理形状生成算法应该有效。
另一种方法是生成表示隧道的多个几何图元(SCNSphere
,SCNBox
等),并创建一个由多个形状组成的SCNPhysicsShape
。这是我在程序生成的岛屿周围构建形状的方法,每个灰色框都是SCNBox
。
SceneKit将通过打开相应的调试选项(可能仅限金属)来帮助显示所有物理形状。例如; scenekitView.debugOptions = SCNDebugOptions.ShowPhysicsShapes
。
我应该补充一点,生成SCNGeometry的方式并没有错。您需要记住一些注意事项,尤其是当网格具有大量三角形时。
希望它有所帮助。