mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 14:18:24 +02:00
merge from upstream
This commit is contained in:
commit
a3c6a4b9bc
4 changed files with 69 additions and 23 deletions
|
@ -195,7 +195,7 @@ private:
|
||||||
bool isMyAvatar() const { return true; }
|
bool isMyAvatar() const { return true; }
|
||||||
virtual int parseDataFromBuffer(const QByteArray& buffer);
|
virtual int parseDataFromBuffer(const QByteArray& buffer);
|
||||||
virtual glm::vec3 getSkeletonPosition() const;
|
virtual glm::vec3 getSkeletonPosition() const;
|
||||||
void updateLocalAABox();
|
|
||||||
glm::vec3 getScriptedMotorVelocity() const { return _scriptedMotorVelocity; }
|
glm::vec3 getScriptedMotorVelocity() const { return _scriptedMotorVelocity; }
|
||||||
float getScriptedMotorTimescale() const { return _scriptedMotorTimescale; }
|
float getScriptedMotorTimescale() const { return _scriptedMotorTimescale; }
|
||||||
QString getScriptedMotorFrame() const;
|
QString getScriptedMotorFrame() const;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <glm/gtx/vector_angle.hpp>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
#include "AnimationHandle.h"
|
#include "AnimationHandle.h"
|
||||||
|
@ -38,18 +39,15 @@ void Rig::removeAnimationHandle(const AnimationHandlePointer& handle) {
|
||||||
|
|
||||||
void Rig::startAnimation(const QString& url, float fps, float priority,
|
void Rig::startAnimation(const QString& url, float fps, float priority,
|
||||||
bool loop, bool hold, float firstFrame, float lastFrame, const QStringList& maskedJoints) {
|
bool loop, bool hold, float firstFrame, float lastFrame, const QStringList& maskedJoints) {
|
||||||
qCDebug(animation) << "startAnimation" << url << fps << priority << loop << hold << firstFrame << lastFrame << maskedJoints;
|
//qCDebug(animation) << "startAnimation" << url << fps << priority << loop << hold << firstFrame << lastFrame << maskedJoints;
|
||||||
AnimationHandlePointer handle = nullptr;
|
|
||||||
foreach (const AnimationHandlePointer& candidate, _animationHandles) {
|
foreach (const AnimationHandlePointer& candidate, _animationHandles) {
|
||||||
if (candidate->getURL() == url) {
|
if (candidate->getURL() == url) {
|
||||||
handle = candidate;
|
candidate->start();
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!handle) {
|
AnimationHandlePointer handle = createAnimationHandle();
|
||||||
handle = createAnimationHandle();
|
|
||||||
handle->setURL(url);
|
handle->setURL(url);
|
||||||
}
|
|
||||||
handle->setFPS(fps);
|
handle->setFPS(fps);
|
||||||
handle->setPriority(priority);
|
handle->setPriority(priority);
|
||||||
handle->setLoop(loop);
|
handle->setLoop(loop);
|
||||||
|
@ -63,18 +61,17 @@ void Rig::startAnimation(const QString& url, float fps, float priority,
|
||||||
void Rig::addAnimationByRole(const QString& role, const QString& url, float fps, float priority,
|
void Rig::addAnimationByRole(const QString& role, const QString& url, float fps, float priority,
|
||||||
bool loop, bool hold, float firstFrame, float lastFrame, const QStringList& maskedJoints, bool startAutomatically) {
|
bool loop, bool hold, float firstFrame, float lastFrame, const QStringList& maskedJoints, bool startAutomatically) {
|
||||||
// check for a configured animation for the role
|
// check for a configured animation for the role
|
||||||
qCDebug(animation) << "addAnimationByRole" << role << url << fps << priority << loop << hold << firstFrame << lastFrame << maskedJoints << startAutomatically;
|
//qCDebug(animation) << "addAnimationByRole" << role << url << fps << priority << loop << hold << firstFrame << lastFrame << maskedJoints << startAutomatically;
|
||||||
AnimationHandlePointer handle = nullptr;
|
|
||||||
foreach (const AnimationHandlePointer& candidate, _animationHandles) {
|
foreach (const AnimationHandlePointer& candidate, _animationHandles) {
|
||||||
if (candidate->getRole() == role) {
|
if (candidate->getRole() == role) {
|
||||||
handle = candidate;
|
if (startAutomatically) {
|
||||||
break;
|
candidate->start();
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!handle) {
|
AnimationHandlePointer handle = createAnimationHandle();
|
||||||
handle = createAnimationHandle();
|
|
||||||
handle->setRole(role);
|
handle->setRole(role);
|
||||||
}
|
|
||||||
handle->setURL(url);
|
handle->setURL(url);
|
||||||
handle->setFPS(fps);
|
handle->setFPS(fps);
|
||||||
handle->setPriority(priority);
|
handle->setPriority(priority);
|
||||||
|
@ -344,7 +341,45 @@ glm::mat4 Rig::getJointVisibleTransform(int jointIndex) const {
|
||||||
return maybeCauterizeHead(jointIndex).getVisibleTransform();
|
return maybeCauterizeHead(jointIndex).getVisibleTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rig::simulateInternal(float deltaTime, glm::mat4 parentTransform) {
|
void Rig::simulateInternal(float deltaTime, glm::mat4 parentTransform, const glm::vec3& worldPosition, const glm::quat& worldRotation) {
|
||||||
|
glm::vec3 front = worldRotation * IDENTITY_FRONT;
|
||||||
|
glm::vec3 delta = worldPosition - _lastPosition ;
|
||||||
|
float forwardSpeed = glm::dot(delta, front) / deltaTime;
|
||||||
|
float rotationalSpeed = glm::angle(front, _lastFront) / deltaTime;
|
||||||
|
bool isWalking = std::abs(forwardSpeed) > 0.01f;
|
||||||
|
bool isTurning = std::abs(rotationalSpeed) > 0.5f;
|
||||||
|
|
||||||
|
// Crude, until we have blending:
|
||||||
|
const float EXPECTED_INTERVAL = 1.0f / 60.0f;
|
||||||
|
if (deltaTime >= EXPECTED_INTERVAL) {
|
||||||
|
isTurning = isTurning && !isWalking; // Only one of walk/turn, walk wins.
|
||||||
|
isTurning = false; // FIXME
|
||||||
|
bool isIdle = !isWalking && !isTurning;
|
||||||
|
auto singleRole = [](bool walking, bool turning, bool idling) {
|
||||||
|
return walking ? "walk" : (turning ? "turn" : (idling ? "idle" : ""));
|
||||||
|
};
|
||||||
|
QString toStop = singleRole(_isWalking && !isWalking, _isTurning && !isTurning, _isIdle && !isIdle);
|
||||||
|
if (!toStop.isEmpty()) {
|
||||||
|
//qCDebug(animation) << "isTurning" << isTurning << "fronts" << front << _lastFront << glm::angle(front, _lastFront) << rotationalSpeed;
|
||||||
|
//stopAnimationByRole(toStop);
|
||||||
|
}
|
||||||
|
QString newRole = singleRole(isWalking && !_isWalking, isTurning && !_isTurning, isIdle && !_isIdle);
|
||||||
|
if (!newRole.isEmpty()) {
|
||||||
|
//startAnimationByRole(newRole);
|
||||||
|
qCDebug(animation) << deltaTime << ":" /*<< _lastPosition << worldPosition << "=>" */<< delta << "." << front << "=> " << forwardSpeed << newRole;
|
||||||
|
/*if (newRole == "idle") {
|
||||||
|
qCDebug(animation) << deltaTime << ":" << _lastPosition << worldPosition << "=>" << delta;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastPosition = worldPosition;
|
||||||
|
_positions[(++_positionIndex) % _positions.count()] = worldPosition; // exp. alt. to above line
|
||||||
|
_lastFront = front;
|
||||||
|
_isWalking = isWalking;
|
||||||
|
_isTurning = isTurning;
|
||||||
|
_isIdle = isIdle;
|
||||||
|
}
|
||||||
|
|
||||||
// update animations
|
// update animations
|
||||||
foreach (const AnimationHandlePointer& handle, _runningAnimations) {
|
foreach (const AnimationHandlePointer& handle, _runningAnimations) {
|
||||||
handle->simulate(deltaTime);
|
handle->simulate(deltaTime);
|
||||||
|
|
|
@ -71,8 +71,9 @@ 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());
|
float lastFrame = FLT_MAX, const QStringList& maskedJoints = QStringList());
|
||||||
void stopAnimationByRole(const QString& role);
|
void stopAnimationByRole(const QString& role);
|
||||||
void addAnimationByRole(const QString& role, const QString& url, float fps, float priority,
|
void addAnimationByRole(const QString& role, const QString& url = QString(), float fps = 30.0f,
|
||||||
bool loop, bool hold, float firstFrame, float lastFrame, const QStringList& maskedJoints, bool startAutomatically);
|
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, int neckJointIndex);
|
float initJointStates(QVector<JointState> states, glm::mat4 parentTransform, int neckJointIndex);
|
||||||
bool jointStatesEmpty() { return _jointStates.isEmpty(); };
|
bool jointStatesEmpty() { return _jointStates.isEmpty(); };
|
||||||
|
@ -107,7 +108,7 @@ public:
|
||||||
void setJointTransform(int jointIndex, glm::mat4 newTransform);
|
void setJointTransform(int jointIndex, glm::mat4 newTransform);
|
||||||
glm::mat4 getJointVisibleTransform(int jointIndex) const;
|
glm::mat4 getJointVisibleTransform(int jointIndex) const;
|
||||||
void setJointVisibleTransform(int jointIndex, glm::mat4 newTransform);
|
void setJointVisibleTransform(int jointIndex, glm::mat4 newTransform);
|
||||||
void simulateInternal(float deltaTime, glm::mat4 parentTransform);
|
void simulateInternal(float deltaTime, glm::mat4 parentTransform, const glm::vec3& worldPosition, const glm::quat& worldRotation);
|
||||||
bool setJointPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation, bool useRotation,
|
bool setJointPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation, bool useRotation,
|
||||||
int lastFreeIndex, bool allIntermediatesFree, const glm::vec3& alignment, float priority,
|
int lastFreeIndex, bool allIntermediatesFree, const glm::vec3& alignment, float priority,
|
||||||
const QVector<int>& freeLineage, glm::mat4 parentTransform);
|
const QVector<int>& freeLineage, glm::mat4 parentTransform);
|
||||||
|
@ -144,6 +145,16 @@ public:
|
||||||
std::vector<int> _headBones;
|
std::vector<int> _headBones;
|
||||||
bool _jointsAreDirty = false;
|
bool _jointsAreDirty = false;
|
||||||
int _neckJointIndex = -1;
|
int _neckJointIndex = -1;
|
||||||
};
|
|
||||||
|
bool _isWalking;
|
||||||
|
bool _isTurning;
|
||||||
|
bool _isIdle;
|
||||||
|
glm::vec3 _lastFront;
|
||||||
|
glm::vec3 _lastPosition;
|
||||||
|
// or, experimentally...
|
||||||
|
QVector<glm::vec3> _positions = QVector<glm::vec3>(4);
|
||||||
|
QVector<float> _timeIntervals = QVector<float>(4);
|
||||||
|
int _positionIndex;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__Rig__) */
|
#endif /* defined(__hifi__Rig__) */
|
||||||
|
|
|
@ -1346,7 +1346,7 @@ void Model::simulateInternal(float deltaTime) {
|
||||||
|
|
||||||
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;
|
||||||
_rig->simulateInternal(deltaTime, parentTransform);
|
_rig->simulateInternal(deltaTime, parentTransform, getTranslation(), getRotation());
|
||||||
|
|
||||||
_shapesAreDirty = !_shapes.isEmpty();
|
_shapesAreDirty = !_shapes.isEmpty();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue