您的位置:首页 > 其它

jiglibflash and AwayPhysics for car

2012-08-10 17:32 134 查看
1、车体不能正确的接确到地面的问题:

在away3d场景中,创建JCar的底盘刚体要正确包围整个模型,模型的轴点对应于刚体的中心点,中心点总是位于刚体中心,away3D和jiglib的坐标系统是一样的,只有away3d对象的坐标原点位于几何体的中心,jiglib的刚体才能正确包围这个对象,所以把模型轴点移动到模型的中心。也可以减小车体(chassis)的高度,同时把四个轮子都向下移动,使轮子接触到地面。

2、jiglib中设置轮子的参数

public function setupWheel(_name:String, pos:Vector3D,

wheelSideFriction:Number = 2, wheelFwdFriction:Number = 2,

wheelTravel:Number = 3, wheelRadius:Number = 10,

wheelRestingFrac:Number = 0.5, wheelDampingFrac:Number = 0.5,

wheelNumRays:int = 1):void

carBody.setupWheel("WheelFL", new Vector3D(-48, -20, 68), 1.3, 1.3, 6, 20, 0.5, 0.5, 2);

每一个参数是车轮名字,第二个参数是轮子相对车子主体的位置,第三和第四个参数是轮子的侧滑,前滑摩擦系数,第五个是轮轴悬挂上下移动的距离,第六个是轮子半径,第七个是弹性系数,第八个是轮轴阻尼系数,一般后面几个可以不管,设为默认值就行了,关键是车子主体(chassis)的 sideLengths要和各个轮子的位置和半径相适应,否则主体可能会和地面接触,所以不能向前移动。wheeltravel一般设为2到5就行了,wheelnumrays影响轮子的碰撞精度,一般是1或2。可以增加setupWheel的第五个参数实现轮子的弹簧效果,不过这个设的太大容易使车体着地,所以需要把所有轮子位置向下移动一定距离。

public function setCar(maxSteerAngle:Number = 45, steerRate:Number = 1, driveTorque:Number = 500):void

要使汽车更容易转弯,你可以增加setcar的第三个参数,就是增加驾驶扭矩,不过太灵活也不好。

3、jiglib和bullet中的单位问题

米和像素当然不是一个概念,bullet是严格按照牛顿定律来模拟真实世界的,使用的基本单位都是真实的物理单位,在与3D模型绑定的时候需要设置物理世界的scale,这个决定了一米等于多少像素。但是jiglib并不像bullet这么严格,为了使用方便并且直观,所以直接使用了像素为基本单位,当然像素是一个2D的概念,用来表示3D世界并不是很贴切,可以理解为3D模型实际的尺寸单位。作者只是为方便当成像素。bullet的单位是米,jiglib用的单位是像素,所以jiglib必须按照实际像素大小设置尺寸,场景都要按相应比例放大。

AwayPhysics(as3通过Alchemy调用bullet的c++库)已经默认设置scaling为100,也就是每单位对应bullet的0.01米,所以设置的刚体尺寸不宜过小,物理引擎的坐标系是与使用的图像引擎相关的,原始的bullet使用opengl渲染图形所以是右手坐标,在AwayPhysics中用fp11,自然就是左手坐标了。

4、怎么让车不容易翻

可以把模型的轴点向下移到车体的中心,而不是整个模型的中心,同时减小chassis包围盒的高度,这样chassis只包围底下的车体,而不是整个模型,chassis的高度太高的话就容易翻。

5、射线检测

bullet的射线检测还没有添加到awayphysics里,目前还用不了,jiglib中有。

6、多car的同步问题

物理的网络同步确实比较复杂,如果实时传输transfrom信息,要注意server和client端是不同的坐标系问题,还有就是只传输各个客户端玩家的输入信息,依靠严格的时间频率控制物体移动,保证不同客户端物理模拟完全一致。因网络延迟问题,不管哪一种都不能保证每个客户端有完全一样的结果,所以需要每隔一定的时间传输一次位置信息修正每个玩家位置。

7、避免高速穿透

awayphysics中,如果车的速度很快,比如60m/s或更大时,车会穿墙而过,如从很高的空中落下来也是这样,重力加速度使速度大到一定时,车会穿过地面,从比较小的高度落下来,车着地时,会有一点穿透,如有半个轮子穿透地面,弹几下慢慢的起来。

可以使用CCD(Continuous Collision Detection)检测避免高速穿透,在AwayPhysics中可以看basicTest那个例子,主要设两个参数,比如:

car.getRigidBody().ccdSweptSphereRadius = 0.5;

car.getRigidBody().ccdMotionThreshold = 1;

轮子穿透可以试试增加suspensionStiffness和suspensionRestLength1这两个参数的值。

8、公式

算线速度的公式是 a=f/m; Vt=V0+a*t;

代码 _currState.linVelocity = _currState.linVelocity.add(JNumber3D.getScaleVector(_force, _invMass * dt));

invMass是mass的倒数,就是1/mass,invOrientation是方向矩阵的逆矩阵。对于旋转矩阵也是它的转置距阵。

旋转矩阵是正交矩阵,正交矩阵的特性是它的逆矩阵等于转置矩阵。

invOrientation = JMatrix3D.getTransposeMatrix(_currState.orientation);

角速度的公式:Wt=W0+a*t; a等于力矩乘转动惯量的逆矩阵,可以理解为角加速度。

分拆开来就可以写为下面三句:

var rac:Vector3D = JNumber3D.getScaleVector(_torque, dt);

rac = _worldInvInertia.transformVector(rac);

_currState.rotVelocity = _currState.rotVelocity.add(rac);







9、jiglib碰撞处理

都在PhysicsSystem里,主要是这两个方法:processCollisionNormal,processCollisionAccumulated,根据不同的碰撞处理类型执行相应方法。

10、点到面的距离

参考JPlan中的算法:

public function pointPlaneDistance(pt:Vector3D):Number

{

return _normal.dotProduct(pt) - _distance;

}

11、jiglig中的刚体RigidBody



Jterrain,通过高度数据生成RigidBody

JTriangleMesh 通过mesh的vertex和index生成RigidBody,用于赛道的物理
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐