mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
neruonAvatar.js: now sets rotations in correct frame.
The rotations from the neuron are effectively in world space and are deltas from the default pose. There still is an issue with the thumb, due to the missing joint from the Neuron. The Neuron only has 3 thumb joints, not 4.
This commit is contained in:
parent
c44f69b370
commit
8b979b67ee
2 changed files with 119 additions and 28 deletions
|
@ -61,6 +61,70 @@ var JOINT_NAME_MAP = {
|
|||
LeftHandPinky3: "LeftHandPinky4"
|
||||
};
|
||||
|
||||
var JOINT_PARENT_MAP = {
|
||||
Hips: "",
|
||||
RightUpLeg: "Hips",
|
||||
RightLeg: "RightUpLeg",
|
||||
RightFoot: "RightLeg",
|
||||
LeftUpLeg: "Hips",
|
||||
LeftLeg: "LeftUpLeg",
|
||||
LeftFoot: "LeftLeg",
|
||||
Spine: "Hips",
|
||||
Spine1: "Spine",
|
||||
Spine2: "Spine1",
|
||||
Spine3: "Spine2",
|
||||
Neck: "Spine3",
|
||||
Head: "Neck",
|
||||
RightShoulder: "Spine3",
|
||||
RightArm: "RightShoulder",
|
||||
RightForeArm: "RightArm",
|
||||
RightHand: "RightForeArm",
|
||||
RightHandThumb1: "RightHand",
|
||||
RightHandThumb2: "RightHandThumb1",
|
||||
RightHandThumb3: "RightHandThumb2",
|
||||
RightHandThumb4: "RightHandThumb3",
|
||||
RightHandIndex1: "RightHand",
|
||||
RightHandIndex2: "RightHandIndex1",
|
||||
RightHandIndex3: "RightHandIndex2",
|
||||
RightHandIndex4: "RightHandIndex3",
|
||||
RightHandMiddle1: "RightHand",
|
||||
RightHandMiddle2: "RightHandMiddle1",
|
||||
RightHandMiddle3: "RightHandMiddle2",
|
||||
RightHandMiddle4: "RightHandMiddle3",
|
||||
RightHandRing1: "RightHand",
|
||||
RightHandRing2: "RightHandRing1",
|
||||
RightHandRing3: "RightHandRing2",
|
||||
RightHandRing4: "RightHandRing3",
|
||||
RightHandPinky1: "RightHand",
|
||||
RightHandPinky2: "RightHandPinky1",
|
||||
RightHandPinky3: "RightHandPinky2",
|
||||
RightHandPinky4: "RightHandPinky3",
|
||||
LeftShoulder: "Spine3",
|
||||
LeftArm: "LeftShoulder",
|
||||
LeftForeArm: "LeftArm",
|
||||
LeftHand: "LeftForeArm",
|
||||
LeftHandThumb1: "LeftHand",
|
||||
LeftHandThumb2: "LeftHandThumb1",
|
||||
LeftHandThumb3: "LeftHandThumb2",
|
||||
LeftHandThumb4: "LeftHandThumb3",
|
||||
LeftHandIndex1: "LeftHand",
|
||||
LeftHandIndex2: "LeftHandIndex1",
|
||||
LeftHandIndex3: "LeftHandIndex2",
|
||||
LeftHandIndex4: "LeftHandIndex3",
|
||||
LeftHandMiddle1: "LeftHand",
|
||||
LeftHandMiddle2: "LeftHandMiddle1",
|
||||
LeftHandMiddle3: "LeftHandMiddle2",
|
||||
LeftHandMiddle4: "LeftHandMiddle3",
|
||||
LeftHandRing1: "LeftHand",
|
||||
LeftHandRing2: "LeftHandRing1",
|
||||
LeftHandRing3: "LeftHandRing2",
|
||||
LeftHandRing4: "LeftHandRing3",
|
||||
LeftHandPinky1: "LeftHand",
|
||||
LeftHandPinky2: "LeftHandPinky1",
|
||||
LeftHandPinky3: "LeftHandPinky2",
|
||||
LeftHandPinky: "LeftHandPinky3",
|
||||
};
|
||||
|
||||
function dumpHardwareMapping() {
|
||||
Object.keys(Controller.Hardware).forEach(function (deviceName) {
|
||||
Object.keys(Controller.Hardware[deviceName]).forEach(function (input) {
|
||||
|
@ -103,6 +167,21 @@ NeuronAvatar.prototype.activate = function () {
|
|||
Script.update.connect(updateCallback);
|
||||
}
|
||||
this._active = true;
|
||||
|
||||
// build absDefaultPoseMap
|
||||
this._absDefaultRotMap = {};
|
||||
var keys = Object.keys(JOINT_NAME_MAP);
|
||||
var i, l = keys.length;
|
||||
for (i = 0; i < l; i++) {
|
||||
var jointName = JOINT_NAME_MAP[keys[i]];
|
||||
var j = MyAvatar.getJointIndex(jointName);
|
||||
var parentJointName = JOINT_PARENT_MAP[jointName];
|
||||
if (parentJointName === "") {
|
||||
this._absDefaultRotMap[jointName] = MyAvatar.getDefaultJointRotation(j);
|
||||
} else {
|
||||
this._absDefaultRotMap[jointName] = Quat.multiply(this._absDefaultRotMap[parentJointName], MyAvatar.getDefaultJointRotation(j));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
NeuronAvatar.prototype.deactivate = function () {
|
||||
|
@ -117,14 +196,22 @@ NeuronAvatar.prototype.deactivate = function () {
|
|||
NeuronAvatar.prototype.update = function (deltaTime) {
|
||||
var keys = Object.keys(JOINT_NAME_MAP);
|
||||
var i, l = keys.length;
|
||||
var absDefaultRot = {};
|
||||
for (i = 0; i < l; i++) {
|
||||
var channel = Controller.Hardware.Neuron[keys[i]];
|
||||
if (channel) {
|
||||
var pose = Controller.getPoseValue(channel);
|
||||
var j = MyAvatar.getJointIndex(JOINT_NAME_MAP[keys[i]]);
|
||||
var defaultRot = MyAvatar.getDefaultJointRotation(j);
|
||||
var rot = Quat.multiply(Quat.inverse(defaultRot), Quat.multiply(pose.rotation, defaultRot));
|
||||
MyAvatar.setJointRotation(j, Quat.multiply(defaultRot, rot));
|
||||
var jointName = JOINT_NAME_MAP[keys[i]];
|
||||
var parentJointName = JOINT_PARENT_MAP[jointName];
|
||||
var j = MyAvatar.getJointIndex(jointName);
|
||||
var defaultAbsRot = this._absDefaultRotMap[jointName];
|
||||
var parentDefaultAbsRot;
|
||||
if (parentJointName === "") {
|
||||
parentDefaultAbsRot = {x: 0, y: 0, z: 0, w: 1};
|
||||
} else {
|
||||
parentDefaultAbsRot = this._absDefaultRotMap[parentJointName];
|
||||
}
|
||||
MyAvatar.setJointRotation(j, Quat.multiply(Quat.inverse(parentDefaultAbsRot), Quat.multiply(pose.rotation, defaultAbsRot)));
|
||||
//MyAvatar.setJointTranslation(j, Vec3.multiply(100.0, pose.translation));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,21 +107,37 @@ void FrameDataReceivedCallback(void* context, SOCKET_REF sender, BvhDataHeaderEx
|
|||
// version 1.0
|
||||
if (header->DataVersion.Major == 1 && header->DataVersion.Minor == 0) {
|
||||
|
||||
std::lock_guard<std::mutex> guard(neuronPlugin->_jointsMutex);
|
||||
|
||||
// Data is 6 floats: 3 position values, 3 rotation euler angles (degrees)
|
||||
|
||||
// resize vector if necessary
|
||||
const size_t NUM_FLOATS_PER_JOINT = 6;
|
||||
const size_t NUM_JOINTS = header->DataCount / NUM_FLOATS_PER_JOINT;
|
||||
if (neuronPlugin->_joints.size() != NUM_JOINTS) {
|
||||
neuronPlugin->_joints.resize(NUM_JOINTS, { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } });
|
||||
// skip reference joint if present
|
||||
if (header->WithReference && header->WithDisp) {
|
||||
data += 6;
|
||||
} else if (header->WithReference && !header->WithDisp) {
|
||||
data += 3;
|
||||
}
|
||||
|
||||
assert(sizeof(NeuronPlugin::NeuronJoint) == (NUM_FLOATS_PER_JOINT * sizeof(float)));
|
||||
if (header->WithDisp) {
|
||||
// enter mutex
|
||||
std::lock_guard<std::mutex> guard(neuronPlugin->_jointsMutex);
|
||||
|
||||
// copy the data
|
||||
memcpy(&(neuronPlugin->_joints[0]), data, sizeof(NeuronPlugin::NeuronJoint) * NUM_JOINTS);
|
||||
//
|
||||
// Data is 6 floats per joint: 3 position values, 3 rotation euler angles (degrees)
|
||||
//
|
||||
|
||||
// resize vector if necessary
|
||||
const size_t NUM_FLOATS_PER_JOINT = 6;
|
||||
const size_t NUM_JOINTS = header->DataCount / NUM_FLOATS_PER_JOINT;
|
||||
if (neuronPlugin->_joints.size() != NUM_JOINTS) {
|
||||
neuronPlugin->_joints.resize(NUM_JOINTS, { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } });
|
||||
}
|
||||
|
||||
assert(sizeof(NeuronPlugin::NeuronJoint) == (NUM_FLOATS_PER_JOINT * sizeof(float)));
|
||||
|
||||
// copy the data
|
||||
memcpy(&(neuronPlugin->_joints[0]), data, sizeof(NeuronPlugin::NeuronJoint) * NUM_JOINTS);
|
||||
} else {
|
||||
|
||||
qCCritical(inputplugins) << "NeruonPlugin: format not supported";
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
static bool ONCE = false;
|
||||
|
@ -368,18 +384,6 @@ void NeuronPlugin::InputDevice::update(float deltaTime, const std::vector<Neuron
|
|||
angularVel = glm::vec3(d.x, d.y, d.z) / (0.5f * deltaTime);
|
||||
}
|
||||
_poseStateMap[poseIndex] = controller::Pose(pos, rot, linearVel, angularVel);
|
||||
|
||||
// dump the first 5 joints
|
||||
if (i <= JointIndex::LeftFoot) {
|
||||
qCDebug(inputplugins) << neuronJointName((JointIndex)i);
|
||||
qCDebug(inputplugins) << " trans = " << joints[i].pos;
|
||||
qCDebug(inputplugins) << " euler = " << joints[i].euler;
|
||||
}
|
||||
/*
|
||||
if (glm::length(angularVel) > 0.5f) {
|
||||
qCDebug(inputplugins) << "Movement in joint" << i << neuronJointName((JointIndex)i);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue