Beispiel #1
0
        private void PreviewArea()
        {
            //visualize:
            Vector3[] playspacePerimeterOnFloor   = new Vector3[_playspaceCorners.Count];
            Vector3[] playspacePerimeterOnCeiling = new Vector3[_playspaceCorners.Count];

            //populate floor and ceiling corner loops:
            for (int i = 0; i < _playspaceCorners.Count; i++)
            {
                //cache floor and ceiling locations:
                Vector3 floor   = TransformUtilities.WorldPosition(pcfAnchor.Position, pcfAnchor.Rotation, _playspaceCorners[i]);
                Vector3 ceiling = floor + new Vector3(0, Height);
                playspacePerimeterOnFloor[i]   = floor;
                playspacePerimeterOnCeiling[i] = ceiling;

                //draw corner supports:
                LineRenderer cornerSupportsOutline = Lines.DrawLine($"PlayspaceCornerSupport{i}", Color.green, Color.green, .005f, floor, ceiling);
                cornerSupportsOutline.material = perimeterOutlineMaterial;
            }

            //draw ceiling and floor perimeter:
            LineRenderer ceilingOutline = Lines.DrawLine($"PlayspaceCeilingOutline", Color.green, Color.green, .005f, playspacePerimeterOnCeiling);
            LineRenderer floorOutline   = Lines.DrawLine($"PlayspaceFloorOutline", Color.green, Color.green, .005f, playspacePerimeterOnFloor);

            ceilingOutline.material = perimeterOutlineMaterial;
            floorOutline.material   = perimeterOutlineMaterial;
        }
Beispiel #2
0
        //Loops:
        private void Update()
        {
            if (!HandInput.Ready)
            {
                return;
            }

            //place:
            transform.SetPositionAndRotation(_managedHand.Skeleton.Position, _managedHand.Skeleton.Rotation);

            //hide axis if inside clip plane:
            _axisVisualizer.enabled = !_managedHand.Skeleton.InsideClipPlane;

            //wrist:
            Lines.DrawLine(Name("wrist"), GetColor(_managedHand.Skeleton.WristCenter.InsideClipPlane), GetColor(_managedHand.Skeleton.InsideClipPlane), .0005f, _managedHand.Skeleton.WristCenter.positionFiltered, _managedHand.Skeleton.Position);

            //fingers:
            DrawDigit("thumb", _managedHand.Skeleton.Thumb, GetColor(_managedHand.Skeleton.Thumb.Knuckle.InsideClipPlane), GetColor(_managedHand.Skeleton.Thumb.Tip.InsideClipPlane));
            DrawDigit("index", _managedHand.Skeleton.Index, GetColor(_managedHand.Skeleton.Index.Knuckle.InsideClipPlane), GetColor(_managedHand.Skeleton.Index.Tip.InsideClipPlane));
            DrawDigit("middle", _managedHand.Skeleton.Middle, GetColor(_managedHand.Skeleton.Middle.Knuckle.InsideClipPlane), GetColor(_managedHand.Skeleton.Middle.Tip.InsideClipPlane));
            DrawDigit("ring", _managedHand.Skeleton.Ring, GetColor(_managedHand.Skeleton.Ring.Knuckle.InsideClipPlane), GetColor(_managedHand.Skeleton.Ring.Tip.InsideClipPlane));
            DrawDigit("pinky", _managedHand.Skeleton.Pinky, GetColor(_managedHand.Skeleton.Pinky.Knuckle.InsideClipPlane), GetColor(_managedHand.Skeleton.Pinky.Tip.InsideClipPlane));

            //finger connections:
            DrawBone("thumbConnection", _managedHand.Skeleton.Position, _managedHand.Skeleton.Thumb.Knuckle, GetColor(_managedHand.Skeleton.InsideClipPlane), GetColor(_managedHand.Skeleton.Thumb.Knuckle.InsideClipPlane));
            DrawBone("indexConnection", _managedHand.Skeleton.Position, _managedHand.Skeleton.Index.Knuckle, GetColor(_managedHand.Skeleton.InsideClipPlane), GetColor(_managedHand.Skeleton.Index.Knuckle.InsideClipPlane));
            DrawBone("middleConnection", _managedHand.Skeleton.Position, _managedHand.Skeleton.Middle.Knuckle, GetColor(_managedHand.Skeleton.InsideClipPlane), GetColor(_managedHand.Skeleton.Middle.Knuckle.InsideClipPlane));
            DrawBone("ringConnection", _managedHand.Skeleton.Position, _managedHand.Skeleton.Ring.Knuckle, GetColor(_managedHand.Skeleton.InsideClipPlane), GetColor(_managedHand.Skeleton.Ring.Knuckle.InsideClipPlane));
            DrawBone("pinkyConnection", _managedHand.Skeleton.Position, _managedHand.Skeleton.Pinky.Knuckle, GetColor(_managedHand.Skeleton.InsideClipPlane), GetColor(_managedHand.Skeleton.Pinky.Knuckle.InsideClipPlane));
        }
Beispiel #3
0
        private void DrawDigit(string fingerName, ManagedFinger finger, Color colorA, Color colorB)
        {
            fingerName = Name(fingerName);
            Lines.DrawLine(fingerName, colorA, colorB, .0005f, finger.PointLocationsFiltered);

            if (_managedHand.Visible && finger.IsVisible)
            {
                Lines.SetVisibility(fingerName, true);
            }
            else
            {
                Lines.SetVisibility(fingerName, false);
            }
        }
Beispiel #4
0
        private void DrawBone(string fingerName, Vector3 from, ManagedKeypoint to, Color colorA, Color colorB)
        {
            fingerName = Name(fingerName);
            Lines.DrawLine(fingerName, colorA, colorB, .0005f, from, to.positionFiltered);

            if (_managedHand.Visible && to.Visible)
            {
                Lines.SetVisibility(fingerName, true);
            }
            else
            {
                Lines.SetVisibility(fingerName, false);
            }
        }
        private void HandleDragUpdate(InteractionPoint[] interactionPoint, Vector3 position, Quaternion rotation, float scale)
        {
            float percentage = MathUtilities.TraveledPercentage(startPosition.position, endPosition.position, position);

            handle.transform.position = Vector3.Lerp(startPosition.position, endPosition.position, Mathf.Clamp01(percentage));
            _value = Mathf.Lerp(minValue, maxValue, percentage);
            if (wholeNumbers)
            {
                _value = Mathf.Round(_value);
            }
            OnChanged?.Invoke(Value);

            //draw connection line:
            Lines.DrawLine(_lineID, Color.green, Color.green, .0025f, interactionPoint[0].position, handle.transform.position);

            //dragged too far?
            if (Vector3.Distance(interactionPoint[0].position, handle.transform.position) > dragBreakDistance)
            {
                handle.StopGrab();
            }
        }
Beispiel #6
0
        public void GrabUpdate(InteractionPoint interactionPoint)
        {
            //dragging started?
            if (!Dragging)
            {
                foreach (var item in _initialInteractionPoses)
                {
                    if (Vector3.Distance(item.Key.position, item.Value.position) > _dragThreshold)
                    {
                        //halt physics:
                        if (_rigidBody != null)
                        {
                            _rigidBody.velocity        = Vector3.zero;
                            _rigidBody.angularVelocity = Vector3.zero;
                            _rigidBody.isKinematic     = true;
                        }

                        //find offset:
                        Matrix4x4  matrix         = Matrix4x4.TRS(item.Key.position, item.Key.rotation, Vector3.one);
                        Vector3    positionOffset = matrix.inverse.MultiplyPoint3x4(transform.position);
                        Quaternion rotationOffset = Quaternion.Inverse(item.Key.rotation) * transform.rotation;
                        _offset = new Pose(positionOffset, rotationOffset);

                        //resets:
                        _position = Vector3.zero;
                        _rotation = Quaternion.identity;

                        //status:
                        Dragging = true;
                        OnDragBegin?.Invoke(item.Key);
                        break;
                    }
                }
            }

            //dragging?
            if (Dragging)
            {
                //find center of interaction points involved with this drag:
                Bounds dragBounds = new Bounds(activeInteractionPoints[0].position, Vector3.zero);
                for (int i = 1; i < activeInteractionPoints.Count; i++)
                {
                    dragBounds.Encapsulate(activeInteractionPoints[i].position);
                }

                //discover drag distance and percentage;
                float biManualDistance = dragBounds.size.magnitude;

                //holders:
                Vector3    dragLocation    = Vector3.zero;
                Quaternion dragOrientation = Quaternion.identity;
                Vector3    forward         = Vector3.zero;
                float      scaleDelta      = 0;

                //rotation:
                if (activeInteractionPoints.Count == 2)
                {
                    //get rotated amount:
                    forward = activeInteractionPoints[0].position - activeInteractionPoints[1].position;
                    Vector3 forwardNormalized = forward.normalized;
                    Vector3 previousForward   = _bimanualBaseRotation * Vector3.forward;
                    Vector3 up    = Vector3.Cross(forwardNormalized, previousForward).normalized;
                    float   angle = Vector3.SignedAngle(previousForward, forwardNormalized, up);

                    //update rotation:
                    Quaternion rotationDelta = Quaternion.AngleAxis(angle, up);
                    _bimanualBaseRotation = rotationDelta * _bimanualBaseRotation;
                    dragOrientation       = _bimanualBaseRotation * _offset.rotation;
                }
                else
                {
                    dragOrientation = activeInteractionPoints[0].rotation * _offset.rotation;
                }

                //position:
                if (activeInteractionPoints.Count == 2)
                {
                    Matrix4x4 matrix = Matrix4x4.TRS(dragBounds.center, _bimanualBaseRotation, Vector3.one);
                    dragLocation = matrix.MultiplyPoint3x4(_offset.position);
                }
                else
                {
                    Matrix4x4 matrix = Matrix4x4.TRS(activeInteractionPoints[0].position, activeInteractionPoints[0].rotation, Vector3.one);
                    dragLocation = matrix.MultiplyPoint3x4(_offset.position);
                }

                //scale:
                if (activeInteractionPoints.Count == 2)
                {
                    scaleDelta = biManualDistance - _scaleInitialDistance;
                }

                //set smoothing origins:
                if (_position == Vector3.zero || _rotation == Quaternion.identity)
                {
                    _position = dragLocation;
                    _rotation = dragOrientation;
                }

                //application:
                if (draggable)
                {
                    _position = Vector3.SmoothDamp(_position, dragLocation, ref _positionVelocity, positionSmoothTime);
                    if (_rigidBody != null)
                    {
                        _rigidBody.MovePosition(_position);
                        _averageVelocity.Add(_rigidBody.velocity);
                        _averageAngularVelocity.Add(_rigidBody.angularVelocity);
                    }
                    else
                    {
                        transform.position = _position;
                    }
                }

                if (rotatable)
                {
                    _rotation = MotionUtilities.SmoothDamp(_rotation, dragOrientation, ref _rotationVelocity, rotationSmoothTime);
                    if (_rigidBody != null)
                    {
                        _rigidBody.MoveRotation(_rotation);
                    }
                    else
                    {
                        transform.rotation = _rotation;
                    }
                }

                if (scalable && activeInteractionPoints.Count == 2)
                {
                    Vector3 proposedScale = _scaleBase + (Vector3.one * scaleDelta);

                    //constrain scale and do not not assume uniform initial scale:
                    if (Mathf.Max(proposedScale.x, proposedScale.y, proposedScale.z) <= maxScale &&
                        Mathf.Min(proposedScale.x, proposedScale.y, proposedScale.z) >= minScale)
                    {
                        transform.localScale = _scaleBase + (Vector3.one * scaleDelta);
                    }
                }

                //visuals:
                if (activeInteractionPoints.Count == 2)
                {
                    Lines.SetVisibility(_handConnectionLine, true);
                    Lines.DrawLine(_handConnectionLine, Color.cyan, Color.cyan, .0005f, activeInteractionPoints[0].position, activeInteractionPoints[1].position);
                }

                //status:
                OnDragUpdate?.Invoke(activeInteractionPoints.ToArray(), _position, _rotation, scaleDelta);
            }
        }
Beispiel #7
0
        private void DrawPerimeter_HandleTriggerDown(byte controllerId, float triggerValue)
        {
            //cache room details (to avoid tilt if room analyzation updates):
            if (_plottedCorners.Count == 0)
            {
                _roomVerticalCenter = SurfaceDetails.VerticalCenter;
                _roomCeilingHeight  = SurfaceDetails.CeilingHeight;
                _roomFloorHeight    = SurfaceDetails.FloorHeight;
                Height = SurfaceDetails.RoomHeight;
            }

            //corner details:
            Vector3 controlPosition = MLInput.GetController(controllerId).Position;
            Vector3 cornerLocation  = new Vector3(controlPosition.x, _roomVerticalCenter, controlPosition.z);

            //invalid placement if this proposed segment would overlap any previous ones:
            if (_plottedCorners.Count >= 3)
            {
                //proposed line segment:
                Vector2 proposedStart = new Vector2(_plottedCorners[_plottedCorners.Count - 1].position.x, _plottedCorners[_plottedCorners.Count - 1].position.z);
                Vector2 proposedEnd   = new Vector2(cornerLocation.x, cornerLocation.z);

                //look for any intersections (in 2d):
                for (int i = 1; i < _plottedCorners.Count; i++)
                {
                    //get a pervious segment:
                    Vector2 startA = new Vector2(_plottedCorners[i - 1].position.x, _plottedCorners[i - 1].position.z);
                    Vector2 endA   = new Vector2(_plottedCorners[i].position.x, _plottedCorners[i].position.z);

                    //is there an intersection with something previous?
                    Vector2 previousIntersection = Vector2.zero;
                    if (MathUtilities.LineSegmentsIntersecting(startA, endA, proposedStart, proposedEnd, false))
                    {
                        //ignore this proposed corner since it would create an overlapped wall:
                        return;
                    }
                }
            }

            //bounds:
            if (_plottedCorners.Count == 0)
            {
                _plottedBounds = new Bounds(cornerLocation, Vector3.zero);
            }
            else
            {
                _plottedBounds.Encapsulate(cornerLocation);
            }

            //loop complete?
            bool loopComplete = false;

            if (_plottedCorners.Count > 3)
            {
                //close to first? close to last? close the loop:
                if (Vector3.Distance(cornerLocation, _plottedCorners[0].position) <= _loopClosureDistance || Vector3.Distance(cornerLocation, _plottedCorners[_plottedCorners.Count - 1].position) <= _loopClosureDistance)
                {
                    _plottedCorners.Add(_plottedCorners[0]);
                    loopComplete = true;
                }
            }

            if (!loopComplete)
            {
                //visualize corner:
                GameObject corner = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
                corner.GetComponent <Renderer>().material = cornerMaterial;
                corner.name = $"(Corner{_plottedCorners.Count})";
                corner.transform.position   = cornerLocation;
                corner.transform.localScale = new Vector3(0.0508f, Height * .5f, 0.0508f);
                _plottedCorners.Add(corner.transform);

                //visualize boundry:
                Lines.DrawLine("Boundry", Color.white, Color.white, .01f, _plottedCorners.ToArray());
            }
            else
            {
                //visualize boundry:
                Lines.DrawLine("Boundry", Color.white, Color.white, .01f, _plottedCorners.ToArray());

                ChangeState(State.FindWalls);
            }
        }