3.Rigid Bodies

来源:互联网 发布:睢阳保卫战知乎 编辑:程序博客网 时间:2024/06/04 20:04

任何真实世界的不改变形状的物体在Havok中能作为一个刚体被模拟,从一辆车到一个冲向山腰的鹅卵石。

 

刚体在havok动力学系统中是最重要的。如果你用一个完全刚性的物体,你能进行刚性物理模拟在实时。刚体模拟是完全适合制作许多真实世界物体,这些物体在一个游戏环境中移动。

 

你模仿刚体用hkpRigidBody类,一个hkpEntity的派生类。一个hkpRigidBody有一个hkpRigidMotion来存储关于刚体怎样运动的信息,包括它的质量和速度。这个hkpRigidBody也有一个hkpCollidable成员来包含物体和碰撞检测系统工作的信息—一个hkpShape和一个hkMotionState指针。这个刚体动作状态指针指向一个包含刚体位置和方位的结构,因此链接碰撞检测系统到动力学系统。

注意:

碰撞检测系统是被设计来没有动力学库工作,因此间接的层次存在在collidable和刚体之间。

 

3.1 创建一个刚体

如同hkpWorld,你用一个cinfo创建一个hkpRigidBody,这个hkpRigidBodyCinfo.你能指定所以下面的详细信息,或者用他们提供的默认值:

 

.hkpShape  m_shape。一个hkpRigidBody's hkpShape定义这个对象的形状和尺寸,为碰撞检测的目的。一个hkpShape能有许多implementations例如简单的形状(一个箱子或者一个球),一个被更简单的hkShapes复合的形状。你能在碰撞检测章节找到更多关于不同的形状类型和怎样创建它们。

 

.hkUint32 m_collisionFilterInfo。这个值能被碰撞过滤器用来指定实体。例如,如果一个组的碰撞过滤器被用,这个值将指定这个实体的碰撞组。默认这个值是0。你能找到更多用碰撞过滤器的信息在碰撞检测章节。

 

.Properties.看hkpProperty。

 

.hkpMaterial::ResponseType  m_collisionResponse. 这个值决定了刚体对于碰撞怎么做出反应。看hkpMaterial一个完整的可能值列表和结果行为。

 

.hkUint16  m_processContactCallbackDelay.这个值标识了实体发送过程接触事件到任何你加到实体的碰撞收听器的频繁程度。默认值是65535,这个即是调用回调为第一次碰撞和然后每65536帧,直到刚体移动出碰撞容差。你能找到更多的信息关于这个值和它的影响在收听器章节的碰撞收听器。

 

.hkVector4  m_position. hkpRigidBody的初始位置。

 

.hkQuaternion  m_rotation。hkpRigidBody的初始转动。默认的,这个设置为单位四元素。

 

.hkpMotion::MotionType  m_motionType.

用这个参数用一个惯性类型或关键帧来指定是否hkpRigidBody是固定的,可移动的。默认的是hkpMotion::MOTION_DYNAMIC。看hkpMotion::MotionType的一个运动类型的完整列表和她们的含义。你也能找到更多的信息关于关键帧的hkpRigidBodies在这个章节的关键帧对象部分。

如果你创建一个固定的或者关键帧的HkpRigidBody,你不能使他在之后的模拟期间动态的(用hkpRigidBody::setMotionType() ),但是你能使一个动态的HkpRigidBody固定或者关键帧在模拟期间。

MOTION_DYNAMIC是另一个枚举运动类型,是被用来在用setMotionType()模拟期间转回到先前的动态运动状态.

 

.hkMatrix3  m_inertiaTensor。hkpRigidBody的惯性张量。一个惯性张量描述了绕一个任意给的轴转动一个物体的难易程度。在实际中,假设大多数在Havok没有固定的物体用一个箱子惯性张量是合理的。这个惯性张量被刚体的运动类型决定。你能用hkpInertiaTensorComputer类来计算一个适当的值为这个。这个算法用刚体的其他的信息,如他的大小和质量,创建一个实际的惯性张量,如下:

hkpRigidBodyCinfo info;hkpMassProperties massProperties;hkVector4 boxSize ( 1.0f, 2.0f, 3.0f );hkReal boxMass = 10.0f;hkpInertiaTensorComputer::computeBoxVolumeMassProperties(boxSize, boxMass, massProperties);info.m_inertiaTensor = massProperties.m_inertiaTensor;

 

注意这个展示的方法是为box。不同的方法是被提供来计算不同类型刚体的惯性张量。一个方便的方法是hkplnertiaTensorComputer::setShapeVolumeMassPropertise( shape,mass,rigidbodyInfoOut )

 

如同物体的刚性运动类型,没有默认的惯性张量值被提供,你需要为每一个非固定的hkpRigidBody指定这个。

 

Note that depending on the motion type, this inertia matrix gets reduced to:

  • hkpMotion::MOTION_SPHERE_INERTIA: The highest value of the inertia diagonal is used, and all outer diagonals are set to 0. This simplification is valid for quite a few objects like spheres or equally sized boxes.

  • hkpMotion::MOTION_BOX_INERTIA: The diagonal is used and all outer diagonal elements are discarded. This simplification is valid for all symmetric objects. As Havok's solver does not support full inertia, make sure that all your objects are aligned to the local coordinate space.

.hkReal  m_mass。hkpRigidBody的质量,默认为1.0f。记住指定这个值在千克如果这个世界的度量用的米。0质量是暗示了hkpRigidBody是固定的和用固定运动类型。

 

.hkReal  m_linearDamping,m_angularDamping。这些指定了为线性和角度运动初始的阻尼(damping),默认的线性阻尼值为0,然而默认的角度阻尼值为0.05。线性阻尼在一段时间减少物体的移动,和角度阻尼 运行同样的函数但是是物体的转动。如果你设置线性阻尼值为0.1f,则每秒物体直线速度大约10%被减少(更精确的:newVelocity = oldVelocity*exp(-damping*deltaTime))

 

hkReal  m_maxLinearVelocity, m_maxAngularVelocity.

为hkpRigidBody的线性和角度速度设置限制 、默认的线性速度限制是设置为200m/s。如果你为快速的子弹需要一个更高的值,也可以考虑设置hkpWorldCinfo::m_expectedMaxLinearVelocity.角度速度初始是被设置为一个非常大的值。然而注意,在空间中有另一个剪裁机制限制角度速度到170度没模拟帧。这些值事实上被坚固的限制。一个刚体将绝不会超过这个值。注意:这个最大线性速度是直接建立进整合器的坚固限制。这个可能导致奇怪的效果如果一个刚体到达最大速度一段长时间:比如你限制一个Box的最大速度为10m/s。如果一个快速的汽车撞击这个box,这个车不能推这个Box比10/s更快。然而,Havok解决器不知道这个限制。这意味着解决器不将如同希望的工作。和这个box将浸没进这个车。如果连续物理是激活的在车和box之间,额外的CPU资源将被投资在TOI分解(看连续物理章节),然而整合器将简单放手TOI解决器的工作。所以这个参数只是应该被用来作为一个安全网来阻止物理变的疯狂,若果你想要限制速度为游戏原因你应该用阻尼或者写你自己的行为(action)。

 

hkReal  m_friction .你用这个值来为hkpRigidBody制定初始的摩擦力。一个刚体的摩擦力它表明的光滑程度和因此是和其他物体滑动的容易程度。通常摩擦值在0,1之间,但是能是更高(最大255)。默认值为0.5。你能在FrictionChangeDemo中看见改变摩擦值的效果。

 

hkReal  m_restitution. 你用这个来指定一个初始的还原值为hkpRigidBody。这个表明了一个物体的弹性程度,换句话说,就是碰撞后有多少能量。默认值为0.4。你能在RestitutionApi demo看见改变还原值的效果。这个复原的性能是粗略的大概值,所以你可能想要在你的游戏中实验不同的值来得到想要的效果。主要这个参数有一个1.99的坚固的限制。为了重复一个球弹离地板永远,设置地板和求的复原值都为1。当然,不得不确保也移除任何线性速度阻尼来获得准确的行为。为了获得在复原值内部运行的更多的信息,看hkContactPointMaterial::setRestitution.

 

hkVector4  m_centerOfMass. 这个hkpRigidBody的质量中心,在物体的本地空间。默认的,这个被设置为本地空间的中心。对box和球,这个是形状的中心,对其他形状,这个取决于你怎么样设置的形状—为更多信息看碰撞检测章节。注意改变物体的质量中心不改变物体的位置,和可能设置这个点在物体的外面、

 

.hkpCollidableQualityType  m_qualityType。这个特性类型决定了和其他物体相互作用的类型。类型是被储存在hkpRigidBody的colliadble。havok有十个预定义的物体类别:HK_COLLIDABLE_QUALITY_FIXED, HK_COLLIDABLE_QUALITY_KEYFRAMED, HK_COLLIDABLE_QUALITY_DEBRIS, HK_COLLIDABLE_QUALITY_DEBRIS_WITH_SIMPLIFIED_TOI, HK_COLLIDABLE_QUALITY_MOVING, HK_COLLIDABLE_QUALITY_CRITICAL, HK_COLLIDABLE_QUALITY_BULLET, HK_COLLIDABLE_QUALITY_USER, HK_COLLIDABLE_QUALITY_CHARACTER HK_COLLIDABLE_QUALITY_KEYFRAMED_REPORTING。

作用特征类型是被hkpCollisionDispatcher决定。更多信息看连续物理章节。

.hkReal  m_allowedPenetrationDepth。允许物体穿过的最大值。默认-0.1f。这是一个暗示,CPU投资多少来阻止物体穿透。一个高的选择是物体直径的5%到20%。

hkpRigidBodyCinfo::SolverDeactivation m_solverDeactivation。运行你激活一个额外的单个的物体钝化算法。这个意味着引擎将试图是单个物体速度为0如果物体变的非常慢。

以上性质的更多信息,看Physics Primer文档。

现在看一个简单的例子。接下来的片段展示了创建一个凸hkpRigidBody,质量为10和一个适当的惯性张力为形状和尺寸。默认值是用hkpRigidBodyCinfo剩下的默认值。

int numVertices = 4;// 16 = 4 (size of "each float group", 3 for x,y,z, 1 for padding) * 4 (size of float)int stride = sizeof(float) * 4;float vertices[] = { // 4 vertices plus padding-2.0f, 2.0f, 1.0f, 0.0f, // v0 1.0f, 3.0f, 0.0f, 0.0f, // v1 0.0f, 1.0f, 3.0f, 0.0f, // v2 1.0f, 0.0f, 0.0f, 0.0f  // v3};hkStridedVertices stridedVerts;{stridedVerts.m_numVertices = numVertices;stridedVerts.m_striding = sizeof(hkVector4);stridedVerts.m_vertices = &(vertices[0](0));}// We do not plan to use raycast on this object, so we do not have to pass in planeequationshkArray<hkVector4> dummyPlaneEquations;hkpConvexVerticesShape* pShape = new hkpConvexVerticesShape(stridedVerts, dummyPlaneEquations);hkpRigidBodyCinfo rigidBodyInfo;rigidBodyInfo.m_shape = pShape;// Compute the shapes inertia tensorhkReal mass = 10.0f;hkpInertiaTensorComputer::setShapeVolumeMassProperties(pShape, mass, rigidBodyInfo);rigidBodyInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA;rigidBodyInfo.m_qualityType = HK_COLLIDABLE_QUALITY_MOVING;hkpRigidBody* pRigidBody = new hkpRigidBody(rigidBodyInfo);
你创建了一个hkpRigidBody之后,你能用hkpWorldObject,hkpEntity和hkpRigidBody函数获取和重置上面的值,包括物体的位置和转动。

原创粉丝点击