Ejemplo n.º 1
0
        /** Updates this hand model. */
        public override void UpdateHand()
        {
#if UNITY_EDITOR
            if (!EditorApplication.isPlaying)
            {
                return;
            }
#endif

            float deadzone = DEAD_ZONE_FRACTION * _hand.Fingers[1].Bone((Bone.BoneType) 1).Width;

            for (int fingerIndex = 0; fingerIndex < N_FINGERS; fingerIndex++)
            {
                for (int jointIndex = 0; jointIndex < N_ACTIVE_BONES; jointIndex++)
                {
                    Bone bone                      = _hand.Fingers[fingerIndex].Bone((Bone.BoneType)(jointIndex + 1));
                    int  boneArrayIndex            = fingerIndex * N_ACTIVE_BONES + jointIndex;
                    InteractionBrushBone brushBone = _brushBones[boneArrayIndex];
                    Rigidbody            body      = brushBone.capsuleBody;

                    // This hack works best when we set a fixed rotation for bones.  Otherwise
                    // most friction is lost as the bones roll on contact.
                    body.MoveRotation(bone.Rotation.ToQuaternion());

                    if (brushBone.updateTriggering() == false)
                    {
                        // Calculate how far off the mark the brushes are.
                        float targetingError = (brushBone.lastTarget - body.position).magnitude / bone.Width;
                        float massScale      = Mathf.Clamp(1.0f - (targetingError * 2.0f), 0.1f, 1.0f);
                        body.mass = _perBoneMass * massScale;

                        if (targetingError >= DISLOCATION_FRACTION)
                        {
                            brushBone.startTriggering();
                        }
                    }

                    // Add a deadzone to avoid vibration.
                    Vector3 delta    = bone.Center.ToVector3() - body.position;
                    float   deltaLen = delta.magnitude;
                    if (deltaLen <= deadzone)
                    {
                        body.velocity        = Vector3.zero;
                        brushBone.lastTarget = body.position;
                    }
                    else
                    {
                        delta               *= (deltaLen - deadzone) / deltaLen;
                        body.velocity        = delta / Time.fixedDeltaTime;
                        brushBone.lastTarget = body.position + delta;
                    }
                }
            }
        }
Ejemplo n.º 2
0
        private void UpdateBone(Bone bone, int boneArrayIndex, float deadzone)
        {
            InteractionBrushBone brushBone = _brushBones[boneArrayIndex];
            Rigidbody            body      = brushBone.body;

            // This hack works best when we set a fixed rotation for bones.  Otherwise
            // most friction is lost as the bones roll on contact.
            body.MoveRotation(bone.Rotation.ToQuaternion());

            // Calculate how far off the mark the brushes are.
            float targetingError = Vector3.Distance(brushBone.lastTarget, body.position) / bone.Width;
            float massScale      = Mathf.Clamp(1.0f - (targetingError * 2.0f), 0.1f, 1.0f) * Mathf.Clamp(_hand.PalmVelocity.Magnitude * 10f, 1f, 10f);

            body.mass = _perBoneMass * massScale * brushBone.massOfLastTouchedObject;

            //If these conditions are met, stop using brush hands to contact objects and switch to "Soft Contact"
            if (!_softContactEnabled && targetingError >= DISLOCATION_FRACTION && _hand.PalmVelocity.Magnitude < 1.5f && boneArrayIndex != N_ACTIVE_BONES * N_FINGERS)
            {
                enableSoftContact();
                return;
            }

            // Add a deadzone to avoid vibration.
            Vector3 delta    = bone.Center.ToVector3() - body.position;
            float   deltaLen = delta.magnitude;

            if (deltaLen <= deadzone)
            {
                body.velocity        = Vector3.zero;
                brushBone.lastTarget = body.position;
            }
            else
            {
                delta *= (deltaLen - deadzone) / deltaLen;
                brushBone.lastTarget = body.position + delta;
                delta        /= Time.fixedDeltaTime;
                body.velocity = (delta / delta.magnitude) * Mathf.Clamp(delta.magnitude, 0f, 6f);
            }
        }
Ejemplo n.º 3
0
        private InteractionBrushBone BeginBone(Bone bone, GameObject brushGameObject, int boneArrayIndex, Collider collider_)
        {
            brushGameObject.layer = gameObject.layer;
            brushGameObject.transform.localScale = Vector3.one;

            InteractionBrushBone brushBone = brushGameObject.GetComponent <InteractionBrushBone>();

            brushBone.col = collider_;
            if (_manager != null)
            {
                brushBone.manager = _manager;
            }
            _brushBones[boneArrayIndex] = brushBone;

            Transform capsuleTransform = brushGameObject.transform;

            capsuleTransform.SetParent(_handParent.transform, false);

            Rigidbody body = brushGameObject.GetComponent <Rigidbody>();

            body.freezeRotation         = true;
            brushBone.body              = body;
            body.useGravity             = false;
            body.collisionDetectionMode = _collisionDetection;
            if (collider_ is BoxCollider)
            {
                body.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
            }

            body.mass     = _perBoneMass;
            body.position = bone != null?bone.Center.ToVector3() : _hand.PalmPosition.ToVector3();

            body.rotation = bone != null?bone.Rotation.ToQuaternion() : _hand.Rotation.ToQuaternion();

            brushBone.lastTarget = bone != null?bone.Center.ToVector3() : _hand.PalmPosition.ToVector3();

            return(brushBone);
        }
Ejemplo n.º 4
0
        /** Start using this hand model to represent a tracked hand. */
        public override void BeginHand()
        {
            base.BeginHand();

            if (handBegun)
            {
                for (int i = _brushBones.Length; i-- != 0;)
                {
                    _brushBones[i].gameObject.SetActive(true);
                    _brushBones[i].transform.position = _hand.PalmPosition.ToVector3();
                }
                _handParent.SetActive(true);
                enableSoftContact();
                return;
            }

#if UNITY_EDITOR
            if (!EditorApplication.isPlaying)
            {
                return;
            }

            // We also require a material for friction to be able to work.
            if (_material == null || _material.bounciness != 0.0f || _material.bounceCombine != PhysicMaterialCombine.Minimum)
            {
                Debug.LogError("An InteractionBrushHand must have a material with 0 bounciness and a bounceCombine of Minimum.  Name: " + gameObject.name);
            }

            checkContactState();
#endif

            _handParent = new GameObject(gameObject.name);
            if (_manager != null)
            {
                _handParent.transform.parent = _manager.transform;
            }                                                                      // Prevent hand from moving when you turn your head.

#if UNITY_EDITOR
            _handParent.AddComponent <RuntimeColliderGizmos>();
#endif

            _brushBones = new InteractionBrushBone[N_FINGERS * N_ACTIVE_BONES + 1];

            for (int fingerIndex = 0; fingerIndex < N_FINGERS; fingerIndex++)
            {
                for (int jointIndex = 0; jointIndex < N_ACTIVE_BONES; jointIndex++)
                {
                    Bone bone           = _hand.Fingers[fingerIndex].Bone((Bone.BoneType)(jointIndex) + 1); // +1 to skip first bone.
                    int  boneArrayIndex = fingerIndex * N_ACTIVE_BONES + jointIndex;

                    GameObject brushGameObject = new GameObject(gameObject.name, typeof(CapsuleCollider), typeof(Rigidbody), typeof(InteractionBrushBone));

                    brushGameObject.transform.position = bone.Center.ToVector3();
                    brushGameObject.transform.rotation = bone.Rotation.ToQuaternion();
                    CapsuleCollider capsule = brushGameObject.GetComponent <CapsuleCollider>();
                    capsule.direction = 2;
                    capsule.radius    = bone.Width * 0.5f;
                    capsule.height    = bone.Length + bone.Width;
                    capsule.material  = _material;

                    InteractionBrushBone brushBone = BeginBone(bone, brushGameObject, boneArrayIndex, capsule);

                    brushBone.lastTarget = bone.Center.ToVector3();
                }
            }

            // Palm is attached to the third metacarpal and derived from it.
            {
                Bone       bone            = _hand.Fingers[(int)Finger.FingerType.TYPE_MIDDLE].Bone(Bone.BoneType.TYPE_METACARPAL);
                int        boneArrayIndex  = N_FINGERS * N_ACTIVE_BONES;
                GameObject brushGameObject = new GameObject(gameObject.name, typeof(BoxCollider), typeof(Rigidbody), typeof(InteractionBrushBone));

                brushGameObject.transform.position = _hand.PalmPosition.ToVector3();
                brushGameObject.transform.rotation = _hand.Rotation.ToQuaternion();
                BoxCollider box = brushGameObject.GetComponent <BoxCollider>();
                box.center   = new Vector3(_hand.IsLeft ? -0.005f : 0.005f, bone.Width * -0.1f, -0.015f);
                box.size     = new Vector3(bone.Length, bone.Width, bone.Length);
                box.material = _material;

                BeginBone(null, brushGameObject, boneArrayIndex, box);
            }

            //Add joints between each of the hand's rigidbodies to ensure they do not separate
            addHandJoints();

            handBegun = true;
        }
Ejemplo n.º 5
0
        /** Start using this hand model to represent a tracked hand. */
        public override void BeginHand()
        {
            base.BeginHand();

#if UNITY_EDITOR
            if (!EditorApplication.isPlaying)
            {
                return;
            }

            // We also require a material for friction to be able to work.
            if (_material == null || _material.bounciness != 0.0f || _material.bounceCombine != PhysicMaterialCombine.Minimum)
            {
                Debug.LogError("An InteractionBrushHand must have a material with 0 bounciness and a bounceCombine of Minimum.  Name: " + gameObject.name);
            }

            checkContactState();
#endif

            _handParent = new GameObject(gameObject.name);
            _handParent.transform.parent = null; // Prevent hand from moving when you turn your head.

            _brushBones = new InteractionBrushBone[N_FINGERS * N_ACTIVE_BONES];

            for (int fingerIndex = 0; fingerIndex < N_FINGERS; fingerIndex++)
            {
                for (int jointIndex = 0; jointIndex < N_ACTIVE_BONES; jointIndex++)
                {
                    Bone bone           = _hand.Fingers[fingerIndex].Bone((Bone.BoneType)(jointIndex + 1)); // +1 to skip first bone.
                    int  boneArrayIndex = fingerIndex * N_ACTIVE_BONES + jointIndex;

                    GameObject brushGameObject = new GameObject(gameObject.name, typeof(CapsuleCollider), typeof(Rigidbody), typeof(InteractionBrushBone));
                    brushGameObject.layer = gameObject.layer;
                    brushGameObject.transform.localScale = Vector3.one;

                    InteractionBrushBone brushBone = brushGameObject.GetComponent <InteractionBrushBone>();
                    brushBone.manager           = _manager;
                    _brushBones[boneArrayIndex] = brushBone;

                    Transform capsuleTransform = brushGameObject.transform;
                    capsuleTransform.SetParent(_handParent.transform, false);

                    CapsuleCollider capsule = brushGameObject.GetComponent <CapsuleCollider>();
                    capsule.direction         = 2;
                    capsule.radius            = bone.Width * 0.5f;
                    capsule.height            = bone.Length + bone.Width;
                    capsule.material          = _material;
                    brushBone.capsuleCollider = capsule;

                    Rigidbody body = brushGameObject.GetComponent <Rigidbody>();
                    brushBone.capsuleBody = body;
                    body.position         = bone.Center.ToVector3();
                    body.rotation         = bone.Rotation.ToQuaternion();
                    body.freezeRotation   = true;
                    body.useGravity       = false;

                    body.mass = _perBoneMass;
                    body.collisionDetectionMode = _collisionDetection;

                    brushBone.lastTarget = bone.Center.ToVector3();
                }
            }
        }