Exemplo n.º 1
0
/**Calculate a slice plane given the defined parameters.
 */
SlicePlane SliceComputer::getPlane()  const
{
	std::pair<Vector3D,Vector3D> basis = generateBasisVectors();
	SlicePlane plane;
	plane.i = basis.first;
	plane.j = basis.second;
	plane.c = Vector3D(0,0,mToolOffset);

	// transform position from tool to reference space
	plane.c = m_rMt.coord(plane.c);
	// transform orientation from tool to reference space for the oblique case only
	if (mOrientType==otOBLIQUE)
	{
		plane.i = m_rMt.vector(plane.i);
		plane.j = m_rMt.vector(plane.j);
	}

	// orient planes so that gravity is down
	plane = orientToGravity(plane);

	// try to to this also for oblique views, IF the ftFIXED_CENTER is set.
	// use special acs centermod algo
	plane.c = generateFixedIJCenter(mFixedCenter, plane.c, plane.i, plane.j);

	// set center so that it is a fixed distance from viewport top
	plane = applyViewOffset(plane);

	return plane; 
}
Exemplo n.º 2
0
// rotate bone's y-axis with target.
AnimPose boneLookAt(const glm::vec3& target, const AnimPose& bone) {
    glm::vec3 u, v, w;
    generateBasisVectors(target - bone.trans(), bone.rot() * Vectors::UNIT_X, u, v, w);
    glm::mat4 lookAt(glm::vec4(v, 0.0f),
                     glm::vec4(u, 0.0f),
                     // AJT: TODO REVISIT THIS, this could be -w.
                     glm::vec4(glm::normalize(glm::cross(v, u)), 0.0f),
                     glm::vec4(bone.trans(), 1.0f));
    return AnimPose(lookAt);
}
Exemplo n.º 3
0
// This will attempt to determine the proper body facing of a characters body
// assumes headRot is z-forward and y-up.
// and returns a bodyRot that is also z-forward and y-up
glm::quat computeBodyFacingFromHead(const glm::quat& headRot, const glm::vec3& up) {

    glm::vec3 bodyUp = glm::normalize(up);

    // initially take the body facing from the head.
    glm::vec3 headUp = headRot * Vectors::UNIT_Y;
    glm::vec3 headForward = headRot * Vectors::UNIT_Z;
    glm::vec3 headLeft = headRot * Vectors::UNIT_X;
    const float NOD_THRESHOLD = cosf(glm::radians(45.0f));
    const float TILT_THRESHOLD = cosf(glm::radians(30.0f));

    glm::vec3 bodyForward = headForward;

    float nodDot = glm::dot(headForward, bodyUp);
    float tiltDot = glm::dot(headLeft, bodyUp);

    if (fabsf(tiltDot) < TILT_THRESHOLD) { // if we are not tilting too much
        if (nodDot < -NOD_THRESHOLD) { // head is looking downward
            // the body should face in the same direction as the top the head.
            bodyForward = headUp;
        } else if (nodDot > NOD_THRESHOLD) {  // head is looking upward
            // the body should face away from the top of the head.
            bodyForward = -headUp;
        }
    }

    // cancel out upward component
    bodyForward = glm::normalize(bodyForward - nodDot * bodyUp);

    glm::vec3 u, v, w;
    generateBasisVectors(bodyForward, bodyUp, u, v, w);

    // create matrix from orthogonal basis vectors
    glm::mat4 bodyMat(glm::vec4(w, 0.0f), glm::vec4(v, 0.0f), glm::vec4(u, 0.0f), glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));

    return glmExtractRotation(bodyMat);
}
Exemplo n.º 4
0
void GLMHelpersTests::testGenerateBasisVectors() {
    { // very simple case: primary along X, secondary is linear combination of X and Y
        glm::vec3 u(1.0f, 0.0f, 0.0f);
        glm::vec3 v(1.0f, 1.0f, 0.0f);
        glm::vec3 w;

        generateBasisVectors(u, v, u, v, w);

        QCOMPARE_WITH_ABS_ERROR(u, Vectors::UNIT_X, EPSILON);
        QCOMPARE_WITH_ABS_ERROR(v, Vectors::UNIT_Y, EPSILON);
        QCOMPARE_WITH_ABS_ERROR(w, Vectors::UNIT_Z, EPSILON);
    }

    { // point primary along Y instead of X
        glm::vec3 u(0.0f, 1.0f, 0.0f);
        glm::vec3 v(1.0f, 1.0f, 0.0f);
        glm::vec3 w;

        generateBasisVectors(u, v, u, v, w);

        QCOMPARE_WITH_ABS_ERROR(u, Vectors::UNIT_Y, EPSILON);
        QCOMPARE_WITH_ABS_ERROR(v, Vectors::UNIT_X, EPSILON);
        QCOMPARE_WITH_ABS_ERROR(w, -Vectors::UNIT_Z, EPSILON);
    }

    { // pass bad data (both vectors along Y).  The helper will guess X for secondary.
        glm::vec3 u(0.0f, 1.0f, 0.0f);
        glm::vec3 v(0.0f, 1.0f, 0.0f);
        glm::vec3 w;

        generateBasisVectors(u, v, u, v, w);

        QCOMPARE_WITH_ABS_ERROR(u, Vectors::UNIT_Y, EPSILON);
        QCOMPARE_WITH_ABS_ERROR(v, Vectors::UNIT_X, EPSILON);
        QCOMPARE_WITH_ABS_ERROR(w, -Vectors::UNIT_Z, EPSILON);
    }

    { // pass bad data (both vectors along X).  The helper will guess X for secondary, fail, then guess Y.
        glm::vec3 u(1.0f, 0.0f, 0.0f);
        glm::vec3 v(1.0f, 0.0f, 0.0f);
        glm::vec3 w;

        generateBasisVectors(u, v, u, v, w);

        QCOMPARE_WITH_ABS_ERROR(u, Vectors::UNIT_X, EPSILON);
        QCOMPARE_WITH_ABS_ERROR(v, Vectors::UNIT_Y, EPSILON);
        QCOMPARE_WITH_ABS_ERROR(w, Vectors::UNIT_Z, EPSILON);
    }

    { // general case for arbitrary rotation
        float angle = 1.234f;
        glm::vec3 axis = glm::normalize(glm::vec3(1.0f, 2.0f, 3.0f));
        glm::quat rotation = glm::angleAxis(angle, axis);

        // expected values
        glm::vec3 x = rotation * Vectors::UNIT_X;
        glm::vec3 y = rotation * Vectors::UNIT_Y;
        glm::vec3 z = rotation * Vectors::UNIT_Z;

        // primary is along x
        // secondary is linear combination of x and y
        // tertiary is unknown
        glm::vec3 u  = 1.23f * x;
        glm::vec3 v = 2.34f * x + 3.45f * y;
        glm::vec3 w;

        generateBasisVectors(u, v, u, v, w);

        QCOMPARE_WITH_ABS_ERROR(u, x, EPSILON);
        QCOMPARE_WITH_ABS_ERROR(v, y, EPSILON);
        QCOMPARE_WITH_ABS_ERROR(w, z, EPSILON);
    }
}
Exemplo n.º 5
0
static void addLink(const AnimPose& rootPose, const AnimPose& pose, const AnimPose& parentPose,
                    float radius, const glm::vec4& colorVec, AnimDebugDrawData::Vertex*& v) {

    uint32_t color = toRGBA(colorVec);

    AnimPose pose0 = rootPose * parentPose;
    AnimPose pose1 = rootPose * pose;

    glm::vec3 boneAxisWorld = glm::normalize(pose1.trans() - pose0.trans());
    glm::vec3 boneAxis0 = glm::normalize(pose0.inverse().xformVector(boneAxisWorld));
    glm::vec3 boneAxis1 = glm::normalize(pose1.inverse().xformVector(boneAxisWorld));

    glm::vec3 boneBase = pose0 * (boneAxis0 * radius);
    glm::vec3 boneTip = pose1 * (boneAxis1 * -radius);

    const int NUM_BASE_CORNERS = 4;

    // make sure there's room between the two bones to draw a nice bone link.
    if (glm::dot(boneTip - pose0.trans(), boneAxisWorld) > glm::dot(boneBase - pose0.trans(), boneAxisWorld)) {

        // there is room, so lets draw a nice bone

        glm::vec3 uAxis, vAxis, wAxis;
        generateBasisVectors(boneAxis0, glm::vec3(1.0f, 0.0f, 0.0f), uAxis, vAxis, wAxis);

        glm::vec3 boneBaseCorners[NUM_BASE_CORNERS];
        boneBaseCorners[0] = pose0 * ((uAxis * radius) + (vAxis * radius) + (wAxis * radius));
        boneBaseCorners[1] = pose0 * ((uAxis * radius) - (vAxis * radius) + (wAxis * radius));
        boneBaseCorners[2] = pose0 * ((uAxis * radius) - (vAxis * radius) - (wAxis * radius));
        boneBaseCorners[3] = pose0 * ((uAxis * radius) + (vAxis * radius) - (wAxis * radius));

        for (int i = 0; i < NUM_BASE_CORNERS; i++) {
            v->pos = boneBaseCorners[i];
            v->rgba = color;
            v++;
            v->pos = boneBaseCorners[(i + 1) % NUM_BASE_CORNERS];
            v->rgba = color;
            v++;
        }

        for (int i = 0; i < NUM_BASE_CORNERS; i++) {
            v->pos = boneBaseCorners[i];
            v->rgba = color;
            v++;
            v->pos = boneTip;
            v->rgba = color;
            v++;
        }
    } else {
        // There's no room between the bones to draw the link.
        // just draw a line between the two bone centers.
        // We add the same line multiple times, so the vertex count is correct.
        for (int i = 0; i < NUM_BASE_CORNERS * 2; i++) {
            v->pos = pose0.trans();
            v->rgba = color;
            v++;
            v->pos = pose1.trans();
            v->rgba = color;
            v++;
        }
    }
}