Clean up instantiation.

This commit is contained in:
Howard Stearns 2015-08-07 12:27:26 -07:00
parent a840a17106
commit 145b730f80
5 changed files with 85 additions and 136 deletions

View file

@ -18,16 +18,14 @@
#include "JointState.h"
JointState::JointState() :
_animationPriority(0.0f),
_transformChanged(true),
_rotationIsValid(false),
_positionInParentFrame(0.0f),
_distanceToParent(0.0f),
_constraint(NULL) {
JointState::~JointState() {
if (_constraint) {
delete _constraint;
_constraint = NULL;
}
}
JointState::JointState(const JointState& other) : _constraint(NULL) {
void JointState::copyState(const JointState& other) {
_transformChanged = other._transformChanged;
_transform = other._transform;
_rotationIsValid = other._rotationIsValid;
@ -36,14 +34,18 @@ JointState::JointState(const JointState& other) : _constraint(NULL) {
_positionInParentFrame = other._positionInParentFrame;
_distanceToParent = other._distanceToParent;
_animationPriority = other._animationPriority;
_visibleTransform = other._visibleTransform;
_visibleRotation = extractRotation(_visibleTransform);
_visibleRotationInConstrainedFrame = other._visibleRotationInConstrainedFrame;
// DO NOT copy _constraint
_name = other._name;
_isFree = other._isFree;
_boneRadius = other._boneRadius;
_parentIndex = other._parentIndex;
_translation = other._translation;
_defaultRotation = other._defaultRotation;
_inverseDefaultRotation = other._inverseDefaultRotation;
_translation = other._translation;
_rotationMin = other._rotationMin;
_rotationMax = other._rotationMax;
_preRotation = other._preRotation;
@ -52,49 +54,22 @@ JointState::JointState(const JointState& other) : _constraint(NULL) {
_postTransform = other._postTransform;
_inverseBindRotation = other._inverseBindRotation;
}
JointState::~JointState() {
delete _constraint;
_constraint = NULL;
if (_constraint) {
delete _constraint;
_constraint = NULL;
}
}
glm::quat JointState::getRotation() const {
if (!_rotationIsValid) {
const_cast<JointState*>(this)->_rotation = extractRotation(_transform);
const_cast<JointState*>(this)->_rotationIsValid = true;
}
return _rotation;
}
void JointState::setFBXJoint(const FBXJoint* joint) {
assert(joint != NULL);
_rotationInConstrainedFrame = joint->rotation;
_transformChanged = true;
_rotationIsValid = false;
_name = joint->name;
_isFree = joint->isFree;
_boneRadius = joint->boneRadius;
_parentIndex = joint->parentIndex;
_translation = joint->translation;
_defaultRotation = joint->rotation;
_inverseDefaultRotation = joint->inverseDefaultRotation;
_rotationMin = joint->rotationMin;
_rotationMax = joint->rotationMax;
_preRotation = joint->preRotation;
_postRotation = joint->postRotation;
_preTransform = joint->preTransform;
_postTransform = joint->postTransform;
_inverseBindRotation = joint->inverseBindRotation;
if (_constraint) {
delete _constraint;
_constraint = NULL;
}
JointState::JointState(const FBXJoint& joint) {
_rotationInConstrainedFrame = joint.rotation;
_name = joint.name;
_isFree = joint.isFree;
_boneRadius = joint.boneRadius;
_parentIndex = joint.parentIndex;
_translation = joint.translation;
_defaultRotation = joint.rotation;
_inverseDefaultRotation = joint.inverseDefaultRotation;
_rotationMin = joint.rotationMin;
_rotationMax = joint.rotationMax;
_preRotation = joint.preRotation;
_postRotation = joint.postRotation;
_preTransform = joint.preTransform;
_postTransform = joint.postTransform;
_inverseBindRotation = joint.inverseBindRotation;
}
void JointState::buildConstraint() {
@ -109,34 +84,13 @@ void JointState::buildConstraint() {
}
}
void JointState::copyState(const JointState& state) {
_animationPriority = state._animationPriority;
_transformChanged = state._transformChanged;
_transform = state._transform;
_rotationIsValid = state._rotationIsValid;
_rotation = state._rotation;
_rotationInConstrainedFrame = state._rotationInConstrainedFrame;
_positionInParentFrame = state._positionInParentFrame;
_distanceToParent = state._distanceToParent;
_visibleTransform = state._visibleTransform;
_visibleRotation = extractRotation(_visibleTransform);
_visibleRotationInConstrainedFrame = state._visibleRotationInConstrainedFrame;
// DO NOT copy _constraint
_name = state._name;
_isFree = state._isFree;
_boneRadius = state._boneRadius;
_parentIndex = state._parentIndex;
_defaultRotation = state._defaultRotation;
_inverseDefaultRotation = state._inverseDefaultRotation;
_translation = state._translation;
_rotationMin = state._rotationMin;
_rotationMax = state._rotationMax;
_preRotation = state._preRotation;
_postRotation = state._postRotation;
_preTransform = state._preTransform;
_postTransform = state._postTransform;
_inverseBindRotation = state._inverseBindRotation;
glm::quat JointState::getRotation() const {
if (!_rotationIsValid) {
const_cast<JointState*>(this)->_rotation = extractRotation(_transform);
const_cast<JointState*>(this)->_rotationIsValid = true;
}
return _rotation;
}
void JointState::initTransform(const glm::mat4& parentTransform) {

View file

@ -26,15 +26,13 @@ class AngularConstraint;
class JointState {
public:
JointState();
JointState(const JointState& other);
JointState() {}
JointState(const JointState& other) : _constraint(NULL) { copyState(other); }
JointState(const FBXJoint& joint);
~JointState();
void setFBXJoint(const FBXJoint* joint);
void buildConstraint();
void copyState(const JointState& state);
void buildConstraint();
void initTransform(const glm::mat4& parentTransform);
// if synchronousRotationCompute is true, then _transform is still computed synchronously,
// but _rotation will be asynchronously extracted
@ -98,9 +96,7 @@ public:
void slaveVisibleTransform();
float _animationPriority; // the priority of the animation affecting this joint
/// \return parent model-frame rotation
/// \return parent model-frame rotation
// (used to keep _rotation consistent when modifying _rotationInWorldFrame directly)
glm::quat computeParentRotation() const;
glm::quat computeVisibleParentRotation() const;
@ -118,19 +114,24 @@ public:
const QString& getName() const { return _name; }
float getBoneRadius() const { return _boneRadius; }
bool getIsFree() const { return _isFree; }
float getAnimationPriority() const { return _animationPriority; }
void setAnimationPriority(float priority) { _animationPriority = priority; }
private:
void setRotationInConstrainedFrameInternal(const glm::quat& targetRotation);
/// debug helper function
void loadBindRotation();
bool _transformChanged;
bool _transformChanged {true};
bool _rotationIsValid {false};
glm::vec3 _positionInParentFrame {0.0f}; // only changes when the Model is scaled
float _animationPriority {0.0f}; // the priority of the animation affecting this joint
float _distanceToParent {0.0f};
AngularConstraint* _constraint{nullptr}; // JointState owns its AngularConstraint
glm::mat4 _transform; // joint- to model-frame
bool _rotationIsValid;
glm::quat _rotation; // joint- to model-frame
glm::quat _rotationInConstrainedFrame; // rotation in frame where angular constraints would be applied
glm::vec3 _positionInParentFrame; // only changes when the Model is scaled
float _distanceToParent;
glm::mat4 _visibleTransform;
glm::quat _visibleRotation;
@ -139,8 +140,10 @@ private:
glm::quat _defaultRotation; // Not necessarilly bind rotation. See FBXJoint transform/bindTransform
glm::quat _inverseDefaultRotation;
glm::vec3 _translation;
float _boneRadius;
QString _name;
int _parentIndex;
bool _isFree;
float _boneRadius;
glm::vec3 _rotationMin;
glm::vec3 _rotationMax;
glm::quat _preRotation;
@ -148,9 +151,6 @@ private:
glm::mat4 _preTransform;
glm::mat4 _postTransform;
glm::quat _inverseBindRotation;
int _parentIndex;
QString _name;
AngularConstraint* _constraint; // JointState owns its AngularConstraint
};
#endif // hifi_JointState_h

View file

@ -299,20 +299,20 @@ void Rig::clearJointStates() {
void Rig::clearJointAnimationPriority(int index) {
if (index != -1 && index < _jointStates.size()) {
_jointStates[index]._animationPriority = 0.0f;
_jointStates[index].setAnimationPriority(0.0f);
}
}
float Rig::getJointAnimatinoPriority(int index) {
if (index != -1 && index < _jointStates.size()) {
return _jointStates[index]._animationPriority;
return _jointStates[index].getAnimationPriority();
}
return 0.0f;
}
void Rig::setJointAnimatinoPriority(int index, float newPriority) {
if (index != -1 && index < _jointStates.size()) {
_jointStates[index]._animationPriority = newPriority;
_jointStates[index].setAnimationPriority(newPriority);
}
}

View file

@ -226,9 +226,7 @@ QVector<JointState> Model::createJointStates(const FBXGeometry& geometry) {
for (int i = 0; i < geometry.joints.size(); ++i) {
const FBXJoint& joint = geometry.joints[i];
// store a pointer to the FBXJoint in the JointState
JointState state;
state.setFBXJoint(&joint);
JointState state(joint);
jointStates.append(state);
}
return jointStates;

View file

@ -47,39 +47,9 @@
#include "AvatarRig.h" // We might later test Rig vs AvatarRig separately, but for now, we're concentrating on the main use case.
#include "RigTests.h"
QTEST_MAIN(RigTests)
void RigTests::initTestCase() {
//#define FROM_FILE "/Users/howardstearns/howardHiFi/Zack.fbx"
#ifdef FROM_FILE
QFile file(FROM_FILE);
QCOMPARE(file.open(QIODevice::ReadOnly), true);
FBXGeometry geometry = readFBX(file.readAll(), QVariantHash());
#else
QUrl fbxUrl("https://s3.amazonaws.com/hifi-public/models/skeletons/Zack/Zack.fbx");
QNetworkReply* reply = OBJReader().request(fbxUrl, false); // Just a convenience hack for synchronoud http request
auto fbxHttpCode = !reply->isFinished() ? -1 : reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QCOMPARE(fbxHttpCode, 200);
FBXGeometry geometry = readFBX(reply->readAll(), QVariantHash());
#endif
QVector<JointState> jointStates;
for (int i = 0; i < geometry.joints.size(); ++i) {
// Note that if the geometry is stack allocated and goes away, so will the joints. Hence the heap copy here.
FBXJoint* joint = new FBXJoint(geometry.joints[i]);
JointState state;
state.setFBXJoint(joint);
jointStates.append(state);
}
_rig = std::make_shared<AvatarRig>();
_rig->initJointStates(jointStates, glm::mat4());
std::cout << "Rig is ready " << geometry.joints.count() << " joints " << std::endl;
}
static void reportJoint(int index, JointState joint) { // Handy for debugging
std::cout << "\n";
std::cout << index << " " << joint.getName.toUtf8().data() << "\n";
std::cout << index << " " << joint.getName().toUtf8().data() << "\n";
std::cout << " pos:" << joint.getPosition() << "/" << joint.getPositionInParentFrame() << " from " << joint.getParentIndex() << "\n";
std::cout << " rot:" << safeEulerAngles(joint.getRotation()) << "/" << safeEulerAngles(joint.getRotationInParentFrame()) << "/" << safeEulerAngles(joint.getRotationInBindFrame()) << "\n";
std::cout << "\n";
@ -101,7 +71,34 @@ static void reportSome(RigPointer rig) {
}
}
QTEST_MAIN(RigTests)
void RigTests::initTestCase() {
//#define FROM_FILE "/Users/howardstearns/howardHiFi/Zack.fbx"
#ifdef FROM_FILE
QFile file(FROM_FILE);
QCOMPARE(file.open(QIODevice::ReadOnly), true);
FBXGeometry geometry = readFBX(file.readAll(), QVariantHash());
#else
QUrl fbxUrl("https://s3.amazonaws.com/hifi-public/models/skeletons/Zack/Zack.fbx");
QNetworkReply* reply = OBJReader().request(fbxUrl, false); // Just a convenience hack for synchronoud http request
auto fbxHttpCode = !reply->isFinished() ? -1 : reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QCOMPARE(fbxHttpCode, 200);
FBXGeometry geometry = readFBX(reply->readAll(), QVariantHash());
#endif
QVector<JointState> jointStates;
for (int i = 0; i < geometry.joints.size(); ++i) {
JointState state(geometry.joints[i]);
jointStates.append(state);
}
_rig = std::make_shared<AvatarRig>();
_rig->initJointStates(jointStates, glm::mat4(), 0, 41, 40, 39, 17, 16, 15); // FIXME? get by name? do we really want to exclude the shoulder blades?
std::cout << "Rig is ready " << geometry.joints.count() << " joints " << std::endl;
reportAll(_rig);
}
void RigTests::initialPoseArmsDown() {
//reportAll(_rig);
reportSome(_rig);
}