Skip to content

Commit ea6e975

Browse files
authored
SkinnedMesh: Update "applyBoneTransform" to optionally take Vector4, support direction or position transformation (mrdoob#33091)
1 parent 7bbb584 commit ea6e975

1 file changed

Lines changed: 26 additions & 9 deletions

File tree

src/objects/SkinnedMesh.js

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ import { Ray } from '../math/Ray.js';
88
import { AttachedBindMode, DetachedBindMode } from '../constants.js';
99
import { warn } from '../utils.js';
1010

11-
const _basePosition = /*@__PURE__*/ new Vector3();
11+
const _baseVector = /*@__PURE__*/ new Vector4();
1212

1313
const _skinIndex = /*@__PURE__*/ new Vector4();
1414
const _skinWeight = /*@__PURE__*/ new Vector4();
1515

16-
const _vector3 = /*@__PURE__*/ new Vector3();
16+
const _vector4 = /*@__PURE__*/ new Vector4();
1717
const _matrix4 = /*@__PURE__*/ new Matrix4();
1818
const _vertex = /*@__PURE__*/ new Vector3();
1919

@@ -309,12 +309,12 @@ class SkinnedMesh extends Mesh {
309309

310310
/**
311311
* Applies the bone transform associated with the given index to the given
312-
* vertex position. Returns the updated vector.
312+
* vector. Can be used to transform positions or direction vectors by providing
313+
* a Vector4 with 1 or 0 in the w component respectively. Returns the updated vector.
313314
*
314315
* @param {number} index - The vertex index.
315-
* @param {Vector3} target - The target object that is used to store the method's result.
316-
* the skinned mesh's world matrix will be used instead.
317-
* @return {Vector3} The updated vertex position.
316+
* @param {Vector3|Vector4} target - The target object that is used to store the method's result.
317+
* @return {Vector3|Vector4} The updated vertex attribute data.
318318
*/
319319
applyBoneTransform( index, target ) {
320320

@@ -324,9 +324,19 @@ class SkinnedMesh extends Mesh {
324324
_skinIndex.fromBufferAttribute( geometry.attributes.skinIndex, index );
325325
_skinWeight.fromBufferAttribute( geometry.attributes.skinWeight, index );
326326

327-
_basePosition.copy( target ).applyMatrix4( this.bindMatrix );
327+
if ( target.isVector4 ) {
328+
329+
_baseVector.copy( target );
330+
target.set( 0, 0, 0, 0 );
331+
332+
} else {
333+
334+
_baseVector.set( ...target, 1 );
335+
target.set( 0, 0, 0 );
328336

329-
target.set( 0, 0, 0 );
337+
}
338+
339+
_baseVector.applyMatrix4( this.bindMatrix );
330340

331341
for ( let i = 0; i < 4; i ++ ) {
332342

@@ -338,12 +348,19 @@ class SkinnedMesh extends Mesh {
338348

339349
_matrix4.multiplyMatrices( skeleton.bones[ boneIndex ].matrixWorld, skeleton.boneInverses[ boneIndex ] );
340350

341-
target.addScaledVector( _vector3.copy( _basePosition ).applyMatrix4( _matrix4 ), weight );
351+
target.addScaledVector( _vector4.copy( _baseVector ).applyMatrix4( _matrix4 ), weight );
342352

343353
}
344354

345355
}
346356

357+
if ( target.isVector4 ) {
358+
359+
// ensure the homogenous coordinate remains unchanged after vector operations
360+
target.w = _baseVector.w;
361+
362+
}
363+
347364
return target.applyMatrix4( this.bindMatrixInverse );
348365

349366
}

0 commit comments

Comments
 (0)