Пример #1
0
        /**
         * Restore controller and object state when releasing
         * */
        public override void EndInteraction(SteamVR_TrackedObject controller)
        {
            // Not interacting with this controller
            if (controller != currentController)
            {
                return;
            }
            InputController.Instance.Release(controller);

            // Re-enable colisions that would push this object
            foreach (Collider collider in controller.GetComponents <Collider>())
            {
                if (collider.isTrigger)
                {
                    continue;
                }
                foreach (Collider objectCollider in GetComponents <Collider>())
                {
                    Physics.IgnoreCollision(collider, objectCollider, false);
                }
            }

            var device = SteamVR_Controller.Input((int)currentController.index);

            // Set velocity of the object when releasing based on controller velocity
            var rigidbody = GetComponent <Rigidbody>();
            var origin    = currentController.origin ? currentController.origin : currentController.transform.parent;

            if (origin != null)
            {
                rigidbody.velocity        = origin.TransformVector(device.velocity);
                rigidbody.angularVelocity = origin.TransformVector(device.angularVelocity);
            }
            else
            {
                rigidbody.velocity        = device.velocity;
                rigidbody.angularVelocity = device.angularVelocity;
            }
            //
            rigidbody.maxAngularVelocity = rigidbody.angularVelocity.magnitude;

            // Hide gauge
            var controllerGauge = currentController.GetComponent <IForceGauge>();

            if (controllerGauge != null)
            {
                controllerGauge.ForceValue = 0;
            }

            // Destroy joint
            if (currentJoint != null)
            {
                currentJoint.connectedBody.useGravity = true;
                DestroyImmediate(currentJoint);
                currentJoint = null;
            }
            currentController = null;
        }
Пример #2
0
        /**
         * Reset controller after a couple seconds after releasing an object.
         * We have to wait otherwise colliders would push each other in unnatural ways
         * */
        private IEnumerator RestoreController(SteamVR_TrackedObject trackedController)
        {
            foreach (var renderer in trackedController.GetComponentsInChildren <MeshRenderer>())
            {
                renderer.enabled = true;
            }
            yield return(new WaitForSeconds(0.15f));

            foreach (Collider collider in trackedController.GetComponents <Collider>())
            {
                collider.enabled = true;
            }
        }
Пример #3
0
        public override void OnTriggerDownColliding(SteamVR_TrackedObject controller)
        {
            // Clean previous interaction
            if (currentController != null)
            {
                EndInteraction(currentController);
            }

            // Try to acquire a lock for this controller
            if (!InputController.Instance.Lock(controller))
            {
                return;                                             // Stop if someone already has it
            }
            // Disable colisions that would push this object
            foreach (Collider collider in controller.GetComponents <Collider>())
            {
                if (collider.isTrigger)
                {
                    continue;
                }
                foreach (Collider objectCollider in GetComponents <Collider>())
                {
                    Debug.Log("Collision disabled" + collider + " " + objectCollider);
                    Physics.IgnoreCollision(collider, objectCollider, true);
                }
            }

            // Attach
            currentController = controller;
            var joint = gameObject.AddComponent <ConfigurableJoint>();

            joint.xMotion        = ConfigurableJointMotion.Locked;
            joint.yMotion        = ConfigurableJointMotion.Locked;
            joint.zMotion        = ConfigurableJointMotion.Locked;
            joint.angularXMotion = ConfigurableJointMotion.Locked;
            joint.angularYMotion = ConfigurableJointMotion.Locked;
            joint.angularZMotion = ConfigurableJointMotion.Locked;
            joint.connectedBody  = currentController.GetComponent <Rigidbody>();
            joint.breakForce     = breakForce;

            currentJoint = joint;
        }
Пример #4
0
        public void FixedUpdate()
        {
            // Not doing anything if not interacting
            if (trackedController == null)
            {
                return;
            }

            var device    = SteamVR_Controller.Input((int)trackedController.index);
            var rigidBody = GetComponent <Rigidbody>();

            // Line between object and controller
            var lineRenderer = trackedController.GetComponent <LineRenderer>();

            lineRenderer.enabled = currentJoint == null;

            // Move object towards you while there is no joint
            if (currentJoint == null)
            {
                // distance betwen where it is and where it should be
                var positionTarget       = trackedController.transform.position + trackedController.transform.forward * 0.06f;
                var attachPoint          = transform.TransformPoint(collisionOffset);
                var distanceDelta        = positionTarget - attachPoint;
                var distanceMassRelation = (float)Math.Sqrt((float)Math.Pow(rigidBody.mass, 2f) / distanceDelta.sqrMagnitude) / 1000f;

                // Increase amount of work done
                currentWork += distanceMassRelation;

                // Haptics
                if (hapticsOnDrag)
                {
                    SteamVR_Controller.Input((int)trackedController.index).TriggerHapticPulse((ushort)(distanceDelta.magnitude * 1000));
                }

                // Drop it if pulled too fast
                var lineTension = distanceDelta.magnitude * rigidBody.mass / 7f; // Constant for line tension strength

                // Set line initial and final position
                if (lineRenderer != null)
                {
                    lineRenderer.SetPosition(0, positionTarget);
                    lineRenderer.SetPosition(1, attachPoint);
                    var lineW = Math.Max((1 - lineTension) * 0.01f, 0.001f);
                    lineRenderer.SetWidth(lineW, lineW);
                    var c = Math.Max(Math.Min(1, lineTension), 0);
                    lineRenderer.material.color = new Color(c, 1 - c, 0);
                }

                // Break the line based on its tension
                if (lineTension > 1 && lineBreaks)
                {
                    EndInteraction(trackedController);
                    return;
                }

                // Create joint if too close
                var bounds = GetComponent <Renderer>().bounds;
                bounds.Expand(0.2f);
                if ((
                        (attachMode == AttachMode.Timer && interactionTime + attachTimer * rigidBody.mass < Time.time) ||
                        (attachMode == AttachMode.Work && currentWork > attachWork * rigidBody.mass)
                        ) && (
                        (attachCondition == AttachCondition.ProximityToBounds && bounds.Contains(positionTarget)) ||
                        (attachCondition == AttachCondition.CollisionWithObject && collidingWithController)
                        ))
                {
                    if (hideControllerOnSnap)
                    {
                        foreach (Renderer renderer in trackedController.GetComponentsInChildren <Renderer>())
                        {
                            renderer.enabled = false;
                        }
                        foreach (Collider collider in trackedController.GetComponents <Collider>())
                        {
                            if (!collider.isTrigger)
                            {
                                collider.enabled = false;
                            }
                        }
                        transform.position = trackedController.transform.position;
                    }

                    var createJoint = true;
                    if (snapPoint != null)
                    {
                        // Disable colliders
                        foreach (var collider in GetComponents <Collider>())
                        {
                            collider.enabled = false;
                        }

                        var finalTarget = positionTarget + (transform.position - snapPoint.position);
                        createJoint = (snapPoint.position - positionTarget).magnitude < 0.04;

                        rigidBody.transform.position = Vector3.Slerp(
                            transform.position,
                            finalTarget,
                            10f * Time.fixedDeltaTime
                            );
                        rigidBody.transform.rotation = Quaternion.Slerp(
                            rigidBody.transform.rotation,
                            Quaternion.LookRotation(trackedController.transform.forward * -1, snapPoint.up),
                            15f * Time.fixedDeltaTime
                            );

                        Debug.Log("snapping!" + finalTarget + " -> " + device.transform.pos);
                        Debug.DrawLine(transform.TransformPoint(snapPoint.localPosition), positionTarget, Color.green);
                    }

                    // Attach
                    if (createJoint)
                    {
                        // Re enable colliders
                        foreach (var collider in GetComponents <Collider>())
                        {
                            collider.enabled = true;
                        }

                        // Disable colisions that would push this object and break the joint
                        foreach (Collider collider in trackedController.GetComponents <Collider>())
                        {
                            if (collider.isTrigger)
                            {
                                continue;
                            }
                            foreach (Collider objectCollider in GetComponents <Collider>())
                            {
                                Physics.IgnoreCollision(collider, objectCollider, true);
                            }
                        }

                        var joint = gameObject.AddComponent <ConfigurableJoint>();
                        joint.xMotion        = ConfigurableJointMotion.Locked;
                        joint.yMotion        = ConfigurableJointMotion.Locked;
                        joint.zMotion        = ConfigurableJointMotion.Locked;
                        joint.angularXMotion = ConfigurableJointMotion.Locked;
                        joint.angularYMotion = ConfigurableJointMotion.Locked;
                        joint.angularZMotion = ConfigurableJointMotion.Locked;
                        joint.connectedBody  = trackedController.GetComponent <Rigidbody>();
                        joint.breakForce     = breakForce;

                        rigidBody.velocity        = new Vector3();
                        rigidBody.angularVelocity = new Vector3();

                        currentJoint = joint;
                    }
                }
                else
                {
                    // Disable gravity if it's being pulled
                    rigidBody.useGravity = false;

                    /**
                     * Move objects according to selected option
                     * */
                    if (moveBy == MoveBy.ApplyingForce)
                    {
                        var wCollisionOffset = transform.TransformPoint(collisionOffset);
                        rigidBody.AddForceAtPosition((positionTarget - wCollisionOffset).normalized / (rigidBody.mass * .01f), wCollisionOffset);
                        rigidBody.maxAngularVelocity = 2f;
                        //Debug.DrawRay(wCollisionOffset, (positionTarget - wCollisionOffset) / rigidBody.mass *10, Color.cyan);
                    }
                    else if (moveBy == MoveBy.ChangingVelocity)
                    {
                        var wCollisionOffset = transform.TransformPoint(collisionOffset);
                        rigidBody.velocity           = (positionTarget - wCollisionOffset) / (rigidBody.mass * 0.1f);
                        rigidBody.maxAngularVelocity = 2f;

                        // Throttle velocity when object is too light
                        if (rigidBody.velocity.sqrMagnitude > Mathf.Pow(MaxVelocity, 2))
                        {
                            rigidBody.velocity = rigidBody.velocity.normalized * MaxVelocity;
                        }
                        //Debug.DrawRay(wCollisionOffset, (positionTarget - wCollisionOffset) / rigidBody.mass *10, Color.cyan);
                    }
                    else if (moveBy == MoveBy.Slerp)
                    {
                        var interpolationAmount = 0.005f;                   // 10f / rigidBody.mass * Time.fixedDeltaTime;
                        rigidBody.velocity          *= Time.fixedDeltaTime; // Decrease physics velocity because we don't want other objecs interfearing with our pull
                        rigidBody.transform.position = Vector3.Slerp(rigidBody.transform.position, positionTarget, interpolationAmount);
                        rigidBody.transform.rotation = trackedController.transform.rotation * rotationOffset;
                    }
                }
            }

            if (device.GetTouchUp(SteamVR_Controller.ButtonMask.Trigger))
            {
                EndInteraction(trackedController);
            }
        }
Пример #5
0
        /**
         * Release object and restore initial state
         * */
        public override void EndInteraction(SteamVR_TrackedObject controller)
        {
            if (trackedController == null || trackedController != controller)
            {
                return;
            }

            // Unlock controller
            InputController.Instance.Release(controller);
            // Remove it manually from the list because a collider might be disabled
            if (currentControllers.Contains(trackedController))
            {
                currentControllers.Remove(trackedController);
            }

            // Re-enable colisions that would push this object
            foreach (Collider collider in controller.GetComponents <Collider>())
            {
                if (collider.isTrigger)
                {
                    continue;
                }
                foreach (Collider objectCollider in GetComponents <Collider>())
                {
                    Physics.IgnoreCollision(collider, objectCollider, false);
                }
            }

            var device = SteamVR_Controller.Input((int)trackedController.index);

            // Set velocity of the object when releasing based on controller velocity
            var rigidbody = GetComponent <Rigidbody>();
            var origin    = trackedController.origin ? trackedController.origin : trackedController.transform.parent;

            if (origin != null)
            {
                rigidbody.velocity        = origin.TransformVector(device.velocity);
                rigidbody.angularVelocity = origin.TransformVector(device.angularVelocity);
            }
            else
            {
                rigidbody.velocity        = device.velocity;
                rigidbody.angularVelocity = device.angularVelocity;
            }
            rigidbody.useGravity         = true;
            rigidbody.maxAngularVelocity = rigidbody.angularVelocity.magnitude;

            // Destroy joint
            if (currentJoint != null)
            {
                currentJoint.connectedBody.useGravity = true;
                DestroyImmediate(currentJoint);
                currentJoint = null;
                // Pick it up if within a time th
                droppedAt = Time.time;
            }

            // Reset gauge
            var controllerGauge = trackedController.GetComponent <IForceGauge>();

            if (controllerGauge != null)
            {
                controllerGauge.ForceValue = 0;
            }
            var lineRenderer = trackedController.GetComponent <LineRenderer>();

            lineRenderer.enabled = false;
            Debug.Log("Line renderer disabled");

            // Reset colliders - snap
            foreach (var collider in GetComponents <Collider>())
            {
                collider.enabled = true;
            }

            currentWork = 0;

            // Reset controller properties
            StartCoroutine(RestoreController(trackedController));

            // No controller interacting anymore
            trackedController       = null;
            collidingWithController = false;
        }