private void EnableHand(SnugHand hand, string motionControlName) { var motionControl = trackers.motionControls.FirstOrDefault(mc => mc.name == motionControlName); if (motionControl == null || !motionControl.SyncMotionControl()) { return; } hand.motionControl = motionControl; if (trackers.restorePoseAfterPossessJSON.val) { hand.snapshot = FreeControllerV3Snapshot.Snap(hand.controller); } _previousState.Add(new FreeControllerV3GrabSnapshot { controller = hand.controller, canGrabPosition = hand.controller.canGrabPosition, canGrabRotation = hand.controller.canGrabRotation }); hand.active = true; hand.controller.canGrabPosition = false; hand.controller.canGrabRotation = false; hand.controller.possessed = true; (hand.controller.GetComponent <HandControl>() ?? hand.controller.GetComponent <HandControlLink>().handControl).possessed = true; if (previewSnugOffsetJSON.val) { hand.showCueLine = true; } }
public override void Awake() { try { base.Awake(); autoSetup = new SnugAutoSetup(context.containingAtom, this); disableSelfGrabJSON = new JSONStorableBool("DisablePersonGrab", false); falloffJSON = new JSONStorableFloat("Falloff", 0.3f, 0f, 5f, false); _lHand = new SnugHand { controller = containingAtom.freeControllers.FirstOrDefault(fc => fc.name == "lHandControl") }; _rHand = new SnugHand { controller = containingAtom.freeControllers.FirstOrDefault(fc => fc.name == "rHandControl") }; InitAnchors(); InitVisualCues(); } catch (Exception exc) { SuperController.LogError($"{nameof(SnugModule)}.{nameof(Awake)}: {exc}"); } }
private void DisableHand(SnugHand hand) { if (hand == null) { return; } if (!hand.active) { return; } hand.controller.possessed = false; (hand.controller.GetComponent <HandControl>() ?? hand.controller.GetComponent <HandControlLink>().handControl).possessed = false; hand.active = false; var mac = hand.controller.GetComponent <MotionAnimationControl>(); if (mac != null) { mac.suspendPositionPlayback = false; mac.suspendRotationPlayback = false; } if (hand.snapshot != null) { hand.snapshot.Restore(false); hand.snapshot = null; } hand.showCueLine = false; }
private void EnableHand(SnugHand hand, string motionControlName) { var motionControl = context.trackers.motionControls.FirstOrDefault(mc => mc.name == motionControlName); if (motionControl == null) { return; } if (!motionControl.enabled) { return; } if (!motionControl.SyncMotionControl()) { return; } if (!motionControl.controlPosition) { return; } hand.motionControl = motionControl; hand.snapshot = FreeControllerV3Snapshot.Snap(hand.controller); hand.active = true; hand.controller.canGrabPosition = false; hand.controller.canGrabRotation = false; hand.controller.currentPositionState = FreeControllerV3.PositionState.On; if (motionControl.controlRotation) { hand.controller.currentRotationState = FreeControllerV3.RotationState.On; } hand.controller.possessed = true; var mac = hand.controller.GetComponent <MotionAnimationControl>(); if (mac != null) { mac.suspendPositionPlayback = true; if (motionControl.controlRotation) { mac.suspendRotationPlayback = true; } } if (!motionControl.keepCurrentPhysicsHoldStrength) { hand.controller.RBHoldPositionSpring = SuperController.singleton.possessPositionSpring; if (motionControl.controlRotation) { hand.controller.RBHoldRotationSpring = SuperController.singleton.possessRotationSpring; } } if (previewSnugOffsetJSON.val) { hand.showCueLine = true; } }
private void DisableHand(SnugHand hand) { if (!hand.active) { return; } hand.controller.possessed = false; (hand.controller.GetComponent <HandControl>() ?? hand.controller.GetComponent <HandControlLink>().handControl).possessed = false; hand.active = false; if (hand.snapshot != null) { if (trackers.restorePoseAfterPossessJSON.val) { hand.snapshot.Restore(); } hand.snapshot = null; } hand.showCueLine = false; }
public override void InitReferences() { base.InitReferences(); autoSetup = new SnugAutoSetup(context.containingAtom, this); _lHand = new SnugHand { controller = containingAtom.freeControllers.First(fc => fc.name == "lHandControl") }; _rHand = new SnugHand { controller = containingAtom.freeControllers.First(fc => fc.name == "rHandControl") }; _lToe = context.bones.First(b => b.name == "lToe"); _rToe = context.bones.First(b => b.name == "rToe"); foreach (var anchorPoint in anchorPoints) { anchorPoint.scaleChangeReceiver = context.scaleChangeReceiver; anchorPoint.bone = anchorPoint.initBone(); anchorPoint.Update(); } }
public override void Awake() { try { base.Awake(); autoSetup = new SnugAutoSetup(context.containingAtom, this); _lHand = new SnugHand { controller = containingAtom.freeControllers.FirstOrDefault(fc => fc.name == "lHandControl") }; _rHand = new SnugHand { controller = containingAtom.freeControllers.FirstOrDefault(fc => fc.name == "rHandControl") }; InitAnchors(); InitVisualCues(); } catch (Exception exc) { SuperController.LogError($"{nameof(SnugModule)}.{nameof(Awake)}: {exc}"); } }
private void ProcessHand(SnugHand hand) { var motionControl = hand.motionControl; var motionControlPosition = motionControl.currentMotionControl.position; var visualCueLinePoints = hand.visualCueLinePoints; // Find the anchor over and under the controller ControllerAnchorPoint lower = null; ControllerAnchorPoint upper = null; foreach (var anchorPoint in anchorPoints) { if (!anchorPoint.active) { continue; } var anchorPointPos = anchorPoint.GetAdjustedWorldPosition(); if (motionControlPosition.y > anchorPointPos.y && (lower == null || anchorPointPos.y > lower.GetAdjustedWorldPosition().y)) { lower = anchorPoint; } else if (motionControlPosition.y < anchorPointPos.y && (upper == null || anchorPointPos.y < upper.GetAdjustedWorldPosition().y)) { upper = anchorPoint; } } if (lower == null) { lower = upper; } else if (upper == null) { upper = lower; } // TODO: If an anchor is higher than one that should be higher, ignore it // Find the weight of both anchors (closest = strongest effect) // ReSharper disable once PossibleNullReferenceException var upperPosition = upper.GetAdjustedWorldPosition(); // ReSharper disable once PossibleNullReferenceException var lowerPosition = lower.GetAdjustedWorldPosition(); var yUpperDelta = upperPosition.y - motionControlPosition.y; var yLowerDelta = motionControlPosition.y - lowerPosition.y; var totalDelta = yLowerDelta + yUpperDelta; var upperWeight = totalDelta == 0 ? 1f : yLowerDelta / totalDelta; var lowerWeight = 1f - upperWeight; var lowerRotation = lower.rigidBody.transform.rotation; var upperRotation = upper.rigidBody.transform.rotation; // TODO: We can use a bezier curve or similar to make a curve following the angle of the upper/lower controls var anchorPosition = Vector3.Lerp(upperPosition, lowerPosition, lowerWeight); var anchorRotation = Quaternion.Lerp(upperRotation, lowerRotation, lowerWeight); var angle = Mathf.Deg2Rad * Vector3.SignedAngle(anchorRotation * Vector3.forward, motionControlPosition - anchorPosition, anchorRotation * Vector3.up); var realLifeSize = Vector3.Lerp(upper.realLifeSize, lower.realLifeSize, lowerWeight); var anchorHook = anchorPosition + new Vector3(Mathf.Sin(angle) * realLifeSize.x / 2f, 0f, Mathf.Cos(angle) * realLifeSize.z / 2f); var hookDistanceFromAnchor = Vector3.Distance(anchorPosition, anchorHook); var motionControlDistanceFromAnchor = Vector3.Distance(anchorPosition, motionControlPosition); float effectWeight; if (motionControlDistanceFromAnchor < hookDistanceFromAnchor) { effectWeight = 1f; } else if (falloffJSON.val == 0) { effectWeight = 0f; } else { var distanceFromAnchorHook = Vector3.Distance(anchorHook, motionControlPosition); if (distanceFromAnchorHook > falloffJSON.val) { effectWeight = 0f; } else { effectWeight = 1f - (Mathf.Clamp(distanceFromAnchorHook, 0, falloffJSON.val) / falloffJSON.val); } } var realOffset = Vector3.Lerp(upper.realLifeOffset, lower.realLifeOffset, lowerWeight); var inGameSize = Vector3.Lerp(upper.inGameSize, lower.inGameSize, lowerWeight); var scale = new Vector3(inGameSize.x / realLifeSize.x, 1f, inGameSize.z / realLifeSize.z); var actualRelativePosition = motionControlPosition - anchorPosition; var scaled = Vector3.Scale(actualRelativePosition, scale); var finalPosition = Vector3.Lerp(motionControlPosition, anchorPosition + scaled - realOffset, effectWeight); visualCueLinePoints[0] = finalPosition; visualCueLinePoints[1] = motionControlPosition; // TODO: Compute for both anchors and average them using smooth lerp var finalPositionToControlPoint = finalPosition + (hand.motionControl.possessPointTransform.position - motionControlPosition); if (previewSnugOffsetJSON.val) { visualCueLinePoints[0] = motionControl.currentMotionControl.position; visualCueLinePoints[1] = finalPosition; } hand.controllerRigidbody.MovePosition(finalPositionToControlPoint); hand.controllerRigidbody.MoveRotation(motionControl.possessPointTransform.rotation); }
private void ProcessHand(SnugHand hand) { if (!hand.active) { return; } var motionControl = hand.motionControl; var motionControlPosition = motionControl.currentMotionControl.position; var visualCueLinePoints = hand.visualCueLinePoints; if (!hand.motionControl.currentMotionControl.gameObject.activeInHierarchy) { return; } // Find the anchor over and under the controller ControllerAnchorPoint lower = null; ControllerAnchorPoint upper = null; for (var i = anchorPoints.Count - 1; i >= 0; i--) { var anchorPoint = anchorPoints[i]; if (!anchorPoint.active) { continue; } var anchorPointPos = anchorPoint.GetAdjustedWorldPosition(); if (motionControlPosition.y > anchorPointPos.y && (lower == null || anchorPointPos.y > lower.GetAdjustedWorldPosition().y)) { lower = anchorPoint; } else if (motionControlPosition.y < anchorPointPos.y && (upper == null || anchorPointPos.y < upper.GetAdjustedWorldPosition().y)) { upper = anchorPoint; } } if (lower == null) { lower = upper; } else if (upper == null) { upper = lower; } // Find the weight of both anchors (closest = strongest effect) // ReSharper disable once PossibleNullReferenceException var upperPosition = upper.GetAdjustedWorldPosition(); // ReSharper disable once PossibleNullReferenceException var lowerPosition = lower.GetAdjustedWorldPosition(); if (lower.floor) { lowerPosition = new Vector3(motionControlPosition.x, Mathf.Min(_lToe.transform.position.y, _rToe.transform.position.y), motionControlPosition.z); } var yUpperDelta = upperPosition.y - motionControlPosition.y; var yLowerDelta = motionControlPosition.y - lowerPosition.y; var totalDelta = yLowerDelta + yUpperDelta; var upperWeight = totalDelta == 0 ? 1f : yLowerDelta / totalDelta; var lowerWeight = 1f - upperWeight; var finalPositionUpper = ComputeHandPositionFromAnchor(upperPosition, motionControlPosition, upper); var finalPositionLower = ComputeHandPositionFromAnchor(lowerPosition, motionControlPosition, lower); var finalPosition = new Vector3( Mathf.SmoothStep(finalPositionUpper.x, finalPositionLower.x, lowerWeight), Mathf.SmoothStep(finalPositionUpper.y, finalPositionLower.y, lowerWeight), Mathf.SmoothStep(finalPositionUpper.z, finalPositionLower.z, lowerWeight) ); var effectWeight = ComputeEffectWeight(upper, lower, lowerWeight, motionControlPosition); var possessPointPosition = hand.motionControl.controllerPointTransform.position; var finalPositionToControlPoint = finalPosition + (possessPointPosition - motionControlPosition); if (previewSnugOffsetJSON.val) { visualCueLinePoints[0] = motionControlPosition; visualCueLinePoints[1] = Vector3.Lerp(motionControlPosition, finalPosition, effectWeight); } hand.controllerRigidbody.MovePosition(Vector3.Lerp(possessPointPosition, finalPositionToControlPoint, effectWeight)); hand.controllerRigidbody.MoveRotation(motionControl.controllerPointTransform.rotation); }