龙空技术网

three.js cannon.js物理引擎之约束(二)

那个男孩boy 1656

前言:

今天咱们对“js小球与边框碰撞反弹”都比较珍视,姐妹们都需要知道一些“js小球与边框碰撞反弹”的相关资讯。那么小编在网摘上搜集了一些有关“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);}

转载自:郭先生的博客()

标签: #js小球与边框碰撞反弹