コード例 #1
0
    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);
    }
コード例 #2
0
    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());
        }
    }
コード例 #3
0
    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);
    }
コード例 #4
0
    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);
        }
    }
コード例 #5
0
    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());
    }
コード例 #6
0
    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);
        }
    }