/// <summary> /// Интерполирование двух кадров /// </summary> /// <param name="mf1">Первый кадр</param> /// <param name="mf2">Второй кадр</param> /// <param name="delta">Значение интерполяции</param> MorphFrame InterpolateFrame(MorphFrame mf1, MorphFrame mf2, float delta) { MorphFrame mf = new MorphFrame(); mf.verts = new float[mf1.verts.Length]; mf.normals = new float[mf1.normals.Length]; // Интерполяция данных float p1, p2; for (int i = 0; i < mf.verts.Length; i++) { // Вершина p1 = mf1.verts[i]; p2 = mf2.verts[i]; mf.verts[i] = p1 + (p2 - p1) * delta; // Нормаль p1 = mf1.normals[i]; p2 = mf2.normals[i]; mf.normals[i] = p1 + (p2 - p1) * delta; } // Сохранение временного кадра return(mf); }
/// <summary> /// Обновление состояния буфферов /// </summary> void UpdateBuffers(MorphFrame f1, MorphFrame f2, float d) { bool needFirstBuffer = false; bool needSecondBuffer = false; if (firstFrameUsed != f1.Time) { needFirstBuffer = true; firstFrameUsed = f1.Time; } if (secondFrameUsed != f2.Time) { needSecondBuffer = true; secondFrameUsed = f2.Time; } if (needFirstBuffer) { if (firstVertexBuffer == 0) { firstVertexBuffer = GL.GenBuffer(); } if (firstNormalBuffer == 0) { firstNormalBuffer = GL.GenBuffer(); } GL.BindBuffer(BufferTarget.ArrayBuffer, firstVertexBuffer); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(f1.verts.Length * 4), f1.verts, BufferUsageHint.StreamDraw); GL.BindBuffer(BufferTarget.ArrayBuffer, firstNormalBuffer); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(f1.normals.Length * 4), f1.normals, BufferUsageHint.StreamDraw); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } if (needSecondBuffer) { if (secondVertexBuffer == 0) { secondVertexBuffer = GL.GenBuffer(); } if (secondNormalBuffer == 0) { secondNormalBuffer = GL.GenBuffer(); } GL.BindBuffer(BufferTarget.ArrayBuffer, secondVertexBuffer); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(f2.verts.Length * 4), f2.verts, BufferUsageHint.StreamDraw); GL.BindBuffer(BufferTarget.ArrayBuffer, secondNormalBuffer); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(f2.normals.Length * 4), f2.normals, BufferUsageHint.StreamDraw); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } bufferInterpolation = d; }
/// <summary> /// Обновление анимации /// </summary> protected override void UpdateAnimation() { Frame[] frms = Frames; if (frms != null) { QueuedMeshUpdate q = queuedUpdate; MorphFrame f1, f2; float d = 0; if (q.Time < 0) { f1 = transitionFrame; f2 = GetFrameForward(q.Time, q.IsLooping, q.FirstFrame, q.LastFrame); d = 1f + q.Time; } else { f1 = GetFrameBackward(q.Time, q.IsLooping, q.FirstFrame, q.LastFrame); f2 = GetFrameForward(q.Time, q.IsLooping, q.FirstFrame, q.LastFrame); if (f2 == null) { f2 = f1; } else if (f1 == null) { f1 = f2; } else { if (f1.Time != f2.Time) { d = (q.Time - f1.Time) / (f2.Time - f1.Time); } } if (d < 0) { d = 1f + d; } } if (GraphicalCaps.ShaderPipeline) { UpdateBuffers(f1, f2, d); } else { currentFrame = InterpolateFrame(f1, f2, d); vertices = currentFrame.verts; normals = currentFrame.normals; } } }
/// <summary> /// Изменение сферы отсечения /// </summary> void RebuildCullingSphere() { Frame[] frames = Frames; if (frames != null) { Vec3 max = Vec3.One * float.MinValue, min = Vec3.One * float.MaxValue; foreach (Frame f in frames) { MorphFrame cf = (MorphFrame)f; if (cf != null) { for (int i = 0; i < cf.verts.Length; i += 3) { if (cf.verts[i] > max.X) { max.X = cf.verts[i]; } if (cf.verts[i + 1] > max.Y) { max.Y = cf.verts[i + 1]; } if (-cf.verts[i + 2] > max.Z) { max.Z = -cf.verts[i + 2]; } if (cf.verts[i] < min.X) { min.X = cf.verts[i]; } if (cf.verts[i + 1] < min.Y) { min.Y = cf.verts[i + 1]; } if (-cf.verts[i + 2] < min.Z) { min.Z = -cf.verts[i + 2]; } } cull = new CullBox(); cull.Min = min; cull.Max = max; } } RebuildParentCull(); } }
/// <summary> /// Создание переходного кадра /// </summary> protected override void UpdateTransition() { Frame[] frms = Frames; if (frms != null) { QueuedMeshUpdate q = queuedTransitionUpdate; MorphFrame f1, f2; float d = 0; if (q.Time < 0) { if (transitionFrame == null) { // WTF transitionFrame = GetFrameForward(q.FirstFrame, true, q.FirstFrame, q.LastFrame); } f1 = transitionFrame; f2 = GetFrameForward(q.Time, q.IsLooping, q.FirstFrame, q.LastFrame); d = 1f + q.Time; } else { f1 = GetFrameBackward(q.Time, q.IsLooping, q.FirstFrame, q.LastFrame); f2 = GetFrameForward(q.Time, q.IsLooping, q.FirstFrame, q.LastFrame); if (f2 == null) { f2 = f1; } else if (f1 == null) { f1 = f2; } else { if (f1.Time != f2.Time) { d = (q.Time - f1.Time) / (f2.Time - f1.Time); } } if (d < 0) { d = 1f + d; } } transitionFrame = InterpolateFrame(f1, f2, d); } }
static void Main(string[] args) { if (args.Length != 2) { Console.WriteLine("第一引数にvmdファイルへのファイルパス,第二引数に出力先のファイルパスを指定してください。"); return; } String filePath = args[0]; String fileDest = args[1]; if (!File.Exists(filePath)) { Console.WriteLine("指定されたvmdファイルは存在しません。"); return; } using (FileStream source = File.OpenRead(filePath)) { MotionData data = MotionData.getMotion(source); //ヘッダー情報の生製 Console.WriteLine("ヘッダー情報の生成"); VocaloidMotionEvolved vme = new VocaloidMotionEvolved(); vme.header = new Header(); vme.header.versionInfo = "Vocaloid Motion Evolved"; vme.header.modelInfo.Add(data.header.ModelName); //ボーンフレームのインデックス処理 Console.WriteLine("VME用ボーンインデックスの生成"); HashSet <String> boneNames = new HashSet <string>(); foreach (var frameData in data.boneFrameList.boneFrameDatas) { boneNames.Add(frameData.BoneName); } Dictionary <string, ulong> boneIdtable = new Dictionary <string, ulong>(); ulong id = 0; foreach (var boneName in boneNames) { boneIdtable.Add(boneName, id); IDTag tag = new IDTag(); tag.id = id; tag.name = boneName; vme.boneIDTable.Add(tag); id++; } //ボーンフレームの書き出し処理 Console.WriteLine("ボーンフレーム情報の生成"); foreach (var boneName in boneNames) { Console.WriteLine("ボーンフレームテーブル生成:{0}", boneName); BoneFrameTable frameTable = new BoneFrameTable(); frameTable.id = boneIdtable[boneName]; foreach (var frameData in data.boneFrameList.boneFrameDatas) { if (frameData.BoneName.Equals(boneName)) { BoneFrame frame = new BoneFrame(); frame.frameNumber = frameData.FrameNumber; frame.position = frameData.BonePosition.ToData(); frame.rotation = frameData.BoneRotatingQuaternion.ToData(); frame.interpolParameters = new BezInterpolParams(); BezInterpolParams interpol = frame.interpolParameters; interpol.X1 = new bvec2() { x = frameData.Interpolation[0][0][0], y = frameData.Interpolation[0][1][0] }; interpol.X2 = new bvec2() { x = frameData.Interpolation[0][2][0], y = frameData.Interpolation[0][3][0] }; interpol.Y1 = new bvec2() { x = frameData.Interpolation[0][0][1], y = frameData.Interpolation[0][1][1] }; interpol.Y2 = new bvec2() { x = frameData.Interpolation[0][2][1], y = frameData.Interpolation[0][3][1] }; interpol.Z1 = new bvec2() { x = frameData.Interpolation[0][0][2], y = frameData.Interpolation[0][1][2] }; interpol.Z2 = new bvec2() { x = frameData.Interpolation[0][2][2], y = frameData.Interpolation[0][3][2] }; interpol.R1 = new bvec2() { x = frameData.Interpolation[0][0][3], y = frameData.Interpolation[0][1][3] }; interpol.R2 = new bvec2() { x = frameData.Interpolation[0][2][3], y = frameData.Interpolation[0][3][3] }; frameTable.frames.Add(frame); } } frameTable.frames.Sort(new FrameComparator()); vme.boneFrameTables.Add(frameTable); } Console.WriteLine("ボーンフレームリスト生成完了"); Console.WriteLine("モーフ用フレームリスト生成"); HashSet <String> faceNames = new HashSet <string>(); foreach (var frameData in data.morphFrameList.morphFrameDatas) { faceNames.Add(frameData.Name); } Dictionary <string, ulong> faceIdtable = new Dictionary <string, ulong>(); id = 0; foreach (var faceName in faceNames) { faceIdtable.Add(faceName, id); IDTag tag = new IDTag(); tag.id = id; tag.name = faceName; vme.morphIDTable.Add(tag); id++; } foreach (var morphName in faceNames) { Console.WriteLine("モーフフレームテーブル生成:{0}", morphName); MorphFrameTable frameTable = new MorphFrameTable(); frameTable.id = faceIdtable[morphName]; foreach (var frameData in data.morphFrameList.morphFrameDatas) { if (frameData.Name.Equals(morphName)) { MorphFrame frame = new MorphFrame(); frame.frameNumber = frameData.FrameNumber; frame.value = frameData.MorphValue; frameTable.frames.Add(frame); } } frameTable.frames.Sort(new FrameComparator()); vme.morphFrameTables.Add(frameTable); } Console.WriteLine("モーフフレーム生成完了"); if (data.CameraFrames.CameraFrameCount > 0) { Console.WriteLine("カメラ用フレームリスト生成"); IDTag camTag = new IDTag(); camTag.id = 0; camTag.name = "Default"; vme.cameraIDTable.Add(camTag); CameraFrameTable table = new CameraFrameTable(); table.id = camTag.id; foreach (var cameraFrame in data.CameraFrames.CameraFrames) { CameraFrame frame = new CameraFrame(); frame.frameNumber = cameraFrame.FrameNumber; frame.position = cameraFrame.CameraPosition.ToData(); frame.rotation = cameraFrame.CameraRotation.ToData(); frame.viewAngle = cameraFrame.ViewAngle; frame.perspective = cameraFrame.Perspective; frame.distance = cameraFrame.Distance; frame.interpolParameters = new BezInterpolParams(); BezInterpolParams interpol = frame.interpolParameters; interpol.X1 = new bvec2() { x = cameraFrame.Interpolation[0][0], y = cameraFrame.Interpolation[1][0] }; interpol.X2 = new bvec2() { x = cameraFrame.Interpolation[2][0], y = cameraFrame.Interpolation[3][0] }; interpol.Y1 = new bvec2() { x = cameraFrame.Interpolation[0][1], y = cameraFrame.Interpolation[1][1] }; interpol.Y2 = new bvec2() { x = cameraFrame.Interpolation[2][1], y = cameraFrame.Interpolation[3][1] }; interpol.Z1 = new bvec2() { x = cameraFrame.Interpolation[0][2], y = cameraFrame.Interpolation[1][2] }; interpol.Z2 = new bvec2() { x = cameraFrame.Interpolation[2][2], y = cameraFrame.Interpolation[3][2] }; interpol.R1 = new bvec2() { x = cameraFrame.Interpolation[0][3], y = cameraFrame.Interpolation[1][3] }; interpol.R2 = new bvec2() { x = cameraFrame.Interpolation[2][3], y = cameraFrame.Interpolation[3][3] }; CameraExtraBezParams camInterpol = frame.cameraInterpolParams = new CameraExtraBezParams(); camInterpol.L1 = new bvec2() { x = cameraFrame.Interpolation[0][4], y = cameraFrame.Interpolation[1][4] }; camInterpol.L2 = new bvec2() { x = cameraFrame.Interpolation[2][4], y = cameraFrame.Interpolation[3][4] }; camInterpol.V1 = new bvec2() { x = cameraFrame.Interpolation[0][5], y = cameraFrame.Interpolation[1][5] }; camInterpol.V2 = new bvec2() { x = cameraFrame.Interpolation[2][5], y = cameraFrame.Interpolation[3][5] }; table.frames.Add(frame); } } if (data.LightFrames.LightCount > 0) { Console.WriteLine("ライト用フレームリストの生成"); IDTag lightTag = new IDTag(); lightTag.id = 0; lightTag.name = "Default"; vme.lightIDTable.Add(lightTag); LightFrameTable table = new LightFrameTable(); table.id = lightTag.id; foreach (var lightFrame in data.LightFrames.LightFrames) { LightFrame frame = new LightFrame(); frame.frameNumber = lightFrame.FrameNumber; frame.position = lightFrame.LightPosition.ToData(); frame.color = lightFrame.LightColor.ToData(); table.frames.Add(frame); } } if (File.Exists(fileDest)) { File.Delete(fileDest); } using (FileStream fs = File.OpenWrite(fileDest)) { Serializer.Serialize(fs, vme); } } }
public int Compare(MorphFrame x, MorphFrame y) { return((int)(x.frameNumber - y.frameNumber)); }