mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 19:53:29 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into smooth-faded-animations
This commit is contained in:
commit
2f2b59b6b6
18 changed files with 230 additions and 80 deletions
interface
resources/meshes
src
libraries
64
interface/resources/meshes/defaultAvatar_full.fst
Normal file
64
interface/resources/meshes/defaultAvatar_full.fst
Normal file
|
@ -0,0 +1,64 @@
|
|||
name = defaultAvatar_full
|
||||
type = body+head
|
||||
scale = 1
|
||||
filename = defaultAvatar_full/defaultAvatar_full.fbx
|
||||
texdir = defaultAvatar_full/textures
|
||||
joint = jointNeck = Head
|
||||
joint = jointLeftHand = LeftHand
|
||||
joint = jointRoot = Hips
|
||||
joint = jointHead = HeadTop_End
|
||||
joint = jointRightHand = RightHand
|
||||
joint = jointLean = Spine
|
||||
freeJoint = LeftArm
|
||||
freeJoint = LeftForeArm
|
||||
freeJoint = RightArm
|
||||
freeJoint = RightForeArm
|
||||
jointIndex = LeftHand = 35
|
||||
jointIndex = Reye = 3
|
||||
jointIndex = Hips = 10
|
||||
jointIndex = LeftHandIndex1 = 36
|
||||
jointIndex = LeftHandIndex2 = 37
|
||||
jointIndex = LeftHandIndex3 = 38
|
||||
jointIndex = LeftHandIndex4 = 39
|
||||
jointIndex = LeftShoulder = 32
|
||||
jointIndex = RightLeg = 12
|
||||
jointIndex = Grp_blendshapes = 0
|
||||
jointIndex = Leye = 4
|
||||
jointIndex = headphone = 8
|
||||
jointIndex = RightForeArm = 26
|
||||
jointIndex = Spine = 21
|
||||
jointIndex = LeftFoot = 18
|
||||
jointIndex = RightToeBase = 14
|
||||
jointIndex = face = 1
|
||||
jointIndex = LeftToe_End = 20
|
||||
jointIndex = Spine1 = 22
|
||||
jointIndex = body = 9
|
||||
jointIndex = Spine2 = 23
|
||||
jointIndex = RightUpLeg = 11
|
||||
jointIndex = top1 = 7
|
||||
jointIndex = Neck = 40
|
||||
jointIndex = HeadTop_End = 42
|
||||
jointIndex = RightShoulder = 24
|
||||
jointIndex = RightArm = 25
|
||||
jointIndex = Head = 41
|
||||
jointIndex = LeftLeg = 17
|
||||
jointIndex = LeftForeArm = 34
|
||||
jointIndex = hair = 6
|
||||
jointIndex = RightHand = 27
|
||||
jointIndex = LeftToeBase = 19
|
||||
jointIndex = LeftUpLeg = 16
|
||||
jointIndex = mouth = 2
|
||||
jointIndex = RightFoot = 13
|
||||
jointIndex = LeftArm = 33
|
||||
jointIndex = shield = 5
|
||||
jointIndex = RightHandIndex1 = 28
|
||||
jointIndex = RightHandIndex2 = 29
|
||||
jointIndex = RightToe_End = 15
|
||||
jointIndex = RightHandIndex3 = 30
|
||||
jointIndex = RightHandIndex4 = 31
|
||||
ry = 0
|
||||
rz = 0
|
||||
tx = 0
|
||||
ty = 0
|
||||
tz = 0
|
||||
rx = 0
|
Binary file not shown.
BIN
interface/resources/meshes/defaultAvatar_full/textures/visor.png
Normal file
BIN
interface/resources/meshes/defaultAvatar_full/textures/visor.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 4.6 KiB |
|
@ -2013,6 +2013,7 @@ void Application::setActiveFaceTracker() {
|
|||
#ifdef HAVE_DDE
|
||||
bool isUsingDDE = Menu::getInstance()->isOptionChecked(MenuOption::UseCamera);
|
||||
Menu::getInstance()->getActionForOption(MenuOption::BinaryEyelidControl)->setVisible(isUsingDDE);
|
||||
Menu::getInstance()->getActionForOption(MenuOption::CoupleEyelids)->setVisible(isUsingDDE);
|
||||
Menu::getInstance()->getActionForOption(MenuOption::UseAudioForMouth)->setVisible(isUsingDDE);
|
||||
Menu::getInstance()->getActionForOption(MenuOption::VelocityFilter)->setVisible(isUsingDDE);
|
||||
Menu::getInstance()->getActionForOption(MenuOption::CalibrateCamera)->setVisible(isUsingDDE);
|
||||
|
|
|
@ -421,6 +421,8 @@ Menu::Menu() {
|
|||
faceTrackingMenu->addSeparator();
|
||||
QAction* binaryEyelidControl = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::BinaryEyelidControl, 0, true);
|
||||
binaryEyelidControl->setVisible(true); // DDE face tracking is on by default
|
||||
QAction* coupleEyelids = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::CoupleEyelids, 0, true);
|
||||
coupleEyelids->setVisible(true); // DDE face tracking is on by default
|
||||
QAction* useAudioForMouth = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::UseAudioForMouth, 0, true);
|
||||
useAudioForMouth->setVisible(true); // DDE face tracking is on by default
|
||||
QAction* ddeFiltering = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::VelocityFilter, 0, true);
|
||||
|
|
|
@ -165,6 +165,7 @@ namespace MenuOption {
|
|||
const QString ControlWithSpeech = "Control With Speech";
|
||||
const QString CopyAddress = "Copy Address to Clipboard";
|
||||
const QString CopyPath = "Copy Path to Clipboard";
|
||||
const QString CoupleEyelids = "Couple Eyelids";
|
||||
const QString DebugAmbientOcclusion = "Debug Ambient Occlusion";
|
||||
const QString DecreaseAvatarSize = "Decrease Avatar Size";
|
||||
const QString DeleteBookmark = "Delete Bookmark...";
|
||||
|
|
|
@ -936,8 +936,14 @@ void Avatar::setFaceModelURL(const QUrl& faceModelURL) {
|
|||
|
||||
void Avatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
|
||||
AvatarData::setSkeletonModelURL(skeletonModelURL);
|
||||
const QUrl DEFAULT_FULL_MODEL_URL = QUrl::fromLocalFile(PathUtils::resourcesPath() + "meshes/defaultAvatar_full.fst");
|
||||
const QUrl DEFAULT_SKELETON_MODEL_URL = QUrl::fromLocalFile(PathUtils::resourcesPath() + "meshes/defaultAvatar_body.fst");
|
||||
_skeletonModel.setURL(_skeletonModelURL, DEFAULT_SKELETON_MODEL_URL, true, !isMyAvatar());
|
||||
if (isMyAvatar()) {
|
||||
_skeletonModel.setURL(_skeletonModelURL,
|
||||
getUseFullAvatar() ? DEFAULT_FULL_MODEL_URL : DEFAULT_SKELETON_MODEL_URL, true, !isMyAvatar());
|
||||
} else {
|
||||
_skeletonModel.setURL(_skeletonModelURL, DEFAULT_SKELETON_MODEL_URL, true, !isMyAvatar());
|
||||
}
|
||||
}
|
||||
|
||||
void Avatar::setAttachmentData(const QVector<AttachmentData>& attachmentData) {
|
||||
|
|
|
@ -150,6 +150,7 @@ public:
|
|||
Q_INVOKABLE glm::vec3 getAngularVelocity() const { return _angularVelocity; }
|
||||
Q_INVOKABLE glm::vec3 getAngularAcceleration() const { return _angularAcceleration; }
|
||||
|
||||
virtual bool getUseFullAvatar() const { return false; }
|
||||
|
||||
/// Scales a world space position vector relative to the avatar position and scale
|
||||
/// \param vector position to be scaled. Will store the result
|
||||
|
|
|
@ -116,7 +116,7 @@ public:
|
|||
Q_INVOKABLE void useHeadAndBodyURLs(const QUrl& headURL, const QUrl& bodyURL,
|
||||
const QString& headName = QString(), const QString& bodyName = QString());
|
||||
|
||||
Q_INVOKABLE bool getUseFullAvatar() const { return _useFullAvatar; }
|
||||
Q_INVOKABLE virtual bool getUseFullAvatar() const { return _useFullAvatar; }
|
||||
Q_INVOKABLE const QUrl& getFullAvatarURLFromPreferences() const { return _fullAvatarURLFromPreferences; }
|
||||
Q_INVOKABLE const QUrl& getHeadURLFromPreferences() const { return _headURLFromPreferences; }
|
||||
Q_INVOKABLE const QUrl& getBodyURLFromPreferences() const { return _skeletonURLFromPreferences; }
|
||||
|
|
|
@ -42,7 +42,23 @@ SkeletonModel::~SkeletonModel() {
|
|||
void SkeletonModel::initJointStates(QVector<JointState> states) {
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset;
|
||||
_boundingRadius = _rig->initJointStates(states, parentTransform);
|
||||
|
||||
int rootJointIndex = geometry.rootJointIndex;
|
||||
int leftHandJointIndex = geometry.leftHandJointIndex;
|
||||
int leftElbowJointIndex = leftHandJointIndex >= 0 ? geometry.joints.at(leftHandJointIndex).parentIndex : -1;
|
||||
int leftShoulderJointIndex = leftElbowJointIndex >= 0 ? geometry.joints.at(leftElbowJointIndex).parentIndex : -1;
|
||||
int rightHandJointIndex = geometry.rightHandJointIndex;
|
||||
int rightElbowJointIndex = rightHandJointIndex >= 0 ? geometry.joints.at(rightHandJointIndex).parentIndex : -1;
|
||||
int rightShoulderJointIndex = rightElbowJointIndex >= 0 ? geometry.joints.at(rightElbowJointIndex).parentIndex : -1;
|
||||
|
||||
_boundingRadius = _rig->initJointStates(states, parentTransform,
|
||||
rootJointIndex,
|
||||
leftHandJointIndex,
|
||||
leftElbowJointIndex,
|
||||
leftShoulderJointIndex,
|
||||
rightHandJointIndex,
|
||||
rightElbowJointIndex,
|
||||
rightShoulderJointIndex);
|
||||
|
||||
// Determine the default eye position for avatar scale = 1.0
|
||||
int headJointIndex = _geometry->getFBXGeometry().headJointIndex;
|
||||
|
@ -227,7 +243,7 @@ void SkeletonModel::applyPalmData(int jointIndex, PalmData& palm) {
|
|||
palmRotation = rotationBetween(palmRotation * glm::vec3(-sign, 0.0f, 0.0f), fingerDirection) * palmRotation;
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::AlternateIK)) {
|
||||
setHandPosition(jointIndex, palmPosition, palmRotation);
|
||||
_rig->setHandPosition(jointIndex, palmPosition, palmRotation, extractUniformScale(_scale), PALM_PRIORITY);
|
||||
} else if (Menu::getInstance()->isOptionChecked(MenuOption::AlignForearmsWithWrists)) {
|
||||
float forearmLength = geometry.joints.at(jointIndex).distanceToParent * extractUniformScale(_scale);
|
||||
glm::vec3 forearm = palmRotation * glm::vec3(sign * forearmLength, 0.0f, 0.0f);
|
||||
|
@ -332,69 +348,6 @@ void SkeletonModel::renderOrientationDirections(gpu::Batch& batch, int jointInde
|
|||
geometryCache->renderLine(batch, position, pFront, blue, jointLineIDs._front);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SkeletonModel::setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation) {
|
||||
// this algorithm is from sample code from sixense
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
int elbowJointIndex = geometry.joints.at(jointIndex).parentIndex;
|
||||
if (elbowJointIndex == -1) {
|
||||
return;
|
||||
}
|
||||
int shoulderJointIndex = geometry.joints.at(elbowJointIndex).parentIndex;
|
||||
glm::vec3 shoulderPosition;
|
||||
if (!getJointPosition(shoulderJointIndex, shoulderPosition)) {
|
||||
return;
|
||||
}
|
||||
// precomputed lengths
|
||||
float scale = extractUniformScale(_scale);
|
||||
float upperArmLength = geometry.joints.at(elbowJointIndex).distanceToParent * scale;
|
||||
float lowerArmLength = geometry.joints.at(jointIndex).distanceToParent * scale;
|
||||
|
||||
// first set wrist position
|
||||
glm::vec3 wristPosition = position;
|
||||
|
||||
glm::vec3 shoulderToWrist = wristPosition - shoulderPosition;
|
||||
float distanceToWrist = glm::length(shoulderToWrist);
|
||||
|
||||
// prevent gimbal lock
|
||||
if (distanceToWrist > upperArmLength + lowerArmLength - EPSILON) {
|
||||
distanceToWrist = upperArmLength + lowerArmLength - EPSILON;
|
||||
shoulderToWrist = glm::normalize(shoulderToWrist) * distanceToWrist;
|
||||
wristPosition = shoulderPosition + shoulderToWrist;
|
||||
}
|
||||
|
||||
// cosine of angle from upper arm to hand vector
|
||||
float cosA = (upperArmLength * upperArmLength + distanceToWrist * distanceToWrist - lowerArmLength * lowerArmLength) /
|
||||
(2 * upperArmLength * distanceToWrist);
|
||||
float mid = upperArmLength * cosA;
|
||||
float height = sqrt(upperArmLength * upperArmLength + mid * mid - 2 * upperArmLength * mid * cosA);
|
||||
|
||||
// direction of the elbow
|
||||
glm::vec3 handNormal = glm::cross(rotation * glm::vec3(0.0f, 1.0f, 0.0f), shoulderToWrist); // elbow rotating with wrist
|
||||
glm::vec3 relaxedNormal = glm::cross(glm::vec3(0.0f, 1.0f, 0.0f), shoulderToWrist); // elbow pointing straight down
|
||||
const float NORMAL_WEIGHT = 0.5f;
|
||||
glm::vec3 finalNormal = glm::mix(relaxedNormal, handNormal, NORMAL_WEIGHT);
|
||||
|
||||
bool rightHand = (jointIndex == geometry.rightHandJointIndex);
|
||||
if (rightHand ? (finalNormal.y > 0.0f) : (finalNormal.y < 0.0f)) {
|
||||
finalNormal.y = 0.0f; // dont allow elbows to point inward (y is vertical axis)
|
||||
}
|
||||
|
||||
glm::vec3 tangent = glm::normalize(glm::cross(shoulderToWrist, finalNormal));
|
||||
|
||||
// ik solution
|
||||
glm::vec3 elbowPosition = shoulderPosition + glm::normalize(shoulderToWrist) * mid - tangent * height;
|
||||
glm::vec3 forwardVector(rightHand ? -1.0f : 1.0f, 0.0f, 0.0f);
|
||||
glm::quat shoulderRotation = rotationBetween(forwardVector, elbowPosition - shoulderPosition);
|
||||
|
||||
_rig->setJointRotationInBindFrame(shoulderJointIndex, shoulderRotation, PALM_PRIORITY);
|
||||
_rig->setJointRotationInBindFrame(elbowJointIndex,
|
||||
rotationBetween(shoulderRotation * forwardVector, wristPosition - elbowPosition) *
|
||||
shoulderRotation, PALM_PRIORITY);
|
||||
_rig->setJointRotationInBindFrame(jointIndex, rotation, PALM_PRIORITY);
|
||||
}
|
||||
|
||||
bool SkeletonModel::getLeftHandPosition(glm::vec3& position) const {
|
||||
return getJointPositionInWorldFrame(getLeftHandJointIndex(), position);
|
||||
}
|
||||
|
|
|
@ -131,11 +131,6 @@ private:
|
|||
QHash<int, OrientationLineIDs> _jointOrientationLines;
|
||||
int _triangleFanID;
|
||||
|
||||
/// \param jointIndex index of joint in model
|
||||
/// \param position position of joint in model-frame
|
||||
/// \param rotation rotation of joint in model-frame
|
||||
void setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation);
|
||||
|
||||
bool getEyeModelPositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition) const;
|
||||
|
||||
Avatar* _owningAvatar;
|
||||
|
|
|
@ -564,6 +564,13 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
|
|||
eyeCoefficients[1] = _filteredEyeBlinks[1];
|
||||
}
|
||||
|
||||
// Couple eyelid values if configured - use the most "open" value for both
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CoupleEyelids)) {
|
||||
float eyeCoefficient = std::min(eyeCoefficients[0], eyeCoefficients[1]);
|
||||
eyeCoefficients[0] = eyeCoefficient;
|
||||
eyeCoefficients[1] = eyeCoefficient;
|
||||
}
|
||||
|
||||
// Use EyeBlink values to control both EyeBlink and EyeOpen
|
||||
if (eyeCoefficients[0] > 0) {
|
||||
_coefficients[_leftBlinkIndex] = eyeCoefficients[0];
|
||||
|
|
|
@ -20,15 +20,81 @@ void AvatarRig::updateJointState(int index, glm::mat4 parentTransform) {
|
|||
const FBXJoint& joint = state.getFBXJoint();
|
||||
|
||||
// compute model transforms
|
||||
int parentIndex = joint.parentIndex;
|
||||
if (parentIndex == -1) {
|
||||
if (index == _rootJointIndex) {
|
||||
// we always zero-out the translation part of an avatar's root join-transform.
|
||||
state.computeTransform(parentTransform);
|
||||
clearJointTransformTranslation(index);
|
||||
} else {
|
||||
// guard against out-of-bounds access to _jointStates
|
||||
if (joint.parentIndex >= 0 && joint.parentIndex < _jointStates.size()) {
|
||||
int parentIndex = joint.parentIndex;
|
||||
if (parentIndex >= 0 && parentIndex < _jointStates.size()) {
|
||||
const JointState& parentState = _jointStates.at(parentIndex);
|
||||
state.computeTransform(parentState.getTransform(), parentState.getTransformChanged());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AvatarRig::setHandPosition(int jointIndex,
|
||||
const glm::vec3& position, const glm::quat& rotation,
|
||||
float scale, float priority) {
|
||||
bool rightHand = (jointIndex == _rightHandJointIndex);
|
||||
|
||||
int elbowJointIndex = rightHand ? _rightElbowJointIndex : _leftElbowJointIndex;
|
||||
int shoulderJointIndex = rightHand ? _rightShoulderJointIndex : _leftShoulderJointIndex;
|
||||
|
||||
// this algorithm is from sample code from sixense
|
||||
if (elbowJointIndex == -1 || shoulderJointIndex == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
glm::vec3 shoulderPosition;
|
||||
if (!getJointPosition(shoulderJointIndex, shoulderPosition)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// precomputed lengths
|
||||
float upperArmLength = _jointStates[elbowJointIndex].getFBXJoint().distanceToParent * scale;
|
||||
float lowerArmLength = _jointStates[jointIndex].getFBXJoint().distanceToParent * scale;
|
||||
|
||||
// first set wrist position
|
||||
glm::vec3 wristPosition = position;
|
||||
|
||||
glm::vec3 shoulderToWrist = wristPosition - shoulderPosition;
|
||||
float distanceToWrist = glm::length(shoulderToWrist);
|
||||
|
||||
// prevent gimbal lock
|
||||
if (distanceToWrist > upperArmLength + lowerArmLength - EPSILON) {
|
||||
distanceToWrist = upperArmLength + lowerArmLength - EPSILON;
|
||||
shoulderToWrist = glm::normalize(shoulderToWrist) * distanceToWrist;
|
||||
wristPosition = shoulderPosition + shoulderToWrist;
|
||||
}
|
||||
|
||||
// cosine of angle from upper arm to hand vector
|
||||
float cosA = (upperArmLength * upperArmLength + distanceToWrist * distanceToWrist - lowerArmLength * lowerArmLength) /
|
||||
(2 * upperArmLength * distanceToWrist);
|
||||
float mid = upperArmLength * cosA;
|
||||
float height = sqrt(upperArmLength * upperArmLength + mid * mid - 2 * upperArmLength * mid * cosA);
|
||||
|
||||
// direction of the elbow
|
||||
glm::vec3 handNormal = glm::cross(rotation * glm::vec3(0.0f, 1.0f, 0.0f), shoulderToWrist); // elbow rotating with wrist
|
||||
glm::vec3 relaxedNormal = glm::cross(glm::vec3(0.0f, 1.0f, 0.0f), shoulderToWrist); // elbow pointing straight down
|
||||
const float NORMAL_WEIGHT = 0.5f;
|
||||
glm::vec3 finalNormal = glm::mix(relaxedNormal, handNormal, NORMAL_WEIGHT);
|
||||
|
||||
if (rightHand ? (finalNormal.y > 0.0f) : (finalNormal.y < 0.0f)) {
|
||||
finalNormal.y = 0.0f; // dont allow elbows to point inward (y is vertical axis)
|
||||
}
|
||||
|
||||
glm::vec3 tangent = glm::normalize(glm::cross(shoulderToWrist, finalNormal));
|
||||
|
||||
// ik solution
|
||||
glm::vec3 elbowPosition = shoulderPosition + glm::normalize(shoulderToWrist) * mid - tangent * height;
|
||||
glm::vec3 forwardVector(rightHand ? -1.0f : 1.0f, 0.0f, 0.0f);
|
||||
glm::quat shoulderRotation = rotationBetween(forwardVector, elbowPosition - shoulderPosition);
|
||||
|
||||
setJointRotationInBindFrame(shoulderJointIndex, shoulderRotation, priority);
|
||||
setJointRotationInBindFrame(elbowJointIndex,
|
||||
rotationBetween(shoulderRotation * forwardVector, wristPosition - elbowPosition) *
|
||||
shoulderRotation, priority);
|
||||
setJointRotationInBindFrame(jointIndex, rotation, priority);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ class AvatarRig : public Rig {
|
|||
public:
|
||||
~AvatarRig() {}
|
||||
virtual void updateJointState(int index, glm::mat4 parentTransform);
|
||||
virtual void setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation,
|
||||
float scale, float priority);
|
||||
};
|
||||
|
||||
#endif // hifi_AvatarRig_h
|
||||
|
|
|
@ -22,6 +22,8 @@ class EntityRig : public Rig {
|
|||
public:
|
||||
~EntityRig() {}
|
||||
virtual void updateJointState(int index, glm::mat4 parentTransform);
|
||||
virtual void setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation,
|
||||
float scale, float priority) {}
|
||||
};
|
||||
|
||||
#endif // hifi_EntityRig_h
|
||||
|
|
|
@ -182,8 +182,24 @@ void Rig::deleteAnimations() {
|
|||
_animationHandles.clear();
|
||||
}
|
||||
|
||||
float Rig::initJointStates(QVector<JointState> states, glm::mat4 parentTransform) {
|
||||
float Rig::initJointStates(QVector<JointState> states, glm::mat4 parentTransform,
|
||||
int rootJointIndex,
|
||||
int leftHandJointIndex,
|
||||
int leftElbowJointIndex,
|
||||
int leftShoulderJointIndex,
|
||||
int rightHandJointIndex,
|
||||
int rightElbowJointIndex,
|
||||
int rightShoulderJointIndex) {
|
||||
_jointStates = states;
|
||||
|
||||
_rootJointIndex = rootJointIndex;
|
||||
_leftHandJointIndex = leftHandJointIndex;
|
||||
_leftElbowJointIndex = leftElbowJointIndex;
|
||||
_leftShoulderJointIndex = leftShoulderJointIndex;
|
||||
_rightHandJointIndex = rightHandJointIndex;
|
||||
_rightElbowJointIndex = rightElbowJointIndex;
|
||||
_rightShoulderJointIndex = rightShoulderJointIndex;
|
||||
|
||||
initJointTransforms(parentTransform);
|
||||
|
||||
int numStates = _jointStates.size();
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
|
||||
class AnimationHandle;
|
||||
typedef std::shared_ptr<AnimationHandle> AnimationHandlePointer;
|
||||
// typedef QWeakPointer<AnimationHandle> WeakAnimationHandlePointer;
|
||||
|
||||
class Rig;
|
||||
typedef std::shared_ptr<Rig> RigPointer;
|
||||
|
@ -91,7 +90,14 @@ public:
|
|||
float priority = 1.0f, bool loop = false, bool hold = false, float firstFrame = 0.0f,
|
||||
float lastFrame = FLT_MAX, const QStringList& maskedJoints = QStringList(), bool startAutomatically = false);
|
||||
|
||||
float initJointStates(QVector<JointState> states, glm::mat4 parentTransform);
|
||||
float initJointStates(QVector<JointState> states, glm::mat4 parentTransform,
|
||||
int rootJointIndex,
|
||||
int leftHandJointIndex,
|
||||
int leftElbowJointIndex,
|
||||
int leftShoulderJointIndex,
|
||||
int rightHandJointIndex,
|
||||
int rightElbowJointIndex,
|
||||
int rightShoulderJointIndex);
|
||||
bool jointStatesEmpty() { return _jointStates.isEmpty(); };
|
||||
int getJointStateCount() const { return _jointStates.size(); }
|
||||
int indexOfJoint(const QString& jointName) ;
|
||||
|
@ -150,6 +156,9 @@ public:
|
|||
|
||||
void updateFromHeadParameters(const HeadParameters& params);
|
||||
|
||||
virtual void setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation,
|
||||
float scale, float priority) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
void updateLeanJoint(int index, float leanSideways, float leanForward, float torsoTwist);
|
||||
|
@ -157,6 +166,15 @@ public:
|
|||
void updateEyeJoint(int index, const glm::quat& worldHeadOrientation, const glm::vec3& lookAt, const glm::vec3& saccade);
|
||||
|
||||
QVector<JointState> _jointStates;
|
||||
int _rootJointIndex = -1;
|
||||
|
||||
int _leftHandJointIndex = -1;
|
||||
int _leftElbowJointIndex = -1;
|
||||
int _leftShoulderJointIndex = -1;
|
||||
|
||||
int _rightHandJointIndex = -1;
|
||||
int _rightElbowJointIndex = -1;
|
||||
int _rightShoulderJointIndex = -1;
|
||||
|
||||
QList<AnimationHandlePointer> _animationHandles;
|
||||
QList<AnimationHandlePointer> _runningAnimations;
|
||||
|
@ -164,6 +182,6 @@ public:
|
|||
bool _enableRig;
|
||||
glm::vec3 _lastFront;
|
||||
glm::vec3 _lastPosition;
|
||||
};
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__Rig__) */
|
||||
|
|
|
@ -473,7 +473,23 @@ bool Model::updateGeometry() {
|
|||
void Model::initJointStates(QVector<JointState> states) {
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset;
|
||||
_boundingRadius = _rig->initJointStates(states, parentTransform);
|
||||
|
||||
int rootJointIndex = geometry.rootJointIndex;
|
||||
int leftHandJointIndex = geometry.leftHandJointIndex;
|
||||
int leftElbowJointIndex = leftHandJointIndex >= 0 ? geometry.joints.at(leftHandJointIndex).parentIndex : -1;
|
||||
int leftShoulderJointIndex = leftElbowJointIndex >= 0 ? geometry.joints.at(leftElbowJointIndex).parentIndex : -1;
|
||||
int rightHandJointIndex = geometry.rightHandJointIndex;
|
||||
int rightElbowJointIndex = rightHandJointIndex >= 0 ? geometry.joints.at(rightHandJointIndex).parentIndex : -1;
|
||||
int rightShoulderJointIndex = rightElbowJointIndex >= 0 ? geometry.joints.at(rightElbowJointIndex).parentIndex : -1;
|
||||
|
||||
_boundingRadius = _rig->initJointStates(states, parentTransform,
|
||||
rootJointIndex,
|
||||
leftHandJointIndex,
|
||||
leftElbowJointIndex,
|
||||
leftShoulderJointIndex,
|
||||
rightHandJointIndex,
|
||||
rightElbowJointIndex,
|
||||
rightShoulderJointIndex);
|
||||
}
|
||||
|
||||
bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
||||
|
|
Loading…
Reference in a new issue