|
|
@@ -1,6 +1,5 @@
|
|
|
|
|
|
import { float, Fn, ivec2, int, If, uniform } from '../tsl/TSLBase.js';
|
|
|
-import { reference } from './ReferenceNode.js';
|
|
|
import { Loop } from '../utils/LoopNode.js';
|
|
|
import { OnObjectUpdate } from '../utils/EventNode.js';
|
|
|
import { textureLoad } from './TextureNode.js';
|
|
|
@@ -12,10 +11,11 @@ import { DataArrayTexture } from '../../textures/DataArrayTexture.js';
|
|
|
import { Vector2 } from '../../math/Vector2.js';
|
|
|
import { Vector4 } from '../../math/Vector4.js';
|
|
|
import { FloatType } from '../../constants.js';
|
|
|
+import { uniformArray } from './UniformArrayNode.js';
|
|
|
|
|
|
const _morphTextures = /*@__PURE__*/ new WeakMap();
|
|
|
const _morphVec4 = /*@__PURE__*/ new Vector4();
|
|
|
-const _morphBaseInfluences = /*@__PURE__*/ new WeakMap();
|
|
|
+const _morphInfluencesData = /*@__PURE__*/ new WeakMap();
|
|
|
|
|
|
/**
|
|
|
* TSL function that retrieves and scales the morphed attribute (position or normal) texel value.
|
|
|
@@ -174,13 +174,6 @@ function getEntry( geometry ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * TSL object representing a reference to the mesh's morphTargetInfluences array.
|
|
|
- *
|
|
|
- * @type {ReferenceNode<float>}
|
|
|
- */
|
|
|
-export const morphTargetInfluences = /*@__PURE__*/ reference( 'morphTargetInfluences', 'float' );
|
|
|
-
|
|
|
/**
|
|
|
* TSL function representing the vertex shader morph targets blend setup.
|
|
|
* Dynamically computes morph targets weights and updates positionLocal and normalLocal in-place.
|
|
|
@@ -201,33 +194,30 @@ export const morphReference = /*@__PURE__*/ Fn( ( [ mesh ] ) => {
|
|
|
|
|
|
if ( morphTargetsCount === 0 ) return;
|
|
|
|
|
|
- let morphBaseInfluence = _morphBaseInfluences.get( mesh );
|
|
|
-
|
|
|
- if ( ! morphBaseInfluence ) {
|
|
|
-
|
|
|
- morphBaseInfluence = uniform( 1 );
|
|
|
- _morphBaseInfluences.set( mesh, morphBaseInfluence );
|
|
|
-
|
|
|
- OnObjectUpdate( ( { object } ) => {
|
|
|
+ // Init
|
|
|
|
|
|
- if ( object.geometry.morphTargetsRelative ) {
|
|
|
+ let morphInfluenceData = _morphInfluencesData.get( mesh );
|
|
|
|
|
|
- morphBaseInfluence.value = 1;
|
|
|
+ if ( morphInfluenceData === undefined || morphInfluenceData.count !== morphTargetsCount ) {
|
|
|
|
|
|
- } else {
|
|
|
+ morphInfluenceData = {
|
|
|
+ base: uniform( 1 ),
|
|
|
+ influences: mesh.morphTargetInfluences ? uniformArray( mesh.morphTargetInfluences, 'float' ) : null,
|
|
|
+ count: morphTargetsCount
|
|
|
+ };
|
|
|
|
|
|
- morphBaseInfluence.value = 1 - object.morphTargetInfluences.reduce( ( a, b ) => a + b, 0 );
|
|
|
+ _morphInfluencesData.set( mesh, morphInfluenceData );
|
|
|
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- } );
|
|
|
+ const { base, influences } = morphInfluenceData;
|
|
|
|
|
|
- }
|
|
|
+ // Shader
|
|
|
|
|
|
const { texture: bufferMap, stride, size } = getEntry( geometry );
|
|
|
|
|
|
- if ( hasMorphPosition === true ) positionLocal.mulAssign( morphBaseInfluence );
|
|
|
- if ( hasMorphNormals === true ) normalLocal.mulAssign( morphBaseInfluence );
|
|
|
+ if ( hasMorphPosition === true ) positionLocal.mulAssign( base );
|
|
|
+ if ( hasMorphNormals === true ) normalLocal.mulAssign( base );
|
|
|
|
|
|
const width = int( size.width );
|
|
|
|
|
|
@@ -241,7 +231,7 @@ export const morphReference = /*@__PURE__*/ Fn( ( [ mesh ] ) => {
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- influence.assign( morphTargetInfluences.element( i ).toVar() );
|
|
|
+ influence.assign( influences.element( i ).toVar() );
|
|
|
|
|
|
}
|
|
|
|
|
|
@@ -277,6 +267,31 @@ export const morphReference = /*@__PURE__*/ Fn( ( [ mesh ] ) => {
|
|
|
|
|
|
} );
|
|
|
|
|
|
+ // Update
|
|
|
+
|
|
|
+ OnObjectUpdate( ( { object } ) => {
|
|
|
+
|
|
|
+ const { base, influences } = morphInfluenceData;
|
|
|
+
|
|
|
+ if ( object.geometry.morphTargetsRelative ) {
|
|
|
+
|
|
|
+ base.value = 1;
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ base.value = 1 - object.morphTargetInfluences.reduce( ( a, b ) => a + b, 0 );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( influences ) {
|
|
|
+
|
|
|
+ influences.array = object.morphTargetInfluences;
|
|
|
+ influences.update();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } );
|
|
|
+
|
|
|
}, 'void' );
|
|
|
|
|
|
|