mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 11:45:36 +02:00
commit
878f7129f4
9 changed files with 137 additions and 140 deletions
|
@ -103,11 +103,8 @@ MyAvatar::MyAvatar(RigPointer rig) :
|
|||
_realWorldFieldOfView("realWorldFieldOfView",
|
||||
DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES),
|
||||
_rig(rig),
|
||||
_firstPersonSkeletonModel(this, nullptr, rig),
|
||||
_prevShouldDrawHead(true)
|
||||
{
|
||||
_firstPersonSkeletonModel.setIsFirstPerson(true);
|
||||
|
||||
ShapeCollider::initDispatchTable();
|
||||
for (int i = 0; i < MAX_DRIVE_KEYS; i++) {
|
||||
_driveKeys[i] = 0.0f;
|
||||
|
@ -141,7 +138,6 @@ QByteArray MyAvatar::toByteArray() {
|
|||
|
||||
void MyAvatar::reset() {
|
||||
_skeletonModel.reset();
|
||||
_firstPersonSkeletonModel.reset();
|
||||
getHead()->reset();
|
||||
|
||||
_targetVelocity = glm::vec3(0.0f);
|
||||
|
@ -200,7 +196,6 @@ void MyAvatar::simulate(float deltaTime) {
|
|||
{
|
||||
PerformanceTimer perfTimer("skeleton");
|
||||
_skeletonModel.simulate(deltaTime);
|
||||
_firstPersonSkeletonModel.simulate(deltaTime);
|
||||
}
|
||||
|
||||
if (!_skeletonModel.hasSkeleton()) {
|
||||
|
@ -1028,15 +1023,8 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
|
|||
|
||||
if (_useFullAvatar) {
|
||||
_skeletonModel.setVisibleInScene(_prevShouldDrawHead, scene);
|
||||
|
||||
const QUrl DEFAULT_SKELETON_MODEL_URL = QUrl::fromLocalFile(PathUtils::resourcesPath() + "meshes/defaultAvatar_body.fst");
|
||||
_firstPersonSkeletonModel.setURL(_skeletonModelURL, DEFAULT_SKELETON_MODEL_URL, true, !isMyAvatar());
|
||||
_firstPersonSkeletonModel.setVisibleInScene(!_prevShouldDrawHead, scene);
|
||||
} else {
|
||||
_skeletonModel.setVisibleInScene(true, scene);
|
||||
|
||||
_firstPersonSkeletonModel.setVisibleInScene(false, scene);
|
||||
_firstPersonSkeletonModel.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1254,23 +1242,14 @@ void MyAvatar::preRender(RenderArgs* renderArgs) {
|
|||
const bool shouldDrawHead = shouldRenderHead(renderArgs);
|
||||
|
||||
_skeletonModel.initWhenReady(scene);
|
||||
if (_useFullAvatar) {
|
||||
_firstPersonSkeletonModel.initWhenReady(scene);
|
||||
}
|
||||
|
||||
if (shouldDrawHead != _prevShouldDrawHead) {
|
||||
if (_useFullAvatar) {
|
||||
if (shouldDrawHead) {
|
||||
_skeletonModel.setVisibleInScene(true, scene);
|
||||
_firstPersonSkeletonModel.setVisibleInScene(false, scene);
|
||||
} else {
|
||||
_skeletonModel.setVisibleInScene(false, scene);
|
||||
_firstPersonSkeletonModel.setVisibleInScene(true, scene);
|
||||
}
|
||||
_skeletonModel.setVisibleInScene(true, scene);
|
||||
_rig->setFirstPerson(!shouldDrawHead);
|
||||
} else {
|
||||
getHead()->getFaceModel().setVisibleInScene(shouldDrawHead, scene);
|
||||
}
|
||||
|
||||
}
|
||||
_prevShouldDrawHead = shouldDrawHead;
|
||||
}
|
||||
|
|
|
@ -287,8 +287,6 @@ private:
|
|||
QString _fullAvatarModelName;
|
||||
|
||||
RigPointer _rig;
|
||||
// used for rendering when in first person view or when in an HMD.
|
||||
SkeletonModel _firstPersonSkeletonModel;
|
||||
bool _prevShouldDrawHead;
|
||||
};
|
||||
|
||||
|
|
|
@ -40,8 +40,7 @@ SkeletonModel::SkeletonModel(Avatar* owningAvatar, QObject* parent, RigPointer r
|
|||
_standingFoot(NO_FOOT),
|
||||
_standingOffset(0.0f),
|
||||
_clampedFootPosition(0.0f),
|
||||
_headClipDistance(DEFAULT_NEAR_CLIP),
|
||||
_isFirstPerson(false)
|
||||
_headClipDistance(DEFAULT_NEAR_CLIP)
|
||||
{
|
||||
assert(_rig);
|
||||
assert(_owningAvatar);
|
||||
|
@ -54,7 +53,7 @@ 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);
|
||||
_boundingRadius = _rig->initJointStates(states, parentTransform, geometry.neckJointIndex);
|
||||
|
||||
// Determine the default eye position for avatar scale = 1.0
|
||||
int headJointIndex = _geometry->getFBXGeometry().headJointIndex;
|
||||
|
@ -98,6 +97,29 @@ void SkeletonModel::initJointStates(QVector<JointState> states) {
|
|||
const float PALM_PRIORITY = DEFAULT_PRIORITY;
|
||||
const float LEAN_PRIORITY = DEFAULT_PRIORITY;
|
||||
|
||||
|
||||
void SkeletonModel::updateClusterMatrices() {
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
glm::mat4 modelToWorld = glm::mat4_cast(_rotation);
|
||||
for (int i = 0; i < _meshStates.size(); i++) {
|
||||
MeshState& state = _meshStates[i];
|
||||
const FBXMesh& mesh = geometry.meshes.at(i);
|
||||
if (_showTrueJointTransforms) {
|
||||
for (int j = 0; j < mesh.clusters.size(); j++) {
|
||||
const FBXCluster& cluster = mesh.clusters.at(j);
|
||||
state.clusterMatrices[j] =
|
||||
modelToWorld * _rig->getJointTransform(cluster.jointIndex) * cluster.inverseBindMatrix;
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < mesh.clusters.size(); j++) {
|
||||
const FBXCluster& cluster = mesh.clusters.at(j);
|
||||
state.clusterMatrices[j] =
|
||||
modelToWorld * _rig->getJointVisibleTransform(cluster.jointIndex) * cluster.inverseBindMatrix;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonModel::simulate(float deltaTime, bool fullUpdate) {
|
||||
setTranslation(_owningAvatar->getSkeletonPosition());
|
||||
static const glm::quat refOrientation = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
|
@ -154,8 +176,11 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) {
|
|||
}
|
||||
}
|
||||
|
||||
if (_isFirstPerson) {
|
||||
cauterizeHead();
|
||||
// if (_isFirstPerson) {
|
||||
// cauterizeHead();
|
||||
// updateClusterMatrices();
|
||||
// }
|
||||
if (_rig->getJointsAreDirty()) {
|
||||
updateClusterMatrices();
|
||||
}
|
||||
|
||||
|
@ -766,7 +791,7 @@ void SkeletonModel::resetShapePositionsToDefaultPose() {
|
|||
// geometry or joints have not yet been created
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
if (geometry.joints.isEmpty()) {
|
||||
return;
|
||||
|
@ -822,7 +847,7 @@ void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float alpha
|
|||
|
||||
// draw a green cylinder between the two points
|
||||
glm::vec3 origin(0.0f);
|
||||
Avatar::renderJointConnectingCone(batch, origin, axis, _boundingShape.getRadius(), _boundingShape.getRadius(),
|
||||
Avatar::renderJointConnectingCone(batch, origin, axis, _boundingShape.getRadius(), _boundingShape.getRadius(),
|
||||
glm::vec4(0.6f, 0.8f, 0.6f, alpha));
|
||||
}
|
||||
|
||||
|
@ -830,56 +855,5 @@ bool SkeletonModel::hasSkeleton() {
|
|||
return isActive() ? _geometry->getFBXGeometry().rootJointIndex != -1 : false;
|
||||
}
|
||||
|
||||
void SkeletonModel::initHeadBones() {
|
||||
_headBones.clear();
|
||||
const FBXGeometry& fbxGeometry = _geometry->getFBXGeometry();
|
||||
const int neckJointIndex = fbxGeometry.neckJointIndex;
|
||||
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 < fbxGeometry.joints.size(); i++) {
|
||||
const FBXJoint& fbxJoint = fbxGeometry.joints[i];
|
||||
if (jointIndex == fbxJoint.parentIndex) {
|
||||
_headBones.push_back(i);
|
||||
q.push(i);
|
||||
}
|
||||
}
|
||||
q.pop();
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonModel::invalidateHeadBones() {
|
||||
_headBones.clear();
|
||||
}
|
||||
|
||||
void SkeletonModel::cauterizeHead() {
|
||||
if (isActive()) {
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
const int neckJointIndex = geometry.neckJointIndex;
|
||||
if (neckJointIndex > 0 && neckJointIndex < _rig->getJointStateCount()) {
|
||||
|
||||
// lazy init of headBones
|
||||
if (_headBones.size() == 0) {
|
||||
initHeadBones();
|
||||
}
|
||||
|
||||
// preserve the translation for the neck
|
||||
// glm::vec4 trans = _jointStates[neckJointIndex].getTransform()[3];
|
||||
glm::vec4 trans = _rig->getJointTransform(neckJointIndex)[3];
|
||||
glm::vec4 zero(0, 0, 0, 0);
|
||||
for (const int &i : _headBones) {
|
||||
glm::mat4 newXform(zero, zero, zero, trans);
|
||||
_rig->setJointTransform(i, newXform);
|
||||
_rig->setJointVisibleTransform(i, newXform);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonModel::onInvalidate() {
|
||||
invalidateHeadBones();
|
||||
}
|
||||
|
|
|
@ -112,9 +112,6 @@ public:
|
|||
|
||||
float getHeadClipDistance() const { return _headClipDistance; }
|
||||
|
||||
void setIsFirstPerson(bool value) { _isFirstPerson = value; }
|
||||
bool getIsFirstPerson() const { return _isFirstPerson; }
|
||||
|
||||
virtual void onInvalidate() override;
|
||||
|
||||
signals:
|
||||
|
@ -138,6 +135,7 @@ protected:
|
|||
void maybeUpdateNeckRotation(const JointState& parentState, const FBXJoint& joint, int index);
|
||||
void maybeUpdateEyeRotation(const JointState& parentState, const FBXJoint& joint, int index);
|
||||
|
||||
void updateClusterMatrices();
|
||||
void cauterizeHead();
|
||||
void initHeadBones();
|
||||
void invalidateHeadBones();
|
||||
|
@ -174,9 +172,6 @@ private:
|
|||
glm::vec3 _clampedFootPosition;
|
||||
|
||||
float _headClipDistance; // Near clip distance to use if no separate head model
|
||||
|
||||
bool _isFirstPerson;
|
||||
std::vector<int> _headBones;
|
||||
};
|
||||
|
||||
#endif // hifi_SkeletonModel_h
|
||||
|
|
|
@ -176,8 +176,7 @@ void AnimationHandle::replaceMatchingPriorities(float newPriority) {
|
|||
for (int i = 0; i < _jointMappings.size(); i++) {
|
||||
int mapping = _jointMappings.at(i);
|
||||
if (mapping != -1) {
|
||||
JointState state = _rig->getJointState(mapping);
|
||||
if (_priority == state._animationPriority) {
|
||||
if (_priority == _rig->getJointAnimatinoPriority(mapping)) {
|
||||
_rig->setJointAnimatinoPriority(mapping, newPriority);
|
||||
}
|
||||
}
|
||||
|
@ -188,8 +187,7 @@ void AnimationHandle::restoreJoints() {
|
|||
for (int i = 0; i < _jointMappings.size(); i++) {
|
||||
int mapping = _jointMappings.at(i);
|
||||
if (mapping != -1) {
|
||||
JointState state = _rig->getJointState(mapping);
|
||||
_rig->restoreJointRotation(mapping, 1.0f, state._animationPriority);
|
||||
_rig->restoreJointRotation(mapping, 1.0f, _rig->getJointAnimatinoPriority(mapping));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <queue>
|
||||
|
||||
#include "AnimationHandle.h"
|
||||
|
||||
#include "Rig.h"
|
||||
|
@ -48,9 +50,9 @@ void Rig::deleteAnimations() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
float Rig::initJointStates(QVector<JointState> states, glm::mat4 parentTransform) {
|
||||
float Rig::initJointStates(QVector<JointState> states, glm::mat4 parentTransform, int neckJointIndex) {
|
||||
_jointStates = states;
|
||||
_neckJointIndex = neckJointIndex;
|
||||
initJointTransforms(parentTransform);
|
||||
|
||||
int numStates = _jointStates.size();
|
||||
|
@ -66,6 +68,8 @@ float Rig::initJointStates(QVector<JointState> states, glm::mat4 parentTransform
|
|||
_jointStates[i].slaveVisibleTransform();
|
||||
}
|
||||
|
||||
initHeadBones();
|
||||
|
||||
return radius;
|
||||
}
|
||||
|
||||
|
@ -106,7 +110,8 @@ JointState Rig::getJointState(int jointIndex) const {
|
|||
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
||||
return JointState();
|
||||
}
|
||||
return _jointStates[jointIndex];
|
||||
// return _jointStates[jointIndex];
|
||||
return maybeCauterizeHead(jointIndex);
|
||||
}
|
||||
|
||||
bool Rig::getJointStateRotation(int index, glm::quat& rotation) const {
|
||||
|
@ -144,6 +149,13 @@ void Rig::clearJointAnimationPriority(int index) {
|
|||
}
|
||||
}
|
||||
|
||||
float Rig::getJointAnimatinoPriority(int index) {
|
||||
if (index != -1 && index < _jointStates.size()) {
|
||||
return _jointStates[index]._animationPriority;
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void Rig::setJointAnimatinoPriority(int index, float newPriority) {
|
||||
if (index != -1 && index < _jointStates.size()) {
|
||||
_jointStates[index]._animationPriority = newPriority;
|
||||
|
@ -173,7 +185,8 @@ bool Rig::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position,
|
|||
return false;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -182,7 +195,7 @@ bool Rig::getJointPosition(int jointIndex, glm::vec3& position) const {
|
|||
return false;
|
||||
}
|
||||
// position is in model-frame
|
||||
position = extractTranslation(_jointStates[jointIndex].getTransform());
|
||||
position = extractTranslation(maybeCauterizeHead(jointIndex).getTransform());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -190,7 +203,7 @@ bool Rig::getJointRotationInWorldFrame(int jointIndex, glm::quat& result, const
|
|||
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
||||
return false;
|
||||
}
|
||||
result = rotation * _jointStates[jointIndex].getRotation();
|
||||
result = rotation * maybeCauterizeHead(jointIndex).getRotation();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -198,7 +211,7 @@ bool Rig::getJointRotation(int jointIndex, glm::quat& rotation) const {
|
|||
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
||||
return false;
|
||||
}
|
||||
rotation = _jointStates[jointIndex].getRotation();
|
||||
rotation = maybeCauterizeHead(jointIndex).getRotation();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -206,7 +219,7 @@ bool Rig::getJointCombinedRotation(int jointIndex, glm::quat& result, const glm:
|
|||
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
||||
return false;
|
||||
}
|
||||
result = rotation * _jointStates[jointIndex].getRotation();
|
||||
result = rotation * maybeCauterizeHead(jointIndex).getRotation();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -217,7 +230,7 @@ bool Rig::getVisibleJointPositionInWorldFrame(int jointIndex, glm::vec3& positio
|
|||
return false;
|
||||
}
|
||||
// position is in world-frame
|
||||
position = translation + rotation * _jointStates[jointIndex].getVisiblePosition();
|
||||
position = translation + rotation * maybeCauterizeHead(jointIndex).getVisiblePosition();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -225,7 +238,7 @@ bool Rig::getVisibleJointRotationInWorldFrame(int jointIndex, glm::quat& result,
|
|||
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
||||
return false;
|
||||
}
|
||||
result = rotation * _jointStates[jointIndex].getVisibleRotation();
|
||||
result = rotation * maybeCauterizeHead(jointIndex).getVisibleRotation();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -233,14 +246,14 @@ glm::mat4 Rig::getJointTransform(int jointIndex) const {
|
|||
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
||||
return glm::mat4();
|
||||
}
|
||||
return _jointStates[jointIndex].getTransform();
|
||||
return maybeCauterizeHead(jointIndex).getTransform();
|
||||
}
|
||||
|
||||
glm::mat4 Rig::getJointVisibleTransform(int jointIndex) const {
|
||||
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
||||
return glm::mat4();
|
||||
}
|
||||
return _jointStates[jointIndex].getVisibleTransform();
|
||||
return maybeCauterizeHead(jointIndex).getVisibleTransform();
|
||||
}
|
||||
|
||||
void Rig::simulateInternal(float deltaTime, glm::mat4 parentTransform) {
|
||||
|
@ -492,7 +505,7 @@ glm::vec3 Rig::getJointDefaultTranslationInConstrainedFrame(int jointIndex) {
|
|||
if (jointIndex == -1 || _jointStates.isEmpty()) {
|
||||
return glm::vec3();
|
||||
}
|
||||
return _jointStates[jointIndex].getDefaultTranslationInConstrainedFrame();
|
||||
return maybeCauterizeHead(jointIndex).getDefaultTranslationInConstrainedFrame();
|
||||
}
|
||||
|
||||
glm::quat Rig::setJointRotationInConstrainedFrame(int jointIndex, glm::quat targetRotation, float priority, bool constrain) {
|
||||
|
@ -537,5 +550,53 @@ glm::quat Rig::getJointDefaultRotationInParentFrame(int jointIndex) {
|
|||
if (jointIndex == -1 || _jointStates.isEmpty()) {
|
||||
return glm::quat();
|
||||
}
|
||||
return _jointStates[jointIndex].getDefaultRotationInParentFrame();
|
||||
return maybeCauterizeHead(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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,14 +11,18 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
/* TBD:
|
||||
- What iare responsibilities of Animation/AnimationPointer/AnimationCache/AnimationDetails/AnimationObject/AnimationLoop?
|
||||
- What are responsibilities of Animation/AnimationPointer/AnimationCache/AnimationDetails/AnimationObject/AnimationLoop?
|
||||
Is there common/copied code (e.g., ScriptableAvatar::update)?
|
||||
- How do attachments interact with the physics of the attached entity? E.g., do hand joints need to reflect held object physics?
|
||||
- Is there any current need (i.e., for initial campatability) to have multiple animations per role (e.g., idle) with the system choosing randomly?
|
||||
- How do attachments interact with the physics of the attached entity? E.g., do hand joints need to reflect held object
|
||||
physics?
|
||||
- Is there any current need (i.e., for initial campatability) to have multiple animations per role (e.g., idle) with the
|
||||
system choosing randomly?
|
||||
|
||||
- Distribute some doc from here to the right files if it turns out to be correct:
|
||||
- AnimationDetails is a script-useable copy of animation state, analogous to EntityItemProperties, but without anything equivalent to editEntity.
|
||||
But what's the intended difference vs AnimationObjection? Maybe AnimationDetails is to Animation as AnimationObject is to AnimationPointer?
|
||||
- AnimationDetails is a script-useable copy of animation state, analogous to EntityItemProperties, but without anything
|
||||
equivalent to editEntity.
|
||||
But what's the intended difference vs AnimationObjection? Maybe AnimationDetails is to Animation as AnimationObject
|
||||
is to AnimationPointer?
|
||||
*/
|
||||
|
||||
#ifndef __hifi__Rig__
|
||||
|
@ -51,7 +55,7 @@ public:
|
|||
const QList<AnimationHandlePointer>& getRunningAnimations() const { return _runningAnimations; }
|
||||
void deleteAnimations();
|
||||
|
||||
float initJointStates(QVector<JointState> states, glm::mat4 parentTransform);
|
||||
float initJointStates(QVector<JointState> states, glm::mat4 parentTransform, int neckJointIndex);
|
||||
bool jointStatesEmpty() { return _jointStates.isEmpty(); };
|
||||
int getJointStateCount() const { return _jointStates.size(); }
|
||||
|
||||
|
@ -60,11 +64,12 @@ public:
|
|||
void reset(const QVector<FBXJoint>& fbxJoints);
|
||||
bool getJointStateRotation(int index, glm::quat& rotation) const;
|
||||
void applyJointRotationDelta(int jointIndex, const glm::quat& delta, bool constrain, float priority);
|
||||
JointState getJointState(int jointIndex) const;
|
||||
JointState getJointState(int jointIndex) const; // XXX
|
||||
bool getVisibleJointState(int index, glm::quat& rotation) const;
|
||||
void clearJointState(int index);
|
||||
void clearJointStates();
|
||||
void clearJointAnimationPriority(int index);
|
||||
float getJointAnimatinoPriority(int index);
|
||||
void setJointAnimatinoPriority(int index, float newPriority);
|
||||
void setJointState(int index, bool valid, const glm::quat& rotation, float priority);
|
||||
void restoreJointRotation(int index, float fraction, float priority);
|
||||
|
@ -102,11 +107,23 @@ public:
|
|||
virtual void updateJointState(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; }
|
||||
|
||||
protected:
|
||||
QVector<JointState> _jointStates;
|
||||
|
||||
QSet<AnimationHandlePointer> _animationHandles;
|
||||
QList<AnimationHandlePointer> _runningAnimations;
|
||||
|
||||
JointState maybeCauterizeHead(int jointIndex) const;
|
||||
void initHeadBones();
|
||||
bool _isFirstPerson = false;
|
||||
std::vector<int> _headBones;
|
||||
bool _jointsAreDirty = false;
|
||||
int _neckJointIndex = -1;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__Rig__) */
|
||||
|
|
|
@ -478,7 +478,7 @@ 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);
|
||||
_boundingRadius = _rig->initJointStates(states, parentTransform, geometry.neckJointIndex);
|
||||
}
|
||||
|
||||
bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const glm::vec3& direction, float& distance,
|
||||
|
@ -1341,28 +1341,6 @@ void Model::simulate(float deltaTime, bool fullUpdate) {
|
|||
}
|
||||
}
|
||||
|
||||
void Model::updateClusterMatrices() {
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
glm::mat4 modelToWorld = glm::mat4_cast(_rotation);
|
||||
for (int i = 0; i < _meshStates.size(); i++) {
|
||||
MeshState& state = _meshStates[i];
|
||||
const FBXMesh& mesh = geometry.meshes.at(i);
|
||||
if (_showTrueJointTransforms) {
|
||||
for (int j = 0; j < mesh.clusters.size(); j++) {
|
||||
const FBXCluster& cluster = mesh.clusters.at(j);
|
||||
state.clusterMatrices[j] =
|
||||
modelToWorld * _rig->getJointTransform(cluster.jointIndex) * cluster.inverseBindMatrix;
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < mesh.clusters.size(); j++) {
|
||||
const FBXCluster& cluster = mesh.clusters.at(j);
|
||||
state.clusterMatrices[j] =
|
||||
modelToWorld * _rig->getJointVisibleTransform(cluster.jointIndex) * cluster.inverseBindMatrix;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Model::simulateInternal(float deltaTime) {
|
||||
// update the world space transforms for all joints
|
||||
|
||||
|
|
|
@ -308,9 +308,6 @@ protected:
|
|||
_calculatedMeshTrianglesValid = false;
|
||||
}
|
||||
|
||||
// rebuild the clusterMatrices from the current jointStates
|
||||
void updateClusterMatrices();
|
||||
|
||||
// hook for derived classes to be notified when setUrl invalidates the current model.
|
||||
virtual void onInvalidate() {};
|
||||
|
||||
|
|
Loading…
Reference in a new issue