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