Constraint fix, apply constraints to wrists.

This commit is contained in:
Andrzej Kapolka 2013-11-12 15:43:11 -08:00
parent df30e3c851
commit a36f9d52af
4 changed files with 48 additions and 23 deletions

View file

@ -141,7 +141,8 @@ void SkeletonModel::applyPalmData(int jointIndex, const QVector<int>& fingerJoin
float sign = (jointIndex == geometry.rightHandJointIndex) ? 1.0f : -1.0f;
glm::quat palmRotation;
getJointRotation(jointIndex, palmRotation, true);
palmRotation = rotationBetween(palmRotation * geometry.palmDirection, palm.getNormal()) * palmRotation;
applyRotationDelta(jointIndex, rotationBetween(palmRotation * geometry.palmDirection, palm.getNormal()));
getJointRotation(jointIndex, palmRotation, true);
// sort the finger indices by raw x, get the average direction
QVector<IndexValue> fingerIndices;
@ -161,9 +162,9 @@ void SkeletonModel::applyPalmData(int jointIndex, const QVector<int>& fingerJoin
// rotate palm according to average finger direction
float directionLength = glm::length(direction);
if (directionLength > EPSILON) {
palmRotation = rotationBetween(palmRotation * glm::vec3(-sign, 0.0f, 0.0f), direction) * palmRotation;
applyRotationDelta(jointIndex, rotationBetween(palmRotation * glm::vec3(-sign, 0.0f, 0.0f), direction));
getJointRotation(jointIndex, palmRotation, true);
}
setJointRotation(jointIndex, palmRotation, true);
// no point in continuing if there are no fingers
if (palm.getNumFingers() == 0 || fingerJointIndices.isEmpty()) {

View file

@ -875,9 +875,10 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
glm::vec3 preRotation, rotation, postRotation;
glm::vec3 scale = glm::vec3(1.0f, 1.0f, 1.0f);
glm::vec3 scalePivot, rotationPivot;
bool rotationMinX = false, rotationMinY = false, rotationMinZ = false;
bool rotationMaxX = false, rotationMaxY = false, rotationMaxZ = false;
glm::vec3 rotationMin, rotationMax;
FBXModel model = { name, -1 };
model.rotationMin = glm::vec3(-180.0f, -180.0f, -180.0f);
model.rotationMax = glm::vec3(180.0f, 180.0f, 180.0f);
foreach (const FBXNode& subobject, object.children) {
bool properties = false;
QByteArray propertyName;
@ -920,10 +921,28 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
scale = getVec3(property.properties, index);
} else if (property.properties.at(0) == "RotationMin") {
model.rotationMin = getVec3(property.properties, index);
rotationMin = getVec3(property.properties, index);
} else if (property.properties.at(0) == "RotationMax") {
model.rotationMax = getVec3(property.properties, index);
rotationMax = getVec3(property.properties, index);
} else if (property.properties.at(0) == "RotationMinX") {
rotationMinX = property.properties.at(index).toBool();
} else if (property.properties.at(0) == "RotationMinY") {
rotationMinY = property.properties.at(index).toBool();
} else if (property.properties.at(0) == "RotationMinZ") {
rotationMinZ = property.properties.at(index).toBool();
} else if (property.properties.at(0) == "RotationMaxX") {
rotationMaxX = property.properties.at(index).toBool();
} else if (property.properties.at(0) == "RotationMaxY") {
rotationMaxY = property.properties.at(index).toBool();
} else if (property.properties.at(0) == "RotationMaxZ") {
rotationMaxZ = property.properties.at(index).toBool();
}
}
}
@ -940,6 +959,10 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
model.postRotation = glm::quat(glm::radians(postRotation));
model.postTransform = glm::translate(-rotationPivot) * glm::translate(scalePivot) *
glm::scale(scale) * glm::translate(-scalePivot);
model.rotationMin = glm::vec3(rotationMinX ? rotationMin.x : -180.0f,
rotationMinY ? rotationMin.y : -180.0f, rotationMinZ ? rotationMin.z : -180.0f);
model.rotationMax = glm::vec3(rotationMaxX ? rotationMax.x : 180.0f,
rotationMaxY ? rotationMax.y : 180.0f, rotationMaxZ ? rotationMax.z : 180.0f);
models.insert(getID(object.properties), model);
} else if (object.name == "Texture") {

View file

@ -686,6 +686,21 @@ float Model::getLimbLength(int jointIndex) const {
return length;
}
void Model::applyRotationDelta(int jointIndex, const glm::quat& delta) {
JointState& state = _jointStates[jointIndex];
const FBXJoint& joint = _geometry->getFBXGeometry().joints[jointIndex];
if (joint.rotationMin == glm::vec3(-180.0f, -180.0f, -180.0f) && joint.rotationMax == glm::vec3(180.0f, 180.0f, 180.0f)) {
// no constraints
state.rotation = state.rotation * glm::inverse(state.combinedRotation) * delta * state.combinedRotation;
state.combinedRotation = delta * state.combinedRotation;
return;
}
glm::quat newRotation = glm::quat(glm::radians(glm::clamp(safeEulerAngles(state.rotation *
glm::inverse(state.combinedRotation) * delta * state.combinedRotation), joint.rotationMin, joint.rotationMax)));
state.combinedRotation = state.combinedRotation * glm::inverse(state.rotation) * newRotation;
state.rotation = newRotation;
}
void Model::setJointTranslation(int jointIndex, int parentIndex, int childIndex, const glm::vec3& translation) {
const FBXGeometry& geometry = _geometry->getFBXGeometry();
JointState& state = _jointStates[jointIndex];
@ -705,21 +720,6 @@ void Model::setJointTranslation(int jointIndex, int parentIndex, int childIndex,
::setTranslation(state.transform, translation);
}
void Model::applyRotationDelta(int jointIndex, const glm::quat& delta) {
JointState& state = _jointStates[jointIndex];
const FBXJoint& joint = _geometry->getFBXGeometry().joints[jointIndex];
if (joint.rotationMin == glm::vec3(-180.0f, -180.0f, -180.0f) && joint.rotationMax == glm::vec3(180.0f, 180.0f, 180.0f)) {
// no constraints
state.rotation = state.rotation * glm::inverse(state.combinedRotation) * delta * state.combinedRotation;
state.combinedRotation = delta * state.combinedRotation;
return;
}
glm::quat newRotation = glm::quat(glm::radians(glm::clamp(safeEulerAngles(state.rotation *
glm::inverse(state.combinedRotation) * delta * state.combinedRotation), joint.rotationMin, joint.rotationMax)));
state.combinedRotation = state.combinedRotation * glm::inverse(state.rotation) * newRotation;
state.rotation = newRotation;
}
void Model::deleteGeometry() {
foreach (Model* attachment, _attachments) {
delete attachment;

View file

@ -156,10 +156,11 @@ protected:
/// first free ancestor.
float getLimbLength(int jointIndex) const;
void applyRotationDelta(int jointIndex, const glm::quat& delta);
private:
void setJointTranslation(int jointIndex, int parentIndex, int childIndex, const glm::vec3& translation);
void applyRotationDelta(int jointIndex, const glm::quat& delta);
void deleteGeometry();