public override void FindClosestPointOnSurface(Vector3 pos, out Vector3 surfacePos, out Vector3 surfaceNorm) { // The closest-point functions operate on an unrotated ellipsoid at the origin. // I'll call that coordinate system "ellipse space (ES)". // "object space (OS)" is the true scale-compensated object-space coordinate system. // Take (uniform) scale from parent, but no scale from this object. // Our local scale is instead treated as Extents TrTransform xfWorldFromEllipse = TrTransform.FromTransform(transform.parent) * TrTransform.TR(transform.localPosition, transform.localRotation); TrTransform xfEllipseFromWorld = xfWorldFromEllipse.inverse; Vector3 halfExtent = Extents * .5f; Vector3 pos_OS = transform.InverseTransformPoint(pos); Vector3 pos_ES = xfEllipseFromWorld * pos; Vector3 closest_ES = MathEllipsoidAnton.ClosestPointEllipsoid(halfExtent, pos_ES); // Transform from ES -> OS, get the OS normal, then transform OS -> WS. // Normals are axial, so OS -> WS uses the inv-transpose. That all ends // up simplifying to this: surfaceNorm = transform.rotation * CDiv(closest_ES, CMul(halfExtent, halfExtent)).normalized; surfacePos = xfWorldFromEllipse * closest_ES; }
public void TestEllipsoidInOctant_Anton() { TestEllipsoidInOctant((a, b) => MathEllipsoidAnton.ClosestPointEllipsoid(a, b)); }
public void TestEllipsoidTangent_Anton() { TestEllipsoidRandomPoints((a, b) => MathEllipsoidAnton.ClosestPointEllipsoid(a, b)); }