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查看测 ...
随机推荐
- uva10859 Placing Lampposts (树形dp+求两者最小值方法)
题目链接:点击打开链接 题意:给你一个n个点m条边的无向无环图,在尽量少的节点上放灯,使得所有边都被照亮,每盏灯将照亮以它为一个端点的所有边.在灯的总数最小的前提下,被两盏灯同时照亮的边数应尽量大. ...
- codeforces626D . Jerry's Protest (概率)
Andrew and Jerry are playing a game with Harry as the scorekeeper. The game consists of three rounds ...
- 哈希算法解决:HDU1686 && POJ2774 && POJ3261
HDU1686 题意: 找A串在B串中的出现次数(可重叠),可用KMP做,这里只提供哈希算法做的方法 题解: 先得到A串的hash值,然后在B中枚举起点,长度为lena的子串,检验hash值是否相同就 ...
- 营业额统计 HYSBZ - 1588
营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额.分析营业情况 ...
- K8S(10)配置中心实战-configmap资源
k8s配置中心实战-configmap资源 目录 k8s配置中心实战-configmap资源 0 configmap前置说明 0.1.1 configmap和secret 0.1.2 怎么使用conf ...
- 宝塔面板&FLASK¢os 7.2 &腾讯云 配置网站出现的若干问题
1.解决跨域问题&&中文显示问题 from flask import Flask, url_for, request, render_template, redirect from f ...
- BZOJ 3676 回文串(回文树)题解
题意: 一个回文的价值为长度 * 出现次数,问一个串中的子串的最大回文价值 思路: 回文树模板题,跑PAM,然后计算所有节点出现次数. 参考: 回文串问题的克星--Palindrome Tree(回文 ...
- hdu2333-贪心,如何去后效性,背包太大怎么办,如何最大化最小值,从无序序列中发掘有序性质
补充一下我理解的中文题意.. 你要重新组装电脑..电脑有一些部件..你的预算有b,b(1~1e9),有n个部件..每个部件有类型和名称以及价钱和质量现在你要在不超过预算b的情况下..每个类型都买一个部 ...
- js regular expression & email checker
js regular expression & email checker const isValidEmail = (email = ``) => /^([\w+\.])+@(\w+) ...
- free useful skills videos courses & tutorials
free useful skills videos courses & tutorials website video courses https://realpython.com/ http ...