今天郭先生继续讲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物理引擎之约束(二)的更多相关文章

  1. three.js cannon.js物理引擎之ConvexPolyhedron多边形

    年后第一天上班,郭先生来说一说cannon.js的ConvexPolyhedron(多边形),cannon.js是一个物理引擎,内部通过连续的计算得到各个时间点的数据的状态,three.js的模型可以 ...

  2. three.js cannon.js物理引擎之约束

    今天郭先生继续说cannon.js,主演内容就是点对点约束和2D坐标转3D坐标.仍然以一个案例为例,场景由一个地面.若干网格组成的约束体和一些拥有初速度的球体组成,如下图.线案例请点击博客原文. 下面 ...

  3. three.js cannon.js物理引擎之制作拥有物理特性的汽车

    今天郭先生说一说使用cannon.js的车辆辅助类让我们的汽车模型拥有物理特性.效果图如下,在线案例请点击博客原文. 下面我们说一下今天要使用的两个类,并简单的看看他们的物理意义 1. Raycast ...

  4. three.js cannon.js物理引擎之齿轮动画

    郭先生今天继续说一说cannon.js物理引擎,并用之前已经学习过的知识实现一个小动画,知识点包括ConvexPolyhedron多边形.Shape几何体.Body刚体.HingeConstraint ...

  5. three.js cannon.js物理引擎地形生成器和使用指针锁定控件

    今天郭先生说一说使用cannon.js物理引擎绘制地形和使用指针锁定控件.效果如下图.线案例请点击博客原文. 这里面的生成地形的插件和指针锁定控件也是cannon.js的作者schteppe封装的,当 ...

  6. three.js cannon.js物理引擎之Heightfield

    今天郭先生说一说cannon.js物理引擎之Heightfield高度场,学过场论的朋友都知道物理学中把某个物理量在空间的一个区域内的分布称为场,高度场就是与高度相关的场,而cannon.js物理引擎 ...

  7. three.js cannon.js物理引擎制作一个保龄球游戏

    关于cannon.js我们已经学习了一些知识,今天郭先生就使用已学的cannon.js物理引擎的知识配合three基础知识来做一个保龄球小游戏,效果如下图,在线案例请点击博客原文. 我们需要掌握的技能 ...

  8. three.js 之cannon.js物理引擎

    今天郭先生说的是一个物理引擎,它十分小巧并且操作简单,没错他就是cannon.js.这些优点都源自于他是基于js编写的,对于js使用者来说cannon.js拥有其他物理引擎没有的纯粹性.从学习成本来看 ...

  9. 基于Babylon.js编写宇宙飞船模拟程序1——程序基础结构、物理引擎使用、三维罗盘

    计划做一个宇宙飞船模拟程序,首先做一些技术准备. 可以访问https://ljzc002.github.io/test/Spacetest/HTML/PAGE/spacetestwp2.html查看测 ...

随机推荐

  1. P1387 最大正方形 && P1736 创意吃鱼法(DP)

    题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入输出格式 输入格式: 输入文件第一行为两个整数n,m(1<=n,m<=100),接下来n行,每行m ...

  2. 最新版gradle安装使用简介

    目录 简介 安装gradle和解决gradle安装的问题 Gradle特性 标准task Build phases Gradle Wrapper wrapper的使用 wrapper的升级 一个简单的 ...

  3. nginx 80端口跳转到443

    nginx配置文件80配置中增加 rewrite ^ https://$http_host$request_uri? permanent; 如图: https://blog.csdn.net/jian ...

  4. kubernetes生态--交付prometheus监控及grafana炫酷dashboard到k8s集群

    由于docker容器的特殊性,传统的zabbix无法对k8s集群内的docker状态进行监控,所以需要使用prometheus来进行监控: 什么是Prometheus? Prometheus是由Sou ...

  5. MySQL数据库系列(四)- InnoDB下的共享表空间和独立表空间详解

    一.概念 共享表空间: Innodb的所有数据保存在一个单独的表空间里面,而这个表空间可以由很多个文件组成,一个表可以跨多个文件存在,所以其大小限制不再是文件大小的限制,而是其自身的限制.从Innod ...

  6. mysql+python+pymysql的一些细节问题

    报错 (1044, "Access denied for user 'erio'@'localhost' to database 'library'") 就是权限问题了,没什么好说 ...

  7. mybatis(三)配置mapper.xml 的基本操作

    参考:https://www.cnblogs.com/wuzhenzhao/p/11101555.html XML 映射文件 本文参考mybatis中文官网进行学习总结:http://www.myba ...

  8. 基于HSV彩色空间与直方图信息的植物叶脉FFCM算法提取

    宣旭峰,王美丽,张建锋. 基于HSV彩色空间与直方图信息的植物叶脉FFCM算法提取[J/OL]. 计算机应用研究,2018,(08):1-7. (2017-07-21)[2017-10-09]. ht ...

  9. CDN maxcdn for speed up

    https://www.maxcdn.com/ The Next Generation CDN.Plug into a whole new level of speed.From: https://w ...

  10. git 取消未成功的 merge

    git 取消未成功的 merge # 合并时遇到冲突想取消操作,恢复index $ git merge --abort # 可以回退到某个提交 $ git reset --hard # 可以撤销某个提 ...