mirror of
https://github.com/SlimeVR/SlimeVR-Server.git
synced 2026-04-06 02:01:58 +02:00
AutoBone: Add AutoBone, PoseFrame, and finish implementing SimpleSkeleton
This commit is contained in:
13
src/main/java/io/eiren/gui/autobone/AutoBone.java
Normal file
13
src/main/java/io/eiren/gui/autobone/AutoBone.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
33
src/main/java/io/eiren/gui/autobone/PoseFrame.java
Normal file
33
src/main/java/io/eiren/gui/autobone/PoseFrame.java
Normal 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()));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user