我有一个非常简单的场景:一个带有动态物理物体的立方体和一个带有静态物理物体的平面。当立方体掉落并撞击地面时,两个对象之间存在可见的间隙,您可以看到以下here的视频:
我尝试了SCNPhysicsShapeTypeKey
的所有不同组合,并尝试将SCNPhysicsBody的形状也设置为nil(文档说:“保留此nil将使系统决定并使用最有效的边界表示形式”),但是没有任何方法能够消除这种差距。
// ...
// plane physics
var body = SCNPhysicsBody(type: SCNPhysicsBodyType.Static, shape: SCNPhysicsShape(geometry: result.node!.geometry!, options: [SCNPhysicsShapeTypeKey:SCNPhysicsShapeTypeConvexHull]));
result.node!.physicsBody = body;
} else {
// cube physics
var body = SCNPhysicsBody(type: SCNPhysicsBodyType.Dynamic, shape: SCNPhysicsShape(node: result.node!, options: [SCNPhysicsShapeTypeKey:SCNPhysicsShapeTypeConvexHull]));
result.node!.physicsBody = body;
}
我已经检查了我的dae文件(attached here),并应用了所有scale/transition as per this question,但是结果相同。
我想我这里缺少明显的东西,有什么想法吗?
最佳答案
@Toyos关于filing a bug的评论是一个好主意。但是,在这种情况下,最好不要依赖默认的凸包生成。
TLDR:在可能的情况下,将原始参数化实体(或其中的化合物)用于物理形状。
当您从自定义几何图形生成物理形状(即从DAE加载)时,SceneKit必须构建一个复杂的数据结构来描述该几何图形的凸包,并且必须遍历该数据结构以对每个渲染帧执行碰撞检测(即每秒最多60次)。
相反,当您使用内置参数形状之一(SCNBox
,SCNSphere
等)时,您会向SceneKit发出信号,告知它可以使用该形状的理想表示形式,而不是基于其多边形网格的复杂数据结构。
举一个极端的例子,考虑一个球体:渲染一个看起来不错的球体需要a lot of polygons。如果将这样的网格输入到碰撞检测算法中,要么陷入顶点数据的复杂性中,要么必须生成不太复杂但精度较低的形状近似值(例如十二面体)。另一方面,球体是检测碰撞最简单的形状-要确定给定点是否在球体内,您需要做的就是获取从该点到球体中心的距离,并查看其是否小于半径。 (做对了,您甚至不必担心sqrt
的费用。)