Basic joint data sending. Closes #2166.

This commit is contained in:
Andrzej Kapolka 2014-03-06 17:07:29 -08:00
parent 8ec7a5e600
commit 3adea84b81
8 changed files with 107 additions and 2 deletions

View file

@ -136,6 +136,12 @@ void Avatar::simulate(float deltaTime) {
getHand()->simulate(deltaTime, false);
_skeletonModel.setLODDistance(getLODDistance());
// copy joint data to skeleton
for (int i = 0; i < _jointData.size(); i++) {
const JointData& data = _jointData.at(i);
_skeletonModel.setJointState(i, data.valid, data.rotation);
}
glm::vec3 headPosition = _position;
if (!_shouldRenderBillboard) {
_skeletonModel.simulate(deltaTime);

View file

@ -307,6 +307,13 @@ void MyAvatar::simulate(float deltaTime) {
_skeletonModel.simulate(deltaTime);
// copy out the skeleton joints from the model
_jointData.resize(_skeletonModel.getJointStateCount());
for (int i = 0; i < _jointData.size(); i++) {
JointData& data = _jointData[i];
data.valid = _skeletonModel.getJointState(i, data.rotation);
}
Head* head = getHead();
glm::vec3 headPosition;
if (!_skeletonModel.getHeadPosition(headPosition)) {

View file

@ -30,6 +30,10 @@ void SkeletonModel::simulate(float deltaTime, bool delayLoad) {
Model::simulate(deltaTime, delayLoad);
if (!_owningAvatar->isMyAvatar()) {
return; // only simulate for own avatar
}
// find the left and rightmost active Leap palms
int leftPalmIndex, rightPalmIndex;
Hand* hand = _owningAvatar->getHand();
@ -188,6 +192,9 @@ void SkeletonModel::updateJointState(int index) {
}
void SkeletonModel::maybeUpdateLeanRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) {
if (!_owningAvatar->isMyAvatar()) {
return;
}
// get the rotation axes in joint space and use them to adjust the rotation
glm::mat3 axes = glm::mat3_cast(_rotation);
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform * glm::translate(state.translation) *

View file

@ -373,6 +373,24 @@ Extents Model::getStaticExtents() const {
return scaledExtents;
}
bool Model::getJointState(int index, glm::quat& rotation) const {
if (index >= _jointStates.size()) {
return false;
}
rotation = _jointStates.at(index).rotation;
const glm::quat& defaultRotation = _geometry->getFBXGeometry().joints.at(index).rotation;
return glm::abs(rotation.x - defaultRotation.x) >= EPSILON ||
glm::abs(rotation.y - defaultRotation.y) >= EPSILON ||
glm::abs(rotation.z - defaultRotation.z) >= EPSILON ||
glm::abs(rotation.w - defaultRotation.w) >= EPSILON;
}
void Model::setJointState(int index, bool valid, const glm::quat& rotation) {
if (index < _jointStates.size()) {
_jointStates[index].rotation = valid ? rotation : _geometry->getFBXGeometry().joints.at(index).rotation;
}
}
int Model::getParentJointIndex(int jointIndex) const {
return (isActive() && jointIndex != -1) ? _geometry->getFBXGeometry().joints.at(jointIndex).parentIndex : -1;
}

View file

@ -81,6 +81,16 @@ public:
/// Returns a reference to the shared geometry.
const QSharedPointer<NetworkGeometry>& getGeometry() const { return _geometry; }
/// Returns the number of joint states in the model.
int getJointStateCount() const { return _jointStates.size(); }
/// Fetches the joint state at the specified index.
/// \return whether or not the joint state is "valid" (that is, non-default)
bool getJointState(int index, glm::quat& rotation) const;
/// Sets the joint state at the specified index.
void setJointState(int index, bool valid, const glm::quat& rotation);
/// Returns the index of the left hand joint, or -1 if not found.
int getLeftHandJointIndex() const { return isActive() ? _geometry->getFBXGeometry().leftHandJointIndex : -1; }

View file

@ -156,10 +156,32 @@ QByteArray AvatarData::toByteArray() {
// pupil dilation
destinationBuffer += packFloatToByte(destinationBuffer, _headData->_pupilDilation, 1.0f);
// joint data
*destinationBuffer++ = _jointData.size();
unsigned char validity = 0;
int validityBit = 0;
foreach (const JointData& data, _jointData) {
if (data.valid) {
validity |= (1 << validityBit);
}
if (++validityBit == BITS_IN_BYTE) {
*destinationBuffer++ = validity;
validityBit = validity = 0;
}
}
if (validityBit != 0) {
*destinationBuffer++ = validity;
}
foreach (const JointData& data, _jointData) {
if (data.valid) {
destinationBuffer += packOrientationQuatToBytes(destinationBuffer, data.rotation);
}
}
// hand data
destinationBuffer += HandData::encodeData(_handData, destinationBuffer);
return avatarDataByteArray.left(destinationBuffer - startPosition);
}
@ -264,6 +286,25 @@ int AvatarData::parseData(const QByteArray& packet) {
// pupil dilation
sourceBuffer += unpackFloatFromByte(sourceBuffer, _headData->_pupilDilation, 1.0f);
// joint data
int jointCount = *sourceBuffer++;
_jointData.resize(jointCount);
unsigned char validity;
int validityBit = 0;
for (int i = 0; i < jointCount; i++) {
if (validityBit == 0) {
validity = *sourceBuffer++;
}
_jointData[i].valid = validity & (1 << validityBit);
validityBit = (validityBit + 1) % BITS_IN_BYTE;
}
for (int i = 0; i < jointCount; i++) {
JointData& data = _jointData[i];
if (data.valid) {
sourceBuffer += unpackOrientationQuatFromBytes(sourceBuffer, data.rotation);
}
}
// hand data
if (sourceBuffer - startPosition < packet.size()) {
// check passed, bytes match

View file

@ -33,6 +33,7 @@ typedef unsigned long long quint64;
#include <QtCore/QObject>
#include <QtCore/QUrl>
#include <QtCore/QUuid>
#include <QtCore/QVector>
#include <QtCore/QVariantMap>
#include <QRect>
@ -70,6 +71,8 @@ const glm::vec3 vec3Zero(0.0f);
class QNetworkAccessManager;
class JointData;
class AvatarData : public NodeData {
Q_OBJECT
@ -137,6 +140,9 @@ public:
void setHandState(char s) { _handState = s; }
char getHandState() const { return _handState; }
const QVector<JointData>& getJointData() const { return _jointData; }
void setJointData(const QVector<JointData>& jointData) { _jointData = jointData; }
// key state
void setKeyState(KeyState s) { _keyState = s; }
KeyState keyState() const { return _keyState; }
@ -205,6 +211,8 @@ protected:
// Hand state (are we grabbing something or not)
char _handState;
QVector<JointData> _jointData; ///< the state of the skeleton joints
// key state
KeyState _keyState;
@ -235,4 +243,10 @@ private:
AvatarData& operator= (const AvatarData&);
};
class JointData {
public:
bool valid;
glm::quat rotation;
};
#endif /* defined(__hifi__AvatarData__) */

View file

@ -44,6 +44,8 @@ int packArithmeticallyCodedValue(int value, char* destination) {
PacketVersion versionForPacketType(PacketType type) {
switch (type) {
PacketTypeAvatarData:
return 1;
case PacketTypeParticleData:
return 1;
case PacketTypeDomainList: