Esempio n. 1
0
    private static void AutoSetup(Component rb, ControllerAnchorPoint anchor, IEnumerable <Collider> colliders)
    {
        const float raycastDistance  = 100f;
        var         rbTransform      = rb.transform;
        var         rbUp             = rbTransform.up;
        var         rbOffsetPosition = rbTransform.position + rbUp * anchor.inGameOffset.y;
        var         rbForward        = rbTransform.forward;

        var rays = new List <Ray>();

        for (var i = 0; i < 360; i += 5)
        {
            var rotation = Quaternion.AngleAxis(i, rbUp);
            var origin   = rbOffsetPosition + rotation * (rbForward * raycastDistance);
            rays.Add(new Ray(origin, rbOffsetPosition - origin));
        }

        var min   = Vector3.positiveInfinity;
        var max   = Vector3.negativeInfinity;
        var isHit = false;

        foreach (var collider in colliders)
        {
            foreach (var ray in rays)
            {
                RaycastHit hit;
                if (!collider.Raycast(ray, out hit, raycastDistance))
                {
                    continue;
                }
                isHit = true;
                var localPoint = rbTransform.InverseTransformPoint(hit.point);
                min = Vector3.Min(min, localPoint);
                max = Vector3.Max(max, localPoint);

                // var hitCue = VisualCuesHelper.CreatePrimitive(null, PrimitiveType.Cube, new Color(0f, 1f, 0f, 0.2f));
                // hitCue.transform.localScale = Vector3.one * 0.002f;
                // hitCue.transform.position = hit.point;
            }
        }

        if (!isHit)
        {
            return;
        }

        var offset = min + (max - min) / 2f;
        var size   = max - min;

        // var cue1 = VisualCuesHelper.Cross(Color.red);
        // cue1.transform.localScale = Vector3.one * 0.5f;
        // cue1.transform.position = min;

        var padding = new Vector3(0.02f, 0f, 0.02f);

        anchor.inGameSize   = size + padding;
        anchor.inGameOffset = offset;
        anchor.Update();
    }
 public MeasureAnchorWidthStep(WizardContext context, string part, ControllerAnchorPoint anchor)
 {
     _context          = context;
     _part             = part;
     _anchor           = anchor;
     _leftHandControl  = context.containingAtom.freeControllers.First(fc => fc.name == "lHandControl");
     _rightHandControl = context.containingAtom.freeControllers.First(fc => fc.name == "rHandControl");
 }
Esempio n. 3
0
 public MeasureAnchorWidthStep(EmbodyContext context, ControllerAnchorPoint anchor, float handRotate, bool ignoreDepth = false)
     : base(context)
 {
     _anchor           = anchor;
     _handRotate       = handRotate;
     _ignoreDepth      = ignoreDepth;
     _leftHandControl  = context.containingAtom.freeControllers.First(fc => fc.name == "lHandControl");
     _rightHandControl = context.containingAtom.freeControllers.First(fc => fc.name == "rHandControl");
 }
Esempio n. 4
0
 public MeasureArmsAtRestStep(EmbodyContext context, ControllerAnchorPoint anchor)
     : base(context)
 {
     _anchor           = anchor;
     _leftHandControl  = context.containingAtom.freeControllers.First(fc => fc.name == "lHandControl");
     _rightHandControl = context.containingAtom.freeControllers.First(fc => fc.name == "rHandControl");
     _leftHandMotion   = context.trackers.motionControls.First(mc => mc.name == MotionControlNames.LeftHand);
     _rightHandMotion  = context.trackers.motionControls.First(mc => mc.name == MotionControlNames.RightHand);
 }
 public MeasureAnchorDepthAndOffsetStep(EmbodyContext context, ControllerAnchorPoint anchor, float handRotate)
     : base(context)
 {
     _anchor           = anchor;
     _handRotate       = handRotate;
     _leftHandControl  = context.containingAtom.freeControllers.First(fc => fc.name == "lHandControl");
     _rightHandControl = context.containingAtom.freeControllers.First(fc => fc.name == "rHandControl");
     _headControl      = context.containingAtom.freeControllers.First(fc => fc.name == "headControl");
     _chestControl     = context.containingAtom.freeControllers.First(fc => fc.name == "chestControl");
 }
Esempio n. 6
0
    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);
    }
Esempio n. 7
0
    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);
    }
Esempio n. 8
0
    private void ProcessHand(GameObject handTarget, Transform physicalHand, Transform autoSnapPoint, Vector3 palmToWristOffset, Vector3 handRotateOffset, Vector3[] visualCueLinePoints)
    {
        // Base position
        var position   = physicalHand.position;
        var snapOffset = autoSnapPoint.localPosition;

        // 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.GetWorldPosition();
            if (position.y > anchorPointPos.y && (lower == null || anchorPointPos.y > lower.GetWorldPosition().y))
            {
                lower = anchorPoint;
            }
            else if (position.y < anchorPointPos.y && (upper == null || anchorPointPos.y < upper.GetWorldPosition().y))
            {
                upper = anchorPoint;
            }
        }

        if (lower == null)
        {
            lower = upper;
        }
        else if (upper == null)
        {
            upper = lower;
        }

        // Find the weight of both anchors (closest = strongest effect)
        var upperPosition  = upper.GetWorldPosition();
        var lowerPosition  = lower.GetWorldPosition();
        var yUpperDelta    = upperPosition.y - position.y;
        var yLowerDelta    = position.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;
        var anchorPosition = Vector3.Lerp(upperPosition, lowerPosition, lowerWeight);
        var anchorRotation = Quaternion.Lerp(upperRotation, lowerRotation, lowerWeight);

        // TODO: Is this useful?
        anchorPosition.y = position.y;
        visualCueLinePoints[VisualCueLineIndices.Anchor] = anchorPosition;

        // Determine the falloff (closer = stronger, fades out with distance)
        // TODO: Even better to use closest point on ellipse, but not necessary.
        var distance        = Mathf.Abs(Vector3.Distance(anchorPosition, position));
        var physicalCueSize = Vector3.Lerp(Vector3.Scale(upper.VirtualScale, upper.PhysicalScale), Vector3.Scale(lower.VirtualScale, lower.PhysicalScale), lowerWeight) * (_baseCueSize / 2f);
        var physicalCueDistanceFromCenter = Mathf.Max(physicalCueSize.x, physicalCueSize.z);
        // TODO: Check both x and z to determine a falloff relative to both distances
        var falloff = _falloffJSON.val > 0 ? 1f - (Mathf.Clamp(distance - physicalCueDistanceFromCenter, 0, _falloffJSON.val) / _falloffJSON.val) : 1f;

        // Calculate the controller offset based on the physical scale/offset of anchors
        var physicalScale  = Vector3.Lerp(upper.PhysicalScale, lower.PhysicalScale, lowerWeight);
        var physicalOffset = Vector3.Lerp(upper.PhysicalOffset, lower.PhysicalOffset, lowerWeight);
        var baseOffset     = position - anchorPosition;
        var resultOffset   = Quaternion.Inverse(anchorRotation) * baseOffset;

        resultOffset = new Vector3(resultOffset.x / physicalScale.x, resultOffset.y / physicalScale.y, resultOffset.z / physicalScale.z) - physicalOffset;
        resultOffset = anchorRotation * resultOffset;
        var resultPosition = anchorPosition + Vector3.Lerp(baseOffset, resultOffset, falloff);

        visualCueLinePoints[VisualCueLineIndices.Hand] = resultPosition;

        // Apply the hands adjustments
        var resultRotation = autoSnapPoint.rotation * Quaternion.Euler(handRotateOffset);

        resultPosition += resultRotation * (snapOffset + palmToWristOffset);

        // Do the displacement
        var rb = handTarget.GetComponent <Rigidbody>();

        rb.MovePosition(resultPosition);
        rb.MoveRotation(resultRotation);

        visualCueLinePoints[VisualCueLineIndices.Controller] = physicalHand.transform.position;

        // SuperController.singleton.ClearMessages();
        // SuperController.LogMessage($"y {position.y:0.00} btwn {lower.RigidBody.name} y {yLowerDelta:0.00} w {lowerWeight:0.00} and {upper.RigidBody.name} y {yUpperDelta:0.00} w {upperWeight: 0.00}");
        // SuperController.LogMessage($"dist {distance:0.00}/{physicalCueDistanceFromCenter:0.00} falloff {falloff:0.00}");
        // SuperController.LogMessage($"rot {upperRotation.eulerAngles} psca {physicalScale} poff {physicalOffset} base {baseOffset} res {resultOffset}");
    }
Esempio n. 9
0
    private static Vector3 ComputeHandPositionFromAnchor(Vector3 anchorPosition, Vector3 motionControlPosition, ControllerAnchorPoint anchorPoint)
    {
        var realLifeSize           = anchorPoint.realLifeSize;
        var realOffset             = anchorPoint.realLifeOffset;
        var inGameSize             = anchorPoint.inGameSize;
        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          = anchorPosition + scaled - (realOffset * SuperController.singleton.worldScale);

        return(finalPosition);
    }
Esempio n. 10
0
    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);
    }
Esempio n. 11
0
 public MeasureAnchorDepthAndOffsetStep(WizardContext context, string part, ControllerAnchorPoint anchor)
 {
     _context = context;
     _part    = part;
     _anchor  = anchor;
 }