float CalculateAngle(BendingSegment seg, float angle)
    {
        // Handle threshold angle difference, bending multiplier,
        // and max angle difference here
        float hAngleThr =
            Mathf.Max(
                0,
                Mathf.Abs(angle) - seg.thresholdAngleDifference)
            * Mathf.Sign(angle);

        angle =
            Mathf.Max(
                Mathf.Abs(hAngleThr) * Mathf.Abs(seg.bendingMultiplier),
                Mathf.Abs(angle) - seg.maxAngleDifference)
            * Mathf.Sign(angle)
            * Mathf.Sign(seg.bendingMultiplier);

        // If we're in restricted mode
        float maxBendingAngle = seg.maxBendingAngle;

        if (this.Restricted == true)
        {
            maxBendingAngle = seg.restrictedBendingAngle;
        }

        // Handle max bending angle here
        angle =
            Mathf.Clamp(
                angle,
                -maxBendingAngle,
                maxBendingAngle);

        return(angle);
    }
예제 #2
0
 private void Start()
 {
     if (this.rootNode == null)
     {
         this.rootNode = base.transform;
     }
     BendingSegment[] array = this.segments;
     for (int i = 0; i < array.Length; i++)
     {
         BendingSegment bendingSegment = array[i];
         Quaternion     rotation       = bendingSegment.firstTransform.parent.rotation;
         Quaternion     lhs            = Quaternion.Inverse(rotation);
         bendingSegment.referenceLookDir = lhs * this.rootNode.rotation * this.headLookVector.normalized;
         bendingSegment.referenceUpDir   = lhs * this.rootNode.rotation * this.headUpVector.normalized;
         bendingSegment.angleH           = 0f;
         bendingSegment.angleV           = 0f;
         bendingSegment.dirUp            = bendingSegment.referenceUpDir;
         bendingSegment.chainLength      = 1;
         Transform transform = bendingSegment.lastTransform;
         while (transform != bendingSegment.firstTransform && transform != transform.root)
         {
             bendingSegment.chainLength++;
             transform = transform.parent;
         }
         bendingSegment.origRotations = new Quaternion[bendingSegment.chainLength];
         transform = bendingSegment.lastTransform;
         for (int j = bendingSegment.chainLength - 1; j >= 0; j--)
         {
             bendingSegment.origRotations[j] = transform.localRotation;
             transform = transform.parent;
         }
     }
 }
예제 #3
0
 public void AddSegment(BendingSegment Segment)
 {
     if (this.segments == null)
     {
         this.segments = new List <BendingSegment>();
     }
     this.segments.Add(Segment);
 }
예제 #4
0
    public BendingSegment(BendingSegment other)
    {
        this.firstTransform           = other.firstTransform;
        this.lastTransform            = other.lastTransform;
        this.bodyPart                 = other.bodyPart;
        this.thresholdAngleDifference = other.thresholdAngleDifference;
        this.bendingMultiplier        = other.bendingMultiplier;
        this.maxAngleDifference       = other.maxAngleDifference;
        this.maxBendingAngle          = other.maxBendingAngle;
        this.responsiveness           = other.responsiveness;
        this.angleH           = other.angleH;
        this.angleV           = other.angleV;
        this.dirUp            = other.dirUp;
        this.referenceLookDir = other.referenceLookDir;
        this.referenceUpDir   = other.referenceUpDir;
        this.chainLength      = other.chainLength;
        this.origRotations    = new Quaternion[other.origRotations.Length];

        for (int i = 0; i < this.origRotations.Length; ++i)
        {
            this.origRotations[i] = other.origRotations[i];
        }
    }
예제 #5
0
    public void AutoPopulateSegments()
    {
        segments = new BendingSegment[5];
        nonAffectedJoints = new Impulsion.NonAffectedJoints[2];

        for (int i = 0; i < 5; i++)
            segments[i] = new BendingSegment();

        for (int i = 0; i < 2; i++)
            nonAffectedJoints[i] = new Impulsion.NonAffectedJoints();

        nonAffectedJoints[0].joint = _abf.findBone("LeftArm");
        nonAffectedJoints[0].effect = 0.4f;
        nonAffectedJoints[1].joint = _abf.findBone("RightArm");
        nonAffectedJoints[1].effect = 0.4f;

        segments[0].firstTransform = _abf.findBone("Spine");
        segments[0].lastTransform = _abf.findBone("Spine1");
        segments[0].thresholdAngleDifference = 45f;
        segments[0].bendingMultiplier = 0.6f;
        segments[0].maxAngleDifference = 30f;
        segments[0].maxBendingAngle = 10f;
        segments[0].responsiveness = 0.5f;
        segments[0].leanEffect = 0.5f;

        segments[1].firstTransform = segments[0].lastTransform;
        segments[1].lastTransform = _abf.findBone("Spine2");
        segments[1].thresholdAngleDifference = 30f;
        segments[1].bendingMultiplier = 0.6f;
        segments[1].maxAngleDifference = 90f;
        segments[1].maxBendingAngle = 20f;
        segments[1].responsiveness = 0.5f;
        segments[1].leanEffect = 0.5f;

        segments[2].firstTransform = _abf.findBone("Neck");
        segments[2].lastTransform = _abf.findBone("Head");
        segments[2].isHead = true;
        segments[2].thresholdAngleDifference = 15f;
        segments[2].bendingMultiplier = 0.7f;
        segments[2].maxAngleDifference = 75f;
        segments[2].maxBendingAngle = 65f;
        segments[2].responsiveness = 2f;
        segments[2].leanEffect = 0f;

        segments[3].firstTransform = _abf.findBone("LeftEye");
        segments[3].lastTransform = segments[3].firstTransform;
        segments[3].isEye = true;
        segments[3].thresholdAngleDifference = 0f;
        segments[3].bendingMultiplier = 1f;
        segments[3].maxAngleDifference = 0f;
        segments[3].maxBendingAngle = 15f;
        segments[3].responsiveness = 20f;
        segments[3].leanEffect = 0f;

        segments[4].firstTransform = _abf.findBone("RightEye");
        segments[4].lastTransform = segments[4].firstTransform;
        segments[4].isEye = true;
        segments[4].thresholdAngleDifference = 0f;
        segments[4].bendingMultiplier = 1f;
        segments[4].maxAngleDifference = 0f;
        segments[4].maxBendingAngle = 15f;
        segments[4].responsiveness = 20f;
        segments[4].leanEffect = 0f;
    }
예제 #6
0
 private void LateUpdate()
 {
     if (Time.deltaTime == 0f)
     {
         return;
     }
     Vector3[] array = new Vector3[this.nonAffectedJoints.Length];
     for (int i = 0; i < this.nonAffectedJoints.Length; i++)
     {
         IEnumerator enumerator = this.nonAffectedJoints[i].joint.GetEnumerator();
         try
         {
             if (enumerator.MoveNext())
             {
                 Transform transform = (Transform)enumerator.Current;
                 array[i] = transform.position - this.nonAffectedJoints[i].joint.position;
             }
         }
         finally
         {
             IDisposable disposable = enumerator as IDisposable;
             if (disposable != null)
             {
                 disposable.Dispose();
             }
         }
     }
     BendingSegment[] array2 = this.segments;
     for (int j = 0; j < array2.Length; j++)
     {
         BendingSegment bendingSegment = array2[j];
         Transform      transform2     = bendingSegment.lastTransform;
         if (this.overrideAnimation)
         {
             for (int k = bendingSegment.chainLength - 1; k >= 0; k--)
             {
                 transform2.localRotation = bendingSegment.origRotations[k];
                 transform2 = transform2.parent;
             }
         }
         Quaternion rotation   = bendingSegment.firstTransform.parent.rotation;
         Quaternion rotation2  = Quaternion.Inverse(rotation);
         Vector3    normalized = (this.target - bendingSegment.lastTransform.position).normalized;
         Vector3    vector     = rotation2 * normalized;
         float      num        = HeadLookController.AngleAroundAxis(bendingSegment.referenceLookDir, vector, bendingSegment.referenceUpDir);
         Vector3    axis       = Vector3.Cross(bendingSegment.referenceUpDir, vector);
         Vector3    dirA       = vector - Vector3.Project(vector, bendingSegment.referenceUpDir);
         float      num2       = HeadLookController.AngleAroundAxis(dirA, vector, axis);
         float      f          = Mathf.Max(0f, Mathf.Abs(num) - bendingSegment.thresholdAngleDifference) * Mathf.Sign(num);
         float      f2         = Mathf.Max(0f, Mathf.Abs(num2) - bendingSegment.thresholdAngleDifference) * Mathf.Sign(num2);
         num  = Mathf.Max(Mathf.Abs(f) * Mathf.Abs(bendingSegment.bendingMultiplier), Mathf.Abs(num) - bendingSegment.maxAngleDifference) * Mathf.Sign(num) * Mathf.Sign(bendingSegment.bendingMultiplier);
         num2 = Mathf.Max(Mathf.Abs(f2) * Mathf.Abs(bendingSegment.bendingMultiplier), Mathf.Abs(num2) - bendingSegment.maxAngleDifference) * Mathf.Sign(num2) * Mathf.Sign(bendingSegment.bendingMultiplier);
         num  = Mathf.Clamp(num, -bendingSegment.maxBendingAngle, bendingSegment.maxBendingAngle);
         num2 = Mathf.Clamp(num2, -bendingSegment.maxBendingAngle, bendingSegment.maxBendingAngle);
         Vector3 axis2 = Vector3.Cross(bendingSegment.referenceUpDir, bendingSegment.referenceLookDir);
         bendingSegment.angleH = Mathf.Lerp(bendingSegment.angleH, num, Time.deltaTime * bendingSegment.responsiveness);
         bendingSegment.angleV = Mathf.Lerp(bendingSegment.angleV, num2, Time.deltaTime * bendingSegment.responsiveness);
         vector = Quaternion.AngleAxis(bendingSegment.angleH, bendingSegment.referenceUpDir) * Quaternion.AngleAxis(bendingSegment.angleV, axis2) * bendingSegment.referenceLookDir;
         Vector3 referenceUpDir = bendingSegment.referenceUpDir;
         Vector3.OrthoNormalize(ref vector, ref referenceUpDir);
         Vector3 forward = vector;
         bendingSegment.dirUp = Vector3.Slerp(bendingSegment.dirUp, referenceUpDir, Time.deltaTime * 5f);
         Vector3.OrthoNormalize(ref forward, ref bendingSegment.dirUp);
         Quaternion to  = rotation * Quaternion.LookRotation(forward, bendingSegment.dirUp) * Quaternion.Inverse(rotation * Quaternion.LookRotation(bendingSegment.referenceLookDir, bendingSegment.referenceUpDir));
         Quaternion lhs = Quaternion.Slerp(Quaternion.identity, to, this.effect / (float)bendingSegment.chainLength);
         transform2 = bendingSegment.lastTransform;
         for (int l = 0; l < bendingSegment.chainLength; l++)
         {
             transform2.rotation = lhs * transform2.rotation;
             transform2          = transform2.parent;
         }
     }
     for (int m = 0; m < this.nonAffectedJoints.Length; m++)
     {
         Vector3     vector2     = Vector3.zero;
         IEnumerator enumerator2 = this.nonAffectedJoints[m].joint.GetEnumerator();
         try
         {
             if (enumerator2.MoveNext())
             {
                 Transform transform3 = (Transform)enumerator2.Current;
                 vector2 = transform3.position - this.nonAffectedJoints[m].joint.position;
             }
         }
         finally
         {
             IDisposable disposable2 = enumerator2 as IDisposable;
             if (disposable2 != null)
             {
                 disposable2.Dispose();
             }
         }
         Vector3 toDirection = Vector3.Slerp(array[m], vector2, this.nonAffectedJoints[m].effect);
         this.nonAffectedJoints[m].joint.rotation = Quaternion.FromToRotation(vector2, toDirection) * this.nonAffectedJoints[m].joint.rotation;
     }
 }
예제 #7
0
    public void OnStart(CBody oBody)
    {
        _oBody = oBody;						//###MOD: Init segment from code as our component is added at runtime now
        BendingSegment oSeg = new BendingSegment();

        oSeg.firstTransform		= _oBody._oBodyBase.FindBone("chest/neck");			//###IMPROVE?  Can spine be added (or would interfere with our anim too much?)
        oSeg.lastTransform		= _oBody._oBodyBase.FindBone("chest/neck/head");
        oSeg.thresholdAngleDifference = 0;			//###???
        oSeg.bendingMultiplier = 1.0f;				//###IMPROVE!!!: Add 'eyes' and get them to move part of the way
        oSeg.maxAngleDifference = 90;
        oSeg.maxBendingAngle = 40;					//###IMPROVE: Reduce angle for head up / down and wider for head left/right
        oSeg.responsiveness = 3.0f;					//###TUNE!!!
        segments[0] = oSeg;

        if (rootNode == null)
            rootNode = transform;

        // Setup segments
        foreach (BendingSegment segment in segments) {
            Quaternion parentRot = segment.firstTransform.parent.rotation;
            Quaternion parentRotInv = Quaternion.Inverse(parentRot);
            segment.referenceLookDir =
                parentRotInv * rootNode.rotation * headLookVector.normalized;
            segment.referenceUpDir =
                parentRotInv * rootNode.rotation * headUpVector.normalized;
            segment.angleH = 0;
            segment.angleV = 0;
            segment.dirUp = segment.referenceUpDir;

            segment.chainLength = 1;
            Transform t = segment.lastTransform;
            while (t != segment.firstTransform && t != t.root) {
                segment.chainLength++;
                t = t.parent;
            }

            segment.origRotations = new Quaternion[segment.chainLength];
            t = segment.lastTransform;
            for (int i=segment.chainLength - 1; i >= 0; i--) {
                segment.origRotations[i] = t.localRotation;
                t = t.parent;
            }
        }
    }
    float CalculateAngle(BendingSegment seg, float angle)
    {
        // Handle threshold angle difference, bending multiplier,
        // and max angle difference here
        float hAngleThr =
            Mathf.Max(
                0,
                Mathf.Abs(angle) - seg.thresholdAngleDifference)
            * Mathf.Sign(angle);

        angle =
            Mathf.Max(
                Mathf.Abs(hAngleThr) * Mathf.Abs(seg.bendingMultiplier),
                Mathf.Abs(angle) - seg.maxAngleDifference)
            * Mathf.Sign(angle)
            * Mathf.Sign(seg.bendingMultiplier);

        // If we're in restricted mode
        float maxBendingAngle = seg.maxBendingAngle;
        if (this.Restricted == true)
            maxBendingAngle = seg.restrictedBendingAngle;

        // Handle max bending angle here
        angle =
            Mathf.Clamp(
                angle,
                -maxBendingAngle,
                maxBendingAngle);

        return angle;
    }