three.js 之cannon.js物理引擎
今天郭先生说的是一个物理引擎,它十分小巧并且操作简单,没错他就是cannon.js。这些优点都源自于他是基于js编写的,对于js使用者来说cannon.js拥有其他物理引擎没有的纯粹性。从学习成本来看,cannon.js的学习成本比较低,对于新手来说比较友好,因为它有相对完善的api,学习cannon.js之前我们不妨来看看cannons.js的官方网站以及他的API,对于js学习者来说这是十分必要的。官网上面有一些example,他们十分典型并囊括了大多数的知识点,配合api一起学习是个不错的选择。在线案例请点击博客原文。效果如下图,接下来以一个小案例,简单的介绍一下cannon.js。

1. 初始化three场景
创建three场景(或者说three世界)来作为物理世界的载体,这一步很简单,主要就是添加渲染器、场景、相机和网格等three元素,没必要多说。
scene = new THREE.Scene();//step 1 创建场景 camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.y = 30;
camera.position.z = 20;
camera.lookAt(0,5,0);
scene.add( camera ); //step 2 场景中添加相机 scene.add(new THREE.AmbientLight(0x888888));
const light = new THREE.DirectionalLight(0xbbbbbb, 1);
light.position.set(6, 30, 6);
scene.add(light); //step 3 场景中添加另种光源 renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
renderer.setClearColor(0xbfd1e5);
this.$refs.box.appendChild(renderer.domElement); //step 4 dom中添加渲染器 let groundGeom = new THREE.BoxBufferGeometry(40, 0.2, 40);
let groundMate = new THREE.MeshPhongMaterial({color: 0xdddddd, map: texture})
ground = new THREE.Mesh(groundGeom, groundMate);
ground.position.y = -0.1;
ground.receiveShadow = true;
scene.add(ground); //step 5 添加地面网格
2. 初始化物理世界
这里是初始化物理世界,我们详细的讲一下他们的用法。
initCannon() {
world = new CANNON.World(); //该方法初始化物理世界,里面包含着物理世界的相关数据(如刚体数据,世界中所受外力等等)
world.gravity.set(0,-9.8,0); //设置物理世界的重力为沿y轴向上-9.8米每二次方秒
world.broadphase = new CANNON.NaiveBroadphase();//NaiveBroadphase是默认的碰撞检测方式,该碰撞检测速度比较高
world.solver.iterations = 5;//解算器的迭代次数,更高的迭代次数意味着更加精确同时性能将会降低
bodyGround = new CANNON.Body({ //创建一个刚体(物理世界的刚体数据)
mass: 0, //刚体的质量,这里单位为kg
position: new CANNON.Vec3(0, -0.1, 0), //刚体的位置,单位是米
shape: new CANNON.Box(new CANNON.Vec3(20, 0.1, 20)), //刚体的形状(这里是立方体,立方体的参数是一个包含半长、半宽、半高的三维向量,具体我们以后会说)
material: new CANNON.Material({friction: 0.05, restitution: 0}) //材质数据,里面规定了摩擦系数和弹性系数
});
ground.userData = bodyGround; //将刚体的数据赋值给地面网格的userData属性
world.addBody(bodyGround); //物理世界添加地面刚体
},
3. 向场景中添加网格并向物理世界中添加刚体数据
这里我们通过setInterval函数我们定时向场景中添加网格并向物理世界中添加刚体数据,
interval = setInterval(() => {
this.createBox(); //创建网格和刚体的方法
}, 200);
下面是具体的方法
createBox() {
let x = Math.random() * 10 - 5;
let z = Math.random() * 10 - 5;
let box = new THREE.Mesh( geometry, this.createRandomMaterial() ); //createRandomMaterial创建随机颜色的材质
box.position.set(x, 20, z);
scene.add( box ); //创建box,并添加到场景
let bodyBox = new CANNON.Body({
mass: 1,
position: new CANNON.Vec3(x, 20, z),
shape: new CANNON.Box(new CANNON.Vec3(1,1,1)),
material: new CANNON.Material({friction: 0.1, restitution: 0})
});//创建一个质量为1kg,位置为(x,20,z),形状为halfSize为1,1,1的正方形刚体,材质中摩擦系数为0.1,弹性系数为0。
box.userData = bodyBox;//给box的userData属性添加刚体数据
world.addBody(bodyBox);//在物理世界中添加该刚体
setTimeout(() => { //10秒钟之后在场景中移除box,并在物理世界中移除该刚体
scene.remove(box);
box.material.dispose();
box.geometry.dispose();
world.removeBody(bodyBox);
}, 10000)
},
4. 根据物理引擎的数据更新three网格数据
这一步我们逐帧根据物理引擎的数据渲染three场景
animation() { //requestAnimationFrame动画中调用render方法
this.globalID = requestAnimationFrame(this.animation);
this.render();
},
render() { //更新性能插件,根据物理引擎数据更新网格数据,最后渲染场景
stats.update();
this.updatePhysics();
renderer.render( scene, camera );
},
updatePhysics() { // world.step
world.step(timeStep); //第一个参数是以固定步长更新物理世界参数(详情请看api)
scene.children.forEach(d => {//遍历场景中的子对象,如果对象的isMesh属性为true,我们就将更新改对象的position和quaternion属性(他们对应的刚体数据存在对应的userData中)。
if(d.isMesh == true) {
d.position.copy(d.userData.position);
d.quaternion.copy(d.userData.quaternion);
}
})
}
这样我们就将cannon.js物理引擎应用到了three中。不出意外的话,接下来我会讲解一下官方的examples。
转载请注明地址:郭先生的博客
three.js 之cannon.js物理引擎的更多相关文章
- 基于Babylon.js编写宇宙飞船模拟程序1——程序基础结构、物理引擎使用、三维罗盘
计划做一个宇宙飞船模拟程序,首先做一些技术准备. 可以访问https://ljzc002.github.io/test/Spacetest/HTML/PAGE/spacetestwp2.html查看测 ...
- 造个海洋球池来学习物理引擎【Three.js系列】
github地址:https://github.com/hua1995116/Fly-Three.js 大家好,我是秋风.继上一篇<Three.js系列: 游戏中的第一/三人称视角>今 ...
- three.js cannon.js物理引擎地形生成器和使用指针锁定控件
今天郭先生说一说使用cannon.js物理引擎绘制地形和使用指针锁定控件.效果如下图.线案例请点击博客原文. 这里面的生成地形的插件和指针锁定控件也是cannon.js的作者schteppe封装的,当 ...
- three.js cannon.js物理引擎之Heightfield
今天郭先生说一说cannon.js物理引擎之Heightfield高度场,学过场论的朋友都知道物理学中把某个物理量在空间的一个区域内的分布称为场,高度场就是与高度相关的场,而cannon.js物理引擎 ...
- three.js cannon.js物理引擎之制作拥有物理特性的汽车
今天郭先生说一说使用cannon.js的车辆辅助类让我们的汽车模型拥有物理特性.效果图如下,在线案例请点击博客原文. 下面我们说一下今天要使用的两个类,并简单的看看他们的物理意义 1. Raycast ...
- three.js cannon.js物理引擎制作一个保龄球游戏
关于cannon.js我们已经学习了一些知识,今天郭先生就使用已学的cannon.js物理引擎的知识配合three基础知识来做一个保龄球小游戏,效果如下图,在线案例请点击博客原文. 我们需要掌握的技能 ...
- three.js cannon.js物理引擎之ConvexPolyhedron多边形
年后第一天上班,郭先生来说一说cannon.js的ConvexPolyhedron(多边形),cannon.js是一个物理引擎,内部通过连续的计算得到各个时间点的数据的状态,three.js的模型可以 ...
- three.js cannon.js物理引擎之齿轮动画
郭先生今天继续说一说cannon.js物理引擎,并用之前已经学习过的知识实现一个小动画,知识点包括ConvexPolyhedron多边形.Shape几何体.Body刚体.HingeConstraint ...
- three.js cannon.js物理引擎之约束
今天郭先生继续说cannon.js,主演内容就是点对点约束和2D坐标转3D坐标.仍然以一个案例为例,场景由一个地面.若干网格组成的约束体和一些拥有初速度的球体组成,如下图.线案例请点击博客原文. 下面 ...
随机推荐
- 使用纯js 不导包实现 table 导出 Excel
1.将js粘贴到项目 2.设置table标签 id3.定义按钮,调用方法即可 1 <!DOCTYPE html> 2 <html lang="zh_CN"> ...
- Kubernetes 最佳安全实践指南
原文链接:https://fuckcloudnative.io/posts/security-best-practices-for-kubernetes-pods/ 对于大部分 Kubernetes ...
- 超详细分析Bootloader到内核的启动流程(万字长文)
@ 目录 Bootloader启动流程分析 Bootloader第一阶段的功能 硬件设备初始化 为加载 Bootloader的第二阶段代码准备RAM空间(初始化内存空间) 复制 Bootloader的 ...
- 仵航说 Vue用replace修改数组中对象的键值或者字段名 仵老大
仵航说 Vue用replace修改数组中对象的键值或者字段名 仵老大 1.介绍 先看图 今天在项目中遇到了一个问题,例如我现在需要传一些数据到后端,数组例如是 let arr = [ {" ...
- Java详细指南
Java 基础 并发 JVM Java8 新特性 代码优化 网络 操作系统 数据结构与算法 数据库 系统设计 设计模式 常用框架 网站架构 软件底层 其他 Java 基础 <Head First ...
- robotframework中的参数展开
robot调用关键字传参的方式是用分隔符分开不同参数,如 keyword arg1 arg2 arg3 arg4 当参数中传入了使用@符号的列表变量时,@符号会将列表展开: @{list1}= Cre ...
- Redisearch实现的全文检索功能服务
"检索"是很多产品中无法绕开的一个功能模块,当数据量小的时候可以使用模糊查询等操作凑合一下,但是当面临海量数据和高并发的时候,业界常用 elasticsearch 和 lucene ...
- 数组单调性判断以及all和diff函数的用法
clc;clear all;close all; n = 1 ;x = zeros(100,1);while n~= 0 n = input('请输入向量的长度n(0退出程序):'); for i = ...
- python初学者-从键盘输入两个数判断大小
a = int(input("a:")) b = int(input("b:")) if a > b : print(a) else : print(b)
- 4.mysql profile的使用方法
profile的使用 1.作用 使用profile可以对某一条sql性能进行分析 2.语法 mysql> show variables like '%profil%'; +----------- ...