Now supports sensorConfig with hips and chest sensors

This commit is contained in:
Anthony J. Thibault 2017-04-10 13:36:30 -07:00
parent adaf7dda7c
commit 0ebaba7cf8
4 changed files with 100 additions and 38 deletions

View file

@ -81,10 +81,10 @@
"typeVar": "leftFootType"
},
{
"jointName": "Neck",
"positionVar": "neckPosition",
"rotationVar": "neckRotation",
"typeVar": "neckType"
"jointName": "Spine2",
"positionVar": "spine2Position",
"rotationVar": "spine2Rotation",
"typeVar": "spine2Type"
},
{
"jointName": "Head",

View file

@ -1033,6 +1033,9 @@ void Rig::updateFromHeadParameters(const HeadParameters& params, float dt) {
} else {
_animVars.set("hipsType", (int)IKTarget::Type::Unknown);
}
// by default this IK target is disabled.
_animVars.set("spine2Type", (int)IKTarget::Type::Unknown);
}
void Rig::updateFromEyeParameters(const EyeParameters& params) {

View file

@ -27,18 +27,59 @@ Controller.enableMapping(MAPPING_NAME);
var leftFoot;
var rightFoot;
var hips;
var spine2;
var FEET_ONLY = 0;
var FEET_AND_HIPS = 1;
var FEET_AND_CHEST = 2;
var FEET_HIPS_AND_CHEST = 3;
var SENSOR_CONFIG_NAMES = [
"FeetOnly",
"FeetAndHips",
"FeetAndChest",
"FeetHipsAndChest"
];
var ANIM_VARS = [
"leftFootType",
"leftFootPosition",
"leftFootRotation",
"rightFootType",
"rightFootPosition",
"rightFootRotation",
"hipsType",
"hipsPosition",
"hipsRotation",
"spine2Type",
"spine2Position",
"spine2Rotation"
];
var sensorConfig = FEET_HIPS_AND_CHEST;
var Y_180 = {x: 0, y: 1, z: 0, w: 0};
var Y_180_XFORM = new Xform(Y_180, {x: 0, y: 0, z: 0});
function computeOffsetXform(pose, jointIndex) {
var poseXform = new Xform(pose.rotation, pose.translation);
// TODO: we can do better here...
// one idea, hang default pose skeleton from HMD head.
var referenceXform = new Xform(MyAvatar.getAbsoluteDefaultJointRotationInObjectFrame(jointIndex),
MyAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(jointIndex));
return Xform.mul(poseXform.inv(), referenceXform);
}
function calibrate() {
print("AJT: calibrating");
print("AJT: calibrating...");
leftFoot = undefined;
rightFoot = undefined;
hips = undefined;
spine2 = undefined;
var poses = [];
if (Controller.Hardware.Vive) {
TRACKED_OBJECT_POSES.forEach(function (key) {
@ -76,12 +117,30 @@ function calibrate() {
print("AJT: rightFoot = " + JSON.stringify(rightFoot));
print("AJT: leftFoot = " + JSON.stringify(leftFoot));
if (poses.length >= 3) {
if (sensorConfig === FEET_ONLY) {
// we're done!
} else if (sensorConfig === FEET_AND_HIPS && poses.length >= 3) {
hips = poses[2];
hips.offsetXform = computeOffsetXform(hips.pose, MyAvatar.getJointIndex("Hips"));
} else if (sensorConfig === FEET_AND_CHEST && poses.length >= 3) {
spine2 = poses[2];
} else if (sensorConfig === FEET_HIPS_AND_CHEST && poses.length >= 4) {
hips = poses[2];
spine2 = poses[3];
} else {
// TODO: better error messages
print("AJT: could not calibrate for sensor config " + SENSOR_CONFIG_NAMES[sensorConfig] + ", please try again!");
}
if (hips) {
hips.offsetXform = computeOffsetXform(hips.pose, MyAvatar.getJointIndex("Hips"));
print("AJT: hips = " + JSON.stringify(hips));
}
if (spine2) {
spine2.offsetXform = computeOffsetXform(spine2.pose, MyAvatar.getJointIndex("Spine2"));
print("AJT: spine2 = " + JSON.stringify(spine2));
}
} else {
print("AJT: could not find two trackers, try again!");
}
@ -97,6 +156,12 @@ var ikTypes = {
var handlerId;
function computeIKTargetXform(jointInfo) {
var pose = Controller.getPoseValue(jointInfo.channel);
var offsetXform = jointInfo.offsetXform;
return Xform.mul(Y_180_XFORM, Xform.mul(new Xform(pose.rotation, pose.translation), offsetXform));
}
function update(dt) {
if (rightTriggerPressed && leftTriggerPressed) {
if (!calibrated) {
@ -107,59 +172,53 @@ function update(dt) {
MyAvatar.removeAnimationStateHandler(handlerId);
}
// hook up anim state callback
var propList = [
"leftFootType", "leftFootPosition", "leftFootRotation",
"rightFootType", "rightFootPosition", "rightFootRotation",
"hipsType", "hipsPosition", "hipsRotation"
];
handlerId = MyAvatar.addAnimationStateHandler(function (props) {
var result = {}, pose, offsetXform, xform;
var result = {}, xform;
if (rightFoot) {
pose = Controller.getPoseValue(rightFoot.channel);
offsetXform = rightFoot.offsetXform;
xform = Xform.mul(new Xform(pose.rotation, pose.translation), offsetXform);
xform = computeIKTargetXform(rightFoot);
result.rightFootType = ikTypes.RotationAndPosition;
result.rightFootPosition = Vec3.multiplyQbyV(Y_180, xform.pos);
result.rightFootRotation = Quat.multiply(Y_180, xform.rot);
result.rightFootPosition = xform.pos;
result.rightFootRotation = xform.rot;
} else {
result.rightFootType = props.rightFootType;
result.rightFootPositon = props.rightFootPosition;
result.rightFootPosition = props.rightFootPosition;
result.rightFootRotation = props.rightFootRotation;
}
if (leftFoot) {
pose = Controller.getPoseValue(leftFoot.channel);
offsetXform = leftFoot.offsetXform;
xform = Xform.mul(new Xform(pose.rotation, pose.translation), offsetXform);
xform = computeIKTargetXform(leftFoot);
result.leftFootType = ikTypes.RotationAndPosition;
result.leftFootPosition = Vec3.multiplyQbyV(Y_180, xform.pos);
result.leftFootRotation = Quat.multiply(Y_180, xform.rot);
result.leftFootPosition = xform.pos;
result.leftFootRotation = xform.rot;
} else {
result.leftFootType = props.leftFootType;
result.leftFootPositon = props.leftFootPosition;
result.leftFootPosition = props.leftFootPosition;
result.leftFootRotation = props.leftFootRotation;
}
if (hips) {
pose = Controller.getPoseValue(hips.channel);
offsetXform = hips.offsetXform;
xform = Xform.mul(new Xform(pose.rotation, pose.translation), offsetXform);
xform = computeIKTargetXform(hips);
result.hipsType = ikTypes.RotationAndPosition;
result.hipsPosition = Vec3.multiplyQbyV(Y_180, xform.pos);
result.hipsRotation = Quat.multiply(Y_180, xform.rot);
result.hipsPosition = xform.pos;
result.hipsRotation = xform.rot;
} else {
result.hipsType = props.hipsType;
result.hipsPositon = props.hipsPosition;
result.hipsPosition = props.hipsPosition;
result.hipsRotation = props.hipsRotation;
}
if (spine2) {
xform = computeIKTargetXform(spine2);
result.spine2Type = ikTypes.RotationAndPosition;
result.spine2Position = xform.pos;
result.spine2Rotation = xform.rot;
} else {
result.spine2Type = ikTypes.Off;
}
return result;
}, propList);
}, ANIM_VARS);
}
} else {

View file

@ -18,14 +18,14 @@ function shutdown() {
});
}
var WHITE = {x: 1, y: 1, z: 1, w: 1};
var BLUE = {x: 0, y: 0, z: 1, w: 1};
function update(dt) {
if (Controller.Hardware.Vive) {
TRACKED_OBJECT_POSES.forEach(function (key) {
var pose = Controller.getPoseValue(Controller.Hardware.Vive[key]);
if (pose.valid) {
DebugDraw.addMyAvatarMarker(key, pose.rotation, pose.translation, WHITE);
DebugDraw.addMyAvatarMarker(key, pose.rotation, pose.translation, BLUE);
} else {
DebugDraw.removeMyAvatarMarker(key);
}