日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

three.js 之cannon.js物理引擎

發布時間:2023/12/29 综合教程 35 生活家
生活随笔 收集整理的這篇文章主要介紹了 three.js 之cannon.js物理引擎 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天郭先生說的是一個物理引擎,它十分小巧并且操作簡單,沒錯他就是cannon.js。這些優點都源自于他是基于js編寫的,對于js使用者來說cannon.js擁有其他物理引擎沒有的純粹性。從學習成本來看,cannon.js的學習成本比較低,對于新手來說比較友好,因為它有相對完善的api,學習cannon.js之前我們不妨來看看cannon.js的官方網站以及他的API,對于js學習者來說這是十分必要的。官網上面有一些example,他們十分典型并囊括了大多數的知識點,配合api一起學習是個不錯的選擇。在線案例請點擊博客原文。效果如下圖,接下來以一個小案例,簡單的介紹一下cannon.js。

1. 初始化three場景

創建three場景(或者說three世界)來作為物理世界的載體,這一步很簡單,主要就是添加渲染器、場景、相機和網格等three元素,沒必要多說。

scene = new THREE.Scene();//step 1 創建場景

camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.y = 30;
camera.position.z = 20;
camera.lookAt(0,5,0);
scene.add( camera ); //step 2 場景中添加相機

scene.add(new THREE.AmbientLight(0x888888));
const light = new THREE.DirectionalLight(0xbbbbbb, 1);
light.position.set(6, 30, 6);
scene.add(light); //step 3 場景中添加另種光源

renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
renderer.setClearColor(0xbfd1e5);
this.$refs.box.appendChild(renderer.domElement); //step 4 dom中添加渲染器

let groundGeom = new THREE.BoxBufferGeometry(40, 0.2, 40);
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); //step 5 添加地面網格

2. 初始化物理世界

這里是初始化物理世界,我們詳細的講一下他們的用法。

initCannon() {
    world = new CANNON.World(); //該方法初始化物理世界,里面包含著物理世界的相關數據(如剛體數據,世界中所受外力等等)
    world.gravity.set(0,-9.8,0); //設置物理世界的重力為沿y軸向上-9.8米每二次方秒
    world.broadphase = new CANNON.NaiveBroadphase();//NaiveBroadphase是默認的碰撞檢測方式,該碰撞檢測速度比較高
    world.solver.iterations = 5;//解算器的迭代次數,更高的迭代次數意味著更加精確同時性能將會降低

    bodyGround = new CANNON.Body({ //創建一個剛體(物理世界的剛體數據)
        mass: 0, //剛體的質量,這里單位為kg
        position: new CANNON.Vec3(0, -0.1, 0), //剛體的位置,單位是米
        shape: new CANNON.Box(new CANNON.Vec3(20, 0.1, 20)), //剛體的形狀(這里是立方體,立方體的參數是一個包含半長、半寬、半高的三維向量,具體我們以后會說)
        material: new CANNON.Material({friction: 0.05, restitution: 0}) //材質數據,里面規定了摩擦系數和彈性系數
    });
    ground.userData = bodyGround; //將剛體的數據賦值給地面網格的userData屬性
    world.addBody(bodyGround); //物理世界添加地面剛體
},

3. 向場景中添加網格并向物理世界中添加剛體數據

這里我們通過setInterval函數我們定時向場景中添加網格并向物理世界中添加剛體數據,

interval = setInterval(() => {
    this.createBox(); //創建網格和剛體的方法
}, 200);

下面是具體的方法

createBox() {
    let x = Math.random() * 10 - 5;
    let z = Math.random() * 10 - 5;
    let box = new THREE.Mesh( geometry, this.createRandomMaterial() ); //createRandomMaterial創建隨機顏色的材質
    box.position.set(x, 20, z);
    scene.add( box ); //創建box,并添加到場景

    let bodyBox = new CANNON.Body({
        mass: 1,
        position: new CANNON.Vec3(x, 20, z),
        shape: new CANNON.Box(new CANNON.Vec3(1,1,1)),
        material: new CANNON.Material({friction: 0.1, restitution: 0})
    });//創建一個質量為1kg,位置為(x,20,z),形狀為halfSize為1,1,1的正方形剛體,材質中摩擦系數為0.1,彈性系數為0。
    box.userData = bodyBox;//給box的userData屬性添加剛體數據
    world.addBody(bodyBox);//在物理世界中添加該剛體

    setTimeout(() => { //10秒鐘之后在場景中移除box,并在物理世界中移除該剛體
        scene.remove(box);
        box.material.dispose();
        box.geometry.dispose();
        world.removeBody(bodyBox);
    }, 10000)
},

4. 根據物理引擎的數據更新three網格數據

這一步我們逐幀根據物理引擎的數據渲染three場景

animation() { //requestAnimationFrame動畫中調用render方法
    this.globalID = requestAnimationFrame(this.animation);
    this.render();
},
render() { //更新性能插件,根據物理引擎數據更新網格數據,最后渲染場景
    stats.update();
    this.updatePhysics();
    renderer.render( scene, camera );
},
updatePhysics() { // world.step
    world.step(timeStep); //第一個參數是以固定步長更新物理世界參數(詳情請看api)
    scene.children.forEach(d => {//遍歷場景中的子對象,如果對象的isMesh屬性為true,我們就將更新改對象的position和quaternion屬性(他們對應的剛體數據存在對應的userData中)。
        if(d.isMesh == true) {
            d.position.copy(d.userData.position);
            d.quaternion.copy(d.userData.quaternion);
        }
    })
}

這樣我們就將cannon.js物理引擎應用到了three中。不出意外的話,接下來我會講解一下官方的examples。

轉載請注明地址:郭先生的博客

總結

以上是生活随笔為你收集整理的three.js 之cannon.js物理引擎的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。