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坐标.仍然以一个案例为例,场景由一个地面.若干网格组成的约束体和一些拥有初速度的球体组成,如下图.线案例请点击博客原文. 下面 ...
随机推荐
- Hadoop使用实例 词频统计和气象分析
一.词频统计 下载喜欢的电子书或大量文本数据,并保存在本地文本文件中 编写map与reduce函数 本地测试map与reduce 将文本数据上传至HDFS上 用hadoop streaming提交任务 ...
- HDFS 操作命令
本地文件系统创建一个文件,输入带姓名学号信息. 查看新建文件所在目录 查看新建文件内容 将此文件上传到HDFS文件系统上的用户目录 HDFS上查看相应目录 HDFS上查看文件内容 HDFS上查看文件大 ...
- STL(标准模板库)
STL 主要分为三类: container(容器) - 用来管理一组数据元素 lterator(迭代器) - 可遍历STL容器内全部或部分元素的对象 algorithm(算法) - 对数据进行处理(解 ...
- 11g RAC开启归档模式
1.关闭集群数据库 [oracle@rac01-+ASM1 ~]$ srvctl stop database -d rac 2.开启节点一数据库到mount状态 SQL> startup mou ...
- JavaSE11-多态&抽象类&接口
1.多态 1.1 多态的概述 什么是多态 同一个对象,在不同时刻表现出来的不同形态 多态的前提 要有继承或实现关系 要有方法的重写 要有父类引用指向子类对象 1.2 多态中的成员访问特点 成员访问特点 ...
- JavaSE09-(练手)简易学生管理系统
1.学生管理系统实现步骤 案例需求 系统主要功能如下: 添加学生:通过键盘录入学生信息,添加到集合中 删除学生:通过键盘录入要删除学生的学号,将该学生对象从集合中删除 修改学生:通过键盘录入要修改学生 ...
- DRF框架笔记
序列化器类的定义格式? 继承serializers.Serializer:字段 = serializers.字段类型(选项参数) 序列化器类的基本使用? 序列化器类(instance=None, da ...
- Flink批处理读取Hive写入MySql
把hive 表stu77 的数据写入 mysql 表test_stu 中. 中间可以加自己的逻辑. import org.apache.flink.table.api.EnvironmentSetti ...
- matplotlib的学习1-为什么学他
1.是一个非常强大的python画图的一个工具 2.手中有很多的数据,但是不知道如何呈现 matplotlib->能画出 线图; 散点图; 等高线图; 条形图; 柱状图; 3D 图形, 甚至是图 ...
- [GXYCTF2019]simple CPP
[GXYCTF2019]simple CPP 一.查壳 无壳,64位程序 二.IDA分析 找到主函数后动态调试,看的更清楚 经过调试后我们可以找到len就是储存字符串长度的变量,之后判断长度是不是大于 ...