private string GenerateFrame(BVHAnimation animation, BVHAnimation.BVHFrame frame, int sequence, bool mirrored)
    {
        //Sequence number
        string line = sequence + Separator;

        //Frame index
        line += frame.Index + Separator;

        //Frame time
        line += frame.Timestamp + Separator;

        //Get current trajectory
        Trajectory currentTrajectory = animation.ExtractTrajectory(frame, mirrored);

        //Get root transformation
        Matrix4x4 root = currentTrajectory.Points[6].GetTransformation();

        //Extract data
        Matrix4x4[] posture    = animation.ExtractPosture(frame, mirrored);
        Vector3[]   velocities = animation.ExtractBoneVelocities(frame, mirrored);

        //Bone data
        for (int k = 0; k < animation.Character.Hierarchy.Length; k++)
        {
            if (animation.Bones[k])
            {
                //Position
                line += FormatVector3(posture[k].GetPosition().GetRelativePositionTo(root));

                //Rotation
                line += FormatVector3(posture[k].GetForward().GetRelativeDirectionTo(root));
                line += FormatVector3(posture[k].GetUp().GetRelativeDirectionTo(root));

                //Bone Velocity
                line += FormatVector3(velocities[k].GetRelativeDirectionTo(root));
            }
        }

        //Trajectory data
        for (int k = 0; k < 12; k++)
        {
            Vector3 position = currentTrajectory.Points[k].GetPosition().GetRelativePositionTo(root);
            Vector3 facing   = currentTrajectory.Points[k].GetDirection().GetRelativeDirectionTo(root);
            Vector3 velocity = currentTrajectory.Points[k].GetVelocity().GetRelativeDirectionTo(root);
            line += FormatValue(position.x);
            line += FormatValue(position.z);
            line += FormatValue(facing.x);
            line += FormatValue(facing.z);
            line += FormatValue(velocity.x);
            line += FormatValue(velocity.z);
            line += FormatArray(currentTrajectory.Points[k].Styles);
        }

        //Translational and angular root offset
        BVHAnimation.BVHFrame prevFrame          = animation.GetFrame(Mathf.Clamp(frame.Timestamp - 1f / (float)Framerate, 0f, animation.GetTotalTime()));
        Trajectory            previousTrajectory = animation.ExtractTrajectory(prevFrame, mirrored);
        Matrix4x4             offset             = currentTrajectory.Points[6].GetTransformation().GetRelativeTransformationTo(previousTrajectory.Points[6].GetTransformation());

        line += FormatValue(offset.GetPosition().x);
        line += FormatValue(offset.GetPosition().z);
        line += FormatValue(Vector3.SignedAngle(Vector3.forward, offset.GetForward(), Vector3.up));

        //Phase
        float prev    = mirrored ? animation.MirroredPhaseFunction.GetPhase(prevFrame) : animation.PhaseFunction.GetPhase(prevFrame);
        float current = mirrored ? animation.MirroredPhaseFunction.GetPhase(frame) : animation.PhaseFunction.GetPhase(frame);

        line += FormatValue(current);
        line += FormatValue(GetPhaseUpdate(prev, current));

        //Previous postures
        for (int t = 0; t < 6; t++)
        {
            float       timestamp          = Mathf.Clamp(frame.Timestamp - 1f + (float)t / 6f, 0f, animation.GetTotalTime());
            Matrix4x4[] previousPosture    = animation.ExtractPosture(animation.GetFrame(timestamp), mirrored);
            Vector3[]   previousVelocities = animation.ExtractBoneVelocities(animation.GetFrame(timestamp), mirrored);
            //Previous bone data
            for (int k = 0; k < animation.Character.Hierarchy.Length; k++)
            {
                if (animation.Bones[k])
                {
                    //Position
                    line += FormatVector3(previousPosture[k].GetPosition().GetRelativePositionTo(root));

                    //Rotation
                    line += FormatVector3(previousPosture[k].GetForward().GetRelativeDirectionTo(root));
                    line += FormatVector3(previousPosture[k].GetUp().GetRelativeDirectionTo(root));

                    //Bone Velocity
                    line += FormatVector3(previousVelocities[k].GetRelativeDirectionTo(root));
                }
            }
        }

        //Future postures
        for (int t = 1; t < 6; t++)
        {
            float       timestamp        = Mathf.Clamp(frame.Timestamp + (float)t / 5f, 0f, animation.GetTotalTime());
            Matrix4x4[] futurePosture    = animation.ExtractPosture(animation.GetFrame(timestamp), mirrored);
            Vector3[]   futureVelocities = animation.ExtractBoneVelocities(animation.GetFrame(timestamp), mirrored);
            //Previous bone data
            for (int k = 0; k < animation.Character.Hierarchy.Length; k++)
            {
                if (animation.Bones[k])
                {
                    //Position
                    line += FormatVector3(futurePosture[k].GetPosition().GetRelativePositionTo(root));

                    //Rotation
                    line += FormatVector3(futurePosture[k].GetForward().GetRelativeDirectionTo(root));
                    line += FormatVector3(futurePosture[k].GetUp().GetRelativeDirectionTo(root));

                    //Bone Velocity
                    line += FormatVector3(futureVelocities[k].GetRelativeDirectionTo(root));
                }
            }
        }

        //Postprocess
        line = line.Remove(line.Length - 1);
        line = line.Replace(",", ".");

        return(line);
    }
예제 #2
0
    private void ExportRootVelocities()
    {
        if (Animations.Length == 0)
        {
            Debug.Log("No animations specified.");
            return;
        }

        System.Collections.Generic.List <float>[] velocities = new System.Collections.Generic.List <float> [Animations[0].StyleFunction.Styles.Length];
        for (int i = 0; i < velocities.Length; i++)
        {
            velocities[i] = new System.Collections.Generic.List <float>();
        }
        for (int i = 0; i < Animations.Length; i++)
        {
            if (Use[i])
            {
                for (int s = 0; s < Animations[i].Sequences.Length; s++)
                {
                    int startIndex = Animations[i].Sequences[s].Start;
                    int endIndex   = Animations[i].Sequences[s].End;
                    for (int j = startIndex; j <= endIndex; j++)
                    {
                        BVHAnimation.BVHFrame frame = Animations[i].GetFrame(j);
                        for (int v = 0; v < velocities.Length; v++)
                        {
                            if (Animations[i].StyleFunction.GetFlag(frame, v))
                            {
                                velocities[v].Add(Animations[i].PhaseFunction.RootVelocities[frame.Index - 1]);
                            }
                        }
                    }
                }
            }
        }

        for (int v = 0; v < velocities.Length; v++)
        {
            //Debug.Log(Animations[0].StyleFunction.Styles[v].Name + ": " + "Mean: " + Utility.ComputeMean(velocities[v].ToArray()) + " StdDev: " + Utility.ComputeSigma(velocities[v].ToArray()));

            string name     = Animations[0].StyleFunction.Styles[v].Name;
            string filename = string.Empty;
            if (!File.Exists(Application.dataPath + "/Project/" + name + ".txt"))
            {
                filename = Application.dataPath + "/Project/" + name;
            }
            else
            {
                int i = 1;
                while (File.Exists(Application.dataPath + "/Project/" + name + " (" + i + ").txt"))
                {
                    i += 1;
                }
                filename = Application.dataPath + "/Project/" + name + " (" + i + ")";
            }

            StreamWriter data = File.CreateText(filename + ".txt");
            data.WriteLine(FormatArray(velocities[v].ToArray()));
            data.Close();
        }
    }
예제 #3
0
    private void WriteAnimations(ref StreamWriter data, ref int sequence, bool mirrored)
    {
        for (int i = 0; i < Animations.Length; i++)
        {
            if (Use[i])
            {
                for (int s = 0; s < Animations[i].Sequences.Length; s++)
                {
                    for (int e = 0; e < Animations[i].Sequences[s].Export; e++)
                    {
                        sequence += 1;
                        //float timeStart = Animations[i].GetFrame(Animations[i].SequenceStart).Timestamp;
                        //float timeEnd = Animations[i].GetFrame(Animations[i].SequenceEnd).Timestamp;
                        //for(float j=timeStart; j<=timeEnd; j+=1f/60f) {
                        int startIndex = Animations[i].Sequences[s].Start;
                        int endIndex   = Animations[i].Sequences[s].End;
                        for (int j = startIndex; j <= endIndex; j++)
                        {
                            //Get frame
                            BVHAnimation.BVHFrame frame = Animations[i].GetFrame(j);
                            //BVHAnimation.BVHFrame prevFrame = Animations[i].GetFrame(Mathf.Clamp(j-1f/60f, 0f, Animations[i].TotalTime));
                            BVHAnimation.BVHFrame prevFrame = Animations[i].GetFrame(Mathf.Clamp(j - 1, 1, Animations[i].GetTotalFrames()));

                            //j = frame.Timestamp;

                            //Sequence number
                            string line = sequence + Separator;

                            //Frame index
                            line += frame.Index + Separator;

                            //Frame time
                            line += frame.Timestamp + Separator;

                            //Extract data
                            Matrix4x4[] transformations = Animations[i].ExtractTransformations(frame, mirrored);
                            Vector3[]   velocities      = Animations[i].ExtractVelocities(frame, mirrored, 0.1f);
                            Trajectory  trajectory      = Animations[i].ExtractTrajectory(frame, mirrored);
                            Trajectory  prevTrajectory  = Animations[i].ExtractTrajectory(prevFrame, mirrored);

                            //Get root transformation
                            Matrix4x4 root = trajectory.Points[6].GetTransformation();

                            //Bone data
                            for (int k = 0; k < Animations[i].Character.Hierarchy.Length; k++)
                            {
                                //Position
                                line += FormatVector3(transformations[k].GetPosition().GetRelativePositionTo(root));

                                //Rotation
                                line += FormatVector3(transformations[k].GetForward().GetRelativeDirectionTo(root));
                                line += FormatVector3(transformations[k].GetUp().GetRelativeDirectionTo(root));

                                //Velocity
                                line += FormatVector3(velocities[k].GetRelativeDirectionTo(root));
                            }

                            //Trajectory data
                            for (int k = 0; k < 12; k++)
                            {
                                line += FormatVector3(trajectory.Points[k].GetPosition().GetRelativePositionTo(root));
                                //line += FormatVector3(trajectory.Points[k].GetDirection().GetRelativeDirectionTo(root));
                                line += FormatValue(trajectory.Points[k].GetDirection().GetRelativeDirectionTo(root).x);
                                line += FormatValue(trajectory.Points[k].GetDirection().GetRelativeDirectionTo(root).z);
                                line += FormatValue(trajectory.Points[k].GetVelocity());
                                line += FormatValue(trajectory.Points[k].GetLeftSample().y - root.GetPosition().y);
                                line += FormatValue(trajectory.Points[k].GetRightSample().y - root.GetPosition().y);
                            }

                            for (int k = 0; k < 12; k++)
                            {
                                line += FormatArray(trajectory.Points[k].Styles);
                            }

                            /*
                             * //Phase
                             * if(mirrored) {
                             *      line += FormatValue(Animations[i].MirroredPhaseFunction.GetPhase(frame));
                             * } else {
                             *      line += FormatValue(Animations[i].PhaseFunction.GetPhase(frame));
                             * }
                             */

                            //Translational and angular root velocity
                            Vector3 position      = trajectory.Points[6].GetPosition();
                            Vector3 direction     = trajectory.Points[6].GetDirection();
                            Vector3 prevPosition  = prevTrajectory.Points[6].GetPosition();
                            Vector3 prevDirection = prevTrajectory.Points[6].GetDirection();

                            Vector3 translationOffset = Quaternion.Inverse(Quaternion.LookRotation(prevDirection, Vector3.up)) * (position - prevPosition);
                            line += FormatValue(translationOffset.x);
                            line += FormatValue(translationOffset.z);

                            float rotationOffset = Vector3.SignedAngle(prevDirection, direction, Vector3.up);
                            line += FormatValue(rotationOffset);

                            /*
                             * //Phase change
                             * if(mirrored) {
                             *      line += FormatValue(GetPhaseChange(Animations[i].MirroredPhaseFunction.GetPhase(prevFrame), Animations[i].MirroredPhaseFunction.GetPhase(frame)));
                             * } else {
                             *      line += FormatValue(GetPhaseChange(Animations[i].PhaseFunction.GetPhase(prevFrame), Animations[i].PhaseFunction.GetPhase(frame)));
                             * }
                             */

                            //Postprocess
                            line = line.Remove(line.Length - 1);
                            line = line.Replace(",", ".");

                            //Write
                            data.WriteLine(line);
                        }
                    }
                }
            }
        }
    }
예제 #4
0
    private IEnumerator Record()
    {
        Data           = ScriptableObject.CreateInstance <BVHAnimation>();
        Data.Character = Animation.Character;
        Data.FrameTime = FrameTime;

        Data.Trajectory            = new Trajectory(0, Animation.Controller.Styles.Length);
        Data.PhaseFunction         = new BVHAnimation.BVHPhaseFunction(Data);
        Data.MirroredPhaseFunction = new BVHAnimation.BVHPhaseFunction(Data);
        Data.StyleFunction         = new BVHAnimation.BVHStyleFunction(Data);
        for (int i = 0; i < Animation.Controller.Styles.Length; i++)
        {
            Data.StyleFunction.AddStyle(Animation.Controller.Styles[i].Name);
        }
        //Data.StyleFunction.SetStyle(BVHAnimation.BVHStyleFunction.STYLE.Quadruped);

        int index = 0;

        while (Recording && Application.isPlaying)
        {
            yield return(new WaitForEndOfFrame());

            //Frames
            BVHAnimation.BVHFrame frame = new BVHAnimation.BVHFrame(Data, Data.GetTotalFrames() + 1, Data.GetTotalFrames() * FrameTime);
            frame.Local = Data.Character.GetLocalTransformations();
            frame.World = Data.Character.GetWorldTransformations();
            Utility.Add(ref Data.Frames, frame);

            //Trajectory
            Trajectory.Point point = new Trajectory.Point(Data.Trajectory.Points.Length, Animation.Controller.Styles.Length);
            point.SetTransformation(Animation.GetTrajectory().Points[60].GetTransformation());
            point.SetLeftsample(Animation.GetTrajectory().Points[60].GetLeftSample());
            point.SetRightSample(Animation.GetTrajectory().Points[60].GetRightSample());
            point.SetSlope(Animation.GetTrajectory().Points[60].GetSlope());
            for (int i = 0; i < Animation.Controller.Styles.Length; i++)
            {
                point.Styles[i] = Animation.GetTrajectory().Points[60].Styles[i];
            }
            Utility.Add(ref Data.Trajectory.Points, point);

            //Phase Function

            /*
             * Utility.Add(ref Data.PhaseFunction.Phase, Mathf.Repeat(Animation.GetPhase() / (2f*Mathf.PI), 1f));
             * Utility.Add(ref Data.PhaseFunction.Keys, index == 0 ? true : Data.PhaseFunction.Phase[index-1] > Data.PhaseFunction.Phase[index]);
             * Utility.Add(ref Data.PhaseFunction.Cycle, 0f);
             * Utility.Add(ref Data.PhaseFunction.NormalisedCycle, 0f);
             * Utility.Add(ref Data.PhaseFunction.Velocities, 0f);
             * Utility.Add(ref Data.PhaseFunction.NormalisedVelocities, 0f);
             * Utility.Add(ref Data.PhaseFunction.Heights, 0f);
             */
            Utility.Add(ref Data.PhaseFunction.Phase, 0f);
            Utility.Add(ref Data.PhaseFunction.Keys, false);
            Utility.Add(ref Data.PhaseFunction.Cycle, 0f);
            Utility.Add(ref Data.PhaseFunction.NormalisedCycle, 0f);
            Utility.Add(ref Data.PhaseFunction.Velocities, 0f);
            Utility.Add(ref Data.PhaseFunction.NormalisedVelocities, 0f);
            Utility.Add(ref Data.PhaseFunction.Heights, 0f);
            Utility.Add(ref Data.PhaseFunction.RootVelocities, 0f);
            Utility.Add(ref Data.PhaseFunction.NormalisedRootVelocities, 0f);

            //Mirrored Phase Function
            Utility.Add(ref Data.MirroredPhaseFunction.Phase, 0f);
            Utility.Add(ref Data.MirroredPhaseFunction.Keys, false);
            Utility.Add(ref Data.MirroredPhaseFunction.Cycle, 0f);
            Utility.Add(ref Data.MirroredPhaseFunction.NormalisedCycle, 0f);
            Utility.Add(ref Data.MirroredPhaseFunction.Velocities, 0f);
            Utility.Add(ref Data.MirroredPhaseFunction.NormalisedVelocities, 0f);
            Utility.Add(ref Data.MirroredPhaseFunction.Heights, 0f);
            Utility.Add(ref Data.MirroredPhaseFunction.RootVelocities, 0f);
            Utility.Add(ref Data.MirroredPhaseFunction.NormalisedRootVelocities, 0f);

            //Style Function
            bool styleUpdate = false;
            for (int i = 0; i < Animation.Controller.Styles.Length; i++)
            {
                Utility.Add(ref Data.StyleFunction.Styles[i].Flags, Animation.Controller.Styles[i].Query());
                Utility.Add(ref Data.StyleFunction.Styles[i].Values, Animation.GetTrajectory().Points[60].Styles[i]);
                if (index == 0)
                {
                    styleUpdate = true;
                }
                else
                {
                    if (Data.StyleFunction.Styles[i].Flags[index - 1] != Data.StyleFunction.Styles[i].Flags[index])
                    {
                        styleUpdate = true;
                    }
                }
            }
            Utility.Add(ref Data.StyleFunction.Keys, styleUpdate);

            index += 1;
        }

        //Setup
        Data.TimeWindow  = Data.GetTotalTime();
        Data.Corrections = new Vector3[Animation.Character.Hierarchy.Length];
        Data.DetectSymmetry();

        //Postprocess
        Data.PhaseFunction.Keys[index - 1] = true;
        Data.StyleFunction.Keys[index - 1] = true;
        Data.PhaseFunction.Recompute();
        Data.StyleFunction.Recompute();

        //Finish
        Recording = false;
    }