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); }
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); }
public bool BeginCapture(ITransformable target, Ray worldRay, UIRayHit hit) { // save local and world frames rotateFrameL = target.GetLocalFrame(CoordSpace.ObjectCoords); rotateFrameW = target.GetLocalFrame(CoordSpace.WorldCoords); rotateAxisW = rotateFrameW.GetAxis(nRotationAxis); // save angle of hitpos in 2D plane perp to rotateAxis, so we can find delta-angle later Vector3 vWorldHitPos = hit.hitPos; Vector3 dv = vWorldHitPos - 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)); fRotateStartAngle = (float)Math.Atan2(fY, fX); // construct plane we will ray-intersect with in UpdateCapture() raycastFrame = new Frame3(vWorldHitPos, rotateAxisW); 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); }
float fTranslateStartT; // start T-value along translateAxisW public bool BeginCapture(ITransformable target, Ray worldRay, UIRayHit hit) { // save local and world frames translateFrameL = target.GetLocalFrame(CoordSpace.ObjectCoords); translateFrameW = target.GetLocalFrame(CoordSpace.WorldCoords); translateAxisW = translateFrameW.GetAxis(nTranslationAxis); // save t-value of closest point on translation axis, so we can find delta-t Vector3 vWorldHitPos = hit.hitPos; fTranslateStartT = MathUtil.ClosestPointOnLineT( translateFrameW.Origin, translateAxisW, vWorldHitPos); // construct plane we will ray-intersect with in UpdateCapture() Vector3 vForward = Vector3.Cross(Camera.main.transform.up, translateAxisW); raycastFrame = new Frame3(vWorldHitPos, vForward); return(true); }