three.js cannon.js物理引擎之约束(二)
今天郭先生继续讲cannon.js的物理约束,之前的一篇文章曾简单的提及过PointToPointConstraint约束,那么今天详细的说一说cannon.js的约束和使用方法。在线案例请点击博客原文。
1. cannon.js约束的种类
1. PointToPointConstraint点对点约束
它的构造函数如下(之前可能介绍过了,这次统一说)
PointToPointConstraint ( bodyA pivotA bodyB pivotB maxForce )
- bodyA — 刚体A。
- pivotA — 相对于刚体A的质心的点,刚体A被约束到该点。
- bodyB — 刚体B。
- pivotB — 相对于刚体B的质心的点,刚体B被约束到该点。
- maxForce — 约束物体应施加的最大力。
点对点约束顾名思义就是A刚体的某一点和B刚体的某一点形成约束,刚体之间仅通过约束点相连,如下图。

2. LockConstraint锁定约束
它的构造函数如下
LockConstraint ( bodyA bodyB { maxForce } )
- bodyA — 刚体A。
- bodyB — 刚体B。
- maxForce — 约束物体应施加的最大力。
为什么不需要设置约束点的位置呢,因为锁定约束其实就是点对点约束的简化版本,他们pivotA和pivotB默认为刚体的中心,如下图。

3. DistanceConstraint距离约束
它的构造函数如下
DistanceConstraint ( bodyA bodyB distance maxForce )
- bodyA — 刚体A。
- bodyB — 刚体B。
- distance — 要保持的距离。如果未定义,它将被设置为刚体A和刚体B之间的当前距离。
- maxForce — 约束物体应施加的最大力。
距离约束将两个物体约束为彼此重心的距离恒定,如下图是相邻小球保持恒定距离。

4. HingeConstraint铰链约束
它的构造函数如下
HingeConstraint ( bodyA bodyB { pivotA axisA pivotB axisB maxForce } )
- bodyA — 刚体A。
- bodyB — 刚体B。
- pivotA — 相对于刚体A的质心的点,刚体A被约束到该点。
- axisA — 在刚体A中局部定义的刚体A可以绕其旋转的轴。
- pivotB — 相对于刚体B的质心的点,刚体B被约束到该点。
- axisB — 在刚体B中局部定义的刚体B可以绕其旋转的轴。
- maxForce — 约束物体应施加的最大力。
铰链又称合页,这个约束就像门的铰链一样,让两个物理只能在各自的点沿着固定的轴旋转。如下图。

2. 案例的主要代码
下面是案例的主要代码
var bodies = [], meshes = [];
initPoint() {
var size = 0.5;
var boxShape = new CANNON.Box(new CANNON.Vec3(size,size,size));
var mass = 0;
var N=10, last;
for(var i=0; i<N; i++){
// Create a box
var boxbody = new CANNON.Body({
mass: mass,
shape: boxShape,
position: new CANNON.Vec3(i * 0.6, (N - i) * Math.sqrt(size * size * 3) * 2, 0),
quaternion: new CANNON.Quaternion().setFromEuler(-Math.PI / 4, -Math.PI / 4, 0),
material: pubMaterial
});
boxbody.angularDamping = 0.3;
bodies.push(boxbody);
world.addBody(boxbody);
if(i == 0) {
mass = 1;
} else {
var c = new CANNON.PointToPointConstraint(boxbody, new CANNON.Vec3(size, size ,size), last, new CANNON.Vec3(-size, -size ,-size));
world.addConstraint(c);
}
last = boxbody;
}
for(let i=0; i<10; i++) {
let mesh = new THREE.Mesh(new THREE.BoxBufferGeometry(1), new THREE.MeshNormalMaterial());
meshes.push(mesh);
scene.add(mesh);
}
console.log(world)
}
initLock() {
var size = 0.5;
var boxShape = new CANNON.Box(new CANNON.Vec3(size,size,size));
var mass = 1;
var space = 0.1*size;
var N=10, last;
for(var i=0; i<N; i++){
// Create a box
var boxbody = new CANNON.Body({
mass: mass,
shape: boxShape,
position: new CANNON.Vec3((N-i-N/2)*(size*2+2*space), size*6+space, 0),
sleepSpeedLimit: 0,
material: pubMaterial
});
bodies.push(boxbody);
world.addBody(boxbody);
if(last){
// Connect the current body to the last one
var c = new CANNON.LockConstraint(boxbody, last);
world.addConstraint(c);
}
// To keep track of which body was added last
last = boxbody;
}
var bodyA = new CANNON.Body({
mass: 0,
shape: boxShape,
position: new CANNON.Vec3((-N/2+1)*(size*2+2*space), size*3-1, 0),
material: pubMaterial
});
bodies.push(bodyA);
world.addBody(bodyA);
var bodyB = new CANNON.Body({
mass: 0,
shape: boxShape,
position: new CANNON.Vec3((N/2)*(size*2+2*space), size*3-1, 0),
material: pubMaterial
});
bodies.push(bodyB);
world.addBody(bodyB);
for(let i=0; i<12; i++) {
let mesh = new THREE.Mesh(new THREE.BoxBufferGeometry(1), new THREE.MeshNormalMaterial());
meshes.push(mesh);
scene.add(mesh);
}
}
initCloth() {
var size = 0.2;
var dis = 0.5;
var sphereShape = new CANNON.Sphere(size);
var mass = 1;
var Nrows = 15, Ncols = 15;
for(let i=0; i<Nrows; i++) {
for(let j=0; j<Ncols; j++) {
let body = new CANNON.Body({
mass: mass,
shape: sphereShape,
position: new CANNON.Vec3((i - 0.5 * Nrows + 0.5) * dis, 9, (j - 0.5 * Ncols + 0.5) * dis),
material: pubMaterial
})
bodies.push(body);
world.addBody(body);
}
}
let spherebody = new CANNON.Body({
mass: 0,
shape: new CANNON.Sphere(4),
position: new CANNON.Vec3(0,4,0),
material: pubMaterial
})
bodies.push(spherebody);
world.add(spherebody);
for(let i=0; i<Nrows * Ncols; i++) {
let r = Math.floor(i / Nrows);
let c = i % Nrows;
if(r < Nrows - 1) {
world.addConstraint(new CANNON.DistanceConstraint(bodies[r * Nrows + c], b2, dis, 5));
}
if(c < Ncols - 1) {
world.addConstraint(new CANNON.DistanceConstraint(bodies[r * Nrows + c], bodies[r * Nrows + c + 1], dis, 5));
}
}
for(let i=0; i<Nrows * Ncols; i++) {
let mesh = new THREE.Mesh(new THREE.SphereBufferGeometry(size), new THREE.MeshNormalMaterial());
meshes.push(mesh);
scene.add(mesh);
}
let mesh = new THREE.Mesh(new THREE.SphereBufferGeometry(4, 32, 16), new THREE.MeshNormalMaterial());
meshes.push(mesh);
scene.add(mesh);
}
initHinge() {
let bodyA = new CANNON.Body({
mass: 0,
shape: new CANNON.Box(new CANNON.Vec3(0.2, 4, 0.2)),
position: new CANNON.Vec3(-3.2, 5, 0),
material: pubMaterial
})
let bodyB = new CANNON.Body({
mass: 1,
shape: new CANNON.Box(new CANNON.Vec3(3, 4, 0.2)),
position: new CANNON.Vec3(0, 5, 0),
// material: pubMaterial
})
bodyB.velocity.set(0, 0, -10);
bodies.push(bodyA);
bodies.push(bodyB);
world.add(bodyA);
world.add(bodyB);
var c = new CANNON.HingeConstraint(bodyA, bodyB, {
pivotA: new CANNON.Vec3(0.3, 0, 0),
axisA: new CANNON.Vec3(0, 1, 0),
pivotB: new CANNON.Vec3(-3.1, 0, 0),
axisB: new CANNON.Vec3(0, 1, 0),
maxForce: 2
});
world.addConstraint(c);
let meshA = new THREE.Mesh(new THREE.BoxBufferGeometry(0.4, 8, 0.4), new THREE.MeshNormalMaterial());
let meshB = new THREE.Mesh(new THREE.BoxBufferGeometry(6, 8, 0.4), new THREE.MeshNormalMaterial());
meshes.push(meshA);
meshes.push(meshB);
scene.add(meshA);
scene.add(meshB);
}
转载请注明地址:郭先生的博客
three.js cannon.js物理引擎之约束(二)的更多相关文章
- three.js cannon.js物理引擎之ConvexPolyhedron多边形
年后第一天上班,郭先生来说一说cannon.js的ConvexPolyhedron(多边形),cannon.js是一个物理引擎,内部通过连续的计算得到各个时间点的数据的状态,three.js的模型可以 ...
- three.js cannon.js物理引擎之约束
今天郭先生继续说cannon.js,主演内容就是点对点约束和2D坐标转3D坐标.仍然以一个案例为例,场景由一个地面.若干网格组成的约束体和一些拥有初速度的球体组成,如下图.线案例请点击博客原文. 下面 ...
- three.js cannon.js物理引擎之制作拥有物理特性的汽车
今天郭先生说一说使用cannon.js的车辆辅助类让我们的汽车模型拥有物理特性.效果图如下,在线案例请点击博客原文. 下面我们说一下今天要使用的两个类,并简单的看看他们的物理意义 1. Raycast ...
- three.js cannon.js物理引擎之齿轮动画
郭先生今天继续说一说cannon.js物理引擎,并用之前已经学习过的知识实现一个小动画,知识点包括ConvexPolyhedron多边形.Shape几何体.Body刚体.HingeConstraint ...
- 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我们已经学习了一些知识,今天郭先生就使用已学的cannon.js物理引擎的知识配合three基础知识来做一个保龄球小游戏,效果如下图,在线案例请点击博客原文. 我们需要掌握的技能 ...
- three.js 之cannon.js物理引擎
今天郭先生说的是一个物理引擎,它十分小巧并且操作简单,没错他就是cannon.js.这些优点都源自于他是基于js编写的,对于js使用者来说cannon.js拥有其他物理引擎没有的纯粹性.从学习成本来看 ...
- 基于Babylon.js编写宇宙飞船模拟程序1——程序基础结构、物理引擎使用、三维罗盘
计划做一个宇宙飞船模拟程序,首先做一些技术准备. 可以访问https://ljzc002.github.io/test/Spacetest/HTML/PAGE/spacetestwp2.html查看测 ...
随机推荐
- Codeforces Global Round 12 D. Rating Compression (思维,双指针)
题意:给你一长度为\(n\)的数组,有一长度为\(k\ (1\le k \le n)\)的区间不断从左往右扫过这个数组,总共扫\(n\)次,每次扫的区间长度\(k=i\),在扫的过程中,每次取当前区间 ...
- typedef struct xxx xxx与struct xxx区别 && “->”和“.”访问结构体变量
1. struct //是C中的结构体的关键词.如: stuct node{ int a;.....} a; node 相当于结构体的类型,关键是其实在C中stuct node 才相当于一个数据类型, ...
- 1、Django框架目录介绍
1.windows上安装django pip install django==1.10.3 安装完成后:django-admin.exe 默认存放路径:C:\Users\licl11092\AppDa ...
- 使用 Typecho 搭建博客
nginx 配置文件 [root@dbtest ~]# cat /etc/nginx/conf.d/www.typecho.com.conf server { listen 80; server_na ...
- 缓冲区溢出实验 4 内存管理(类似于malloc free)
实验环境.代码.及准备 https://www.cnblogs.com/lqerio/p/12870834.html vul4 观察foo函数,可见问题在于最后一次tfree(q).由于之前已经tfr ...
- Androidstudio 新GradlePlugin和Gradle Version对应关系
Project Gradle AS建议升级到4.2. Plugin对应AS的版本,Plugin工具也要和Gradle对应上,否则某些语法不支持,如果是非必要的建议不要轻易升级. Gradle DSL ...
- Chrome Canary crashed bug
Chrome Canary crashed bug Aw, Snap https://support.google.com/chrome/?p=e_awsnap clear cache, 使用隐身模式 ...
- GitHub Actions in Action
GitHub Actions in Action https://lab.github.com/githubtraining/github-actions:-hello-world https://g ...
- 微信小程序-云开发实战教程
微信小程序-云开发实战教程 云函数,云存储,云数据库,云调用 https://developers.weixin.qq.com/miniprogram/dev/wxcloud/basis/gettin ...
- cnblogs 日期错乱 bug
cnblogs 日期错乱 bug 时间错乱 bug archive/2004/01/13/ 什么鬼 呀默认时间戳 https://www.cnblogs.com/xgqfrms/archive/200 ...