Threejs 物理引擎高阶:作用力、休眠与组合体奥秘

休眠

当一个物体在小范围内移动时,物理引擎会认为它是静止的,此时物体就会进入休眠状态,不再受到物理引擎的影响。休眠状态可以减少物理引擎的计算量,提高性能。

  • 设置物理世界休眠
js 复制代码
const world = new CANNON.World();
world.allowSleep = true;

allowSleep: 是否允许休眠,默认为 false。

  • 设置物体休眠
js 复制代码
const boxBody = new CANNON.Body({
  shape: new CANNON.Box(new CANNON.Vec3(0.5, 0.5, 0.5)),
  position: new CANNON.Vec3(-2, 5, 0),
  mass: 1,
  material: boxMaterialCon,
  collisionFilterGroup: GROUP1,
  collisionFilterMask: GROUP1 | GROUP2 | GROUP3 | GROUP4,
});
boxBody.allowSleep = true; // 允许休眠
boxBody.sleepSpeedLimit = 0.5; //速度小于0.5时休眠
boxBody.sleepTimeLimit = 1; // 休眠时间超过1秒
world.addBody(boxBody);

sleepSpeedLimit: 速度小于该值时,物体进入休眠状态。

sleepTimeLimit: 休眠时间超过该值时,物体从休眠状态恢复。

休眠事件

当物体从运动状态到休眠状态,会触发很多事件,我们可以监听这些事件,做一些操作。

  • 监听物体休眠事件
js 复制代码
boxBody.addEventListener("sleep", () => {
  console.log("休眠");
});
  • 监听即将休眠事件
js 复制代码
boxBody.addEventListener("sleepy", () => {
  console.log("即将休眠");
});

物体组合

将多个物体组合成一个物体,可以减少物理引擎的计算量,提高性能。

js 复制代码
// 创建一个物理组合体
const capsuleBody = new CANNON.Body({
  mass: 1,
  position: new CANNON.Vec3(0, 4, 0),
  material: boxMaterialCon,
  collisionFilterGroup: GROUP2,
  collisionFilterMask: GROUP1 | GROUP2 | GROUP3,
});
//创建球体
const sphereShape = new CANNON.Sphere(0.5);
//创建圆柱体
const cylinderShape = new CANNON.Cylinder(0.5, 0.5, 1.5, 20);
//创建胶囊体
capsuleBody.addShape(sphereShape, new CANNON.Vec3(0, 0.75, 0));
capsuleBody.addShape(cylinderShape, new CANNON.Vec3(0, 0, 0));
capsuleBody.addShape(sphereShape, new CANNON.Vec3(0, -0.75, 0));
capsuleBody.velocity.set(2, 0, 0); //设置速度
world.addBody(capsuleBody);

//创建胶囊体网格
const capsuleGeometry = new THREE.CylinderGeometry(0.5, 0.5, 1.5, 20);
const capsuleMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const capsule = new THREE.Mesh(capsuleGeometry, capsuleMaterial);
capsule.position.copy(capsuleBody.position);
capsule.quaternion.copy(capsuleBody.quaternion);
scene.add(capsule);
//创建球体网格
const sphereGeometry = new THREE.SphereGeometry(0.5, 20, 20);
const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere.position.set(0, 0.75, 0);
capsule.add(sphere);
const sphere2 = new THREE.Mesh(sphereGeometry, sphereMaterial);
sphere2.position.set(0, -0.75, 0);
capsule.add(sphere2);

addShape: 添加形状,第一个参数为形状,第二个参数为形状相对于物体的位置。

施加力

给物体施加力,可以让物体运动。

applyForce

js 复制代码
//创建物理球
const sphereBody = new CANNON.Body({
  mass: 1,
  shape: new CANNON.Sphere(0.5),
  position: new CANNON.Vec3(0, 5, 0),
  material: boxMaterialCon,
  collisionFilterGroup: GROUP2,
  collisionFilterMask: GROUP1 | GROUP2 | GROUP3,
});
world.addBody(sphereBody);

//创建3D球
const sphereGeometry = new THREE.SphereGeometry(0.5, 8, 8);
const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true });
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
scene.add(sphere);

//监听鼠标点击事件
window.addEventListener("click", () => {
  console.log("点击了:", sphereBody.position);
  sphereBody.applyForce(new CANNON.Vec3(10, 0, 0), sphereBody.position);
});

applyForce: 施加力,第一个参数为力的大小,第二个参数为力的方向。

applyLocalForce

js 复制代码
sphereBody.quaternion.setFromAxisAngle(new CANNON.Vec3(0, 0, 1), Math.PI / 2); //设置旋转

window.addEventListener("click", () => {
  console.log("点击了:", sphereBody.position);
  sphereBody.applyLocalForce(new CANNON.Vec3(10, 0, 0), new CANNON.Vec3(0, -0.5, 0));
});

applyLocalForce: 施加局部力,第一个参数为力的大小,第二个参数为力的方向。

这个是相对物体自身的力,物体自身旋转后,力的方向也会跟着旋转。就会出现向后滚动的效果。

applyImpulse

js 复制代码
sphereBody.applyImpulse(new CANNON.Vec3(10, 0, 0), sphereBody.position);

applyImpulse: 施加冲量,第一个参数为冲量的大小,第二个参数为冲量的方向。

冲量是力的积累,力的作用时间越长,冲量越大。所以如果想达到上面的效果,就需要修改冲量的大小。如果是 60 帧,那么就需要将冲量的大小改为 new CANNON.Vec3(10*(1/60), 0, 0)

applyTorque

js 复制代码
sphereBody.applyTorque(new CANNON.Vec3(0, 0, 10));

applyTorque: 施加扭矩,第一个参数为扭矩的大小,第二个参数为扭矩的方向。

书洞笔记

相关推荐
donecoding31 分钟前
一个 sudo 引发的血案:npm 全局包权限错乱彻底修复
前端·node.js·前端工程化
风骏时光牛马35 分钟前
Raku正则匹配与数据批量处理实操案例
前端
nbwenren38 分钟前
2026实测:Gemini 3 镜像站视觉能力实践——拍照原型图,一键生成 HTML+CSS 代码
前端·css·html
Lee川41 分钟前
Prisma 实战指南:像搭积木一样设计古诗词数据库
前端·数据库·后端
jinanwuhuaguo1 小时前
(第二十九篇)OpenClaw 实时与具身的跃迁——从异步孤岛到数字世界的“原住民”
前端·网络·人工智能·重构·openclaw
广州华水科技1 小时前
深度测评2026年单北斗GNSS位移监测系统推荐,与高口碑变形监测设备一同引领行业新风尚
前端
Alice-YUE2 小时前
【js高频八股】防抖与节流
开发语言·前端·javascript·笔记·学习·ecmascript
是上好佳佳佳呀3 小时前
【前端(十一)】JavaScript 语法基础笔记(多语言对比)
前端·javascript·笔记
CDN3604 小时前
排查实录:网站偶发502/504错误?360CDN回源超时配置与日志分析技巧
前端·数据库