protected void standard_update_capture(InputEvent e, InteractionMode eMode) { if (eMode == InteractionMode.InPressDrag) { Vector3f hitPos = vHandleStartW.RayPlaneIntersection(e.ray.Origin, e.ray.Direction, 1); onSliderBarPressDrag(e, hitPos); } else if (eMode == InteractionMode.InHandleDrag) { Vector3f hitPos = vHandleStartW.RayPlaneIntersection(e.ray.Origin, e.ray.Direction, 1); Vector3f dv = hitPos - vStartHitW; Vector3f vRelPos = vHandleStartW.Origin + dv; onHandlePressDrag(e, vRelPos); } }
public void UpdateSetWorldScale(Ray3f left, Ray3f right) { Vector3f hit1 = hitFrame.RayPlaneIntersection(left.Origin, left.Direction, 2); Vector3f hit2 = hitFrame.RayPlaneIntersection(right.Origin, right.Direction, 2); Vector3f avg = (hit1 + hit2) * 0.5f; float r0 = (hit1 - (Vector3f)go.transform.position).Length; float r1 = (hit2 - (Vector3f)go.transform.position).Length; float r = (r0 + r1) * 0.5f; float min_r = VRUtil.GetVRRadiusForVisualAngle(avg, camState.camPosition, 2.0f); r = (float)Math.Max(r, min_r); go.transform.localScale = r * Vector3f.One; go.GetComponent <Renderer>().material = (r > deadzone_r) ? mYes : mNo; }
public override bool UpdateCapture(ITransformable target, Ray3f worldRay) { // ray-hit with world-space translation plane Vector3f 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 Vector3f delta = (planeHit - vInitialHitPos); delta *= TranslationScaleF(); float dx = Vector3f.Dot(delta, translateFrameW.GetAxis(e0)); float dy = Vector3f.Dot(delta, translateFrameW.GetAxis(e1)); if (DeltaDistanceConstraintF != null) { dx = DeltaDistanceConstraintF(translateFrameL, e0, dx); dy = DeltaDistanceConstraintF(translateFrameL, e1, dy); } // construct new local frame translated along plane axes Frame3f newFrame = translateFrameL; newFrame.Origin += dx * translateFrameL.GetAxis(e0) + dy * translateFrameL.GetAxis(e1); // update target target.SetLocalFrame(newFrame, CoordSpace.ObjectCoords); return(true); }
// try to compute a stable ray/plane intersection. when origin is at < +/- an altitude threshold, // use ray/line distance with view-perp line, instead of actual intersection public static Vector3f SafeRayPlaneIntersection(Ray3f ray, Vector3f forwardDir, Vector3f planeOrigin, Vector3f planeNormal, float fAngleThresh = 10.0f) { // determine if we are in unstable condition float fOriginAngleDeg = (float)Math.Abs( planeNormal.AngleD((planeOrigin - ray.Origin).Normalized)); bool bOriginUnstable = Math.Abs(fOriginAngleDeg - 90.0f) < fAngleThresh; // we use ray/plane intersect if stable Frame3f planeF = new Frame3f(planeOrigin, planeNormal); Vector3f planeHit = planeF.RayPlaneIntersection(ray.Origin, ray.Direction, 2); if (bOriginUnstable == false) { return(planeHit); } // if unstable, find "right" direction in plane (ie perp to forward dir, which // may just be ray dir), then intersection is ray/axis closest point Vector3f fwDirInPlane = (forwardDir - planeNormal.Dot(forwardDir)).Normalized; Vector3f perpDirInPlane = Quaternionf.AxisAngleD(planeNormal, 90.0f) * fwDirInPlane; float fAxisDist = (float)DistLine3Ray3.MinDistanceLineParam(ray, new Line3d(planeOrigin, perpDirInPlane)); return(planeOrigin + fAxisDist * perpDirInPlane); }
public void UpdateDraw_Ray(Ray3f ray) { float fScale = scene.GetSceneScale(); Vector3f vHit = planarF.RayPlaneIntersection(ray.Origin, ray.Direction, 2); smooth_append(preview, scene.SceneFrame.ToFrameP(vHit) / fScale, dist_thresh(Width, fScale)); }
public override bool UpdateCapture(ITransformable target, Ray worldRay) { // ray-hit with plane perpendicular to rotateAxisW Vector3f planeHit = raycastFrame.RayPlaneIntersection(worldRay.origin, worldRay.direction, 2); // find angle of hitpos in 2D plane perp to rotateAxis, and compute delta-angle Vector3f 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 Vector3f rotateAxisL = rotateFrameL.GetAxis(nRotationAxis); Quaternionf q = Quaternion.AngleAxis(fDeltaAngle * Mathf.Rad2Deg, rotateAxisL); Frame3f newFrame = rotateFrameL; newFrame.Rotation = q * newFrame.Rotation; // order matters here! // update target target.SetLocalFrame(newFrame, CoordSpace.ObjectCoords); return(true); }
void update_last_hit(SculptCurveTool tool, Ray3f ray) { SORayHit soHit; // stick brush to target if we have one if (tool.BrushTarget != null) { Vector3d hitPos, hitNormal; bool bHit = tool.BrushTarget.RayIntersect(ray, out hitPos, out hitNormal); if (bHit) { lastHitPosW = (Vector3f)hitPos; } } else if (in_draw) { lastHitPosW = curDrawFrameW.RayPlaneIntersection(ray.Origin, ray.Direction, 2); } else if (SceneUtil.FindNearestRayIntersection(tool.Targets, ray, out soHit)) { lastHitPosW = soHit.hitPos; } else { Frame3f f = new Frame3f(lastHitPosW, context.ActiveCamera.Forward()); lastHitPosW = f.RayPlaneIntersection(ray.Origin, ray.Direction, 2); } }
public override bool UpdateCapture(ITransformable target, Ray3f worldRay) { // ray-hit with plane that contains translation axis Vector3f planeHit = raycastFrame.RayPlaneIntersection(worldRay.Origin, worldRay.Direction, 2); // figure out new T-value along axis, then our translation update is delta-t float fNewT = Distance.ClosestPointOnLineT(translateFrameW.Origin, translateAxisW, planeHit); float fDeltaT = (fNewT - fTranslateStartT); fDeltaT *= TranslationScaleF(); if (DeltaDistanceConstraintF != null) { fDeltaT = DeltaDistanceConstraintF(translateFrameL, nTranslationAxis, fDeltaT); } // construct new frame translated along axis (in local space) Frame3f newFrame = translateFrameL; newFrame.Origin += fDeltaT * translateFrameL.GetAxis(nTranslationAxis); // update target target.SetLocalFrame(newFrame, CoordSpace.ObjectCoords); return(true); }
public void UpdateDraw_Ray(Ray3f ray) { float fScale = scene.GetSceneScale(); Vector3f vHit = planarF.RayPlaneIntersection(ray.Origin, ray.Direction, 2); smooth_append(preview.Curve, scene.ToSceneP(vHit), dist_thresh(Radius, fScale)); }
public virtual void BeginStroke(Ray3f rayS) { Vector3f camDirW = Scene.ActiveCamera.Forward(); Vector3f camDirS = Scene.ToSceneP(camDirW); PlaneFrameS = new Frame3f(Target.GetLocalFrame(CoordSpace.SceneCoords).Origin, camDirS); CurrentStroke.Clear(); CurrentStroke.Add(rayS); CurrentStart = PlaneFrameS.RayPlaneIntersection(rayS.Origin, rayS.Direction, 2); CurrentEnd = CurrentStart; if (currentLine == null) { currentLine = new LineIndicator() { SceneStartF = () => { return(CurrentStart); }, SceneEndF = () => { return(CurrentEnd); }, VisibleF = () => { return(CurrentStroke.Count > 1); }, ColorF = () => { return(this.LineColor); }, LineWidth = fDimension.Scene(LineWidth) }; Indicators.AddIndicator(currentLine); } }
public override bool UpdateCapture(ITransformable target, Ray3f worldRay) { // ray-hit with plane perpendicular to rotateAxisW Vector3f planeHitW = raycastFrame.RayPlaneIntersection(worldRay.Origin, worldRay.Direction, 2); // find angle of hitpos in 2D plane perp to rotateAxis, and compute delta-angle Vector3f dv = planeHitW - 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); if (AbsoluteAngleConstraintF != null) { fNewAngle = AbsoluteAngleConstraintF(rotateFrameL, nRotationAxis, fNewAngle); } float fDeltaAngle = (fNewAngle - fRotateStartAngle); if (DeltaAngleConstraintF != null) { fDeltaAngle = DeltaAngleConstraintF(rotateFrameL, nRotationAxis, fDeltaAngle); } bool on_snap = false; if (EnableSnapping) { double dist = (planeHitW - rotateFrameW.Origin).Length; on_snap = Math.Abs(dist - gizmoRadiusW) < gizmoRadiusW * 0.15f; if (on_snap) { fDeltaAngle = (float)Snapping.SnapToIncrement(fDeltaAngle, SnapIncrementDeg * MathUtil.Deg2Radf); } enable_snap_indicator(true); update_snap_indicator(-fDeltaAngle, on_snap); } // construct new frame for target that is rotated around axis Vector3f rotateAxisL = rotateFrameL.GetAxis(nRotationAxis); Quaternionf q = Quaternion.AngleAxis(fDeltaAngle * Mathf.Rad2Deg, rotateAxisL); Frame3f newFrame = rotateFrameL; newFrame.Rotation = q * newFrame.Rotation; // order matters here! // update target target.SetLocalFrame(newFrame, CoordSpace.ObjectCoords); if (EnableSnapping) { update_circle_indicator(on_snap); } return(true); }
public override bool UpdateCapture(ITransformable target, Ray3f worldRay) { Frame3f plane = new Frame3f(Vector3.zero, Vector3.forward); Vector3 vHit = plane.RayPlaneIntersection(worldRay.Origin, worldRay.Direction, 2); vHit = targetW.ToFrameP(vHit); deformer.UpdateDeformation(vHit); return(true); }
Vector3f vInitialHitPos; // initial hit position in frame public override bool BeginCapture(ITransformable target, Ray3f 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); }
override public bool UpdateCapture(InputEvent e) { if (eInterMode == InteractionMode.InCustom) { custom_update_capture(e); } else if (eInterMode == InteractionMode.InPressDrag) { Vector3f hitPos = vHandleStartW.RayPlaneIntersection(e.ray.Origin, e.ray.Direction, 1); onSliderBarPressDrag(e, hitPos); } else if (eInterMode == InteractionMode.InHandleDrag) { Vector3f hitPos = vHandleStartW.RayPlaneIntersection(e.ray.Origin, e.ray.Direction, 1); Vector3f dv = hitPos - vStartHitW; Vector3f vRelPos = vHandleStartW.Origin + dv; onHandlePressDrag(e, vRelPos); } return(true); }
Vector3f vInitialHitPos; // initial hit position in frame public override bool BeginCapture(ITransformable target, Ray3f worldRay, UIRayHit hit) { if (target.SupportsScaling == false) { return(false); } // save local and world frames scaleFrameW = target.GetLocalFrame(CoordSpace.WorldCoords); cameraFrameW = new Frame3f(scaleFrameW.Origin, activeCamera.transform.rotation); startScale = target.GetLocalScale(); // save initial hitpos in plane vInitialHitPos = cameraFrameW.RayPlaneIntersection(worldRay.Origin, worldRay.Direction, 2); return(true); }
public override bool UpdateCapture(ITransformable target, Ray3f worldRay) { // ray-hit with plane that contains translation axis Vector3f planeHit = raycastFrame.RayPlaneIntersection(worldRay.Origin, worldRay.Direction, 2); // figure out new T-value along axis, then our translation update is delta-t float fNewT = Distance.ClosestPointOnLineT(targetFrameW.Origin, heightAxisW, planeHit); float fDeltaT = (fNewT - fHeightStartT); fDeltaT *= DeltaScalingF(); float fNewValue = fStartValue + fDeltaT; fNewValue = Mathf.Clamp(fNewValue, ValidRangeMin, ValidRangeMax); primitive.Parameters.SetValue(AxisParamName, fNewValue); return(true); }
public override bool UpdateCapture(ITransformable target, Ray3f worldRay) { // ray-hit with world-space translation plane Vector3f planeHit = cameraFrameW.RayPlaneIntersection(worldRay.Origin, worldRay.Direction, 2); // construct delta in world space and project into frame coordinates Vector3f delta = (planeHit - vInitialHitPos); delta *= ScaleMultiplierF(); //float dx = Vector3f.Dot(delta, cameraFrameW.GetAxis(0)); float dy = Vector3f.Dot(delta, cameraFrameW.GetAxis(1)); float scaleDelta = 1.0f + dy; float scaleFactor = Mathf.Clamp(scaleDelta, 0.1f, 1000.0f); // update target target.SetLocalScale(startScale * scaleFactor); return(true); }
public bool UpdateCapture(MMDModel target, RayWrap worldRay) { int normalAxis = 2; if (nTranslationAxis == 2) { normalAxis = 1; } // ray-hit with plane that contains translation axis var planeHitOpt = raycastFrame.RayPlaneIntersection(worldRay.From, worldRay.Dir, normalAxis); if (!planeHitOpt.HasValue) { return(false); } Vector3 planeHit = planeHitOpt.Value; // figure out new T-value along axis, then our translation update is delta-t float fNewT = ClosestPointOnLineT(translateFrameW.Origin, translateAxisW, planeHit); float fDeltaT = (fNewT - fTranslateStartT); fDeltaT *= TranslationScaleF( ); if (DeltaDistanceConstraintF != null) { fDeltaT = DeltaDistanceConstraintF(translateFrameL, nTranslationAxis, fDeltaT); } // construct new frame translated along axis (in local space) Frame3f newFrame = translateFrameL; newFrame.Origin += fDeltaT * translateFrameL.GetAxis(nTranslationAxis); // update target //target.SetLocalFrame (newFrame, CoordSpace.ObjectCoords); target.Position = newFrame.Origin; return(true); }
// FixedUpdate is called before any Update public void Update() { if (bFreezeCursor) { return; } // if we are in capture we freeze the cursor plane if (context.InCaptureMouse == false) { Vector3 camPos = camera.gameObject.transform.position; Vector3 forward = camera.gameObject.transform.forward; // orient Y-up plane so that it is in front of eye, perp to camera direction float fCursorDepth = 10.0f; fCursorSpeedNormalization = 1.0f; if (context.ActiveCockpit != null && context.ActiveCockpit.DefaultCursorDepth > 0) { fCursorDepth = context.ActiveCockpit.DefaultCursorDepth; // cursor speed will change depending on cursor plane distance, unless we normalize fCursorSpeedNormalization *= (fCursorDepth / 10.0f); } xformObject.transform.position = camPos + fCursorDepth * forward; xformObject.transform.LookAt(camera.gameObject.transform); xformObject.transform.RotateAround(xformObject.transform.position, xformObject.transform.right, 90); // that plane is the plane the mouse cursor moves on this.vCursorPlaneOrigin = xformObject.transform.position; this.vCursorPlaneRight = xformObject.transform.right; this.vCursorPlaneUp = xformObject.transform.forward; // because we rotated? weird... this.vRaySourcePosition = camera.transform.position; // if we were capturing, then plane was frozen and when we stop capturing, if // head moved, the cursor will pop to a new position (because it is stored in // local plane coords). So raycast through old cursor to hit new plane and figure // out new local coords (fCurPlaneX, fCurPlaneY) if (bWasInCaptureFreeze) { Frame3f newF = new Frame3f(vCursorPlaneOrigin, this.camera.transform.forward); Vector3 vPlaneHit = newF.RayPlaneIntersection(this.vRaySourcePosition, (vPlaneCursorPos - vRaySourcePosition).normalized, 2); fCurPlaneX = Vector3.Dot((vPlaneHit - vCursorPlaneOrigin), vCursorPlaneRight); fCurPlaneY = Vector3.Dot((vPlaneHit - vCursorPlaneOrigin), vCursorPlaneUp); bWasInCaptureFreeze = false; } } else { bWasInCaptureFreeze = true; } Vector2f mousePos = InputExtension.Get.Mouse.PositionDelta; Vector2f leftStick = InputExtension.Get.GamepadLeftStick.Position; float fX = mousePos.x + leftStick.x; float fY = mousePos.y + leftStick.y; // auto-hide cursor if it doesn't move for a while if (fX == 0 && fY == 0 && SceneGraphConfig.MouseCursorHideTimeout > 0) { if ((FPlatform.RealTime() - lastMouseEventTime) > SceneGraphConfig.MouseCursorHideTimeout) { Cursor.SetVisible(false); mouseInactiveState = true; } if (mouseInactiveState) { return; } } else { lastMouseEventTime = FPlatform.RealTime(); if (mouseInactiveState) { Cursor.SetVisible(true); } mouseInactiveState = false; } // update cursor location fCurPlaneX -= 0.3f * fX * fCursorSpeedNormalization; fCurPlaneY -= 0.3f * fY * fCursorSpeedNormalization; vPlaneCursorPos = vCursorPlaneOrigin + fCurPlaneX * vCursorPlaneRight + fCurPlaneY * vCursorPlaneUp; vSceneCursorPos = vPlaneCursorPos; // if cursor gets outside of viewpoint it is almost impossible to get it back. // So, if it goes too far out of view (45 deg here), we snap it back to the origin if (context.InCameraManipulation == false && context.InCaptureMouse == false) { float fAngle = Vector3.Angle((vPlaneCursorPos - camera.transform.position).normalized, camera.transform.forward); if (fAngle > 50.0f) { fCurPlaneX = fCurPlaneY = 0; vPlaneCursorPos = vCursorPlaneOrigin + fCurPlaneX * vCursorPlaneRight + fCurPlaneY * vCursorPlaneUp; vSceneCursorPos = vPlaneCursorPos; } } bool bHit = false; // [RMS] boundsHit cursor orientation could be useful for things where you are picking a point // on the ground plane (eg like drawing contours). Not sure how to toggle that though. // Just disabling for now... //bool bIsBoundsHit = false; if (context != null) { Ray r = new Ray(camera.transform.position, (vPlaneCursorPos - camera.transform.position).normalized); AnyRayHit hit = null; if (context.FindAnyRayIntersection(r, out hit)) { vSceneCursorPos = hit.hitPos; bHit = true; } else { GameObjectRayHit ghit = null; if (context.GetScene().FindWorldBoundsHit(r, out ghit)) { vSceneCursorPos = ghit.hitPos; //bIsBoundsHit = true; } } } this.CurrentCursorPosWorld = vPlaneCursorPos; this.CurrentCursorRaySourceWorld = this.vRaySourcePosition; Vector3 vEyeToPos = (vPlaneCursorPos - camera.transform.position).normalized; //if (bIsBoundsHit) { // Vector3 rotAxis = (vEyeToPos + camera.transform.right).normalized; // Cursor.transform.localRotation = Quaternion.AngleAxis(180.0f-45.0f, rotAxis); //} else { Quaternion rotAlignUp = Quaternion.FromToRotation(Vector3.up, camera.transform.up); Vector3 rotAxis = (vEyeToPos + camera.transform.right).normalized; Cursor.transform.localRotation = Quaternion.AngleAxis(45.0f, rotAxis) * rotAlignUp; //} Cursor.transform.position = vSceneCursorPos; if (context.InCaptureMouse) { Cursor.GetComponent <MeshRenderer> ().material = CursorCapturingMaterial; } else if (bHit) { Cursor.GetComponent <MeshRenderer> ().material = CursorHitMaterial; } else { Cursor.GetComponent <MeshRenderer> ().material = CursorDefaultMaterial; } Cursor.SetLayer(FPlatform.CursorLayer); // maintain a consistent visual size for 3D cursor sphere float fScaling = VRUtil.GetVRRadiusForVisualAngle(vSceneCursorPos, camera.transform.position, CursorVisualAngleInDegrees); Cursor.transform.localScale = new Vector3(fScaling, fScaling, fScaling); // update cursor Mesh useMesh = context.ToolManager.HasActiveTool(ToolSide.Right) ? activeToolCursorMesh : standardCursorMesh; if (Cursor.GetSharedMesh() != useMesh) { Cursor.SetSharedMesh(useMesh); } }
// FixedUpdate is called before any Update public void Update() { if (CheckForSpatialInputActive() == false) { return; } Vector3 rootPos = spatialCamRig.transform.position; SpatialDevice[] hands = { Left, Right }; for (int i = 0; i < 2; ++i) { SpatialDevice h = hands[i]; h.CursorActive = VRPlatform.IsSpatialDeviceTracked(i); if (h.CursorActive) { h.Hand.Show(); h.Cursor.Show(); Vector3 handPos = VRPlatform.GetLocalControllerPosition(i); Quaternion handRot = VRPlatform.GetLocalControllerRotation(i); h.AbsoluteHandFrame = new Frame3f(rootPos + handPos, handRot); float fPositionT = 0.2f; float fRotationT = 0.2f; //float fPositionT = 1.0f; //float fRotationT = 1.0f; if (h.SmoothedHandFrame.Origin != Vector3f.Zero) { Vector3 new_origin = Vector3.Lerp(h.SmoothedHandFrame.Origin, h.AbsoluteHandFrame.Origin, fPositionT); Quaternion new_rotation = Quaternion.Slerp(h.SmoothedHandFrame.Rotation, h.AbsoluteHandFrame.Rotation, fRotationT); h.SmoothedHandFrame = new Frame3f(new_origin, new_rotation); } else { h.SmoothedHandFrame = h.AbsoluteHandFrame; } h.Hand.transform.position = h.SmoothedHandFrame.Origin; h.Hand.transform.rotation = h.SmoothedHandFrame.Rotation * (Quaternionf)handGeomRotation; h.CursorRay = new Ray(h.SmoothedHandFrame.Origin, (h.SmoothedHandFrame.Rotation * Vector3.forward).Normalized); if (Mathf.Abs(h.CursorRay.direction.sqrMagnitude - 1.0f) > 0.001f) { DebugUtil.Log(2, "SpatialInputController.Update - invlaid cursor ray! rotation was {0}", h.SmoothedHandFrame.Rotation); h.CursorRay = new Ray(h.SmoothedHandFrame.Origin, Vector3.up); } // raycast into scene to see if we hit object, UI, bounds, etc. bool bHit = false; if (context != null) { // want to hit-test active gizmo first, because that has hit-priority if (context.TransformManager.HaveActiveGizmo) { UIRayHit uiHit = null; if (context.TransformManager.ActiveGizmo.FindRayIntersection(h.CursorRay, out uiHit)) { h.RayHitPos = uiHit.hitPos; bHit = true; } } // next we tested scene if (bHit == false) { AnyRayHit hit = null; if (context.FindAnyRayIntersection(h.CursorRay, out hit)) { h.RayHitPos = hit.hitPos; bHit = true; } } // finally test worldbounds if (bHit == false) { GameObjectRayHit ghit = null; if (context.GetScene().FindWorldBoundsHit(h.CursorRay, out ghit)) { h.RayHitPos = ghit.hitPos; } } } // if not, plane cursor on view-perp plane centered at last hit pos, // otherwise it will be stuck/disappear if (bHit == false) { Frame3f f = new Frame3f(h.RayHitPos, camera.transform.forward); h.RayHitPos = f.RayPlaneIntersection(h.CursorRay.origin, h.CursorRay.direction, 2); } h.Cursor.transform.position = h.RayHitPos; //if (scene.InCapture) // MaterialUtil.SetMaterial(h.Cursor, h.CursorCapturingMaterial); //else if (bHit) { MaterialUtil.SetMaterial(h.Cursor, h.CursorHitMaterial); } else { MaterialUtil.SetMaterial(h.Cursor, h.CursorDefaultMaterial); } // maintain a consistent visual size for 3D cursor sphere float fScaling = VRUtil.GetVRRadiusForVisualAngle(h.RayHitPos, camera.transform.position, CursorVisualAngleInDegrees); h.Cursor.transform.localScale = fScaling * Vector3.one; // orient cursor so it is tilted like a 2D cursor, but per-hand Vector3 cursor_right = Vector3.Cross(camera.transform.up, h.CursorRay.direction); Vector3 cursor_fw = Vector3.Cross(cursor_right, camera.transform.up); float rotSign = (h == Right) ? 1.0f : -1.0f; Vector3 pointDir = (camera.transform.up + cursor_fw - 0.5f * rotSign * cursor_right).normalized; h.Cursor.transform.localRotation = Quaternion.FromToRotation(Vector3.up, pointDir); // update laser line if (h.Laser != null) { float hDist = (h.RayHitPos - h.CursorRay.origin).magnitude; Vector3 p0 = h.RayHitPos - 0.9f * hDist * h.CursorRay.direction; Vector3 p1 = h.RayHitPos + 100.0f * h.CursorRay.direction; float r0 = VRUtil.GetVRRadiusForVisualAngle(p0, camera.transform.position, 0.5f); h.LaserRen.SetPosition(0, p0); h.LaserRen.SetPosition(1, p1); h.LaserRen.startWidth = h.LaserRen.endWidth = r0; } // udpate cursor Mesh useMesh = context.ToolManager.HasActiveTool(i) ? activeToolCursorMesh : standardCursorMesh; if (h.Cursor.GetSharedMesh() != useMesh) { h.Cursor.SetSharedMesh(useMesh); } } else { h.Hand.Hide(); h.Cursor.Hide(); } } }
public void UpdateStroke(Ray3f rayS) { CurrentStroke.Add(rayS); CurrentEnd = PlaneFrameS.RayPlaneIntersection(rayS.Origin, rayS.Direction, 2); }
public bool UpdateCapture(MMDModel target, RayWrap worldRay) { int normalAxis = 2; if (nRotationAxis == 2) { normalAxis = 1; } // ray-hit with plane perpendicular to rotateAxisW var planeHitWOpt = raycastFrame.RayPlaneIntersection(worldRay.From, worldRay.Dir, normalAxis); if (!planeHitWOpt.HasValue) { return(false); } var planeHitW = planeHitWOpt.Value; // find angle of hitpos in 2D plane perp to rotateAxis, and compute delta-angle Vector3f dv = planeHitW - 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)); Util.DebugWrite("dv " + dv.ToString( )); Util.DebugWrite("planeHitW " + planeHitW.ToString( )); Util.DebugWrite("rotateFrameW " + rotateFrameW.Origin.ToString( )); float fNewAngle = (float)Math.Atan2(fY, fX); //if ( AbsoluteAngleConstraintF != null ) // fNewAngle = AbsoluteAngleConstraintF( rotateFrameL , nRotationAxis , fNewAngle ); float fDeltaAngle = (fNewAngle - fRotateStartAngle); //if (DeltaAngleConstraintF != null) // fDeltaAngle = DeltaAngleConstraintF(rotateFrameL, nRotationAxis, fDeltaAngle); Util.DebugWrite("fDeltaAngle " + fDeltaAngle); fDeltaAngle *= 0.03f; bool on_snap = false; if (EnableSnapping) { //double dist = (planeHitW - rotateFrameW.Origin).Length(); //on_snap = Math.Abs(dist - gizmoRadiusW) < gizmoRadiusW * 0.15f; //if (on_snap) // fDeltaAngle = (float)Snapping.SnapToIncrement(fDeltaAngle, SnapIncrementDeg * MathUtil.Deg2Radf); //enable_snap_indicator(true); //update_snap_indicator(-fDeltaAngle, on_snap); } // 軸を中心に回るターゲットのための新しいフレームを作る Vector3f rotateAxisL = rotateFrameL.GetAxis(nRotationAxis); Quaternion q = Quaternion.RotationAxis(rotateAxisL, fDeltaAngle.Deg()); Frame3f newFrame = rotateFrameL; newFrame.Rotation = q * newFrame.Rotation; // order matters here! // update target target.SetLocalFrame(newFrame, CoordSpace.ObjectCoords); if (EnableSnapping) { //update_circle_indicator(on_snap); } return(true); }