Merge pull request #1595 from ey6es/master

Fix hand jerkiness when flying (by always keeping the hand positions relative to the body orientation/position).
This commit is contained in:
Philip Rosedale 2014-01-20 14:50:20 -08:00
commit 19793a9a4a
9 changed files with 37 additions and 28 deletions

View file

@ -124,10 +124,6 @@ glm::vec3 Avatar::getChestPosition() const {
return _skeletonModel.getNeckPosition(neckPosition) ? (_position + neckPosition) * 0.5f : _position; return _skeletonModel.getNeckPosition(neckPosition) ? (_position + neckPosition) * 0.5f : _position;
} }
glm::quat Avatar::getOrientation() const {
return glm::quat(glm::radians(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll)));
}
glm::quat Avatar::getWorldAlignedOrientation () const { glm::quat Avatar::getWorldAlignedOrientation () const {
return computeRotationFromBodyToWorldUp() * getOrientation(); return computeRotationFromBodyToWorldUp() * getOrientation();
} }

View file

@ -92,7 +92,6 @@ public:
const glm::vec3& getVelocity() const { return _velocity; } const glm::vec3& getVelocity() const { return _velocity; }
Head& getHead() { return _head; } Head& getHead() { return _head; }
Hand& getHand() { return _hand; } Hand& getHand() { return _hand; }
glm::quat getOrientation() const;
glm::quat getWorldAlignedOrientation() const; glm::quat getWorldAlignedOrientation() const;
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const; bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const;

View file

@ -262,15 +262,6 @@ void Hand::simulate(float deltaTime, bool isMine) {
if (isMine) { if (isMine) {
_buckyBalls.simulate(deltaTime); _buckyBalls.simulate(deltaTime);
}
const glm::vec3 leapHandsOffsetFromFace(0.0, -0.2, -0.3); // place the hand in front of the face where we can see it
Head& head = _owningAvatar->getHead();
_baseOrientation = _owningAvatar->getOrientation();
_basePosition = head.calculateAverageEyePosition() + _baseOrientation * leapHandsOffsetFromFace * head.getScale();
if (isMine) {
updateCollisions(); updateCollisions();
} }
@ -465,7 +456,7 @@ void Hand::calculateGeometry() {
const float standardBallRadius = FINGERTIP_COLLISION_RADIUS; const float standardBallRadius = FINGERTIP_COLLISION_RADIUS;
_leapFingerTipBalls.resize(_leapFingerTipBalls.size() + 1); _leapFingerTipBalls.resize(_leapFingerTipBalls.size() + 1);
HandBall& ball = _leapFingerTipBalls.back(); HandBall& ball = _leapFingerTipBalls.back();
ball.rotation = _baseOrientation; ball.rotation = getBaseOrientation();
ball.position = finger.getTipPosition(); ball.position = finger.getTipPosition();
ball.radius = standardBallRadius; ball.radius = standardBallRadius;
ball.touchForce = 0.0; ball.touchForce = 0.0;
@ -487,7 +478,7 @@ void Hand::calculateGeometry() {
const float standardBallRadius = 0.005f; const float standardBallRadius = 0.005f;
_leapFingerRootBalls.resize(_leapFingerRootBalls.size() + 1); _leapFingerRootBalls.resize(_leapFingerRootBalls.size() + 1);
HandBall& ball = _leapFingerRootBalls.back(); HandBall& ball = _leapFingerRootBalls.back();
ball.rotation = _baseOrientation; ball.rotation = getBaseOrientation();
ball.position = finger.getRootPosition(); ball.position = finger.getRootPosition();
ball.radius = standardBallRadius; ball.radius = standardBallRadius;
ball.touchForce = 0.0; ball.touchForce = 0.0;

View file

@ -798,7 +798,10 @@ bool Model::restoreJointPosition(int jointIndex, float percent) {
const QVector<int>& freeLineage = geometry.joints.at(jointIndex).freeLineage; const QVector<int>& freeLineage = geometry.joints.at(jointIndex).freeLineage;
foreach (int index, freeLineage) { foreach (int index, freeLineage) {
_jointStates[index].rotation = safeMix(_jointStates[index].rotation, geometry.joints.at(index).rotation, percent); JointState& state = _jointStates[index];
const FBXJoint& joint = geometry.joints.at(index);
state.rotation = safeMix(state.rotation, joint.rotation, percent);
state.translation = glm::mix(state.translation, joint.translation, percent);
} }
return true; return true;
} }

View file

@ -44,6 +44,15 @@ AvatarData::~AvatarData() {
delete _handData; delete _handData;
} }
glm::vec3 AvatarData::getHandPosition() const {
return getOrientation() * _handPosition + _position;
}
void AvatarData::setHandPosition(const glm::vec3& handPosition) {
// store relative to position/orientation
_handPosition = glm::inverse(getOrientation()) * (handPosition - _position);
}
int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
unsigned char* bufferStart = destinationBuffer; unsigned char* bufferStart = destinationBuffer;

View file

@ -76,8 +76,8 @@ public:
const glm::vec3& getPosition() const { return _position; } const glm::vec3& getPosition() const { return _position; }
void setPosition(const glm::vec3 position) { _position = position; } void setPosition(const glm::vec3 position) { _position = position; }
const glm::vec3& getHandPosition() const { return _handPosition; } glm::vec3 getHandPosition() const;
void setHandPosition(const glm::vec3 handPosition) { _handPosition = handPosition; } void setHandPosition(const glm::vec3& handPosition);
int getBroadcastData(unsigned char* destinationBuffer); int getBroadcastData(unsigned char* destinationBuffer);
int parseData(unsigned char* sourceBuffer, int numBytes); int parseData(unsigned char* sourceBuffer, int numBytes);
@ -93,6 +93,8 @@ public:
float getBodyRoll() const { return _bodyRoll; } float getBodyRoll() const { return _bodyRoll; }
void setBodyRoll(float bodyRoll) { _bodyRoll = bodyRoll; } void setBodyRoll(float bodyRoll) { _bodyRoll = bodyRoll; }
glm::quat getOrientation() const { return glm::quat(glm::radians(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll))); }
// Scale // Scale
float getTargetScale() const { return _targetScale; } float getTargetScale() const { return _targetScale; }
void setTargetScale(float targetScale) { _targetScale = targetScale; } void setTargetScale(float targetScale) { _targetScale = targetScale; }

View file

@ -16,8 +16,6 @@
const int fingerVectorRadix = 4; const int fingerVectorRadix = 4;
HandData::HandData(AvatarData* owningAvatar) : HandData::HandData(AvatarData* owningAvatar) :
_basePosition(0.0f, 0.0f, 0.0f),
_baseOrientation(0.0f, 0.0f, 0.0f, 1.0f),
_owningAvatarData(owningAvatar) _owningAvatarData(owningAvatar)
{ {
// Start with two palms // Start with two palms
@ -26,11 +24,11 @@ HandData::HandData(AvatarData* owningAvatar) :
} }
glm::vec3 HandData::worldPositionToLeapPosition(const glm::vec3& worldPosition) const { glm::vec3 HandData::worldPositionToLeapPosition(const glm::vec3& worldPosition) const {
return glm::inverse(_baseOrientation) * (worldPosition - _basePosition) / LEAP_UNIT_SCALE; return glm::inverse(getBaseOrientation()) * (worldPosition - getBasePosition()) / LEAP_UNIT_SCALE;
} }
glm::vec3 HandData::worldVectorToLeapVector(const glm::vec3& worldVector) const { glm::vec3 HandData::worldVectorToLeapVector(const glm::vec3& worldVector) const {
return glm::inverse(_baseOrientation) * worldVector / LEAP_UNIT_SCALE; return glm::inverse(getBaseOrientation()) * worldVector / LEAP_UNIT_SCALE;
} }
PalmData& HandData::addNewPalm() { PalmData& HandData::addNewPalm() {
@ -254,6 +252,15 @@ bool HandData::findSpherePenetration(const glm::vec3& penetratorCenter, float pe
return false; return false;
} }
glm::quat HandData::getBaseOrientation() const {
return _owningAvatarData->getOrientation();
}
glm::vec3 HandData::getBasePosition() const {
const glm::vec3 LEAP_HANDS_OFFSET_FROM_TORSO(0.0, 0.3, -0.3);
return _owningAvatarData->getPosition() + getBaseOrientation() * LEAP_HANDS_OFFSET_FROM_TORSO *
_owningAvatarData->getTargetScale();
}
void FingerData::setTrailLength(unsigned int length) { void FingerData::setTrailLength(unsigned int length) {
_tipTrailPositions.resize(length); _tipTrailPositions.resize(length);

View file

@ -50,10 +50,10 @@ public:
// position conversion // position conversion
glm::vec3 leapPositionToWorldPosition(const glm::vec3& leapPosition) { glm::vec3 leapPositionToWorldPosition(const glm::vec3& leapPosition) {
return _basePosition + _baseOrientation * (leapPosition * LEAP_UNIT_SCALE); return getBasePosition() + getBaseOrientation() * (leapPosition * LEAP_UNIT_SCALE);
} }
glm::vec3 leapDirectionToWorldDirection(const glm::vec3& leapDirection) { glm::vec3 leapDirectionToWorldDirection(const glm::vec3& leapDirection) {
return _baseOrientation * leapDirection; return getBaseOrientation() * leapDirection;
} }
glm::vec3 worldPositionToLeapPosition(const glm::vec3& worldPosition) const; glm::vec3 worldPositionToLeapPosition(const glm::vec3& worldPosition) const;
glm::vec3 worldVectorToLeapVector(const glm::vec3& worldVector) const; glm::vec3 worldVectorToLeapVector(const glm::vec3& worldVector) const;
@ -86,10 +86,12 @@ public:
friend class AvatarData; friend class AvatarData;
protected: protected:
glm::vec3 _basePosition; // Hands are placed relative to this
glm::quat _baseOrientation; // Hands are placed relative to this
AvatarData* _owningAvatarData; AvatarData* _owningAvatarData;
std::vector<PalmData> _palms; std::vector<PalmData> _palms;
glm::quat getBaseOrientation() const;
glm::vec3 getBasePosition() const;
private: private:
// privatize copy ctor and assignment operator so copies of this object cannot be made // privatize copy ctor and assignment operator so copies of this object cannot be made
HandData(const HandData&); HandData(const HandData&);

View file

@ -20,7 +20,7 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type) {
return 2; return 2;
case PACKET_TYPE_HEAD_DATA: case PACKET_TYPE_HEAD_DATA:
return 14; return 15;
case PACKET_TYPE_AVATAR_URLS: case PACKET_TYPE_AVATAR_URLS:
return 2; return 2;