とげとげジオメトリの生成
threejsの基本geometryは、indexバッファ使ってなかったから簡単にとげとげにできた。#threejs pic.twitter.com/T1rvlU4ZEp
— ma38su (@ma38su) 2022年4月23日
コードはこんな感じ。正二十面体の各面に対して、まず面の法線と重心を求めて、重心から法線方向に一定値delta進めたところに一つ頂点をを生やした感じ。
function generateNeedlesGeometry(size: number) { const delta = size * 2.0; const geometry = new THREE.IcosahedronGeometry(size, 0); const positions = geometry.attributes.position; const { array, itemSize } = positions; const bufArray: number[] = []; const v1 = new THREE.Vector3(); const v2 = new THREE.Vector3(); const v3 = new THREE.Vector3(); for (let i = 0, j = 0; i < array.length; i += itemSize, j++) { const x = array[i]; const y = array[i+1]; const z = array[i+2]; if (j == 0) { v1.set(x, y, z); } else if (j == 1) { v2.set(x, y, z); } else if (j == 2) { v3.set(x, y, z); const v12 = new THREE.Vector3().subVectors(v2, v1); const v23 = new THREE.Vector3().subVectors(v3, v2); const vn = new THREE.Vector3().crossVectors(v12, v23).normalize(); vn.multiplyScalar(delta); const vg = new THREE.Vector3(); vg.add(v1); vg.add(v2); vg.add(v3); vg.multiplyScalar(1/3); vg.add(vn); bufArray.push(v1.x, v1.y, v1.z); bufArray.push(v2.x, v2.y, v2.z); bufArray.push(vg.x, vg.y, vg.z); bufArray.push(v2.x, v2.y, v2.z); bufArray.push(v3.x, v3.y, v3.z); bufArray.push(vg.x, vg.y, vg.z); bufArray.push(v3.x, v3.y, v3.z); bufArray.push(v1.x, v1.y, v1.z); bufArray.push(vg.x, vg.y, vg.z); j = 0; } } const buf = new THREE.BufferGeometry(); buf.setAttribute( 'position', new THREE.Float32BufferAttribute( bufArray, 3 ) ); return buf; }