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
324 glm::vec3 position = extractTranslation(mat);324 glm::vec3 position = extractTranslation(mat);
325 glm::quat rotation = glm::quat_cast(mat);325 glm::quat rotation = glm::quat_cast(mat);
326 326
327 // Flip the rotation appropriately for each hand327 // When the sensor-to-world rotation is identity the coordinate axes look like this:
328 int sign = index == LEFT_HAND ? 1 : -1;328 //
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));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;
330 385
331 position += rotation * glm::vec3(0, 0, -CONTROLLER_LENGTH_OFFSET);386 position += rotation * glm::vec3(0, 0, -CONTROLLER_LENGTH_OFFSET);
332 387