diff --git a/src/main/java/io/eiren/vr/processor/ComputedHumanPoseTrackerPosition.java b/src/main/java/io/eiren/vr/processor/ComputedHumanPoseTrackerPosition.java index a7c887620..dbb3ff74e 100644 --- a/src/main/java/io/eiren/vr/processor/ComputedHumanPoseTrackerPosition.java +++ b/src/main/java/io/eiren/vr/processor/ComputedHumanPoseTrackerPosition.java @@ -3,6 +3,6 @@ package io.eiren.vr.processor; public enum ComputedHumanPoseTrackerPosition { WAIST, - LEFT_FOOT, - RIGHT_FOOT; + LEFT_ANKLE, + RIGHT_ANKLE; } diff --git a/src/main/java/io/eiren/vr/processor/HumanPoseProcessor.java b/src/main/java/io/eiren/vr/processor/HumanPoseProcessor.java index c214899bb..74177a361 100644 --- a/src/main/java/io/eiren/vr/processor/HumanPoseProcessor.java +++ b/src/main/java/io/eiren/vr/processor/HumanPoseProcessor.java @@ -1,8 +1,10 @@ package io.eiren.vr.processor; import java.util.EnumMap; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import com.jme3.math.Quaternion; import com.jme3.math.Vector3f; @@ -19,15 +21,15 @@ public class HumanPoseProcessor { private final VRServer server; private final HMDTracker hmd; private final List computedTrackers = new FastList<>(); - private final EnumMap trackers = new EnumMap<>(TrackerBodyPosition.class); + private final Map trackers = new EnumMap<>(TrackerBodyPosition.class); private HumanSkeleton skeleton; public HumanPoseProcessor(VRServer server, HMDTracker hmd) { this.server = server; this.hmd = hmd; computedTrackers.add(new ComputedHumanPoseTracker(ComputedHumanPoseTrackerPosition.WAIST)); - //computedTrackers.add(new ComputedHumanPoseTracker(ComputedHumanPoseTrackerPosition.LEFT_FOOT)); - //computedTrackers.add(new ComputedHumanPoseTracker(ComputedHumanPoseTrackerPosition.RIGHT_FOOT)); + computedTrackers.add(new ComputedHumanPoseTracker(ComputedHumanPoseTrackerPosition.LEFT_ANKLE)); + computedTrackers.add(new ComputedHumanPoseTracker(ComputedHumanPoseTrackerPosition.RIGHT_ANKLE)); } public List getComputedTrackers() { @@ -58,19 +60,23 @@ public class HumanPoseProcessor { private void updateSekeltonModel() { boolean hasWaist = false; - //boolean hasBothLegs = false; + boolean hasBothLegs = false; //boolean hasChest = false; if(trackers.get(TrackerBodyPosition.WAIST) != null) hasWaist = true; //if(trackers.get(TrackerBodyPosition.CHEST) != null) // hasChest = true; - //if(trackers.get(TrackerBodyPosition.LEFT_FOOT) != null && trackers.get(TrackerBodyPosition.LEFT_LEG) != null - // && trackers.get(TrackerBodyPosition.RIGHT_FOOT) != null && trackers.get(TrackerBodyPosition.RIGHT_LEG) != null) - // hasBothLegs = true; + if(trackers.get(TrackerBodyPosition.LEFT_ANKLE) != null && trackers.get(TrackerBodyPosition.LEFT_LEG) != null + && trackers.get(TrackerBodyPosition.RIGHT_ANKLE) != null && trackers.get(TrackerBodyPosition.RIGHT_LEG) != null) + hasBothLegs = true; if(!hasWaist) { skeleton = null; // Can't track anything without waist + } else if(hasBothLegs) { + if(skeleton instanceof HumanSekeletonWithLegs) { + return; // Proper skeleton applied + } + skeleton = new HumanSekeletonWithLegs(server, trackers, computedTrackers); } else { - // TODO : Add legs and chest support if(skeleton instanceof HumanSkeleonWithWaist) { return; // Proper skeleton applied } diff --git a/src/main/java/io/eiren/vr/processor/HumanSekeletonWithLegs.java b/src/main/java/io/eiren/vr/processor/HumanSekeletonWithLegs.java new file mode 100644 index 000000000..f4c72c856 --- /dev/null +++ b/src/main/java/io/eiren/vr/processor/HumanSekeletonWithLegs.java @@ -0,0 +1,92 @@ +package io.eiren.vr.processor; + +import java.util.List; +import java.util.Map; + +import io.eiren.vr.VRServer; +import io.eiren.vr.trackers.Tracker; + +public class HumanSekeletonWithLegs extends HumanSkeleonWithWaist { + + protected final Tracker leftLegTracker; + protected final Tracker leftAnkleTracker; + protected final ComputedHumanPoseTracker computedLeftAnkleTracker; + protected final Tracker rightLegTracker; + protected final Tracker rightAnkleTracker; + protected final ComputedHumanPoseTracker computedRightAnkleTracker; + + protected final TransformNode leftLegNode = new TransformNode(); + protected final TransformNode leftKneeNode = new TransformNode(); + protected final TransformNode leftAnkleNode = new TransformNode(); + protected final TransformNode rightLegNode = new TransformNode(); + protected final TransformNode rightKneeNode = new TransformNode(); + protected final TransformNode rightAnkleNode = new TransformNode(); + + protected float hipsWidth = 0.3f; + protected float kneeLength = 0.5f; + protected float ankleLength = 0.4f; + + public HumanSekeletonWithLegs(VRServer server, Map trackers, List computedTrackers) { + super(server, trackers.get(TrackerBodyPosition.WAIST), computedTrackers); + this.leftLegTracker = trackers.get(TrackerBodyPosition.LEFT_LEG); + this.leftAnkleTracker = trackers.get(TrackerBodyPosition.LEFT_ANKLE); + this.rightLegTracker = trackers.get(TrackerBodyPosition.RIGHT_LEG); + this.rightAnkleTracker = trackers.get(TrackerBodyPosition.RIGHT_ANKLE); + ComputedHumanPoseTracker lat = null; + ComputedHumanPoseTracker rat = null; + for(int i = 0; i < computedTrackers.size(); ++i) { + ComputedHumanPoseTracker t = computedTrackers.get(i); + if(t.skeletonPosition == ComputedHumanPoseTrackerPosition.LEFT_ANKLE) + lat = t; + if(t.skeletonPosition == ComputedHumanPoseTrackerPosition.RIGHT_ANKLE) + rat = t; + } + computedLeftAnkleTracker = lat; + computedRightAnkleTracker = rat; + + waistNode.attachChild(leftLegNode); + leftLegNode.localTransform.setTranslation(-hipsWidth / 2, 0, 0); + + waistNode.attachChild(rightLegNode); + rightLegNode.localTransform.setTranslation(hipsWidth / 2, 0, 0); + + leftLegNode.attachChild(leftKneeNode); + leftKneeNode.localTransform.setTranslation(0, -kneeLength, 0); + + rightLegNode.attachChild(rightKneeNode); + rightKneeNode.localTransform.setTranslation(0, -kneeLength, 0); + + leftKneeNode.attachChild(leftAnkleNode); + leftAnkleNode.localTransform.setTranslation(0, -ankleLength, 0); + + rightKneeNode.attachChild(rightAnkleNode); + rightAnkleNode.localTransform.setTranslation(0, -ankleLength, 0); + } + + @Override + public void updateLocalTransforms() { + super.updateLocalTransforms(); + leftLegTracker.getRotation(qBuf); + leftLegNode.localTransform.setRotation(qBuf); + + rightLegTracker.getRotation(qBuf); + rightLegNode.localTransform.setRotation(qBuf); + + leftAnkleTracker.getRotation(qBuf); + leftKneeNode.localTransform.setRotation(qBuf); + + rightAnkleTracker.getRotation(qBuf); + rightKneeNode.localTransform.setRotation(qBuf); + } + + @Override + protected void updateComputedTrackers() { + super.updateComputedTrackers(); + + computedLeftAnkleTracker.position.set(leftAnkleNode.worldTransform.getTranslation()); + computedLeftAnkleTracker.rotation.set(leftAnkleNode.worldTransform.getRotation()); + + computedRightAnkleTracker.position.set(rightAnkleNode.worldTransform.getTranslation()); + computedRightAnkleTracker.rotation.set(rightAnkleNode.worldTransform.getRotation()); + } +} diff --git a/src/main/java/io/eiren/vr/processor/HumanSkeleonWithWaist.java b/src/main/java/io/eiren/vr/processor/HumanSkeleonWithWaist.java index d82111a7a..5d9d6bc7b 100644 --- a/src/main/java/io/eiren/vr/processor/HumanSkeleonWithWaist.java +++ b/src/main/java/io/eiren/vr/processor/HumanSkeleonWithWaist.java @@ -41,6 +41,12 @@ public class HumanSkeleonWithWaist extends HumanSkeleton { @Override public void updatePose() { + updateLocalTransforms(); + hmdNode.update(); + updateComputedTrackers(); + } + + protected void updateLocalTransforms() { wasitTracker.getRotation(qBuf); if(waistSwingMultiplier != 1.0) { // TODO : Adjust waist swing if swing multiplier != 0 @@ -49,13 +55,9 @@ public class HumanSkeleonWithWaist extends HumanSkeleton { hmdTracker.getPosition(vBuf); hmdNode.localTransform.setTranslation(vBuf); hmdNode.localTransform.setRotation(qBuf); - - hmdNode.update(); - - updateTrackers(); } - protected void updateTrackers() { + protected void updateComputedTrackers() { computedWaistTracker.position.set(waistNode.worldTransform.getTranslation()); computedWaistTracker.rotation.set(waistNode.worldTransform.getRotation()); } diff --git a/src/main/java/io/eiren/vr/processor/TrackerBodyPosition.java b/src/main/java/io/eiren/vr/processor/TrackerBodyPosition.java index bb0684975..9a8a22134 100644 --- a/src/main/java/io/eiren/vr/processor/TrackerBodyPosition.java +++ b/src/main/java/io/eiren/vr/processor/TrackerBodyPosition.java @@ -11,8 +11,8 @@ public enum TrackerBodyPosition { WAIST(Quaternion.IDENTITY, "body:waist"), LEFT_LEG(Quaternion.IDENTITY, "body:left_leg"), RIGHT_LEG(Quaternion.IDENTITY, "body:right_leg"), - LEFT_FOOT(Quaternion.IDENTITY, "body:left_foot"), - RIGHT_FOOT(Quaternion.IDENTITY, "body:right_foot"), + LEFT_ANKLE(Quaternion.IDENTITY, "body:left_ankle"), + RIGHT_ANKLE(Quaternion.IDENTITY, "body:right_ankle"), ; public final Quaternion baseRotation;