mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 09:33:49 +02:00
Now supports sensorConfig with hips and chest sensors
This commit is contained in:
parent
adaf7dda7c
commit
0ebaba7cf8
4 changed files with 100 additions and 38 deletions
|
@ -81,10 +81,10 @@
|
|||
"typeVar": "leftFootType"
|
||||
},
|
||||
{
|
||||
"jointName": "Neck",
|
||||
"positionVar": "neckPosition",
|
||||
"rotationVar": "neckRotation",
|
||||
"typeVar": "neckType"
|
||||
"jointName": "Spine2",
|
||||
"positionVar": "spine2Position",
|
||||
"rotationVar": "spine2Rotation",
|
||||
"typeVar": "spine2Type"
|
||||
},
|
||||
{
|
||||
"jointName": "Head",
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue