diff --git a/src/modules/headset/headset_vrapi.c b/src/modules/headset/headset_vrapi.c index 8a4bab48..7e3f83d9 100644 --- a/src/modules/headset/headset_vrapi.c +++ b/src/modules/headset/headset_vrapi.c @@ -210,6 +210,21 @@ static bool vrapi_getPose(Device device, float* position, float* orientation) { vec3_set(position, pose->Position.x, pose->Position.y + state.offset, pose->Position.z); quat_init(orientation, &pose->Orientation.x); + + // make tracked hands face -Z + if(index < 2 && state.hands[index].Type == ovrControllerType_Hand) { + float rotation[4] = {0,0,0,1}; + if (device == DEVICE_HAND_LEFT) { + float q[4]; + quat_fromAngleAxis(rotation, (float) M_PI, 0.f, 0.f, 1.f); + quat_mul(rotation, rotation, quat_fromAngleAxis(q, (float) M_PI / 2.f, 0.f, 1.f, 0.f)); + } else if(device == DEVICE_HAND_RIGHT) { + quat_fromAngleAxis(rotation, (float) M_PI / 2.f, 0.f, 1.f, 0.f); + } + quat_mul(orientation, orientation, rotation); + } + + return valid; } @@ -616,11 +631,24 @@ static bool vrapi_animate(Device device, struct Model* model) { lovrModelResetPose(model); + // compensate for vrapi_getPose changing "forward" to be -Z + float compensate[4]; + if (device == DEVICE_HAND_LEFT) { + float q[4]; + quat_fromAngleAxis(compensate, (float) -M_PI, 0.f, 0.f, 1.f); + quat_mul(compensate, compensate, quat_fromAngleAxis(q, (float) -M_PI / 2.f, 0.f, 1.f, 0.f)); + } else { + quat_fromAngleAxis(compensate, (float) -M_PI / 2.f, 0.f, 1.f, 0.f); + } + // Replace node rotations with the rotations in the hand pose, keeping the position the same for (uint32_t i = 0; i < ovrHandBone_MaxSkinnable && i < modelData->nodeCount; i++) { float position[4], orientation[4]; vec3_init(position, modelData->nodes[i].transform.properties.translation); quat_init(orientation, &handPose->BoneRotations[i].x); + if(i == ovrHandBone_WristRoot) { + quat_mul(orientation, orientation, compensate); + } lovrModelPose(model, i, position, orientation, 1.f); }