初探 Threejs 物理引擎CANNON,解锁 3D 动态魅力

简介

Cannon.js 是一个基于 JavaScript 的物理引擎,它可以在浏览器中模拟物理效果。它支持碰撞检测、刚体动力学、约束等物理效果,可以用于创建逼真的物理场景和交互。

参考文档

官方示例

原理

Cannon.js 使用了欧拉角来表示物体的旋转,而不是四元数。这使得它在处理旋转时更加直观和易于理解。Cannon.js 还支持多种碰撞检测算法,包括离散碰撞检测和连续碰撞检测。

Cannon.js 还支持多种约束类型,包括固定约束、滑动约束和铰链约束等。这些约束可以用于限制物体的运动,例如将两个物体固定在一起,或者将一个物体限制在一个滑动路径上。这使得 Cannon.js 可以创建逼真的物理场景和交互。

安装

npm install cannon-es

使用

需要要使用 Cannon.js,首先需要创建一个物理世界,然后向其中添加物体和约束。接下来,在每个时间步长中更新物理世界,并使用物理世界中的物体和约束来计算物体的位置和旋转,由于在物理世界中创建的物体是看不到的,所以需要将这些位置和旋转应用到 Three.js 场景中的物体上。

引入

import * as CANNON from "cannon-es";

创建物理世界

const world = new CANNON.World();
world.gravity.set(0, -9.82, 0); // 设置重力

word.gravity: 属性用于设置物理世界的重力。

  • x: 重力的 x 分量。
  • y: 重力的 y 分量。
  • z: 重力的 z 分量。

创建物体

//物理世界物体
const sphereShape = new CANNON.Sphere(1); // 创建一个球体形状
const sphereBody = new CANNON.Body({mass: 1,shape: sphereShape,position: new CANNON.Vec3(0, 5, 0),
}); // 创建一个球体物体
world.addBody(sphereBody); // 将球体添加到物理世界中
//Three.js 场景中的物体
const sphereGeometry = new THREE.SphereGeometry(1, 32, 32); // 创建一个球体几何体
const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); // 创建一个球体材质
const sphereMesh = new THREE.Mesh(sphereGeometry, sphereMaterial); // 创建一个球体网格
scene.add(sphereMesh); // 将球体网格添加到场景中

CANNON.Sphere(): 方法用于创建一个球体形状。

  • radius: 球体的半径。

CANNON.Body(): 方法用于创建一个物体。

  • mass: 物体的质量。
  • shape: 物体的形状。
  • position: 物体的位置。

world.addBody(): 方法用于将物体添加到物理世界中。

更新物理世界

function animate() {requestAnimationFrame(animate);world.step(1 / 60); // 更新物理世界// 将物理世界中的球体位置应用到 Three.js 场景中的球体网格上sphereMesh.position.copy(sphereBody.position);// 将物理世界中的球体旋转应用到 Three.js 场景中的球体网格上sphereMesh.quaternion.copy(sphereBody.quaternion);renderer.render(scene, camera); // 渲染场景
}
animate();

world.step(): 方法用于更新物理世界中的物体和约束的状态。

  • dt: 时间步长,用于计算物体的运动和碰撞。
  • time: 当前时间,用于计算物体的运动和碰撞。
  • correction: 时间步长修正,用于修正时间步长导致的误差。

copy(): 方法用于将一个向量的值复制到另一个向量中。

  • v: 要复制的向量。

在这里插入图片描述

碰撞检测

Cannon.js 支持多种碰撞检测算法,包括离散碰撞检测和连续碰撞检测。离散碰撞检测是在每个时间步长中检查物体之间的碰撞,而连续碰撞检测则是在物体之间可能发生碰撞的路径上插入额外的检查点。这使得 Cannon.js 可以处理复杂的碰撞场景,例如物体之间的穿透和重叠。

const groundShape = new CANNON.Box(new CANNON.Vec3(5, 0.1, 5));
const groundBody = new CANNON.Body({shape: groundShape,position: new CANNON.Vec3(0, 0, 0),type: CANNON.Body.STATIC,
});
groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), 0.1);
world.addBody(groundBody);//创建一个平面的几何体
const groundGeometry = new THREE.BoxGeometry(10, 0.2, 10);
//创建一个平面的材质
const groundMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 });
//创建一个平面的网格
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
//设置平面的位置
ground.position.x = 0.1;
//将平面添加到场景中
scene.add(ground);

CANNON.Plane(): 方法用于创建一个平面形状。

CANNON.Box(): 方法用于创建一个盒子形状。

setFromAxisAngle(): 方法用于设置物体的旋转。

  • axis: 旋转轴。
  • angle: 旋转角度。

body.type: 物体的类型

  • CANNON.Body.KINEMATIC: 物体是动态的,可以移动和旋转。
  • CANNON.Body.STATIC: 物体是静态的,不能移动和旋转。
  • CANNON.Body.DYNAMIC: 物体是动态的,可以移动和旋转,并且受到物理世界的重力和其他力的作用。
const groundBody = new CANNON.Body({shape: groundShape,position: new CANNON.Vec3(0, 0, 0),type: CANNON.Body.STATIC, // 设置物体类型为静态
}); 

示例

import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
//引入CannonJS
import * as CANNON from "cannon-es";// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
camera.position.y = 5;
camera.position.x = -10;// 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);// 创建物理世界
const world = new CANNON.World();
world.gravity.set(0, -9.82, 0);// 创建一个球体
const sphereShape = new CANNON.Sphere(1);
const sphereBody = new CANNON.Body({mass: 1,shape: sphereShape,position: new CANNON.Vec3(0, 5, 0),
});
world.addBody(sphereBody);// 创建一个平面
const groundShape = new CANNON.Box(new CANNON.Vec3(5, 0.1, 5));
const groundBody = new CANNON.Body({shape: groundShape,position: new CANNON.Vec3(0, 0, 0),type: CANNON.Body.STATIC,
});
groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), 0.1);
world.addBody(groundBody);//创建一个球体的几何体
const sphereGeometry = new THREE.SphereGeometry(0.5, 32, 32);
//创建一个球体的材质
const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
//创建一个球体的网格
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
//将球体添加到场景中
scene.add(sphere);//创建一个平面的几何体
const groundGeometry = new THREE.BoxGeometry(10, 0.2, 10);
//创建一个平面的材质
const groundMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 });
//创建一个平面的网格
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
//设置平面的位置
ground.position.x = 0.1;
//将平面添加到场景中
scene.add(ground);//创建控制器
const controls = new OrbitControls(camera, renderer.domElement);
// 启用阻尼效果
controls.enableDamping = true;function animate() {requestAnimationFrame(animate);world.step(1 / 60);sphere.position.copy(sphereBody.position);sphere.quaternion.copy(sphereBody.quaternion);renderer.render(scene, camera);
}animate();//监听窗口大小变化
window.addEventListener("resize", () => {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);
});

在这里插入图片描述
书洞笔记

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/34373.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【小沐学Web3D】three.js 加载三维模型(React)

文章目录 1、简介1.1 three.js1.2 react.js 2、three.js React结语 1、简介 1.1 three.js Three.js 是一款 webGL(3D绘图标准)引擎,可以运行于所有支持 webGL 的浏览器。Three.js 封装了 webGL 底层的 API ,为我们提供了高级的…

简述计算机网络中的七层模型和四层模型

在计算机网络中,网络协议栈的设计通常采用分层结构来处理不同的通信任务。常见的分层结构有OSI七层模型和TCP/IP四层模型。虽然它们的层次数量不同,但本质上都在解决如何有效地进行计算机间通信。本文将分别介绍这两种结构的功能和各层的协议。 一、OSI七…

在 CentOS 上安装 Oracle 数据库

文章目录 **1. 系统准备****1.1 检查系统要求****1.2 更新系统****1.3 安装必要的依赖包****1.4 创建 Oracle 用户和组****1.5 配置内核参数****1.6 配置用户限制****1.7 配置 PAM 模块****1.8 创建 Oracle 安装目录** **2. 下载 Oracle 数据库安装包****2.1 访问 Oracle 官方网…

掌握这些 UI 交互设计原则,提升产品易用性

在当今数字化时代,用户对于产品的体验要求越来越高,UI 交互设计成为决定产品成败的关键因素之一。一个易用的产品能够让用户轻松、高效地完成各种操作,而实现这一目标的核心在于遵循一系列科学合理的 UI 交互设计原则。本文将详细阐述简洁性、…

创新实践分享:基于边缘智能+扣子的智能取物机器人解决方案

在 2024 年全国大学生物联网设计竞赛中,火山引擎作为支持企业,不仅参与了赛道的命题设计,还为参赛队伍提供了相关的硬件和软件支持。以边缘智能和扣子的联合应用为核心,参赛者们在这场竞赛中展现出了卓越的创新性和实用性&#xf…

Python----数据可视化(Pyecharts一:介绍安装,全局配置,系列配置)

一、PyEcharts介绍 1.1、概况 Echarts 是一个由百度开源的数据可视化,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。而 Python 是一门富有表达力的语言,很适合用于数据处理。当数据分析遇上数据可视化时&#xff…

Cursor初体验:excel转成CANoe的vsysvar文件

今天公司大佬先锋们给培训了cursor的使用,还给注册了官方账号!跃跃欲试,但是测试任务好重,结合第三方工具开发也是没有头绪。 但巧的是,刚好下午有同事有个需求,想要把一个几千行的excel转成canoe的系统变…

【3DGS】SuperSplat本地运行+修改监听端口+导入ply模型+修剪模型+在线渲染3DGS网站推荐

SuperSplat官网代码:https://github.com/playcanvas/supersplat 本地安装和运行 Clone the repository: git clone https://github.com/playcanvas/supersplat.git cd supersplat Install dependencies: npm install Build SuperSplat and start a local web ser…

MySQL中的B+树索引经验总结

一、什么是B树 B树是一种二叉树,由二叉查找树,平衡二叉树,B树演化而来。 请看上图 B树的特点: 1)非叶子节点不存放数据,只存放键值,数据都存放在叶子节点中。 2)叶子节点都在同一…

C# NX二次开发:在多个体的模型中如何实现拉伸操作布尔减

大家好,今天接着上一篇拉伸文章去讲。 UF_MODL_create_extruded1 (view source) uf_list_p_tobjectsInputList of objects to be extruded.char *taper_angleInputTaper angle (in degrees).char *limit [ 2 ]InputLimit of extrusion. This is declared as: char …

【深度学习】多源物料融合算法(一):量纲对齐常见方法

目录 一、引言 二、量纲对齐常见方法 2.1 Z-score标准化Sigmoid归一化 2.2 Min-Max 归一化 2.3 Rank Transformation 2.4 Log Transformation 2.5 Robust Scaling 3、总结 一、引言 类似抖音、快手、小红书等产品的信息流推荐业务,主要通过信息流广告、信…

前端高级CSS用法

前端高级CSS用法 在前端开发中,CSS(层叠样式表)不仅是用来控制网页的外观和布局,更是实现复杂交互和动态效果的关键技术之一。随着前端技术的不断发展,CSS的用法也日益丰富和高级。本文将深入探讨前端高级CSS的用法&a…

How to install a package in offline scenario in Ubuntu 24.04

概述 做过信创项目的兄弟们在工作上每天可能面对很多需要解决的问题,不过,有一类问题可能是大家经常遇的,比方说,有时候我们不得不硬着头皮在离线生产环境中安装某些软件包,相信很多兄弟被这种细碎的小事搞得焦头烂额…

C++类与对象——拷贝构造与运算符重载

拷贝构造函数和赋值运算符重载就是C类默认六个函数之二。 拷贝构造函数: 如果⼀个构造函数的第⼀个参数是自身类类型的引用,且任何额外的参数都有默认值,则此构造函数 也叫做拷贝构造函数,也就是说拷贝构造是⼀个特殊的构造函数…

数学建模 第一节

目录​​​​​​ 前言 一 优化模型的类型 二 线性规划1 线性规划2 三 0-1规划 总结 前言 数学建模主要是将问题转化为模型,然后再以编程的形式输出出来 算法都知道,数学建模也需要用到算法,但是不是主要以编程形式展示,而是…

计算机网络——DNS

一、什么是DNS? DNS(Domain Name System,域名系统) 是互联网的核心服务,负责将人类可读的域名(如 www.baidu.com)转换为机器可识别的 IP地址(如 14.119.104.254)。它像一…

【软考-架构】5.2、传输介质-通信方式-IP地址-子网划分

✨资料&文章更新✨ GitHub地址:https://github.com/tyronczt/system_architect 文章目录 传输介质网线光纤无线信道 通信方式和交换方式会考:交换方式 💯考试真题第一题第二题 IP地址表示子网划分💯考试真题第一题第二题 传输…

基于SpringBoot+Vue的毕业论文管理系统+LW示例参考

1.项目介绍 系统角色:管理员、指导教师、评阅教师、学生功能模块:用户管理、毕业论文管理、课题信息管理、选题申请管理、课题任务管理、基础数据管理、公告信息管理、评阅教师管理、指导教师管理等技术选型:SpringBoot,Vue等测试…

文件系统 linux ─── 第19课

前面博客讲解的是内存级文件管理,接下来介绍磁盘级文件管理 文件系统分为两部分 内存级文件系统 : OS加载进程 ,进程打开文件, OS为文件创建struct file 和文件描述符表 ,将进程与打开的文件相连, struct file 内还函数有指针表, 屏蔽了底层操作的差异,struct file中还有内核级…

第十次CCF-CSP认证(含C++源码)

第十次CCF-CSP认证 分蛋糕满分题解 学生排队满分题解 Markdown语法题目解读满分代码 结语 分蛋糕 题目链接 满分题解 基本思路:我们需要保证除了最后一个小朋友之外的所有人,分得的蛋糕都大于等于给定的K值,为什么是大于等于,是…