Inheritance: RootMotion.FinalIK.IKSolverFullBody
Beispiel #1
0
            // Update this body, apply the offset to the effector
            public void Update(IKSolverFullBodyBiped solver, float weight, float deltaTime)
            {
                if (transform == null) return;

                // If first update, set this body to Transform
                if (firstUpdate) {
                    Reset();
                    firstUpdate = false;
                }

                // Acceleration
                direction = Vector3.Lerp(direction, ((transform.position - lazyPoint) / deltaTime) * 0.01f, deltaTime * acceleration);

                // Lazy follow
                lazyPoint += direction * deltaTime * speed;

                // Match velocity
                delta = transform.position - lastPosition;
                lazyPoint += delta * matchVelocity;

                // Gravity
                lazyPoint.y += gravity * deltaTime;

                // Apply position offset to the effector
                foreach (EffectorLink effectorLink in effectorLinks) {
                    solver.GetEffector(effectorLink.effector).positionOffset += (lazyPoint - transform.position) * effectorLink.weight * weight;
                }

                lastPosition = transform.position;
            }
Beispiel #2
0
        // Apply the curve to the specified solver, effector, with the value and weight.
        private void Apply(IKSolverFullBodyBiped solver, FullBodyBipedEffector effector, WeightCurve.Type type, float value, float weight)
        {
            switch (type)
            {
            case WeightCurve.Type.PositionWeight:
                solver.GetEffector(effector).positionWeight = Mathf.Lerp(solver.GetEffector(effector).positionWeight, value, weight);
                return;

            case WeightCurve.Type.RotationWeight:
                solver.GetEffector(effector).rotationWeight = Mathf.Lerp(solver.GetEffector(effector).rotationWeight, value, weight);
                return;

            case WeightCurve.Type.PositionOffsetX:
                solver.GetEffector(effector).position += solver.GetRoot().rotation *Vector3.right *value *weight;
                return;

            case WeightCurve.Type.PositionOffsetY:
                solver.GetEffector(effector).position += solver.GetRoot().rotation *Vector3.up *value *weight;
                return;

            case WeightCurve.Type.PositionOffsetZ:
                solver.GetEffector(effector).position += solver.GetRoot().rotation *Vector3.forward *value *weight;
                return;

            case WeightCurve.Type.Pull:
                solver.GetChain(effector).pull = Mathf.Lerp(solver.GetChain(effector).pull, value, weight);
                return;

            case WeightCurve.Type.Reach:
                solver.GetChain(effector).reach = Mathf.Lerp(solver.GetChain(effector).reach, value, weight);
                return;
            }
        }
Beispiel #3
0
 public void Apply(IKSolverFullBodyBiped solver, float weight, Quaternion rotation)
 {
     for (int i = 0; i < this.effectorLinks.Length; i++)
     {
         this.effectorLinks[i].Apply(solver, weight, rotation);
     }
 }
Beispiel #4
0
        protected virtual void Start()
        {
            if (this.fullBody == null)
            {
                this.fullBody = base.GetComponent <FullBodyBipedIK>();
            }
            if (this.fullBody == null)
            {
                Warning.Log("InteractionSystem can not find a FullBodyBipedIK component", base.transform, false);
                return;
            }
            IKSolverFullBodyBiped solver = this.fullBody.solver;

            solver.OnPreUpdate = (IKSolver.UpdateDelegate)Delegate.Combine(solver.OnPreUpdate, new IKSolver.UpdateDelegate(this.OnPreFBBIK));
            IKSolverFullBodyBiped solver2 = this.fullBody.solver;

            solver2.OnPostUpdate     = (IKSolver.UpdateDelegate)Delegate.Combine(solver2.OnPostUpdate, new IKSolver.UpdateDelegate(this.OnPostFBBIK));
            this.OnInteractionStart  = (InteractionSystem.InteractionDelegate)Delegate.Combine(this.OnInteractionStart, new InteractionSystem.InteractionDelegate(this.LookAtInteraction));
            this.OnInteractionPause  = (InteractionSystem.InteractionDelegate)Delegate.Combine(this.OnInteractionPause, new InteractionSystem.InteractionDelegate(this.InteractionPause));
            this.OnInteractionResume = (InteractionSystem.InteractionDelegate)Delegate.Combine(this.OnInteractionResume, new InteractionSystem.InteractionDelegate(this.InteractionResume));
            this.OnInteractionStop   = (InteractionSystem.InteractionDelegate)Delegate.Combine(this.OnInteractionStop, new InteractionSystem.InteractionDelegate(this.InteractionStop));
            foreach (InteractionEffector interactionEffector in this.interactionEffectors)
            {
                interactionEffector.Initiate(this);
            }
            this.triggersInRange = new List <InteractionTrigger>();
            this.c = base.GetComponent <Collider>();
            this.UpdateTriggerEventBroadcasting();
            this.initiated = true;
        }
        // Check for possible warnings with the biped references setup
        private void CheckWarning(BipedReferences references, IKSolverFullBodyBiped solver, Transform context, bool log)
        {
            // Check for all the warnings common to all bipeds
            BipedReferences.CheckSetupWarning(script.references, log);

            // Check for warnings specific to FBBIK
            Vector3 toRightShoulder    = references.rightUpperArm.position - references.leftUpperArm.position;
            Vector3 shoulderToRootNode = solver.rootNode.position - references.leftUpperArm.position;
            float   dot = Vector3.Dot(toRightShoulder.normalized, shoulderToRootNode.normalized);

            if (dot > 0.95f)
            {
                if (log)
                {
                    Warning.Log("The root node, the left upper arm and the right upper arm bones should ideally form a triangle that is as close to equilateral as possible. " +
                                "Currently the root node bone seems to be very close to the line between the left upper arm and the right upper arm bones. This might cause unwanted behaviour like the spine turning upside down when pulled by a hand effector." +
                                "Please set the root node bone to be one of the lower bones in the spine.", context, true);
                }
            }

            Vector3 toRightThigh    = references.rightThigh.position - references.leftThigh.position;
            Vector3 thighToRootNode = solver.rootNode.position - references.leftThigh.position;

            dot = Vector3.Dot(toRightThigh.normalized, thighToRootNode.normalized);

            if (dot > 0.95f && log)
            {
                Warning.Log("The root node, the left thigh and the right thigh bones should ideally form a triangle that is as close to equilateral as possible. " +
                            "Currently the root node bone seems to be very close to the line between the left thigh and the right thigh bones. This might cause unwanted behaviour like the hip turning upside down when pulled by an effector." +
                            "Please set the root node bone to be one of the higher bones in the spine.", context, true);
            }
        }
 public bool ResetToDefaults(IKSolverFullBodyBiped solver, float speed)
 {
     if (this.inInteraction)
     {
         return(false);
     }
     if (this.isPaused)
     {
         return(false);
     }
     if (this.defaults)
     {
         return(false);
     }
     this.resetTimer = Mathf.Clamp(this.resetTimer -= Time.deltaTime * speed, 0f, 1f);
     if (this.effector.isEndEffector)
     {
         solver.GetChain(this.effectorType).pull       = Mathf.Lerp(this.defaultPull, solver.GetChain(this.effectorType).pull, this.resetTimer);
         solver.GetChain(this.effectorType).reach      = Mathf.Lerp(this.defaultReach, solver.GetChain(this.effectorType).reach, this.resetTimer);
         solver.GetChain(this.effectorType).push       = Mathf.Lerp(this.defaultPush, solver.GetChain(this.effectorType).push, this.resetTimer);
         solver.GetChain(this.effectorType).pushParent = Mathf.Lerp(this.defaultPushParent, solver.GetChain(this.effectorType).pushParent, this.resetTimer);
     }
     this.effector.positionWeight = Mathf.Lerp(0f, this.effector.positionWeight, this.resetTimer);
     this.effector.rotationWeight = Mathf.Lerp(0f, this.effector.rotationWeight, this.resetTimer);
     if (this.resetTimer <= 0f)
     {
         this.defaults = true;
     }
     return(true);
 }
Beispiel #7
0
 private void LateUpdate()
 {
     if (this.ik == null)
     {
         return;
     }
     if (!this.initiated)
     {
         IKSolverFullBodyBiped solver = this.ik.solver;
         solver.OnPostUpdate = (IKSolver.UpdateDelegate)Delegate.Combine(solver.OnPostUpdate, new IKSolver.UpdateDelegate(this.OnPostFBBIK));
         this.initiated      = true;
     }
     if (this.ik.solver.leftHandEffector.target != null)
     {
         Vector3 left = Vector3.left;
         this.ik.solver.leftArmChain.bendConstraint.direction = this.ik.solver.leftHandEffector.target.rotation * left + this.ik.solver.leftHandEffector.target.rotation * this.bendDirectionOffsetLeft + this.ik.transform.rotation * this.characterSpaceBendOffsetLeft;
         this.ik.solver.leftArmChain.bendConstraint.weight    = 1f;
     }
     if (this.ik.solver.rightHandEffector.target != null)
     {
         Vector3 right = Vector3.right;
         this.ik.solver.rightArmChain.bendConstraint.direction = this.ik.solver.rightHandEffector.target.rotation * right + this.ik.solver.rightHandEffector.target.rotation * this.bendDirectionOffsetRight + this.ik.transform.rotation * this.characterSpaceBendOffsetRight;
         this.ik.solver.rightArmChain.bendConstraint.weight    = 1f;
     }
 }
Beispiel #8
0
        // Called after FBBIK update
        public void OnPostFBBIK(IKSolverFullBodyBiped fullBody)
        {
            if (!inInteraction)
            {
                return;
            }

            // Rotate the hands/feet to the RotateBoneWeight curve
            float rotateBoneWeight = interactionObject.GetValue(InteractionObject.WeightCurve.Type.RotateBoneWeight, interactionTarget, timer) * weight;

            if (rotateBoneWeight > 0f)
            {
                Quaternion r = pickedUp? pickUpRotation: effector.rotation;

                Quaternion targetRotation = Quaternion.Slerp(effector.bone.rotation, r, rotateBoneWeight * rotateBoneWeight);
                effector.bone.localRotation = Quaternion.Inverse(effector.bone.parent.rotation) * targetRotation;
            }

            // Positioning the interaction object to the effector (not the bone, because it is still at it's animated translation)
            if (pickUpOnPostFBBIK)
            {
                Vector3 bonePosition = effector.bone.position;
                effector.bone.SetPosition(pickUpPosition);

                interactionObject.targetsRoot.parent = effector.bone;

                effector.bone.SetPosition(bonePosition);

                pickUpOnPostFBBIK = false;
            }
        }
Beispiel #9
0
            // Apply to IKSolverFullBodyBiped
            public void Apply(IKSolverFullBodyBiped solver, float weight)
            {
                float deltaTime = Time.time - lastTime;

                lastTime = Time.time;

                if (timer >= length)
                {
                    return;
                }

                // Advance the timer
                timer = Mathf.Clamp(timer + deltaTime, 0f, length);

                // Advance the crossFader
                if (crossFadeSpeed > 0f)
                {
                    crossFader = Mathf.Clamp(crossFader + (deltaTime * crossFadeSpeed), 0f, 1f);
                }
                else
                {
                    crossFader = 1f;
                }

                // Pass this on to the hit points
                OnApply(solver, weight);
            }
Beispiel #10
0
 public void Apply(IKSolverFullBodyBiped solver, FullBodyBipedEffector effector, InteractionTarget target, float timer, float weight)
 {
     for (int i = 0; i < this.weightCurves.Length; i++)
     {
         float num = (!(target == null)) ? target.GetValue(this.weightCurves[i].type) : 1f;
         this.Apply(solver, effector, this.weightCurves[i].type, this.weightCurves[i].GetValue(timer), weight * num);
     }
     for (int j = 0; j < this.multipliers.Length; j++)
     {
         if (this.multipliers[j].curve == this.multipliers[j].result && !Warning.logged)
         {
             Warning.Log("InteractionObject Multiplier 'Curve' " + this.multipliers[j].curve.ToString() + "and 'Result' are the same.", base.transform, false);
         }
         int weightCurveIndex = this.GetWeightCurveIndex(this.multipliers[j].curve);
         if (weightCurveIndex != -1)
         {
             float num2 = (!(target == null)) ? target.GetValue(this.multipliers[j].result) : 1f;
             this.Apply(solver, effector, this.multipliers[j].result, this.multipliers[j].GetValue(this.weightCurves[weightCurveIndex], timer), weight * num2);
         }
         else if (!Warning.logged)
         {
             Warning.Log("InteractionObject Multiplier curve " + this.multipliers[j].curve.ToString() + "does not exist.", base.transform, false);
         }
     }
 }
Beispiel #11
0
        // Interpolate to default values when currently not in interaction
        public void ResetToDefaults(IKSolverFullBodyBiped solver, float speed)
        {
            if (inInteraction)
            {
                return;
            }
            if (isPaused)
            {
                return;
            }
            if (defaults)
            {
                return;
            }

            resetTimer = Mathf.Clamp(resetTimer -= Time.deltaTime * speed, 0f, 1f);

            // Pull and Reach
            if (effector.isEndEffector)
            {
                solver.GetChain(effectorType).pull  = Mathf.Lerp(defaultPull, solver.GetChain(effectorType).pull, resetTimer);
                solver.GetChain(effectorType).reach = Mathf.Lerp(defaultReach, solver.GetChain(effectorType).reach, resetTimer);
            }

            // Effector weights
            effector.positionWeight = Mathf.Lerp(0f, effector.positionWeight, resetTimer);
            effector.rotationWeight = Mathf.Lerp(0f, effector.rotationWeight, resetTimer);

            if (resetTimer <= 0f)
            {
                defaults = true;
            }
        }
Beispiel #12
0
            // Update this body, apply the offset to the effector
            public void Update(IKSolverFullBodyBiped solver, float weight, float deltaTime)
            {
                if (transform == null)
                {
                    return;
                }

                // If first update, set this body to Transform
                if (firstUpdate)
                {
                    Reset();
                    firstUpdate = false;
                }

                // Acceleration
                direction = Vector3.Lerp(direction, ((transform.position - lazyPoint) / deltaTime) * 0.01f, deltaTime * acceleration);

                // Lazy follow
                lazyPoint += direction * deltaTime * speed;

                // Match velocity
                delta      = transform.position - lastPosition;
                lazyPoint += delta * matchVelocity;

                // Gravity
                lazyPoint.y += gravity * deltaTime;

                // Apply position offset to the effector
                foreach (EffectorLink effectorLink in effectorLinks)
                {
                    solver.GetEffector(effectorLink.effector).positionOffset += (lazyPoint - transform.position) * effectorLink.weight * weight;
                }

                lastPosition = transform.position;
            }
Beispiel #13
0
        protected virtual void Start()
        {
            if (this.fullBody == null)
            {
                this.fullBody = base.GetComponent <FullBodyBipedIK>();
            }
            if (this.fullBody == null)
            {
                Warning.Log("InteractionSystem can not find a FullBodyBipedIK component", base.transform, false);
                return;
            }
            IKSolverFullBodyBiped expr_4B = this.fullBody.solver;

            expr_4B.OnPreUpdate = (IKSolver.UpdateDelegate)Delegate.Combine(expr_4B.OnPreUpdate, new IKSolver.UpdateDelegate(this.OnPreFBBIK));
            IKSolverFullBodyBiped expr_77 = this.fullBody.solver;

            expr_77.OnPostUpdate    = (IKSolver.UpdateDelegate)Delegate.Combine(expr_77.OnPostUpdate, new IKSolver.UpdateDelegate(this.OnPostFBBIK));
            this.OnInteractionStart = (InteractionSystem.InteractionDelegate)Delegate.Combine(this.OnInteractionStart, new InteractionSystem.InteractionDelegate(this.LookAtInteraction));
            InteractionEffector[] array = this.interactionEffectors;
            for (int i = 0; i < array.Length; i++)
            {
                InteractionEffector interactionEffector = array[i];
                interactionEffector.Initiate(this, this.fullBody.solver);
            }
            this.triggersInRange = new List <InteractionTrigger>();
            this.c = base.GetComponent <Collider>();
            this.UpdateTriggerEventBroadcasting();
            this.initiated = true;
        }
Beispiel #14
0
            public void Update(IKSolverFullBodyBiped solver, float w, float deltaTime)
            {
                if (this.transform == null || this.relativeTo == null)
                {
                    return;
                }
                Vector3 a = this.relativeTo.InverseTransformDirection(this.transform.position - this.relativeTo.position);

                if (this.firstUpdate)
                {
                    this.lastRelativePos = a;
                    this.firstUpdate     = false;
                }
                Vector3 vector = (a - this.lastRelativePos) / deltaTime;

                this.smoothDelta = ((this.speed > 0f) ? Vector3.Lerp(this.smoothDelta, vector, deltaTime * this.speed) : vector);
                Vector3 v  = this.relativeTo.TransformDirection(this.smoothDelta);
                Vector3 a2 = V3Tools.ExtractVertical(v, solver.GetRoot().up, this.verticalWeight) + V3Tools.ExtractHorizontal(v, solver.GetRoot().up, this.horizontalWeight);

                for (int i = 0; i < this.effectorLinks.Length; i++)
                {
                    solver.GetEffector(this.effectorLinks[i].effector).positionOffset += a2 * w * this.effectorLinks[i].weight;
                }
                this.lastRelativePos = a;
            }
Beispiel #15
0
        private void Start()
        {
            this.ik = base.GetComponent <FullBodyBipedIK>();
            IKSolverFullBodyBiped solver = this.ik.solver;

            solver.OnPostUpdate = (IKSolver.UpdateDelegate)Delegate.Combine(solver.OnPostUpdate, new IKSolver.UpdateDelegate(this.RotateShoulders));
        }
Beispiel #16
0
        /*
         * Draws the scene view helpers for IKSolverFullBodyBiped
         * */
        public static void AddScene(IKSolverFullBodyBiped solver, Color color, bool modifiable, ref int selectedEffector, Transform root)
        {
            if (!solver.IsValid(false))
            {
                return;
            }

            float heightF = Vector3.Distance(solver.chain.children[0].nodes[0].transform.position, solver.chain.children[0].nodes[1].transform.position) +
                            Vector3.Distance(solver.chain.children[2].nodes[0].transform.position, solver.chain.children[2].nodes[1].transform.position);

            float size = Mathf.Clamp(heightF * 0.1f, 0.005f, 0.05f);

            // Chain
            if (!Application.isPlaying)
            {
                IKSolverFullBodyInspector.AddChain(solver.chain, color, size);
                Handles.DrawLine(solver.chain.children[0].nodes[0].transform.position, solver.chain.children[1].nodes[0].transform.position);
                Handles.DrawLine(solver.chain.children[2].nodes[0].transform.position, solver.chain.children[3].nodes[0].transform.position);

                AddLimbHelper(solver.chain.children[0], size);
                AddLimbHelper(solver.chain.children[1], size);
                AddLimbHelper(solver.chain.children[2], size, root);
                AddLimbHelper(solver.chain.children[3], size, root);
            }

            // Effectors
            IKSolverFullBodyInspector.AddScene(solver, color, modifiable, ref selectedEffector, size);
        }
 private void AutoDetectReferences()
 {
     this.references = new BipedReferences();
     BipedReferences.AutoDetectReferences(ref this.references, base.transform, new BipedReferences.AutoDetectParams(true, false));
     this.solver.rootNode = IKSolverFullBodyBiped.DetectRootNodeBone(this.references);
     this.solver.SetToReferences(this.references, this.solver.rootNode);
 }
 // Apply offset to FBBIK effectors
 public void Apply(IKSolverFullBodyBiped solver, Quaternion rotation, float masterWeight)
 {
     foreach (EffectorLink e in effectorLinks)
     {
         solver.GetEffector(e.effector).positionOffset += rotation * (offset * masterWeight * e.weight);
     }
 }
Beispiel #19
0
            // Update the Body
            public void Update(IKSolverFullBodyBiped solver, float w, float deltaTime)
            {
                if (transform == null || relativeTo == null) return;

                // Find the relative position of the transform
                Vector3 relativePos = relativeTo.InverseTransformDirection(transform.position - relativeTo.position);

                // Initiating
                if (firstUpdate) {
                    lastRelativePos = relativePos;
                    firstUpdate = false;
                }

                // Find how much the relative position has changed
                Vector3 delta = (relativePos - lastRelativePos) / deltaTime;

                // Smooth the change
                smoothDelta = speed <= 0f? delta: Vector3.Lerp(smoothDelta, delta, deltaTime * speed);

                // Convert to world space
                Vector3 worldDelta = relativeTo.TransformDirection(smoothDelta);

                // Extract horizontal and vertical offset
                Vector3 offset = V3Tools.ExtractVertical(worldDelta, solver.GetRoot().up, verticalWeight) + V3Tools.ExtractHorizontal(worldDelta, solver.GetRoot().up, horizontalWeight);

                // Apply the amplitude to the effector links
                for (int i = 0; i < effectorLinks.Length; i++) {
                    solver.GetEffector(effectorLinks[i].effector).positionOffset += offset * w * effectorLinks[i].weight;
                }

                lastRelativePos = relativePos;
            }
Beispiel #20
0
 public void Apply(IKSolverFullBodyBiped solver, float weight)
 {
     for (int i = 0; i < this.effectorLinks.Length; i++)
     {
         this.effectorLinks[i].Apply(solver, weight, solver.GetRoot().rotation);
     }
 }
        public void Update(Transform root, IKSolverFullBodyBiped solver, float speed)
        {
            if (!this.inInteraction)
            {
                return;
            }
            if (this.interactionTarget != null && !this.interactionTarget.rotateOnce)
            {
                this.interactionTarget.RotateTo(this.effector.bone.position);
            }
            if (this.isPaused)
            {
                this.effector.position = this.target.TransformPoint(this.pausePositionRelative);
                this.effector.rotation = this.target.rotation * this.pauseRotationRelative;
                this.interactionObject.Apply(solver, this.effectorType, this.interactionTarget, this.timer, this.weight);
                return;
            }
            this.timer += Time.deltaTime * speed * ((!(this.interactionTarget != null)) ? 1f : this.interactionTarget.interactionSpeedMlp);
            this.weight = Mathf.Clamp(this.weight + Time.deltaTime * this.fadeInSpeed, 0f, 1f);
            bool flag  = false;
            bool flag2 = false;

            this.TriggerUntriggeredEvents(true, out flag, out flag2);
            Vector3    b  = (!this.pickedUp) ? this.target.position : this.pickUpPosition;
            Quaternion b2 = (!this.pickedUp) ? this.target.rotation : this.pickUpRotation;

            this.effector.position = Vector3.Lerp(this.effector.bone.position, b, this.weight);
            this.effector.rotation = Quaternion.Lerp(this.effector.bone.rotation, b2, this.weight);
            this.interactionObject.Apply(solver, this.effectorType, this.interactionTarget, this.timer, this.weight);
            if (flag)
            {
                this.PickUp(root);
            }
            if (flag2)
            {
                this.Pause();
            }
            float value = this.interactionObject.GetValue(InteractionObject.WeightCurve.Type.PoserWeight, this.interactionTarget, this.timer);

            if (this.poser != null)
            {
                this.poser.weight = Mathf.Lerp(this.poser.weight, value, this.weight);
            }
            else if (value > 0f)
            {
                Warning.Log(string.Concat(new string[]
                {
                    "InteractionObject ",
                    this.interactionObject.name,
                    " has a curve/multipler for Poser Weight, but the bone of effector ",
                    this.effectorType.ToString(),
                    " has no HandPoser/GenericPoser attached."
                }), this.effector.bone, false);
            }
            if (this.timer >= this.length)
            {
                this.Stop();
            }
        }
        // Draws the scene view helpers for IKSolverFullBodyBiped
        public static void AddScene(UnityEngine.Object target, IKSolverFullBodyBiped solver, Color color, ref int selectedEffector, Transform root)
        {
            if (Application.isPlaying && !solver.initiated) return;
            if (!Application.isPlaying && !solver.IsValid()) return;

            bool modifiable = solver.initiated;

            //@todo TEMP
            /*
            for (int i = 0; i < solver.chain.Length; i++) {
                for (int n = 0; n < solver.chain[i].nodes.Length; n++) {
                    Handles.DotCap(0, solver.chain[i].nodes[n].solverPosition, Quaternion.identity, 0.02f);
                }
            }
            */
            /*
            foreach (IKMappingLimb limb in solver.limbMappings) {
                Handles.DotCap(0, limb.GetBoneMap(IKMappingLimb.BoneMapType.Bone3).node.solverPosition, Quaternion.identity, 0.02f);
            }
            */

            float heightF = Vector3.Distance(solver.chain[1].nodes[0].transform.position, solver.chain[1].nodes[1].transform.position) +
                Vector3.Distance(solver.chain[3].nodes[0].transform.position, solver.chain[3].nodes[1].transform.position);

            float size = Mathf.Clamp(heightF * 0.075f, 0.001f, Mathf.Infinity);

            // Bend goals
            for (int i = 0; i < solver.chain.Length; i++) {
                if (solver.chain[i].nodes.Length == 3 && solver.chain[i].bendConstraint.bendGoal != null && solver.chain[i].bendConstraint.weight > 0f) {
                    Color c = color;
                    c.a = solver.chain[i].bendConstraint.weight;
                    Handles.color = c;

                    Handles.DrawLine(solver.chain[i].nodes[1].transform.position, solver.chain[i].bendConstraint.bendGoal.position);
                    Handles.SphereCap(0, solver.chain[i].nodes[1].transform.position, Quaternion.identity, size * 0.5f);
                    Handles.SphereCap(0, solver.chain[i].bendConstraint.bendGoal.position, Quaternion.identity, size * 0.5f);

                    Handles.color = Color.white;
                }
            }

            // Chain
            if (!modifiable) {
                for (int i = 0; i < solver.chain.Length; i++) {
                    IKSolverFullBodyInspector.AddChain(solver.chain, i, color, size);
                }

                Handles.DrawLine(solver.chain[1].nodes[0].transform.position, solver.chain[2].nodes[0].transform.position);
                Handles.DrawLine(solver.chain[3].nodes[0].transform.position, solver.chain[4].nodes[0].transform.position);

                AddLimbHelper(solver.chain[1], size);
                AddLimbHelper(solver.chain[2], size);
                AddLimbHelper(solver.chain[3], size, root);
                AddLimbHelper(solver.chain[4], size, root);
            }

            // Effectors
            IKSolverFullBodyInspector.AddScene(target, solver, color, modifiable, ref selectedEffector, size);
        }
Beispiel #23
0
 private void OnDestroy()
 {
     if (this.initiated && this.ik != null)
     {
         IKSolverFullBodyBiped expr_27 = this.ik.solver;
         expr_27.OnPreUpdate = (IKSolver.UpdateDelegate)Delegate.Remove(expr_27.OnPreUpdate, new IKSolver.UpdateDelegate(this.OnSolverUpdate));
     }
 }
Beispiel #24
0
			// Apply offset to FBBIK effectors
			public void Apply(IKSolverFullBodyBiped solver, Quaternion rotation, float masterWeight, float length, float timeLeft) {
				additiveOffset = Vector3.Lerp(Vector3.zero, additiveOffset, timeLeft / length);
				lastOffset = (rotation * (offset * masterWeight)) + (rotation * additiveOffset);

				foreach (EffectorLink e in effectorLinks) {
					solver.GetEffector(e.effector).positionOffset += lastOffset * e.weight;
				}
			}
Beispiel #25
0
 protected virtual void OnDestroy()
 {
     if (this.ik != null)
     {
         IKSolverFullBodyBiped solver = this.ik.solver;
         solver.OnPreUpdate = (IKSolver.UpdateDelegate)Delegate.Remove(solver.OnPreUpdate, new IKSolver.UpdateDelegate(this.ModifyOffset));
     }
 }
Beispiel #26
0
 private void OnDestroy()
 {
     if (this.ik != null)
     {
         IKSolverFullBodyBiped solver = this.ik.solver;
         solver.OnPostUpdate = (IKSolver.UpdateDelegate)Delegate.Remove(solver.OnPostUpdate, new IKSolver.UpdateDelegate(this.RotateShoulders));
     }
 }
Beispiel #27
0
            public void Apply(IKSolverFullBodyBiped solver, float weight, Quaternion rotation)
            {
                solver.GetEffector(this.effector).positionOffset += rotation * this.offset * weight;
                Vector3 vector  = solver.GetRoot().position + rotation * this.pin - solver.GetEffector(this.effector).bone.position;
                Vector3 vector2 = this.pinWeight * Mathf.Abs(weight);

                solver.GetEffector(this.effector).positionOffset = new Vector3(Mathf.Lerp(solver.GetEffector(this.effector).positionOffset.x, vector.x, vector2.x), Mathf.Lerp(solver.GetEffector(this.effector).positionOffset.y, vector.y, vector2.y), Mathf.Lerp(solver.GetEffector(this.effector).positionOffset.z, vector.z, vector2.z));
            }
            public Transform target; // The target

            #endregion Fields

            #region Methods

            // Update IK position, rotation and weight
            public void Update(IKSolverFullBodyBiped solver, float weight)
            {
                solver.GetEffector(effector).position = target.position;
                solver.GetEffector(effector).rotation = target.rotation;

                solver.GetEffector(effector).positionWeight = positionWeight * weight;
                solver.GetEffector(effector).rotationWeight = rotationWeight * weight;
            }
        void AutoDetectReferences()
        {
            references = new BipedReferences();
            BipedReferences.AutoDetectReferences(ref references, transform, new BipedReferences.AutoDetectParams(true, false));

            solver.rootNode = IKSolverFullBodyBiped.DetectRootNodeBone(references);

            solver.SetToReferences(references, solver.rootNode);
        }
Beispiel #30
0
 public void Apply(IKSolverFullBodyBiped solver, Quaternion rotation, float masterWeight, float length, float timeLeft)
 {
     this.additiveOffset = Vector3.Lerp(Vector3.zero, this.additiveOffset, timeLeft / length);
     this.lastOffset     = rotation * (this.offset * masterWeight) + rotation * this.additiveOffset;
     foreach (Recoil.RecoilOffset.EffectorLink effectorLink in this.effectorLinks)
     {
         solver.GetEffector(effectorLink.effector).positionOffset += this.lastOffset * effectorLink.weight;
     }
 }
Beispiel #31
0
            // Calculate offset, apply to the bones
            protected override void OnApply(IKSolverFullBodyBiped solver, float weight)
            {
                float      comValue = aroundCenterOfMass.Evaluate(timer) * weight;
                Quaternion offset   = Quaternion.AngleAxis(comValue, comAxis);

                foreach (BoneLink b in boneLinks)
                {
                    b.Apply(solver, offset, crossFader);
                }
            }
Beispiel #32
0
            // Apply offset to FBBIK effectors
            public void Apply(IKSolverFullBodyBiped solver, Quaternion rotation, float masterWeight, float length, float timeLeft)
            {
                additiveOffset = Vector3.Lerp(Vector3.zero, additiveOffset, timeLeft / length);
                lastOffset     = (rotation * (offset * masterWeight)) + (rotation * additiveOffset);

                foreach (EffectorLink e in effectorLinks)
                {
                    solver.GetEffector(e.effector).positionOffset += lastOffset * e.weight;
                }
            }
        // Draws the scene view helpers for IKSolverFullBodyBiped
        public static void AddScene(UnityEngine.Object target, IKSolverFullBodyBiped solver, Color color, ref int selectedEffector, Transform root)
        {
            if (Application.isPlaying && !solver.initiated)
            {
                return;
            }
            if (!Application.isPlaying && !solver.IsValid())
            {
                return;
            }

            bool modifiable = solver.initiated;

            float heightF = Vector3.Distance(solver.chain[1].nodes[0].transform.position, solver.chain[1].nodes[1].transform.position) +
                            Vector3.Distance(solver.chain[3].nodes[0].transform.position, solver.chain[3].nodes[1].transform.position);

            float size = Mathf.Clamp(heightF * 0.075f, 0.001f, Mathf.Infinity);

            // Bend goals
            for (int i = 0; i < solver.chain.Length; i++)
            {
                if (solver.chain[i].nodes.Length == 3 && solver.chain[i].bendConstraint.bendGoal != null && solver.chain[i].bendConstraint.weight > 0f)
                {
                    Color c = color;
                    c.a           = solver.chain[i].bendConstraint.weight;
                    Handles.color = c;

                    Handles.DrawLine(solver.chain[i].nodes[1].transform.position, solver.chain[i].bendConstraint.bendGoal.position);
                    Handles.SphereHandleCap(0, solver.chain[i].nodes[1].transform.position, Quaternion.identity, size * 0.5f, EventType.Repaint);
                    Handles.SphereHandleCap(0, solver.chain[i].bendConstraint.bendGoal.position, Quaternion.identity, size * 0.5f, EventType.Repaint);

                    Handles.color = Color.white;
                }
            }

            // Chain
            if (!modifiable)
            {
                for (int i = 0; i < solver.chain.Length; i++)
                {
                    IKSolverFullBodyInspector.AddChain(solver.chain, i, color, size);
                }

                Handles.DrawLine(solver.chain[1].nodes[0].transform.position, solver.chain[2].nodes[0].transform.position);
                Handles.DrawLine(solver.chain[3].nodes[0].transform.position, solver.chain[4].nodes[0].transform.position);

                AddLimbHelper(solver.chain[1], size);
                AddLimbHelper(solver.chain[2], size);
                AddLimbHelper(solver.chain[3], size, root);
                AddLimbHelper(solver.chain[4], size, root);
            }

            // Effectors
            IKSolverFullBodyInspector.AddScene(target, solver, color, modifiable, ref selectedEffector, size);
        }
        // Checks the biped references for errors
        private bool CheckError(BipedReferences references, IKSolverFullBodyBiped solver, Transform context, bool log)
        {
            // All the errors common to all bipeds
            if (!BipedReferences.CheckSetupError(script.references, log))
            {
                if (log)
                {
                    Warning.Log("Invalid references, can't initiate the solver.", context, true);
                }
                return(false);
            }

            // All the errors specific to FBBIK
            if (references.spine.Length == 0)
            {
                if (log)
                {
                    Warning.Log("Biped has no spine bones, can't initiate the solver.", context, true);
                }
                return(false);
            }

            if (solver.rootNode == null)
            {
                if (log)
                {
                    Warning.Log("Root Node bone is null, can't initiate the solver.", context, true);
                }
                return(false);
            }

            if (solver.rootNode != references.pelvis)
            {
                bool inSpine = false;

                for (int i = 0; i < references.spine.Length; i++)
                {
                    if (solver.rootNode == references.spine[i])
                    {
                        inSpine = true;
                        break;
                    }
                }

                if (!inSpine)
                {
                    if (log)
                    {
                        Warning.Log("The Root Node has to be one of the bones in the Spine or the Pelvis, can't initiate the solver.", context, true);
                    }
                }
            }

            return(true);
        }
Beispiel #35
0
            // Multiple raycasting to accumulate the offset
            private Vector3 GetOffsetTarget(IKSolverFullBodyBiped solver)
            {
                Vector3 t = Vector3.zero;

                foreach (Transform from in raycastFrom)
                {
                    t += Raycast(from.position, raycastTo.position + t);
                }

                return(t);
            }
		// Initiate this, get the default values
		public void Initiate(InteractionSystem interactionSystem, IKSolverFullBodyBiped solver) {
			this.interactionSystem = interactionSystem;

			// Find the effector if we haven't already
			if (effector == null) {
				effector = solver.GetEffector(effectorType);
				poser = effector.bone.GetComponent<Poser>();
			}

			defaultPull = solver.GetChain(effectorType).pull;
			defaultReach = solver.GetChain(effectorType).reach;
			defaultPush = solver.GetChain(effectorType).push;
			defaultPushParent = solver.GetChain(effectorType).pushParent;
		}
Beispiel #37
0
			public Vector3 pinWeight; // Pin weight vector

			// Apply positionOffset to the effector
			public void Apply(IKSolverFullBodyBiped solver, float weight, Quaternion rotation) {
				// Offset
				solver.GetEffector(effector).positionOffset += rotation * offset * weight;
				
				// Calculating pinned position
				Vector3 pinPosition = solver.GetRoot().position + rotation * pin;
				Vector3 pinPositionOffset = pinPosition - solver.GetEffector(effector).bone.position;
				
				Vector3 pinWeightVector = pinWeight * Mathf.Abs(weight);
				
				// Lerping to pinned position
				solver.GetEffector(effector).positionOffset = new Vector3(
					Mathf.Lerp(solver.GetEffector(effector).positionOffset.x, pinPositionOffset.x, pinWeightVector.x),
					Mathf.Lerp(solver.GetEffector(effector).positionOffset.y, pinPositionOffset.y, pinWeightVector.y),
					Mathf.Lerp(solver.GetEffector(effector).positionOffset.z, pinPositionOffset.z, pinWeightVector.z)
					);
			}
Beispiel #38
0
			// Apply to IKSolverFullBodyBiped
			public void Apply(IKSolverFullBodyBiped solver, float weight) {
				float deltaTime = Time.time - lastTime;
				lastTime = Time.time;

				if (timer >= length) {
					return;
				}

				// Advance the timer
				timer = Mathf.Clamp(timer + deltaTime, 0f, length);

				// Advance the crossFader
				if (crossFadeSpeed > 0f) crossFader = Mathf.Clamp(crossFader + (deltaTime * crossFadeSpeed), 0f, 1f);
				else crossFader = 1f;

				// Pass this on to the hit points
				OnApply(solver, weight);
			}
		// Draws the scene view helpers for IKSolverFullBodyBiped
		public static void AddScene(IKSolverFullBodyBiped solver, Color color, bool modifiable, ref int selectedEffector, Transform root) {
			if (!solver.IsValid(false)) return;
			if (Application.isPlaying && !solver.initiated) return;

			float heightF = Vector3.Distance(solver.chain[1].nodes[0].transform.position, solver.chain[1].nodes[1].transform.position) + 
				Vector3.Distance(solver.chain[3].nodes[0].transform.position, solver.chain[3].nodes[1].transform.position);

			float size = Mathf.Clamp(heightF * 0.075f, 0.001f, Mathf.Infinity);

			// Bend goals
			for (int i = 0; i < solver.chain.Length; i++) {
				if (solver.chain[i].nodes.Length == 3 && solver.chain[i].bendConstraint.bendGoal != null && solver.chain[i].bendConstraint.weight > 0f) {
					Color c = color;
					c.a = solver.chain[i].bendConstraint.weight;
					Handles.color = c;
					
					Handles.DrawLine(solver.chain[i].nodes[1].transform.position, solver.chain[i].bendConstraint.bendGoal.position);
					Handles.SphereCap(0, solver.chain[i].nodes[1].transform.position, Quaternion.identity, size * 0.5f);
					Handles.SphereCap(0, solver.chain[i].bendConstraint.bendGoal.position, Quaternion.identity, size * 0.5f);
					
					Handles.color = Color.white;
				}
			}

			// Chain
			if (!Application.isPlaying) {
				for (int i = 0; i < solver.chain.Length; i++) {
					IKSolverFullBodyInspector.AddChain(solver.chain, i, color, size);
				}

				Handles.DrawLine(solver.chain[1].nodes[0].transform.position, solver.chain[2].nodes[0].transform.position);
				Handles.DrawLine(solver.chain[3].nodes[0].transform.position, solver.chain[4].nodes[0].transform.position);

				AddLimbHelper(solver.chain[1], size);
				AddLimbHelper(solver.chain[2], size);
				AddLimbHelper(solver.chain[3], size, root);
				AddLimbHelper(solver.chain[4], size, root);
			}
			
			// Effectors
			IKSolverFullBodyInspector.AddScene(solver, color, modifiable, ref selectedEffector, size);
		}
		// Interpolate to default values when currently not in interaction
		public bool ResetToDefaults(IKSolverFullBodyBiped solver, float speed) {
			if (inInteraction) return false;
			if (isPaused) return false;
			if (defaults) return false; 

			resetTimer = Mathf.Clamp(resetTimer -= Time.deltaTime * speed, 0f, 1f);

			// Pull and Reach
			if (effector.isEndEffector) {
				solver.GetChain(effectorType).pull = Mathf.Lerp(defaultPull, solver.GetChain(effectorType).pull, resetTimer);
				solver.GetChain(effectorType).reach = Mathf.Lerp(defaultReach, solver.GetChain(effectorType).reach, resetTimer);
				solver.GetChain(effectorType).push = Mathf.Lerp(defaultPush, solver.GetChain(effectorType).push, resetTimer);
				solver.GetChain(effectorType).pushParent = Mathf.Lerp(defaultPushParent, solver.GetChain(effectorType).pushParent, resetTimer);
			}

			// Effector weights
			effector.positionWeight = Mathf.Lerp(0f, effector.positionWeight, resetTimer);
			effector.rotationWeight = Mathf.Lerp(0f, effector.rotationWeight, resetTimer);

			if (resetTimer <= 0f) defaults = true;

			return true;
		}
Beispiel #41
0
        // Applies the weight curves and multipliers to the FBBIK solver
        public void Apply(IKSolverFullBodyBiped solver, FullBodyBipedEffector effector, InteractionTarget target, float timer, float weight)
        {
            for (int i = 0; i < weightCurves.Length; i++) {
                float mlp = target == null? 1f: target.GetValue(weightCurves[i].type);

                Apply(solver, effector, weightCurves[i].type, weightCurves[i].GetValue(timer), weight * mlp);
            }

            for (int i = 0; i < multipliers.Length; i++) {
                if (multipliers[i].curve == multipliers[i].result) {
                    if (!Warning.logged) Warning.Log("InteractionObject Multiplier 'Curve' " + multipliers[i].curve.ToString() + "and 'Result' are the same.", transform);
                }

                int curveIndex = GetWeightCurveIndex(multipliers[i].curve);

                if (curveIndex != -1) {
                    float mlp = target == null? 1f: target.GetValue(multipliers[i].result);

                    Apply(solver, effector, multipliers[i].result, multipliers[i].GetValue(weightCurves[curveIndex], timer), weight * mlp);
                } else {
                    if (!Warning.logged) Warning.Log("InteractionObject Multiplier curve " + multipliers[i].curve.ToString() + "does not exist.", transform);
                }
            }
        }
                // Apply a rotational offset to this effector
                public void Apply(IKSolverFullBodyBiped solver, Quaternion offset, float crossFader)
                {
                    current = Quaternion.Lerp(lastValue, Quaternion.Lerp(Quaternion.identity, offset, weight), crossFader);

                    bone.rotation = current * bone.rotation;
                }
            // Calculate offset, apply to the bones
            protected override void OnApply(IKSolverFullBodyBiped solver, float weight)
            {
                if (rigidbody == null) rigidbody = collider.GetComponent<Rigidbody>();
                if (rigidbody != null) {
                    Vector3 comAxis = Vector3.Cross(force, point - rigidbody.worldCenterOfMass);
                    float comValue = aroundCenterOfMass.Evaluate(timer) * weight;
                    Quaternion offset = Quaternion.AngleAxis(comValue, comAxis);

                    foreach (BoneLink b in boneLinks) b.Apply(solver, offset, crossFader);
                }
            }
Beispiel #44
0
 public void Apply(IKSolverFullBodyBiped solver, float weight, Quaternion rotation)
 {
     for (int i = 0; i < effectorLinks.Length; i++) effectorLinks[i].Apply(solver, weight, rotation);
 }
Beispiel #45
0
 // Apply positionOffsets of all the EffectorLinks
 public void Apply(IKSolverFullBodyBiped solver, float weight)
 {
     for (int i = 0; i < effectorLinks.Length; i++) effectorLinks[i].Apply(solver, weight, solver.GetRoot().rotation);
 }
            // Calculate offset, apply to FBBIK effectors
            protected override void OnApply(IKSolverFullBodyBiped solver, float weight)
            {
                Vector3 up = solver.GetRoot().up * force.magnitude;

                Vector3 offset = (offsetInForceDirection.Evaluate(timer) * force) + (offsetInUpDirection.Evaluate(timer) * up);
                offset *= weight;

                foreach (EffectorLink e in effectorLinks) e.Apply(solver, offset, crossFader);
            }
 public override void Execute()
 {
     var ik = EntityView.GetComponent<FullBodyBipedIK>();
     Solver = ik.solver;
 }
        /*
         * Draws the scene view helpers for IKSolverFullBodyBiped
         * */
        public static void AddScene(IKSolverFullBodyBiped solver, Color color, bool modifiable, ref int selectedEffector, Transform root)
        {
            if (!solver.IsValid(false)) return;

            float heightF = Vector3.Distance(solver.chain[1].nodes[0].transform.position, solver.chain[1].nodes[1].transform.position) +
                Vector3.Distance(solver.chain[3].nodes[0].transform.position, solver.chain[3].nodes[1].transform.position);

            float size = Mathf.Clamp(heightF * 0.075f, 0.001f, Mathf.Infinity);

            // Chain
            if (!Application.isPlaying) {
                for (int i = 0; i < solver.chain.Length; i++) {
                    IKSolverFullBodyInspector.AddChain(solver.chain, i, color, size);
                }

                Handles.DrawLine(solver.chain[1].nodes[0].transform.position, solver.chain[2].nodes[0].transform.position);
                Handles.DrawLine(solver.chain[3].nodes[0].transform.position, solver.chain[4].nodes[0].transform.position);

                AddLimbHelper(solver.chain[1], size);
                AddLimbHelper(solver.chain[2], size);
                AddLimbHelper(solver.chain[3], size, root);
                AddLimbHelper(solver.chain[4], size, root);
            }

            // Effectors
            IKSolverFullBodyInspector.AddScene(solver, color, modifiable, ref selectedEffector, size);
        }
 protected abstract void OnApply(IKSolverFullBodyBiped solver, float weight);
    private bool BipedIsValid(BipedReferences references, IKSolverFullBodyBiped solver, Transform context, bool log)
    {
        BipedReferences.CheckSetup(script.references);

        if (!references.isValid)
        {
            //if (log) Warning.Log("BipedReferences contains one or more missing Transforms.", context, true);
            return false;
        }
        if (references.spine.Length == 0)
        {
            //if (log) Warning.Log("Biped has no spine bones.", context, true);
            return false;
        }

        if (solver.rootNode == null)
        {
            //if (log) Warning.Log("Root Node bone is null.", context, true);
            return false;
        }

        Vector3 toRightShoulder = references.rightUpperArm.position - references.leftUpperArm.position;
        Vector3 shoulderToRootNode = solver.rootNode.position - references.leftUpperArm.position;
        float dot = Vector3.Dot(toRightShoulder.normalized, shoulderToRootNode.normalized);

        if (dot > 0.95f)
        {
            if (log) Warning.Log("The root node, the left upper arm and the right upper arm bones should ideally form a triangle that is as close to equilateral as possible. " +
                "Currently the root node bone seems to be very close to the line between the left upper arm and the right upper arm bones. This might cause unwanted behaviour like the spine turning upside down when pulled by a hand effector." +
                "Please set the root node bone to be one of the lower bones in the spine.", context, true);
        }

        Vector3 toRightThigh = references.rightThigh.position - references.leftThigh.position;
        Vector3 thighToRootNode = solver.rootNode.position - references.leftThigh.position;
        dot = Vector3.Dot(toRightThigh.normalized, thighToRootNode.normalized);

        if (dot > 0.95f && log)
        {
            Warning.Log("The root node, the left thigh and the right thigh bones should ideally form a triangle that is as close to equilateral as possible. " +
                "Currently the root node bone seems to be very close to the line between the left thigh and the right thigh bones. This might cause unwanted behaviour like the hip turning upside down when pulled by an effector." +
                "Please set the root node bone to be one of the higher bones in the spine.", context, true);
        }

        /*
        Vector3 shoulderCross = Vector3.Cross(toRightShoulder, shoulderToRootNode);
        Vector3 charCross = Vector3.Cross(references.rightHand.position - references.leftHand.position, references.rightFoot.position - references.leftHand.position);
			
        float shoulderInvertDot = Vector3.Dot(shoulderCross.normalized, charCross.normalized);
			
        if (shoulderInvertDot < 0 && log) {
            Warning.Log("The triangle formed by the root node, left upper arm and right upper arm bones seems to be flipped. The root node bone should be below the upper arm bones.", context, true);
        }
			
        Vector3 thighCross = Vector3.Cross(toRightThigh, thighToRootNode);
			
        float thighInvertDot = Vector3.Dot(thighCross.normalized, charCross.normalized);
			
        if (thighInvertDot > 0 && log) {
            Warning.Log("The triangle formed by the root node, left thigh and right thigh bones seems to be flipped. The root node bone should be above the thigh bones.", context, true);
        }
        */

        return true;
    }
        public FBIKChain.ReachSmoothing reachSmoothing; // Smoothing of the Reach effect (since 0.2)

        #endregion Fields

        #region Methods

        // Apply the settings
        public void Apply(FullBodyBipedChain chain, IKSolverFullBodyBiped solver)
        {
            solver.GetChain(chain).reachSmoothing = reachSmoothing;
            solver.GetEndEffector(chain).maintainRelativePositionWeight = maintainRelativePositionWeight;
            solver.GetLimbMapping(chain).weight = mappingWeight;
        }
Beispiel #52
0
 // Apply offset to FBBIK effectors
 public void Apply(IKSolverFullBodyBiped solver, Quaternion rotation, float masterWeight)
 {
     foreach (EffectorLink e in effectorLinks) {
         solver.GetEffector(e.effector).positionOffset += rotation * (offset * masterWeight * e.weight);
     }
 }
		// Called after FBBIK update
		public void OnPostFBBIK(IKSolverFullBodyBiped fullBody) {
			if (!inInteraction) return;

			// Rotate the hands/feet to the RotateBoneWeight curve
			float rotateBoneWeight = interactionObject.GetValue(InteractionObject.WeightCurve.Type.RotateBoneWeight, interactionTarget, timer) * weight;

			if (rotateBoneWeight > 0f) {
				Quaternion r = pickedUp? pickUpRotation: effector.rotation;

				Quaternion targetRotation = Quaternion.Slerp(effector.bone.rotation, r, rotateBoneWeight * rotateBoneWeight);
				effector.bone.localRotation = Quaternion.Inverse(effector.bone.parent.rotation) * targetRotation;
			}

			// Positioning the interaction object to the effector (not the bone, because it is still at it's animated translation)
			if (pickUpOnPostFBBIK) {
				Vector3 bonePosition = effector.bone.position;
				effector.bone.position = pickUpPosition;

				interactionObject.targetsRoot.parent = effector.bone;
				
				effector.bone.position = bonePosition;

				pickUpOnPostFBBIK = false;
			}
		}
Beispiel #54
0
                // Update and Apply the position offset to the effector
                public void Update(IKSolverFullBodyBiped solver, Vector3 offsetTarget, float weight)
                {
                    // Lerping offset to the offset target
                    offset = Vector3.Lerp(offset, offsetTarget * multiplier, Time.deltaTime * speed);

                    // Apply gravity
                    Vector3 g = (solver.GetRoot().up * gravity) * offset.magnitude;

                    // Apply the offset to the effector
                    solver.GetEffector(effector).positionOffset += (offset * weight * this.weight) + (g * weight);
                }
		// Update the (possibly) ongoing interaction
		public void Update(Transform root, IKSolverFullBodyBiped solver, float speed) {
			if (!inInteraction) {
				// If the InteractionObject has been destroyed, reset to defaults
				if (started) {
					isPaused = false;
					pickedUp = false;
					defaults = false;
					resetTimer = 1f;
					started = false;
				}
				return;
			}

			// Rotate target
			if (interactionTarget != null && !interactionTarget.rotateOnce) interactionTarget.RotateTo(effector.bone.position);

			if (isPaused) {
				effector.position = target.TransformPoint(pausePositionRelative);
				effector.rotation = target.rotation * pauseRotationRelative;

				// Apply the current interaction state to the solver
				interactionObject.Apply(solver, effectorType, interactionTarget, timer, weight);

				return;
			}

			// Advance the interaction timer and weight
			timer += Time.deltaTime * speed * (interactionTarget != null? interactionTarget.interactionSpeedMlp: 1f);
			weight = Mathf.Clamp(weight + Time.deltaTime * fadeInSpeed * speed, 0f, 1f);

			// Interaction events
			bool pickUp = false;
			bool pause = false;
			TriggerUntriggeredEvents(true, out pickUp, out pause);

			// Effector target positions and rotations
			Vector3 targetPosition = pickedUp? pickUpPosition: target.position;
			Quaternion targetRotation = pickedUp? pickUpRotation: target.rotation;

			// Interpolate effector position and rotation
			effector.position = Vector3.Lerp(effector.bone.position, targetPosition, weight);
			effector.rotation = Quaternion.Lerp(effector.bone.rotation, targetRotation, weight);

			// Apply the current interaction state to the solver
			interactionObject.Apply(solver, effectorType, interactionTarget, timer, weight);

			if (pickUp) PickUp(root);
			if (pause) Pause();

			// Hand poser weight
			float poserWeight = interactionObject.GetValue (InteractionObject.WeightCurve.Type.PoserWeight, interactionTarget, timer);

			if (poser != null) {
				poser.weight = Mathf.Lerp (poser.weight, poserWeight, weight);
			} else {
				if (poserWeight > 0f) {
					Warning.Log("InteractionObject " + interactionObject.name + " has a curve/multipler for Poser Weight, but the bone of effector " + effectorType.ToString() + " has no HandPoser/GenericPoser attached.", effector.bone);
				}
			}

			if (timer >= length) Stop();
		}
Beispiel #56
0
            // Update and apply this hit point
            public void Update(IKSolverFullBodyBiped solver, float weight)
            {
                // Update velocity
                velocity = Vector3.Lerp(velocity, -offset, Time.deltaTime * spring);

                // Update offset
                offset += velocity * Time.deltaTime * speed;

                // Update Effector Links
                foreach (EffectorLink e in effectorLinks) e.Update(solver, offset, weight);

                // Update Bone Links
                foreach (BoneLink b in boneLinks) b.Update(offset, weight);
            }
Beispiel #57
0
			// Set effector position and rotation to match it's bone
			public void SetToBone(IKSolverFullBodyBiped solver) {
				// Using world space position and rotation here for the sake of simplicity of the demo
				// Ideally we should use position and rotation relative to character's root, so we could move around while doing this.
				solver.GetEffector(effector).position = solver.GetEffector(effector).bone.position;
				solver.GetEffector(effector).rotation = solver.GetEffector(effector).bone.rotation;
			}
		// Apply the curve to the specified solver, effector, with the value and weight.
		private void Apply(IKSolverFullBodyBiped solver, FullBodyBipedEffector effector, WeightCurve.Type type, float value, float weight) {
			switch(type) {
			case WeightCurve.Type.PositionWeight:
				solver.GetEffector(effector).positionWeight = Mathf.Lerp(solver.GetEffector(effector).positionWeight, value, weight);
				return;
			case WeightCurve.Type.RotationWeight:
				solver.GetEffector(effector).rotationWeight = Mathf.Lerp(solver.GetEffector(effector).rotationWeight, value, weight);
				return;
			case WeightCurve.Type.PositionOffsetX:
				solver.GetEffector(effector).position += (positionOffsetSpace != null? positionOffsetSpace.rotation: solver.GetRoot().rotation) * Vector3.right * value * weight;
				return;
			case WeightCurve.Type.PositionOffsetY:
				solver.GetEffector(effector).position += (positionOffsetSpace != null? positionOffsetSpace.rotation: solver.GetRoot().rotation) * Vector3.up * value * weight;
				return;
			case WeightCurve.Type.PositionOffsetZ:
				solver.GetEffector(effector).position += (positionOffsetSpace != null? positionOffsetSpace.rotation: solver.GetRoot().rotation) * Vector3.forward * value * weight;
				return;
			case WeightCurve.Type.Pull:
				solver.GetChain(effector).pull = Mathf.Lerp(solver.GetChain(effector).pull, value, weight);
				return;
			case WeightCurve.Type.Reach:
				solver.GetChain(effector).reach = Mathf.Lerp(solver.GetChain(effector).reach, value, weight);
				return;
			case WeightCurve.Type.Push:
				solver.GetChain(effector).push = Mathf.Lerp(solver.GetChain(effector).push, value, weight);
				return;
			case WeightCurve.Type.PushParent:
				solver.GetChain(effector).pushParent = Mathf.Lerp(solver.GetChain(effector).pushParent, value, weight);
				return;
			}
		}
Beispiel #59
0
			// Set effector position and rotation weight to match the value, multiply with the weight of this Absorber
			public void SetEffectorWeights(IKSolverFullBodyBiped solver, float w) {
				solver.GetEffector(effector).positionWeight = w * weight;
				solver.GetEffector(effector).rotationWeight = w * weight;
			}
                // Apply an offset to this effector
                public void Apply(IKSolverFullBodyBiped solver, Vector3 offset, float crossFader)
                {
                    current = Vector3.Lerp(lastValue, offset * weight, crossFader);

                    solver.GetEffector(effector).positionOffset += current;
                }