mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 07:23:00 +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);
|
getHand()->simulate(deltaTime, false);
|
||||||
_skeletonModel.setLODDistance(getLODDistance());
|
_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;
|
glm::vec3 headPosition = _position;
|
||||||
if (!_shouldRenderBillboard) {
|
if (!_shouldRenderBillboard) {
|
||||||
_skeletonModel.simulate(deltaTime);
|
_skeletonModel.simulate(deltaTime);
|
||||||
|
|
|
@ -307,6 +307,13 @@ void MyAvatar::simulate(float deltaTime) {
|
||||||
|
|
||||||
_skeletonModel.simulate(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();
|
Head* head = getHead();
|
||||||
glm::vec3 headPosition;
|
glm::vec3 headPosition;
|
||||||
if (!_skeletonModel.getHeadPosition(headPosition)) {
|
if (!_skeletonModel.getHeadPosition(headPosition)) {
|
||||||
|
|
|
@ -30,6 +30,10 @@ void SkeletonModel::simulate(float deltaTime, bool delayLoad) {
|
||||||
|
|
||||||
Model::simulate(deltaTime, delayLoad);
|
Model::simulate(deltaTime, delayLoad);
|
||||||
|
|
||||||
|
if (!_owningAvatar->isMyAvatar()) {
|
||||||
|
return; // only simulate for own avatar
|
||||||
|
}
|
||||||
|
|
||||||
// find the left and rightmost active Leap palms
|
// find the left and rightmost active Leap palms
|
||||||
int leftPalmIndex, rightPalmIndex;
|
int leftPalmIndex, rightPalmIndex;
|
||||||
Hand* hand = _owningAvatar->getHand();
|
Hand* hand = _owningAvatar->getHand();
|
||||||
|
@ -188,6 +192,9 @@ void SkeletonModel::updateJointState(int index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonModel::maybeUpdateLeanRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) {
|
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
|
// get the rotation axes in joint space and use them to adjust the rotation
|
||||||
glm::mat3 axes = glm::mat3_cast(_rotation);
|
glm::mat3 axes = glm::mat3_cast(_rotation);
|
||||||
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform * glm::translate(state.translation) *
|
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform * glm::translate(state.translation) *
|
||||||
|
|
|
@ -373,6 +373,24 @@ Extents Model::getStaticExtents() const {
|
||||||
return scaledExtents;
|
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 {
|
int Model::getParentJointIndex(int jointIndex) const {
|
||||||
return (isActive() && jointIndex != -1) ? _geometry->getFBXGeometry().joints.at(jointIndex).parentIndex : -1;
|
return (isActive() && jointIndex != -1) ? _geometry->getFBXGeometry().joints.at(jointIndex).parentIndex : -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,16 @@ public:
|
||||||
/// Returns a reference to the shared geometry.
|
/// Returns a reference to the shared geometry.
|
||||||
const QSharedPointer<NetworkGeometry>& getGeometry() const { return _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.
|
/// Returns the index of the left hand joint, or -1 if not found.
|
||||||
int getLeftHandJointIndex() const { return isActive() ? _geometry->getFBXGeometry().leftHandJointIndex : -1; }
|
int getLeftHandJointIndex() const { return isActive() ? _geometry->getFBXGeometry().leftHandJointIndex : -1; }
|
||||||
|
|
||||||
|
|
|
@ -156,10 +156,32 @@ QByteArray AvatarData::toByteArray() {
|
||||||
|
|
||||||
// pupil dilation
|
// pupil dilation
|
||||||
destinationBuffer += packFloatToByte(destinationBuffer, _headData->_pupilDilation, 1.0f);
|
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
|
// hand data
|
||||||
destinationBuffer += HandData::encodeData(_handData, destinationBuffer);
|
destinationBuffer += HandData::encodeData(_handData, destinationBuffer);
|
||||||
|
|
||||||
return avatarDataByteArray.left(destinationBuffer - startPosition);
|
return avatarDataByteArray.left(destinationBuffer - startPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,6 +286,25 @@ int AvatarData::parseData(const QByteArray& packet) {
|
||||||
// pupil dilation
|
// pupil dilation
|
||||||
sourceBuffer += unpackFloatFromByte(sourceBuffer, _headData->_pupilDilation, 1.0f);
|
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
|
// hand data
|
||||||
if (sourceBuffer - startPosition < packet.size()) {
|
if (sourceBuffer - startPosition < packet.size()) {
|
||||||
// check passed, bytes match
|
// check passed, bytes match
|
||||||
|
|
|
@ -33,6 +33,7 @@ typedef unsigned long long quint64;
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <QtCore/QUrl>
|
#include <QtCore/QUrl>
|
||||||
#include <QtCore/QUuid>
|
#include <QtCore/QUuid>
|
||||||
|
#include <QtCore/QVector>
|
||||||
#include <QtCore/QVariantMap>
|
#include <QtCore/QVariantMap>
|
||||||
#include <QRect>
|
#include <QRect>
|
||||||
|
|
||||||
|
@ -70,6 +71,8 @@ const glm::vec3 vec3Zero(0.0f);
|
||||||
|
|
||||||
class QNetworkAccessManager;
|
class QNetworkAccessManager;
|
||||||
|
|
||||||
|
class JointData;
|
||||||
|
|
||||||
class AvatarData : public NodeData {
|
class AvatarData : public NodeData {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -137,6 +140,9 @@ public:
|
||||||
void setHandState(char s) { _handState = s; }
|
void setHandState(char s) { _handState = s; }
|
||||||
char getHandState() const { return _handState; }
|
char getHandState() const { return _handState; }
|
||||||
|
|
||||||
|
const QVector<JointData>& getJointData() const { return _jointData; }
|
||||||
|
void setJointData(const QVector<JointData>& jointData) { _jointData = jointData; }
|
||||||
|
|
||||||
// key state
|
// key state
|
||||||
void setKeyState(KeyState s) { _keyState = s; }
|
void setKeyState(KeyState s) { _keyState = s; }
|
||||||
KeyState keyState() const { return _keyState; }
|
KeyState keyState() const { return _keyState; }
|
||||||
|
@ -205,6 +211,8 @@ protected:
|
||||||
// Hand state (are we grabbing something or not)
|
// Hand state (are we grabbing something or not)
|
||||||
char _handState;
|
char _handState;
|
||||||
|
|
||||||
|
QVector<JointData> _jointData; ///< the state of the skeleton joints
|
||||||
|
|
||||||
// key state
|
// key state
|
||||||
KeyState _keyState;
|
KeyState _keyState;
|
||||||
|
|
||||||
|
@ -235,4 +243,10 @@ private:
|
||||||
AvatarData& operator= (const AvatarData&);
|
AvatarData& operator= (const AvatarData&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class JointData {
|
||||||
|
public:
|
||||||
|
bool valid;
|
||||||
|
glm::quat rotation;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__AvatarData__) */
|
#endif /* defined(__hifi__AvatarData__) */
|
||||||
|
|
|
@ -44,6 +44,8 @@ int packArithmeticallyCodedValue(int value, char* destination) {
|
||||||
|
|
||||||
PacketVersion versionForPacketType(PacketType type) {
|
PacketVersion versionForPacketType(PacketType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
PacketTypeAvatarData:
|
||||||
|
return 1;
|
||||||
case PacketTypeParticleData:
|
case PacketTypeParticleData:
|
||||||
return 1;
|
return 1;
|
||||||
case PacketTypeDomainList:
|
case PacketTypeDomainList:
|
||||||
|
|
Loading…
Reference in a new issue