ARKit基础--sceneKit基础碰撞检测

基本理论

2D中的碰撞检查大家都能能理解,涉及到的数学知识并不复杂。但在3D中碰撞检测要涉及到更复杂的数学知识了,很多人数学功底不好的同学就犯难了,我也是。幸好SceneKit框架 提供了方便的方法去判断碰撞检测。
要想让SCNNode 模拟碰撞检测,首先要设置它的Physics Body,Physics Body有三种类型:
(1)Dynamic:动态的物体,受力的影响(applyForce)。
(2)Static: 静态的物体,不受力的影响。
(3)Kinemat:这种类型比较特殊,你可以直接移动,旋转它,在空间变换中,会对Dynamic的物体产生力的影响。
其次需要设置categoryBitMask,来表示物体的特质,比如下面我们定义了一个bottom和cube,这样碰撞的时候,我们可以通过这个mask来判断碰撞node的类型。

typedef NS_OPTIONS(NSUInteger, CollisionCategory) {
  CollisionCategoryBottom  = 1 << 0,
  CollisionCategoryCube    = 1 << 1,
};

Kinemat物体

 SCNNode *bottomNode = [SCNNode nodeWithGeometry:bottomPlane];
  bottomNode.physicsBody = [SCNPhysicsBody
                             bodyWithType:SCNPhysicsBodyTypeKinematic
                            shape: nil];
  bottomNode.physicsBody.categoryBitMask = CollisionCategoryBottom;

这里设置了一个Kinemat物体,可以吸引其他物体,该物体的标示为CollisionCategoryBottom.

Dynamic物体

node.physicsBody = [SCNPhysicsBody bodyWithType:SCNPhysicsBodyTypeDynamic shape:nil];
  node.physicsBody.mass = 2.0;
  node.physicsBody.categoryBitMask = CollisionCategoryCube;

这里设置了一个Dynamic物体,mass为其重量,会影响其动能,该物体的标示为CollisionCategoryCube.

设置碰撞delegate

@protocol SCNPhysicsContactDelegate 
@optional
- (void)physicsWorld:(SCNPhysicsWorld *)world didBeginContact:(SCNPhysicsContact *)contact;
- (void)physicsWorld:(SCNPhysicsWorld *)world didUpdateContact:(SCNPhysicsContact *)contact;
- (void)physicsWorld:(SCNPhysicsWorld *)world didEndContact:(SCNPhysicsContact *)contact;
@end

 self.sceneView.scene.physicsWorld.contactDelegate = self;

一共3个碰撞函数,碰撞开始前,碰撞开始中,碰撞开始后。

- (void)physicsWorld:(SCNPhysicsWorld *)world didBeginContact:(SCNPhysicsContact *)contact {
  if (contact.nodeA.physicsBody.categoryBitMask == CollisionCategoryBottom) {
      //对bottom的SCNNode做处理
    } else {
      //对cube的SCNNode做处理
    }
}

碰撞中,返回碰撞的nodeA|nodeB,可以通过categoryBitMask来判断是SCNNode的类型。

具体参看demo

你可能感兴趣的:(ARKit基础--sceneKit基础碰撞检测)