public void Run() { var adjustedHipsCenter = _anchor.GetAdjustedWorldPosition(); var realHipsFront = Vector3.MoveTowards(_context.context.rightHand.position, adjustedHipsCenter, _context.handsDistance / 2f); _anchor.realLifeSize = new Vector3(_anchor.realLifeSize.x, 0f, Vector3.Distance(realHipsFront, adjustedHipsCenter) * 2f); _anchor.Update(); }
private float ComputeEffectWeight(ControllerAnchorPoint upper, ControllerAnchorPoint lower, float lowerWeight, Vector3 motionControlPosition) { if (falloffDistanceJSON.val == 0) { return(1f); } var realLifeSize = Vector3.Lerp(upper.realLifeSize, lower.realLifeSize, lowerWeight); var anchorPosition = Vector3.Lerp(upper.GetAdjustedWorldPosition(), lower.GetAdjustedWorldPosition(), lowerWeight); var anchorRotation = Quaternion.Slerp(upper.bone.transform.rotation, lower.bone.transform.rotation, lowerWeight); var angle = Mathf.Deg2Rad * Vector3.SignedAngle(anchorRotation * Vector3.forward, motionControlPosition - anchorPosition, anchorRotation * Vector3.up); 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 distanceFromAnchorHook = Mathf.Clamp(Vector3.Distance(anchorPosition, motionControlPosition) - hookDistanceFromAnchor, 0f, falloffDistanceJSON.val); var effectWeight = 1f - (distanceFromAnchorHook / falloffDistanceJSON.val); var exponentialWeight = ExponentialScale(effectWeight, falloffMidPointJSON.val); return(exponentialWeight); }
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); }