Threejs实现物理运动模拟

一、物理运动原理

在 Three.js 中实现物理运动的核心思想是:

  1. Three.js 负责渲染:Three.js 是一个图形库,用于创建和渲染 3D 场景。
  2. 物理引擎负责计算:物理引擎(如 Cannon.js或 Ammo.js, 本文用的是前一种)模拟现实世界的物理规则,例如重力、碰撞、反弹等。
  3. 数据同步:在每一帧中,将物理引擎计算的结果(如物体的位置、速度、旋转等)同步到 Three.js 的对象上。

二、实现步骤详解

1. 初始化 Three.js 场景

initScene 方法中,创建 Three.js 的基本组件(场景、相机、渲染器等)。

function initScene() {
   
  if (!canvas.value) return
  makeRenderer(canvas.value.clientWidth, canvas.value.clientHeight)
  makeScene()
  makeCamera(canvas.value.clientWidth, canvas.value.clientHeight)
  orbitControls()
  addSky()
  addGround()
}
  • 初始化 WebGL 渲染器,并设置画布大小和设备像素比。 makeRenderer
  • 创建 Three.js 场景,并添加光源。 makeScene
  • 创建透视相机,并设置初始位置。 makeCamera
  • 添加轨道控制器,用于控制相机视角。 orbitControls
  • 和 :分别添加天空和地面。 addSky``addGround
2. 创建物理世界

使用 Cannon.js 创建物理世界,并设置重力。

world = new Cannon.World()
world.gravity.set(0, -9.82, 0) // 设置重力 (m/s²)
  • world.gravity.set(0, -9.82, 0):设置重力方向为向下(Y 轴负方向),模拟地球重力。
3. 创建物体并同步到物理引擎

在 Three.js 和物理引擎中分别创建物体,并保持它们之间的同步。

创建球体(Three.js 对象)
sphere = new THREE.Mesh(
  new THREE.SphereGeometry(2, 32, 32),
  new THREE.MeshBasicMaterial({
    color: 0xff11ff }),
)
sphere.position.set(0, 10, 0)
scene.add(sphere)
  • 使用 THREE.SphereGeometry 创建一个半径为 2 的球体。
  • 将球体添加到 Three.js 场景中。
创建对应的物理刚体(Cannon.js 对象)
const sphereBody = new Cannon.Body({
   
  mass: 1,
  shape: new Cannon.Sphere(2),
  position: new Cannon.Vec3(sphere.position.x, sphere.position.y, sphere.position.z),
})
world.addBody(sphereBody)
  • 使用 Cannon.Sphere 创建一个物理刚体,并设置质量为 1。
  • 将物理刚体添加到物理世界中。
添加地面
const groundBody = new Cannon.Body({
   
  mass: 0,
  shape: new Cannon.Plane(),
})
groundBody.quaternion.setFromEuler(-Math.PI / 2, 0, 0)
world.addBody(groundBody)
  • 创建一个静态的平面作为地面(mass: 0 表示静态物体)。
  • 使用 setFromEuler 旋转平面使其水平。
4. 动画循环

在每一帧中更新物理引擎的状态,并同步到 Three.js 场景。

function animate() {
   
  animationFrameId = requestAnimationFrame(animate)

  // 更新物理引擎
  updatePhysic()

  // 渲染场景
  renderer.render(scene, camera)
}

function updatePhysic() {
   
  world.step(1 / 60) // 模拟 60 帧每秒
  sphere.position.copy(sphereBody.position) // 同步位置
}
  • world.step(1 / 60):更新物理引擎的世界状态,模拟 60 帧每秒。
  • sphere.position.copy(sphereBody.position):将物理引擎计算的结果同步到 Three.js 的球体对象上。
5. 处理窗口大小调整

当窗口大小发生变化时,重新调整渲染器和相机的参数。

function onWindowResize() {
   
  if

你可能感兴趣的:(Threejs实现物理运动模拟)