mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 07:12:40 +02:00
Animation unit tests now compile.
not all of them pass tho...
This commit is contained in:
parent
354fae5063
commit
f291ddae97
3 changed files with 91 additions and 81 deletions
|
@ -93,6 +93,9 @@ void makeTestFBXJoints(FBXGeometry& geometry) {
|
|||
}
|
||||
|
||||
void AnimInverseKinematicsTests::testSingleChain() {
|
||||
|
||||
AnimContext context(false, false, false, glm::mat4(), glm::mat4());
|
||||
|
||||
FBXGeometry geometry;
|
||||
makeTestFBXJoints(geometry);
|
||||
|
||||
|
@ -108,14 +111,14 @@ void AnimInverseKinematicsTests::testSingleChain() {
|
|||
//
|
||||
// A------>B------>C------>D
|
||||
AnimPose pose;
|
||||
pose.scale = glm::vec3(1.0f);
|
||||
pose.rot = identity;
|
||||
pose.trans = origin;
|
||||
pose.scale() = glm::vec3(1.0f);
|
||||
pose.rot() = identity;
|
||||
pose.trans() = origin;
|
||||
|
||||
AnimPoseVec poses;
|
||||
poses.push_back(pose);
|
||||
|
||||
pose.trans = xAxis;
|
||||
pose.trans() = xAxis;
|
||||
for (int i = 1; i < (int)geometry.joints.size(); ++i) {
|
||||
poses.push_back(pose);
|
||||
}
|
||||
|
@ -133,8 +136,13 @@ void AnimInverseKinematicsTests::testSingleChain() {
|
|||
AnimVariantMap varMap;
|
||||
varMap.set("positionD", targetPosition);
|
||||
varMap.set("rotationD", targetRotation);
|
||||
varMap.set("targetType", (int)IKTarget::Type::RotationAndPosition);
|
||||
ikDoll.setTargetVars(QString("D"), QString("positionD"), QString("rotationD"), QString("targetType"));
|
||||
varMap.set("targetTypeD", (int)IKTarget::Type::RotationAndPosition);
|
||||
varMap.set("poleVectorEnabledD", false);
|
||||
|
||||
std::vector<float> flexCoefficients = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
ikDoll.setTargetVars(QString("D"), QString("positionD"), QString("rotationD"), QString("targetTypeD"),
|
||||
QString("weightD"), 1.0f, flexCoefficients, QString("poleVectorEnabledD"),
|
||||
QString("poleReferenceVectorD"), QString("poleVectorD"));
|
||||
AnimNode::Triggers triggers;
|
||||
|
||||
// the IK solution should be:
|
||||
|
@ -147,14 +155,14 @@ void AnimInverseKinematicsTests::testSingleChain() {
|
|||
|
||||
// iterate several times
|
||||
float dt = 1.0f;
|
||||
ikDoll.overlay(varMap, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, context, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, context, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, context, dt, triggers, poses);
|
||||
|
||||
ikDoll.overlay(varMap, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, dt, triggers, poses);
|
||||
const AnimPoseVec& relativePoses = ikDoll.overlay(varMap, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, context, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, context, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, context, dt, triggers, poses);
|
||||
const AnimPoseVec& relativePoses = ikDoll.overlay(varMap, context, dt, triggers, poses);
|
||||
|
||||
// verify absolute results
|
||||
// NOTE: since we expect this solution to converge very quickly (one loop)
|
||||
|
@ -165,27 +173,27 @@ void AnimInverseKinematicsTests::testSingleChain() {
|
|||
}
|
||||
ikDoll.computeAbsolutePoses(absolutePoses);
|
||||
const float acceptableAngleError = 0.001f;
|
||||
QCOMPARE_QUATS(absolutePoses[0].rot, identity, acceptableAngleError);
|
||||
QCOMPARE_QUATS(absolutePoses[1].rot, identity, acceptableAngleError);
|
||||
QCOMPARE_QUATS(absolutePoses[2].rot, quaterTurnAroundZ, acceptableAngleError);
|
||||
QCOMPARE_QUATS(absolutePoses[3].rot, quaterTurnAroundZ, acceptableAngleError);
|
||||
QCOMPARE_QUATS(absolutePoses[0].rot(), identity, acceptableAngleError);
|
||||
QCOMPARE_QUATS(absolutePoses[1].rot(), identity, acceptableAngleError);
|
||||
QCOMPARE_QUATS(absolutePoses[2].rot(), quaterTurnAroundZ, acceptableAngleError);
|
||||
QCOMPARE_QUATS(absolutePoses[3].rot(), quaterTurnAroundZ, acceptableAngleError);
|
||||
|
||||
const float acceptableTranslationError = 0.025f;
|
||||
QCOMPARE_WITH_ABS_ERROR(absolutePoses[0].trans, origin, acceptableTranslationError);
|
||||
QCOMPARE_WITH_ABS_ERROR(absolutePoses[1].trans, xAxis, acceptableTranslationError);
|
||||
QCOMPARE_WITH_ABS_ERROR(absolutePoses[2].trans, 2.0f * xAxis, acceptableTranslationError);
|
||||
QCOMPARE_WITH_ABS_ERROR(absolutePoses[3].trans, targetPosition, acceptableTranslationError);
|
||||
QCOMPARE_WITH_ABS_ERROR(absolutePoses[0].trans(), origin, acceptableTranslationError);
|
||||
QCOMPARE_WITH_ABS_ERROR(absolutePoses[1].trans(), xAxis, acceptableTranslationError);
|
||||
QCOMPARE_WITH_ABS_ERROR(absolutePoses[2].trans(), 2.0f * xAxis, acceptableTranslationError);
|
||||
QCOMPARE_WITH_ABS_ERROR(absolutePoses[3].trans(), targetPosition, acceptableTranslationError);
|
||||
|
||||
// verify relative results
|
||||
QCOMPARE_QUATS(relativePoses[0].rot, identity, acceptableAngleError);
|
||||
QCOMPARE_QUATS(relativePoses[1].rot, identity, acceptableAngleError);
|
||||
QCOMPARE_QUATS(relativePoses[2].rot, quaterTurnAroundZ, acceptableAngleError);
|
||||
QCOMPARE_QUATS(relativePoses[3].rot, identity, acceptableAngleError);
|
||||
QCOMPARE_QUATS(relativePoses[0].rot(), identity, acceptableAngleError);
|
||||
QCOMPARE_QUATS(relativePoses[1].rot(), identity, acceptableAngleError);
|
||||
QCOMPARE_QUATS(relativePoses[2].rot(), quaterTurnAroundZ, acceptableAngleError);
|
||||
QCOMPARE_QUATS(relativePoses[3].rot(), identity, acceptableAngleError);
|
||||
|
||||
QCOMPARE_WITH_ABS_ERROR(relativePoses[0].trans, origin, acceptableTranslationError);
|
||||
QCOMPARE_WITH_ABS_ERROR(relativePoses[1].trans, xAxis, acceptableTranslationError);
|
||||
QCOMPARE_WITH_ABS_ERROR(relativePoses[2].trans, xAxis, acceptableTranslationError);
|
||||
QCOMPARE_WITH_ABS_ERROR(relativePoses[3].trans, xAxis, acceptableTranslationError);
|
||||
QCOMPARE_WITH_ABS_ERROR(relativePoses[0].trans(), origin, acceptableTranslationError);
|
||||
QCOMPARE_WITH_ABS_ERROR(relativePoses[1].trans(), xAxis, acceptableTranslationError);
|
||||
QCOMPARE_WITH_ABS_ERROR(relativePoses[2].trans(), xAxis, acceptableTranslationError);
|
||||
QCOMPARE_WITH_ABS_ERROR(relativePoses[3].trans(), xAxis, acceptableTranslationError);
|
||||
}
|
||||
{ // hard test IK of joint C
|
||||
// load intial poses that look like this:
|
||||
|
@ -196,15 +204,15 @@ void AnimInverseKinematicsTests::testSingleChain() {
|
|||
// A------>B
|
||||
//
|
||||
AnimPose pose;
|
||||
pose.scale = glm::vec3(1.0f);
|
||||
pose.rot = identity;
|
||||
pose.trans = origin;
|
||||
pose.scale() = glm::vec3(1.0f);
|
||||
pose.rot() = identity;
|
||||
pose.trans() = origin;
|
||||
|
||||
AnimPoseVec poses;
|
||||
poses.push_back(pose);
|
||||
pose.trans = xAxis;
|
||||
pose.trans() = xAxis;
|
||||
|
||||
pose.rot = quaterTurnAroundZ;
|
||||
pose.rot() = quaterTurnAroundZ;
|
||||
poses.push_back(pose);
|
||||
poses.push_back(pose);
|
||||
poses.push_back(pose);
|
||||
|
@ -222,8 +230,12 @@ void AnimInverseKinematicsTests::testSingleChain() {
|
|||
AnimVariantMap varMap;
|
||||
varMap.set("positionD", targetPosition);
|
||||
varMap.set("rotationD", targetRotation);
|
||||
varMap.set("targetType", (int)IKTarget::Type::RotationAndPosition);
|
||||
ikDoll.setTargetVars(QString("D"), QString("positionD"), QString("rotationD"), QString("targetType"));
|
||||
varMap.set("targetTypeD", (int)IKTarget::Type::RotationAndPosition);
|
||||
varMap.set("poleVectorEnabledD", false);
|
||||
std::vector<float> flexCoefficients = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
ikDoll.setTargetVars(QString("D"), QString("positionD"), QString("rotationD"), QString("targetTypeD"),
|
||||
QString("weightD"), 1.0f, flexCoefficients, QString("poleVectorEnabledD"),
|
||||
QString("poleReferenceVectorD"), QString("poleVectorD"));
|
||||
AnimNode::Triggers triggers;
|
||||
|
||||
// the IK solution should be:
|
||||
|
@ -233,15 +245,15 @@ void AnimInverseKinematicsTests::testSingleChain() {
|
|||
|
||||
// iterate several times
|
||||
float dt = 1.0f;
|
||||
ikDoll.overlay(varMap, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, dt, triggers, poses);
|
||||
const AnimPoseVec& relativePoses = ikDoll.overlay(varMap, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, context, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, context, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, context, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, context, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, context, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, context, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, context, dt, triggers, poses);
|
||||
ikDoll.overlay(varMap, context, dt, triggers, poses);
|
||||
const AnimPoseVec& relativePoses = ikDoll.overlay(varMap, context, dt, triggers, poses);
|
||||
|
||||
// verify absolute results
|
||||
// NOTE: the IK algorithm doesn't converge very fast for full-reach targets,
|
||||
|
@ -256,27 +268,27 @@ void AnimInverseKinematicsTests::testSingleChain() {
|
|||
}
|
||||
ikDoll.computeAbsolutePoses(absolutePoses);
|
||||
float acceptableAngle = 0.01f; // radians
|
||||
QCOMPARE_QUATS(absolutePoses[0].rot, identity, acceptableAngle);
|
||||
QCOMPARE_QUATS(absolutePoses[1].rot, identity, acceptableAngle);
|
||||
QCOMPARE_QUATS(absolutePoses[2].rot, identity, acceptableAngle);
|
||||
QCOMPARE_QUATS(absolutePoses[3].rot, identity, acceptableAngle);
|
||||
QCOMPARE_QUATS(absolutePoses[0].rot(), identity, acceptableAngle);
|
||||
QCOMPARE_QUATS(absolutePoses[1].rot(), identity, acceptableAngle);
|
||||
QCOMPARE_QUATS(absolutePoses[2].rot(), identity, acceptableAngle);
|
||||
QCOMPARE_QUATS(absolutePoses[3].rot(), identity, acceptableAngle);
|
||||
|
||||
float acceptableDistance = 0.03f;
|
||||
QCOMPARE_WITH_ABS_ERROR(absolutePoses[0].trans, origin, acceptableDistance);
|
||||
QCOMPARE_WITH_ABS_ERROR(absolutePoses[1].trans, xAxis, acceptableDistance);
|
||||
QCOMPARE_WITH_ABS_ERROR(absolutePoses[2].trans, 2.0f * xAxis, acceptableDistance);
|
||||
QCOMPARE_WITH_ABS_ERROR(absolutePoses[3].trans, 3.0f * xAxis, acceptableDistance);
|
||||
QCOMPARE_WITH_ABS_ERROR(absolutePoses[0].trans(), origin, acceptableDistance);
|
||||
QCOMPARE_WITH_ABS_ERROR(absolutePoses[1].trans(), xAxis, acceptableDistance);
|
||||
QCOMPARE_WITH_ABS_ERROR(absolutePoses[2].trans(), 2.0f * xAxis, acceptableDistance);
|
||||
QCOMPARE_WITH_ABS_ERROR(absolutePoses[3].trans(), 3.0f * xAxis, acceptableDistance);
|
||||
|
||||
// verify relative results
|
||||
QCOMPARE_QUATS(relativePoses[0].rot, identity, acceptableAngle);
|
||||
QCOMPARE_QUATS(relativePoses[1].rot, identity, acceptableAngle);
|
||||
QCOMPARE_QUATS(relativePoses[2].rot, identity, acceptableAngle);
|
||||
QCOMPARE_QUATS(relativePoses[3].rot, identity, acceptableAngle);
|
||||
QCOMPARE_QUATS(relativePoses[0].rot(), identity, acceptableAngle);
|
||||
QCOMPARE_QUATS(relativePoses[1].rot(), identity, acceptableAngle);
|
||||
QCOMPARE_QUATS(relativePoses[2].rot(), identity, acceptableAngle);
|
||||
QCOMPARE_QUATS(relativePoses[3].rot(), identity, acceptableAngle);
|
||||
|
||||
QCOMPARE_WITH_ABS_ERROR(relativePoses[0].trans, origin, acceptableDistance);
|
||||
QCOMPARE_WITH_ABS_ERROR(relativePoses[1].trans, xAxis, acceptableDistance);
|
||||
QCOMPARE_WITH_ABS_ERROR(relativePoses[2].trans, xAxis, acceptableDistance);
|
||||
QCOMPARE_WITH_ABS_ERROR(relativePoses[3].trans, xAxis, acceptableDistance);
|
||||
QCOMPARE_WITH_ABS_ERROR(relativePoses[0].trans(), origin, acceptableDistance);
|
||||
QCOMPARE_WITH_ABS_ERROR(relativePoses[1].trans(), xAxis, acceptableDistance);
|
||||
QCOMPARE_WITH_ABS_ERROR(relativePoses[2].trans(), xAxis, acceptableDistance);
|
||||
QCOMPARE_WITH_ABS_ERROR(relativePoses[3].trans(), xAxis, acceptableDistance);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,6 +305,6 @@ void AnimInverseKinematicsTests::testBar() {
|
|||
AnimPose poseC = poseA * poseB;
|
||||
|
||||
glm::vec3 expectedTransC = transA + transB;
|
||||
QCOMPARE_WITH_ABS_ERROR(expectedTransC, poseC.trans, EPSILON);
|
||||
QCOMPARE_WITH_ABS_ERROR(expectedTransC, poseC.trans(), EPSILON);
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ static float framesToSec(float secs) {
|
|||
}
|
||||
|
||||
void AnimTests::testClipEvaulate() {
|
||||
AnimContext context(false, false, false, glm::mat4(), glm::mat4());
|
||||
QString id = "myClipNode";
|
||||
QString url = "https://hifi-public.s3.amazonaws.com/ozan/support/FightClubBotTest1/Animations/standard_idle.fbx";
|
||||
float startFrame = 2.0f;
|
||||
|
@ -73,12 +74,12 @@ void AnimTests::testClipEvaulate() {
|
|||
AnimClip clip(id, url, startFrame, endFrame, timeScale, loopFlag, mirrorFlag);
|
||||
|
||||
AnimNode::Triggers triggers;
|
||||
clip.evaluate(vars, framesToSec(10.0f), triggers);
|
||||
clip.evaluate(vars, context, framesToSec(10.0f), triggers);
|
||||
QCOMPARE_WITH_ABS_ERROR(clip._frame, 12.0f, EPSILON);
|
||||
|
||||
// does it loop?
|
||||
triggers.clear();
|
||||
clip.evaluate(vars, framesToSec(12.0f), triggers);
|
||||
clip.evaluate(vars, context, framesToSec(12.0f), triggers);
|
||||
QCOMPARE_WITH_ABS_ERROR(clip._frame, 3.0f, EPSILON); // Note: frame 3 and not 4, because extra frame between start and end.
|
||||
|
||||
// did we receive a loop trigger?
|
||||
|
@ -87,7 +88,7 @@ void AnimTests::testClipEvaulate() {
|
|||
// does it pause at end?
|
||||
triggers.clear();
|
||||
clip.setLoopFlagVar("FalseVar");
|
||||
clip.evaluate(vars, framesToSec(20.0f), triggers);
|
||||
clip.evaluate(vars, context, framesToSec(20.0f), triggers);
|
||||
QCOMPARE_WITH_ABS_ERROR(clip._frame, 22.0f, EPSILON);
|
||||
|
||||
// did we receive a done trigger?
|
||||
|
@ -95,6 +96,7 @@ void AnimTests::testClipEvaulate() {
|
|||
}
|
||||
|
||||
void AnimTests::testClipEvaulateWithVars() {
|
||||
AnimContext context(false, false, false, glm::mat4(), glm::mat4());
|
||||
QString id = "myClipNode";
|
||||
QString url = "https://hifi-public.s3.amazonaws.com/ozan/support/FightClubBotTest1/Animations/standard_idle.fbx";
|
||||
float startFrame = 2.0f;
|
||||
|
@ -121,7 +123,7 @@ void AnimTests::testClipEvaulateWithVars() {
|
|||
clip.setLoopFlagVar("loopFlag2");
|
||||
|
||||
AnimNode::Triggers triggers;
|
||||
clip.evaluate(vars, framesToSec(0.1f), triggers);
|
||||
clip.evaluate(vars, context, framesToSec(0.1f), triggers);
|
||||
|
||||
// verify that the values from the AnimVariantMap made it into the clipNode's
|
||||
// internal state
|
||||
|
|
|
@ -49,21 +49,21 @@
|
|||
|
||||
static void reportJoint(const Rig& rig, int index) { // Handy for debugging
|
||||
std::cout << "\n";
|
||||
std::cout << index << " " << rig->getAnimSkeleton()->getJointName(index).toUtf8().data() << "\n";
|
||||
std::cout << index << " " << rig.getAnimSkeleton()->getJointName(index).toUtf8().data() << "\n";
|
||||
glm::vec3 pos;
|
||||
rig->getJointPosition(index, pos);
|
||||
rig.getJointPosition(index, pos);
|
||||
glm::quat rot;
|
||||
rig->getJointRotation(index, rot);
|
||||
rig.getJointRotation(index, rot);
|
||||
std::cout << " pos:" << pos << "\n";
|
||||
std::cout << " rot:" << safeEulerAngles(rot) << "\n";
|
||||
std::cout << "\n";
|
||||
}
|
||||
static void reportByName(const Rig& rig, const QString& name) {
|
||||
int jointIndex = rig->indexOfJoint(name);
|
||||
int jointIndex = rig.indexOfJoint(name);
|
||||
reportJoint(rig, jointIndex);
|
||||
}
|
||||
static void reportAll(const Rig& rig) {
|
||||
for (int i = 0; i < rig->getJointStateCount(); i++) {
|
||||
for (int i = 0; i < rig.getJointStateCount(); i++) {
|
||||
reportJoint(rig, i);
|
||||
}
|
||||
}
|
||||
|
@ -77,18 +77,14 @@ static void reportSome(const Rig& rig) {
|
|||
QTEST_MAIN(RigTests)
|
||||
|
||||
void RigTests::initTestCase() {
|
||||
//#define FROM_FILE "/Users/howardstearns/howardHiFi/Zack.fbx"
|
||||
#ifdef FROM_FILE
|
||||
QFile file(FROM_FILE);
|
||||
|
||||
// TODO: include this fbx in the test case assets, we are not testing networking here.
|
||||
QString fileName("/Users/howardstearns/howardHiFi/Zack.fbx");
|
||||
|
||||
QFile file(fileName);
|
||||
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
|
||||
|
||||
QVERIFY((bool)geometry);
|
||||
|
||||
_rig.initJointStates(*geometry, glm::mat4());
|
||||
|
|
Loading…
Reference in a new issue