private void AddHeightMapVoxelIJL() { float sqdist = heightmap_radius * heightmap_radius; int max = Mathf.CeilToInt(heightmap_radius); for (int i = -max; i <= max; i++) { for (int j = -max; j <= max; j++) { //distance validity check Vector3 v = VMD.VoxelVertex(new IJL(i, j, 0)); if (VMD.VoxelVertex(new IJL(i, j, 0)).sqrMagnitude > sqdist) { continue; } float h = height * Mathf.PerlinNoise(perlin_scale * (j + 0.1f), perlin_scale * (i + 0.1f)); int max_l = Mathf.CeilToInt(h); for (int l = 0; l < max_l; l++) { if (l > h) { continue; } AddVoxelIJL(new IJL(i, j, l)); } } } }
private void InitializeChunkObject(int index) { if (index < 0 || index >= _chunkobjs.Count || _chunkobjs[index] != null) { return; } IJL chunk = _chunksobj_ijls[index]; _chunkobjs[index] = new GameObject("Chunk " + chunk.ToString()); _chunkobjs[index].transform.localPosition = VMD.VoxelVertex(Vx.ChunkVoxelIJL(chunk, chunk_radius)); _chunkobjs[index].AddComponent <MeshFilter>(); MeshRenderer renderer = _chunkobjs[index].AddComponent <MeshRenderer>(); renderer.sharedMaterial = material; }
// CSV + VMD更新、連結WAV private void button3_Click(object sender, EventArgs e) { if (textBox1.Text == "") { MessageBox.Show("LABデータが読み込まれていません。", APP_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } string sFile = ""; openFileDialog1.FileName = ""; openFileDialog1.Title = "読み込むVMDファイルを選択してください。"; openFileDialog1.Filter = "VMDファイル(*.vmd)|*.vmd"; if (openFileDialog1.ShowDialog() == DialogResult.OK) { sFile = openFileDialog1.FileName; } else { return; } string[] sLines = null; // データ更新 sLines = textBox1.Text.Split('\n'); List <string> listLines = new List <string>(); List <float>[] mouth_size = new List <float> [6]; // 口の大きさ(0.0~1.0) List <uint>[] face_val = new List <uint> [6]; // あ/い/う/え/お/(空白)/ん for (int i = 0; i < 6; i++) { mouth_size[i] = new List <float>(); face_val[i] = new List <uint>(); } ulong ulULTime = 0; // 実際の秒数(0.055とか)を10000000倍した数値(550,000) uint uiStartTimeFrame = 0, uiStartTimeFrameORG = 0; uint uiEndTimeFrame = 0, uiEndTimeFrameORG = 0; uint uiFrames = 0; uint uiSt = 0, uiEd = 0; List <ulong> listSentenceTime = new List <ulong>(); List <ulong> listStartTime = new List <ulong>(); ulong ulULFirstStartTime = 0; for (int j = 0; j < sLines.Length; j++) { string sss = sLines[j]; // 一行単位で切り出し sss = sss.Replace("\r", ""); // \r を除去しておく if (sss == "") { listSentenceTime.Add(ulULTime); // 累計時間 continue; } if (sss.StartsWith("##StartTime,") == true) { double d = double.Parse(sss.Substring(12)); ulULTime = (ulong)(d * 10000000.0 + 0.9); // 加算ではなく直接指定 if (ulULFirstStartTime == 0) { ulULFirstStartTime = ulULTime; } continue; } if (sss.StartsWith("# ") == true) { listStartTime.Add(ulULTime); continue; } if (sss.StartsWith("#") == true) { MessageBox.Show(sss + " の行はスキップします。", APP_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Information); continue; } int nShapePrev = -1; string[] st1 = sss.Split(','); // "m" , "0.055" string sPhoneme = st1[0]; // "m" ulong ulULStartTime = ulULTime; ulong ulULEndTime = ulULStartTime + (ulong)(double.Parse(st1[1]) * 10000000.0 + 0.9); ulULTime = ulULEndTime; // System.Diagnostics.Trace.WriteLine("/音素: " + sPhoneme + " /開始: " + fStartTime.ToString("0.000") + " /終了: " + fEndTime.ToString("0.000")); uiStartTimeFrame = uiStartTimeFrameORG + (uint)((double)ulULStartTime / 10000000.0 * 30.0); uiEndTimeFrame = uiEndTimeFrameORG + (uint)((double)ulULEndTime / 10000000.0 * 30.0); // 口の形は何か string s = sPhoneme; int nShape = -1; if (s == "a" || s == "A") { nShape = 0; } // あ行 if (s == "i" || s == "I") { nShape = 1; } if (s == "u" || s == "U") { nShape = 2; } if (s == "e" || s == "E") { nShape = 3; } if (s == "o" || s == "O") { nShape = 4; } if (s == "N") { nShape = 5; } // ん if (s == "pau") { nShape = -100; } // pause // 子音とかかも if ((nShape == -1) && (j < sLines.Length - 1)) { string sss2 = sLines[j + 1].Replace("\r", ""); st1 = sss2.Split(','); // "m" , "0.055" sPhoneme = st1[0]; // "m" ulULEndTime = ulULEndTime + (ulong)(double.Parse(st1[1]) * 10000000.0 + 0.9); // fStartはいじる必要なし ulULTime = ulULEndTime; s = sPhoneme; if (s == "a" || s == "A") { nShape = 0; } if (s == "i" || s == "I") { nShape = 1; } if (s == "u" || s == "U") { nShape = 2; } if (s == "e" || s == "E") { nShape = 3; } if (s == "o" || s == "O") { nShape = 4; } if (nShape >= 0) { uiEndTimeFrame = uiEndTimeFrameORG + (uint)((double)ulULEndTime / 10000000.0 * 30.0); // System.Diagnostics.Trace.WriteLine("/音素: " + sPhoneme + " /開始: " + fStartTime.ToString("0.000") + " /終了: " + fEndTime.ToString("0.000")); j = j + 1; // 子音の場合は次の母音までを1セットとする } else if (j < sLines.Length - 2) { // ソリッド ⇒ s/o/r/i/cl/d/o なので+2が必要 sss2 = sLines[j + 2].Replace("\r", "");; st1 = sss2.Split(','); // "m" , "0.055" sPhoneme = st1[0]; // "m" ulULEndTime = ulULEndTime + (ulong)(double.Parse(st1[1]) * 10000000.0 + 0.9); // fStartはいじる必要なし ulULTime = ulULEndTime; s = sPhoneme; if (s == "a" || s == "A") { nShape = 0; } if (s == "i" || s == "I") { nShape = 1; } if (s == "u" || s == "U") { nShape = 2; } if (s == "e" || s == "E") { nShape = 3; } if (s == "o" || s == "O") { nShape = 4; } if (nShape >= 0) { uiEndTimeFrame = uiEndTimeFrameORG + (uint)((double)ulULEndTime / 10000000.0 * 30.0); // System.Diagnostics.Trace.WriteLine("/音素: " + sPhoneme + " /開始: " + fStartTime.ToString("0.000") + " /終了: " + fEndTime.ToString("0.000")); j = j + 2; // 子音の場合は次の母音までを1セットとする } } } while (uiFrames < uiStartTimeFrame) { uiFrames++; } // ここの uiFrames が開始フレーム uiSt = uiFrames; int nCount = 0; float fValue = 0.0F; if (nShape >= 0) { while (uiFrames < uiEndTimeFrame) { switch (nCount) { case 0: fValue = 0.66F; if (uiFrames > 0) { face_val[nShape].Add(uiFrames - 1); if (nShapePrev == nShape) { mouth_size[nShape].Add(0.33F); } else { mouth_size[nShape].Add(0.0F); } } face_val[nShape].Add(uiFrames); mouth_size[nShape].Add(fValue); break; case 1: fValue = 1.0F; face_val[nShape].Add(uiFrames); mouth_size[nShape].Add(fValue); break; default: fValue = 1.0F; break; } uiFrames++; nCount++; } // 終了フレームは次の音素の開始。なので前の音素は 0.00 にしておく face_val[nShape].Add(uiFrames); mouth_size[nShape].Add(0.0F); } else { while (uiFrames < uiEndTimeFrame) { uiFrames++; } } // ここの uiFrames が終了フレーム uiEd = uiFrames; nShapePrev = nShape; ulULTime = ulULEndTime; } // 書き出し List <string> ss = new List <string>(); for (int i = 0; i < 6; i++) { string s = ""; switch (i) { case 0: s = "あ"; break; case 1: s = "い"; break; case 2: s = "う"; break; case 3: s = "え"; break; case 4: s = "お"; break; case 5: s = "ん"; break; } for (int j = 0; j < face_val[i].Count; j++) { ss.Add(s + "," + face_val[i][j] + "," + mouth_size[i][j]); } } // まばたきも入れよう // uiFrames 約10秒単位でまばたき (300)ごと 1秒30コマ uint uiFrame2 = 0; while (uiFrame2 < uiFrames) { int r = 30 * 8 + rnd.Next(120 + 1); // 8~12秒間隔 if (uiFrame2 + (uint)r < uiFrames) { ss.Add("まばたき," + (uiFrame2 + (uint)r + 0) + ",0"); ss.Add("まばたき," + (uiFrame2 + (uint)r + 25) + ",0.11"); ss.Add("まばたき," + (uiFrame2 + (uint)r + 30) + ",0.35"); ss.Add("まばたき," + (uiFrame2 + (uint)r + 35) + ",0.11"); ss.Add("まばたき," + (uiFrame2 + (uint)r + 60) + ",0"); } uiFrame2 += (uint)r; } sLines = ss.ToArray(); // VMD読み込み+書き出し // string sFile2 = sFile.Substring(0, sFile.Length - 4) + "_改.vmd"; VMD vmd = new VMD(); if (vmd.Load(sFile) == false) { MessageBox.Show(sFile + " を読み込めません。", APP_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // モーフの中に "_DUMMY_1","_DUMMY_2" があるか int n1 = -1, n2 = -1; for (int i = 0; i < (int)vmd.uiSkinCount; i++) { string s = vmd.clsSkin[i].sSkinName; if (s == "_DUMMY_1") { n1 = i; } if (s == "_DUMMY_2") { n2 = i; } } VMD_SKIN[] newSkin = null; if (n1 >= 0 && n2 >= 0) { newSkin = new VMD_SKIN[vmd.uiSkinCount - (n2 - n1 + 1) + sLines.Length + 2]; } else { newSkin = new VMD_SKIN[vmd.uiSkinCount + sLines.Length + 2]; } int nPtr = 0; for (int i = 0; i < n1; i++) { newSkin[nPtr] = new VMD_SKIN(); newSkin[nPtr].SkinName = vmd.clsSkin[i].SkinName; newSkin[nPtr].FrameNo = vmd.clsSkin[i].FrameNo; newSkin[nPtr].Weight = vmd.clsSkin[i].Weight; nPtr++; } for (int i = n2 + 1; i < (int)vmd.uiSkinCount; i++) { newSkin[nPtr] = new VMD_SKIN(); newSkin[nPtr].SkinName = vmd.clsSkin[i].SkinName; newSkin[nPtr].FrameNo = vmd.clsSkin[i].FrameNo; newSkin[nPtr].Weight = vmd.clsSkin[i].Weight; nPtr++; } // 追加分 byte[] bt = null; newSkin[nPtr] = new VMD_SKIN(); bt = Encoding.GetEncoding("Shift_JIS").GetBytes("_DUMMY_1"); for (int i = 0; i < bt.Length; i++) { newSkin[nPtr].SkinName[i] = bt[i]; } newSkin[nPtr].FrameNo = 0; newSkin[nPtr].Weight = 0; nPtr++; for (int i = 0; i < sLines.Length; i++) { newSkin[nPtr] = new VMD_SKIN(); string s = sLines[i]; string[] sv = s.Split(','); // "まばたき" "0" "1.0" bt = Encoding.GetEncoding("Shift_JIS").GetBytes(sv[0]); for (int j = 0; j < bt.Length; j++) { newSkin[nPtr].SkinName[j] = bt[j]; } newSkin[nPtr].FrameNo = UInt32.Parse(sv[1]); newSkin[nPtr].Weight = Single.Parse(sv[2]); nPtr++; } newSkin[nPtr] = new VMD_SKIN(); bt = Encoding.GetEncoding("Shift_JIS").GetBytes("_DUMMY_2"); for (int i = 0; i < bt.Length; i++) { newSkin[nPtr].SkinName[i] = bt[i]; } newSkin[nPtr].FrameNo = 0; newSkin[nPtr].Weight = 0; vmd.uiSkinCount = (uint)newSkin.Length; vmd.clsSkin = newSkin; if (vmd.Save(sFile2, checkBox3.Checked) == false) { MessageBox.Show(sFile2 + " の書き出しに失敗しました。", APP_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } else { MessageBox.Show(sFile2 + " を書き出しました。", APP_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Information); } // CSV更新 // string sCSVFile = sFile.Substring(0, sFile.Length - 4) + "_改.csv"; string[] sLines3 = vmd.list.ToArray(); File.WriteAllLines(sCSVFile, sLines3, Encoding.Default); // 連結.wav作成 if (checkBox1.Checked == false) { return; } List <int> anSSound = new List <int>(); List <int> anSSoundSize = new List <int>(); string[] sLAB_FILES = Directory.GetFiles(sLAB_Folder, "*.lab"); int nSize = 0, nID = -1; for (int i = 0; i < sLAB_FILES.Length; i++) { string sWAVFile = sLAB_FILES[i].Substring(0, sLAB_FILES[i].Length - 4) + ".wav"; // if (sWAVFile.IndexOf("結合wav_") >= 0) continue; nID = DX.LoadSoftSound(sWAVFile); if (nID == -1) { MessageBox.Show(sWAVFile + " の読み込みでエラーが発生しました。中止します。", APP_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); DX.InitSoftSound(); return; } int ch, bps, rt, f; DX.GetSoftSoundFormat(nID, out ch, out bps, out rt, out f); if (!(ch == 1 && bps == 16 && rt == 48000)) { MessageBox.Show(sWAVFile + " はデータフォーマットが異なります。中止します。", APP_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); DX.InitSoftSound(); return; } int n = DX.GetSoftSoundSampleNum(nID); // 1ch, 16bit, 48000Hz ... 1秒間に 48000*2*1byte float ff1 = (float)n / 48000.0F; // WAVEファイルから取得秒数 float ff2 = 0.0F; if (i == 0) { ff2 = (float)((double)(listSentenceTime[0] / 10000000.0)); // 3.6999984 --> 3699.984 +0.999 } else { ff2 = (float)((double)((listSentenceTime[i] - listSentenceTime[i - 1]) / 10000000.0)); // 3.6999984 --> 3699.984 +0.999 } n = (int)(ff2 * 48000.0F); anSSoundSize.Add(n); nSize += n; anSSound.Add(nID); } nSize = (int)((double)(ulULTime * 48000) / 10000000.0); if (nSize <= 0) { MessageBox.Show("書き込むデータサイズが小さすぎます。終了します。", APP_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (nSize > 3600 * 48000 * 10) // 10時間 { MessageBox.Show("書き込むデータサイズが大きすぎます。終了します。", APP_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } int nSSID = DX.MakeSoftSoundCustom(1, 16, 48000, nSize); // CeVIOの仕様 for (int i = 0; i < nSize; i++) // まず0で全埋め { DX.WriteSoftSoundData(nSSID, i, 0, 0); } nPtr = 0; int h = 0; for (int i = 0; i < sLAB_FILES.Length; i++) { // if (sWAV_FILES[i].IndexOf("結合wav_") >= 0) continue; nPtr = (int)((double)listStartTime[h] / 10000000.0 * 48000.0); nID = anSSound[h]; // 読み出すSoftSoundのID int n = DX.GetSoftSoundSampleNum(nID); // 1ch, 16bit, 48000Hz ... 1秒間に 48000*2*1byte for (int j = 0; j < n; j++) { int ch1, ch2, v = DX.ReadSoftSoundData(nID, j, out ch1, out ch2); int ch1Z, ch2Z; DX.ReadSoftSoundData(nSSID, nPtr, out ch1Z, out ch2Z); ch1 += ch1Z; ch2 += ch2Z; DX.WriteSoftSoundData(nSSID, nPtr, ch1, ch2); nPtr++; if (nPtr > nSize) { MessageBox.Show("書き込むデータサイズがバッファサイズより大きいため、途中までの内容でデータを書きだします。", APP_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Information); break; } } h++; } sFile = sLAB_Folder + "結合wav_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".wav"; if (DX.SaveSoftSound(nSSID, sFile) == 0) { MessageBox.Show(sFile + " を作成しました。", APP_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show(sFile + " の作成中にエラーが発生しました。", APP_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } DX.InitSoftSound(); }