// This costs about 154 flops. const Constraint::SphereOnSphereContactImpl::PositionCache& Constraint::SphereOnSphereContactImpl:: ensurePositionCacheRealized(const State& s) const { if (getMyMatterSubsystemRep().isCacheValueRealized(s, m_posCacheIx)) return getPositionCache(s); const Parameters& params = getParameters(s); const Vec3& p_FSf = params.m_p_FSf; const Vec3& p_BSb = params.m_p_BSb; const Real rf = params.m_radius_F; const Real rb = params.m_radius_B; PositionCache& pc = updPositionCache(s); pc.kf = rf/(rf+rb); // we'll put Co at Sf + kf*p_SfSb, ~10 flops const Transform& X_AF = getBodyTransformFromState(s, m_mobod_F); const Transform& X_AB = getBodyTransformFromState(s, m_mobod_B); const Vec3& p_AF = X_AF.p(); const Vec3& p_AB = X_AB.p(); pc.p_FSf_A = X_AF.R() * p_FSf; // exp. in A, 15 flops const Vec3 p_ASf = X_AF.p() + pc.p_FSf_A; // meas. from Ao, 3 flops pc.p_BSb_A = X_AB.R() * p_BSb; // exp. in A, 15 flops const Vec3 p_ASb = X_AB.p() + pc.p_BSb_A; // meas. from Ao, 3 flops pc.p_SfSb_A = p_ASb - p_ASf; // vec from Sf to Sb, exp. in A, 3 flops pc.r = pc.p_SfSb_A.norm(); // ~20 flops pc.oor = 1/pc.r; // ~10 flops (might be Infinity) // Assume non-singular. UnitVec3 Cz_A(pc.p_SfSb_A * pc.oor, true); // 3 flops pc.isSingular = false; if (pc.r < TinyReal) { pc.isSingular = true; Cz_A = X_AF.z(); // arbitrary } // Now compute the contact frame C, in A. It would be somewhat more elegant // to compute it in F, so that the x-y axis directions would depend only // on the relative pose between the two bodies. However, that is more // expensive than working in A and since the x-y axes are arbitrary and // ephemeral anyway doing it faster seems like the way to go (sherm 140502). // Place the contact point along the center-to-center line. const Vec3 p_ACo(p_ASf + pc.kf*pc.p_SfSb_A); // 6 flops pc.X_AC.updP() = p_ACo; pc.X_AC.updR().setRotationFromOneAxis(Cz_A, ZAxis); // ~60 flops // We'll need contact point Co measured from F and from B. pc.p_FCo_A = p_ACo - p_AF; // 3 flops pc.p_BCo_A = p_ACo - p_AB; // 3 flops getMyMatterSubsystemRep().markCacheValueRealized(s, m_posCacheIx); return pc; }
const Constraint::LineOnLineContactImpl::PositionCache& Constraint::LineOnLineContactImpl:: ensurePositionCacheRealized(const State& s) const { if (getMyMatterSubsystemRep().isCacheValueRealized(s, m_posCacheIx)) return getPositionCache(s); PositionCache& pc = updPositionCache(s); const Transform& X_AF = getBodyTransformFromState(s, m_mobod_F); const Transform& X_AB = getBodyTransformFromState(s, m_mobod_B); calcPositionInfo(s, X_AF, X_AB, pc); getMyMatterSubsystemRep().markCacheValueRealized(s, m_posCacheIx); return pc; }