Created
March 4, 2022 19:57
-
-
Save claydegruchy/14033c451f26e3e5e7fe725ed34ace14 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Creates UVs for THREE js geometry | |
// useful for if you need to add a texture to a concave hull, for example | |
import * as THREE from 'three'; | |
function generateUvs(geometry) { | |
const uvNumComponents = 2; | |
geometry.computeVertexNormals(); | |
function pointsInPlaneToPoints2D(points3D) { | |
// The normal is a unit vector that sticks out from face. | |
// We're using the first 3 points, assuming that there | |
// are at least 3, and they are not co-linear. | |
const [p0, p1, p2] = points3D; | |
const planeNormal = new THREE.Vector3() | |
.crossVectors( | |
new THREE.Vector3().subVectors(p0, p1), | |
new THREE.Vector3().subVectors(p1, p2) | |
) | |
.normalize(); | |
// Unit vector on the Z axis, where we want to rotate our face | |
const zUnit = new THREE.Vector3(0, 0, 1); | |
// Quaternion representing the rotation of the face plane to Z | |
const qRot = new THREE.Quaternion().setFromUnitVectors(planeNormal, zUnit); | |
// Rotate each point, assuming that they are all co-planar | |
// with the first 3. | |
return points3D.map(function (p) { | |
const pRot = p.clone().applyQuaternion(qRot); | |
// Output format [x, y] (ignoring z) | |
return [pRot.x, pRot.y]; | |
}); | |
} | |
var verts = geometry.attributes.position.array.length / 3; | |
var b = []; | |
var g = []; | |
var uvs = []; | |
let pos = geometry.attributes.position; | |
let norm = geometry.attributes.normal; | |
var newNormal = []; | |
Array.from({ length: verts }).forEach((s, i) => { | |
let vertex = new THREE.Vector3(pos.getX(i), pos.getY(i), pos.getZ(i)); | |
let normal = new THREE.Vector3(norm.getX(i), norm.getY(i), norm.getZ(i)); | |
b.push(vertex); | |
g.push(normal); | |
if (b.length == 3) { | |
var flatten = pointsInPlaneToPoints2D(b); | |
newNormal.push(...flatten.flat()); | |
b = []; | |
} | |
}); | |
geometry.setAttribute( | |
'uv', | |
new THREE.BufferAttribute(new Float32Array(newNormal), uvNumComponents) | |
); | |
return geometry; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment