add JointState::_positionInParentFrame

This commit is contained in:
Andrew Meadows 2014-07-14 15:18:34 -07:00
parent c5a5f8c5d4
commit 00544aa975
5 changed files with 25 additions and 15 deletions

View file

@ -589,7 +589,7 @@ float VERY_BIG_MASS = 1.0e6f;
// virtual
void SkeletonModel::buildShapes() {
if (!_geometry || _rootIndex == -1) {
if (_geometry == NULL || _jointStates.isEmpty()) {
return;
}
@ -743,7 +743,7 @@ void SkeletonModel::resetShapePositionsToDefaultPose() {
// Moves shapes to the joint default locations for debug visibility into
// how the bounding shape is computed.
if (!_geometry || _rootIndex == -1 || _shapes.isEmpty()) {
if (!_geometry || _shapes.isEmpty()) {
// geometry or joints have not yet been created
return;
}

View file

@ -76,17 +76,22 @@ void JointState::copyState(const JointState& state) {
// DO NOT copy _fbxJoint or _constraint
}
void JointState::initTransform(const glm::mat4& parentTransform) {
computeTransform(parentTransform);
_positionInParentFrame = glm::inverse(extractRotation(parentTransform)) * (extractTranslation(_transform) - extractTranslation(parentTransform));
}
void JointState::computeTransform(const glm::mat4& parentTransform) {
glm::quat rotationInConstrainedFrame = _fbxJoint->preRotation * _rotationInConstrainedFrame * _fbxJoint->postRotation;
glm::mat4 modifiedTransform = _fbxJoint->preTransform * glm::mat4_cast(rotationInConstrainedFrame) * _fbxJoint->postTransform;
_transform = parentTransform * glm::translate(_fbxJoint->translation) * modifiedTransform;
glm::mat4 rotationInParentFrame = _fbxJoint->preTransform * glm::mat4_cast(rotationInConstrainedFrame) * _fbxJoint->postTransform;
_transform = parentTransform * glm::translate(_fbxJoint->translation) * rotationInParentFrame;
_rotation = extractRotation(_transform);
}
void JointState::computeVisibleTransform(const glm::mat4& parentTransform) {
glm::quat rotationInConstrainedFrame = _fbxJoint->preRotation * _visibleRotationInConstrainedFrame * _fbxJoint->postRotation;
glm::mat4 modifiedTransform = _fbxJoint->preTransform * glm::mat4_cast(rotationInConstrainedFrame) * _fbxJoint->postTransform;
_visibleTransform = parentTransform * glm::translate(_fbxJoint->translation) * modifiedTransform;
glm::mat4 rotationInParentFrame = _fbxJoint->preTransform * glm::mat4_cast(rotationInConstrainedFrame) * _fbxJoint->postTransform;
_visibleTransform = parentTransform * glm::translate(_fbxJoint->translation) * rotationInParentFrame;
_visibleRotation = extractRotation(_visibleTransform);
}

View file

@ -32,6 +32,7 @@ public:
void updateConstraint();
void copyState(const JointState& state);
void initTransform(const glm::mat4& parentTransform);
void computeTransform(const glm::mat4& parentTransform);
void computeVisibleTransform(const glm::mat4& parentTransform);
@ -98,6 +99,7 @@ private:
glm::mat4 _transform; // joint- to model-frame
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
glm::mat4 _visibleTransform;
glm::quat _visibleRotation;

View file

@ -40,7 +40,6 @@ Model::Model(QObject* parent) :
_snapModelToCenter(false),
_snappedToCenter(false),
_showTrueJointTransforms(true),
_rootIndex(-1),
_lodDistance(0.0f),
_pupilDilation(0.0f),
_url("http://invalid.com") {
@ -126,6 +125,7 @@ void Model::setScaleInternal(const glm::vec3& scale) {
const float ONE_PERCENT = 0.01f;
if (relativeDeltaScale > ONE_PERCENT || scaleLength < EPSILON) {
_scale = scale;
initJointTransforms();
if (_shapes.size() > 0) {
clearShapes();
buildShapes();
@ -165,24 +165,26 @@ QVector<JointState> Model::createJointStates(const FBXGeometry& geometry) {
state.setFBXJoint(&joint);
jointStates.append(state);
}
return jointStates;
};
void Model::initJointTransforms() {
// compute model transforms
int numJoints = jointStates.size();
int numJoints = _jointStates.size();
for (int i = 0; i < numJoints; ++i) {
JointState& state = jointStates[i];
JointState& state = _jointStates[i];
const FBXJoint& joint = state.getFBXJoint();
int parentIndex = joint.parentIndex;
if (parentIndex == -1) {
_rootIndex = i;
const FBXGeometry& geometry = _geometry->getFBXGeometry();
// NOTE: in practice geometry.offset has a non-unity scale (rather than a translation)
glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset;
state.computeTransform(parentTransform);
state.initTransform(parentTransform);
} else {
const JointState& parentState = jointStates.at(parentIndex);
state.computeTransform(parentState.getTransform());
const JointState& parentState = _jointStates.at(parentIndex);
state.initTransform(parentState.getTransform());
}
}
return jointStates;
}
void Model::init() {
@ -560,6 +562,7 @@ bool Model::updateGeometry() {
// virtual
void Model::setJointStates(QVector<JointState> states) {
_jointStates = states;
initJointTransforms();
int numJoints = _jointStates.size();
float radius = 0.0f;

View file

@ -164,7 +164,6 @@ protected:
bool _snapModelToCenter; /// is the model's offset automatically adjusted to center around 0,0,0 in model space
bool _snappedToCenter; /// are we currently snapped to center
bool _showTrueJointTransforms;
int _rootIndex;
glm::vec3 _localLightDirections[MAX_LOCAL_LIGHTS];
glm::vec3 _localLightColors[MAX_LOCAL_LIGHTS];
@ -227,6 +226,7 @@ private:
void deleteGeometry();
void renderMeshes(float alpha, RenderMode mode, bool translucent, bool receiveShadows);
QVector<JointState> createJointStates(const FBXGeometry& geometry);
void initJointTransforms();
QSharedPointer<NetworkGeometry> _baseGeometry; ///< reference required to prevent collection of base
QSharedPointer<NetworkGeometry> _nextBaseGeometry;