void PrepareSimilarMotion(GameObject go, MotionSimilarity.FrameData frame, int beat) { Animation anim = go.GetComponent <Animation>(); foreach (AnimationState state in anim) { anim.RemoveClip(state.clip); } anim.clip = null; string resName = string.Format("Assets/DanceMotion/resource/{0}/Take 001.anim", frame.name); var res = (AnimationClip)AssetDatabase.LoadAssetAtPath(resName, typeof(AnimationClip)); anim.AddClip(res, "Take 001"); anim.clip = res; float time = frame.startTime + beat * frame.beatTime; var script = go.GetComponent <ExtractMotionFeatures>(); script.StartTime = time; script.BeatTime = frame.beatTime; script.Init(); }
void ExtractingMotionFeatures(Transform[] joints, Animation animation, MotionSimilarity.FrameData frameData, string outputFile) { //float bpm = musicInfo["bpm"]; //float enterTime = musicInfo["et"]; // 一拍中分6个window,window间50%重叠,每个window采样6次 // 一拍共6 * 3.5=21个采样点 int samplesPerBeat = 3 * MotionSimilarity.NumSamplesPerBeat; float dt = frameData.beatTime / samplesPerBeat; //Debug.LogFormat("bpm {0} delta time {1}", bpm, dt); Transform reference = joints[0]; AnimationState state = animation["Take 001"]; state.weight = 1.0f; state.enabled = true; float invdt = 1.0f / dt; Quaternion[] prevRot = new Quaternion[joints.Length]; // init rotation to first frame state.time = frameData.startTime - dt; animation.Sample(); for (int i = 0; i < joints.Length; i++) { prevRot[i] = joints[i].localRotation; } var featureData = new List <float>(); int numSamples = frameData.numBeats * samplesPerBeat; for (int i = 0; i < numSamples; i++) { float time = frameData.startTime + dt * i; state.time = time; animation.Sample(); //featureData.Add(time); Vector3 refPos = reference.position; for (int j = 0; j < joints.Length; j++) { float dis = (joints[j].position - refPos).magnitude; Quaternion q = joints[j].localRotation; float omiga = Quaternion.Angle(q, prevRot[j]); prevRot[j] = q; featureData.Add(dis * invdt); featureData.Add(omiga * invdt); } } Debug.LogFormat("feature data {0} frames {1} joints {2} floats", numSamples, joints.Length, numSamples * joints.Length * 2); Debug.LogFormat("num beats {0} num filtered samples {1}", frameData.numBeats, frameData.numBeats * MotionSimilarity.NumSamplesPerBeat); FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write); BinaryWriter bw = new BinaryWriter(fs); bw.Write(numSamples); // sample per beat bw.Write(samplesPerBeat); bw.Write(joints.Length * 2); //bw.Write(frameData.startTime); bw.Write(dt); foreach (var d in featureData) { bw.Write(d); } bw.Close(); fs.Close(); Debug.LogFormat("write file {0}", outputFile); }