Adds a MigrationUtil to migrate from old system to new system
This commit is contained in:
parent
e5057ad7fa
commit
728e28857b
jme3-core/src/main/java/com/jme3
anim
scene/debug/custom
jme3-examples/src/main/java/jme3test/model/anim
@ -4,8 +4,7 @@ import com.jme3.renderer.RenderManager;
|
||||
import com.jme3.renderer.ViewPort;
|
||||
import com.jme3.scene.control.AbstractControl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by Nehon on 20/12/2017.
|
||||
@ -65,6 +64,14 @@ public class AnimComposer extends AbstractControl {
|
||||
time = 0;
|
||||
}
|
||||
|
||||
public Collection<AnimClip> getAnimClips() {
|
||||
return Collections.unmodifiableCollection(animClipMap.values());
|
||||
}
|
||||
|
||||
public Collection<String> getAnimClipsNames() {
|
||||
return Collections.unmodifiableCollection(animClipMap.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void controlUpdate(float tpf) {
|
||||
if (currentAnimClip != null) {
|
||||
|
@ -169,7 +169,7 @@ public class Armature implements JmeCloneable, Savable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the current Armature state as it's bind pose.
|
||||
* Saves the current Armature state as its bind pose.
|
||||
*/
|
||||
public void setBindPose() {
|
||||
//make sure all bones are updated
|
||||
|
@ -34,11 +34,6 @@ public class Joint implements Savable, JmeCloneable {
|
||||
* Or relative to the model's origin for the root joint.
|
||||
*/
|
||||
private Transform localTransform = new Transform();
|
||||
/**
|
||||
* The base transform of the joint in local space.
|
||||
* Those transform are the joint's initial value.
|
||||
*/
|
||||
private Transform baseLocalTransform = new Transform();
|
||||
|
||||
/**
|
||||
* The transform of the joint in model space. Relative to the origin of the model.
|
||||
@ -134,7 +129,6 @@ public class Joint implements Savable, JmeCloneable {
|
||||
//Note that the whole Armature must be updated before calling this method.
|
||||
getModelTransform().toTransformMatrix(inverseModelBindMatrix);
|
||||
inverseModelBindMatrix.invertLocal();
|
||||
baseLocalTransform.set(localTransform);
|
||||
}
|
||||
|
||||
protected void resetToBindPose() {
|
||||
@ -267,8 +261,6 @@ public class Joint implements Savable, JmeCloneable {
|
||||
this.children = cloner.clone(children);
|
||||
this.attachedNode = cloner.clone(attachedNode);
|
||||
this.targetGeometry = cloner.clone(targetGeometry);
|
||||
|
||||
this.baseLocalTransform = cloner.clone(baseLocalTransform);
|
||||
this.localTransform = cloner.clone(localTransform);
|
||||
this.jointModelTransform = cloner.clone(jointModelTransform);
|
||||
this.inverseModelBindMatrix = cloner.clone(inverseModelBindMatrix);
|
||||
@ -283,8 +275,6 @@ public class Joint implements Savable, JmeCloneable {
|
||||
name = input.readString("name", null);
|
||||
attachedNode = (Node) input.readSavable("attachedNode", null);
|
||||
targetGeometry = (Geometry) input.readSavable("targetGeometry", null);
|
||||
baseLocalTransform = (Transform) input.readSavable("baseLocalTransforms", baseLocalTransform);
|
||||
localTransform.set(baseLocalTransform);
|
||||
inverseModelBindMatrix = (Matrix4f) input.readSavable("inverseModelBindMatrix", inverseModelBindMatrix);
|
||||
jointModelTransform = (JointModelTransform) input.readSavable("jointModelTransform", null);
|
||||
|
||||
@ -301,7 +291,6 @@ public class Joint implements Savable, JmeCloneable {
|
||||
output.write(name, "name", null);
|
||||
output.write(attachedNode, "attachedNode", null);
|
||||
output.write(targetGeometry, "targetGeometry", null);
|
||||
output.write(baseLocalTransform, "baseLocalTransform", new Transform());
|
||||
output.write(inverseModelBindMatrix, "inverseModelBindMatrix", new Matrix4f());
|
||||
output.writeSavableArrayList(children, "children", null);
|
||||
output.write(jointModelTransform, "jointModelTransform", null);
|
||||
|
@ -1,24 +1,189 @@
|
||||
package com.jme3.anim.util;
|
||||
|
||||
import com.jme3.animation.AnimControl;
|
||||
import com.jme3.scene.SceneGraphVisitor;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.anim.*;
|
||||
import com.jme3.animation.*;
|
||||
import com.jme3.math.Quaternion;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.scene.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class AnimMigrationUtils {
|
||||
|
||||
private static AnimControlVisitor animControlVisitor = new AnimControlVisitor();
|
||||
private static SkeletonControlVisitor skeletonControlVisitor = new SkeletonControlVisitor();
|
||||
|
||||
|
||||
public static Spatial migrate(Spatial source) {
|
||||
//source.depthFirstTraversal();
|
||||
Map<Skeleton, Armature> skeletonArmatureMap = new HashMap<>();
|
||||
animControlVisitor.setMappings(skeletonArmatureMap);
|
||||
source.depthFirstTraversal(animControlVisitor);
|
||||
skeletonControlVisitor.setMappings(skeletonArmatureMap);
|
||||
source.depthFirstTraversal(skeletonControlVisitor);
|
||||
return source;
|
||||
}
|
||||
|
||||
private class AnimControlVisitor implements SceneGraphVisitor {
|
||||
private static class AnimControlVisitor implements SceneGraphVisitor {
|
||||
|
||||
Map<Skeleton, Armature> skeletonArmatureMap;
|
||||
|
||||
@Override
|
||||
public void visit(Spatial spatial) {
|
||||
AnimControl control = spatial.getControl(AnimControl.class);
|
||||
if (control != null) {
|
||||
AnimComposer composer = new AnimComposer();
|
||||
Skeleton skeleton = control.getSkeleton();
|
||||
if (skeleton == null) {
|
||||
//only bone anim for now
|
||||
return;
|
||||
}
|
||||
|
||||
Joint[] joints = new Joint[skeleton.getBoneCount()];
|
||||
for (int i = 0; i < skeleton.getBoneCount(); i++) {
|
||||
Bone b = skeleton.getBone(i);
|
||||
Joint j = joints[i];
|
||||
if (j == null) {
|
||||
j = fromBone(b);
|
||||
joints[i] = j;
|
||||
}
|
||||
for (Bone bone : b.getChildren()) {
|
||||
int index = skeleton.getBoneIndex(bone);
|
||||
Joint joint = joints[index];
|
||||
if (joint == null) {
|
||||
joint = fromBone(bone);
|
||||
}
|
||||
j.addChild(joint);
|
||||
joints[index] = joint;
|
||||
}
|
||||
}
|
||||
|
||||
Armature armature = new Armature(joints);
|
||||
armature.setBindPose();
|
||||
skeletonArmatureMap.put(skeleton, armature);
|
||||
|
||||
for (String animName : control.getAnimationNames()) {
|
||||
Animation anim = control.getAnim(animName);
|
||||
AnimClip clip = new AnimClip(animName);
|
||||
Joint[] staticJoints = new Joint[joints.length];
|
||||
System.arraycopy(joints, 0, staticJoints, 0, joints.length);
|
||||
for (Track track : anim.getTracks()) {
|
||||
if (track instanceof BoneTrack) {
|
||||
BoneTrack boneTrack = (BoneTrack) track;
|
||||
int index = boneTrack.getTargetBoneIndex();
|
||||
Bone bone = skeleton.getBone(index);
|
||||
Joint joint = joints[index];
|
||||
JointTrack jointTrack = fromBoneTrack(boneTrack, bone, joint);
|
||||
clip.addTrack(jointTrack);
|
||||
//this joint is animated let's remove it from the static joints
|
||||
staticJoints[index] = null;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < staticJoints.length; i++) {
|
||||
Joint j = staticJoints[i];
|
||||
if (j != null) {
|
||||
// joint has no track , we create one with the default pose
|
||||
float[] times = new float[]{0};
|
||||
Vector3f[] translations = new Vector3f[]{j.getLocalTranslation()};
|
||||
Quaternion[] rotations = new Quaternion[]{j.getLocalRotation()};
|
||||
Vector3f[] scales = new Vector3f[]{j.getLocalScale()};
|
||||
JointTrack track = new JointTrack(j, times, translations, rotations, scales);
|
||||
clip.addTrack(track);
|
||||
}
|
||||
}
|
||||
|
||||
composer.addAnimClip(clip);
|
||||
}
|
||||
spatial.removeControl(control);
|
||||
spatial.addControl(composer);
|
||||
}
|
||||
}
|
||||
|
||||
public void setMappings(Map<Skeleton, Armature> skeletonArmatureMap) {
|
||||
this.skeletonArmatureMap = skeletonArmatureMap;
|
||||
}
|
||||
}
|
||||
|
||||
private static class SkeletonControlVisitor implements SceneGraphVisitor {
|
||||
|
||||
Map<Skeleton, Armature> skeletonArmatureMap;
|
||||
|
||||
@Override
|
||||
public void visit(Spatial spatial) {
|
||||
SkeletonControl control = spatial.getControl(SkeletonControl.class);
|
||||
if (control != null) {
|
||||
Armature armature = skeletonArmatureMap.get(control.getSkeleton());
|
||||
SkinningControl skinningControl = new SkinningControl(armature);
|
||||
Map<String, List<Spatial>> attachedSpatials = new HashMap<>();
|
||||
for (int i = 0; i < control.getSkeleton().getBoneCount(); i++) {
|
||||
Bone b = control.getSkeleton().getBone(i);
|
||||
Node n = control.getAttachmentsNode(b.getName());
|
||||
n.removeFromParent();
|
||||
if (!n.getChildren().isEmpty()) {
|
||||
attachedSpatials.put(b.getName(), n.getChildren());
|
||||
}
|
||||
}
|
||||
spatial.removeControl(control);
|
||||
spatial.addControl(skinningControl);
|
||||
for (String name : attachedSpatials.keySet()) {
|
||||
List<Spatial> spatials = attachedSpatials.get(name);
|
||||
for (Spatial child : spatials) {
|
||||
skinningControl.getAttachmentsNode(name).attachChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void setMappings(Map<Skeleton, Armature> skeletonArmatureMap) {
|
||||
this.skeletonArmatureMap = skeletonArmatureMap;
|
||||
}
|
||||
}
|
||||
|
||||
public static JointTrack fromBoneTrack(BoneTrack boneTrack, Bone bone, Joint joint) {
|
||||
float[] times = new float[boneTrack.getTimes().length];
|
||||
int length = times.length;
|
||||
System.arraycopy(boneTrack.getTimes(), 0, times, 0, length);
|
||||
//translation
|
||||
Vector3f[] translations = new Vector3f[length];
|
||||
if (boneTrack.getTranslations() != null) {
|
||||
for (int i = 0; i < boneTrack.getTranslations().length; i++) {
|
||||
Vector3f oldTrans = boneTrack.getTranslations()[i];
|
||||
Vector3f newTrans = new Vector3f();
|
||||
newTrans.set(bone.getBindPosition()).addLocal(oldTrans);
|
||||
translations[i] = newTrans;
|
||||
}
|
||||
}
|
||||
//rotation
|
||||
Quaternion[] rotations = new Quaternion[length];
|
||||
if (boneTrack.getRotations() != null) {
|
||||
for (int i = 0; i < boneTrack.getRotations().length; i++) {
|
||||
Quaternion oldRot = boneTrack.getRotations()[i];
|
||||
Quaternion newRot = new Quaternion();
|
||||
newRot.set(bone.getBindRotation()).multLocal(oldRot);
|
||||
rotations[i] = newRot;
|
||||
}
|
||||
}
|
||||
//scale
|
||||
Vector3f[] scales = new Vector3f[length];
|
||||
if (boneTrack.getScales() != null) {
|
||||
for (int i = 0; i < boneTrack.getScales().length; i++) {
|
||||
Vector3f oldScale = boneTrack.getScales()[i];
|
||||
Vector3f newScale = new Vector3f();
|
||||
newScale.set(bone.getBindScale()).multLocal(oldScale);
|
||||
scales[i] = newScale;
|
||||
}
|
||||
}
|
||||
|
||||
return new JointTrack(joint, times, translations, rotations, scales);
|
||||
}
|
||||
|
||||
private static Joint fromBone(Bone b) {
|
||||
Joint j = new Joint(b.getName());
|
||||
j.setLocalTranslation(b.getBindPosition());
|
||||
j.setLocalRotation(b.getBindRotation());
|
||||
j.setLocalScale(b.getBindScale());
|
||||
return j;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,8 +6,7 @@ package com.jme3.scene.debug.custom;
|
||||
|
||||
import com.jme3.anim.*;
|
||||
import com.jme3.app.Application;
|
||||
import com.jme3.app.state.AbstractAppState;
|
||||
import com.jme3.app.state.AppStateManager;
|
||||
import com.jme3.app.state.BaseAppState;
|
||||
import com.jme3.collision.CollisionResults;
|
||||
import com.jme3.input.MouseInput;
|
||||
import com.jme3.input.controls.ActionListener;
|
||||
@ -22,15 +21,17 @@ import java.util.*;
|
||||
/**
|
||||
* @author Nehon
|
||||
*/
|
||||
public class ArmatureDebugAppState extends AbstractAppState {
|
||||
public class ArmatureDebugAppState extends BaseAppState {
|
||||
|
||||
private Node debugNode = new Node("debugNode");
|
||||
private Map<Armature, ArmatureDebugger> armatures = new HashMap<>();
|
||||
private Map<Armature, Joint> selectedBones = new HashMap<>();
|
||||
private Application app;
|
||||
ViewPort vp;
|
||||
|
||||
@Override
|
||||
public void initialize(AppStateManager stateManager, Application app) {
|
||||
ViewPort vp = app.getRenderManager().createMainView("debug", app.getCamera());
|
||||
protected void initialize(Application app) {
|
||||
vp = app.getRenderManager().createMainView("debug", app.getCamera());
|
||||
vp.attachScene(debugNode);
|
||||
vp.setClearDepth(true);
|
||||
this.app = app;
|
||||
@ -39,12 +40,26 @@ public class ArmatureDebugAppState extends AbstractAppState {
|
||||
}
|
||||
app.getInputManager().addListener(actionListener, "shoot");
|
||||
app.getInputManager().addMapping("shoot", new MouseButtonTrigger(MouseInput.BUTTON_LEFT), new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));
|
||||
super.initialize(stateManager, app);
|
||||
|
||||
|
||||
debugNode.addLight(new DirectionalLight(new Vector3f(-1f, -1f, -1f).normalizeLocal()));
|
||||
|
||||
debugNode.addLight(new DirectionalLight(new Vector3f(1f, 1f, 1f).normalizeLocal(), new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f)));
|
||||
vp.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cleanup(Application app) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onEnable() {
|
||||
vp.setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDisable() {
|
||||
vp.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -53,13 +68,13 @@ public class ArmatureDebugAppState extends AbstractAppState {
|
||||
debugNode.updateGeometricState();
|
||||
}
|
||||
|
||||
public ArmatureDebugger addArmature(SkinningControl skinningControl) {
|
||||
public ArmatureDebugger addArmatureFrom(SkinningControl skinningControl) {
|
||||
Armature armature = skinningControl.getArmature();
|
||||
Spatial forSpatial = skinningControl.getSpatial();
|
||||
return addArmature(armature, forSpatial);
|
||||
return addArmatureFrom(armature, forSpatial);
|
||||
}
|
||||
|
||||
public ArmatureDebugger addArmature(Armature armature, Spatial forSpatial) {
|
||||
public ArmatureDebugger addArmatureFrom(Armature armature, Spatial forSpatial) {
|
||||
|
||||
ArmatureDebugger ad = new ArmatureDebugger(forSpatial.getName() + "_Armature", armature);
|
||||
ad.setLocalTransform(forSpatial.getWorldTransform());
|
||||
|
@ -0,0 +1,147 @@
|
||||
package jme3test.model.anim;
|
||||
|
||||
import com.jme3.anim.AnimComposer;
|
||||
import com.jme3.anim.SkinningControl;
|
||||
import com.jme3.anim.util.AnimMigrationUtils;
|
||||
import com.jme3.app.ChaseCameraAppState;
|
||||
import com.jme3.app.SimpleApplication;
|
||||
import com.jme3.input.KeyInput;
|
||||
import com.jme3.input.controls.ActionListener;
|
||||
import com.jme3.input.controls.KeyTrigger;
|
||||
import com.jme3.light.AmbientLight;
|
||||
import com.jme3.light.DirectionalLight;
|
||||
import com.jme3.math.*;
|
||||
import com.jme3.scene.Node;
|
||||
import com.jme3.scene.Spatial;
|
||||
import com.jme3.scene.debug.custom.ArmatureDebugAppState;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
/**
|
||||
* Created by Nehon on 18/12/2017.
|
||||
*/
|
||||
public class TestAnimMigration extends SimpleApplication {
|
||||
|
||||
ArmatureDebugAppState debugAppState;
|
||||
AnimComposer composer;
|
||||
Queue<String> anims = new LinkedList<>();
|
||||
boolean playAnim = true;
|
||||
|
||||
public static void main(String... argv) {
|
||||
TestAnimMigration app = new TestAnimMigration();
|
||||
app.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void simpleInitApp() {
|
||||
setTimer(new EraseTimer());
|
||||
//cam.setFrustumPerspective(90f, (float) cam.getWidth() / cam.getHeight(), 0.01f, 10f);
|
||||
viewPort.setBackgroundColor(ColorRGBA.DarkGray);
|
||||
rootNode.addLight(new DirectionalLight(new Vector3f(-1, -1, -1).normalizeLocal()));
|
||||
rootNode.addLight(new AmbientLight(ColorRGBA.DarkGray));
|
||||
|
||||
Spatial model = assetManager.loadModel("Models/Jaime/Jaime.j3o");
|
||||
//Spatial model = assetManager.loadModel("Models/Oto/Oto.mesh.xml");
|
||||
//Spatial model = assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml");
|
||||
//Spatial model = assetManager.loadModel("Models/Elephant/Elephant.mesh.xml");
|
||||
|
||||
AnimMigrationUtils.migrate(model);
|
||||
|
||||
rootNode.attachChild(model);
|
||||
|
||||
|
||||
debugAppState = new ArmatureDebugAppState();
|
||||
stateManager.attach(debugAppState);
|
||||
|
||||
setupModel(model);
|
||||
|
||||
flyCam.setEnabled(false);
|
||||
|
||||
Node target = new Node("CamTarget");
|
||||
//target.setLocalTransform(model.getLocalTransform());
|
||||
target.move(0, 1, 0);
|
||||
ChaseCameraAppState chaseCam = new ChaseCameraAppState();
|
||||
chaseCam.setTarget(target);
|
||||
getStateManager().attach(chaseCam);
|
||||
chaseCam.setInvertHorizontalAxis(true);
|
||||
chaseCam.setInvertVerticalAxis(true);
|
||||
chaseCam.setZoomSpeed(0.5f);
|
||||
chaseCam.setMinVerticalRotation(-FastMath.HALF_PI);
|
||||
chaseCam.setRotationSpeed(3);
|
||||
chaseCam.setDefaultDistance(3);
|
||||
chaseCam.setMinDistance(0.01f);
|
||||
chaseCam.setZoomSpeed(0.01f);
|
||||
chaseCam.setDefaultVerticalRotation(0.3f);
|
||||
|
||||
initInputs();
|
||||
}
|
||||
|
||||
public void initInputs() {
|
||||
inputManager.addMapping("toggleAnim", new KeyTrigger(KeyInput.KEY_RETURN));
|
||||
|
||||
inputManager.addListener(new ActionListener() {
|
||||
@Override
|
||||
public void onAction(String name, boolean isPressed, float tpf) {
|
||||
if (isPressed) {
|
||||
playAnim = !playAnim;
|
||||
if (playAnim) {
|
||||
String anim = anims.poll();
|
||||
anims.add(anim);
|
||||
composer.setCurrentAnimClip(anim);
|
||||
System.err.println(anim);
|
||||
} else {
|
||||
composer.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, "toggleAnim");
|
||||
inputManager.addMapping("nextAnim", new KeyTrigger(KeyInput.KEY_RIGHT));
|
||||
inputManager.addListener(new ActionListener() {
|
||||
@Override
|
||||
public void onAction(String name, boolean isPressed, float tpf) {
|
||||
if (isPressed && composer != null) {
|
||||
String anim = anims.poll();
|
||||
anims.add(anim);
|
||||
composer.setCurrentAnimClip(anim);
|
||||
System.err.println(anim);
|
||||
}
|
||||
}
|
||||
}, "nextAnim");
|
||||
}
|
||||
|
||||
private void setupModel(Spatial model) {
|
||||
if (composer != null) {
|
||||
return;
|
||||
}
|
||||
composer = model.getControl(AnimComposer.class);
|
||||
if (composer != null) {
|
||||
|
||||
SkinningControl sc = model.getControl(SkinningControl.class);
|
||||
debugAppState.addArmatureFrom(sc);
|
||||
|
||||
anims.clear();
|
||||
for (String name : composer.getAnimClipsNames()) {
|
||||
anims.add(name);
|
||||
}
|
||||
if (anims.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (playAnim) {
|
||||
String anim = anims.poll();
|
||||
anims.add(anim);
|
||||
composer.setCurrentAnimClip(anim);
|
||||
System.err.println(anim);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (model instanceof Node) {
|
||||
Node n = (Node) model;
|
||||
for (Spatial child : n.getChildren()) {
|
||||
setupModel(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -6,7 +6,6 @@ import com.jme3.app.SimpleApplication;
|
||||
import com.jme3.input.KeyInput;
|
||||
import com.jme3.input.controls.ActionListener;
|
||||
import com.jme3.input.controls.KeyTrigger;
|
||||
import com.jme3.light.DirectionalLight;
|
||||
import com.jme3.material.Material;
|
||||
import com.jme3.math.*;
|
||||
import com.jme3.scene.*;
|
||||
@ -37,6 +36,7 @@ public class TestArmature extends SimpleApplication {
|
||||
//cam.setFrustumPerspective(90f, (float) cam.getWidth() / cam.getHeight(), 0.01f, 10f);
|
||||
viewPort.setBackgroundColor(ColorRGBA.DarkGray);
|
||||
|
||||
//create armature
|
||||
Joint root = new Joint("Root_Joint");
|
||||
j1 = new Joint("Joint_1");
|
||||
j2 = new Joint("Joint_2");
|
||||
@ -52,9 +52,9 @@ public class TestArmature extends SimpleApplication {
|
||||
|
||||
final Armature armature = new Armature(joints);
|
||||
// armature.setModelTransformClass(SeparateJointModelTransform.class);
|
||||
|
||||
armature.setBindPose();
|
||||
|
||||
//create animations
|
||||
AnimClip clip = new AnimClip("anim");
|
||||
float[] times = new float[]{0, 2, 4};
|
||||
Quaternion[] rotations = new Quaternion[]{
|
||||
@ -83,15 +83,18 @@ public class TestArmature extends SimpleApplication {
|
||||
clip.addTrack(track1);
|
||||
clip.addTrack(track2);
|
||||
|
||||
//create the animComposer control
|
||||
final AnimComposer composer = new AnimComposer();
|
||||
composer.addAnimClip(clip);
|
||||
|
||||
//create the SkinningControl
|
||||
SkinningControl ac = new SkinningControl(armature);
|
||||
ac.setHardwareSkinningPreferred(false);
|
||||
Node node = new Node("Test Armature");
|
||||
|
||||
rootNode.attachChild(node);
|
||||
|
||||
//Create the mesh to deform.
|
||||
Geometry cylinder = new Geometry("cylinder", createMesh());
|
||||
Material m = new Material(assetManager, "Common/MatDefs/Misc/fakeLighting.j3md");
|
||||
m.setColor("Color", ColorRGBA.randomColor());
|
||||
@ -103,14 +106,9 @@ public class TestArmature extends SimpleApplication {
|
||||
composer.setCurrentAnimClip("anim");
|
||||
|
||||
ArmatureDebugAppState debugAppState = new ArmatureDebugAppState();
|
||||
debugAppState.addArmature(ac);
|
||||
debugAppState.addArmatureFrom(ac);
|
||||
stateManager.attach(debugAppState);
|
||||
|
||||
rootNode.addLight(new DirectionalLight(new Vector3f(-1f, -1f, -1f).normalizeLocal()));
|
||||
|
||||
rootNode.addLight(new DirectionalLight(new Vector3f(1f, 1f, 1f).normalizeLocal(), new ColorRGBA(0.7f, 0.7f, 0.7f, 1.0f)));
|
||||
|
||||
|
||||
flyCam.setEnabled(false);
|
||||
|
||||
ChaseCameraAppState chaseCam = new ChaseCameraAppState();
|
||||
@ -132,12 +130,10 @@ public class TestArmature extends SimpleApplication {
|
||||
@Override
|
||||
public void onAction(String name, boolean isPressed, float tpf) {
|
||||
if (isPressed) {
|
||||
play = false;
|
||||
composer.reset();
|
||||
armature.resetToBindPose();
|
||||
|
||||
} else {
|
||||
play = true;
|
||||
composer.setCurrentAnimClip("anim");
|
||||
}
|
||||
}
|
||||
@ -202,12 +198,10 @@ public class TestArmature extends SimpleApplication {
|
||||
|
||||
c.updateCounts();
|
||||
c.updateBound();
|
||||
//the mesh has some skinning let's create needed buffers for HW skinning
|
||||
//creating empty buffers for HW skinning
|
||||
//the buffers will be setup if ever used.
|
||||
|
||||
VertexBuffer weightsHW = new VertexBuffer(VertexBuffer.Type.HWBoneWeight);
|
||||
VertexBuffer indicesHW = new VertexBuffer(VertexBuffer.Type.HWBoneIndex);
|
||||
//setting usage to cpuOnly so that the buffer is not send empty to the GPU
|
||||
|
||||
indicesHW.setUsage(VertexBuffer.Usage.CpuOnly);
|
||||
weightsHW.setUsage(VertexBuffer.Usage.CpuOnly);
|
||||
c.setBuffer(weightsHW);
|
||||
@ -220,20 +214,4 @@ public class TestArmature extends SimpleApplication {
|
||||
}
|
||||
|
||||
|
||||
float time = 0;
|
||||
boolean play = true;
|
||||
|
||||
@Override
|
||||
public void simpleUpdate(float tpf) {
|
||||
|
||||
|
||||
// if (play == false) {
|
||||
// return;
|
||||
// }
|
||||
// time += tpf;
|
||||
// float rot = FastMath.sin(time);
|
||||
// j1.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.HALF_PI * rot, Vector3f.UNIT_Z));
|
||||
// j2.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.HALF_PI * rot, Vector3f.UNIT_Z));
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user