public void SetJointData(Data.Joint jData, Data.Joint prev = null)
        {
            jData.isLeft   = isLeft;
            jData.chainPos = chainPos;

            jData.position      = _root.InverseTransformPoint(transform.position);
            jData.rotEuler      = _root.InverseTransformDirection(transform.rotation.eulerAngles);
            jData.rotQuaternion = _root.transform.rotation * transform.rotation;
            jData.rotMat        = new float3x3(
                _root.InverseTransformDirection(transform.forward),
                _root.InverseTransformDirection(transform.up),
                _root.InverseTransformDirection(transform.right));

            jData.geoDistance           = joint.geoDistance;
            jData.geoDistanceNormalised = joint.geoDistanceNormalised;

            jData.inertiaObj = inertiaObj;
            // jData.COM = centerOfMass;
            jData.totalMass = totalMass;
            if (prev == null)
            {
                jData.velocity        = (jData.position - initPosition) / Time.fixedDeltaTime;
                jData.angularVelocity = (jData.rotEuler - initRotationEuler) / Time.fixedDeltaTime;
            }
            else
            {
                jData.velocity        = (jData.position - prev.position) / Time.fixedDeltaTime;
                jData.angularVelocity = (jData.rotEuler - prev.rotEuler) / Time.fixedDeltaTime;
            }
            jData.linearMomentum  = jData.velocity * totalMass;
            jData.inertia         = math.mul(jData.rotMat, math.mul(jData.inertiaObj, math.transpose(jData.rotMat)));
            jData.angularMomentum = math.mul(jData.inertia, jData.angularVelocity);

            jData.x = new BioJoint.Motion(joint.X);
            jData.y = new BioJoint.Motion(joint.Y);
            jData.z = new BioJoint.Motion(joint.Z);

            if (keyBone)
            {
                jData.tGoalPosition  = target.InverseTransformPoint(transform.position);
                jData.tGoalDirection = target.InverseTransformDirection(transform.rotation.eulerAngles);

                jData.cost = DistanceObjective.ComputeCost(transform, target, _root);

                jData.contact = Vector3.Distance(target.transform.position, transform.position) < threshold;
                contact       = jData.contact;
                jData.key     = keyBone;
            }
        }
示例#2
0
        public void Record(int contactFrames = 5)
        {
            /*
             * Assumes the target is already placed.
             */
            replaying = resetting = false;
            _rig.ik.EnableObjective.Invoke(true);
            contactingFrames = 0;

            UnityEngine.Random.InitState(2021);

            List <Frame> frames     = new List <Frame>();
            List <float> timestamps = new List <float>();

            Data.Joint[] joints;
            Data.Joint[] jointsPrev = null;
            int          len        = _rig.joints.Length;

            bool[] contacted = new bool[_rig.joints.Length];

            for (int i = 0; i < this.clipSize; ++i)
            {
                // Set joint data for each joint in the rig
                joints = new Data.Joint[len];
                if (i == 0)
                {
                    for (int j = 0; j < len; ++j)
                    {
                        joints[j] = new Anim.Data.Joint();
                        var jojo = _rig.joints[j];
                        jojo.SetJointData(joints[j], null);

                        if (joints[j].contact)
                        {
                            contacted[j] = true;
                        }
                    }
                }
                else
                {
                    for (int j = 0; j < len; ++j)
                    {
                        joints[j] = new Anim.Data.Joint();
                        var jojo = _rig.joints[j];
                        jojo.SetJointData(joints[j], jointsPrev[j]);

                        if (joints[j].contact)
                        {
                            contacted[j] = true;
                        }
                    }
                }

                if (contactingFrames > -1 && contacted.Count(ifTrue) >= _rig.targets.Length)
                {
                    Contacted(contactFrames);
                }

                if (twoFold && contactingFrames < 0)
                {
                    foreach (var jo in _rig.joints)
                    {
                        jo.joint.X.TargetValue = jo.joint.defaultX.TargetValue;
                        jo.joint.Y.TargetValue = jo.joint.defaultY.TargetValue;
                        jo.joint.Z.TargetValue = jo.joint.defaultZ.TargetValue;
                    }
                }

                var targetTransforms = new float3[_rig.targets.Length];
                var targetRotations  = new float3[_rig.targets.Length];
                for (int ii = 0; ii < _rig.targets.Length; ++ii)
                {
                    targetTransforms[ii] = _rig.targets[ii].transform.position;
                    targetRotations[ii]  = _rig.targets[ii].transform.rotation.eulerAngles;
                }
                // Set frame data
                var f = new Anim.Data.Frame();
                f.joints           = joints;
                f.targetsPositions = targetTransforms;
                f.targetsRotations = targetRotations;
                jointsPrev         = joints;
                // Append timestamp and frame data to the sequence
                timestamps.Add(i);
                frames.Add(f);

                // Use BioIK to compute the next pose
                _rig.ik.ManualUpdate();
            }

            if (clip == null)
            {
                clip = Instantiate(prefabSequence);
            }

            clip.frames    = frames.ToArray();
            clip.timestamp = timestamps.ToArray();

            ResetPose();
        }
示例#3
0
        public void Record(float amplitude, float frequency, float stepSize)
        {
            /*
             * For locomotion
             */
            _rig.ik.EnableObjective.Invoke(true);

            List <Frame> frames     = new List <Frame>();
            List <float> timestamps = new List <float>();

            Data.Joint[] joints;
            Data.Joint[] jointsPrev = null;
            int          len        = _rig.joints.Length;

            var locomotion = _rig.locomotion;

            locomotion.SetAmplitude(amplitude);
            locomotion.SetFrequency(frequency);
            locomotion.SetStepSize(stepSize);

            for (int i = 0; i < this.clipSize; ++i)
            {
                // Set joint data for each joint in the rig
                joints = new Data.Joint[len];
                bool contacted = false;
                if (i == 0)
                {
                    for (int j = 0; j < len; ++j)
                    {
                        joints[j] = new Anim.Data.Joint();
                        var jojo = _rig.joints[j];
                        jojo.SetJointData(joints[j], null);
                    }
                }
                else
                {
                    for (int j = 0; j < len; ++j)
                    {
                        joints[j] = new Anim.Data.Joint();
                        var jojo = _rig.joints[j];
                        jojo.SetJointData(joints[j], jointsPrev[j]);
                    }
                }

                locomotion.Step();

                var targetTransforms = new float3[_rig.targets.Length];
                var targetRotations  = new float3[_rig.targets.Length];
                for (int ii = 0; ii < _rig.targets.Length; ++ii)
                {
                    targetTransforms[ii] = _rig.targets[ii].transform.position;
                    targetRotations[ii]  = _rig.targets[ii].transform.rotation.eulerAngles;
                }
                // Set frame data
                var f = new Anim.Data.Frame();
                f.joints           = joints;
                f.targetsPositions = targetTransforms;
                f.targetsRotations = targetRotations;
                jointsPrev         = joints;

                // Append timestamp and frame data to the sequence
                timestamps.Add(i);
                frames.Add(f);

                // Use BioIK to compute the next pose
                _rig.ik.ManualUpdate();
            }

            if (clip == null)
            {
                clip = Instantiate(prefabSequence);
            }

            clip.frames    = frames.ToArray();
            clip.timestamp = timestamps.ToArray();

            _rig.locomotion.Reset();
            ResetPose();
        }
示例#4
0
        public void Record(List <float3[]> path, float[] timings, int contactFrames)
        {
            /*
             * Introduces a random path for the key-joints for a random duration, before spawning the target.
             */
            var disableIK = true;

            contactingFrames = 0;
            _rig.ik.EnableObjective.Invoke(false);

            replaying = resetting = false;
            _rig.ik.EnableObjective.Invoke(true);

            List <Frame> frames     = new List <Frame>();
            List <float> timestamps = new List <float>();

            Data.Joint[] joints;
            Data.Joint[] jointsPrev = null;
            int          len        = _rig.joints.Length;


            int[] keyframes = new int[timings.Length];
            for (int i = 0; i < keyframes.Length; ++i)
            {
                keyframes[i] = (int)(timings[i] * this.clipSize);
            }
            int keyframePtr = 0;

            for (int i = 0; i < this.clipSize; ++i)
            {
                // Set joint data for each joint in the rig
                joints = new Data.Joint[len];
                bool contacted = false;
                if (i == 0)
                {
                    for (int j = 0; j < len; ++j)
                    {
                        joints[j] = new Anim.Data.Joint();
                        var jojo = _rig.joints[j];
                        jojo.SetJointData(joints[j], null);

                        if (joints[j].contact)
                        {
                            contacted = true;
                        }
                    }
                }
                else
                {
                    for (int j = 0; j < len; ++j)
                    {
                        joints[j] = new Anim.Data.Joint();
                        var jojo = _rig.joints[j];
                        jojo.SetJointData(joints[j], jointsPrev[j]);

                        if (joints[j].contact)
                        {
                            contacted = true;
                        }
                    }
                }


                if (disableIK && i < keyframes[keyframePtr])
                {
                    int k = 0;
                    foreach (var jo in _rig.joints)
                    {
                        if (jo.keyBone)
                        {
                            var jojo = jo.joint;
                            jojo.X.TargetValue = path[keyframePtr][k].x;
                            jojo.Y.TargetValue = path[keyframePtr][k].y;
                            jojo.Z.TargetValue = path[keyframePtr][k].z;
                            ++k;
                        }
                    }
                }
                else
                {
                    if (++keyframePtr >= keyframes.Length && disableIK)
                    {
                        disableIK = false;
                        _rig.ik.EnableObjective.Invoke(true);
                    }

                    if (contacted)
                    {
                        Contacted(contactFrames);
                    }
                }

                if (twoFold && contactingFrames < 0)
                {
                    foreach (var jo in _rig.joints)
                    {
                        jo.joint.X.TargetValue = 0;
                        jo.joint.Y.TargetValue = 0;
                        jo.joint.Z.TargetValue = 0;
                    }
                }

                var targetTransforms = new float3[_rig.targets.Length];
                var targetRotations  = new float3[_rig.targets.Length];
                for (int ii = 0; ii < _rig.targets.Length; ++ii)
                {
                    targetTransforms[ii] = _rig.targets[ii].transform.position;
                    targetRotations[ii]  = _rig.targets[ii].transform.rotation.eulerAngles;
                }
                // Set frame data
                var f = new Anim.Data.Frame();
                f.joints           = joints;
                f.targetsPositions = targetTransforms;
                f.targetsRotations = targetRotations;
                jointsPrev         = joints;

                // Append timestamp and frame data to the sequence
                timestamps.Add(i);
                frames.Add(f);

                // Use BioIK to compute the next pose
                _rig.ik.ManualUpdate();
            }

            if (clip == null)
            {
                clip = Instantiate(prefabSequence);
            }

            clip.frames    = frames.ToArray();
            clip.timestamp = timestamps.ToArray();

            // ResetPose();
        }