parent
a4267393e1
commit
a1a9486424
@ -0,0 +1,168 @@ |
|||||||
|
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.asset.plugins.FileLocator; |
||||||
|
import com.jme3.export.binary.BinaryExporter; |
||||||
|
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 com.jme3.system.JmeSystem; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.io.IOException; |
||||||
|
import java.util.LinkedList; |
||||||
|
import java.util.Queue; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by Nehon on 18/12/2017. |
||||||
|
*/ |
||||||
|
public class TestAnimSerialization extends SimpleApplication { |
||||||
|
|
||||||
|
ArmatureDebugAppState debugAppState; |
||||||
|
AnimComposer composer; |
||||||
|
Queue<String> anims = new LinkedList<>(); |
||||||
|
boolean playAnim = true; |
||||||
|
File file; |
||||||
|
|
||||||
|
public static void main(String... argv) { |
||||||
|
TestAnimSerialization app = new TestAnimSerialization(); |
||||||
|
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"); |
||||||
|
|
||||||
|
AnimMigrationUtils.migrate(model); |
||||||
|
|
||||||
|
File storageFolder = JmeSystem.getStorageFolder(); |
||||||
|
file = new File(storageFolder.getPath() + File.separator + "newJaime.j3o"); |
||||||
|
BinaryExporter be = new BinaryExporter(); |
||||||
|
try { |
||||||
|
be.save(model, file); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
|
||||||
|
assetManager.registerLocator(storageFolder.getPath(), FileLocator.class); |
||||||
|
model = assetManager.loadModel("newJaime.j3o"); |
||||||
|
|
||||||
|
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); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void destroy() { |
||||||
|
super.destroy(); |
||||||
|
file.delete(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,217 @@ |
|||||||
|
package jme3test.model.anim; |
||||||
|
|
||||||
|
import com.jme3.anim.*; |
||||||
|
import com.jme3.app.ChaseCameraAppState; |
||||||
|
import com.jme3.app.SimpleApplication; |
||||||
|
import com.jme3.asset.plugins.FileLocator; |
||||||
|
import com.jme3.export.binary.BinaryExporter; |
||||||
|
import com.jme3.input.KeyInput; |
||||||
|
import com.jme3.input.controls.ActionListener; |
||||||
|
import com.jme3.input.controls.KeyTrigger; |
||||||
|
import com.jme3.material.Material; |
||||||
|
import com.jme3.math.*; |
||||||
|
import com.jme3.scene.*; |
||||||
|
import com.jme3.scene.debug.custom.ArmatureDebugAppState; |
||||||
|
import com.jme3.scene.shape.Cylinder; |
||||||
|
import com.jme3.system.JmeSystem; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.io.IOException; |
||||||
|
import java.nio.FloatBuffer; |
||||||
|
import java.nio.ShortBuffer; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by Nehon on 18/12/2017. |
||||||
|
*/ |
||||||
|
public class TestBaseAnimSerialization extends SimpleApplication { |
||||||
|
|
||||||
|
Joint j1; |
||||||
|
Joint j2; |
||||||
|
AnimComposer composer; |
||||||
|
Armature armature; |
||||||
|
File file; |
||||||
|
|
||||||
|
public static void main(String... argv) { |
||||||
|
TestBaseAnimSerialization app = new TestBaseAnimSerialization(); |
||||||
|
app.start(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void simpleInitApp() { |
||||||
|
setTimer(new EraseTimer()); |
||||||
|
renderManager.setSinglePassLightBatchSize(2); |
||||||
|
//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"); |
||||||
|
Joint j3 = new Joint("Joint_3"); |
||||||
|
root.addChild(j1); |
||||||
|
j1.addChild(j2); |
||||||
|
j2.addChild(j3); |
||||||
|
root.setLocalTranslation(new Vector3f(0, 0, 0.5f)); |
||||||
|
j1.setLocalTranslation(new Vector3f(0, 0.0f, -0.5f)); |
||||||
|
j2.setLocalTranslation(new Vector3f(0, 0.0f, -0.3f)); |
||||||
|
j3.setLocalTranslation(new Vector3f(0, 0, -0.2f)); |
||||||
|
Joint[] joints = new Joint[]{root, j1, j2, j3}; |
||||||
|
|
||||||
|
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[]{ |
||||||
|
new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X), |
||||||
|
new Quaternion().fromAngleAxis(FastMath.HALF_PI, Vector3f.UNIT_X), |
||||||
|
new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X) |
||||||
|
}; |
||||||
|
Vector3f[] translations = new Vector3f[]{ |
||||||
|
new Vector3f(0, 0.2f, 0), |
||||||
|
new Vector3f(0, 1.0f, 0), |
||||||
|
new Vector3f(0, 0.2f, 0), |
||||||
|
}; |
||||||
|
Vector3f[] scales = new Vector3f[]{ |
||||||
|
new Vector3f(1, 1, 1), |
||||||
|
new Vector3f(1, 1, 2), |
||||||
|
new Vector3f(1, 1, 1), |
||||||
|
}; |
||||||
|
Vector3f[] scales2 = new Vector3f[]{ |
||||||
|
new Vector3f(1, 1, 1), |
||||||
|
new Vector3f(1, 1, 0.5f), |
||||||
|
new Vector3f(1, 1, 1), |
||||||
|
}; |
||||||
|
|
||||||
|
JointTrack track1 = new JointTrack(j1, times, null, rotations, scales); |
||||||
|
JointTrack track2 = new JointTrack(j2, times, null, rotations, null); |
||||||
|
clip.addTrack(track1); |
||||||
|
clip.addTrack(track2); |
||||||
|
|
||||||
|
//create the animComposer control
|
||||||
|
composer = new AnimComposer(); |
||||||
|
composer.addAnimClip(clip); |
||||||
|
|
||||||
|
//create the SkinningControl
|
||||||
|
SkinningControl ac = new SkinningControl(armature); |
||||||
|
Node node = new Node("Test Armature"); |
||||||
|
|
||||||
|
//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()); |
||||||
|
cylinder.setMaterial(m); |
||||||
|
node.attachChild(cylinder); |
||||||
|
node.addControl(composer); |
||||||
|
node.addControl(ac); |
||||||
|
|
||||||
|
File storageFolder = JmeSystem.getStorageFolder(); |
||||||
|
file = new File(storageFolder.getPath() + File.separator + "test.j3o"); |
||||||
|
BinaryExporter be = new BinaryExporter(); |
||||||
|
try { |
||||||
|
be.save(node, file); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
|
||||||
|
assetManager.registerLocator(storageFolder.getPath(), FileLocator.class); |
||||||
|
Node newNode = (Node) assetManager.loadModel("test.j3o"); |
||||||
|
|
||||||
|
rootNode.attachChild(newNode); |
||||||
|
|
||||||
|
composer = newNode.getControl(AnimComposer.class); |
||||||
|
ac = newNode.getControl(SkinningControl.class); |
||||||
|
ac.setHardwareSkinningPreferred(false); |
||||||
|
armature = ac.getArmature(); |
||||||
|
composer.setCurrentAnimClip("anim"); |
||||||
|
|
||||||
|
ArmatureDebugAppState debugAppState = new ArmatureDebugAppState(); |
||||||
|
debugAppState.addArmatureFrom(ac); |
||||||
|
stateManager.attach(debugAppState); |
||||||
|
|
||||||
|
flyCam.setEnabled(false); |
||||||
|
|
||||||
|
ChaseCameraAppState chaseCam = new ChaseCameraAppState(); |
||||||
|
chaseCam.setTarget(node); |
||||||
|
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); |
||||||
|
|
||||||
|
|
||||||
|
inputManager.addMapping("bind", new KeyTrigger(KeyInput.KEY_SPACE)); |
||||||
|
inputManager.addListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void onAction(String name, boolean isPressed, float tpf) { |
||||||
|
if (isPressed) { |
||||||
|
composer.reset(); |
||||||
|
armature.resetToBindPose(); |
||||||
|
|
||||||
|
} else { |
||||||
|
composer.setCurrentAnimClip("anim"); |
||||||
|
} |
||||||
|
} |
||||||
|
}, "bind"); |
||||||
|
} |
||||||
|
|
||||||
|
private Mesh createMesh() { |
||||||
|
Cylinder c = new Cylinder(30, 16, 0.1f, 1, true); |
||||||
|
|
||||||
|
ShortBuffer jointIndex = (ShortBuffer) VertexBuffer.createBuffer(VertexBuffer.Format.UnsignedShort, 4, c.getVertexCount()); |
||||||
|
jointIndex.rewind(); |
||||||
|
c.setMaxNumWeights(1); |
||||||
|
FloatBuffer jointWeight = (FloatBuffer) VertexBuffer.createBuffer(VertexBuffer.Format.Float, 4, c.getVertexCount()); |
||||||
|
jointWeight.rewind(); |
||||||
|
VertexBuffer vb = c.getBuffer(VertexBuffer.Type.Position); |
||||||
|
FloatBuffer fvb = (FloatBuffer) vb.getData(); |
||||||
|
fvb.rewind(); |
||||||
|
for (int i = 0; i < c.getVertexCount(); i++) { |
||||||
|
fvb.get(); |
||||||
|
fvb.get(); |
||||||
|
float z = fvb.get(); |
||||||
|
int index = 0; |
||||||
|
if (z > 0) { |
||||||
|
index = 0; |
||||||
|
} else if (z > -0.2) { |
||||||
|
index = 1; |
||||||
|
} else { |
||||||
|
index = 2; |
||||||
|
} |
||||||
|
jointIndex.put((short) index).put((short) 0).put((short) 0).put((short) 0); |
||||||
|
jointWeight.put(1f).put(0f).put(0f).put(0f); |
||||||
|
|
||||||
|
} |
||||||
|
c.setBuffer(VertexBuffer.Type.BoneIndex, 4, jointIndex); |
||||||
|
c.setBuffer(VertexBuffer.Type.BoneWeight, 4, jointWeight); |
||||||
|
|
||||||
|
c.updateCounts(); |
||||||
|
c.updateBound(); |
||||||
|
|
||||||
|
VertexBuffer weightsHW = new VertexBuffer(VertexBuffer.Type.HWBoneWeight); |
||||||
|
VertexBuffer indicesHW = new VertexBuffer(VertexBuffer.Type.HWBoneIndex); |
||||||
|
|
||||||
|
indicesHW.setUsage(VertexBuffer.Usage.CpuOnly); |
||||||
|
weightsHW.setUsage(VertexBuffer.Usage.CpuOnly); |
||||||
|
c.setBuffer(weightsHW); |
||||||
|
c.setBuffer(indicesHW); |
||||||
|
c.generateBindPose(); |
||||||
|
|
||||||
|
c.prepareForAnim(false); |
||||||
|
|
||||||
|
return c; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void destroy() { |
||||||
|
super.destroy(); |
||||||
|
file.delete(); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue