예제 #1
0
    void FixHand(HandModel handModel, Side side, Transform wristOffset)
    {
        // Check errors
        if (handModel.fingers.Length == 0)
        {
            Debug.LogError("Fingers array is empty!");
            return;
        }

        // Not all hands need an offset
        if (!wristOffset)
        {
            wristOffset = handModel.wrist.transformRef;
        }

        // Pinch center
        if (!handModel.pinchCenter)
        {
            GameObject pinchCenter = BasicHelpers.InstantiateEmptyChild(handModel.wrist.transformRef.parent.gameObject);
            pinchCenter.name = "PinchCenter";

            PositionConstraint pinchPosConstraint = pinchCenter.AddComponent <PositionConstraint>();

            ConstraintSource indexTipSource = new ConstraintSource();
            indexTipSource.sourceTransform = handModel.index.fingerTip;
            indexTipSource.weight          = 1.0f;

            ConstraintSource thumbTipSource = new ConstraintSource();
            thumbTipSource.sourceTransform = handModel.thumb.fingerTip;
            thumbTipSource.weight          = 1.0f;

            pinchPosConstraint.AddSource(indexTipSource);
            pinchPosConstraint.AddSource(thumbTipSource);

            pinchPosConstraint.translationOffset = Vector3.zero;

            pinchPosConstraint.constraintActive = true;

            handModel.pinchCenter = pinchCenter.transform;
        }

        // Throat center
        if (!handModel.throatCenter)
        {
            GameObject throatCenter = BasicHelpers.InstantiateEmptyChild(handModel.wrist.transformRef.parent.gameObject);
            throatCenter.name = "ThroatCenter";

            PositionConstraint throatPosConstraint = throatCenter.AddComponent <PositionConstraint>();

            ConstraintSource indexBaseSource = new ConstraintSource();
            indexBaseSource.sourceTransform = handModel.index.fingerBase;
            indexBaseSource.weight          = 1.0f;

            ConstraintSource thumbBaseSource = new ConstraintSource();
            thumbBaseSource.sourceTransform = handModel.thumb.fingerBase;
            thumbBaseSource.weight          = 1.0f;

            throatPosConstraint.AddSource(indexBaseSource);
            throatPosConstraint.AddSource(thumbBaseSource);

            throatPosConstraint.translationOffset = Vector3.zero;

            throatPosConstraint.constraintActive = true;

            handModel.throatCenter = throatCenter.transform;
        }

        // meanPoint
        meanPoint = Vector3.zero;
        for (int f = 0; f < handModel.fingers.Length; f++)
        {
            meanPoint += handModel.fingers[f].fingerBase.position;
        }
        meanPoint = meanPoint / handModel.fingers.Length;

        // palmRadius
        float meanDistance = 0.0f;

        for (int f = 0; f < handModel.fingers.Length; f++)
        {
            meanDistance += Vector3.Distance(meanPoint, handModel.fingers[f].fingerBase.position);
        }
        meanDistance = meanDistance / handModel.fingers.Length;
        palmRadius   = meanDistance;

        // Palm center
        if (!handModel.palmCenter)
        {
            GameObject palmCenter = BasicHelpers.InstantiateEmptyChild(wristOffset.gameObject);
            palmCenter.name = "PalmCenter";

            palmCenter.transform.position = meanPoint;

            if (side == Side.L)
            {
                palmCenter.transform.position     += new Vector3(0.0f, fingerRadius, 0.0f);
                palmCenter.transform.localRotation = Quaternion.Euler(new Vector3(-90.0f, 0.0f, 0.0f));
            }
            else
            {
                palmCenter.transform.position     -= new Vector3(0.0f, fingerRadius, 0.0f);
                palmCenter.transform.localRotation = Quaternion.Euler(new Vector3(-90.0f, 0.0f, 180.0f));
            }

            handModel.palmCenter = palmCenter.transform;
        }

        // Palm normal (depends on palmCenter)
        if (!handModel.palmNormal)
        {
            GameObject palmNormal = BasicHelpers.InstantiateEmptyChild(wristOffset.gameObject);
            palmNormal.name = "PalmNormal";

            palmNormal.transform.position = handModel.palmCenter.position;

            if (side == Side.L)
            {
                palmNormal.transform.localRotation = Quaternion.Euler(new Vector3(-90.0f, 0.0f, 0.0f));
            }
            else
            {
                palmNormal.transform.localRotation = Quaternion.Euler(new Vector3(90.0f, 0.0f, 0.0f));
            }

            handModel.palmNormal = palmNormal.transform;
        }

        // Palm interior/exterior (depend on PalmCenter and palmRadius)
        if (!handModel.palmInterior)
        {
            GameObject palmInterior = BasicHelpers.InstantiateEmptyChild(wristOffset.gameObject);
            palmInterior.name = "PalmInterior";

            palmInterior.transform.position = handModel.palmCenter.position;
            palmInterior.transform.rotation = handModel.palmCenter.rotation;

            palmInterior.transform.position += handModel.palmCenter.up * palmRadius;

            handModel.palmInterior = palmInterior.transform;
        }
        if (!handModel.palmExterior)
        {
            GameObject palmExterior = BasicHelpers.InstantiateEmptyChild(wristOffset.gameObject);
            palmExterior.name = "PalmExterior";

            palmExterior.transform.position = handModel.palmCenter.position;
            palmExterior.transform.rotation = handModel.palmCenter.rotation;

            palmExterior.transform.position -= handModel.palmCenter.up * palmRadius;

            handModel.palmExterior = palmExterior.transform;
        }

        // Ray line (depend on PalmCenter)
        if (!handModel.ray)
        {
            GameObject ray = BasicHelpers.InstantiateEmptyChild(wristOffset.gameObject);
            ray.name = "Ray";

            ray.transform.position = handModel.palmCenter.position;

            LineRenderer lineRenderer = ray.AddComponent <LineRenderer>();
            lineRenderer.useWorldSpace = false;
            lineRenderer.SetPositions(new Vector3[] { Vector3.zero, new Vector3(0.0f, 0.0f, 0.5f) });
            lineRenderer.material   = rayMat;
            lineRenderer.startWidth = rayWidth;
            lineRenderer.endWidth   = rayWidth;

            handModel.ray = ray.transform;
        }

        if (handModel is SlaveHandModel)
        {
            SlaveHandModel slaveHandModel = handModel as SlaveHandModel;

            // Palm trigger (depend on PalmCenter and palmRadius)
            if (!slaveHandModel.palmTrigger)
            {
                GameObject palmTrigger = BasicHelpers.InstantiateEmptyChild(wristOffset.gameObject);
                palmTrigger.name = "PalmTrigger";

                palmTrigger.transform.position = handModel.palmCenter.position;

                SphereCollider trigger = palmTrigger.AddComponent <SphereCollider>();
                trigger.isTrigger = true;
                trigger.radius    = palmRadius;

                TriggerNotifier notifier = palmTrigger.AddComponent <TriggerNotifier>();
                notifier.ignoreChildren = handModel.wrist.transformRef.parent;

                slaveHandModel.palmTrigger = notifier;
            }

            // Hand trigger (depend on PalmCenter and palmRadius)
            if (!slaveHandModel.handTrigger)
            {
                GameObject handTrigger = BasicHelpers.InstantiateEmptyChild(wristOffset.gameObject);
                handTrigger.name = "HandTrigger";

                handTrigger.transform.position = handModel.palmCenter.position;

                SphereCollider trigger = handTrigger.AddComponent <SphereCollider>();
                trigger.isTrigger = true;
                trigger.radius    = Vector3.Distance(meanPoint, BasicHelpers.FurthestPoint(meanPoint, GetFingerTips(slaveHandModel))) + 0.02f;

                TriggerNotifier notifier = handTrigger.AddComponent <TriggerNotifier>();
                notifier.ignoreChildren = handModel.wrist.transformRef.parent;

                slaveHandModel.handTrigger = notifier;
            }
        }

        // Colliders, Rigidbodies and Joitsn if needed
        if (handModel is SlaveHandModel)
        {
            // Setup colliders, rbs and joints for slave
            SetupPhysics(handModel as SlaveHandModel, wristOffset, meanPoint, palmRadius, fingerRadius);
        }
    }