Hello everyone
This is a small program using the Havok physics engine to simulate a space battleship: https://mazetest-21w.pages.dev/SHIP/QXShip2 (press o to switch to free camera). The Babylon.js version I am using is 9.5.2, and the rendering mode is WebGpu. Currently, I am encountering two puzzling issues.
One is how to make the physics simulator move according to physical effects while also being able to control its motion state through code. For example, we can make the spacecraft move roughly to the vicinity of the target position based on physical effects, and then use code to precisely place it at the target point. This is what I am currently doing:
var impostor=ship_flag.physicsImpostor;
let body=impostor.body;
if(av_x==0&&av_y==0&&av_z==0)
{
console.log(ship_flag.name+"到达目标姿态附近");
//在渲染循环中只能设置力不能设置速度????
body.setAngularVelocity(new BABYLON.Vector3(0,0,0));
ship_flag.mydata.turning=false;//暂时先不测试跳转,先测试渐变@@@@
requestAnimationFrame(function(){
//越过物理引擎直接设置角速度时是否需要切换运动类型????<-如果下一帧里又开始转动了怎么办?
body.setMotionType(BABYLON.PhysicsMotionType.ANIMATED);
ship_flag.parent.rotation=new BABYLON.Vector3(ship_flag.mydata.rx,ship_flag.mydata.ry,ship_flag.mydata.rz);
ship_flag.parent.rotationQuaternion=null;//将它设为null才能让rotation有效!!!!
requestAnimationFrame(function(){
body.setMotionType(BABYLON.PhysicsMotionType.DYNAMIC);
})
if(ship_flag.parent._rotationQuaternion)
{
ship_flag.parent.rotation=ship_flag.parent._rotationQuaternion.toEulerAngles();
}
if(ship_flag.isControl) {
updatePinPerFream()
}
});
}
else
{
var avv3=new BABYLON.Vector3(av_x*200,av_y*200,av_z*200);//最终合成的角速度
body.setAngularVelocity(new BABYLON.Vector3(0,0,0));
body.applyAngularImpulse(avv3);//冲量是一个瞬间值??
}
Is this the correct approach?
The second question is how to seamlessly transition from the animation provided by the physics engine to the animation of Babylon.js. For instance, I want to simulate a scenario where a cannonball hits a local spacecraft, expands, simulates an explosion, and then disappears. Here’s how I do it:
function hit0(collisionEvent)
{
let mesh_arrow,mesh_ship;
if(collisionEvent.collider.mesh_arrow)//两个arrow相撞?
{
mesh_arrow=collisionEvent.collider.mesh_arrow;
if(collisionEvent.collidedAgainst.mesh_ship)
{
mesh_ship=collisionEvent.collidedAgainst.mesh_ship
}
}
else if(collisionEvent.collidedAgainst.mesh_arrow)
{
mesh_arrow=collisionEvent.collidedAgainst.mesh_arrow;
if(collisionEvent.collider.mesh_ship)
{
mesh_ship=collisionEvent.collider.mesh_ship
}
}
if(mesh_arrow)//对于命中的射弹
{//使用一个动画的回调而非定时器进行回收
mesh_arrow.physicsImpostor.body.setMotionType(BABYLON.PhysicsMotionType.ANIMATED);
mesh_arrow.physicsImpostor.body.setLinearVelocity(new BABYLON.Vector3(0,0,0));
var ani=new BABYLON.Animation("animation1_"+mesh_arrow.name,"scaling",30
,BABYLON.Animation.ANIMATIONTYPE_VECTOR3,BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);
var keys=[{frame:0,value:new BABYLON.Vector3(1,1,1)}
,{frame:90,value:new BABYLON.Vector3(3,3,3)}];
ani.setKeys(keys);
mesh_arrow.animations=[ani];
scene.beginAnimation(mesh_arrow,0,90,false,1,function(){
mesh_arrow.physicsImpostor.dispose();
mesh_arrow.dispose();
});
// setTimeout(function(){
// mesh_arrow.physicsImpostor.dispose();
// mesh_arrow.dispose();
// },1000)
}
if(mesh_ship)
{
}
}
Currently, shells can be recycled normally, but the animation showing the shells becoming larger is not displayed.
Thank you !