// 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; } }
void SwipeGestureRecognizer::onTouchMoved(const Touch *touch) { if (numTouches() < numTouchesRequired()) { return; } uint64_t deltaTime = touch->timestamp() - m_startTime; if (deltaTime == 0) { return; } if (state() != State::Possible) { return; } float prevCentralX = centralX(); float prevCentralY = centralY(); updateCentralPoint(); float deltaX = centralX() - prevCentralX; float deltaY = centralY() - prevCentralY; m_cumulativeDeltaX += deltaX; m_cumulativeDeltaY += deltaY; float avrgVelocityX = m_cumulativeDeltaX / deltaTime; float avrgVelocityY = m_cumulativeDeltaY / deltaTime; float cumulativeDeltaSquared = SQUARED_PYTHAGOREAN(m_cumulativeDeltaY, m_cumulativeDeltaX); float avrgVelocitySquared = SQUARED_PYTHAGOREAN(avrgVelocityY, avrgVelocityX); float thresholdSquared = SQUARED(recognitionThreshold()); float minDisplacementSquared = SQUARED(minDisplacement()); float minVelocitySquared = SQUARED(m_minVelocity); // qDebug() << m_minVelocity << " " << minDisplacement() << " " << maxDuration(); // qDebug() << sqrtf(avrgVelocitySquared) << " " << sqrtf(cumulativeDeltaSquared) << " " << deltaTime; if (m_noDirection) { if (cumulativeDeltaSquared >= thresholdSquared && avrgVelocitySquared >= minVelocitySquared && cumulativeDeltaSquared >= minDisplacementSquared) { setState(State::Recognized); } } else { float absVelocityX = fabsf(avrgVelocityX); float absVelocityY = fabsf(avrgVelocityY); if (absVelocityX > absVelocityY) { float absCumulativeDeltaX = fabsf(m_cumulativeDeltaX); if (absCumulativeDeltaX > recognitionThreshold()) { if ((deltaX < 0.0f && (m_direction & Left) == 0) || ((deltaX > 0.0f) && (m_direction & Right) == 0) || fabsf(atanf(m_cumulativeDeltaY /m_cumulativeDeltaX)) >= m_maxAngle) { setState(State::Failed); } else if (absVelocityX >= m_minVelocity && absCumulativeDeltaX >= minDisplacement()) { setState(State::Recognized); } } } else if (absVelocityY > absVelocityX) { float absCumulativeDeltaY = fabsf(m_cumulativeDeltaY); if (absCumulativeDeltaY > recognitionThreshold()) { if ((deltaY < 0.0f && (m_direction & Up) == 0) || ((deltaY > 0.0f) && (m_direction & Down) == 0) || fabsf(atanf(m_cumulativeDeltaX / m_cumulativeDeltaY)) >= m_maxAngle) { setState(State::Failed); } else if (absVelocityY >= m_minVelocity && absCumulativeDeltaY >= minDisplacement()) { setState(State::Recognized); } } } else if (cumulativeDeltaSquared > thresholdSquared) { setState(State::Failed); } } }