mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Made JointState transforms private.
Also changed some function names to be more descriptive. Using "Hybrid" to describe frame with world-rotation + model-local-origin.
This commit is contained in:
parent
4eb4334ed8
commit
9e60b758df
5 changed files with 144 additions and 39 deletions
|
@ -378,7 +378,7 @@ void Avatar::simulateAttachments(float deltaTime) {
|
||||||
model->setLODDistance(getLODDistance());
|
model->setLODDistance(getLODDistance());
|
||||||
}
|
}
|
||||||
if (_skeletonModel.getJointPosition(jointIndex, jointPosition) &&
|
if (_skeletonModel.getJointPosition(jointIndex, jointPosition) &&
|
||||||
_skeletonModel.getJointRotation(jointIndex, jointRotation)) {
|
_skeletonModel.getJointRotationInWorldFrame(jointIndex, jointRotation)) {
|
||||||
model->setTranslation(jointPosition + jointRotation * attachment.translation * _scale);
|
model->setTranslation(jointPosition + jointRotation * attachment.translation * _scale);
|
||||||
model->setRotation(jointRotation * attachment.rotation);
|
model->setRotation(jointRotation * attachment.rotation);
|
||||||
model->setScale(_skeletonModel.getScale() * attachment.scale);
|
model->setScale(_skeletonModel.getScale() * attachment.scale);
|
||||||
|
|
|
@ -49,7 +49,7 @@ void FaceModel::simulate(float deltaTime, bool fullUpdate) {
|
||||||
void FaceModel::maybeUpdateNeckRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) {
|
void FaceModel::maybeUpdateNeckRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) {
|
||||||
// get the rotation axes in joint space and use them to adjust the rotation
|
// get the rotation axes in joint space and use them to adjust the rotation
|
||||||
glm::mat3 axes = glm::mat3_cast(_rotation);
|
glm::mat3 axes = glm::mat3_cast(_rotation);
|
||||||
glm::mat3 inverse = glm::mat3(glm::inverse(parentState._transform * glm::translate(state.getDefaultTranslationInParentFrame()) *
|
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.getHybridTransform() * glm::translate(state.getDefaultTranslationInParentFrame()) *
|
||||||
joint.preTransform * glm::mat4_cast(joint.preRotation)));
|
joint.preTransform * glm::mat4_cast(joint.preRotation)));
|
||||||
state._rotation = glm::angleAxis(- RADIANS_PER_DEGREE * _owningHead->getFinalRoll(), glm::normalize(inverse * axes[2]))
|
state._rotation = glm::angleAxis(- RADIANS_PER_DEGREE * _owningHead->getFinalRoll(), glm::normalize(inverse * axes[2]))
|
||||||
* glm::angleAxis(RADIANS_PER_DEGREE * _owningHead->getFinalYaw(), glm::normalize(inverse * axes[1]))
|
* glm::angleAxis(RADIANS_PER_DEGREE * _owningHead->getFinalYaw(), glm::normalize(inverse * axes[1]))
|
||||||
|
@ -59,7 +59,7 @@ void FaceModel::maybeUpdateNeckRotation(const JointState& parentState, const FBX
|
||||||
|
|
||||||
void FaceModel::maybeUpdateEyeRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) {
|
void FaceModel::maybeUpdateEyeRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) {
|
||||||
// likewise with the eye joints
|
// likewise with the eye joints
|
||||||
glm::mat4 inverse = glm::inverse(parentState._transform * glm::translate(state.getDefaultTranslationInParentFrame()) *
|
glm::mat4 inverse = glm::inverse(parentState.getHybridTransform() * glm::translate(state.getDefaultTranslationInParentFrame()) *
|
||||||
joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation));
|
joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation));
|
||||||
glm::vec3 front = glm::vec3(inverse * glm::vec4(_owningHead->getFinalOrientation() * IDENTITY_FRONT, 0.0f));
|
glm::vec3 front = glm::vec3(inverse * glm::vec4(_owningHead->getFinalOrientation() * IDENTITY_FRONT, 0.0f));
|
||||||
glm::vec3 lookAt = glm::vec3(inverse * glm::vec4(_owningHead->getLookAtPosition() +
|
glm::vec3 lookAt = glm::vec3(inverse * glm::vec4(_owningHead->getLookAtPosition() +
|
||||||
|
|
|
@ -221,9 +221,7 @@ void SkeletonModel::updateJointState(int index) {
|
||||||
Model::updateJointState(index);
|
Model::updateJointState(index);
|
||||||
|
|
||||||
if (index == _geometry->getFBXGeometry().rootJointIndex) {
|
if (index == _geometry->getFBXGeometry().rootJointIndex) {
|
||||||
state._transform[3][0] = 0.0f;
|
state.clearTransformTranslation();
|
||||||
state._transform[3][1] = 0.0f;
|
|
||||||
state._transform[3][2] = 0.0f;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,7 +231,7 @@ void SkeletonModel::maybeUpdateLeanRotation(const JointState& parentState, const
|
||||||
}
|
}
|
||||||
// get the rotation axes in joint space and use them to adjust the rotation
|
// get the rotation axes in joint space and use them to adjust the rotation
|
||||||
glm::mat3 axes = glm::mat3_cast(_rotation);
|
glm::mat3 axes = glm::mat3_cast(_rotation);
|
||||||
glm::mat3 inverse = glm::mat3(glm::inverse(parentState._transform * glm::translate(state.getDefaultTranslationInParentFrame()) *
|
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.getHybridTransform() * glm::translate(state.getDefaultTranslationInParentFrame()) *
|
||||||
joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation)));
|
joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation)));
|
||||||
state._rotation = glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getFinalLeanSideways(),
|
state._rotation = glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getFinalLeanSideways(),
|
||||||
glm::normalize(inverse * axes[2])) * glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getFinalLeanForward(),
|
glm::normalize(inverse * axes[2])) * glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getFinalLeanForward(),
|
||||||
|
@ -259,11 +257,11 @@ void SkeletonModel::renderJointConstraints(int jointIndex) {
|
||||||
do {
|
do {
|
||||||
const FBXJoint& joint = geometry.joints.at(jointIndex);
|
const FBXJoint& joint = geometry.joints.at(jointIndex);
|
||||||
const JointState& jointState = _jointStates.at(jointIndex);
|
const JointState& jointState = _jointStates.at(jointIndex);
|
||||||
glm::vec3 position = extractTranslation(jointState._transform) + _translation;
|
glm::vec3 position = extractTranslation(jointState.getHybridTransform()) + _translation;
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(position.x, position.y, position.z);
|
glTranslatef(position.x, position.y, position.z);
|
||||||
glm::quat parentRotation = (joint.parentIndex == -1) ? _rotation : _jointStates.at(joint.parentIndex)._combinedRotation;
|
glm::quat parentRotation = (joint.parentIndex == -1) ? _rotation : _rotation * _jointStates.at(joint.parentIndex).getRotationInModelFrame();
|
||||||
glm::vec3 rotationAxis = glm::axis(parentRotation);
|
glm::vec3 rotationAxis = glm::axis(parentRotation);
|
||||||
glRotatef(glm::degrees(glm::angle(parentRotation)), rotationAxis.x, rotationAxis.y, rotationAxis.z);
|
glRotatef(glm::degrees(glm::angle(parentRotation)), rotationAxis.x, rotationAxis.y, rotationAxis.z);
|
||||||
float fanScale = directionSize * 0.75f;
|
float fanScale = directionSize * 0.75f;
|
||||||
|
@ -296,7 +294,7 @@ void SkeletonModel::renderJointConstraints(int jointIndex) {
|
||||||
}
|
}
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
renderOrientationDirections(position, jointState._combinedRotation, directionSize);
|
renderOrientationDirections(position, _rotation * jointState.getRotationInModelFrame(), directionSize);
|
||||||
jointIndex = joint.parentIndex;
|
jointIndex = joint.parentIndex;
|
||||||
|
|
||||||
} while (jointIndex != -1 && geometry.joints.at(jointIndex).isFree);
|
} while (jointIndex != -1 && geometry.joints.at(jointIndex).isFree);
|
||||||
|
@ -416,7 +414,7 @@ bool SkeletonModel::getNeckParentRotation(glm::quat& neckParentRotation) const {
|
||||||
if (geometry.neckJointIndex == -1) {
|
if (geometry.neckJointIndex == -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return getJointRotation(geometry.joints.at(geometry.neckJointIndex).parentIndex, neckParentRotation);
|
return getJointRotationInWorldFrame(geometry.joints.at(geometry.neckJointIndex).parentIndex, neckParentRotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkeletonModel::getEyePositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition) const {
|
bool SkeletonModel::getEyePositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition) const {
|
||||||
|
|
|
@ -144,11 +144,26 @@ QVector<JointState> Model::createJointStates(const FBXGeometry& geometry) {
|
||||||
jointStates.append(state);
|
jointStates.append(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compute model transforms
|
||||||
|
int numJoints = jointStates.size();
|
||||||
|
for (int i = 0; i < numJoints; ++i) {
|
||||||
|
JointState& state = jointStates[i];
|
||||||
|
const FBXJoint& joint = state.getFBXJoint();
|
||||||
|
int parentIndex = joint.parentIndex;
|
||||||
|
if (parentIndex == -1) {
|
||||||
|
_rootIndex = i;
|
||||||
|
glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset;
|
||||||
|
state.computeTransformInModelFrame(parentTransform);
|
||||||
|
} else {
|
||||||
|
const JointState& parentState = jointStates.at(parentIndex);
|
||||||
|
state.computeTransformInModelFrame(parentState.getTransformInModelFrame());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// compute transforms
|
// compute transforms
|
||||||
// Unfortunately, the joints are not neccessarily in order from parents to children,
|
// Unfortunately, the joints are not neccessarily in order from parents to children,
|
||||||
// so we must iterate over the list multiple times until all are set correctly.
|
// so we must iterate over the list multiple times until all are set correctly.
|
||||||
QVector<bool> jointIsSet;
|
QVector<bool> jointIsSet;
|
||||||
int numJoints = jointStates.size();
|
|
||||||
jointIsSet.fill(false, numJoints);
|
jointIsSet.fill(false, numJoints);
|
||||||
int numJointsSet = 0;
|
int numJointsSet = 0;
|
||||||
int lastNumJointsSet = -1;
|
int lastNumJointsSet = -1;
|
||||||
|
@ -169,7 +184,8 @@ QVector<JointState> Model::createJointStates(const FBXGeometry& geometry) {
|
||||||
jointIsSet[i] = true;
|
jointIsSet[i] = true;
|
||||||
} else if (jointIsSet[parentIndex]) {
|
} else if (jointIsSet[parentIndex]) {
|
||||||
const JointState& parentState = jointStates.at(parentIndex);
|
const JointState& parentState = jointStates.at(parentIndex);
|
||||||
state.computeTransforms(parentState._transform, parentState._combinedRotation);
|
glm::quat parentRotation = _rotation * parentState.getRotationInModelFrame();
|
||||||
|
state.computeTransforms(parentState.getHybridTransform(), parentRotation);
|
||||||
++numJointsSet;
|
++numJointsSet;
|
||||||
jointIsSet[i] = true;
|
jointIsSet[i] = true;
|
||||||
}
|
}
|
||||||
|
@ -624,11 +640,12 @@ bool Model::getJointPosition(int jointIndex, glm::vec3& position) const {
|
||||||
if (jointIndex == -1 || _jointStates.isEmpty()) {
|
if (jointIndex == -1 || _jointStates.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
position = _translation + extractTranslation(_jointStates[jointIndex]._transform);
|
position = _translation + extractTranslation(_jointStates[jointIndex].getHybridTransform());
|
||||||
|
//position = _translation + _rotation * _jointState[jointIndex].getPositionInModelFrame();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Model::getJointRotation(int jointIndex, glm::quat& rotation, bool fromBind) const {
|
bool Model::getJointRotationInWorldFrame(int jointIndex, glm::quat& rotation, bool fromBind) const {
|
||||||
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
if (jointIndex == -1 || jointIndex >= _jointStates.size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -848,11 +865,12 @@ void Model::updateShapePositions() {
|
||||||
for (int i = 0; i < _jointStates.size(); i++) {
|
for (int i = 0; i < _jointStates.size(); i++) {
|
||||||
const FBXJoint& joint = geometry.joints[i];
|
const FBXJoint& joint = geometry.joints[i];
|
||||||
// shape position and rotation need to be in world-frame
|
// shape position and rotation need to be in world-frame
|
||||||
glm::vec3 jointToShapeOffset = uniformScale * (_jointStates[i]._combinedRotation * joint.shapePosition);
|
glm::quat rotationInWorldFrame = _rotation * _jointStates[i].getRotationInModelFrame();
|
||||||
glm::vec3 worldPosition = extractTranslation(_jointStates[i]._transform) + jointToShapeOffset + _translation;
|
glm::vec3 jointToShapeOffset = uniformScale * (rotationInWorldFrame * joint.shapePosition);
|
||||||
|
glm::vec3 worldPosition = extractTranslation(_jointStates[i].getHybridTransform()) + jointToShapeOffset + _translation;
|
||||||
Shape* shape = _jointShapes[i];
|
Shape* shape = _jointShapes[i];
|
||||||
shape->setPosition(worldPosition);
|
shape->setPosition(worldPosition);
|
||||||
shape->setRotation(_jointStates[i]._combinedRotation * joint.shapeRotation);
|
shape->setRotation(rotationInWorldFrame * joint.shapeRotation);
|
||||||
float distance = glm::distance(worldPosition, _translation) + shape->getBoundingRadius();
|
float distance = glm::distance(worldPosition, _translation) + shape->getBoundingRadius();
|
||||||
if (distance > _boundingRadius) {
|
if (distance > _boundingRadius) {
|
||||||
_boundingRadius = distance;
|
_boundingRadius = distance;
|
||||||
|
@ -874,12 +892,12 @@ bool Model::findRayIntersection(const glm::vec3& origin, const glm::vec3& direct
|
||||||
float radiusScale = extractUniformScale(_scale);
|
float radiusScale = extractUniformScale(_scale);
|
||||||
for (int i = 0; i < _jointStates.size(); i++) {
|
for (int i = 0; i < _jointStates.size(); i++) {
|
||||||
const FBXJoint& joint = geometry.joints[i];
|
const FBXJoint& joint = geometry.joints[i];
|
||||||
glm::vec3 end = extractTranslation(_jointStates[i]._transform);
|
glm::vec3 end = extractTranslation(_jointStates[i].getHybridTransform());
|
||||||
float endRadius = joint.boneRadius * radiusScale;
|
float endRadius = joint.boneRadius * radiusScale;
|
||||||
glm::vec3 start = end;
|
glm::vec3 start = end;
|
||||||
float startRadius = joint.boneRadius * radiusScale;
|
float startRadius = joint.boneRadius * radiusScale;
|
||||||
if (joint.parentIndex != -1) {
|
if (joint.parentIndex != -1) {
|
||||||
start = extractTranslation(_jointStates[joint.parentIndex]._transform);
|
start = extractTranslation(_jointStates[joint.parentIndex].getHybridTransform());
|
||||||
startRadius = geometry.joints[joint.parentIndex].boneRadius * radiusScale;
|
startRadius = geometry.joints[joint.parentIndex].boneRadius * radiusScale;
|
||||||
}
|
}
|
||||||
// for now, use average of start and end radii
|
// for now, use average of start and end radii
|
||||||
|
@ -1090,7 +1108,7 @@ void Model::simulateInternal(float deltaTime) {
|
||||||
glm::vec3 jointTranslation = _translation;
|
glm::vec3 jointTranslation = _translation;
|
||||||
glm::quat jointRotation = _rotation;
|
glm::quat jointRotation = _rotation;
|
||||||
getJointPosition(attachment.jointIndex, jointTranslation);
|
getJointPosition(attachment.jointIndex, jointTranslation);
|
||||||
getJointRotation(attachment.jointIndex, jointRotation);
|
getJointRotationInWorldFrame(attachment.jointIndex, jointRotation);
|
||||||
|
|
||||||
model->setTranslation(jointTranslation + jointRotation * attachment.translation * _scale);
|
model->setTranslation(jointTranslation + jointRotation * attachment.translation * _scale);
|
||||||
model->setRotation(jointRotation * attachment.rotation);
|
model->setRotation(jointRotation * attachment.rotation);
|
||||||
|
@ -1106,7 +1124,7 @@ void Model::simulateInternal(float deltaTime) {
|
||||||
const FBXMesh& mesh = geometry.meshes.at(i);
|
const FBXMesh& mesh = geometry.meshes.at(i);
|
||||||
for (int j = 0; j < mesh.clusters.size(); j++) {
|
for (int j = 0; j < mesh.clusters.size(); j++) {
|
||||||
const FBXCluster& cluster = mesh.clusters.at(j);
|
const FBXCluster& cluster = mesh.clusters.at(j);
|
||||||
state.clusterMatrices[j] = _jointStates[cluster.jointIndex]._transform * cluster.inverseBindMatrix;
|
state.clusterMatrices[j] = _jointStates[cluster.jointIndex].getHybridTransform() * cluster.inverseBindMatrix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1120,13 +1138,26 @@ void Model::updateJointState(int index) {
|
||||||
JointState& state = _jointStates[index];
|
JointState& state = _jointStates[index];
|
||||||
const FBXJoint& joint = state.getFBXJoint();
|
const FBXJoint& joint = state.getFBXJoint();
|
||||||
|
|
||||||
if (joint.parentIndex == -1) {
|
// compute model transforms
|
||||||
|
int parentIndex = joint.parentIndex;
|
||||||
|
if (parentIndex == -1) {
|
||||||
|
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||||
|
glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset;
|
||||||
|
state.computeTransformInModelFrame(parentTransform);
|
||||||
|
} else {
|
||||||
|
const JointState& parentState = _jointStates.at(parentIndex);
|
||||||
|
state.computeTransformInModelFrame(parentState.getTransformInModelFrame());
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute hybrid transforms
|
||||||
|
if (parentIndex == -1) {
|
||||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||||
glm::mat4 baseTransform = glm::mat4_cast(_rotation) * glm::scale(_scale) * glm::translate(_offset) * geometry.offset;
|
glm::mat4 baseTransform = glm::mat4_cast(_rotation) * glm::scale(_scale) * glm::translate(_offset) * geometry.offset;
|
||||||
state.computeTransforms(baseTransform, _rotation);
|
state.computeTransforms(baseTransform, _rotation);
|
||||||
} else {
|
} else {
|
||||||
const JointState& parentState = _jointStates.at(joint.parentIndex);
|
const JointState& parentState = _jointStates.at(parentIndex);
|
||||||
state.computeTransforms(parentState._transform, parentState._combinedRotation);
|
glm::quat parentRotation = _rotation * parentState.getRotationInModelFrame();
|
||||||
|
state.computeTransforms(parentState.getHybridTransform(), parentRotation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1162,7 +1193,7 @@ bool Model::setJointPosition(int jointIndex, const glm::vec3& translation, const
|
||||||
}
|
}
|
||||||
|
|
||||||
// then, we go from the joint upwards, rotating the end as close as possible to the target
|
// then, we go from the joint upwards, rotating the end as close as possible to the target
|
||||||
glm::vec3 endPosition = extractTranslation(_jointStates[jointIndex]._transform);
|
glm::vec3 endPosition = extractTranslation(_jointStates[jointIndex].getHybridTransform());
|
||||||
for (int j = 1; freeLineage.at(j - 1) != lastFreeIndex; j++) {
|
for (int j = 1; freeLineage.at(j - 1) != lastFreeIndex; j++) {
|
||||||
int index = freeLineage.at(j);
|
int index = freeLineage.at(j);
|
||||||
JointState& state = _jointStates[index];
|
JointState& state = _jointStates[index];
|
||||||
|
@ -1170,9 +1201,9 @@ bool Model::setJointPosition(int jointIndex, const glm::vec3& translation, const
|
||||||
if (!(joint.isFree || allIntermediatesFree)) {
|
if (!(joint.isFree || allIntermediatesFree)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
glm::vec3 jointPosition = extractTranslation(state._transform);
|
glm::vec3 jointPosition = extractTranslation(state.getHybridTransform());
|
||||||
glm::vec3 jointVector = endPosition - jointPosition;
|
glm::vec3 jointVector = endPosition - jointPosition;
|
||||||
glm::quat oldCombinedRotation = state._combinedRotation;
|
glm::quat oldCombinedRotation = _rotation * state.getRotationInModelFrame();
|
||||||
glm::quat combinedDelta;
|
glm::quat combinedDelta;
|
||||||
float combinedWeight;
|
float combinedWeight;
|
||||||
if (useRotation) {
|
if (useRotation) {
|
||||||
|
@ -1190,7 +1221,7 @@ bool Model::setJointPosition(int jointIndex, const glm::vec3& translation, const
|
||||||
for (int k = j - 1; k > 0; k--) {
|
for (int k = j - 1; k > 0; k--) {
|
||||||
int index = freeLineage.at(k);
|
int index = freeLineage.at(k);
|
||||||
updateJointState(index);
|
updateJointState(index);
|
||||||
positionSum += extractTranslation(_jointStates.at(index)._transform);
|
positionSum += extractTranslation(_jointStates.at(index).getHybridTransform());
|
||||||
}
|
}
|
||||||
glm::vec3 projectedCenterOfMass = glm::cross(jointVector,
|
glm::vec3 projectedCenterOfMass = glm::cross(jointVector,
|
||||||
glm::cross(positionSum / (j - 1.0f) - jointPosition, jointVector));
|
glm::cross(positionSum / (j - 1.0f) - jointPosition, jointVector));
|
||||||
|
@ -1202,7 +1233,7 @@ bool Model::setJointPosition(int jointIndex, const glm::vec3& translation, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.applyRotationDelta(combinedDelta, true, priority);
|
state.applyRotationDelta(combinedDelta, true, priority);
|
||||||
glm::quat actualDelta = state._combinedRotation * glm::inverse(oldCombinedRotation);
|
glm::quat actualDelta = _rotation * state.getRotationInModelFrame() * glm::inverse(oldCombinedRotation);
|
||||||
endPosition = actualDelta * jointVector + jointPosition;
|
endPosition = actualDelta * jointVector + jointPosition;
|
||||||
if (useRotation) {
|
if (useRotation) {
|
||||||
endRotation = actualDelta * endRotation;
|
endRotation = actualDelta * endRotation;
|
||||||
|
@ -1827,6 +1858,11 @@ void AnimationHandle::replaceMatchingPriorities(float newPriority) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::mat4 Model::getBaseTransform(const glm::mat4& geometryOffset) const {
|
||||||
|
//return glm::translate(_translation) * glm::mat4_cast(_rotation) * glm::scale(_scale) * glm::translate(_offset) * geometryOffset;
|
||||||
|
return glm::mat4_cast(_rotation) * glm::scale(_scale) * glm::translate(_offset) * geometryOffset;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// JointState TODO: move this class to its own files
|
// JointState TODO: move this class to its own files
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -1844,23 +1880,44 @@ void JointState::setFBXJoint(const FBXJoint* joint) {
|
||||||
|
|
||||||
void JointState::copyState(const JointState& state) {
|
void JointState::copyState(const JointState& state) {
|
||||||
_rotation = state._rotation;
|
_rotation = state._rotation;
|
||||||
_transform = state._transform;
|
|
||||||
|
_transformInModelFrame = state._transformInModelFrame;
|
||||||
|
_rotationInModelFrame = extractRotation(_transformInModelFrame);
|
||||||
_combinedRotation = state._combinedRotation;
|
_combinedRotation = state._combinedRotation;
|
||||||
|
_transform = state._transform;
|
||||||
|
|
||||||
_animationPriority = state._animationPriority;
|
_animationPriority = state._animationPriority;
|
||||||
// DO NOT copy _fbxJoint
|
// DO NOT copy _fbxJoint
|
||||||
}
|
}
|
||||||
|
|
||||||
void JointState::computeTransforms(const glm::mat4& baseTransform, const glm::quat& baseRotation) {
|
void JointState::computeTransformInModelFrame(const glm::mat4& parentTransform) {
|
||||||
|
glm::quat modifiedRotation = _fbxJoint->preRotation * _rotation * _fbxJoint->postRotation;
|
||||||
|
glm::mat4 modifiedTransform = _fbxJoint->preTransform * glm::mat4_cast(modifiedRotation) * _fbxJoint->postTransform;
|
||||||
|
_transformInModelFrame = parentTransform * glm::translate(_fbxJoint->translation) * modifiedTransform;
|
||||||
|
_rotationInModelFrame = extractRotation(_transformInModelFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::quat JointState::getRotationInWorldFrame(const glm::quat& baseRotation) const {
|
||||||
|
return baseRotation * _rotationInModelFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 JointState::getPositionInWorldFrame(const glm::quat& baseRotation, const glm::vec3& basePosition) const {
|
||||||
|
return basePosition + baseRotation * extractTranslation(_transformInModelFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JointState::computeTransforms(const glm::mat4& parentTransform, const glm::quat& baseRotation) {
|
||||||
assert(_fbxJoint != NULL);
|
assert(_fbxJoint != NULL);
|
||||||
glm::quat combinedRotation = _fbxJoint->preRotation * _rotation * _fbxJoint->postRotation;
|
|
||||||
_transform = baseTransform * glm::translate(_fbxJoint->translation) * _fbxJoint->preTransform
|
glm::quat modifiedRotation = _fbxJoint->preRotation * _rotation * _fbxJoint->postRotation;
|
||||||
* glm::mat4_cast(combinedRotation) * _fbxJoint->postTransform;
|
glm::mat4 modifiedTransform = _fbxJoint->preTransform * glm::mat4_cast(modifiedRotation) * _fbxJoint->postTransform;
|
||||||
_combinedRotation = baseRotation * combinedRotation;
|
_transform = parentTransform * glm::translate(_fbxJoint->translation) * modifiedTransform;
|
||||||
|
_combinedRotation = baseRotation * modifiedRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::quat JointState::getJointRotation(bool fromBind) const {
|
glm::quat JointState::getJointRotation(bool fromBind) const {
|
||||||
assert(_fbxJoint != NULL);
|
assert(_fbxJoint != NULL);
|
||||||
return _combinedRotation * (fromBind ? _fbxJoint->inverseBindRotation : _fbxJoint->inverseDefaultRotation);
|
return _combinedRotation * (fromBind ? _fbxJoint->inverseBindRotation : _fbxJoint->inverseDefaultRotation);
|
||||||
|
//return _rotationInModelFrame * (fromBind ? _fbxJoint->inverseBindRotation : _fbxJoint->inverseDefaultRotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JointState::restoreRotation(float fraction, float priority) {
|
void JointState::restoreRotation(float fraction, float priority) {
|
||||||
|
@ -1879,6 +1936,15 @@ void JointState::setRotation(const glm::quat& rotation, float priority) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JointState::clearTransformTranslation() {
|
||||||
|
_transform[3][0] = 0.0f;
|
||||||
|
_transform[3][1] = 0.0f;
|
||||||
|
_transform[3][2] = 0.0f;
|
||||||
|
_transformInModelFrame[3][0] = 0.0f;
|
||||||
|
_transformInModelFrame[3][1] = 0.0f;
|
||||||
|
_transformInModelFrame[3][2] = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
void JointState::applyRotationDelta(const glm::quat& delta, bool constrain, float priority) {
|
void JointState::applyRotationDelta(const glm::quat& delta, bool constrain, float priority) {
|
||||||
assert(_fbxJoint != NULL);
|
assert(_fbxJoint != NULL);
|
||||||
if (priority < _animationPriority) {
|
if (priority < _animationPriority) {
|
||||||
|
@ -1899,6 +1965,28 @@ void JointState::applyRotationDelta(const glm::quat& delta, bool constrain, floa
|
||||||
_rotation = newRotation;
|
_rotation = newRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void JointState::applyRotationDelta(const glm::quat& delta, bool constrain, float priority) {
|
||||||
|
assert(_fbxJoint != NULL);
|
||||||
|
if (priority < _animationPriority) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_animationPriority = priority;
|
||||||
|
if (!constrain || (_fbxJoint->rotationMin == glm::vec3(-PI, -PI, -PI) &&
|
||||||
|
_fbxJoint->rotationMax == glm::vec3(PI, PI, PI))) {
|
||||||
|
// no constraints
|
||||||
|
_rotation = _rotation * glm::inverse(_rotationInModelFrame) * delta * _rotationInModelFrame;
|
||||||
|
_rotationInModelFrame = delta * _rotationInModelFrame;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
glm::quat targetRotation = delta * _rotationInModelFrame;
|
||||||
|
glm::vec3 eulers = safeEulerAngles(_rotation * glm::inverse(_rotationInModelFrame) * targetRotation);
|
||||||
|
glm::quat newRotation = glm::quat(glm::clamp(eulers, _fbxJoint->rotationMin, _fbxJoint->rotationMax));
|
||||||
|
_rotationInModelFrame = _rotationInModelFrame * glm::inverse(_rotation) * newRotation;
|
||||||
|
_rotation = newRotation;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
const glm::vec3& JointState::getDefaultTranslationInParentFrame() const {
|
const glm::vec3& JointState::getDefaultTranslationInParentFrame() const {
|
||||||
assert(_fbxJoint != NULL);
|
assert(_fbxJoint != NULL);
|
||||||
return _fbxJoint->translation;
|
return _fbxJoint->translation;
|
||||||
|
|
|
@ -40,6 +40,15 @@ public:
|
||||||
|
|
||||||
void copyState(const JointState& state);
|
void copyState(const JointState& state);
|
||||||
|
|
||||||
|
void computeTransformInModelFrame(const glm::mat4& parentTransform);
|
||||||
|
const glm::mat4& getTransformInModelFrame() const { return _transformInModelFrame; }
|
||||||
|
|
||||||
|
glm::quat getRotationInModelFrame() const { return _rotationInModelFrame; }
|
||||||
|
glm::vec3 getPositionInModelFrame() const { return extractTranslation(_transformInModelFrame); }
|
||||||
|
|
||||||
|
glm::quat getRotationInWorldFrame(const glm::quat& baseRotation) const;
|
||||||
|
glm::vec3 getPositionInWorldFrame(const glm::quat& baseRotation, const glm::vec3& basePosition) const;
|
||||||
|
|
||||||
/// computes new _transform and _combinedRotation
|
/// computes new _transform and _combinedRotation
|
||||||
void computeTransforms(const glm::mat4& baseTransform, const glm::quat& baseRotation);
|
void computeTransforms(const glm::mat4& baseTransform, const glm::quat& baseRotation);
|
||||||
|
|
||||||
|
@ -54,14 +63,22 @@ public:
|
||||||
|
|
||||||
/// \param rotation is from bind- to world-frame
|
/// \param rotation is from bind- to world-frame
|
||||||
/// computes parent relative _rotation and sets that
|
/// computes parent relative _rotation and sets that
|
||||||
|
/// \warning no combined transforms are updated!
|
||||||
void setRotation(const glm::quat& rotation, float priority);
|
void setRotation(const glm::quat& rotation, float priority);
|
||||||
|
|
||||||
|
const glm::mat4& getHybridTransform() const { return _transform; }
|
||||||
|
const glm::quat& getRotationInWorldFrame() const { return _combinedRotation; }
|
||||||
|
void clearTransformTranslation();
|
||||||
|
|
||||||
glm::quat _rotation; // rotation relative to parent
|
glm::quat _rotation; // rotation relative to parent
|
||||||
glm::mat4 _transform; // rotation to world frame + translation in model frame
|
|
||||||
glm::quat _combinedRotation; // rotation from joint local to world frame
|
|
||||||
float _animationPriority; // the priority of the animation affecting this joint
|
float _animationPriority; // the priority of the animation affecting this joint
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
glm::mat4 _transformInModelFrame;
|
||||||
|
glm::quat _rotationInModelFrame;
|
||||||
|
glm::quat _combinedRotation; // rotation from joint local to world frame
|
||||||
|
glm::mat4 _transform; // rotation to world frame + translation in model frame
|
||||||
|
|
||||||
const FBXJoint* _fbxJoint; // JointState does NOT own its FBXJoint
|
const FBXJoint* _fbxJoint; // JointState does NOT own its FBXJoint
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -156,7 +173,7 @@ public:
|
||||||
int getLastFreeJointIndex(int jointIndex) const;
|
int getLastFreeJointIndex(int jointIndex) const;
|
||||||
|
|
||||||
bool getJointPosition(int jointIndex, glm::vec3& position) const;
|
bool getJointPosition(int jointIndex, glm::vec3& position) const;
|
||||||
bool getJointRotation(int jointIndex, glm::quat& rotation, bool fromBind = false) const;
|
bool getJointRotationInWorldFrame(int jointIndex, glm::quat& rotation, bool fromBind = false) const;
|
||||||
|
|
||||||
QStringList getJointNames() const;
|
QStringList getJointNames() const;
|
||||||
|
|
||||||
|
@ -199,6 +216,8 @@ public:
|
||||||
|
|
||||||
const CapsuleShape& getBoundingShape() const { return _boundingShape; }
|
const CapsuleShape& getBoundingShape() const { return _boundingShape; }
|
||||||
|
|
||||||
|
glm::mat4 getBaseTransform(const glm::mat4& geometryOffset) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
QSharedPointer<NetworkGeometry> _geometry;
|
QSharedPointer<NetworkGeometry> _geometry;
|
||||||
|
|
Loading…
Reference in a new issue