Tube Physics Body Acting Like Scncylinder, But How to Make It Act Like Scntube

Tube Physics Body acting like SCNCylinder, but how to make it act like SCNTube?

Dynamic bodies in SceneKit must be convex. (If you look into the general theory behind collision detection in games, i.e. not just SceneKit, you'll find that there are massive differences in speed and efficiency between collision detection on convex versus concave shapes.) A tube is a concave shape — it has a hole in it.

Luckily, your tube is being used as a static body. For static bodies only, there's an option to make the physics shape (an approximation of) a concave geometry:

let shape = SCNPhysicsShape(geometry: tube, 
options: [SCNPhysicsShapeTypeKey: SCNPhysicsShapeTypeConcavePolyhedron])
box.physicsBody = SCNPhysicsBody(type: .Static, shape: shape)

There is a performance cost to this. If you find your framerate limited by CPU usage after this change, or if you want to have a dynamic body be (effectively) concave, you might get better performance by making a physics shape that's a compound of several other shapes — e.g. build a dummy node hierarchy (not one that's actually in your scene) containing a bunch of cylinders or boxes arranged into a ring, then make a physics shape from them with SCNPhycsicsShape(node:options:).

SceneKit – Concave collision box

A "concave" physics body, per SCNPhysicsShapeTypeConcavePolyhedron, must still be "solid" in some sense, and the implied behavior for that collision type is to keep other bodies outside the "solid" form of the body. As such, your cube still has a "solid" interior even if you set its shape type to concave.

(What the concave shape type does do for you is let you make a solid shape that is non-convex — for example, a cube where one of the faces bows inward to produce a bowl shape.)

If you want to confine other bodies to a box-shaped volume, you'll need to create walls: that is, put a few physics bodies around the volume you want to enclose. Here's a quick utility function for something like that:

func wallsForBox(box: SCNBox, thickness: CGFloat) -> SCNNode {

func physicsWall(width: CGFloat, height: CGFloat, length: CGFloat) -> SCNNode {
let node = SCNNode(geometry: SCNBox(width: width, height: height, length: length, chamferRadius: 0))
node.physicsBody = .staticBody()
return node
}

let parent = SCNNode()

let leftWall = physicsWall(thickness, height: box.height, length: box.length)
leftWall.position.x = -box.width / 2
parent.addChildNode(leftWall)

let rightWall = physicsWall(thickness, height: box.height, length: box.length)
rightWall.position.x = box.width / 2
parent.addChildNode(rightWall)

let frontWall = physicsWall(box.width, height: box.height, length: thickness)
frontWall.position.z = box.length / 2
parent.addChildNode(frontWall)

let backWall = physicsWall(box.width, height: box.height, length: thickness)
backWall.position.z = -box.length / 2
parent.addChildNode(backWall)

let topWall = physicsWall(box.width, height: thickness, length: box.length)
topWall.position.y = box.height / 2
parent.addChildNode(topWall)

let bottomWall = physicsWall(box.width, height: thickness, length: box.length)
bottomWall.position.y = -box.height / 2
parent.addChildNode(bottomWall)

return parent
}

This creates a node hierarchy containing visible walls as separate nodes, but you could easily modify it to create invisible walls and/or a single node with a compound physics body. (See SCNPhysicsShape.)

ARKit – Ball is not passing through SCNTorus hole

The code you use to create the physicsbody (body type kinametic and shape nil) results in a simplified “convex hull” representation of the geometry. Simply put, the geometry you see is a torus, but the geometry used for the collision detection is not.

This line of (obj c) code is actually from one of the Apple sample code projects:

_torus.physicsBody = [SCNPhysicsBody bodyWithType:SCNPhysicsBodyTypeStatic shape:[SCNPhysicsShape shapeWithGeometry:_torus.geometry options: @{SCNPhysicsShapeTypeKey : SCNPhysicsShapeTypeConcavePolyhedron} ] ];

In other words, you need to create a static type body and a shape based on the geometry itself using the SCNPhysicsShapeTypeConcavePolyhedron key value (which only works for static bodies) to end up with a more accurate representation of the torus geometry as the physics body.

For more details see: https://developer.apple.com/documentation/scenekit/scnphysicsshape



Related Topics



Leave a reply



Submit