SCNPhysicsBody学习

创建SCNPhysicsBody

+ (instancetype)staticBody;

staticBody是一个不受外力或碰撞影响的物体,不能移动。比如地板、墙壁等。
必须把它附加到SCNNodephysicsBody属性上。附加到节点上后,会自动为节点创建物理形状。
对于包含自定义几何的节点,SceneKit出于对准确性和性能的折衷,创建的只是一个近似的物理形状。基于基本几何类(SCNBox, SCNSphere, SCNPyramid, SCNCone, SCNCylinder, 或者 SCNCapsule)的节点体验效果最好。
如果想手动创建物理形状,使用SCNPhysicsShape类方法。

+ (instancetype)dynamicBody;

dynamicBody是一个可以受力和碰撞影响的物体。
其余同staticBody

+ (instancetype)kinematicBody;

kinematicBody是一个不受外力或碰撞影响的物理实体,但它会在移动时造成碰撞影响其他物体。
其余同staticBody

举一个简单的例子:桌球游戏中,球桌是staticBody,球是dynamicBody,球杆是kinematicBody

+ (instancetype)bodyWithType:(SCNPhysicsBodyType)type shape:(nullable SCNPhysicsShape *)shape;

根据指定类型和形状创建一个物理实体。
如果将nil传递给shape,在将它附加到节点上时,会自动根据节点创建物理性状。
其余同staticBody

定义力如何影响物体

@property(nonatomic, retain) SCNPhysicsShape *physicsShape;

在碰撞检测中物体的形状。
在碰撞检测时往往没必要用真实的几何形状,用简单的形状可以得到更好的性能。通常我们把physicsShape设置为一个简单的形状,把真实的几何形状放里面。
当然对于精准的碰撞测试,我们需要使用更详细的几何图形。
创建物理图形的细节参见SCNPhysicsShape类。

@property(nonatomic) SCNPhysicsBodyType type;

typedef enum SCNPhysicsBodyType : NSInteger {
    SCNPhysicsBodyTypeStatic,
    SCNPhysicsBodyTypeDynamic,
    SCNPhysicsBodyTypeKinematic
} SCNPhysicsBodyType;

物体的类型,枚举类型,就是上文中的staticBodydynamicBodykinematicBody

@property(nonatomic) SCNVector3 velocityFactor;

移动因子
例如,可以通过将其速度因子设置为{1.0,1.0,0.0},从而使物体只能在在两个维度中移动。

@property(nonatomic) SCNVector3 angularVelocityFactor;

旋转因子
例如,可以通过将其旋转因子设置为{0.0,1.0,0.0},从而使物体只能在一个轴上旋转。

@property(nonatomic, getter=isAffectedByGravity) BOOL affectedByGravity;

是否受重力影响
这个属性默认是YES

定义物体的属性

@property(nonatomic) CGFloat mass;

质量,以千克为单位。
质量会影响物体对力的反应。dynamicBody的默认质量是1。staticBodykinematicBody的默认质量为0,但它们不受质量影响。
物理模拟的影响取决于不同物体的相对质量,而不是绝对值。所以你不需要对应用程序中的物体进行实际测量。

@property(nonatomic) CGFloat charge;

电荷,以库仑为单位。
当受到电场或磁场影响时,带有正电荷或负电荷的物体的行为会不同。三种类型的物体的默认电荷均为0,即不会受电场和磁场的影响。
同样不需要去做实际测量。

@property(nonatomic) CGFloat friction;

滑动摩擦力。
当两个物体接触并滑动时,摩擦力决定它们对运动的阻力。如果两个物体的摩擦力都是0,它们会自由地滑动。如果都是1,就不会滑动。默认值为0.5。

@property(nonatomic) CGFloat rollingFriction;

滚动摩擦力。
圆型物体在滚动时的阻力。如果是0,将持续滚动而不减速,除非另有动作。如果是1,将无法滚动。默认值为0。

@property(nonatomic) CGFloat restitution;

可以理解成弹性。
决定了物体在碰撞过程中会保留多少动能。比如一个球掉在地面,如果是0,就不会反弹。如果是1,就会弹回原处。如果大于1,它会弹得比原来更高。默认值是0.5。

@property(nonatomic) CGFloat damping;

移动阻尼。
类似空气摩擦或水摩擦,就是在移动中的阻力。与其他的力独立并共存。如果是0,表示没有阻力,不会造成速度损失。如果是1,就会阻止物体移动。默认值是0.1。

@property(nonatomic) CGFloat angularDamping;

旋转阻尼。
同上,影响物体在旋转中的阻力。默认值是0.1。

@property(nonatomic) SCNVector3 momentOfInertia;

惯性矩阵。
比如x 默认情况下,SceneKit会根据物体的形状和质量自动确定惯性矩阵。如果要自定义,需要设置usesDefaultMomentOfInertiaNO

@property(nonatomic) BOOL usesDefaultMomentOfInertia;

是否自动计算物体的惯性矩矩形。
YES为自动计算,NO为自定义设置。

分类

@property(nonatomic) NSUInteger categoryBitMask;

物体的分类。
每个分类都是位掩码的一个位。我们可以通过位运算给物体设置一个或多个类别。
physicsshapecontacttestbitmask一起使用可以定义物体间的相互作用。
dynamicBodykinematicBody的默认类别是SCNPhysicsCollisionCategoryDefaultstaticBody的默认类别为SCNPhysicsCollisionCategoryStatic

@property(nonatomic) NSUInteger contactTestBitMask;

定义哪些类别的物体与这个物体接触时会收到通知。
当物体A与物体B接触时,SceneKit会比较A.contactTestBitMask&&B.categoryBitMask,如果结果是一个非零的值,会创建一个SCNPhysicsContact对象,我们可以通过contactDelegate来处理我们需要自定义的一些操作。通常为了获得最好的性能,只需为我们感兴趣的交互中的物体设置contactTestBitMask
iOS8或者OS X v10.10的环境下,当且仅当碰撞发生了,SceneKit才会触发delegate。iOS9或者OS X v10.11以后的版本,这个值默认是0,且不管是碰撞,还是穿过彼此,都会触发delegate.

@property(nonatomic) NSUInteger collisionBitMask;

定义哪些分类的物体可以和这个物体发生碰撞。
当物体A与物体B接触时,可能会发生碰撞。SceneKit会比较A.collisionBitMask&&B.categoryBitMask。如果结果是一个非零值,那么物体会发生碰撞。每个物体可以单独选择想发生碰撞的物体。
默认值是SCNPhysicsCollisionCategoryAll,将于所有的类别发生碰撞。

用力

- (void)applyForce:(SCNVector3)direction impulse:(BOOL)impulse;

给物体的质心施加一个力或冲量。
direction:力的大小和方向
impulse:YES,施加的是冲量;NO,施加的是力
物体线性加速度与质量成正比。
impulse参数决定了这个方法如何进行物理模拟。(复习力学知识)
如果设置为YES,会把direction参数作为一个冲量。单位是牛秒(kgm/s 或 N·s = Huygens Hy),并立即加速物体。比如发射炮弹等。
如果设置为NO,会把direction参数作为一个力。单位是牛顿(N),SceneKit会在每一帧的最后,将所有的力都应用到物体上,从而得到一个加速度。
impulse参数改变了量值的单位,如果是冲量,将在每一帧上连续产生一定的加速度,如果紧在一帧里应用,那么加速度将大大降低。
同样不需要去做实际测量。

- (void)applyForce:(SCNVector3)direction atPosition:(SCNVector3)position impulse:(BOOL)impulse;

给物体的某个位置施加一个力或冲量。
position:物体所在的SCNNode的自身坐标系中,施加力或冲量的点。
其余参数同上
在物体的质心以外的位置上施加一个力或冲量,可以是线性加速度或角加速度,这取决于物体在物理世界中的位置,以及作用于它的其他力。

- (void)applyTorque:(SCNVector4)torque impulse:(BOOL)impulse;

给物体施加一个扭矩(旋转的力)或角动量(旋转的冲量)。
torque :方向和大小的扭矩(牛·米)或角动量的变化(在newton-meter-seconds),相对于场景的世界坐标空间。
impulse :YES,施加的是角动量;NO,施加的是扭矩
施加扭矩或角动量到物体上,其角速度与物体的质量、形状有关,此外这并不会影响到物体的线性加速度。

- (void)clearAllForces;

取消所有持续的力或扭矩。

管理物体运动

@property(nonatomic) SCNVector3 velocity;

物体当前运动速度(米/秒)和方向。
在SCNSceneRendererDelegate协议中的任何方法中调用,返回的是物理模拟的当前结果,设置属性会立即应用更改。
在其他时间调用,返回的是最后一次设置的值,设置属性会在下一次渲染循环的过程时生效。

@property(nonatomic) SCNVector4 angularVelocity;

物体当前的旋转轴和旋转速度(弧度/秒)。
从旋转轴指定的方向看,正值代表逆时针旋转。
其余同上。

@property(nonatomic, readonly) BOOL isResting;

表示物体是否出于静止状态。
默认是NO。但是物体没有动,并且没有收到任何力。SceneKit会自动将值变成YES。

@property(nonatomic) BOOL allowsResting;

是否自动将物体设置为“静止”
物理模拟的物体越少,可以提升模拟的性能。
设为YES,将提高模拟性能。
设为NO,将提高准确性。


这里涉及到了很多编程以外的物理知识,需要彻底搞懂的话需要恶补物理先。笑cry。

你可能感兴趣的:(SCNPhysicsBody学习)