Skip to content

Commit

Permalink
ImportMixamo: add an alternate retargeting technique
Browse files Browse the repository at this point in the history
  • Loading branch information
stephengold committed Nov 18, 2024
1 parent ebaedbc commit d6e6ef1
Showing 1 changed file with 41 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,11 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
import com.github.stephengold.wrench.test.MixamoData;
import com.jme3.anim.AnimClip;
import com.jme3.anim.AnimComposer;
import com.jme3.anim.AnimTrack;
import com.jme3.anim.Armature;
import com.jme3.anim.Joint;
import com.jme3.anim.TransformTrack;
import com.jme3.anim.util.HasLocalTransform;
import com.jme3.app.state.AppState;
import com.jme3.asset.AssetNotFoundException;
import com.jme3.asset.TextureKey;
Expand All @@ -60,6 +63,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
import java.util.logging.Level;
import java.util.logging.Logger;
import jme3utilities.Heart;
import jme3utilities.MyAnimation;
import jme3utilities.MyMesh;
import jme3utilities.MySkeleton;
import jme3utilities.MySpatial;
Expand Down Expand Up @@ -99,6 +103,7 @@ final class ImportMixamo extends ActionApplication {
final private static boolean translateForInitialSupport = false;
final private static boolean translateForSupport = true;
final private static boolean translateForTraction = false;
final private static boolean retargetUsingMap = false;
final private static float supportY = 0f;
/**
* message logger for this class
Expand Down Expand Up @@ -276,10 +281,16 @@ public void acorusInit() {
AnimClip sourceClip = Heart.first(clips);

// Retarget the clip to the character's armature:
SkeletonMapping map = new SkeletonMapping(armature);
String clipName = clipNames.get(animationI);
AnimClip retargeted = AnimationEdit.retargetAnimation(
sourceClip, armature, characterArmature, map, clipName);
AnimClip retargeted;
if (retargetUsingMap) {
SkeletonMapping map = new SkeletonMapping(armature);
String clipName = clipNames.get(animationI);
retargeted = AnimationEdit.retargetAnimation(
sourceClip, armature, characterArmature, map, clipName);
} else {
retargetClip(sourceClip, characterArmature);
retargeted = sourceClip; // alias
}

retargeted
= postProcess(retargeted, characterArmature, characterRoot);
Expand Down Expand Up @@ -478,6 +489,32 @@ private static void relocate(Texture texture, String pathPrefix) {
texture.setKey(newKey);
}

/**
* Retarget an AnimClip to the specified Armature without using SkeletopMap.
* This technique preserves any translation and/or scaling in the joint
* tracks.
*
* @param clip the clip to retarget (not null, modified)
* @param armature the desired armature (not null, unaffected)
*/
private static void retargetClip(AnimClip clip, Armature armature) {
AnimTrack[] animTracks = clip.getTracks(); // alias
clip.setTracks(new AnimTrack[0]);
for (AnimTrack animTrack : animTracks) {
if (MyAnimation.isJointTrack(animTrack)) {
TransformTrack transformTrack = (TransformTrack) animTrack;
HasLocalTransform animTarget = transformTrack.getTarget();
Joint animJoint = (Joint) animTarget;
String jointName = animJoint.getName();
Joint charaJoint = armature.getJoint(jointName);
if (charaJoint != null) {
transformTrack.setTarget(charaJoint);
AnimationEdit.addTrack(clip, transformTrack);
}
}
}
}

/**
* Set up asset locators for the specified group and asset.
*
Expand Down

0 comments on commit d6e6ef1

Please sign in to comment.