@@ -10,6 +10,9 @@ import { tangentLocal } from './Tangent.js';
10
10
import { uniform } from '../core/UniformNode.js' ;
11
11
import { buffer } from './BufferNode.js' ;
12
12
import { getDataFromObject } from '../core/NodeUtils.js' ;
13
+ import { storage } from './StorageBufferNode.js' ;
14
+ import { InstancedBufferAttribute } from '../../core/InstancedBufferAttribute.js' ;
15
+ import { instanceIndex } from '../core/IndexNode.js' ;
13
16
14
17
const _frameId = new WeakMap ( ) ;
15
18
@@ -31,9 +34,8 @@ class SkinningNode extends Node {
31
34
* Constructs a new skinning node.
32
35
*
33
36
* @param {SkinnedMesh } skinnedMesh - The skinned mesh.
34
- * @param {boolean } [useReference=false] - Whether to use reference nodes for internal skinned mesh related data or not.
35
37
*/
36
- constructor ( skinnedMesh , useReference = false ) {
38
+ constructor ( skinnedMesh ) {
37
39
38
40
super ( 'void' ) ;
39
41
@@ -44,14 +46,6 @@ class SkinningNode extends Node {
44
46
*/
45
47
this . skinnedMesh = skinnedMesh ;
46
48
47
- /**
48
- * Whether to use reference nodes for internal skinned mesh related data or not.
49
- * TODO: Explain the purpose of the property.
50
- *
51
- * @type {boolean }
52
- */
53
- this . useReference = useReference ;
54
-
55
49
/**
56
50
* The update type overwritten since skinning nodes are updated per object.
57
51
*
@@ -75,42 +69,40 @@ class SkinningNode extends Node {
75
69
*/
76
70
this . skinWeightNode = attribute ( 'skinWeight' , 'vec4' ) ;
77
71
78
- let bindMatrixNode , bindMatrixInverseNode , boneMatricesNode ;
79
-
80
- if ( useReference ) {
81
-
82
- bindMatrixNode = reference ( 'bindMatrix' , 'mat4' ) ;
83
- bindMatrixInverseNode = reference ( 'bindMatrixInverse' , 'mat4' ) ;
84
- boneMatricesNode = referenceBuffer ( 'skeleton.boneMatrices' , 'mat4' , skinnedMesh . skeleton . bones . length ) ;
85
-
86
- } else {
87
-
88
- bindMatrixNode = uniform ( skinnedMesh . bindMatrix , 'mat4' ) ;
89
- bindMatrixInverseNode = uniform ( skinnedMesh . bindMatrixInverse , 'mat4' ) ;
90
- boneMatricesNode = buffer ( skinnedMesh . skeleton . boneMatrices , 'mat4' , skinnedMesh . skeleton . bones . length ) ;
91
-
92
- }
93
-
94
72
/**
95
73
* The bind matrix node.
96
74
*
97
75
* @type {Node<mat4> }
98
76
*/
99
- this . bindMatrixNode = bindMatrixNode ;
77
+ this . bindMatrixNode = reference ( 'bindMatrix' , 'mat4' ) ;
100
78
101
79
/**
102
80
* The bind matrix inverse node.
103
81
*
104
82
* @type {Node<mat4> }
105
83
*/
106
- this . bindMatrixInverseNode = bindMatrixInverseNode ;
84
+ this . bindMatrixInverseNode = reference ( 'bindMatrixInverse' , 'mat4' ) ;
107
85
108
86
/**
109
87
* The bind matrices as a uniform buffer node.
110
88
*
111
89
* @type {Node }
112
90
*/
113
- this . boneMatricesNode = boneMatricesNode ;
91
+ this . boneMatricesNode = referenceBuffer ( 'skeleton.boneMatrices' , 'mat4' , skinnedMesh . skeleton . bones . length ) ;
92
+
93
+ /**
94
+ * The current vertex position in local space.
95
+ *
96
+ * @type {Node<vec3> }
97
+ */
98
+ this . positionNode = positionLocal ;
99
+
100
+ /**
101
+ * The result of vertex position in local space.
102
+ *
103
+ * @type {Node<vec3> }
104
+ */
105
+ this . toPositionNode = positionLocal ;
114
106
115
107
/**
116
108
* The previous bind matrices as a uniform buffer node.
@@ -127,10 +119,10 @@ class SkinningNode extends Node {
127
119
* Transforms the given vertex position via skinning.
128
120
*
129
121
* @param {Node } [boneMatrices=this.boneMatricesNode] - The bone matrices
130
- * @param {Node<vec3> } [position=positionLocal ] - The vertex position in local space.
122
+ * @param {Node<vec3> } [position=this.positionNode ] - The vertex position in local space.
131
123
* @return {Node<vec3> } The transformed vertex position.
132
124
*/
133
- getSkinnedPosition ( boneMatrices = this . boneMatricesNode , position = positionLocal ) {
125
+ getSkinnedPosition ( boneMatrices = this . boneMatricesNode , position = this . positionNode ) {
134
126
135
127
const { skinIndexNode, skinWeightNode, bindMatrixNode, bindMatrixInverseNode } = this ;
136
128
@@ -225,6 +217,7 @@ class SkinningNode extends Node {
225
217
* Setups the skinning node by assigning the transformed vertex data to predefined node variables.
226
218
*
227
219
* @param {NodeBuilder } builder - The current node builder.
220
+ * @return {Node<vec3> } The transformed vertex position.
228
221
*/
229
222
setup ( builder ) {
230
223
@@ -236,8 +229,9 @@ class SkinningNode extends Node {
236
229
237
230
const skinPosition = this . getSkinnedPosition ( ) ;
238
231
232
+ if ( this . toPositionNode ) this . toPositionNode . assign ( skinPosition ) ;
239
233
240
- positionLocal . assign ( skinPosition ) ;
234
+ //
241
235
242
236
if ( builder . hasGeometryAttribute ( 'normal' ) ) {
243
237
@@ -253,6 +247,8 @@ class SkinningNode extends Node {
253
247
254
248
}
255
249
250
+ return skinPosition ;
251
+
256
252
}
257
253
258
254
/**
@@ -266,7 +262,7 @@ class SkinningNode extends Node {
266
262
267
263
if ( output !== 'void' ) {
268
264
269
- return positionLocal . build ( builder , output ) ;
265
+ return super . generate ( builder , output ) ;
270
266
271
267
}
272
268
@@ -279,8 +275,7 @@ class SkinningNode extends Node {
279
275
*/
280
276
update ( frame ) {
281
277
282
- const object = this . useReference ? frame . object : this . skinnedMesh ;
283
- const skeleton = object . skeleton ;
278
+ const skeleton = frame . object && frame . object . skeleton ? frame . object . skeleton : this . skinnedMesh . skeleton ;
284
279
285
280
if ( _frameId . get ( skeleton ) === frame . frameId ) return ;
286
281
@@ -307,11 +302,25 @@ export default SkinningNode;
307
302
export const skinning = ( skinnedMesh ) => nodeObject ( new SkinningNode ( skinnedMesh ) ) ;
308
303
309
304
/**
310
- * TSL function for creating a skinning node with reference usage .
305
+ * TSL function for computing skinning.
311
306
*
312
307
* @tsl
313
308
* @function
314
309
* @param {SkinnedMesh } skinnedMesh - The skinned mesh.
310
+ * @param {Node<vec3> } [toPosition=null] - The target position.
315
311
* @returns {SkinningNode }
316
312
*/
317
- export const skinningReference = ( skinnedMesh ) => nodeObject ( new SkinningNode ( skinnedMesh , true ) ) ;
313
+ export const computeSkinning = ( skinnedMesh , toPosition = null ) => {
314
+
315
+ const node = new SkinningNode ( skinnedMesh ) ;
316
+ node . positionNode = storage ( new InstancedBufferAttribute ( skinnedMesh . geometry . getAttribute ( 'position' ) . array , 3 ) , 'vec3' ) . setPBO ( true ) . toReadOnly ( ) . element ( instanceIndex ) . toVar ( ) ;
317
+ node . skinIndexNode = storage ( new InstancedBufferAttribute ( new Uint32Array ( skinnedMesh . geometry . getAttribute ( 'skinIndex' ) . array ) , 4 ) , 'uvec4' ) . setPBO ( true ) . toReadOnly ( ) . element ( instanceIndex ) . toVar ( ) ;
318
+ node . skinWeightNode = storage ( new InstancedBufferAttribute ( skinnedMesh . geometry . getAttribute ( 'skinWeight' ) . array , 4 ) , 'vec4' ) . setPBO ( true ) . toReadOnly ( ) . element ( instanceIndex ) . toVar ( ) ;
319
+ node . bindMatrixNode = uniform ( skinnedMesh . bindMatrix , 'mat4' ) ;
320
+ node . bindMatrixInverseNode = uniform ( skinnedMesh . bindMatrixInverse , 'mat4' ) ;
321
+ node . boneMatricesNode = buffer ( skinnedMesh . skeleton . boneMatrices , 'mat4' , skinnedMesh . skeleton . bones . length ) ;
322
+ node . toPositionNode = toPosition ;
323
+
324
+ return nodeObject ( node ) ;
325
+
326
+ } ;
0 commit comments