Example #1
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);
}
Example #2
0
// returns true if the given point lies inside of the k-dop, specified by shapeInfo & shapePose.
// if the given point does lie within the k-dop, it also returns the amount of displacement necessary to push that point outward
// such that it lies on the surface of the kdop.
bool findPointKDopDisplacement(const glm::vec3& point, const AnimPose& shapePose, const HFMJointShapeInfo& shapeInfo, glm::vec3& displacementOut) {

    // transform point into local space of jointShape.
    glm::vec3 localPoint = shapePose.inverse().xformPoint(point);

    // Only works for 14-dop shape infos.
    if (shapeInfo.dots.size() != DOP14_COUNT) {
        return false;
    }

    glm::vec3 minDisplacement(FLT_MAX);
    float minDisplacementLen = FLT_MAX;
    glm::vec3 p = localPoint - shapeInfo.avgPoint;
    float pLen = glm::length(p);
    if (pLen > 0.0f) {
        int slabCount = 0;
        for (int i = 0; i < DOP14_COUNT; i++) {
            float dot = glm::dot(p, DOP14_NORMALS[i]);
            if (dot > 0.0f && dot < shapeInfo.dots[i]) {
                slabCount++;
                float distToPlane = pLen * (shapeInfo.dots[i] / dot);
                float displacementLen = distToPlane - pLen;

                // keep track of the smallest displacement
                if (displacementLen < minDisplacementLen) {
                    minDisplacementLen = displacementLen;
                    minDisplacement = (p / pLen) * displacementLen;
                }
            }
        }
        if (slabCount == (DOP14_COUNT / 2) && minDisplacementLen != FLT_MAX) {
            // we are within the k-dop so push the point along the minimum displacement found
            displacementOut = shapePose.xformVectorFast(minDisplacement);
            return true;
        } else {
            // point is outside of kdop
            return false;
        }
    } else {
        // point is directly on top of shapeInfo.avgPoint.
        // push the point out along the x axis.
        displacementOut = shapePose.xformVectorFast(shapeInfo.points[0]);
        return true;
    }
}
Example #3
0
AnimPose AnimManipulator::computeRelativePoseFromJointVar(const AnimVariantMap& animVars, const JointVar& jointVar,
                                                          const AnimPose& defaultRelPose, const AnimPoseVec& underPoses) {

    AnimPose defaultAbsPose = _skeleton->getAbsolutePose(jointVar.jointIndex, underPoses);

    if (jointVar.type == JointVar::Type::AbsoluteRotation || jointVar.type == JointVar::Type::AbsolutePosition) {

        if (jointVar.type == JointVar::Type::AbsoluteRotation) {
            defaultAbsPose.rot = animVars.lookupRigToGeometry(jointVar.var, defaultAbsPose.rot);
        } else if (jointVar.type == JointVar::Type::AbsolutePosition) {
            defaultAbsPose.trans = animVars.lookupRigToGeometry(jointVar.var, defaultAbsPose.trans);
        }

        // because jointVar is absolute, we must use an absolute parent frame to convert into a relative pose.
        AnimPose parentAbsPose = AnimPose::identity;
        int parentIndex = _skeleton->getParentIndex(jointVar.jointIndex);
        if (parentIndex >= 0) {
            parentAbsPose = _skeleton->getAbsolutePose(parentIndex, underPoses);
        }

        // convert from absolute to relative
        return parentAbsPose.inverse() * defaultAbsPose;

    } else {

        // override the default rel pose
        AnimPose relPose = defaultRelPose;
        if (jointVar.type == JointVar::Type::RelativeRotation) {
            relPose.rot = animVars.lookupRigToGeometry(jointVar.var, defaultRelPose.rot);
        } else if (jointVar.type == JointVar::Type::RelativePosition) {
            relPose.trans = animVars.lookupRigToGeometry(jointVar.var, defaultRelPose.trans);
        }

        return relPose;
    }
}
Example #4
0
void AnimDebugDraw::update() {

    render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene();
    if (!scene) {
        return;
    }
    if (!render::Item::isValidID(_itemID)) {
        return;
    }
    render::Transaction transaction;
    transaction.updateItem<AnimDebugDrawData>(_itemID, [&](AnimDebugDrawData& data) {

        const size_t VERTICES_PER_BONE = (6 + (NUM_CIRCLE_SLICES * 2) * 3);
        const size_t VERTICES_PER_LINK = 8 * 2;
        const size_t VERTICES_PER_RAY = 2;

        const float BONE_RADIUS = 0.01f; // 1 cm
        const float POSE_RADIUS = 0.1f; // 10 cm

        // figure out how many verts we will need.
        int numVerts = 0;

        for (auto& iter : _absolutePoses) {
            AnimSkeleton::ConstPointer& skeleton = std::get<0>(iter.second);
            numVerts += skeleton->getNumJoints() * VERTICES_PER_BONE;
            for (auto i = 0; i < skeleton->getNumJoints(); i++) {
                auto parentIndex = skeleton->getParentIndex(i);
                if (parentIndex >= 0) {
                    numVerts += VERTICES_PER_LINK;
                }
            }
        }

        // count marker verts from shared DebugDraw singleton
        auto markerMap = DebugDraw::getInstance().getMarkerMap();
        numVerts += (int)markerMap.size() * VERTICES_PER_BONE;
        auto myAvatarMarkerMap = DebugDraw::getInstance().getMyAvatarMarkerMap();
        numVerts += (int)myAvatarMarkerMap.size() * VERTICES_PER_BONE;
        auto rays = DebugDraw::getInstance().getRays();
        DebugDraw::getInstance().clearRays();
        numVerts += (int)rays.size() * VERTICES_PER_RAY;

        // allocate verts!
        std::vector<AnimDebugDrawData::Vertex> vertices;
        vertices.resize(numVerts);
        //Vertex* verts = (Vertex*)data._vertexBuffer->editData();
        AnimDebugDrawData::Vertex* v = nullptr;
        if (numVerts) {
            v = &vertices[0];
        }

        // draw absolute poses
        for (auto& iter : _absolutePoses) {
            AnimSkeleton::ConstPointer& skeleton = std::get<0>(iter.second);
            AnimPoseVec& absPoses = std::get<1>(iter.second);
            AnimPose rootPose = std::get<2>(iter.second);
            glm::vec4 color = std::get<3>(iter.second);

            for (int i = 0; i < skeleton->getNumJoints(); i++) {
                const float radius = BONE_RADIUS / (absPoses[i].scale().x * rootPose.scale().x);

                // draw bone
                addBone(rootPose, absPoses[i], radius, color, v);

                // draw link to parent
                auto parentIndex = skeleton->getParentIndex(i);
                if (parentIndex >= 0) {
                    assert(parentIndex < skeleton->getNumJoints());
                    addLink(rootPose, absPoses[i], absPoses[parentIndex], radius, color, v);
                }
            }
        }

        // draw markers from shared DebugDraw singleton
        for (auto& iter : markerMap) {
            glm::quat rot = std::get<0>(iter.second);
            glm::vec3 pos = std::get<1>(iter.second);
            glm::vec4 color = std::get<2>(iter.second);
            const float radius = POSE_RADIUS;
            addBone(AnimPose::identity, AnimPose(glm::vec3(1), rot, pos), radius, color, v);
        }

        AnimPose myAvatarPose(glm::vec3(1), DebugDraw::getInstance().getMyAvatarRot(), DebugDraw::getInstance().getMyAvatarPos());
        for (auto& iter : myAvatarMarkerMap) {
            glm::quat rot = std::get<0>(iter.second);
            glm::vec3 pos = std::get<1>(iter.second);
            glm::vec4 color = std::get<2>(iter.second);
            const float radius = POSE_RADIUS;
            addBone(myAvatarPose, AnimPose(glm::vec3(1), rot, pos), radius, color, v);
        }

        // draw rays from shared DebugDraw singleton
        for (auto& iter : rays) {
            addLine(std::get<0>(iter), std::get<1>(iter), std::get<2>(iter), v);
        }

        data._vertexBuffer->resize(sizeof(AnimDebugDrawData::Vertex) * numVerts);
        data._vertexBuffer->setSubData<AnimDebugDrawData::Vertex>(0, vertices);

        assert((!numVerts && !v) || (numVerts == (v - &vertices[0])));

        render::Item::Bound theBound;
        for (int i = 0; i < numVerts; i++) {
            theBound += vertices[i].pos;
        }
        data._bound = theBound;

        data._isVisible = (numVerts > 0);

        data._indexBuffer->resize(sizeof(uint16_t) * numVerts);
        for (int i = 0; i < numVerts; i++) {
            data._indexBuffer->setSubData<uint16_t>(i, (uint16_t)i);;
        }
    });
    scene->enqueueTransaction(transaction);
}
Example #5
0
static void addBone(const AnimPose& rootPose, const AnimPose& pose, float radius, glm::vec4& vecColor, AnimDebugDrawData::Vertex*& v) {

    const float XYZ_AXIS_LENGTH = radius * 4.0f;
    const uint32_t color = toRGBA(vecColor);

    AnimPose finalPose = rootPose * pose;
    glm::vec3 base = rootPose * pose.trans();

    glm::vec3 xRing[NUM_CIRCLE_SLICES + 1];  // one extra for last index.
    glm::vec3 yRing[NUM_CIRCLE_SLICES + 1];
    glm::vec3 zRing[NUM_CIRCLE_SLICES + 1];
    const float dTheta = (2.0f * (float)M_PI) / NUM_CIRCLE_SLICES;
    for (int i = 0; i < NUM_CIRCLE_SLICES + 1; i++) {
        float rCosTheta = radius * cosf(dTheta * i);
        float rSinTheta = radius * sinf(dTheta * i);
        xRing[i] = finalPose * glm::vec3(0.0f, rCosTheta, rSinTheta);
        yRing[i] = finalPose * glm::vec3(rCosTheta, 0.0f, rSinTheta);
        zRing[i] = finalPose * glm::vec3(rCosTheta, rSinTheta, 0.0f);
    }

    // x-axis
    v->pos = base;
    v->rgba = red;
    v++;
    v->pos = finalPose * glm::vec3(XYZ_AXIS_LENGTH, 0.0f, 0.0f);
    v->rgba = red;
    v++;

    // x-ring
    for (int i = 0; i < NUM_CIRCLE_SLICES; i++) {
        v->pos = xRing[i];
        v->rgba = color;
        v++;
        v->pos = xRing[i + 1];
        v->rgba = color;
        v++;
    }

    // y-axis
    v->pos = base;
    v->rgba = green;
    v++;
    v->pos = finalPose * glm::vec3(0.0f, XYZ_AXIS_LENGTH, 0.0f);
    v->rgba = green;
    v++;

    // y-ring
    for (int i = 0; i < NUM_CIRCLE_SLICES; i++) {
        v->pos = yRing[i];
        v->rgba = color;
        v++;
        v->pos = yRing[i + 1];
        v->rgba = color;
        v++;
    }

    // z-axis
    v->pos = base;
    v->rgba = blue;
    v++;
    v->pos = finalPose * glm::vec3(0.0f, 0.0f, XYZ_AXIS_LENGTH);
    v->rgba = blue;
    v++;

    // z-ring
    for (int i = 0; i < NUM_CIRCLE_SLICES; i++) {
        v->pos = zRing[i];
        v->rgba = color;
        v++;
        v->pos = zRing[i + 1];
        v->rgba = color;
        v++;
    }
}