// 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; } }
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; } }