mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 14:37:46 +02:00
WIP checkin
* AnimManipulator: added absolute and relative position and translation support * Rig: added _overrideFlags and _overridePoses for script overrides.
This commit is contained in:
parent
516aff2ee0
commit
80eb247b9c
10 changed files with 258 additions and 87 deletions
|
@ -75,7 +75,7 @@ function updateJoints(factor){
|
||||||
for (var i = 0; i < startPoseAndTransition.length; i++){
|
for (var i = 0; i < startPoseAndTransition.length; i++){
|
||||||
var scaledTransition = Vec3.multiply(startPoseAndTransition[i].transition, factor);
|
var scaledTransition = Vec3.multiply(startPoseAndTransition[i].transition, factor);
|
||||||
var rotation = Vec3.sum(startPoseAndTransition[i].start, scaledTransition);
|
var rotation = Vec3.sum(startPoseAndTransition[i].start, scaledTransition);
|
||||||
MyAvatar.setJointData(startPoseAndTransition[i].joint, Quat.fromVec3Degrees( rotation ));
|
MyAvatar.setJointRotation(startPoseAndTransition[i].joint, Quat.fromVec3Degrees( rotation ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,7 +282,8 @@ function update(deltaTime){
|
||||||
MyAvatar.position.z != avatarOldPosition.z ||
|
MyAvatar.position.z != avatarOldPosition.z ||
|
||||||
locationChanged) {
|
locationChanged) {
|
||||||
avatarOldPosition = MyAvatar.position;
|
avatarOldPosition = MyAvatar.position;
|
||||||
|
|
||||||
|
/*
|
||||||
var SEARCH_RADIUS = 50;
|
var SEARCH_RADIUS = 50;
|
||||||
var foundModels = Entities.findEntities(MyAvatar.position, SEARCH_RADIUS);
|
var foundModels = Entities.findEntities(MyAvatar.position, SEARCH_RADIUS);
|
||||||
// Let's remove indicator that got out of radius
|
// Let's remove indicator that got out of radius
|
||||||
|
@ -306,6 +307,7 @@ function update(deltaTime){
|
||||||
if (hiddingSeats && passedTime >= animationLenght) {
|
if (hiddingSeats && passedTime >= animationLenght) {
|
||||||
showIndicators(true);
|
showIndicators(true);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var oldHost = location.hostname;
|
var oldHost = location.hostname;
|
||||||
|
|
|
@ -104,7 +104,7 @@
|
||||||
"data": {
|
"data": {
|
||||||
"alpha": 0.0,
|
"alpha": 0.0,
|
||||||
"joints": [
|
"joints": [
|
||||||
{ "var": "lean", "jointName": "Spine" }
|
{ "type": "absoluteRotation", "jointName": "Spine", "var": "lean" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"children": []
|
"children": []
|
||||||
|
|
|
@ -605,9 +605,9 @@ void SkeletonModel::computeBoundingShape() {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// AJT: REMOVE HARDCODED BOUNDING VOLUME
|
// AJT: REMOVE HARDCODED BOUNDING VOLUME
|
||||||
_boundingCapsuleRadius = 0.5f;
|
_boundingCapsuleRadius = 0.3f;
|
||||||
_boundingCapsuleHeight = 2.0f;
|
_boundingCapsuleHeight = 1.3f;
|
||||||
_boundingCapsuleLocalOffset = glm::vec3(0.0f, 1.0f, 0.0f);
|
_boundingCapsuleLocalOffset = glm::vec3(0.0f, -0.25f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float alpha) {
|
void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float alpha) {
|
||||||
|
|
|
@ -46,39 +46,15 @@ const AnimPoseVec& AnimManipulator::overlay(const AnimVariantMap& animVars, floa
|
||||||
|
|
||||||
if (jointVar.jointIndex >= 0) {
|
if (jointVar.jointIndex >= 0) {
|
||||||
|
|
||||||
AnimPose defaultAbsPose;
|
// use the underPose as our default value if we can.
|
||||||
AnimPose defaultRelPose;
|
AnimPose defaultRelPose;
|
||||||
AnimPose parentAbsPose = AnimPose::identity;
|
|
||||||
if (jointVar.jointIndex <= (int)underPoses.size()) {
|
if (jointVar.jointIndex <= (int)underPoses.size()) {
|
||||||
|
|
||||||
// jointVar is an absolute rotation, if it is not set we will use the underPose as our default value
|
|
||||||
defaultRelPose = underPoses[jointVar.jointIndex];
|
defaultRelPose = underPoses[jointVar.jointIndex];
|
||||||
defaultAbsPose = _skeleton->getAbsolutePose(jointVar.jointIndex, underPoses);
|
|
||||||
defaultAbsPose.rot = animVars.lookup(jointVar.var, defaultAbsPose.rot);
|
|
||||||
|
|
||||||
// because jointVar is absolute, we must use an absolute parent frame to convert into a relative pose.
|
|
||||||
int parentIndex = _skeleton->getParentIndex(jointVar.jointIndex);
|
|
||||||
if (parentIndex >= 0) {
|
|
||||||
parentAbsPose = _skeleton->getAbsolutePose(parentIndex, underPoses);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// jointVar is an absolute rotation, if it is not set we will use the bindPose as our default value
|
|
||||||
defaultRelPose = AnimPose::identity;
|
defaultRelPose = AnimPose::identity;
|
||||||
defaultAbsPose = _skeleton->getAbsoluteBindPose(jointVar.jointIndex);
|
|
||||||
defaultAbsPose.rot = animVars.lookup(jointVar.var, defaultAbsPose.rot);
|
|
||||||
|
|
||||||
// because jointVar is absolute, we must use an absolute parent frame to convert into a relative pose
|
|
||||||
// here we use the bind pose
|
|
||||||
int parentIndex = _skeleton->getParentIndex(jointVar.jointIndex);
|
|
||||||
if (parentIndex >= 0) {
|
|
||||||
parentAbsPose = _skeleton->getAbsoluteBindPose(parentIndex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert from absolute to relative
|
AnimPose relPose = computeRelativePoseFromJointVar(animVars, jointVar, defaultRelPose, underPoses);
|
||||||
AnimPose relPose = parentAbsPose.inverse() * defaultAbsPose;
|
|
||||||
|
|
||||||
// blend with underPose
|
// blend with underPose
|
||||||
::blend(1, &defaultRelPose, &relPose, _alpha, &_poses[jointVar.jointIndex]);
|
::blend(1, &defaultRelPose, &relPose, _alpha, &_poses[jointVar.jointIndex]);
|
||||||
|
@ -114,3 +90,44 @@ const AnimPoseVec& AnimManipulator::getPosesInternal() const {
|
||||||
void AnimManipulator::addJointVar(const JointVar& jointVar) {
|
void AnimManipulator::addJointVar(const JointVar& jointVar) {
|
||||||
_jointVars.push_back(jointVar);
|
_jointVars.push_back(jointVar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AnimManipulator::removeAllJointVars() {
|
||||||
|
_jointVars.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimPose AnimManipulator::computeRelativePoseFromJointVar(const AnimVariantMap& animVars, const JointVar& jointVar,
|
||||||
|
const AnimPose& defaultRelPose, const AnimPoseVec& underPoses) {
|
||||||
|
|
||||||
|
AnimPose defaultAbsPose = _skeleton->getAbsolutePose(jointVar.jointIndex, underPoses);
|
||||||
|
|
||||||
|
if (jointVar.type == JointVar::Type::AbsoluteRotation || jointVar.type == JointVar::Type::AbsolutePosition) {
|
||||||
|
|
||||||
|
if (jointVar.type == JointVar::Type::AbsoluteRotation) {
|
||||||
|
defaultAbsPose.rot = animVars.lookup(jointVar.var, defaultAbsPose.rot);
|
||||||
|
} else if (jointVar.type == JointVar::Type::AbsolutePosition) {
|
||||||
|
defaultAbsPose.trans = animVars.lookup(jointVar.var, defaultAbsPose.trans);
|
||||||
|
}
|
||||||
|
|
||||||
|
// because jointVar is absolute, we must use an absolute parent frame to convert into a relative pose.
|
||||||
|
AnimPose parentAbsPose = AnimPose::identity;
|
||||||
|
int parentIndex = _skeleton->getParentIndex(jointVar.jointIndex);
|
||||||
|
if (parentIndex >= 0) {
|
||||||
|
parentAbsPose = _skeleton->getAbsolutePose(parentIndex, underPoses);
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert from absolute to relative
|
||||||
|
return parentAbsPose.inverse() * defaultAbsPose;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// override the default rel pose
|
||||||
|
AnimPose relPose = defaultRelPose;
|
||||||
|
if (jointVar.type == JointVar::Type::RelativeRotation) {
|
||||||
|
relPose.rot = animVars.lookup(jointVar.var, defaultRelPose.rot);
|
||||||
|
} else if (jointVar.type == JointVar::Type::RelativePosition) {
|
||||||
|
relPose.trans = animVars.lookup(jointVar.var, defaultRelPose.trans);
|
||||||
|
}
|
||||||
|
|
||||||
|
return relPose;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -30,19 +30,33 @@ public:
|
||||||
virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) override;
|
virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) override;
|
||||||
|
|
||||||
struct JointVar {
|
struct JointVar {
|
||||||
JointVar(const QString& varIn, const QString& jointNameIn) : var(varIn), jointName(jointNameIn), jointIndex(-1), hasPerformedJointLookup(false) {}
|
enum class Type {
|
||||||
|
AbsoluteRotation = 0,
|
||||||
|
AbsolutePosition,
|
||||||
|
RelativeRotation,
|
||||||
|
RelativePosition,
|
||||||
|
NumTypes
|
||||||
|
};
|
||||||
|
|
||||||
|
JointVar(const QString& varIn, const QString& jointNameIn, Type typeIn) : var(varIn), jointName(jointNameIn), type(typeIn), jointIndex(-1), hasPerformedJointLookup(false) {}
|
||||||
QString var = "";
|
QString var = "";
|
||||||
QString jointName = "";
|
QString jointName = "";
|
||||||
|
Type type = Type::AbsoluteRotation;
|
||||||
int jointIndex = -1;
|
int jointIndex = -1;
|
||||||
bool hasPerformedJointLookup = false;
|
bool hasPerformedJointLookup = false;
|
||||||
|
bool isRelative = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
void addJointVar(const JointVar& jointVar);
|
void addJointVar(const JointVar& jointVar);
|
||||||
|
void removeAllJointVars();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// for AnimDebugDraw rendering
|
// for AnimDebugDraw rendering
|
||||||
virtual const AnimPoseVec& getPosesInternal() const override;
|
virtual const AnimPoseVec& getPosesInternal() const override;
|
||||||
|
|
||||||
|
AnimPose computeRelativePoseFromJointVar(const AnimVariantMap& animVars, const JointVar& jointVar,
|
||||||
|
const AnimPose& defaultRelPose, const AnimPoseVec& underPoses);
|
||||||
|
|
||||||
AnimPoseVec _poses;
|
AnimPoseVec _poses;
|
||||||
float _alpha;
|
float _alpha;
|
||||||
QString _alphaVar;
|
QString _alphaVar;
|
||||||
|
|
|
@ -55,6 +55,41 @@ static const char* animNodeTypeToString(AnimNode::Type type) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static AnimNode::Type stringToAnimNodeType(const QString& str) {
|
||||||
|
// O(n), move to map when number of types becomes large.
|
||||||
|
const int NUM_TYPES = static_cast<int>(AnimNode::Type::NumTypes);
|
||||||
|
for (int i = 0; i < NUM_TYPES; i++) {
|
||||||
|
AnimNode::Type type = static_cast<AnimNode::Type>(i);
|
||||||
|
if (str == animNodeTypeToString(type)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return AnimNode::Type::NumTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* animManipulatorJointVarTypeToString(AnimManipulator::JointVar::Type type) {
|
||||||
|
switch (type) {
|
||||||
|
case AnimManipulator::JointVar::Type::AbsoluteRotation: return "absoluteRotation";
|
||||||
|
case AnimManipulator::JointVar::Type::AbsolutePosition: return "absolutePosition";
|
||||||
|
case AnimManipulator::JointVar::Type::RelativeRotation: return "relativeRotation";
|
||||||
|
case AnimManipulator::JointVar::Type::RelativePosition: return "relativePosition";
|
||||||
|
case AnimManipulator::JointVar::Type::NumTypes: return nullptr;
|
||||||
|
};
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static AnimManipulator::JointVar::Type stringToAnimManipulatorJointVarType(const QString& str) {
|
||||||
|
// O(n), move to map when number of types becomes large.
|
||||||
|
const int NUM_TYPES = static_cast<int>(AnimManipulator::JointVar::Type::NumTypes);
|
||||||
|
for (int i = 0; i < NUM_TYPES; i++) {
|
||||||
|
AnimManipulator::JointVar::Type type = static_cast<AnimManipulator::JointVar::Type>(i);
|
||||||
|
if (str == animManipulatorJointVarTypeToString(type)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return AnimManipulator::JointVar::Type::NumTypes;
|
||||||
|
}
|
||||||
|
|
||||||
static NodeLoaderFunc animNodeTypeToLoaderFunc(AnimNode::Type type) {
|
static NodeLoaderFunc animNodeTypeToLoaderFunc(AnimNode::Type type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case AnimNode::Type::Clip: return loadClipNode;
|
case AnimNode::Type::Clip: return loadClipNode;
|
||||||
|
@ -120,17 +155,6 @@ static NodeProcessFunc animNodeTypeToProcessFunc(AnimNode::Type type) {
|
||||||
} \
|
} \
|
||||||
float NAME = (float)NAME##_VAL.toDouble()
|
float NAME = (float)NAME##_VAL.toDouble()
|
||||||
|
|
||||||
static AnimNode::Type stringToEnum(const QString& str) {
|
|
||||||
// O(n), move to map when number of types becomes large.
|
|
||||||
const int NUM_TYPES = static_cast<int>(AnimNode::Type::NumTypes);
|
|
||||||
for (int i = 0; i < NUM_TYPES; i++) {
|
|
||||||
AnimNode::Type type = static_cast<AnimNode::Type>(i);
|
|
||||||
if (str == animNodeTypeToString(type)) {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return AnimNode::Type::NumTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
static AnimNode::Pointer loadNode(const QJsonObject& jsonObj, const QUrl& jsonUrl) {
|
static AnimNode::Pointer loadNode(const QJsonObject& jsonObj, const QUrl& jsonUrl) {
|
||||||
auto idVal = jsonObj.value("id");
|
auto idVal = jsonObj.value("id");
|
||||||
|
@ -146,7 +170,7 @@ static AnimNode::Pointer loadNode(const QJsonObject& jsonObj, const QUrl& jsonUr
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
QString typeStr = typeVal.toString();
|
QString typeStr = typeVal.toString();
|
||||||
AnimNode::Type type = stringToEnum(typeStr);
|
AnimNode::Type type = stringToAnimNodeType(typeStr);
|
||||||
if (type == AnimNode::Type::NumTypes) {
|
if (type == AnimNode::Type::NumTypes) {
|
||||||
qCCritical(animation) << "AnimNodeLoader, unknown node type" << typeStr << ", id =" << id << ", url =" << jsonUrl.toDisplayString();
|
qCCritical(animation) << "AnimNodeLoader, unknown node type" << typeStr << ", id =" << id << ", url =" << jsonUrl.toDisplayString();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -355,10 +379,17 @@ static AnimNode::Pointer loadManipulatorNode(const QJsonObject& jsonObj, const Q
|
||||||
}
|
}
|
||||||
auto jointObj = jointValue.toObject();
|
auto jointObj = jointValue.toObject();
|
||||||
|
|
||||||
READ_STRING(var, jointObj, id, jsonUrl, nullptr);
|
READ_STRING(type, jointObj, id, jsonUrl, nullptr);
|
||||||
READ_STRING(jointName, jointObj, id, jsonUrl, nullptr);
|
READ_STRING(jointName, jointObj, id, jsonUrl, nullptr);
|
||||||
|
READ_STRING(var, jointObj, id, jsonUrl, nullptr);
|
||||||
|
|
||||||
AnimManipulator::JointVar jointVar(var, jointName);
|
AnimManipulator::JointVar::Type jointVarType = stringToAnimManipulatorJointVarType(type);
|
||||||
|
if (jointVarType == AnimManipulator::JointVar::Type::NumTypes) {
|
||||||
|
qCCritical(animation) << "AnimNodeLoader, bad type in \"joints\", id =" << id << ", url =" << jsonUrl.toDisplayString();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimManipulator::JointVar jointVar(var, jointName, jointVarType);
|
||||||
node->addJointVar(jointVar);
|
node->addJointVar(jointVar);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -78,25 +78,40 @@ void AvatarRig::setHandPosition(int jointIndex,
|
||||||
|
|
||||||
void AvatarRig::setJointTranslation(int index, bool valid, const glm::vec3& translation, float priority) {
|
void AvatarRig::setJointTranslation(int index, bool valid, const glm::vec3& translation, float priority) {
|
||||||
if (index != -1 && index < _jointStates.size()) {
|
if (index != -1 && index < _jointStates.size()) {
|
||||||
JointState& state = _jointStates[index];
|
|
||||||
if (valid) {
|
// AJT: LEGACY
|
||||||
state.setTranslation(translation, priority);
|
{
|
||||||
} else {
|
JointState& state = _jointStates[index];
|
||||||
state.restoreTranslation(1.0f, priority);
|
if (valid) {
|
||||||
|
state.setTranslation(translation, priority);
|
||||||
|
} else {
|
||||||
|
state.restoreTranslation(1.0f, priority);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_overrideFlags[index] = true;
|
||||||
|
_overridePoses[index].trans = translation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AvatarRig::setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority) {
|
void AvatarRig::setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority) {
|
||||||
if (index != -1 && index < _jointStates.size()) {
|
if (index != -1 && index < _jointStates.size()) {
|
||||||
JointState& state = _jointStates[index];
|
|
||||||
if (valid) {
|
// AJT: LEGACY
|
||||||
state.setRotationInConstrainedFrame(rotation, priority);
|
{
|
||||||
state.setTranslation(translation, priority);
|
JointState& state = _jointStates[index];
|
||||||
} else {
|
if (valid) {
|
||||||
state.restoreRotation(1.0f, priority);
|
state.setRotationInConstrainedFrame(rotation, priority);
|
||||||
state.restoreTranslation(1.0f, priority);
|
state.setTranslation(translation, priority);
|
||||||
|
} else {
|
||||||
|
state.restoreRotation(1.0f, priority);
|
||||||
|
state.restoreTranslation(1.0f, priority);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_overrideFlags[index] = true;
|
||||||
|
_overridePoses[index].rot = rotation;
|
||||||
|
_overridePoses[index].trans = translation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,20 @@
|
||||||
|
|
||||||
void EntityRig::setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority) {
|
void EntityRig::setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority) {
|
||||||
if (index != -1 && index < _jointStates.size()) {
|
if (index != -1 && index < _jointStates.size()) {
|
||||||
JointState& state = _jointStates[index];
|
|
||||||
if (valid) {
|
// AJT: LEGACY
|
||||||
state.setRotationInConstrainedFrame(rotation, priority);
|
{
|
||||||
// state.setTranslation(translation, priority);
|
JointState& state = _jointStates[index];
|
||||||
} else {
|
if (valid) {
|
||||||
state.restoreRotation(1.0f, priority);
|
state.setRotationInConstrainedFrame(rotation, priority);
|
||||||
// state.restoreTranslation(1.0f, priority);
|
// state.setTranslation(translation, priority);
|
||||||
|
} else {
|
||||||
|
state.restoreRotation(1.0f, priority);
|
||||||
|
// state.restoreTranslation(1.0f, priority);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_overrideFlags[index] = true;
|
||||||
|
_overridePoses[index].rot = rotation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,16 +23,28 @@
|
||||||
#include "AnimClip.h"
|
#include "AnimClip.h"
|
||||||
#include "IKTarget.h"
|
#include "IKTarget.h"
|
||||||
|
|
||||||
|
#ifdef NDEBUG
|
||||||
|
#define ASSERT()
|
||||||
|
#else
|
||||||
|
#define ASSERT(cond) \
|
||||||
|
do { \
|
||||||
|
if (!(cond)) { \
|
||||||
|
int* ptr = nullptr; \
|
||||||
|
*ptr = 10; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
void Rig::overrideAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame) {
|
void Rig::overrideAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame) {
|
||||||
|
|
||||||
// find an unused AnimClip clipNode
|
// find an unused AnimClip clipNode
|
||||||
std::shared_ptr<AnimClip> clip;
|
std::shared_ptr<AnimClip> clip;
|
||||||
if (_userAnimState == UserAnimState::None || _userAnimState == UserAnimState::B) {
|
if (_userAnimState == UserAnimState::None || _userAnimState == UserAnimState::B) {
|
||||||
_userAnimState = UserAnimState::A;
|
_userAnimState = UserAnimState::A;
|
||||||
clip = std::dynamic_pointer_cast<AnimClip>(_animNode->getChild((int)_userAnimState));
|
clip = std::dynamic_pointer_cast<AnimClip>(_animNode->findByName("userAnimA"));
|
||||||
} else if (_userAnimState == UserAnimState::A) {
|
} else if (_userAnimState == UserAnimState::A) {
|
||||||
_userAnimState = UserAnimState::B;
|
_userAnimState = UserAnimState::B;
|
||||||
clip = std::dynamic_pointer_cast<AnimClip>(_animNode->getChild((int)_userAnimState));
|
clip = std::dynamic_pointer_cast<AnimClip>(_animNode->findByName("userAnimB"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// set parameters
|
// set parameters
|
||||||
|
@ -132,6 +144,10 @@ void Rig::destroyAnimGraph() {
|
||||||
_animSkeleton = nullptr;
|
_animSkeleton = nullptr;
|
||||||
_animLoader = nullptr;
|
_animLoader = nullptr;
|
||||||
_animNode = nullptr;
|
_animNode = nullptr;
|
||||||
|
_relativePoses.clear();
|
||||||
|
_absolutePoses.clear();
|
||||||
|
_overridePoses.clear();
|
||||||
|
_overrideFlags.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rig::initJointStates(const FBXGeometry& geometry, glm::mat4 modelOffset, int rootJointIndex,
|
void Rig::initJointStates(const FBXGeometry& geometry, glm::mat4 modelOffset, int rootJointIndex,
|
||||||
|
@ -139,7 +155,18 @@ void Rig::initJointStates(const FBXGeometry& geometry, glm::mat4 modelOffset, in
|
||||||
int rightHandJointIndex, int rightElbowJointIndex, int rightShoulderJointIndex) {
|
int rightHandJointIndex, int rightElbowJointIndex, int rightShoulderJointIndex) {
|
||||||
|
|
||||||
_animSkeleton = std::make_shared<AnimSkeleton>(geometry);
|
_animSkeleton = std::make_shared<AnimSkeleton>(geometry);
|
||||||
_relativePoses.resize(_animSkeleton->getNumJoints());
|
|
||||||
|
_relativePoses.clear();
|
||||||
|
_relativePoses.resize(_animSkeleton->getNumJoints(), AnimPose::identity);
|
||||||
|
|
||||||
|
_absolutePoses.clear();
|
||||||
|
_absolutePoses.resize(_animSkeleton->getNumJoints(), AnimPose::identity);
|
||||||
|
|
||||||
|
_overridePoses.clear();
|
||||||
|
_overridePoses.resize(_animSkeleton->getNumJoints(), AnimPose::identity);
|
||||||
|
|
||||||
|
_overrideFlags.clear();
|
||||||
|
_overrideFlags.resize(_animSkeleton->getNumJoints(), true);
|
||||||
|
|
||||||
// AJT: LEGACY
|
// AJT: LEGACY
|
||||||
{
|
{
|
||||||
|
@ -264,14 +291,25 @@ bool Rig::getJointStateTranslation(int index, glm::vec3& translation) const {
|
||||||
|
|
||||||
void Rig::clearJointState(int index) {
|
void Rig::clearJointState(int index) {
|
||||||
if (index != -1 && index < _jointStates.size()) {
|
if (index != -1 && index < _jointStates.size()) {
|
||||||
|
// AJT: REMOVE
|
||||||
|
/*
|
||||||
JointState& state = _jointStates[index];
|
JointState& state = _jointStates[index];
|
||||||
state.setRotationInConstrainedFrame(glm::quat(), 0.0f);
|
state.setRotationInConstrainedFrame(glm::quat(), 0.0f);
|
||||||
state.setTranslation(state.getDefaultTranslationInConstrainedFrame(), 0.0f);
|
state.setTranslation(state.getDefaultTranslationInConstrainedFrame(), 0.0f);
|
||||||
|
*/
|
||||||
|
_overrideFlags[index] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rig::clearJointStates() {
|
void Rig::clearJointStates() {
|
||||||
_jointStates.clear();
|
// AJT: LEGACY
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
_jointStates.clear();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
_overrideFlags.clear();
|
||||||
|
_overrideFlags.resize(_animSkeleton->getNumJoints());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rig::clearJointAnimationPriority(int index) {
|
void Rig::clearJointAnimationPriority(int index) {
|
||||||
|
@ -375,12 +413,33 @@ 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// AJT: test if _absolutePoses are the same as jointTransforms
|
||||||
|
glm::mat4 newMat = _absolutePoses[jointIndex];
|
||||||
|
glm::mat4 oldMat = _jointStates[jointIndex].getTransform();
|
||||||
|
|
||||||
|
const float EPSILON = 0.0001f;
|
||||||
|
if (glm::length(newMat[0] - oldMat[0]) > EPSILON ||
|
||||||
|
glm::length(newMat[1] - oldMat[1]) > EPSILON ||
|
||||||
|
glm::length(newMat[2] - oldMat[2]) > EPSILON ||
|
||||||
|
glm::length(newMat[3] - oldMat[3]) > EPSILON) {
|
||||||
|
|
||||||
|
// error?
|
||||||
|
qCDebug(animation) << "AJT: mismatch for joint[" << jointIndex;
|
||||||
|
qCDebug(animation) << "AJT: oldMat = " << AnimPose(oldMat);
|
||||||
|
qCDebug(animation) << "AJT: newMat = " << AnimPose(newMat);
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// AJT: LEGACY
|
||||||
return _jointStates[jointIndex].getTransform();
|
return _jointStates[jointIndex].getTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rig::calcAnimAlpha(float speed, const std::vector<float>& referenceSpeeds, float* alphaOut) const {
|
void Rig::calcAnimAlpha(float speed, const std::vector<float>& referenceSpeeds, float* alphaOut) const {
|
||||||
|
|
||||||
assert(referenceSpeeds.size() > 0);
|
ASSERT(referenceSpeeds.size() > 0);
|
||||||
|
|
||||||
// calculate alpha from linear combination of referenceSpeeds.
|
// calculate alpha from linear combination of referenceSpeeds.
|
||||||
float alpha = 0.0f;
|
float alpha = 0.0f;
|
||||||
|
@ -664,33 +723,38 @@ void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) {
|
||||||
|
|
||||||
// evaluate the animation
|
// evaluate the animation
|
||||||
AnimNode::Triggers triggersOut;
|
AnimNode::Triggers triggersOut;
|
||||||
AnimPoseVec poses = _animNode->evaluate(_animVars, deltaTime, triggersOut);
|
_relativePoses = _animNode->evaluate(_animVars, deltaTime, triggersOut);
|
||||||
|
if (_relativePoses.size() != _animSkeleton->getNumJoints()) {
|
||||||
|
// animations haven't been loaded yet.
|
||||||
|
_relativePoses.resize(_animSkeleton->getNumJoints(), AnimPose::identity);
|
||||||
|
}
|
||||||
_animVars.clearTriggers();
|
_animVars.clearTriggers();
|
||||||
for (auto& trigger : triggersOut) {
|
for (auto& trigger : triggersOut) {
|
||||||
_animVars.setTrigger(trigger);
|
_animVars.setTrigger(trigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearJointStatePriorities();
|
// AJT: LEGACY
|
||||||
|
{
|
||||||
|
clearJointStatePriorities();
|
||||||
|
|
||||||
// copy poses into jointStates
|
// copy poses into jointStates
|
||||||
const float PRIORITY = 1.0f;
|
const float PRIORITY = 1.0f;
|
||||||
for (size_t i = 0; i < poses.size(); i++) {
|
for (size_t i = 0; i < _relativePoses.size(); i++) {
|
||||||
setJointRotationInConstrainedFrame((int)i, glm::inverse(_animSkeleton->getRelativeBindPose(i).rot) * poses[i].rot, PRIORITY, 1.0f);
|
setJointRotationInConstrainedFrame((int)i, glm::inverse(_animSkeleton->getRelativeBindPose(i).rot) * _relativePoses[i].rot, PRIORITY, 1.0f);
|
||||||
setJointTranslation((int)i, true, poses[i].trans, PRIORITY);
|
setJointTranslation((int)i, true, _relativePoses[i].trans, PRIORITY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AJT: REMOVE
|
|
||||||
/*
|
|
||||||
for (int i = 0; i < _jointStates.size(); i++) {
|
|
||||||
updateJointState(i, rootTransform);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
setModelOffset(rootTransform);
|
setModelOffset(rootTransform);
|
||||||
|
//applyOverridePoses();
|
||||||
buildAbsolutePoses();
|
buildAbsolutePoses();
|
||||||
|
|
||||||
for (int i = 0; i < _jointStates.size(); i++) {
|
// AJT: LEGACY
|
||||||
_jointStates[i].resetTransformChanged();
|
{
|
||||||
|
for (int i = 0; i < _jointStates.size(); i++) {
|
||||||
|
_jointStates[i].resetTransformChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1154,12 +1218,29 @@ bool Rig::getModelOffset(glm::vec3& modelOffsetOut) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Rig::applyOverridePoses() {
|
||||||
|
if (!_animSkeleton) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(_animSkeleton->getNumJoints() == _relativePoses.size());
|
||||||
|
ASSERT(_animSkeleton->getNumJoints() == _overrideFlags.size());
|
||||||
|
ASSERT(_animSkeleton->getNumJoints() == _overridePoses.size());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < _overrideFlags.size(); i++) {
|
||||||
|
if (_overrideFlags[i]) {
|
||||||
|
_relativePoses[i] = _overridePoses[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Rig::buildAbsolutePoses() {
|
void Rig::buildAbsolutePoses() {
|
||||||
if (!_animSkeleton) {
|
if (!_animSkeleton) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(_animSkeleton->getNumJoints() == _relativePoses.size());
|
ASSERT(_animSkeleton->getNumJoints() == _relativePoses.size());
|
||||||
|
|
||||||
_absolutePoses.resize(_relativePoses.size());
|
_absolutePoses.resize(_relativePoses.size());
|
||||||
for (int i = 0; i < (int)_relativePoses.size(); i++) {
|
for (int i = 0; i < (int)_relativePoses.size(); i++) {
|
||||||
int parentIndex = _animSkeleton->getParentIndex(i);
|
int parentIndex = _animSkeleton->getParentIndex(i);
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include <QScriptValue>
|
#include <QScriptValue>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "JointState.h" // We might want to change this (later) to something that doesn't depend on gpu, fbx and model. -HRS
|
#include "JointState.h" // We might want to change this (later) to something that doesn't depend on gpu, fbx and model. -HRS
|
||||||
|
|
||||||
|
@ -165,6 +166,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void updateAnimationStateHandlers();
|
void updateAnimationStateHandlers();
|
||||||
|
void applyOverridePoses();
|
||||||
void buildAbsolutePoses();
|
void buildAbsolutePoses();
|
||||||
|
|
||||||
void updateLeanJoint(int index, float leanSideways, float leanForward, float torsoTwist);
|
void updateLeanJoint(int index, float leanSideways, float leanForward, float torsoTwist);
|
||||||
|
@ -178,6 +180,8 @@ public:
|
||||||
AnimPose _modelOffset;
|
AnimPose _modelOffset;
|
||||||
AnimPoseVec _relativePoses;
|
AnimPoseVec _relativePoses;
|
||||||
AnimPoseVec _absolutePoses;
|
AnimPoseVec _absolutePoses;
|
||||||
|
AnimPoseVec _overridePoses;
|
||||||
|
std::vector<bool> _overrideFlags;
|
||||||
|
|
||||||
int _rootJointIndex { -1 };
|
int _rootJointIndex { -1 };
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue