Three?cannon-es?基礎(chǔ)使用示例詳解
Cannon.js的特點(diǎn)
1、輕量級(jí)和高性能:Cannon.js被設(shè)計(jì)為一個(gè)快速而輕便的物理引擎,代碼簡(jiǎn)潔且易于理解。
2、真實(shí)的物理模擬:Cannon.js提供了一套完整的3D物理模擬功能,包括剛體碰撞、力學(xué)模擬和約束等。這使得開發(fā)者可以模擬真實(shí)世界中的物理效果。
3、靈活的約束系統(tǒng):Cannon.js的約束系統(tǒng)非常靈活,并且支持各種類型的約束,如距離約束、彈簧約束、旋轉(zhuǎn)約束等。開發(fā)者可以根據(jù)需要?jiǎng)?chuàng)建各種類型的約束。
4、基于WebGL:Cannon.js與WebGL技術(shù)結(jié)合使用,可以輕松實(shí)現(xiàn)在瀏覽器中展示3D物理效果,并且與其他WebGL應(yīng)用程序進(jìn)行集成。
5、跨平臺(tái)兼容性:Cannon.js可以在多種瀏覽器上運(yùn)行,并且支持移動(dòng)設(shè)備和桌面設(shè)備。這使得開發(fā)者可以輕松地在各種平臺(tái)上開發(fā)和運(yùn)行物理模擬應(yīng)用程序。
cannon-es安裝和引入
可以通過npm命令行安裝cannon.js模塊。
npm install --save cannon-es
在html和js文件中分別引入 cannon-es,three 和 three/jsm 是引入three中的實(shí)例的
<script type="importmap"> { "imports": { "three": "../js/three.module.js", "three/jsm/": "../js/jsm/", "cannon-es": "../node_modules/cannon-es/dist/cannon-es.js" } } </script>
在js中全局引入
import * as Cannon from 'cannon-es'
初始工作
創(chuàng)建我們的3D環(huán)境,引入3D 實(shí)例。
import * as THREE from 'three' import * as Cannon from 'cannon-es' import { OrbitControls } from '../../js/jsm/controls/OrbitControls.js' // 目標(biāo):物理引擎 common-es 使用 // 1. 下載引入 cannon-es 包 // 2. 準(zhǔn)備球體,地面,燈光和陰影 // 3. 基于 cannon 創(chuàng)建物理世界,創(chuàng)建物理世界的小球(圖形+材質(zhì)) // 4. 在渲染循環(huán)中更新物理世界內(nèi)的球體運(yùn)動(dòng)軌跡,并影響到 3D 物體(核心思想) let scene, camera, renderer, controls, ball, floor, world, sphereBody function init() { scene = new THREE.Scene() camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000) camera.position.set(0, 0, 30) renderer = new THREE.WebGLRenderer({ antialias: true }) renderer.setSize(window.innerWidth, window.innerHeight) document.querySelector('#app').appendChild(renderer.domElement) renderer.shadowMap.enabled = true controls = new OrbitControls(camera, renderer.domElement) const axesHelper = new THREE.AxesHelper(5) scene.add(axesHelper) }
一、創(chuàng)建準(zhǔn)備球體。網(wǎng)格模型表示一個(gè)物體,需要通過幾何體Geometry定義Mesh的幾何外形,對(duì)于Body同樣道理,你需要設(shè)置物體Body
的幾何形狀。CannonJS定義幾何體形狀的API有很多種,比如比如長(zhǎng)方體Box
、球體Sphere
等等
因?yàn)樵趫?chǎng)景中已經(jīng)有了一個(gè)球體,現(xiàn)在我們需要在 Cannon.js 的 world 中也創(chuàng)建一個(gè)球體。我們需要使用其 Body 類,它可以自由落體并和其他 body 進(jìn)行碰撞。在創(chuàng)建 body 之前,我們要先定義一個(gè) shape。
//創(chuàng)建屋里小球 const sphereShape = new Cannon.Sphere(1) // 創(chuàng)建物理小球材質(zhì) const sphereMaterial = new Cannon.Material();
二、通過Cannon.World類創(chuàng)建一個(gè)物理世界。定義物理世界的物理屬性,比如設(shè)置重力加速度。重力加速度的屬性gravity
類似body的位置,是一個(gè)三維向量Vec3
。重力加速度x、y、z分量值,實(shí)際開發(fā)根據(jù)自己項(xiàng)目和坐標(biāo)系設(shè)置即可,咱們假設(shè)小球所在的場(chǎng)景,y軸豎直向上,這樣重力就速度就是y方向負(fù)方向。
world = new Cannon.World({ // 自由落體加速度 gravity: new Cannon.Vec3(0, -9.8, 0) })
三、使用方法.addBody()
把物體添加到物理世界,物理球body添加到物理世界中,這樣body就會(huì)受到物理世界加速度的影響World。
// 創(chuàng)建物理世界 sphereBody = new Cannon.Body({ shape: sphereShape, // 物體形狀 material: sphereMaterial, // 物位材質(zhì) position: new Cannon.Vec3(0,0,0,), mass: 1 }) // 把物理小球加入到物理世界 world.addBody(sphereBody)
四、創(chuàng)建一個(gè)地面,這樣就可以作為球體自由落體的參照物。
floor = new THREE.Mesh(new THREE.PlaneGeometry(10, 10), new THREE.MeshStandardMaterial({color: 0xffff00,})); floor.position.set(0, -10, 0); floor.rotation.set(-Math.PI/2, 0, 0); floor.receiveShadow = true;
五、所有的實(shí)例和物體都是離不開光照的,沒有光,所有的都是看不到的,所以我們是需要添加光照的。我這里就添加的環(huán)境光和燈光。
//環(huán)境光 const ambientLingth = new THREE.AmbientLight(0xffffff, 1) //燈光 const directionLight = new THREE.DirectionalLight(0xffffff, 1) directionLight.position.set(0, 15, 0) directionLight.castShadow = true
六、我們需要把我們的球體、地面、環(huán)境光、燈光都添加到場(chǎng)景中去。
scene.add(ball) scene.add(floor) scene.add(ambientLingth) scene.add(directionLight)
七、在渲染循環(huán)中更新物理世界內(nèi)的球體運(yùn)動(dòng)軌跡,并影響到 3D 物體(核心思想)
const clock = new THREE.Clock() function renderLoop() { // 4. 在渲染循環(huán)中更新物理世界內(nèi)的球體運(yùn)動(dòng)軌跡,并影響到 3D 物體(核心思想) const time = clock.getDelta() // 物理世界不斷渲染 // 參數(shù)1:固定步長(zhǎng),間隔多久重繪物理世界 // 參數(shù)2:自上次調(diào)用后要經(jīng)過多長(zhǎng)時(shí)間 world.step(1 / 160, time) // 把物理世界小球最新位置更新給 3D 物體小球位置 ball.position.copy(sphereBody.position) renderer.render(scene, camera) requestAnimationFrame(renderLoop) }
完整代碼和效果圖
import * as THREE from 'three' import * as Cannon from 'cannon-es' import { OrbitControls } from '../../js/jsm/controls/OrbitControls.js' // 目標(biāo):物理引擎 common-es 使用 // 1. 下載引入 cannon-es 包 // 2. 準(zhǔn)備球體,地面,燈光和陰影 // 3. 基于 cannon 創(chuàng)建物理世界,創(chuàng)建物理世界的小球(圖形+材質(zhì)) // 4. 在渲染循環(huán)中更新物理世界內(nèi)的球體運(yùn)動(dòng)軌跡,并影響到 3D 物體(核心思想) let scene, camera, renderer, controls, ball, floor, world, sphereBody function init() { scene = new THREE.Scene() camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000) camera.position.set(0, 0, 30) renderer = new THREE.WebGLRenderer({ antialias: true }) renderer.setSize(window.innerWidth, window.innerHeight) document.querySelector('#app').appendChild(renderer.domElement) renderer.shadowMap.enabled = true controls = new OrbitControls(camera, renderer.domElement) const axesHelper = new THREE.AxesHelper(5) scene.add(axesHelper) } const clock = new THREE.Clock() function renderLoop() { // 4. 在渲染循環(huán)中更新物理世界內(nèi)的球體運(yùn)動(dòng)軌跡,并影響到 3D 物體(核心思想) const time = clock.getDelta() // 物理世界不斷渲染 // 參數(shù)1:固定步長(zhǎng),間隔多久重繪物理世界 // 參數(shù)2:自上次調(diào)用后要經(jīng)過多長(zhǎng)時(shí)間 world.step(1 / 160, time) // 把物理世界小球最新位置更新給 3D 物體小球位置 ball.position.copy(sphereBody.position) renderer.render(scene, camera) requestAnimationFrame(renderLoop) } // 2. 準(zhǔn)備球體,地面,燈光和陰影 function createBase () { // 球體 ball = new THREE.Mesh(new THREE.SphereGeometry(1,32, 16), new THREE.MeshStandardMaterial({color: 0xffff00,})); ball.castShadow = true // 地面 floor = new THREE.Mesh(new THREE.PlaneGeometry(10, 10), new THREE.MeshStandardMaterial({color: 0xffff00,})); floor.position.set(0, -10, 0); floor.rotation.set(-Math.PI/2, 0, 0); floor.receiveShadow = true; //環(huán)境光 const ambientLingth = new THREE.AmbientLight(0xffffff, 1) //燈光 const directionLight = new THREE.DirectionalLight(0xffffff, 1) directionLight.position.set(0, 15, 0) directionLight.castShadow = true scene.add(ball) scene.add(floor) scene.add(ambientLingth) scene.add(directionLight) } // 3. 基于 cannon 創(chuàng)建物理世界 function createWorld () { world = new Cannon.World({ // 自由落體加速度 gravity: new Cannon.Vec3(0, -9.8, 0) }) //創(chuàng)建屋里小球 const sphereShape = new Cannon.Sphere(1) // 創(chuàng)建物理小球材質(zhì) const sphereMaterial = new Cannon.Material(); // 創(chuàng)建物理世界 sphereBody = new Cannon.Body({ shape: sphereShape, // 物體形狀 material: sphereMaterial, // 物位材質(zhì) position: new Cannon.Vec3(0,0,0,), mass: 1 }) // 把物理小球加入到物理世界 world.addBody(sphereBody) } init() createBase() createWorld() setTimeout(() => { renderLoop() },1000)
到此這篇關(guān)于Three cannon-es 基礎(chǔ)使用的文章就介紹到這了,更多相關(guān)Three cannon-es 使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
微信小程序 數(shù)據(jù)緩存實(shí)現(xiàn)方法詳解
這篇文章主要介紹了微信小程序 數(shù)據(jù)緩存實(shí)現(xiàn)方法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08html的DOM中Event對(duì)象onblur事件用法實(shí)例
這篇文章主要介紹了html的DOM中Event對(duì)象onblur事件用法,實(shí)例分析了onblur事件的使用范圍與對(duì)應(yīng)的javascript使用技巧,需要的朋友可以參考下2015-01-01微信小程序在text文本實(shí)現(xiàn)多種字體樣式
這篇文章主要介紹了微信小程序在text文本實(shí)現(xiàn)多種字體樣式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11js 頁面刷新location.reload和location.replace的區(qū)別小結(jié)
在實(shí)際應(yīng)用的時(shí)候,重新刷新頁面的時(shí)候,我們通常使用: location.reload() 或者是 history.go(0) 來做。下面有一些相關(guān)的內(nèi)容,大家看完了就會(huì)有更多的收獲。2009-12-12在js中判斷checkboxlist(.net控件客戶端id)是否有選中
添加或修改內(nèi)容時(shí),需要對(duì)關(guān)鍵數(shù)據(jù)進(jìn)行判空處理,checkboxlist是否有選擇項(xiàng)如何使用js判斷實(shí)現(xiàn),接下來為大家詳細(xì)介紹下實(shí)現(xiàn)方法,感興趣的朋友可以參考下哈2013-04-04JS實(shí)現(xiàn)動(dòng)態(tài)星空背景效果
這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)動(dòng)態(tài)星空背景效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11js實(shí)現(xiàn)無刷新監(jiān)聽URL的變化示例代碼詳解
這篇文章主要介紹了js如何無刷新監(jiān)聽URL的變化,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06