public bool UpdateCapture(ITransformable target, Ray worldRay) { // ray-hit with plane perpendicular to rotateAxisW Vector3 planeHit = raycastFrame.RayPlaneIntersection(worldRay.origin, worldRay.direction, 2); // find angle of hitpos in 2D plane perp to rotateAxis, and compute delta-angle Vector3 dv = planeHit - rotateFrameW.Origin; int iX = (nRotationAxis + 1) % 3; int iY = (nRotationAxis + 2) % 3; float fX = Vector3.Dot(dv, rotateFrameW.GetAxis(iX)); float fY = Vector3.Dot(dv, rotateFrameW.GetAxis(iY)); float fNewAngle = (float)Math.Atan2(fY, fX); float fDeltaAngle = (fNewAngle - fRotateStartAngle); // construct new frame for target that is rotated around axis Vector3 rotateAxisL = rotateFrameL.GetAxis(nRotationAxis); Quaternion q = Quaternion.AngleAxis(fDeltaAngle * Mathf.Rad2Deg, rotateAxisL); Frame3 newFrame = rotateFrameL; newFrame.Rotation = q * newFrame.Rotation; // order matters here! // update target target.SetLocalFrame(newFrame, CoordSpace.ObjectCoords); return(true); }
Vector3 vInitialHitPos; // initial hit position in frame public bool BeginCapture(ITransformable target, Ray worldRay, UIRayHit hit) { // save local and world frames translateFrameL = target.GetLocalFrame(CoordSpace.ObjectCoords); translateFrameW = target.GetLocalFrame(CoordSpace.WorldCoords); // save initial hitpos in translation plane vInitialHitPos = translateFrameW.RayPlaneIntersection(worldRay.origin, worldRay.direction, nTranslationPlaneNormal); return(true); }
public bool UpdateCapture(ITransformable target, Ray worldRay) { // ray-hit with plane that contains translation axis Vector3 planeHit = raycastFrame.RayPlaneIntersection(worldRay.origin, worldRay.direction, 2); // figure out new T-value along axis, then our translation update is delta-t float fNewT = MathUtil.ClosestPointOnLineT(translateFrameW.Origin, translateAxisW, planeHit); float fDeltaT = (fNewT - fTranslateStartT); // construct new frame translated along axis (in local space) Frame3 newFrame = translateFrameL; newFrame.Origin += fDeltaT * translateFrameL.GetAxis(nTranslationAxis); // update target target.SetLocalFrame(newFrame, CoordSpace.ObjectCoords); return(true); }
public bool UpdateCapture(ITransformable target, Ray worldRay) { // ray-hit with world-space translation plane Vector3 planeHit = translateFrameW.RayPlaneIntersection(worldRay.origin, worldRay.direction, nTranslationPlaneNormal); int e0 = (nTranslationPlaneNormal + 1) % 3; int e1 = (nTranslationPlaneNormal + 2) % 3; // construct delta in world space and project into frame coordinates Vector3 delta = (planeHit - vInitialHitPos); float dx = Vector3.Dot(delta, translateFrameW.GetAxis(e0)); float dy = Vector3.Dot(delta, translateFrameW.GetAxis(e1)); // construct new local frame translated along plane axes Frame3 newFrame = translateFrameL; newFrame.Origin += dx * translateFrameL.GetAxis(e0) + dy * translateFrameL.GetAxis(e1); // update target target.SetLocalFrame(newFrame, CoordSpace.ObjectCoords); return(true); }