Skip to content

Commit 1d126cf

Browse files
authored
Examples: add webgpu_animation_retargeting (#29338)
* add webgpu_animation_retargeting * cleanup * Revert "cleanup" This reverts commit 7d51a19. * Update webgpu_animation_retargeting.html * adding floor * update * Update webgpu_animation_retargeting.html * update * update * Update webgpu_animation_retargeting.html * updates * update
1 parent cf392ea commit 1d126cf

File tree

4 files changed

+295
-48
lines changed

4 files changed

+295
-48
lines changed

examples/files.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@
301301
"webgl_performance"
302302
],
303303
"webgpu (wip)": [
304+
"webgpu_animation_retargeting",
304305
"webgpu_backdrop",
305306
"webgpu_backdrop_area",
306307
"webgpu_backdrop_water",

examples/jsm/utils/SkeletonUtils.js

Lines changed: 35 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,23 @@ import {
1212

1313
function retarget( target, source, options = {} ) {
1414

15-
const pos = new Vector3(),
16-
quat = new Quaternion(),
15+
const quat = new Quaternion(),
1716
scale = new Vector3(),
18-
bindBoneMatrix = new Matrix4(),
1917
relativeMatrix = new Matrix4(),
2018
globalMatrix = new Matrix4();
2119

22-
options.preserveMatrix = options.preserveMatrix !== undefined ? options.preserveMatrix : true;
23-
options.preservePosition = options.preservePosition !== undefined ? options.preservePosition : true;
20+
options.preserveBoneMatrix = options.preserveBoneMatrix !== undefined ? options.preserveBoneMatrix : true;
21+
options.preserveBonePositions = options.preserveBonePositions !== undefined ? options.preserveBonePositions : true;
2422
options.preserveHipPosition = options.preserveHipPosition !== undefined ? options.preserveHipPosition : false;
2523
options.useTargetMatrix = options.useTargetMatrix !== undefined ? options.useTargetMatrix : false;
2624
options.hip = options.hip !== undefined ? options.hip : 'hip';
25+
options.scale = options.scale !== undefined ? options.scale : 1;
2726
options.names = options.names || {};
2827

2928
const sourceBones = source.isObject3D ? source.skeleton.bones : getBones( source ),
3029
bones = target.isObject3D ? target.skeleton.bones : getBones( target );
3130

32-
let bindBones,
33-
bone, name, boneTo,
31+
let bone, name, boneTo,
3432
bonesPosition;
3533

3634
// reset bones
@@ -42,11 +40,11 @@ function retarget( target, source, options = {} ) {
4240
} else {
4341

4442
options.useTargetMatrix = true;
45-
options.preserveMatrix = false;
43+
options.preserveBoneMatrix = false;
4644

4745
}
4846

49-
if ( options.preservePosition ) {
47+
if ( options.preserveBonePositions ) {
5048

5149
bonesPosition = [];
5250

@@ -58,7 +56,7 @@ function retarget( target, source, options = {} ) {
5856

5957
}
6058

61-
if ( options.preserveMatrix ) {
59+
if ( options.preserveBoneMatrix ) {
6260

6361
// reset matrix
6462

@@ -76,35 +74,10 @@ function retarget( target, source, options = {} ) {
7674

7775
}
7876

79-
if ( options.offsets ) {
80-
81-
bindBones = [];
82-
83-
for ( let i = 0; i < bones.length; ++ i ) {
84-
85-
bone = bones[ i ];
86-
name = options.names[ bone.name ] || bone.name;
87-
88-
if ( options.offsets[ name ] ) {
89-
90-
bone.matrix.multiply( options.offsets[ name ] );
91-
92-
bone.matrix.decompose( bone.position, bone.quaternion, bone.scale );
93-
94-
bone.updateMatrixWorld();
95-
96-
}
97-
98-
bindBones.push( bone.matrixWorld.clone() );
99-
100-
}
101-
102-
}
103-
10477
for ( let i = 0; i < bones.length; ++ i ) {
10578

10679
bone = bones[ i ];
107-
name = options.names[ bone.name ] || bone.name;
80+
name = options.names[ bone.name ];
10881

10982
boneTo = getBoneByName( name, sourceBones );
11083

@@ -136,31 +109,44 @@ function retarget( target, source, options = {} ) {
136109

137110
if ( target.isObject3D ) {
138111

139-
const boneIndex = bones.indexOf( bone ),
140-
wBindMatrix = bindBones ? bindBones[ boneIndex ] : bindBoneMatrix.copy( target.skeleton.boneInverses[ boneIndex ] ).invert();
112+
if ( options.localOffsets ) {
141113

142-
globalMatrix.multiply( wBindMatrix );
114+
if ( options.localOffsets[ bone.name ] ) {
115+
116+
globalMatrix.multiply( options.localOffsets[ bone.name ] );
117+
118+
}
119+
120+
}
143121

144122
}
145123

146124
globalMatrix.copyPosition( relativeMatrix );
147125

148126
}
149127

150-
if ( bone.parent && bone.parent.isBone ) {
128+
if ( name === options.hip ) {
151129

152-
bone.matrix.copy( bone.parent.matrixWorld ).invert();
153-
bone.matrix.multiply( globalMatrix );
130+
globalMatrix.elements[ 12 ] *= options.scale;
131+
globalMatrix.elements[ 13 ] *= options.scale;
132+
globalMatrix.elements[ 14 ] *= options.scale;
154133

155-
} else {
134+
if ( options.preserveHipPosition ) {
156135

157-
bone.matrix.copy( globalMatrix );
136+
globalMatrix.elements[ 12 ] = globalMatrix.elements[ 14 ] = 0;
137+
138+
}
158139

159140
}
160141

161-
if ( options.preserveHipPosition && name === options.hip ) {
142+
if ( bone.parent ) {
162143

163-
bone.matrix.setPosition( pos.set( 0, bone.position.y, 0 ) );
144+
bone.matrix.copy( bone.parent.matrixWorld ).invert();
145+
bone.matrix.multiply( globalMatrix );
146+
147+
} else {
148+
149+
bone.matrix.copy( globalMatrix );
164150

165151
}
166152

@@ -170,7 +156,7 @@ function retarget( target, source, options = {} ) {
170156

171157
}
172158

173-
if ( options.preservePosition ) {
159+
if ( options.preserveBonePositions ) {
174160

175161
for ( let i = 0; i < bones.length; ++ i ) {
176162

@@ -187,7 +173,7 @@ function retarget( target, source, options = {} ) {
187173

188174
}
189175

190-
if ( options.preserveMatrix ) {
176+
if ( options.preserveBoneMatrix ) {
191177

192178
// restore matrix
193179

@@ -200,6 +186,7 @@ function retarget( target, source, options = {} ) {
200186
function retargetClip( target, source, clip, options = {} ) {
201187

202188
options.useFirstFramePosition = options.useFirstFramePosition !== undefined ? options.useFirstFramePosition : false;
189+
203190
// Calculate the fps from the source clip based on the track with the most frames, unless fps is already provided.
204191
options.fps = options.fps !== undefined ? options.fps : ( Math.max( ...clip.tracks.map( track => track.times.length ) ) / clip.duration );
205192
options.names = options.names || [];
22.5 KB
Loading

0 commit comments

Comments
 (0)