use of com.jme3.animation.AnimChannel in project jmonkeyengine by jMonkeyEngine.
the class SimulationNode method simulateSkeleton.
/**
* Simulates the bone node.
*/
private void simulateSkeleton() {
LOGGER.fine("Simulating skeleton.");
Set<Long> alteredOmas = new HashSet<Long>();
if (animations != null) {
TempVars vars = TempVars.get();
AnimChannel animChannel = animControl.createChannel();
for (Animation animation : animations) {
float[] animationTimeBoundaries = this.computeAnimationTimeBoundaries(animation);
int maxFrame = (int) animationTimeBoundaries[0];
float maxTime = animationTimeBoundaries[1];
Map<Integer, VirtualTrack> tracks = new HashMap<Integer, VirtualTrack>();
for (int frame = 0; frame < maxFrame; ++frame) {
// this MUST be done here, otherwise setting next frame of animation will
// lead to possible errors
this.reset();
// first set proper time for all bones in all the tracks ...
for (Track track : animation.getTracks()) {
float time = ((BoneTrack) track).getTimes()[frame];
track.setTime(time, 1, animControl, animChannel, vars);
skeleton.updateWorldVectors();
}
// ... and then apply constraints from the root bone to the last child ...
Set<Long> applied = new HashSet<Long>();
for (Bone rootBone : skeleton.getRoots()) {
// ignore the 0-indexed bone
if (skeleton.getBoneIndex(rootBone) > 0) {
this.applyConstraints(rootBone, alteredOmas, applied, frame, new Stack<Bone>());
}
}
// ... add virtual tracks if neccessary, for bones that were altered but had no tracks before ...
for (Long boneOMA : alteredOmas) {
BoneContext boneContext = blenderContext.getBoneContext(boneOMA);
int boneIndex = skeleton.getBoneIndex(boneContext.getBone());
if (!tracks.containsKey(boneIndex)) {
tracks.put(boneIndex, new VirtualTrack(boneContext.getBone().getName(), maxFrame, maxTime));
}
}
alteredOmas.clear();
// ... and fill in another frame in the result track
for (Entry<Integer, VirtualTrack> trackEntry : tracks.entrySet()) {
Bone bone = skeleton.getBone(trackEntry.getKey());
Transform startTransform = boneStartTransforms.get(bone);
// track contains differences between the frame position and bind positions of bones/spatials
Vector3f bonePositionDifference = bone.getLocalPosition().subtract(startTransform.getTranslation());
Quaternion boneRotationDifference = startTransform.getRotation().inverse().mult(bone.getLocalRotation()).normalizeLocal();
Vector3f boneScaleDifference = bone.getLocalScale().divide(startTransform.getScale());
trackEntry.getValue().setTransform(frame, new Transform(bonePositionDifference, boneRotationDifference, boneScaleDifference));
}
}
for (Entry<Integer, VirtualTrack> trackEntry : tracks.entrySet()) {
Track newTrack = trackEntry.getValue().getAsBoneTrack(trackEntry.getKey());
if (newTrack != null) {
boolean trackReplaced = false;
for (Track track : animation.getTracks()) {
if (((BoneTrack) track).getTargetBoneIndex() == trackEntry.getKey().intValue()) {
animation.removeTrack(track);
animation.addTrack(newTrack);
trackReplaced = true;
break;
}
}
if (!trackReplaced) {
animation.addTrack(newTrack);
}
}
}
}
vars.release();
animControl.clearChannels();
this.reset();
}
}
use of com.jme3.animation.AnimChannel in project jmonkeyengine by jMonkeyEngine.
the class SpatialTrack method setTime.
/**
*
* Modify the spatial which this track modifies.
*
* @param time
* the current time of the animation
*/
public void setTime(float time, float weight, AnimControl control, AnimChannel channel, TempVars vars) {
Spatial spatial = control.getSpatial();
Vector3f tempV = vars.vect1;
Vector3f tempS = vars.vect2;
Quaternion tempQ = vars.quat1;
Vector3f tempV2 = vars.vect3;
Vector3f tempS2 = vars.vect4;
Quaternion tempQ2 = vars.quat2;
int lastFrame = times.length - 1;
if (time < 0 || lastFrame == 0) {
if (rotations != null)
rotations.get(0, tempQ);
if (translations != null)
translations.get(0, tempV);
if (scales != null) {
scales.get(0, tempS);
}
} else if (time >= times[lastFrame]) {
if (rotations != null)
rotations.get(lastFrame, tempQ);
if (translations != null)
translations.get(lastFrame, tempV);
if (scales != null) {
scales.get(lastFrame, tempS);
}
} else {
int startFrame = 0;
int endFrame = 1;
// use lastFrame so we never overflow the array
for (int i = 0; i < lastFrame && times[i] < time; ++i) {
startFrame = i;
endFrame = i + 1;
}
float blend = (time - times[startFrame]) / (times[endFrame] - times[startFrame]);
if (rotations != null)
rotations.get(startFrame, tempQ);
if (translations != null)
translations.get(startFrame, tempV);
if (scales != null) {
scales.get(startFrame, tempS);
}
if (rotations != null)
rotations.get(endFrame, tempQ2);
if (translations != null)
translations.get(endFrame, tempV2);
if (scales != null) {
scales.get(endFrame, tempS2);
}
tempQ.nlerp(tempQ2, blend);
tempV.interpolateLocal(tempV2, blend);
tempS.interpolateLocal(tempS2, blend);
}
if (translations != null)
spatial.setLocalTranslation(tempV);
if (rotations != null)
spatial.setLocalRotation(tempQ);
if (scales != null) {
spatial.setLocalScale(tempS);
}
}
use of com.jme3.animation.AnimChannel in project jmonkeyengine by jMonkeyEngine.
the class TestModelExportingCloning method simpleInitApp.
@Override
public void simpleInitApp() {
cam.setLocation(new Vector3f(10f, 3f, 40f));
cam.lookAtDirection(Vector3f.UNIT_Z.negate(), Vector3f.UNIT_Y);
DirectionalLight dl = new DirectionalLight();
dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal());
dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f));
rootNode.addLight(dl);
AnimControl control;
AnimChannel channel;
Spatial originalModel = assetManager.loadModel("Models/Oto/Oto.mesh.xml");
control = originalModel.getControl(AnimControl.class);
channel = control.createChannel();
channel.setAnim("Walk");
rootNode.attachChild(originalModel);
Spatial clonedModel = originalModel.clone();
clonedModel.move(10, 0, 0);
control = clonedModel.getControl(AnimControl.class);
channel = control.createChannel();
channel.setAnim("push");
rootNode.attachChild(clonedModel);
Spatial exportedModel = BinaryExporter.saveAndLoad(assetManager, originalModel);
exportedModel.move(20, 0, 0);
control = exportedModel.getControl(AnimControl.class);
channel = control.createChannel();
channel.setAnim("pull");
rootNode.attachChild(exportedModel);
}
Aggregations