mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-05-03 17:19:38 +02:00
198 lines
7 KiB
JavaScript
198 lines
7 KiB
JavaScript
/* global Xform */
|
|
Script.include("/~/system/libraries/Xform.js");
|
|
|
|
var TRACKED_OBJECT_POSES = [
|
|
"TrackedObject00", "TrackedObject01", "TrackedObject02", "TrackedObject03",
|
|
"TrackedObject04", "TrackedObject05", "TrackedObject06", "TrackedObject07",
|
|
"TrackedObject08", "TrackedObject09", "TrackedObject10", "TrackedObject11",
|
|
"TrackedObject12", "TrackedObject13", "TrackedObject14", "TrackedObject15"
|
|
];
|
|
|
|
var calibrated = false;
|
|
var rightTriggerPressed = false;
|
|
var leftTriggerPressed = false;
|
|
|
|
var MAPPING_NAME = "com.highfidelity.viveMotionCapture";
|
|
|
|
var mapping = Controller.newMapping(MAPPING_NAME);
|
|
mapping.from([Controller.Standard.RTClick]).peek().to(function (value) {
|
|
rightTriggerPressed = (value !== 0) ? true : false;
|
|
});
|
|
mapping.from([Controller.Standard.LTClick]).peek().to(function (value) {
|
|
leftTriggerPressed = (value !== 0) ? true : false;
|
|
});
|
|
|
|
Controller.enableMapping(MAPPING_NAME);
|
|
|
|
var leftFoot;
|
|
var rightFoot;
|
|
var hips;
|
|
|
|
var Y_180 = {x: 0, y: 1, z: 0, w: 0};
|
|
|
|
function computeOffsetXform(pose, jointIndex) {
|
|
var poseXform = new Xform(pose.rotation, pose.translation);
|
|
var referenceXform = new Xform(MyAvatar.getAbsoluteDefaultJointRotationInObjectFrame(jointIndex),
|
|
MyAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(jointIndex));
|
|
return Xform.mul(poseXform.inv(), referenceXform);
|
|
}
|
|
|
|
function calibrate() {
|
|
print("AJT: calibrating");
|
|
var poses = [];
|
|
if (Controller.Hardware.Vive) {
|
|
TRACKED_OBJECT_POSES.forEach(function (key) {
|
|
var channel = Controller.Hardware.Vive[key];
|
|
var pose = Controller.getPoseValue(channel);
|
|
if (pose.valid) {
|
|
poses.push({
|
|
channel: channel,
|
|
pose: pose
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
if (poses.length >= 2) {
|
|
// sort by y
|
|
poses.sort(function(a, b) {
|
|
var ay = a.pose.translation.y;
|
|
var by = b.pose.translation.y;
|
|
return ay - by;
|
|
});
|
|
|
|
if (poses[0].pose.translation.x > poses[1].pose.translation.x) {
|
|
rightFoot = poses[0];
|
|
leftFoot = poses[1];
|
|
} else {
|
|
rightFoot = poses[1];
|
|
leftFoot = poses[0];
|
|
}
|
|
|
|
// compute offsets
|
|
rightFoot.offsetXform = computeOffsetXform(rightFoot.pose, MyAvatar.getJointIndex("RightFoot"));
|
|
leftFoot.offsetXform = computeOffsetXform(leftFoot.pose, MyAvatar.getJointIndex("LeftFoot"));
|
|
|
|
print("AJT: rightFoot = " + JSON.stringify(rightFoot));
|
|
print("AJT: leftFoot = " + JSON.stringify(leftFoot));
|
|
|
|
if (poses.length >= 3) {
|
|
hips = poses[2];
|
|
hips.offsetXform = computeOffsetXform(hips.pose, MyAvatar.getJointIndex("Hips"));
|
|
|
|
print("AJT: hips = " + JSON.stringify(hips));
|
|
}
|
|
} else {
|
|
print("AJT: could not find two trackers, try again!");
|
|
}
|
|
}
|
|
|
|
var ikTypes = {
|
|
RotationAndPosition: 0,
|
|
RotationOnly: 1,
|
|
HmdHead: 2,
|
|
HipsRelativeRotationAndPosition: 3,
|
|
Off: 4
|
|
};
|
|
|
|
var handlerId;
|
|
|
|
function update(dt) {
|
|
if (rightTriggerPressed && leftTriggerPressed) {
|
|
if (!calibrated) {
|
|
calibrate();
|
|
calibrated = true;
|
|
|
|
if (handlerId) {
|
|
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;
|
|
if (rightFoot) {
|
|
pose = Controller.getPoseValue(rightFoot.channel);
|
|
offsetXform = rightFoot.offsetXform;
|
|
|
|
xform = Xform.mul(new Xform(pose.rotation, pose.translation), offsetXform);
|
|
result.rightFootType = ikTypes.RotationAndPosition;
|
|
result.rightFootPosition = Vec3.multiplyQbyV(Y_180, xform.pos);
|
|
result.rightFootRotation = Quat.multiply(Y_180, xform.rot);
|
|
|
|
} else {
|
|
result.rightFootType = props.rightFootType;
|
|
result.rightFootPositon = 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);
|
|
result.leftFootType = ikTypes.RotationAndPosition;
|
|
result.leftFootPosition = Vec3.multiplyQbyV(Y_180, xform.pos);
|
|
result.leftFootRotation = Quat.multiply(Y_180, xform.rot);
|
|
} else {
|
|
result.leftFootType = props.leftFootType;
|
|
result.leftFootPositon = 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);
|
|
result.hipsType = ikTypes.RotationAndPosition;
|
|
result.hipsPosition = Vec3.multiplyQbyV(Y_180, xform.pos);
|
|
result.hipsRotation = Quat.multiply(Y_180, xform.rot);
|
|
} else {
|
|
result.hipsType = props.hipsType;
|
|
result.hipsPositon = props.hipsPosition;
|
|
result.hipsRotation = props.hipsRotation;
|
|
}
|
|
|
|
return result;
|
|
}, propList);
|
|
|
|
}
|
|
} else {
|
|
calibrated = false;
|
|
}
|
|
|
|
var drawMarkers = false;
|
|
if (drawMarkers) {
|
|
var RED = {x: 1, y: 0, z: 0, w: 1};
|
|
var GREEN = {x: 0, y: 1, z: 0, w: 1};
|
|
var BLUE = {x: 0, y: 0, z: 1, w: 1};
|
|
|
|
if (leftFoot) {
|
|
var leftFootPose = Controller.getPoseValue(leftFoot.channel);
|
|
DebugDraw.addMyAvatarMarker("leftFootTracker", leftFootPose.rotation, leftFootPose.translation, BLUE);
|
|
}
|
|
|
|
if (rightFoot) {
|
|
var rightFootPose = Controller.getPoseValue(rightFoot.channel);
|
|
DebugDraw.addMyAvatarMarker("rightFootTracker", rightFootPose.rotation, rightFootPose.translation, RED);
|
|
}
|
|
|
|
if (hips) {
|
|
var hipsPose = Controller.getPoseValue(hips.channel);
|
|
DebugDraw.addMyAvatarMarker("hipsTracker", hipsPose.rotation, hipsPose.translation, GREEN);
|
|
}
|
|
}
|
|
}
|
|
|
|
Script.update.connect(update);
|
|
|
|
Script.scriptEnding.connect(function () {
|
|
Controller.disableMapping(MAPPING_NAME);
|
|
Script.update.disconnect(update);
|
|
});
|
|
var TRIGGER_OFF_VALUE = 0.1;
|