@@ -122,7 +122,40 @@ export class NgtsDecal {
122
122
if ( ! rotation || typeof rotation === 'number' ) {
123
123
const obj = new THREE . Object3D ( ) ;
124
124
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
+
126
159
if ( typeof rotation === 'number' ) obj . rotateZ ( rotation ) ;
127
160
applyProps ( state , { rotation : obj . rotation } ) ;
128
161
} else {
0 commit comments