public void TestInvMul() { for (int i = 0; i < 100; ++i) { var xf = RandomTr((i % 2) == 0); AssertAlmostEqual(TrTransform.InvMul(xf, xf), TrTransform.identity); } }
/// Returns xf_RS, relative to the passed line transform. /// Applies m_LineDepth and ignores xf_RS.scale /// TODO: see above. TrTransform GetTransformForLine(Transform line, TrTransform xf_RS) { var xfRoomFromLine = Coords.AsRoom[line]; xf_RS.translation += xf_RS.forward * m_LineDepth; xf_RS.scale = 1; return(TrTransform.InvMul(xfRoomFromLine, xf_RS)); }
public TrTransform this[Transform target] { // Value being get/set is relative to m_parent; the fundamental invariant is: // target.global = m_parent.global * value get { // This works, but loses precision // return AsGlobal[m_parent].inverse * AsGlobal[target]; if (target == m_parent) { return(TrTransform.identity); } // Concatenate up to the root, or to m_parent, whichever comes first. var concatenated = AsLocal[target]; for (var ancestor = target.parent; ancestor != null; ancestor = ancestor.parent) { if (ancestor == m_parent) { return(concatenated); } else { concatenated = AsLocal[ancestor] * concatenated; } } // And project down into m_parent's coordinate system return(TrTransform.InvMul(AsGlobal[m_parent], concatenated)); } set { // This works, but loses precision // AsGlobal[target] = AsGlobal[m_parent] * value; if (target == m_parent) { throw new System.InvalidOperationException("Can't set transform relative to self"); } // Concatenate up to the root, or to m_parent, whichever comes first. // Skip target's local transform, because we're replacing it var concatenated = TrTransform.identity; for (var ancestor = target.parent; ancestor != null; ancestor = ancestor.parent) { if (ancestor == m_parent) { AsLocal[target] = TrTransform.InvMul(concatenated, value); return; } else { concatenated = AsLocal[ancestor] * concatenated; } } AsLocal[target] = TrTransform.InvMul(concatenated, AsGlobal[m_parent] * value); } }