Compare commits

...

3 Commits

Author SHA1 Message Date
Erimel
01274de2f5 update todo comment 2024-05-31 20:46:45 -04:00
Erimel
435834a445 fix logic 2024-05-31 20:40:10 -04:00
Erimel
b64dd256f3 wip 2024-05-30 21:48:49 -04:00
10 changed files with 103 additions and 15 deletions

View File

@@ -44,6 +44,7 @@ body_part-LEFT_HAND = Left hand
body_part-LEFT_UPPER_LEG = Left thigh
body_part-LEFT_LOWER_LEG = Left ankle
body_part-LEFT_FOOT = Left foot
body_part-PLAYSPACE = Playspace (motion compensation)
## Proportions
skeleton_bone-NONE = None

View File

@@ -86,6 +86,9 @@ export const mapPart: Record<
<UpperLegIcon width={width} flipped></UpperLegIcon>
),
[BodyPart.WAIST]: ({ width }) => <WaistIcon width={width}></WaistIcon>,
[BodyPart.PLAYSPACE]: ({ width }) => (
<SlimeVRIcon width={width}></SlimeVRIcon>
), // TODO
};
export function BodyPartIcon({

View File

@@ -307,6 +307,16 @@ export function BodyAssignment({
onClick={() => onRoleSelected(SIDES[right].foot)}
direction="left"
/>
{advanced && (
<TrackerPartCard
onlyAssigned={onlyAssigned}
roleError={rolesWithErrors[BodyPart.PLAYSPACE]?.label}
td={trackerPartGrouped[BodyPart.PLAYSPACE]}
role={BodyPart.PLAYSPACE}
onClick={() => onRoleSelected(BodyPart.PLAYSPACE)}
direction="left"
/>
)}
</div>
</div>
}

View File

@@ -99,6 +99,7 @@ export const mapPart: Record<
<FootIcon width={width} flipped></FootIcon>
),
[BodyPart.WAIST]: ({ width }) => <FootIcon width={width}></FootIcon>,
[BodyPart.PLAYSPACE]: ({ width }) => <FootIcon width={width}></FootIcon>,
};
export function MountingBodyPartIcon({

View File

@@ -185,6 +185,7 @@ export class BoneKind extends Bone {
get boneColor(): Color {
switch (this.boneT.bodyPart) {
case BodyPart.PLAYSPACE:
case BodyPart.NONE:
throw 'Unexpected body part';
case BodyPart.HEAD:
@@ -230,6 +231,7 @@ export class BoneKind extends Bone {
static children(part: BodyPart): BodyPart[] {
switch (part) {
case BodyPart.PLAYSPACE:
case BodyPart.NONE:
throw 'Unexpected body part';
case BodyPart.HEAD:
@@ -283,6 +285,7 @@ export class BoneKind extends Bone {
static parent(part: BodyPart): BodyPart | null {
switch (part) {
case BodyPart.PLAYSPACE:
case BodyPart.NONE:
throw 'Unexpected body part';
case BodyPart.HEAD:

View File

@@ -69,12 +69,19 @@ class Bone(val boneType: BoneType) {
fun getLocalRotation(): Quaternion = headNode.localTransform.rotation
/**
* Sets the global rotation of the bone
* Sets the global rotation of the bone with the rotationOffset
*/
fun setRotation(rotation: Quaternion) {
headNode.localTransform.rotation = rotation * rotationOffset
}
/**
* Sets the global rotation of the bone
*/
fun setRawRotation(rotation: Quaternion) {
headNode.localTransform.rotation = rotation
}
/**
* Returns the global position of the head of the bone
*/

View File

@@ -342,7 +342,7 @@ class HumanPoseManager(val server: VRServer?) {
*/
val trackersToReset: List<Tracker?>
get() =
server?.allTrackers ?: skeleton.localTrackers
server?.allTrackers ?: skeleton.trackersToReset
/**
* @return the head bone, which is the root of the skeleton

View File

@@ -103,6 +103,7 @@ class HumanSkeleton(
var rightHandTracker: Tracker? = null
var leftShoulderTracker: Tracker? = null
var rightShoulderTracker: Tracker? = null
var playspaceTracker: Tracker? = null
// Output trackers
var computedHeadTracker: Tracker? = null
@@ -278,6 +279,7 @@ class HumanSkeleton(
rightHandTracker = getTrackerForSkeleton(trackers, TrackerPosition.RIGHT_HAND)
leftShoulderTracker = getTrackerForSkeleton(trackers, TrackerPosition.LEFT_SHOULDER)
rightShoulderTracker = getTrackerForSkeleton(trackers, TrackerPosition.RIGHT_SHOULDER)
playspaceTracker = getTrackerForSkeleton(trackers, TrackerPosition.PLAYSPACE)
// Check for specific conditions and store them in booleans.
hasSpineTracker = upperChestTracker != null || chestTracker != null || waistTracker != null || hipTracker != null
@@ -354,18 +356,45 @@ class HumanSkeleton(
*/
@VRServerThread
fun updatePose() {
// Check taps for resets
tapDetectionManager.update()
// Do FK
updateTransforms()
// Update bones and output trackers
updateBones()
updateComputedTrackers()
// Don't run post-processing if the tracking is paused
if (pauseTracking) return
// Run Legtweaks
legTweaks.tweakLegs()
// Run Mocap mode
localizer.update()
// Run Vive hip emulation
viveEmulation.update()
// Playspace motion compensation
playspaceTracker?.let {
if (it.hasRotation) {
val motionCompensationRotOffset = it.getRotation().inv()
for (bone in allBones) {
bone.setRawRotation(motionCompensationRotOffset * bone.getLocalRotation())
}
}
if (it.hasPosition) {
// TODO motion compensate for position as well?
// headBone.setPosition(headBone.getPosition() - it.position)
}
// Update bones and output trackers
updateBones()
updateComputedTrackers()
}
}
/**
@@ -390,6 +419,7 @@ class HumanSkeleton(
// Spine
updateSpineTransforms()
// Left leg
updateLegTransforms(
leftUpperLegBone,
@@ -401,6 +431,7 @@ class HumanSkeleton(
leftLowerLegTracker,
leftFootTracker,
)
// Right leg
updateLegTransforms(
rightUpperLegBone,
@@ -412,6 +443,7 @@ class HumanSkeleton(
rightLowerLegTracker,
rightFootTracker,
)
// Left arm
updateArmTransforms(
isTrackingLeftArmFromController,
@@ -426,6 +458,7 @@ class HumanSkeleton(
leftLowerArmTracker,
leftHandTracker,
)
// Right arm
updateArmTransforms(
isTrackingRightArmFromController,
@@ -982,6 +1015,34 @@ class HumanSkeleton(
rightHandBone,
)
/**
* Returns an array of all the bones, trackers or not
*/
private val allBones: Array<Bone>
get() = arrayOf(
headBone,
neckBone,
headTrackerBone,
upperChestBone,
chestBone,
chestTrackerBone,
waistBone,
hipBone,
hipTrackerBone,
leftHipBone,
rightHipBone,
leftUpperLegBone,
leftKneeTrackerBone,
rightUpperLegBone,
rightKneeTrackerBone,
leftLowerLegBone,
rightLowerLegBone,
leftFootBone,
leftFootTrackerBone,
rightFootBone,
rightFootTrackerBone,
) + allArmBones
/**
* Returns all the arm bones, tracker or not.
*/
@@ -1023,7 +1084,7 @@ class HumanSkeleton(
*/
val isTrackingRightArmFromController: Boolean
get() = rightHandTracker != null && rightHandTracker!!.hasPosition && !forceArmsFromHMD
val localTrackers: List<Tracker?>
val trackersToReset: List<Tracker?>
get() = listOf(
neckTracker,
chestTracker,
@@ -1046,10 +1107,8 @@ class HumanSkeleton(
)
fun resetTrackersFull(resetSourceName: String?) {
val trackersToReset = humanPoseManager.trackersToReset
// Resets all axis of the trackers with the HMD as reference.
var referenceRotation = IDENTITY
// Reset the head tracker from identity if needed, else store its rotation
headTracker?.let {
if (it.needsReset) {
it.resetsHandler.resetFull(referenceRotation)
@@ -1057,11 +1116,14 @@ class HumanSkeleton(
referenceRotation = it.getRotation()
}
}
// Resets the trackers with the HMD as reference.
for (tracker in trackersToReset) {
if (tracker != null && tracker.needsReset) {
tracker.resetsHandler.resetFull(referenceRotation)
}
}
// Reset the playspace tracker from identity rotation
playspaceTracker?.resetsHandler?.resetFull(IDENTITY)
// Tell floorclip to reset its floor level on the next update
// of the computed trackers
@@ -1075,10 +1137,8 @@ class HumanSkeleton(
@VRServerThread
fun resetTrackersYaw(resetSourceName: String?) {
val trackersToReset = humanPoseManager.trackersToReset
// Resets the yaw of the trackers with the head as reference.
var referenceRotation = IDENTITY
// Reset the head tracker from identity if needed, else store its rotation
headTracker?.let {
if (it.needsReset) {
it.resetsHandler.resetYaw(referenceRotation)
@@ -1086,22 +1146,23 @@ class HumanSkeleton(
referenceRotation = it.getRotation()
}
}
// Resets the trackers with the HMD as reference.
for (tracker in trackersToReset) {
if (tracker != null && tracker.needsReset) {
tracker.resetsHandler.resetYaw(referenceRotation)
}
}
// Reset the playspace tracker from identity rotation
playspaceTracker?.resetsHandler?.resetYaw(IDENTITY)
legTweaks.resetBuffer()
LogManager.info(String.format("[HumanSkeleton] Reset: yaw (%s)", resetSourceName))
}
@VRServerThread
fun resetTrackersMounting(resetSourceName: String?) {
val trackersToReset = humanPoseManager.trackersToReset
// Resets the mounting orientation of the trackers with the HMD as
// reference.
var referenceRotation = IDENTITY
// Reset the head tracker from identity if needed, else store its rotation
headTracker?.let {
if (it.needsMounting) {
it.resetsHandler.resetMounting(referenceRotation)
@@ -1109,11 +1170,13 @@ class HumanSkeleton(
referenceRotation = it.getRotation()
}
}
// Resets the trackers with the HMD as reference.
for (tracker in trackersToReset) {
if (tracker != null && tracker.needsMounting) {
tracker.resetsHandler.resetMounting(referenceRotation)
}
}
legTweaks.resetBuffer()
localizer.reset()
LogManager.info(String.format("[HumanSkeleton] Reset: mounting (%s)", resetSourceName))
@@ -1121,7 +1184,6 @@ class HumanSkeleton(
@VRServerThread
fun clearTrackersMounting(resetSourceName: String?) {
val trackersToReset = humanPoseManager.trackersToReset
headTracker?.let {
if (it.needsMounting) it.resetsHandler.clearMounting()
}

View File

@@ -36,6 +36,7 @@ enum class TrackerPosition(
RIGHT_HAND("body:right_hand", TrackerRole.RIGHT_HAND, BodyPart.RIGHT_HAND),
LEFT_SHOULDER("body:left_shoulder", TrackerRole.LEFT_SHOULDER, BodyPart.LEFT_SHOULDER),
RIGHT_SHOULDER("body:right_shoulder", TrackerRole.RIGHT_SHOULDER, BodyPart.RIGHT_SHOULDER),
PLAYSPACE("body:playspace", null, BodyPart.PLAYSPACE),
;
/**