mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 16:36:54 +02:00
Merge branch 'rig' of https://github.com/howard-stearns/hifi into rig
This commit is contained in:
commit
68aec1fd36
7 changed files with 98 additions and 107 deletions
|
@ -968,12 +968,8 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
|
||||||
Avatar::setSkeletonModelURL(skeletonModelURL);
|
Avatar::setSkeletonModelURL(skeletonModelURL);
|
||||||
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
|
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
|
||||||
_billboardValid = false;
|
_billboardValid = false;
|
||||||
|
_skeletonModel.setVisibleInScene(true, scene);
|
||||||
if (_useFullAvatar) {
|
_headBoneSet.clear();
|
||||||
_skeletonModel.setVisibleInScene(_prevShouldDrawHead, scene);
|
|
||||||
} else {
|
|
||||||
_skeletonModel.setVisibleInScene(true, scene);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::useFullAvatarURL(const QUrl& fullAvatarURL, const QString& modelName) {
|
void MyAvatar::useFullAvatarURL(const QUrl& fullAvatarURL, const QString& modelName) {
|
||||||
|
@ -1183,17 +1179,45 @@ void MyAvatar::setVisibleInSceneIfReady(Model* model, render::ScenePointer scene
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyAvatar::initHeadBones() {
|
||||||
|
int neckJointIndex = -1;
|
||||||
|
if (_skeletonModel.getGeometry()) {
|
||||||
|
neckJointIndex = _skeletonModel.getGeometry()->getFBXGeometry().neckJointIndex;
|
||||||
|
}
|
||||||
|
if (neckJointIndex == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_headBoneSet.clear();
|
||||||
|
std::queue<int> q;
|
||||||
|
q.push(neckJointIndex);
|
||||||
|
_headBoneSet.insert(neckJointIndex);
|
||||||
|
|
||||||
|
// fbxJoints only hold links to parents not children, so we have to do a bit of extra work here.
|
||||||
|
while (q.size() > 0) {
|
||||||
|
int jointIndex = q.front();
|
||||||
|
for (int i = 0; i < _skeletonModel.getJointStateCount(); i++) {
|
||||||
|
if (jointIndex == _skeletonModel.getParentJointIndex(i)) {
|
||||||
|
_headBoneSet.insert(i);
|
||||||
|
q.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
q.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MyAvatar::preRender(RenderArgs* renderArgs) {
|
void MyAvatar::preRender(RenderArgs* renderArgs) {
|
||||||
|
|
||||||
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
|
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
|
||||||
const bool shouldDrawHead = shouldRenderHead(renderArgs);
|
const bool shouldDrawHead = shouldRenderHead(renderArgs);
|
||||||
|
|
||||||
_skeletonModel.initWhenReady(scene);
|
if (_skeletonModel.initWhenReady(scene)) {
|
||||||
|
initHeadBones();
|
||||||
|
_skeletonModel.setCauterizeBoneSet(_headBoneSet);
|
||||||
|
}
|
||||||
|
|
||||||
if (shouldDrawHead != _prevShouldDrawHead) {
|
if (shouldDrawHead != _prevShouldDrawHead) {
|
||||||
if (_useFullAvatar) {
|
if (_useFullAvatar) {
|
||||||
_skeletonModel.setVisibleInScene(true, scene);
|
_skeletonModel.setCauterizeBones(!shouldDrawHead);
|
||||||
_rig->setFirstPerson(!shouldDrawHead);
|
|
||||||
} else {
|
} else {
|
||||||
getHead()->getFaceModel().setVisibleInScene(shouldDrawHead, scene);
|
getHead()->getFaceModel().setVisibleInScene(shouldDrawHead, scene);
|
||||||
}
|
}
|
||||||
|
|
|
@ -273,7 +273,8 @@ private:
|
||||||
void updatePosition(float deltaTime);
|
void updatePosition(float deltaTime);
|
||||||
void updateCollisionSound(const glm::vec3& penetration, float deltaTime, float frequency);
|
void updateCollisionSound(const glm::vec3& penetration, float deltaTime, float frequency);
|
||||||
void maybeUpdateBillboard();
|
void maybeUpdateBillboard();
|
||||||
|
void initHeadBones();
|
||||||
|
|
||||||
// Avatar Preferences
|
// Avatar Preferences
|
||||||
bool _useFullAvatar = false;
|
bool _useFullAvatar = false;
|
||||||
QUrl _fullAvatarURLFromPreferences;
|
QUrl _fullAvatarURLFromPreferences;
|
||||||
|
@ -286,6 +287,7 @@ private:
|
||||||
|
|
||||||
RigPointer _rig;
|
RigPointer _rig;
|
||||||
bool _prevShouldDrawHead;
|
bool _prevShouldDrawHead;
|
||||||
|
std::unordered_set<int> _headBoneSet;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_MyAvatar_h
|
#endif // hifi_MyAvatar_h
|
||||||
|
|
|
@ -51,7 +51,7 @@ SkeletonModel::~SkeletonModel() {
|
||||||
void SkeletonModel::initJointStates(QVector<JointState> states) {
|
void SkeletonModel::initJointStates(QVector<JointState> states) {
|
||||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||||
glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset;
|
glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset;
|
||||||
_boundingRadius = _rig->initJointStates(states, parentTransform, geometry.neckJointIndex);
|
_boundingRadius = _rig->initJointStates(states, parentTransform);
|
||||||
|
|
||||||
// Determine the default eye position for avatar scale = 1.0
|
// Determine the default eye position for avatar scale = 1.0
|
||||||
int headJointIndex = _geometry->getFBXGeometry().headJointIndex;
|
int headJointIndex = _geometry->getFBXGeometry().headJointIndex;
|
||||||
|
@ -175,14 +175,6 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) {
|
||||||
restoreRightHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY);
|
restoreRightHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (_isFirstPerson) {
|
|
||||||
// cauterizeHead();
|
|
||||||
// updateClusterMatrices();
|
|
||||||
// }
|
|
||||||
if (_rig->getJointsAreDirty()) {
|
|
||||||
updateClusterMatrices();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonModel::renderIKConstraints(gpu::Batch& batch) {
|
void SkeletonModel::renderIKConstraints(gpu::Batch& batch) {
|
||||||
|
|
|
@ -124,9 +124,8 @@ void Rig::deleteAnimations() {
|
||||||
_animationHandles.clear();
|
_animationHandles.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
float Rig::initJointStates(QVector<JointState> states, glm::mat4 parentTransform, int neckJointIndex) {
|
float Rig::initJointStates(QVector<JointState> states, glm::mat4 parentTransform) {
|
||||||
_jointStates = states;
|
_jointStates = states;
|
||||||
_neckJointIndex = neckJointIndex;
|
|
||||||
initJointTransforms(parentTransform);
|
initJointTransforms(parentTransform);
|
||||||
|
|
||||||
int numStates = _jointStates.size();
|
int numStates = _jointStates.size();
|
||||||
|
@ -142,8 +141,6 @@ float Rig::initJointStates(QVector<JointState> states, glm::mat4 parentTransform
|
||||||
_jointStates[i].slaveVisibleTransform();
|
_jointStates[i].slaveVisibleTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
initHeadBones();
|
|
||||||
|
|
||||||
return radius;
|
return radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,8 +192,7 @@ JointState Rig::getJointState(int jointIndex) const {
|
||||||
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
||||||
return JointState();
|
return JointState();
|
||||||
}
|
}
|
||||||
// return _jointStates[jointIndex];
|
return _jointStates[jointIndex];
|
||||||
return maybeCauterizeHead(jointIndex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Rig::getJointStateRotation(int index, glm::quat& rotation) const {
|
bool Rig::getJointStateRotation(int index, glm::quat& rotation) const {
|
||||||
|
@ -270,8 +266,7 @@ bool Rig::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// position is in world-frame
|
// position is in world-frame
|
||||||
// position = translation + rotation * _jointStates[jointIndex].getPosition();
|
position = translation + rotation * _jointStates[jointIndex].getPosition();
|
||||||
position = translation + rotation * maybeCauterizeHead(jointIndex).getPosition();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +275,7 @@ bool Rig::getJointPosition(int jointIndex, glm::vec3& position) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// position is in model-frame
|
// position is in model-frame
|
||||||
position = extractTranslation(maybeCauterizeHead(jointIndex).getTransform());
|
position = extractTranslation(_jointStates[jointIndex].getTransform());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +283,7 @@ bool Rig::getJointRotationInWorldFrame(int jointIndex, glm::quat& result, const
|
||||||
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
result = rotation * maybeCauterizeHead(jointIndex).getRotation();
|
result = rotation * _jointStates[jointIndex].getRotation();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +291,7 @@ bool Rig::getJointRotation(int jointIndex, glm::quat& rotation) const {
|
||||||
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
rotation = maybeCauterizeHead(jointIndex).getRotation();
|
rotation = _jointStates[jointIndex].getRotation();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,7 +299,7 @@ bool Rig::getJointCombinedRotation(int jointIndex, glm::quat& result, const glm:
|
||||||
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
result = rotation * maybeCauterizeHead(jointIndex).getRotation();
|
result = rotation * _jointStates[jointIndex].getRotation();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +310,7 @@ bool Rig::getVisibleJointPositionInWorldFrame(int jointIndex, glm::vec3& positio
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// position is in world-frame
|
// position is in world-frame
|
||||||
position = translation + rotation * maybeCauterizeHead(jointIndex).getVisiblePosition();
|
position = translation + rotation * _jointStates[jointIndex].getVisiblePosition();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,7 +318,7 @@ bool Rig::getVisibleJointRotationInWorldFrame(int jointIndex, glm::quat& result,
|
||||||
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
result = rotation * maybeCauterizeHead(jointIndex).getVisibleRotation();
|
result = rotation * _jointStates[jointIndex].getVisibleRotation();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,14 +326,14 @@ glm::mat4 Rig::getJointTransform(int jointIndex) const {
|
||||||
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
||||||
return glm::mat4();
|
return glm::mat4();
|
||||||
}
|
}
|
||||||
return maybeCauterizeHead(jointIndex).getTransform();
|
return _jointStates[jointIndex].getTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 Rig::getJointVisibleTransform(int jointIndex) const {
|
glm::mat4 Rig::getJointVisibleTransform(int jointIndex) const {
|
||||||
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
||||||
return glm::mat4();
|
return glm::mat4();
|
||||||
}
|
}
|
||||||
return maybeCauterizeHead(jointIndex).getVisibleTransform();
|
return _jointStates[jointIndex].getVisibleTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPosition, const glm::vec3& worldVelocity, const glm::quat& worldRotation) {
|
void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPosition, const glm::vec3& worldVelocity, const glm::quat& worldRotation) {
|
||||||
|
@ -624,7 +619,7 @@ glm::vec3 Rig::getJointDefaultTranslationInConstrainedFrame(int jointIndex) {
|
||||||
if (jointIndex == -1 || _jointStates.isEmpty()) {
|
if (jointIndex == -1 || _jointStates.isEmpty()) {
|
||||||
return glm::vec3();
|
return glm::vec3();
|
||||||
}
|
}
|
||||||
return maybeCauterizeHead(jointIndex).getDefaultTranslationInConstrainedFrame();
|
return _jointStates[jointIndex].getDefaultTranslationInConstrainedFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::quat Rig::setJointRotationInConstrainedFrame(int jointIndex, glm::quat targetRotation, float priority, bool constrain) {
|
glm::quat Rig::setJointRotationInConstrainedFrame(int jointIndex, glm::quat targetRotation, float priority, bool constrain) {
|
||||||
|
@ -669,53 +664,5 @@ glm::quat Rig::getJointDefaultRotationInParentFrame(int jointIndex) {
|
||||||
if (jointIndex == -1 || _jointStates.isEmpty()) {
|
if (jointIndex == -1 || _jointStates.isEmpty()) {
|
||||||
return glm::quat();
|
return glm::quat();
|
||||||
}
|
}
|
||||||
return maybeCauterizeHead(jointIndex).getDefaultRotationInParentFrame();
|
return _jointStates[jointIndex].getDefaultRotationInParentFrame();
|
||||||
}
|
|
||||||
|
|
||||||
void Rig::initHeadBones() {
|
|
||||||
if (_neckJointIndex == -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_headBones.clear();
|
|
||||||
std::queue<int> q;
|
|
||||||
q.push(_neckJointIndex);
|
|
||||||
_headBones.push_back(_neckJointIndex);
|
|
||||||
|
|
||||||
// fbxJoints only hold links to parents not children, so we have to do a bit of extra work here.
|
|
||||||
while (q.size() > 0) {
|
|
||||||
int jointIndex = q.front();
|
|
||||||
for (int i = 0; i < _jointStates.size(); i++) {
|
|
||||||
const FBXJoint& fbxJoint = _jointStates[i].getFBXJoint();
|
|
||||||
if (jointIndex == fbxJoint.parentIndex) {
|
|
||||||
_headBones.push_back(i);
|
|
||||||
q.push(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
q.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
JointState Rig::maybeCauterizeHead(int jointIndex) const {
|
|
||||||
// if (_headBones.contains(jointIndex)) {
|
|
||||||
// XXX fix this... make _headBones a hash? add a flag to JointState?
|
|
||||||
if (_neckJointIndex != -1 &&
|
|
||||||
_isFirstPerson &&
|
|
||||||
std::find(_headBones.begin(), _headBones.end(), jointIndex) != _headBones.end()) {
|
|
||||||
glm::vec4 trans = _jointStates[jointIndex].getTransform()[3];
|
|
||||||
glm::vec4 zero(0, 0, 0, 0);
|
|
||||||
glm::mat4 newXform(zero, zero, zero, trans);
|
|
||||||
JointState jointStateCopy = _jointStates[jointIndex];
|
|
||||||
jointStateCopy.setTransform(newXform);
|
|
||||||
jointStateCopy.setVisibleTransform(newXform);
|
|
||||||
return jointStateCopy;
|
|
||||||
} else {
|
|
||||||
return _jointStates[jointIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rig::setFirstPerson(bool isFirstPerson) {
|
|
||||||
if (_isFirstPerson != isFirstPerson) {
|
|
||||||
_isFirstPerson = isFirstPerson;
|
|
||||||
_jointsAreDirty = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ public:
|
||||||
float priority = 1.0f, bool loop = false, bool hold = false, float firstFrame = 0.0f,
|
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 lastFrame = FLT_MAX, const QStringList& maskedJoints = QStringList(), bool startAutomatically = false);
|
||||||
|
|
||||||
float initJointStates(QVector<JointState> states, glm::mat4 parentTransform, int neckJointIndex);
|
float initJointStates(QVector<JointState> states, glm::mat4 parentTransform);
|
||||||
bool jointStatesEmpty() { return _jointStates.isEmpty(); };
|
bool jointStatesEmpty() { return _jointStates.isEmpty(); };
|
||||||
int getJointStateCount() const { return _jointStates.size(); }
|
int getJointStateCount() const { return _jointStates.size(); }
|
||||||
int indexOfJoint(const QString& jointName) ;
|
int indexOfJoint(const QString& jointName) ;
|
||||||
|
@ -131,10 +131,6 @@ public:
|
||||||
virtual void updateJointState(int index, glm::mat4 parentTransform) = 0;
|
virtual void updateJointState(int index, glm::mat4 parentTransform) = 0;
|
||||||
virtual void updateFaceJointState(int index, glm::mat4 parentTransform) = 0;
|
virtual void updateFaceJointState(int index, glm::mat4 parentTransform) = 0;
|
||||||
|
|
||||||
virtual void setFirstPerson(bool isFirstPerson);
|
|
||||||
virtual bool getIsFirstPerson() const { return _isFirstPerson; }
|
|
||||||
|
|
||||||
bool getJointsAreDirty() { return _jointsAreDirty; }
|
|
||||||
void setEnableRig(bool isEnabled) { _enableRig = isEnabled; }
|
void setEnableRig(bool isEnabled) { _enableRig = isEnabled; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -143,13 +139,6 @@ public:
|
||||||
QList<AnimationHandlePointer> _animationHandles;
|
QList<AnimationHandlePointer> _animationHandles;
|
||||||
QList<AnimationHandlePointer> _runningAnimations;
|
QList<AnimationHandlePointer> _runningAnimations;
|
||||||
|
|
||||||
JointState maybeCauterizeHead(int jointIndex) const;
|
|
||||||
void initHeadBones();
|
|
||||||
bool _isFirstPerson = false;
|
|
||||||
std::vector<int> _headBones;
|
|
||||||
bool _jointsAreDirty = false;
|
|
||||||
int _neckJointIndex = -1;
|
|
||||||
|
|
||||||
bool _enableRig;
|
bool _enableRig;
|
||||||
bool _isWalking;
|
bool _isWalking;
|
||||||
bool _isTurning;
|
bool _isTurning;
|
||||||
|
|
|
@ -67,6 +67,7 @@ Model::Model(RigPointer rig, QObject* parent) :
|
||||||
_snapModelToRegistrationPoint(false),
|
_snapModelToRegistrationPoint(false),
|
||||||
_snappedToRegistrationPoint(false),
|
_snappedToRegistrationPoint(false),
|
||||||
_showTrueJointTransforms(true),
|
_showTrueJointTransforms(true),
|
||||||
|
_cauterizeBones(false),
|
||||||
_lodDistance(0.0f),
|
_lodDistance(0.0f),
|
||||||
_pupilDilation(0.0f),
|
_pupilDilation(0.0f),
|
||||||
_url("http://invalid.com"),
|
_url("http://invalid.com"),
|
||||||
|
@ -452,6 +453,7 @@ bool Model::updateGeometry() {
|
||||||
foreach (const FBXMesh& mesh, fbxGeometry.meshes) {
|
foreach (const FBXMesh& mesh, fbxGeometry.meshes) {
|
||||||
MeshState state;
|
MeshState state;
|
||||||
state.clusterMatrices.resize(mesh.clusters.size());
|
state.clusterMatrices.resize(mesh.clusters.size());
|
||||||
|
state.cauterizedClusterMatrices.resize(mesh.clusters.size());
|
||||||
_meshStates.append(state);
|
_meshStates.append(state);
|
||||||
|
|
||||||
auto buffer = std::make_shared<gpu::Buffer>();
|
auto buffer = std::make_shared<gpu::Buffer>();
|
||||||
|
@ -472,7 +474,7 @@ bool Model::updateGeometry() {
|
||||||
void Model::initJointStates(QVector<JointState> states) {
|
void Model::initJointStates(QVector<JointState> states) {
|
||||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||||
glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset;
|
glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset;
|
||||||
_boundingRadius = _rig->initJointStates(states, parentTransform, geometry.neckJointIndex);
|
_boundingRadius = _rig->initJointStates(states, parentTransform);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
||||||
|
@ -1337,6 +1339,12 @@ void Model::simulateInternal(float deltaTime) {
|
||||||
glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset;
|
glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset;
|
||||||
updateRig(deltaTime, parentTransform);
|
updateRig(deltaTime, parentTransform);
|
||||||
|
|
||||||
|
glm::mat4 zeroScale(glm::vec4(0.0f, 0.0f, 0.0f, 0.0f),
|
||||||
|
glm::vec4(0.0f, 0.0f, 0.0f, 0.0f),
|
||||||
|
glm::vec4(0.0f, 0.0f, 0.0f, 0.0f),
|
||||||
|
glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||||
|
auto cauterizeMatrix = _rig->getJointTransform(geometry.neckJointIndex) * zeroScale;
|
||||||
|
|
||||||
glm::mat4 modelToWorld = glm::mat4_cast(_rotation);
|
glm::mat4 modelToWorld = glm::mat4_cast(_rotation);
|
||||||
for (int i = 0; i < _meshStates.size(); i++) {
|
for (int i = 0; i < _meshStates.size(); i++) {
|
||||||
MeshState& state = _meshStates[i];
|
MeshState& state = _meshStates[i];
|
||||||
|
@ -1344,14 +1352,30 @@ void Model::simulateInternal(float deltaTime) {
|
||||||
if (_showTrueJointTransforms) {
|
if (_showTrueJointTransforms) {
|
||||||
for (int j = 0; j < mesh.clusters.size(); j++) {
|
for (int j = 0; j < mesh.clusters.size(); j++) {
|
||||||
const FBXCluster& cluster = mesh.clusters.at(j);
|
const FBXCluster& cluster = mesh.clusters.at(j);
|
||||||
state.clusterMatrices[j] =
|
auto jointMatrix =_rig->getJointTransform(cluster.jointIndex);
|
||||||
modelToWorld * _rig->getJointTransform(cluster.jointIndex) * cluster.inverseBindMatrix;
|
state.clusterMatrices[j] = modelToWorld * jointMatrix * cluster.inverseBindMatrix;
|
||||||
|
|
||||||
|
// as an optimization, don't build cautrizedClusterMatrices if the boneSet is empty.
|
||||||
|
if (!_cauterizeBoneSet.empty()) {
|
||||||
|
if (_cauterizeBoneSet.find(cluster.jointIndex) != _cauterizeBoneSet.end()) {
|
||||||
|
jointMatrix = cauterizeMatrix;
|
||||||
|
}
|
||||||
|
state.cauterizedClusterMatrices[j] = modelToWorld * jointMatrix * cluster.inverseBindMatrix;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int j = 0; j < mesh.clusters.size(); j++) {
|
for (int j = 0; j < mesh.clusters.size(); j++) {
|
||||||
const FBXCluster& cluster = mesh.clusters.at(j);
|
const FBXCluster& cluster = mesh.clusters.at(j);
|
||||||
state.clusterMatrices[j] =
|
auto jointMatrix = _rig->getJointVisibleTransform(cluster.jointIndex);
|
||||||
modelToWorld * _rig->getJointVisibleTransform(cluster.jointIndex) * cluster.inverseBindMatrix;
|
state.clusterMatrices[j] = modelToWorld * jointMatrix * cluster.inverseBindMatrix;
|
||||||
|
|
||||||
|
// as an optimization, don't build cautrizedClusterMatrices if the boneSet is empty.
|
||||||
|
if (!_cauterizeBoneSet.empty()) {
|
||||||
|
if (_cauterizeBoneSet.find(cluster.jointIndex) != _cauterizeBoneSet.end()) {
|
||||||
|
jointMatrix = cauterizeMatrix;
|
||||||
|
}
|
||||||
|
state.cauterizedClusterMatrices[j] = modelToWorld * jointMatrix * cluster.inverseBindMatrix;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1611,8 +1635,11 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSkinned) {
|
if (isSkinned) {
|
||||||
batch._glUniformMatrix4fv(locations->clusterMatrices, state.clusterMatrices.size(), false,
|
const float* bones = (const float*)state.clusterMatrices.constData();
|
||||||
(const float*)state.clusterMatrices.constData());
|
if (_cauterizeBones) {
|
||||||
|
bones = (const float*)state.cauterizedClusterMatrices.constData();
|
||||||
|
}
|
||||||
|
batch._glUniformMatrix4fv(locations->clusterMatrices, state.clusterMatrices.size(), false, bones);
|
||||||
_transforms[0] = Transform();
|
_transforms[0] = Transform();
|
||||||
_transforms[0].preTranslate(_translation);
|
_transforms[0].preTranslate(_translation);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include <AABox.h>
|
#include <AABox.h>
|
||||||
|
@ -172,6 +173,9 @@ public:
|
||||||
/// \return true if joint exists
|
/// \return true if joint exists
|
||||||
bool getJointRotation(int jointIndex, glm::quat& rotation) const;
|
bool getJointRotation(int jointIndex, glm::quat& rotation) const;
|
||||||
|
|
||||||
|
/// Returns the index of the parent of the indexed joint, or -1 if not found.
|
||||||
|
int getParentJointIndex(int jointIndex) const;
|
||||||
|
|
||||||
void inverseKinematics(int jointIndex, glm::vec3 position, const glm::quat& rotation, float priority);
|
void inverseKinematics(int jointIndex, glm::vec3 position, const glm::quat& rotation, float priority);
|
||||||
|
|
||||||
/// Returns the extents of the model in its bind pose.
|
/// Returns the extents of the model in its bind pose.
|
||||||
|
@ -187,6 +191,12 @@ public:
|
||||||
bool getIsScaledToFit() const { return _scaledToFit; } /// is model scaled to fit
|
bool getIsScaledToFit() const { return _scaledToFit; } /// is model scaled to fit
|
||||||
const glm::vec3& getScaleToFitDimensions() const { return _scaleToFitDimensions; } /// the dimensions model is scaled to
|
const glm::vec3& getScaleToFitDimensions() const { return _scaleToFitDimensions; } /// the dimensions model is scaled to
|
||||||
|
|
||||||
|
void setCauterizeBones(bool flag) { _cauterizeBones = flag; }
|
||||||
|
bool getCauterizeBones() const { return _cauterizeBones; }
|
||||||
|
|
||||||
|
const std::unordered_set<int>& getCauterizeBoneSet() const { return _cauterizeBoneSet; }
|
||||||
|
void setCauterizeBoneSet(const std::unordered_set<int>& boneSet) { _cauterizeBoneSet = boneSet; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void setPupilDilation(float dilation) { _pupilDilation = dilation; }
|
void setPupilDilation(float dilation) { _pupilDilation = dilation; }
|
||||||
|
@ -218,9 +228,6 @@ protected:
|
||||||
/// Clear the joint states
|
/// Clear the joint states
|
||||||
void clearJointState(int index);
|
void clearJointState(int index);
|
||||||
|
|
||||||
/// Returns the index of the parent of the indexed joint, or -1 if not found.
|
|
||||||
int getParentJointIndex(int jointIndex) const;
|
|
||||||
|
|
||||||
/// Returns the index of the last free ancestor of the indexed joint, or -1 if not found.
|
/// Returns the index of the last free ancestor of the indexed joint, or -1 if not found.
|
||||||
int getLastFreeJointIndex(int jointIndex) const;
|
int getLastFreeJointIndex(int jointIndex) const;
|
||||||
|
|
||||||
|
@ -255,9 +262,12 @@ protected:
|
||||||
class MeshState {
|
class MeshState {
|
||||||
public:
|
public:
|
||||||
QVector<glm::mat4> clusterMatrices;
|
QVector<glm::mat4> clusterMatrices;
|
||||||
|
QVector<glm::mat4> cauterizedClusterMatrices;
|
||||||
};
|
};
|
||||||
|
|
||||||
QVector<MeshState> _meshStates;
|
QVector<MeshState> _meshStates;
|
||||||
|
std::unordered_set<int> _cauterizeBoneSet;
|
||||||
|
bool _cauterizeBones;
|
||||||
|
|
||||||
// returns 'true' if needs fullUpdate after geometry change
|
// returns 'true' if needs fullUpdate after geometry change
|
||||||
bool updateGeometry();
|
bool updateGeometry();
|
||||||
|
|
Loading…
Reference in a new issue