merge from upstream

This commit is contained in:
Seth Alves 2015-07-27 09:29:18 -07:00
commit a3c6a4b9bc
4 changed files with 69 additions and 23 deletions
interface/src/avatar
libraries
animation/src
render-utils/src

View file

@ -195,7 +195,7 @@ private:
bool isMyAvatar() const { return true; }
virtual int parseDataFromBuffer(const QByteArray& buffer);
virtual glm::vec3 getSkeletonPosition() const;
void updateLocalAABox();
glm::vec3 getScriptedMotorVelocity() const { return _scriptedMotorVelocity; }
float getScriptedMotorTimescale() const { return _scriptedMotorTimescale; }
QString getScriptedMotorFrame() const;

View file

@ -9,6 +9,7 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <glm/gtx/vector_angle.hpp>
#include <queue>
#include "AnimationHandle.h"
@ -38,18 +39,15 @@ void Rig::removeAnimationHandle(const AnimationHandlePointer& handle) {
void Rig::startAnimation(const QString& url, float fps, float priority,
bool loop, bool hold, float firstFrame, float lastFrame, const QStringList& maskedJoints) {
qCDebug(animation) << "startAnimation" << url << fps << priority << loop << hold << firstFrame << lastFrame << maskedJoints;
AnimationHandlePointer handle = nullptr;
//qCDebug(animation) << "startAnimation" << url << fps << priority << loop << hold << firstFrame << lastFrame << maskedJoints;
foreach (const AnimationHandlePointer& candidate, _animationHandles) {
if (candidate->getURL() == url) {
handle = candidate;
break;
candidate->start();
return;
}
}
if (!handle) {
handle = createAnimationHandle();
handle->setURL(url);
}
AnimationHandlePointer handle = createAnimationHandle();
handle->setURL(url);
handle->setFPS(fps);
handle->setPriority(priority);
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,
bool loop, bool hold, float firstFrame, float lastFrame, const QStringList& maskedJoints, bool startAutomatically) {
// check for a configured animation for the role
qCDebug(animation) << "addAnimationByRole" << role << url << fps << priority << loop << hold << firstFrame << lastFrame << maskedJoints << startAutomatically;
AnimationHandlePointer handle = nullptr;
//qCDebug(animation) << "addAnimationByRole" << role << url << fps << priority << loop << hold << firstFrame << lastFrame << maskedJoints << startAutomatically;
foreach (const AnimationHandlePointer& candidate, _animationHandles) {
if (candidate->getRole() == role) {
handle = candidate;
break;
if (startAutomatically) {
candidate->start();
}
return;
}
}
if (!handle) {
handle = createAnimationHandle();
handle->setRole(role);
}
AnimationHandlePointer handle = createAnimationHandle();
handle->setRole(role);
handle->setURL(url);
handle->setFPS(fps);
handle->setPriority(priority);
@ -344,7 +341,45 @@ glm::mat4 Rig::getJointVisibleTransform(int jointIndex) const {
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
foreach (const AnimationHandlePointer& handle, _runningAnimations) {
handle->simulate(deltaTime);

View file

@ -71,8 +71,9 @@ public:
float priority = 1.0f, bool loop = false, bool hold = false, float firstFrame = 0.0f,
float lastFrame = FLT_MAX, const QStringList& maskedJoints = QStringList());
void stopAnimationByRole(const QString& role);
void addAnimationByRole(const QString& role, const QString& url, float fps, float priority,
bool loop, bool hold, float firstFrame, float lastFrame, const QStringList& maskedJoints, bool startAutomatically);
void addAnimationByRole(const QString& role, const QString& url = QString(), float fps = 30.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 initJointStates(QVector<JointState> states, glm::mat4 parentTransform, int neckJointIndex);
bool jointStatesEmpty() { return _jointStates.isEmpty(); };
@ -107,7 +108,7 @@ public:
void setJointTransform(int jointIndex, glm::mat4 newTransform);
glm::mat4 getJointVisibleTransform(int jointIndex) const;
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,
int lastFreeIndex, bool allIntermediatesFree, const glm::vec3& alignment, float priority,
const QVector<int>& freeLineage, glm::mat4 parentTransform);
@ -144,6 +145,16 @@ public:
std::vector<int> _headBones;
bool _jointsAreDirty = false;
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__) */

View file

@ -1346,7 +1346,7 @@ void Model::simulateInternal(float deltaTime) {
const FBXGeometry& geometry = _geometry->getFBXGeometry();
glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset;
_rig->simulateInternal(deltaTime, parentTransform);
_rig->simulateInternal(deltaTime, parentTransform, getTranslation(), getRotation());
_shapesAreDirty = !_shapes.isEmpty();