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;
    }
Пример #3
0
        // 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();
        }