Skip to content

Commit 72f9c1d

Browse files
committed
fix(soba): update decal
1 parent fc58e47 commit 72f9c1d

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

libs/soba/misc/src/lib/decal.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,40 @@ export class NgtsDecal {
122122
if (!rotation || typeof rotation === 'number') {
123123
const obj = new THREE.Object3D();
124124
obj.position.copy(state.position);
125-
obj.lookAt(parent.position);
125+
126+
// Thanks https://x.com/N8Programs !
127+
const vertices = parent.geometry.attributes['position'].array;
128+
if (parent.geometry.attributes['normal'] === undefined) {
129+
parent.geometry.computeVertexNormals();
130+
}
131+
const normal = parent.geometry.attributes['normal'].array;
132+
let distance = Infinity;
133+
let closestNormal = new THREE.Vector3();
134+
const ox = obj.position.x;
135+
const oy = obj.position.y;
136+
const oz = obj.position.z;
137+
const vLength = vertices.length;
138+
let chosenIdx = -1;
139+
for (let i = 0; i < vLength; i += 3) {
140+
const x = vertices[i];
141+
const y = vertices[i + 1];
142+
const z = vertices[i + 2];
143+
const xDiff = x - ox;
144+
const yDiff = y - oy;
145+
const zDiff = z - oz;
146+
const distSquared = xDiff * xDiff + yDiff * yDiff + zDiff * zDiff;
147+
if (distSquared < distance) {
148+
distance = distSquared;
149+
chosenIdx = i;
150+
}
151+
}
152+
closestNormal.fromArray(normal, chosenIdx);
153+
154+
// Get vector tangent to normal
155+
obj.lookAt(obj.position.clone().add(closestNormal));
156+
obj.rotateZ(Math.PI);
157+
obj.rotateY(Math.PI);
158+
126159
if (typeof rotation === 'number') obj.rotateZ(rotation);
127160
applyProps(state, { rotation: obj.rotation });
128161
} else {

0 commit comments

Comments
 (0)