1、初始化
需要下载两个文件:
https://cdn.babylonjs.com/havok/HavokPhysics_es.js
https://cdn.babylonjs.com/havok/HavokPhysics.wasm
然后引入这个 HavokPhysics_es.js
import HavokPhysics from "/HavokPhysics_es.js"
let havokInterface = await HavokPhysics()
this.physicsEngine = new BABYLON.HavokPlugin(true, havokInterface)
this.scene.enablePhysics(new BABYLON.Vector3(0, -9.81, 0), this.physicsEngine)
2、给物体添加物理引擎
let Box = BABYLON.MeshBuilder.CreateBox("Box", { width: 10, height: 10, depth: 10 }, this.scene)
// 创建一个标准材质
let groundMaterial = new BABYLON.StandardMaterial("BoxMaterial", this.scene)
// 将材质分配给地面
groundMaterial.backFaceCulling = false
ground.material = groundMaterial
ground.position.set(0,0,0)
// 添加物理引擎
// 第一个参数 —— 需要添加的Mesh —— 必填
// 第二个参数 —— 添加Mesh的类型 —— 必填
// 第三个参数 —— mass 重量 friction 摩擦系数 —— 可选
// 第四个参数 —— 表示场景 —— 可选
new BABYLON.PhysicsAggregate(ground, BABYLON.PhysicsShapeType.BOX, { mass: 0, friction: 0.5 }, this.scene)
BABYLON.PhysicsShapeType有以下几种类型:
- SPHERE:球形,由中心点和半径描述。
- BOX:立方体,由中心点、旋转和尺寸描述。
- CAPSULE:胶囊形,类似于圆柱体,但在两端有两个半球。这是角色肢体(有时称为布娃娃)的理想选择。
- CYLINDER:圆柱体,由两个点和半径描述。这是桶、轮子和眼镜的理想选择。
- CONVEX_HULL:凸包,是物理形状中最通用的。凸对象是指可以在任何两个顶点之间绘制一条线而不离开形状的对象。虽然大多数真实世界的对象都不是凸的,但对于物理模拟来说,这是大多数对象的理想近似。输入的网格可以是凹的 - 物理引擎将计算几何体的凸部分。
- MESH:网格,从网格计算碰撞。
- HEIGHTFIELD:高度场。
- CONTAINER:容器,可以包含多个简单的形状。
注意项:
1、给导入的模型添加物理引擎可能会不生效,因为这是需要 顶点数据 (我猜的哈哈^_^)
解决办法,给物体包一个简单Mesh,让物体的姿态都跟随这这个Mesh,使用Babylon创建的Mesh是可以直接添加物理属性的,也可以自定义Shader创建,一般推荐Shader创建,虽然复杂了点,但好在有用,这个顶点的数据可以通过你们的 UE5(我公司用的)导出对应的顶点数据
3、使用 Shader着色器 创建Mesh
// 顶点着色器代码
BABYLON.Effect.ShadersStore["customVertexShader"] = `
attribute vec3 position;
attribute vec4 color;
varying vec4 vColor;
uniform mat4 worldViewProjection;
void main(void) {
gl_Position = worldViewProjection * vec4(position, 1.0);
}
`
// 片元着色器代码
BABYLON.Effect.ShadersStore["customFragmentShader"] = `
varying vec4 vColor;
void main(void) {
gl_FragColor = vColor;
}
`
// 创建着色器材质
let shaderMaterial = new BABYLON.ShaderMaterial(
"shader",
this.scene,
{
vertex: "custom",
fragment: "custom",
},
{
attributes: ["position", "color"],
uniforms: ["worldViewProjection"],
needAlphaBlending: true,
}
)
// 定义顶点数据
let positions = [
0 , 0 , 0,
6 , 6 ,20,
-6, 6 ,20,
-6, -6,20,
6 , -6,20,
]
let indices = [
0, 1, 2,
0, 2, 3,
0, 3, 4,
0, 4, 1,
2, 1, 4,
2, 4, 3
]
// 创建 VertexData 对象
let vertexData = new BABYLON.VertexData()
// 将顶点数据赋值给 VertexData 对象
vertexData.positions = positions
vertexData.indices = indices
// 将 VertexData 对象应用到 mesh 上
let newMesh= new BABYLON.Mesh("newMesh", this.scene)
// 将数据和Mesh绑定
vertexData.applyToMesh(newMesh)
// 给Mesh添加材质
newMesh.material = shaderMaterial
当然这是创建一个Mesh的流程 你可以只给顶点和片段数据,不用赋材质之类的