今天郭先生說一說cannon.js物理引擎之Heightfield高度場,學過場論的朋友都知道物理學中把某個物理量在空間的一個區域內的分布稱為場,高度場就是與高度相關的場,而cannon.js物理引擎的Heightfield的高度就是關於兩個變量的函數,可以表達為HEIGHT(i,j)。當然知不知道場論不耽誤我們學習Heightfield,下面就是一個由Heightfield生成的高度場,在線案例請點擊博客原文。我們來說一說它的用法。
1. Heightfield的用法
說用法之前我們不妨看看他的API,文檔對於它的說明是 – “高度數據以數組形式給出。這些數據點以給定的距離均勻分布”。構造函數如下。
Heightfield ( data , options )
data是一個Y值數組,將用於構建地形。options是一個配置項,有三個可配置參數。minValue是數據數組中數據點的最小值。如果未給出,將自動計算。maxValue最大值。elementSize是X方向上數據點之間的世界間距。他還有一些屬性和方法請大家自行觀看,我就不多說了。
高度場Heightfield本質和cannon.js一樣還是一種數據的表達形式,想要把它應用到three中仍然需要對應的圖形來表達(就像CANNON.Box數據需要THREE.BoxBuferGeometry幾何體一樣),對應的幾何體就是ParametricBufferGeometry,下面我們以一個案例來實際操作一下。
2. Heightfield案例
可以點擊案例來觀看,下面我們直接上代碼。
initCannon() { //這里是生成高度場的代碼 var matrix = [];//創建構造高度場的數組 for (var i = 0; i < size; i++) { matrix.push([]); for (var j = 0; j < size; j++) { //高度由兩個余弦函數疊加形成 var height = Math.cos(i / size * Math.PI * 8) * Math.cos(j / size * Math.PI * 8); matrix[i].push(height) } } var hfShape = new CANNON.Heightfield(matrix, { elementSize: 1 //數據點的距離設置為1 }); var hfBody = new CANNON.Body({ mass: 0, material: physicsMaterial}); var q = new CANNON.Quaternion(); q.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), - Math.PI / 2); hfBody.addShape(hfShape, new CANNON.Vec3(-size / 2, 0, size / 2), q);//由於這個高度場是XOY平面第一象限上,所以需要旋轉和平移,addShape方法為我們提供了這個功能。 world.addBody(hfBody); }, initThree() { //使用ParametricBufferGeometry配合Heightfield形成網格 var groundGeom = new THREE.ParametricBufferGeometry((u,v,target) => { var height = Math.cos(u * Math.PI * 8) * Math.cos(v * Math.PI * 8);//這里的方法和生成高度場的方法是一樣的,不了解ParametricBufferGeometry幾何體的可以參考我之前發的博客。 target.set(u * size - size / 2, height, v * size - size / 2); }, size, size) let groundMate = new THREE.MeshPhongMaterial({color: 0x666666, side: THREE.DoubleSide}); groundMesh = new THREE.Mesh(groundGeom, groundMate); scene.add(groundMesh); },
Heightfield學習起來還是很簡單的,我們后面的案例可能會用到這個高度場作為地面,作為預備知識先了解一下。下一節我們講一下RaycastVehicle類。
轉載請注明地址:郭先生的博客