History

fix for vive controller to place hand for IK

Andrew Meadows committed 11 years ago

Commit 617e2101 parent bb632671 file · +58 −3Browse files

Showing the changes to libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp (1 of 1 file). Show all

Unified · Split

libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp+58−3
@@ -324,9 +324,64 @@ void ViveControllerManager::handlePoseEvent(const mat4& mat, int index) { · 323 unmodified lines
324324 glm::vec3 position = extractTranslation(mat);
325325 glm::quat rotation = glm::quat_cast(mat);
326326
327− // Flip the rotation appropriately for each hand
328− int sign = index == LEFT_HAND ? 1 : -1;
329− rotation = rotation * glm::angleAxis(PI, glm::vec3(1.0f, 0.0f, 0.0f)) * glm::angleAxis(sign * PI_OVER_TWO, glm::vec3(0.0f, 0.0f, 1.0f));
327+ // When the sensor-to-world rotation is identity the coordinate axes look like this:
328+ //
329+ // user
330+ // forward
331+ // z
332+ // |
333+ // y| user
334+ // y o----x right
335+ // o-----x user
336+ // | up
337+ // |
338+ // z
339+ //
340+ // Vive
341+ //
342+
343+ // From ABOVE the hand canonical axes looks like this:
344+ //
345+ // | | | | y | | | |
346+ // | | | | | | | | |
347+ // | | | | |
348+ // |left | / x---- + \ |right|
349+ // | _/ z \_ |
350+ // | | | |
351+ // | | | |
352+ //
353+
354+ // So when the user is standing in Vive space facing the -zAxis with hands outstretched and palms down
355+ // the rotation to align the Vive axes with those of the hands is:
356+ //
357+ // QviveToHand = halfTurnAboutY * quaterTurnAboutX
358+
359+ // Due to how the Vive controllers fit into the palm there is an offset that is different for each hand.
360+ // You can think of this offset as the inverse of the measured rotation when the hands are posed, such that
361+ // the combination (measurement * offset) is identity at this orientation.
362+ //
363+ // Qoffset = glm::inverse(deltaRotation when hand is posed fingers forward, palm down)
364+ //
365+ // An approximate offset for the Vive can be obtained by inpection:
366+ //
367+ // Qoffset = glm::inverse(glm::angleAxis(sign * PI/4.0f, zAxis) * glm::angleAxis(PI/2.0f, xAxis))
368+ //
369+
370+ // Finally there is another flip around the yAxis to re-align from model to Vive space, so the full equation is:
371+ //
372+ // Q = yFlip * combinedMeasurement * viveToHand
373+ //
374+ // Q = yFlip * (deltaQ * QOffset) * (yFlip * quarterTurnAboutX)
375+ //
376+ // Q = yFlip * (deltaQ * inverse(deltaQForAlignedHand)) * (yFlip * quarterTurnAboutX)
377+
378+ const glm::quat quarterX = glm::angleAxis(PI / 2.0f, glm::vec3(1.0f, 0.0f, 0.0f));
379+ const glm::quat yFlip = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f));
380+ float sign = (index == LEFT_HAND) ? -1.0f : 1.0f;
381+ const glm::quat signedQuaterZ = glm::angleAxis(sign * PI / 2.0f, glm::vec3(0.0f, 0.0f, 1.0f));
382+ const glm::quat eighthX = glm::angleAxis(PI / 4.0f, glm::vec3(1.0f, 0.0f, 0.0f));
383+ const glm::quat offset = glm::inverse(signedQuaterZ * eighthX);
384+ rotation = yFlip * rotation * offset * yFlip * quarterX;
330385
331386 position += rotation * glm::vec3(0, 0, -CONTROLLER_LENGTH_OFFSET);
332387