mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 15:43:50 +02:00
Basic joint data sending. Closes #2166.
This commit is contained in:
parent
8ec7a5e600
commit
3adea84b81
8 changed files with 107 additions and 2 deletions
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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) *
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__) */
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue