cannon-es 物理引擎 中文翻译 (1)

入门

cannon-es 是一个web端轻量化并且很简单的3D物理引擎。
它的灵感来源于three.js的简单API,并基于ammon.js和Bullet物理引擎。

首先要建立的是我们的物理世界,它将容纳我们所有的物理体,并推动模拟向前发展。

让我们用地球引力创造一个世界。请注意,canon.js使用国际单位制(米、千克、秒等)。

const world = new CANNON.World({
  gravity: new CANNON.Vec3(0, -9.82, 0), // m/s²
})

为了推进模拟,我们必须在每帧调用world.fixedStep()。作为第一个参数,我们可以通过我们希望模拟运行的固定时间步长,默认值为1/60,即60fps。world.fixedStep()会跟踪上次调用它的时间,以使模拟保持相同的速度,而与帧速率无关,因为requestAnimationFrame调用在不同的设备上可能会有所不同,或者存在性能问题。

function animate() {
  requestAnimationFrame(animate)

  // Run the simulation independently of framerate every 1 / 60 ms
  world.fixedStep()
}
// Start the simulation loop
animate()

如果你想手动设置每帧间隔(就是游戏世界中的 dt),你可以使用更高级的world.step()。

下面是例子:

const timeStep = 1 / 60 // seconds
let lastCallTime
function animate() {
  requestAnimationFrame(animate)

  const time = performance.now() / 1000 // seconds
  if (!lastCallTime) {
    world.step(timeStep)
  } else {
    const dt = time - lastCallTime
    world.step(timeStep, dt)
  }
  lastCallTime = time
}
// Start the simulation loop
animate()

物体是将在世界上模拟的实体,它们可以是简单的形状,如球体、长方体、平面、圆柱体,也可以是更复杂的形状,例如凸多面体、粒子、Heightfield、Trimesh。

让我们创建一个基本的球体。

const radius = 1 // m
const sphereBody = new CANNON.Body({
  mass: 5, // kg
  shape: new CANNON.Sphere(radius),
})
sphereBody.position.set(0, 10, 0) // m
world.addBody(sphereBody)

正如你所看到的,我们指定了一个质量特性,质量定义了物体受力影响时的行为。

当物体有质量并受到力的影响时,它们被称为动力学物体。还有一些运动学物体不受力的影响,但可以有一定的速度并四处移动。第三类物体是静态物体,它只能定位在世界上,不受力和速度的影响。

如果将质量0传递给实体,则该实体将自动标记为静态实体。也可以在实体选项中显式显示实体类型。例如,让我们创建一个静态地面。

const groundBody = new CANNON.Body({
  type: CANNON.Body.STATIC,
  shape: new CANNON.Plane(),
})
groundBody.quaternion.setFromEuler(-Math.PI / 2, 0, 0) // make it face up
world.addBody(groundBody)

以下是前面的所有片段,它们组合在一个完整的示例中。

import * as CANNON from 'cannon-es'

// Setup our physics world
const world = new CANNON.World({
  gravity: new CANNON.Vec3(0, -9.82, 0), // m/s²
})

// Create a sphere body
const radius = 1 // m
const sphereBody = new CANNON.Body({
  mass: 5, // kg
  shape: new CANNON.Sphere(radius),
})
sphereBody.position.set(0, 10, 0) // m
world.addBody(sphereBody)

// Create a static plane for the ground
const groundBody = new CANNON.Body({
  type: CANNON.Body.STATIC, // can also be achieved by setting the mass to 0
  shape: new CANNON.Plane(),
})
groundBody.quaternion.setFromEuler(-Math.PI / 2, 0, 0) // make it face up
world.addBody(groundBody)

// Start the simulation loop
function animate() {
  requestAnimationFrame(animate)

  world.fixedStep()

  // the sphere y position shows the sphere falling
  console.log(`Sphere y position: ${sphereBody.position.y}`)
}
animate()

请注意,cannon并不负责将任何东西渲染到屏幕上,它只计算模拟的数学运算。要真正在屏幕上显示内容,您必须使用诸如three.js之类的渲染库。让我们看看如何实现这一点。

首先,你必须在three.js中创建身体的对应实体。例如,下面是如何在three.js中创建球体的。

const radius = 1 // m
const geometry = new THREE.SphereGeometry(radius)
const material = new THREE.MeshNormalMaterial()
const sphereMesh = new THREE.Mesh(geometry, material)
scene.add(sphereMesh)

然后,您必须将three.js网格与cannon.js主体连接起来。要做到这一点,请在步进世界后的每一帧将位置和旋转数据从实体复制到网格。

function animate() {
  requestAnimationFrame(animate)

  // world stepping...

  sphereMesh.position.copy(sphereBody.position)
  sphereMesh.quaternion.copy(sphereBody.quaternion)

  // three.js render...
}
animate()

你现在应该在屏幕上看到一个落下的球了!查看基本的three.js示例以获取完整的代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值