Chris Howe 2017-06-06 12:11:57 -04:00
parent 6edc6b2756
commit 8166fec0e0
4 changed files with 124 additions and 164 deletions

View file

@ -773,114 +773,78 @@ controller::Pose MyAvatar::getRightHandTipPose() const {
return pose;
}
glm::vec3 MyAvatar::worldToJointPoint(const glm::vec3& position, const int jointIndex) const {
glm::vec3 jointPos = getPosition();//default value if no or invalid joint specified
glm::quat jointRot = getRotation();//default value if no or invalid joint specified
if (jointIndex != -1) {
if (_skeletonModel->getJointPositionInWorldFrame(jointIndex, jointPos)) {
_skeletonModel->getJointRotationInWorldFrame(jointIndex, jointRot);
}
else {
qWarning() << "Invalid joint index specified: " << jointIndex;
}
}
glm::vec3 modelOffset = position - jointPos;
glm::vec3 jointSpacePosition = glm::inverse(jointRot) * modelOffset;
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
//:1P: conversion functions for world-space to avatar-space or vice versa
glm::vec3 MyAvatar::worldToAvatarPoint(const glm::vec3& position, const int jointIndex) const
{
glm::vec3 jointPos = getPosition();//default value if no or invalid joint specified
glm::quat jointRot = getRotation();//default value if no or invalid joint specified
if (jointIndex != -1)
{
if (!_skeletonModel->getJointPositionInWorldFrame(jointIndex, jointPos))
{
qWarning() << "Invalid joint index specified: " << jointIndex;
}
if (!_skeletonModel->getJointRotationInWorldFrame(jointIndex, jointRot))
{
qWarning() << "Invalid joint index specified: " << jointIndex;
}
}
glm::vec3 modelOffset = position - jointPos;
glm::vec3 modelPosition = glm::inverse(jointRot) * modelOffset;
return modelPosition;
return jointSpacePosition;
}
glm::vec3 MyAvatar::worldToAvatarDirection(const glm::vec3& worldDir, const int jointIndex) const
{
glm::quat jointRot = getRotation();//default value if no or invalid joint specified
if (jointIndex != -1)
{
if (!_skeletonModel->getJointRotationInWorldFrame(jointIndex, jointRot))
{
qWarning() << "Invalid joint index specified: " << jointIndex;
}
}
glm::vec3 MyAvatar::worldToJointDirection(const glm::vec3& worldDir, const int jointIndex) const {
glm::quat jointRot = getRotation();//default value if no or invalid joint specified
if ((jointIndex != -1) && (!_skeletonModel->getJointRotationInWorldFrame(jointIndex, jointRot))) {
qWarning() << "Invalid joint index specified: " << jointIndex;
}
glm::vec3 avatarDir = glm::inverse(jointRot) * worldDir;
return avatarDir;
glm::vec3 jointSpaceDir = glm::inverse(jointRot) * worldDir;
return jointSpaceDir;
}
glm::quat MyAvatar::worldToAvatarRotation(const glm::quat& worldRot, const int jointIndex) const
{
glm::quat jointRot = getRotation();//default value if no or invalid joint specified
if (jointIndex != -1)
{
if (!_skeletonModel->getJointRotationInWorldFrame(jointIndex, jointRot))
{
qWarning() << "Invalid joint index specified: " << jointIndex;
}
}
glm::quat avatarRot = glm::inverse(jointRot) * worldRot;
return avatarRot;
glm::quat MyAvatar::worldToJointRotation(const glm::quat& worldRot, const int jointIndex) const {
glm::quat jointRot = getRotation();//default value if no or invalid joint specified
if ((jointIndex != -1) && (!_skeletonModel->getJointRotationInWorldFrame(jointIndex, jointRot))) {
qWarning() << "Invalid joint index specified: " << jointIndex;
}
glm::quat jointSpaceRot = glm::inverse(jointRot) * worldRot;
return jointSpaceRot;
}
glm::vec3 MyAvatar::avatarToWorldPoint(const glm::vec3& avatarPos, const int jointIndex) const
{
glm::vec3 jointPos = getPosition();//default value if no or invalid joint specified
glm::quat jointRot = getRotation();//default value if no or invalid joint specified
glm::vec3 MyAvatar::jointToWorldPoint(const glm::vec3& jointSpacePos, const int jointIndex) const {
glm::vec3 jointPos = getPosition();//default value if no or invalid joint specified
glm::quat jointRot = getRotation();//default value if no or invalid joint specified
if (jointIndex != -1)
{
if (!_skeletonModel->getJointPositionInWorldFrame(jointIndex, jointPos))
{
qWarning() << "Invalid joint index specified: " << jointIndex;
}
if (!_skeletonModel->getJointRotationInWorldFrame(jointIndex, jointRot))
{
qWarning() << "Invalid joint index specified: " << jointIndex;
}
}
if (jointIndex != -1) {
if (_skeletonModel->getJointPositionInWorldFrame(jointIndex, jointPos)) {
_skeletonModel->getJointRotationInWorldFrame(jointIndex, jointRot);
}
else {
qWarning() << "Invalid joint index specified: " << jointIndex;
}
}
glm::vec3 worldOffset = jointRot * avatarPos;
glm::vec3 worldPos = jointPos + worldOffset;
glm::vec3 worldOffset = jointRot * jointSpacePos;
glm::vec3 worldPos = jointPos + worldOffset;
return worldPos;
return worldPos;
}
glm::vec3 MyAvatar::avatarToWorldDirection(const glm::vec3& avatarDir, const int jointIndex) const
{
glm::quat jointRot = getRotation();//default value if no or invalid joint specified
if (jointIndex != -1)
{
if (!_skeletonModel->getJointRotationInWorldFrame(jointIndex, jointRot))
{
qWarning() << "Invalid joint index specified: " << jointIndex;
}
}
glm::vec3 worldDir = jointRot * avatarDir;
return worldDir;
glm::vec3 MyAvatar::jointToWorldDirection(const glm::vec3& jointSpaceDir, const int jointIndex) const {
glm::quat jointRot = getRotation();//default value if no or invalid joint specified
if ((jointIndex != -1) && (!_skeletonModel->getJointRotationInWorldFrame(jointIndex, jointRot))) {
qWarning() << "Invalid joint index specified: " << jointIndex;
}
glm::vec3 worldDir = jointRot * jointSpaceDir;
return worldDir;
}
glm::quat MyAvatar::avatarToWorldRotation(const glm::quat& avatarRot, const int jointIndex) const
{
glm::quat jointRot = getRotation();//default value if no or invalid joint specified
if (jointIndex != -1)
{
if (!_skeletonModel->getJointRotationInWorldFrame(jointIndex, jointRot))
{
qWarning() << "Invalid joint index specified: " << jointIndex;
}
}
glm::quat worldRot = jointRot * avatarRot;
return worldRot;
glm::quat MyAvatar::jointToWorldRotation(const glm::quat& jointSpaceRot, const int jointIndex) const {
glm::quat jointRot = getRotation();//default value if no or invalid joint specified
if ((jointIndex != -1) && (!_skeletonModel->getJointRotationInWorldFrame(jointIndex, jointRot))) {
qWarning() << "Invalid joint index specified: " << jointIndex;
}
glm::quat worldRot = jointRot * jointSpaceRot;
return worldRot;
}
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
// virtual
void MyAvatar::render(RenderArgs* renderArgs) {

View file

@ -379,18 +379,14 @@ public:
Q_INVOKABLE controller::Pose getLeftHandTipPose() const;
Q_INVOKABLE controller::Pose getRightHandTipPose() const;
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
//:1P: world-space to avatar-space rigconversion functions
Q_INVOKABLE glm::vec3 worldToAvatarPoint(const glm::vec3& position, const int jointIndex = -1) const;
Q_INVOKABLE glm::vec3 worldToAvatarDirection(const glm::vec3& direction, const int jointIndex = -1) const;
Q_INVOKABLE glm::quat worldToAvatarRotation(const glm::quat& rotation, const int jointIndex = -1) const;
// world-space to avatar-space rigconversion functions
Q_INVOKABLE glm::vec3 worldToJointPoint(const glm::vec3& position, const int jointIndex = -1) const;
Q_INVOKABLE glm::vec3 worldToJointDirection(const glm::vec3& direction, const int jointIndex = -1) const;
Q_INVOKABLE glm::quat worldToJointRotation(const glm::quat& rotation, const int jointIndex = -1) const;
Q_INVOKABLE glm::vec3 avatarToWorldPoint(const glm::vec3& position, const int jointIndex = -1) const;
Q_INVOKABLE glm::vec3 avatarToWorldDirection(const glm::vec3& direction, const int jointIndex = -1) const;
Q_INVOKABLE glm::quat avatarToWorldRotation(const glm::quat& rotation, const int jointIndex = -1) const;
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
Q_INVOKABLE glm::vec3 jointToWorldPoint(const glm::vec3& position, const int jointIndex = -1) const;
Q_INVOKABLE glm::vec3 jointToWorldDirection(const glm::vec3& direction, const int jointIndex = -1) const;
Q_INVOKABLE glm::quat jointToWorldRotation(const glm::quat& rotation, const int jointIndex = -1) const;
AvatarWeakPointer getLookAtTargetAvatar() const { return _lookAtTargetAvatar; }
void updateLookAtTargetAvatar();

View file

@ -20,45 +20,45 @@ var debugBoxBaseProperties = {
userData: "{ \"grabbableKey\": { \"grabbable\": false, \"kinematic\": false } }"
};
//avatarToWorldPoint
//jointToWorldPoint
// create sphere for finger on left hand
// each frame, calculate world position of finger, with some offset
// update sphere to match this position
var avatarToWorldPointTest_sphereEntity;
function avatarToWorldPointTest() {
var jointToWorldPointTest_sphereEntity;
function jointToWorldPointTest() {
var jointIndex = MyAvatar.getJointIndex("LeftHandPinky4");
var jointOffset_WorldSpace = { x: 0.1, y: 0, z: 0 };
var worldPos = MyAvatar.avatarToWorldPoint(jointOffset_WorldSpace, jointIndex);
var worldPos = MyAvatar.jointToWorldPoint(jointOffset_WorldSpace, jointIndex);
var jointSphereProps = Object.create(debugSphereBaseProperties);
jointSphereProps.name = "avatarToWorldPointTest_Sphere";
jointSphereProps.name = "jointToWorldPointTest_Sphere";
jointSphereProps.color = { blue: 240, green: 150, red: 150 };
jointSphereProps.position = worldPos;
avatarToWorldPointTest_sphereEntity = Entities.addEntity(jointSphereProps);
jointToWorldPointTest_sphereEntity = Entities.addEntity(jointSphereProps);
}
function avatarToWorldPointTest_update(deltaTime) {
function jointToWorldPointTest_update(deltaTime) {
var jointIndex = MyAvatar.getJointIndex("LeftHandPinky4");
var jointOffset_WorldSpace = { x: 0.1, y: 0, z: 0 };
var worldPos = MyAvatar.avatarToWorldPoint(jointOffset_WorldSpace, jointIndex);
var worldPos = MyAvatar.jointToWorldPoint(jointOffset_WorldSpace, jointIndex);
var newProperties = { position: worldPos };
Entities.editEntity(avatarToWorldPointTest_sphereEntity, newProperties);
Entities.editEntity(jointToWorldPointTest_sphereEntity, newProperties);
}
//avatarToWorldDirection
//jointToWorldDirection
// create line in world space
// each frame calculate world space direction of players head z axis
// update line to match
var avatarToWorldDirectionTest_lineEntity;
function avatarToWorldDirectionTest() {
var jointToWorldDirectionTest_lineEntity;
function jointToWorldDirectionTest() {
var jointIndex = MyAvatar.getJointIndex("Head");
var avatarPos = MyAvatar.getJointPosition(jointIndex);
var jointDir = { x: 1, y: 0, z: 1 };
var worldDir = MyAvatar.avatarToWorldDirection(jointDir, jointIndex);
var worldDir = MyAvatar.jointToWorldDirection(jointDir, jointIndex);
print(worldDir.x);
print(worldDir.y);
print(worldDir.z);
avatarToWorldDirectionTest_lineEntity = Entities.addEntity({
jointToWorldDirectionTest_lineEntity = Entities.addEntity({
type: "Line",
color: {red: 250, green: 0, blue: 0},
dimensions: {x: 5, y: 5, z: 5},
@ -72,11 +72,11 @@ function avatarToWorldDirectionTest() {
position : avatarPos,
});
}
function avatarToWorldDirection_update(deltaTime) {
function jointToWorldDirection_update(deltaTime) {
var jointIndex = MyAvatar.getJointIndex("Head");
var avatarPos = MyAvatar.getJointPosition(jointIndex);
var jointDir = { x: 1, y: 0, z: 0 };
var worldDir = MyAvatar.avatarToWorldDirection(jointDir, jointIndex);
var worldDir = MyAvatar.jointToWorldDirection(jointDir, jointIndex);
var newProperties = {
linePoints: [{
x: 0,
@ -87,41 +87,41 @@ function avatarToWorldDirection_update(deltaTime) {
position : avatarPos
};
Entities.editEntity(avatarToWorldDirectionTest_lineEntity, newProperties);
Entities.editEntity(jointToWorldDirectionTest_lineEntity, newProperties);
}
//avatarToWorldRotation
//jointToWorldRotation
// create box in world space
// each frame calculate world space rotation of players head
// update box rotation to match
var avatarToWorldRotationTest_boxEntity;
function avatarToWorldRotationTest() {
var jointToWorldRotationTest_boxEntity;
function jointToWorldRotationTest() {
var jointIndex = MyAvatar.getJointIndex("Head");
var jointPosition_WorldSpace = MyAvatar.getJointPosition(jointIndex);
var jointRot = MyAvatar.getJointRotation(jointIndex);
var jointRot_WorldSpace = MyAvatar.avatarToWorldRotation(jointRot, jointIndex);
var jointRot_WorldSpace = MyAvatar.jointToWorldRotation(jointRot, jointIndex);
var boxProps = Object.create(debugBoxBaseProperties);
boxProps.name = "avatarToWorldRotationTest_Box";
boxProps.name = "jointToWorldRotationTest_Box";
boxProps.color = { blue: 250, green: 250, red: 250 };
boxProps.position = jointPosition_WorldSpace;
boxProps.rotation = jointRot_WorldSpace;
avatarToWorldRotationTest_boxEntity = Entities.addEntity(boxProps);
jointToWorldRotationTest_boxEntity = Entities.addEntity(boxProps);
}
function avatarToWorldRotationTest_update(deltaTime) {
function jointToWorldRotationTest_update(deltaTime) {
var jointIndex = MyAvatar.getJointIndex("Head");
var jointPosition_WorldSpace = MyAvatar.getJointPosition(jointIndex);
var jointRot = MyAvatar.getJointRotation(jointIndex);
var jointRot_WorldSpace = MyAvatar.avatarToWorldRotation(jointRot, jointIndex);
var jointRot_WorldSpace = MyAvatar.jointToWorldRotation(jointRot, jointIndex);
var newProperties = { position: jointPosition_WorldSpace, rotation: jointRot_WorldSpace };
Entities.editEntity(avatarToWorldRotationTest_boxEntity, newProperties);
Entities.editEntity(jointToWorldRotationTest_boxEntity, newProperties);
}
avatarToWorldPointTest();
Script.update.connect(avatarToWorldPointTest_update);
jointToWorldPointTest();
Script.update.connect(jointToWorldPointTest_update);
avatarToWorldDirectionTest();
Script.update.connect(avatarToWorldDirection_update);
jointToWorldDirectionTest();
Script.update.connect(jointToWorldDirection_update);
avatarToWorldRotationTest();
Script.update.connect(avatarToWorldRotationTest_update);
jointToWorldRotationTest();
Script.update.connect(jointToWorldRotationTest_update);

View file

@ -20,22 +20,22 @@ var debugBoxBaseProperties = {
userData: "{ \"grabbableKey\": { \"grabbable\": false, \"kinematic\": false } }"
};
//worldToAvatarPoint
//worldToJointPoint
// calculate position offset from joint using getJointPosition
// pass through worldToAvatarPoint to get offset in joint space of players joint
// pass through worldToJointPoint to get offset in joint space of players joint
// create a blue sphere and attach it to players joint using the joint space offset
// The two spheres should appear in the same place, but the blue sphere will follow the avatar
function worldToAvatarPointTest() {
function worldToJointPointTest() {
var jointIndex = MyAvatar.getJointIndex("LeftHandPinky4");
var avatarPos = MyAvatar.position;
var jointPosition_WorldSpace = MyAvatar.getJointPosition(jointIndex);
var jointOffset_WorldSpace = { x: 0.1, y: 0, z: 0 };
var jointPosition_WorldSpaceOffset = Vec3.sum(jointPosition_WorldSpace, jointOffset_WorldSpace);
var jointPosition_JointSpaceOffset = MyAvatar.worldToAvatarPoint(jointPosition_WorldSpaceOffset, jointIndex);
var jointPosition_JointSpaceOffset = MyAvatar.worldToJointPoint(jointPosition_WorldSpaceOffset, jointIndex);
var jointSphereProps = Object.create(debugSphereBaseProperties);
jointSphereProps.name = "worldToAvatarPointTest_Joint";
jointSphereProps.name = "worldToJointPointTest_Joint";
jointSphereProps.color = { blue: 240, green: 150, red: 150 };
jointSphereProps.localPosition = jointPosition_JointSpaceOffset;
jointSphereProps.parentID = AVATAR_SELF_ID;
@ -43,29 +43,29 @@ function worldToAvatarPointTest() {
Entities.addEntity(jointSphereProps);
var worldSphereProps = Object.create(debugSphereBaseProperties);
worldSphereProps.name = "worldToAvatarPointTest_World";
worldSphereProps.name = "worldToJointPointTest_World";
worldSphereProps.color = { blue: 150, green: 250, red: 150 };
worldSphereProps.position = jointPosition_WorldSpaceOffset;
Entities.addEntity(worldSphereProps);
}
//worldToAvatarDirection
//worldToJointDirection
// create line and attach to avatars head
// each frame calculate direction of world x axis in joint space of players head
// update arrow orientation to match
var worldToAvatarDirectionTest_lineEntity;
function worldToAvatarDirectionTest() {
var worldToJointDirectionTest_lineEntity;
function worldToJointDirectionTest() {
var jointIndex = MyAvatar.getJointIndex("Head");
var jointPosition_WorldSpace = MyAvatar.getJointPosition(jointIndex);
var jointOffset_WorldSpace = { x: 0, y: 0, z: 0 };
var jointPosition_WorldSpaceOffset = Vec3.sum(jointPosition_WorldSpace, jointOffset_WorldSpace);
var jointPosition_JointSpaceOffset = MyAvatar.worldToAvatarPoint(jointPosition_WorldSpaceOffset, jointIndex);
var jointPosition_JointSpaceOffset = MyAvatar.worldToJointPoint(jointPosition_WorldSpaceOffset, jointIndex);
var worldDir = { x: 1, y: 0, z: 0 };
var avatarDir = MyAvatar.worldToAvatarDirection(worldDir, jointIndex);
var avatarDir = MyAvatar.worldToJointDirection(worldDir, jointIndex);
worldToAvatarDirectionTest_lineEntity = Entities.addEntity({
worldToJointDirectionTest_lineEntity = Entities.addEntity({
type: "Line",
color: {red: 200, green: 250, blue: 0},
dimensions: {x: 5, y: 5, z: 5},
@ -82,10 +82,10 @@ function worldToAvatarDirectionTest() {
});
}
function worldToAvatarDirectionTest_update(deltaTime) {
function worldToJointDirectionTest_update(deltaTime) {
var jointIndex = MyAvatar.getJointIndex("Head");
var worldDir = { x: 1, y: 0, z: 0 };
var avatarDir = MyAvatar.worldToAvatarDirection(worldDir, jointIndex);
var avatarDir = MyAvatar.worldToJointDirection(worldDir, jointIndex);
var newProperties = { linePoints: [{
x: 0,
y: 0,
@ -93,42 +93,42 @@ function worldToAvatarDirectionTest_update(deltaTime) {
}, avatarDir
]};
Entities.editEntity(worldToAvatarDirectionTest_lineEntity, newProperties);
Entities.editEntity(worldToJointDirectionTest_lineEntity, newProperties);
}
//worldToAvatarRotation
//worldToJointRotation
// create box and parent to some player joint
// convert world identity rotation to joint space rotation
// each frame, update box with new orientation
var worldToAvatarRotationTest_boxEntity;
function worldToAvatarRotationTest() {
var worldToJointRotationTest_boxEntity;
function worldToJointRotationTest() {
var jointIndex = MyAvatar.getJointIndex("RightHandPinky4");
var avatarPos = MyAvatar.position;
var jointPosition_WorldSpace = MyAvatar.getJointPosition(jointIndex);
var jointOffset_WorldSpace = { x: 0.0, y: 0, z: 0 };
var jointPosition_WorldSpaceOffset = Vec3.sum(jointPosition_WorldSpace, jointOffset_WorldSpace);
var jointPosition_JointSpaceOffset = MyAvatar.worldToAvatarPoint(jointPosition_WorldSpaceOffset, jointIndex);
var jointPosition_JointSpaceOffset = MyAvatar.worldToJointPoint(jointPosition_WorldSpaceOffset, jointIndex);
var jointBoxProps = Object.create(debugBoxBaseProperties);
jointBoxProps.name = "worldToAvatarRotationTest_Box";
jointBoxProps.name = "worldToJointRotationTest_Box";
jointBoxProps.color = { blue: 0, green: 0, red: 250 };
jointBoxProps.localPosition = jointPosition_JointSpaceOffset;
jointBoxProps.parentID = AVATAR_SELF_ID;
jointBoxProps.parentJointIndex = jointIndex;
worldToAvatarRotationTest_boxEntity = Entities.addEntity(jointBoxProps);
worldToJointRotationTest_boxEntity = Entities.addEntity(jointBoxProps);
}
function worldToAvatarRotationTest_update(deltaTime) {
function worldToJointRotationTest_update(deltaTime) {
var jointIndex = MyAvatar.getJointIndex("RightHandPinky4");
var worldRot = Quat.fromPitchYawRollDegrees(0,0,0);
var avatarRot = MyAvatar.worldToAvatarRotation(worldRot, jointIndex);
var avatarRot = MyAvatar.worldToJointRotation(worldRot, jointIndex);
var newProperties = { localRotation: avatarRot };
Entities.editEntity(worldToAvatarRotationTest_boxEntity, newProperties);
Entities.editEntity(worldToJointRotationTest_boxEntity, newProperties);
}
worldToAvatarPointTest();
worldToAvatarDirectionTest();
worldToAvatarRotationTest();
worldToJointPointTest();
worldToJointDirectionTest();
worldToJointRotationTest();
Script.update.connect(worldToAvatarDirectionTest_update);
Script.update.connect(worldToAvatarRotationTest_update);
Script.update.connect(worldToJointDirectionTest_update);
Script.update.connect(worldToJointRotationTest_update);