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

  1. 创建three场景
    这一步是基础工作,对于有一定three基础的同学都不会陌生,我就直接上代码了。

复制代码
initThree() {
scene = new THREE.Scene();

camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.x = 40;
camera.position.y = 52;
camera.position.z = 78;
scene.add( camera );

scene.add(new THREE.AxesHelper(40)); 

scene.add(new THREE.AmbientLight(0x888888));

const light = new THREE.DirectionalLight(0xbbbbbb, 1);
light.position.set(0, 50, 50);
const distance = 200;

let texture = new THREE.TextureLoader().load('/static/images/base/ground.png');
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.copy(new THREE.Vector2(40, 40));

let groundGeom = new THREE.BoxBufferGeometry(100, 0.2, 100);
let groundMate = new THREE.MeshPhongMaterial({color: 0xdddddd, map: texture})
ground = new THREE.Mesh(groundGeom, groundMate);
ground.position.y = -0.1;
ground.receiveShadow = true;
scene.add(ground);

geometry = new THREE.BoxGeometry( 2, 2, 2 );

renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
renderer.setClearColor(0xbfd1e5);

controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 10, 0);
camera.lookAt(0,10,0);

this.$refs.box.appendChild( renderer.domElement );

stats = new Stats();
this.$refs.box.appendChild(stats.dom);

},
复制代码
这里面主要进行初始化场景、相机、渲染器、灯光和地面等操作。

  1. 初始化物理世界
    这里面包括创建CANNON.World,创建地面刚体,每块需要被约束的刚体和设置点对点约束(在给定的偏移点连接两个实体),接下来我们仍以代码注释的形式详细的讲解对于物理世界的创建。

复制代码
initCannon() {
world = new CANNON.World();
world.gravity.set(0, -9.8, 0);
world.broadphase = new CANNON.NaiveBroadphase();
world.solver.iterations = 10;
bodyGround = new CANNON.Body({
mass: 0,
position: new CANNON.Vec3(0, -0.1, 0),
shape: new CANNON.Box(new CANNON.Vec3(50, 0.1, 50)),
material: new CANNON.Material({friction: 0.05, restitution: params.restitution})
});
ground.userData = bodyGround;
world.addBody(bodyGround);
//上面的代码意义上一节已经讲过了,我就不多言,主要看下面的代码。
//这里设置了一些变量,N表示组成约束体刚体的数量,space表示相邻两个刚体直接的距离间隔,mass为刚体的质量变量,width表示刚体半宽度,height表示刚体半高度,last表示上一个相连的刚体。
var N = 20, space = 0.1, mass = 0, width = 10, hHeight = 1, last;
var halfVec = new CANNON.Vec3(width, hHeight, 0.2);//刚体的长宽高的halfSize向量
var boxShape = new CANNON.Box(halfVec);//定义一个长方体数据
var boxGeometry = new THREE.BoxBufferGeometry(halfVec.x * 2, halfVec.y * 2, halfVec.z * 2);//定义一个长方几何体
var boxMaterial = new THREE.MeshLambertMaterial( { color: 0xffaa00 } );//定义几何体材质

for(var i=0; i<N; i++) {//遍历N次,从上到下创建长方体网格和刚体,位置逐渐变低,质量逐渐变小。
    var boxBody = new CANNON.Body({mass: mass, material: new CANNON.Material({friction: 0.05, restitution: params.restitution})});//创建刚体,第一个刚体的质量设置成0(即为不动的刚体),定义材质,并设置摩擦系数和弹性系数
    boxBody.addShape(boxShape);//为刚体添加形状
    var boxMesh = new THREE.Mesh(boxGeometry, boxMaterial);//创建three世界的网格
    boxBody.position.set(0, (N - i + 5) * (hHeight * 2 + space * 2), 0);//这里设置刚体的位置,是由上倒下的顺序
    boxBody.linearDamping = 0.01;//设置线性阻尼
    boxBody.angularDamping = 0.01;//设置旋转阻尼
    world.addBody(boxBody);//将刚体添加到物理世界中
    scene.add(boxMesh);//将网格添加到three场景中
    boxes.push(boxBody);//将刚体添加到数组中
    boxMeshes.push(boxMesh);//将网格添加到数组中,这两步可以在更新物理世界中找到他们的对应关系,也可以添加到Mesh的userData属性中去,具体可以参见上一篇文章
    if(i == 0) { //当i=0时,也就是第一个刚体,在刚体创建完毕后,我们将mass变量设置成1
        mass = 1;
    } else {//从第二个刚体往后都会创建两个点对点的约束,点对点约束我们下面讲
        var ptp1 = new CANNON.PointToPointConstraint(boxBody, new CANNON.Vec3(-width, hHeight + space, 0), last, new CANNON.Vec3(-width, -hHeight - space, 0), (N - i) / 4);
        var ptp2 = new CANNON.PointToPointConstraint(boxBody, new CANNON.Vec3(width, hHeight + space, 0), last, new CANNON.Vec3(width, -hHeight - space, 0), (N - i) / 4);
        world.addConstraint(ptp1);//将约束添加到物理世界
        world.addConstraint(ptp2);//将约束添加到物理世界
    }
    last = boxBody;//这里将本次创建的刚体赋值给last变量,一遍下一个循环使用
}

},
复制代码
Absorbing material: www.goodsmaterial.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值