Skip to content

Instantly share code, notes, and snippets.

@claydegruchy
Created March 4, 2022 19:57
Show Gist options
  • Save claydegruchy/14033c451f26e3e5e7fe725ed34ace14 to your computer and use it in GitHub Desktop.
Save claydegruchy/14033c451f26e3e5e7fe725ed34ace14 to your computer and use it in GitHub Desktop.
// 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