|
@@ -1,128 +0,0 @@
|
|
|
-package com.jme3.scene.plugins.blender.animations;
|
|
|
-
|
|
|
-import com.jme3.animation.Bone;
|
|
|
-import com.jme3.animation.BoneTrack;
|
|
|
-import com.jme3.math.Quaternion;
|
|
|
-import com.jme3.math.Vector3f;
|
|
|
-import com.jme3.scene.Node;
|
|
|
-import com.jme3.scene.Spatial;
|
|
|
-import java.util.Arrays;
|
|
|
-
|
|
|
-/**
|
|
|
- * The purpose of this class is to imitate bone's movement when calculating inverse kinematics.
|
|
|
- * @author Marcin Roguski (Kaelthas)
|
|
|
- */
|
|
|
-public class CalculationBone extends Node {
|
|
|
- private Bone bone;
|
|
|
- /** The bone's tracks. Will be altered at the end of calculation process. */
|
|
|
- private BoneTrack track;
|
|
|
- /** The starting position of the bone. */
|
|
|
- private Vector3f startTranslation;
|
|
|
- /** The starting rotation of the bone. */
|
|
|
- private Quaternion startRotation;
|
|
|
- /** The starting scale of the bone. */
|
|
|
- private Vector3f startScale;
|
|
|
- private Vector3f[] translations;
|
|
|
- private Quaternion[] rotations;
|
|
|
- private Vector3f[] scales;
|
|
|
-
|
|
|
- public CalculationBone(Bone bone, int boneFramesCount) {
|
|
|
- this.bone = bone;
|
|
|
- this.startRotation = bone.getModelSpaceRotation().clone();
|
|
|
- this.startTranslation = bone.getModelSpacePosition().clone();
|
|
|
- this.startScale = bone.getModelSpaceScale().clone();
|
|
|
- this.reset();
|
|
|
- if (boneFramesCount > 0) {
|
|
|
- this.translations = new Vector3f[boneFramesCount];
|
|
|
- this.rotations = new Quaternion[boneFramesCount];
|
|
|
- this.scales = new Vector3f[boneFramesCount];
|
|
|
-
|
|
|
- Arrays.fill(this.translations, 0, boneFramesCount, this.startTranslation);
|
|
|
- Arrays.fill(this.rotations, 0, boneFramesCount, this.startRotation);
|
|
|
- Arrays.fill(this.scales, 0, boneFramesCount, this.startScale);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Constructor. Stores the track, starting transformation and sets the transformation to the starting positions.
|
|
|
- * @param bone
|
|
|
- * the bone this class will imitate
|
|
|
- * @param track
|
|
|
- * the bone's tracks
|
|
|
- */
|
|
|
- public CalculationBone(Bone bone, BoneTrack track) {
|
|
|
- this(bone, 0);
|
|
|
- this.track = track;
|
|
|
- this.translations = track.getTranslations();
|
|
|
- this.rotations = track.getRotations();
|
|
|
- this.scales = track.getScales();
|
|
|
- }
|
|
|
-
|
|
|
- public int getBoneFramesCount() {
|
|
|
- return this.translations == null ? 0 : this.translations.length;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * This method returns the end point of the bone. If the bone has parent it is calculated from the start point
|
|
|
- * of parent to the start point of this bone. If the bone doesn't have a parent the end location is considered
|
|
|
- * to be 1 point up along Y axis (scale is applied if set to != 1.0);
|
|
|
- * @return the end point of this bone
|
|
|
- */
|
|
|
- // TODO: set to Z axis if user defined it this way
|
|
|
- public Vector3f getEndPoint() {
|
|
|
- if (this.getParent() == null) {
|
|
|
- return new Vector3f(0, this.getLocalScale().y, 0);
|
|
|
- } else {
|
|
|
- Node parent = this.getParent();
|
|
|
- return parent.getWorldTranslation().subtract(this.getWorldTranslation()).multLocal(this.getWorldScale());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * This method resets the calculation bone to the starting position.
|
|
|
- */
|
|
|
- public void reset() {
|
|
|
- this.setLocalTranslation(startTranslation);
|
|
|
- this.setLocalRotation(startRotation);
|
|
|
- this.setLocalScale(startScale);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public int attachChild(Spatial child) {
|
|
|
- if (this.getChildren() != null && this.getChildren().size() > 1) {
|
|
|
- throw new IllegalStateException(this.getClass().getName() + " class instance can only have one child!");
|
|
|
- }
|
|
|
- return super.attachChild(child);
|
|
|
- }
|
|
|
-
|
|
|
- public Spatial rotate(Quaternion rot, int frame) {
|
|
|
- Spatial spatial = super.rotate(rot);
|
|
|
- this.updateWorldTransforms();
|
|
|
- if (this.getChildren() != null && this.getChildren().size() > 0) {
|
|
|
- CalculationBone child = (CalculationBone) this.getChild(0);
|
|
|
- child.updateWorldTransforms();
|
|
|
- }
|
|
|
- rotations[frame].set(this.getLocalRotation());
|
|
|
- translations[frame].set(this.getLocalTranslation());
|
|
|
- if (scales != null) {
|
|
|
- scales[frame].set(this.getLocalScale());
|
|
|
- }
|
|
|
- return spatial;
|
|
|
- }
|
|
|
-
|
|
|
- public void applyCalculatedTracks() {
|
|
|
- if (track != null) {
|
|
|
- track.setKeyframes(track.getTimes(), translations, rotations, scales);
|
|
|
- } else {
|
|
|
- bone.setUserControl(true);
|
|
|
- bone.setUserTransforms(translations[0], rotations[0], scales[0]);
|
|
|
- bone.setUserControl(false);
|
|
|
- bone.updateWorldVectors();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public String toString() {
|
|
|
- return bone.getName() + ": " + this.getLocalRotation() + " " + this.getLocalTranslation();
|
|
|
- }
|
|
|
-}
|