public bool LeaveHand(float timestamp, bool mirrored) { ContactModule contact = GetContactModule(); if (contact == null) { return(false); } float shootPeriod = 1.0f; ContactModule.Sensor left = contact.GetSensor(Data.Source.Bones[LeftHand].Name); ContactModule.Sensor right = contact.GetSensor(Data.Source.Bones[RightHand].Name); Frame next = contact.GetNextContactEnd(Data.GetFrame(timestamp), mirrored, left, right); Frame previous = contact.GetPreviousContactEnd(Data.GetFrame(timestamp), mirrored, left, right); if (next != null && next.Timestamp - timestamp <= shootPeriod) { return(true); } if (left.GetContact(timestamp, mirrored) == 0f && right.GetContact(timestamp, mirrored) == 0f && previous != null && timestamp - previous.Timestamp <= shootPeriod) { return(true); } return(false); }
public bool IsDribbling(float timestamp, bool mirrored) { if (!InsideControlRadius()) { return(false); } ContactModule contact = GetContactModule(); if (contact == null) { return(false); } ContactModule.Sensor left = contact.GetSensor(Data.Source.Bones[LeftHand].Name); ContactModule.Sensor right = contact.GetSensor(Data.Source.Bones[RightHand].Name); if (left == null || right == null) { return(false); } //Check holding contacts if (left.GetContact(timestamp, mirrored) == 1f && right.GetContact(timestamp, mirrored) == 1f) { return(false); } //Check dribble contact if (left.GetContact(timestamp, mirrored) == 1f ^ right.GetContact(timestamp, mirrored) == 1f) { return(true); } //Check if contact happened before and happens again after within the future and past window float window = 1f; Frame previous = contact.GetPreviousContactFrame(Data.GetFrame(timestamp), mirrored, left, right); if (previous == null || previous.Timestamp < timestamp - window) { return(false); } Frame next = contact.GetNextContactFrame(Data.GetFrame(timestamp), mirrored, left, right); if (next != null && next.Timestamp - timestamp <= window) { return(left.GetContact(next.Timestamp, mirrored) == 1f ^ right.GetContact(next.Timestamp, mirrored) == 1f); } return(false); bool InsideControlRadius() { RootModule root = GetRootModule(); if (root == null) { return(false); } return(Vector3.Distance(root.GetRootPosition(timestamp, mirrored).ZeroY(), GetBallPosition(timestamp, mirrored).ZeroY()) <= GetControlRadius()); } }
public bool IsHolding(float timestamp, bool mirrored) { ContactModule contact = GetContactModule(); if (contact == null) { return(false); } ContactModule.Sensor left = contact.GetSensor(Data.Source.Bones[LeftHand].Name); ContactModule.Sensor right = contact.GetSensor(Data.Source.Bones[RightHand].Name); if (left == null || right == null) { return(false); } return(left.GetContact(timestamp, mirrored) == 1f && right.GetContact(timestamp, mirrored) == 1f); }
private bool HasControl(float timestamp, bool mirrored) { return(InsideRegion() && HasContact()); bool InsideRegion() { RootModule root = GetRootModule(); if (root == null) { return(false); } return(Vector3.Distance(root.GetRootPosition(timestamp, mirrored).ZeroY(), GetBallPosition(timestamp, mirrored).ZeroY()) <= GetControlRadius()); } bool HasContact() { ContactModule contact = GetContactModule(); if (contact == null) { return(false); } ContactModule.Sensor left = contact.GetSensor(Data.Source.Bones[LeftHand].Name); ContactModule.Sensor right = contact.GetSensor(Data.Source.Bones[RightHand].Name); if (left == null || right == null) { return(false); } float window = 1f; foreach (Frame f in Data.GetFrames(timestamp - window, timestamp + window)) { if (contact.HasContact(f, mirrored, left, right)) { return(true); } } return(false); } }
private float ContactPower(float timestamp, bool mirrored) { ContactModule contact = GetContactModule(); if (contact == null) { return(0f); } ContactModule.Sensor left = contact.GetSensor(Data.Source.Bones[LeftHand].Name); ContactModule.Sensor right = contact.GetSensor(Data.Source.Bones[RightHand].Name); if (left == null || right == null) { return(0f); } SmoothingWindow = SmoothingWindow == null?Data.GetTimeWindow(MotionEditor.GetInstance().PastWindow + MotionEditor.GetInstance().FutureWindow, 1f) : SmoothingWindow; SmoothingContacts = SmoothingContacts.Validate(SmoothingWindow.Length); for (int i = 0; i < SmoothingContacts.Length; i++) { SmoothingContacts[i] = left.GetContact(timestamp + SmoothingWindow[i], mirrored) + right.GetContact(timestamp + SmoothingWindow[i], mirrored); } return(SmoothingContacts.Gaussian()); }
public float GetContact(Frame frame, bool mirrored) { if (Contacts == null || Contacts.Length != Module.Data.Frames.Length) { Debug.Log("Restoring missing contacts for sensor " + ID + " in asset " + Module.Data.GetName() + "."); Contacts = new float[Module.Data.Frames.Length]; } if (!mirrored) { return(Contacts[frame.Index - 1]); } if (MirrorSensor == null) { MirrorSensor = Module.GetSensor(Module.Data.Source.Bones[Module.Data.Symmetry[Module.Data.Source.FindBone(ID).Index]].Name); } return(MirrorSensor == null ? 0f : MirrorSensor.Contacts[frame.Index - 1]); }
public Matrix4x4[] CleanupBallTransformations(bool detectInvalid) { bool invalid = IsInvalid(); if (!detectInvalid && invalid) { invalid = false; Debug.LogWarning("Ignored invalid detection in asset " + Data.GetName() + "."); } Matrix4x4[] motion = new Matrix4x4[Data.Frames.Length]; for (int i = 0; i < Data.Frames.Length; i++) { Matrix4x4 ball = GetTransformation(Ball, Data.Frames[i].Timestamp); Matrix4x4 root = GetRoot(Data.Frames[i].Timestamp, false); float radius = GetControlRadius(); if (invalid) { //Project Surface Matrix4x4 head = GetTransformation(Head, Data.Frames[i].Timestamp); float offset = (head.GetPosition() - root.GetPosition()).ZeroY().magnitude; Vector3 projection = head.GetPosition() + (radius - offset) * (head.GetRotation() * Axis.GetAxis()); Vector3 position = (root.GetPosition().ZeroY() + radius * (projection - root.GetPosition()).ZeroY().normalized).SetY(projection.y); position.y = Mathf.Max(position.y, root.GetPosition().y + Radius); Matrix4x4Extensions.SetPosition(ref ball, position); } else { //Clamp Magnitude Matrix4x4Extensions.SetPosition(ref ball, ball.GetPosition().ClampMagnitudeXZ(radius, root.GetPosition())); } motion[i] = ball; } return(motion); Matrix4x4 GetTransformation(int bone, float timestamp) { float start = Data.GetFirstValidFrame().Timestamp; float end = Data.GetLastValidFrame().Timestamp; if (timestamp < start || timestamp > end) { float boundary = Mathf.Clamp(timestamp, start, end); float pivot = 2f * boundary - timestamp; float clamped = Mathf.Clamp(pivot, start, end); Matrix4x4 reference = Data.GetFrame(clamped).GetBoneTransformation(bone, false); Vector3 position = 2f * Data.GetFrame(boundary).GetBoneTransformation(bone, false).GetPosition() - reference.GetPosition(); position.y = reference.GetPosition().y; Quaternion rotation = reference.GetRotation(); return(Matrix4x4.TRS(position, rotation, Vector3.one)); } else { return(Data.GetFrame(timestamp).GetBoneTransformation(bone, false)); } } bool IsInvalid() { //Get Range int start = Data.GetFirstValidFrame().Index - 1; int end = Data.GetLastValidFrame().Index - 1; //Check contacts ContactModule contact = GetContactModule(); if (contact == null) { return(false); } ContactModule.Sensor left = contact.GetSensor(Data.Source.Bones[LeftHand].Name); ContactModule.Sensor right = contact.GetSensor(Data.Source.Bones[RightHand].Name); if (left != null && right != null) { float[] leftContacts = left.Contacts.GatherByPivots(start, end); float[] rightContacts = left.Contacts.GatherByPivots(start, end); if (leftContacts.All(1f, 0.9f) ^ rightContacts.All(1f, 0.9f) && !ArrayExtensions.Equal(leftContacts, rightContacts).All(true, 0.1f)) { Debug.LogWarning("Stuck-to-hand invalidation in file " + Data.GetName() + "."); return(true); } } //Check transformations Matrix4x4[] transformations = new Matrix4x4[Data.Frames.Length]; for (int i = 0; i < Data.Frames.Length; i++) { transformations[i] = Data.Frames[i].GetBoneTransformation(Ball, false); } if (transformations.GatherByPivots(start, end).Repeating(0.9f)) { Debug.LogWarning("Repeating ball transformation invalidation in file " + Data.GetName() + "."); return(true); } //Check velocities Vector3[] velocities = new Vector3[Data.Frames.Length]; for (int i = 0; i < Data.Frames.Length; i++) { velocities[i] = Data.Frames[i].GetBoneVelocity(Ball, false); } if (velocities.GatherByPivots(start, end).Repeating(0.9f)) { Debug.LogWarning("Ball velocity invalidation in file " + Data.GetName() + "."); return(true); } // //Check out-of-bounds // bool[] bounds = new bool[Data.Frames.Length]; // for(int i=0; i<Data.Frames.Length; i++) { // bounds[i] = Vector3.Distance(GetRoot(Data.Frames[i].Timestamp, false).GetPosition(), Data.Frames[i].GetBoneTransformation(Ball, false).GetPosition()) > 0.5f*GetInteractionArea(); // } // if(bounds.All(true, 0.9f)) { // return true; // } //All seems good return(false); } }