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 Round #671 (Div. 2)
比赛链接:https://codeforces.com/contest/1419 A. Digit Game 题意 给出一个 $n$ 位数,游戏规则如下: 1-indexed Raze标记奇数位 Br ...
- HDU -1151 二分匹配与有向无环图不相交最小路径覆盖数
题意: 考虑一个小镇,那里的所有街道都是单向的,并且每条街道都从一个路口通往另一个路口.还众所周知,从一个十字路口开始,穿过城镇的街道,您将永远无法到达同一十字路口,即,城镇的街道没有环. 基于这些假 ...
- Python内置模块(你还在pip install time?)&& apt-get install -f
一.内置模块 之前不知道time是python自带的,还用pip安装.......还报错..... Python中有以下模块不用单独安装 1.random模块 2.sys模块 3.time模块 4.o ...
- MIT 6.S081 聊聊xv6的文件系统(中)日志层与事务
前言 我本想把上篇中没讲完的剩余层全部在本篇中讲完,但没想到越写越多.日志层的代码不多,其思想和解决问题的手段也不算难以理解,但其背后涉及的原理和思想还是非常值得回味的,因此我打算用一整篇完整的blo ...
- 在kubernetes集群里集成Apollo配置中心(1)之交付Apollo-adminservice至Kubernetes集群
1.部署apollo-adminservice软件包 apollo-adminservice软件包链接地址:https://github.com/ctripcorp/apollo/releases/d ...
- bnuoj-53073 萌萌哒身高差 【数学】【非原创】
"清明时节雨纷纷,路上行人欲断魂." 然而wfy同学的心情是愉快的,因为BNU ACM队出去春游啦!并且,嗯... 以下是wfy同学的日记: 昨天,何老师告诉我们:明天我们去春游, ...
- 强网杯 2019]随便注(堆叠注入,Prepare、execute、deallocate)
然后就是今天学的新东西了,堆叠注入. 1';show databases; # 1';show tables; # 发现两个表1919810931114514.words 依次查询两张表的字段 1'; ...
- webpack4.0源码解析之esModule打包分析
入口文件index.js采用esModule方式导入模块文件,非入口文件index1.js分别采用CommonJS和esmodule规范进行导出. 首先,init之后创建一个简单的webpack基本的 ...
- Node.js Spider
Node.js Spider How To Write a Spider using JavaScript, in order to auto download some svg images for ...
- yapi & mock JSON
yapi & mock JSON json, body https://hellosean1025.github.io/yapi/documents/mock.html response bo ...