Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SceneKit – SCNPhysics Body doesn't match SCNPhysicsShape

I have a very simple scene: a cube with a dynamic physics body and a plane with a static physics body. When the cube falls and hits the ground, there is a visible gap between the two objects, you can see a video of this here:

I have tried all different combinations of SCNPhysicsShapeTypeKey and tried setting SCNPhysicsBody's shape to nil as well (docs say: "Leaving this nil will let the system decide and use the most efficients bounding representation") but nothing has been able to remove the gap.

    // ...
    // 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;
}

I have checked my dae file (attached here) and applied all scale/transforms as per this question, however same result.

I think I'm missing something obvious here, any ideas?

like image 461
N S Avatar asked Nov 09 '14 23:11

N S


1 Answers

@Toyos' comment about filing a bug is a good idea. However, it's best not to rely on the default convex-hull generation in this case.

TLDR: use primitive parametric solids (or compounds of them) for physics shapes whenever you can.

When you generate a physics shape from custom geometry (i.e. loaded from a DAE), SceneKit has to build a complex data structure describing the convex hull of that geometry, and it has to work through that data structure to perform collision detection for every rendered frame (i.e. up to 60 times a second).

When you use one of the built-in parametric shapes (SCNBox, SCNSphere, etc) instead, you signal to SceneKit that it can use an idealized representation of that shape rather than a complex data structure based on its polygon mesh.

For an extreme example, consider a sphere: rendering a decent-looking sphere requires a lot of polygons. If you feed a mesh like that into a collision detection algorithm, either it bogs down in the complexity of the vertex data or it has to generate an approximation of the shape that's less complex but less accurate (say, a dodecahedron). On the other hand, a sphere is the simplest shape for collision detection — all you need to do to find out if a given point is within a sphere is get the distance from that point to the sphere's center and see if it's less than the radius. (Do it right and you don't even have the cost of sqrt to worry about.)

like image 71
rickster Avatar answered Oct 05 '22 23:10

rickster