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; } }
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(); }
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(); }
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(); }