AutoBone: Add AutoBone, PoseFrame, and finish implementing SimpleSkeleton

This commit is contained in:
ButterscotchVanilla
2021-08-10 17:33:12 -04:00
parent 8b209eaf27
commit 19a1101b43
3 changed files with 87 additions and 4 deletions

View File

@@ -0,0 +1,13 @@
package io.eiren.gui.autobone;
import io.eiren.vr.VRServer;
public class AutoBone {
protected final VRServer server;
public AutoBone(VRServer server) {
this.server = server;
}
}

View File

@@ -0,0 +1,33 @@
package io.eiren.gui.autobone;
import java.util.HashMap;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import io.eiren.vr.processor.HumanSkeletonWithLegs;
import io.eiren.vr.processor.TransformNode;
public final class PoseFrame {
public final Vector3f rootPos;
public final HashMap<String, Quaternion> rotations;
public PoseFrame(Vector3f rootPos, HashMap<String, Quaternion> rotations) {
this.rootPos = rootPos;
this.rotations = rotations;
}
public PoseFrame(HumanSkeletonWithLegs skeleton) {
// Copy headset position
TransformNode rootNode = skeleton.getRootNode();
this.rootPos = new Vector3f(rootNode.localTransform.getTranslation());
// Copy all rotations
this.rotations = new HashMap<String, Quaternion>();
rootNode.depthFirstTraversal(visitor -> {
// Insert a copied quaternion so it isn't changed by reference
rotations.put(visitor.getName(), new Quaternion(visitor.localTransform.getRotation()));
});
}
}

View File

@@ -1,6 +1,10 @@
package io.eiren.gui.autobone;
import java.util.HashMap;
import java.util.Map.Entry;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import io.eiren.vr.VRServer;
import io.eiren.vr.processor.HumanSkeletonWithLegs;
@@ -24,7 +28,7 @@ public class SimpleSkeleton {
*/
protected float waistDistance = 0.85f;
/**
* Distacne from eyes to the base of the neck
* Distance from eyes to the base of the neck
*/
protected float neckLength = HumanSkeletonWithWaist.NECK_LENGTH_DEFAULT;
/**
@@ -56,7 +60,7 @@ public class SimpleSkeleton {
protected float legsLength = 0.84f;
protected float footLength = HumanSkeletonWithLegs.FOOT_LENGTH_DEFAULT;
HashMap<String, TransformNode> nodes = new HashMap<String,TransformNode>();
protected final HashMap<String, TransformNode> nodes = new HashMap<String,TransformNode>();
public SimpleSkeleton(VRServer server) {
this.server = server;
@@ -117,8 +121,14 @@ public class SimpleSkeleton {
});
}
public void poseFromSkeleton(HumanSkeletonWithLegs humanSkeleton) {
humanSkeleton.getRootNode().depthFirstTraversal(visitor -> {
public void setPoseFromSkeleton(HumanSkeletonWithLegs humanSkeleton) {
TransformNode rootNode = humanSkeleton.getRootNode();
// Copy headset position
hmdNode.localTransform.setTranslation(rootNode.localTransform.getTranslation());
// Copy all rotations
rootNode.depthFirstTraversal(visitor -> {
TransformNode targetNode = nodes.get(visitor.getName());
// Handle unexpected nodes gracefully
@@ -128,6 +138,21 @@ public class SimpleSkeleton {
});
}
public void setPoseFromFrame(PoseFrame frame) {
// Copy headset position
hmdNode.localTransform.setTranslation(frame.rootPos);
// Copy all rotations
for (Entry<String, Quaternion> rotation : frame.rotations.entrySet()) {
TransformNode targetNode = nodes.get(rotation.getKey());
// Handle unexpected nodes gracefully
if (targetNode != null) {
targetNode.localTransform.setRotation(rotation.getValue());
}
}
}
public void setSkeletonConfig(String joint, float newLength) {
switch(joint) {
case "Head":
@@ -172,6 +197,18 @@ public class SimpleSkeleton {
}
}
public void updatePose() {
hmdNode.update();
}
public Vector3f getLeftFootPos() {
return leftAnkleNode.worldTransform.getTranslation();
}
public Vector3f getRightFootPos() {
return rightAnkleNode.worldTransform.getTranslation();
}
public void saveConfigs() {
// Save waist configs
server.config.setProperty("body.headShift", headShift);