ぬの部屋(仮)
nu-no-he-ya
  •  123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28      
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
    1234567
    891011121314
    15161718192021
    22232425262728
           
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
         12
    3456789
    10111213141516
    17181920212223
    242526272829 
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
        123
    45678910
    11121314151617
    18192021222324
    25262728   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    15161718192021
    293031    
           
         12
    3456789
    10111213141516
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    30      
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
       1234
    567891011
    12131415161718
    19202122232425
    2627282930  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728     
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
        123
    45678910
    11121314151617
    18192021222324
    252627282930 
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
     123456
    78910111213
    14151617181920
    21222324252627
    28293031   
           
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
     123456
    78910111213
    14151617181920
    21222324252627
    282930    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31      
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
      12345
    6789101112
    13141516171819
    20212223242526
    27282930   
           
          1
    2345678
    9101112131415
    16171819202122
    23242526272829
    3031     
          1
    2345678
    9101112131415
    16171819202122
    232425262728 
           
       1234
    567891011
    12131415161718
    19202122232425
    262728293031 
           
    1234567
    891011121314
    15161718192021
    22232425262728
    293031    
           
         12
    3456789
    10111213141516
    17181920212223
    24252627282930
           
      12345
    6789101112
    13141516171819
    20212223242526
    2728293031  
           
    1234567
    891011121314
    15161718192021
    22232425262728
    2930     
           
        123
    45678910
    11121314151617
    18192021222324
    25262728293031
           
  • ICUライブラリのutf16.hで定義されているU16系マクロの実例をいくつか U16_NEXT_UNSAFE

    U16_NEXT_UNSAFEを使ってutf16文字列を一文字ずつ処理する。

    #include <cstdio>
    
    #pragma warning(disable:4996)
    
    #include <unicode/utf16.h>
    
    #include <locale>
    int main()
    {
      std::setlocale(LC_CTYPE, "");
    
      const char16_t* str = u"い👨‍👦は";
    
      const char16_t* p = str;
      int i = 0;
      while (p[i]) {
    
        bool bs = U16_IS_SURROGATE(p[i]);//サロゲートペアかどうか
    
        int iback = i;
        char32_t u32c;
        U16_NEXT_UNSAFE(p, i,u32c);
    
        if (bs==false) {
          if (p[iback] == 0x200d) {//サロゲートペアではないが、結合文字
            printf("[%x] Combine string\n", p[iback]);
          }
          else {//一文字
            printf("%s [%x] (%lc) -> %x\n",
              " true ",
              p[iback],
              p[iback],
              u32c
            );
          }
        }
        else {//サロゲートペア
          printf("%s [%x,%x] -> %x ",
            " false",
            U16_LEAD(u32c),//u32からサロゲートペアを求める
            U16_TRAIL(u32c),
            u32c
          );
          printf(" * [%x,%x]", p[iback], p[iback + 1]);//u16のサロゲートペアを表示
          puts("");
        }
      }
    
    }
    
    true [3044] (い) -> 3044
    false [d83d,dc68] -> 1f468 * [d83d,dc68]
    [200d] Combine string
    false [d83d,dc66] -> 1f466 * [d83d,dc66]
    true [306f] (は) -> 306f

    [雑談] DreamStudioを試した感想

    DreamStudioは今話題の、、流行りのAIでキーワードから画像を生成するサービスで、現時点でかなり性能の高いものらしい。人類の歴史が動く!!と興奮する者さえいる。

    AIを作る場合、今主流のDeepLearningなんかだと、たくさん教えるほど精度が上がる。資料が少ないものほど精度が落ちる。つまり資料(ネット上に落ちていた画像)の量と質で結果に偏りが生じるはず。

    使い方

    利用にはユーザー登録が必要。

    https://beta.dreamstudio.ai/

    登録出来たらログインし、画面下のテキストフィールドにキーワードを入力して[Dream]ボタンを押す。

    使ってみた感想

    率直に言うと、

    1.景観、植物などはそのまま使っても問題ないほど優れたものが出てくる。

    2.動物などは時々はずれが出る。

    3.人間は結構気持ち悪いのが生成される。

    4.開発者の文化圏の影響がなんとなくわかる

    tree

    まずは「tree」。かなり綺麗。大体はそのまま使ってしまえそうなものが出てくる。

    owl

    「owl」フクロウについて詳しくないのでどこかおかしくてもよくわからない。

    woman blonde

    「woman blonde」ここまで整ったものが出来上がる確率は低いが、それでも結構きれいなものが出てくる。というかなんか見たことある気がする。

    ただし次で言うように、日本人の脳はブロンドの見分けがそんなに得意ではないので、おかしくても気づいていないだけかもしれない。

    woman asian

    「woman asian」blondeとの差が傾向として出てしまう…。

    日本人であれば、脳がアジア系の顔の見分けに最適化されているはずなので、どうしても粗が見えやすくなるはず。

    man asian

    「man asian」男性で整った顔が出る確率は結構低い。つまりそういうことorz。

    Manju

    「Manju」饅頭。たこ焼きの間違いでは。

    Hamburger

    「Hamburger」さすがにこいつの精度は高い。

    onigiri

    「onigiri」どう見ても巻き寿司。

    rice ball

    「rice ball」イメージと違う。嘘は言ってない、みたいな結果になる。

    butter

    「butter」バターの精度は高い。

    所感

    単語だけでやってみたが、多分ある程度長い文で出したほうがずっと面白いものができる。

    「christmas night tree in snow」

    ただし、人間、動物、昆虫などはメンタルが強くないならお勧めできない。あたりを引くまでに何度も生成を繰り返すことになるが悪夢になりかねない。

    あと集合体恐怖症への配慮はない。これは本当にきつい。

    雑談

    著者は今ゼノブレイド3をやっていてガチで記事を書く時間がないのだがそもそもネタがなくてやばい。

    [メモ] Blender 3でMesh to VolumeとVolume to Mesh

    Mesh to Volume

    まずはモデルを読み込む。

    [Shift+A]→[Volume]→[Empty] でボリュームを追加。

    モディファイアの設定で、Objectにモデルを選択する。

    Volume to Mesh

    上記方法でボリュームを作った後、これをメッシュ化する。

    [Shift+A]→[Mesh]→[Cube]で立方体を追加する。

    Cubeに対してVolume to Meshモディファイアを適用。

    ObjectにVolumeを選択し、Applyする。

    UPDATED Realistic Procedural Starfield Blender 2.9 を試す

    このチュートリアルは解像度が低いこともあり正確に数字が取れない(し、取れてもたいていうまくいかない)のでざっくりとやってみる。

    まず以下が基本となる。他はすべて、以下のコピーとなる。

    上をコピーして、色を変える。さらにMappingのLocationを6.5にする。

    そしてそれをAdd Shaderする。

    上記二つをコピーし、計四つにする。Voronoi Textureのsizeを60に設定。他はいじらない。

    Voronoiのscaleが60のものを一つだけコピーし、Locationを変更。あと色を変更。

    上記をコピーし三つ作成する。scaleを上から120,180,320に設定。

    結果

    FTGLで改行する

    OpenGLの描画内にFreeType2で簡単に文字列を描画できるFTGLだが改行がやや面倒。

    概要

    FTGLのFTPixmapFontオブジェクトからBBoxメンバ関数を呼び出す。

    この関数はテキストを与えるとそのテキストのバウンディングボックスを返すので、これで一行の高さが分かる。

    ただし、このサイズは単位がピクセルらしいので、表示中のワールド座標系に変換してやる必要がある。

     

    #include <iostream>
    
    #include <Windows.h>
    #include <gl/GL.h>
    #include <gl/GLU.h>
    #include <gl/freeglut.h>
    
    #include <FTGL/ftgl.h>
    
    #pragma comment(lib,"opengl32.lib")
    #pragma comment(lib,"freeglut.lib")
    #pragma comment(lib,"ftgl.lib")
    
    //ウィンドウの幅と高さ
    int width, height;
    
    
    // FTGLを管理しやすくするクラス
    struct CFtglObject {
      const char* FONT_PATHNAME = "C:\\Windows\\Fonts\\msgothic.ttc";
      FTPixmapFont* g_pFont;
      unsigned long g_ulFontSize;  // フォントサイズ
    
      ~CFtglObject() {
        delete g_pFont;
      }
    
    
      // フォントの初期化
      void init(const unsigned long fontsize) {
    
        g_ulFontSize = fontsize;
    
        if (!g_pFont) {
          g_pFont = new FTPixmapFont(FONT_PATHNAME);
          if (g_pFont->Error()) {
            delete g_pFont;
            g_pFont = nullptr;
          }
          else {
            g_pFont->FaceSize(g_ulFontSize);
          }
        }
      }
    
      // FTGLで文字列を描画
      void print(const std::wstring& wstr, float x, float y) {
    
        if (g_pFont) {
          glRasterPos2f(x, y);
          g_pFont->Render(wstr.c_str());
        }
    
      }
      FTPixmapFont& get_font() { return *g_pFont; }
    };
    
    
          
    CFtglObject ftglo;
    
    //描画関数
    void disp(void) {
    
      glViewport(0, 0, width, height);
    
      glClearColor(0.2, 0.2, 0.2, 1);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glOrtho(-1, 1, -1, 1, 1, -1);
    
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
    
    
      glEnable(GL_CULL_FACE);
      double v = 0.7;
    
    
      glBegin(GL_QUADS);
      glColor3d(0, 0, 1);
      glVertex2d(-v, -v);
      glColor3d(1, 0, 1);
      glVertex2d(v, -v);
      glColor3d(1, 1, 1);
      glVertex2d(v, v);
      glColor3d(0, 1, 1);
      glVertex2d(-v, v);
      glEnd();
    
      glLineWidth(2);
      glBegin(GL_LINES);
      glColor3d(1, 1, 0);
      glVertex2d(-v, 0);
      glColor3d(1, 1, 1);
      glVertex2d(v, 0);
    
      glColor3d(1, 1, 0);
      glVertex2d(0, -v);
      glColor3d(1, 1, 1);
      glVertex2d(0, v);
      glEnd();
    
      /////////////////////////////////
      /////////////////////////////////
      /////////////////////////////////
    
      const wchar_t* text;
    
      text = L"いろはに";
      ftglo.print(text, 0, 0);
      FTBBox bbox = ftglo.get_font().BBox(text);
      float BoxHeightPixel = bbox.Upper().Yf() - bbox.Lower().Yf();//文字列の高さを求める
    
      // BoxHeightの単位がピクセルらしいので、これを現在の文字幅に修正する。
      // 現在は -1 ~ 1の範囲を0~height-1ピクセルで表示しているので、
      float ratioh = 2.f/height;
      float pixelh = ratioh * BoxHeightPixel;
    
      text = L"ほへと";
      ftglo.print(text, 0, pixelh);
    
      glFlush();
    }
    
    //ウィンドウサイズの変化時に呼び出される
    void reshape(int w, int h) {
      width = w; height = h;
    
      disp();
    }
    
    
    
    //エントリポイント
    int main(int argc, char** argv)
    {
      glutInit(&argc, argv);
      glutInitWindowPosition(100, 50);
      glutInitWindowSize(500, 500);
      glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
    
      ftglo.init(32);
    
      glutCreateWindow("sample");
      glutDisplayFunc(disp);
      glutReshapeFunc(reshape);
      glutMainLoop();
    
      return 0;
    }
    

    二次元の三角形の内外判定で誤差を指定する

    二次元の、ある点が三角形の内側にあるか外側にあるかを判定するコードを以前紹介したのだが、点が三角形の境界ぎりぎりにある場合問題を起こすことがある。

    判定方法はs,tを計算し、それが0~1に収まっていれば内側と判断するので、この範囲を0.1~0.9などに変更すると誤差を指定することができるようになる。

    誤差指定版

    //https://suzulang.com/2d-triangle-in-out-check/
    template<typename real_t>
    inline bool isInTheTriangle(
      real_t px, real_t py,
      real_t p0x, real_t p0y,
      real_t p1x, real_t p1y,
      real_t p2x, real_t p2y
    ) {
      real_t Area = 0.5 * (-p1y * p2x + p0y * (-p1x + p2x) + p0x * (p1y - p2y) + p1x * p2y);
    
      real_t s = 1.0 / (2.0 * Area) * (p0y * p2x - p0x * p2y + (p2y - p0y) * px + (p0x - p2x) * py);
      real_t t = 1.0 / (2.0 * Area) * (p0x * p1y - p0y * p1x + (p0y - p1y) * px + (p1x - p0x) * py);
    
    
      real_t e = 0.05;
      real_t tmin = 0.0 - e;
      real_t tmax = 1.0 + e;
    
      if (
    
        (tmin < s) && (s < tmax) &&
        (tmin < t) && (t < tmax) &&
        (tmin < (1 - s - t)) &&
        ((1 - s - t) < tmax)
    
        ) {
        return true;
      }
      else {
        return false;
      }
    }
    

    呼び出し例

      auto p0 = glm::vec3(-0.913841, 0.999223, 0);
      auto p1 = glm::vec3(0.032665, -0.787554, 0);
      auto p2 = glm::vec3(0.853559, 0.974719, 0);
    
      glBegin(GL_TRIANGLES);
      glVertex2fv(glm::value_ptr(p0));
      glVertex2fv(glm::value_ptr(p1));
      glVertex2fv(glm::value_ptr(p2));
      glEnd();
    
      glPointSize(5);
      glBegin(GL_POINTS);
      for (float x = -2.f; x < 2.f; x += 0.1f) {
          for (float y = -2.f; y < 2.f; y += 0.1f) {
    
        bool hit = isInTheTriangle(
            x, y,
            p0.x, p0.y,
            p1.x, p1.y,
            p2.x, p2.y
        );
    
        if (hit)
            glColor3d(1, 0, 0);
        else
            glColor3d(0.7, 0.7, 0.7);
    
        glVertex2f(x,y);
    
    
          }
      }
      glEnd();
    

    ICUライブラリのutf16.hで定義されているU16系マクロの実例をいくつか

    ICUライブラリでのutf16の扱い方を調べていてマクロがあることを知ったのでいくつか列挙しておきたい。

    参考

    ICU 71.1:utf16.h File Reference

    https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/utf16_8h.html

    マクロの例

    U16_GET_UNSAFE

    utf16文字からコードポイントを得る

    #pragma warning(disable:4996)
    
    #include <iostream>
    
    #include <unicode/utf16.h>
    
    int main()
    {
      const char16_t* u16c = u"あいう";
    
      char32_t u32c;
    
      FILE* fp = fopen("test.txt", "w");
      U16_GET_UNSAFE(u16c, 0, u32c);
      fwrite(&u32c, 4, 1, fp);
    
      U16_GET_UNSAFE(u16c, 2, u32c);
      fwrite(&u32c, 4, 1, fp);
    
    
      fclose(fp);
    }
    

    U16_LENGTH

    与えられたコードポイントが、utf16で何要素になるかを返す。返却値は 1 または 2。

        std::u32string cc;
        // U16_LENGTH 与えられたu32がu16で何要素になるか
        int len;
        cc = U"a";
        len = U16_LENGTH(cc[0]);
        printf("--- %d\n", len); // 1 utf16一文字
        cc = U"あ";
        len = U16_LENGTH(cc[0]);
        printf("--- %d\n", len); // 1 utf16一文字
        cc = U"👨‍👩‍👧‍👦";
        len = U16_LENGTH(cc[0]);
        printf("--- %d\n", len); // 2 結合文字の最初の一文字
        cc = U"𠀋";
        len = U16_LENGTH(cc[0]);
        printf("--- %d\n", len); // 2 サロゲートペア
        cc = U"𠀋𡚴";
        len = U16_LENGTH(cc[0]);
        printf("--- %d\n", len); // 2 最初の一文字がサロゲートペア
    

    U16_IS_SINGLE , U16_IS_SURROGATE , U16_IS_SURROGATE_LEAD , U16_IS_SURROGATE_TRAIL

    U16_IS_SINGLE(c)  utf16文字cが、サロゲートペアでなければtrue。

    U16_IS_SURROGATE(c) utf16文字cが、サロゲートペアであればtrue。

    U16_IS_SURROGATE_LEAD(c) utf16文字cが、上位サロゲートであればtrue。ただし、cがサロゲートペアであることが分かっている必要がある。

    U16_IS_SURROGATE_TRAIL(c) utf16文字cが、下位サロゲートであればtrue。ただし、cがサロゲートペアであることが分かっている必要がある。


    U16_IS_SINGLE U16_IS_SURROGATE U16_IS_SURROGATE_LEAD U16_IS_SURROGATE_TRAIL
    u”a”[0] true false true false
    u”あ”[0] true false true false
    u”👨‍👩‍👧‍👦”[0] false true true false
    u”&#x2000B”[0] false true true false
    u”a”[1] true false true false
    u”あ”[1] true false true false
    u”👨‍👩‍👧‍👦”[1] false true false true
    u”&#x2000B”[1] false true false true

    U16_LEAD , U16_TRIAL

    コードポイントから上位サロゲート(lead)、下位サロゲート(trail)を算出する

    #pragma warning(disable:4996)
    #include <iostream>
    #include <unicode/utf16.h>
    int main()
    {
      // UTF32
      //char32_t u32c = U'あ';
      char32_t u32c = U'𠀋';
      
      // char32->char16に変換したとき何文字になるかをチェック
      if (U16_LENGTH(u32c) == 2){
    
        // utf16に変換したときサロゲートペアになる場合は上下サロゲートを算出
        char16_t aa[2];
        aa[0] = U16_LEAD(u32c);  // 上位サロゲート
        aa[1] = U16_TRAIL(u32c); // 下位サロゲート
        // ファイル出力
        FILE* fp = fopen("test.txt", "w");
        fwrite(aa, 2, 2, fp);
        fclose(fp);

    } else {
        //サロゲートペアに変換する必要がなければコードユニット値がutf16文字
    
    char16_t u16 = char16_t(u32c); // ファイル出力 FILE* fp = fopen("test.txt", "w"); fwrite(&u16, 2, 1, fp); fclose(fp);

    } }

    アマレココ+AMV4で録画した動画の編集について(+AviUtl)

    前置き

    まず私は動画編集は全く詳しくない。あと今回は半分雑談。

    アマレココ

    http://www.amarectv.com/download_amarecco4.htm

    AMV4

    http://www.amarectv.com/buy.htm

    症状と妥協先

    アマレココはH.264やUtVideoコーデックで録画もできるが、AMV4(有料)をインストールしておかないとロゴが入る。だからAMV4の購入は必須。

    ただしAMV4は「入れてさえおけば」いいのでH.264などが使ったほうが動画編集ソフトで読み込めて勝手が良い。AMV4に対応している編集ソフトは多くない(知らない)。

    だから私はずっと「アマレココ」 + 「AMV4」 + 「x264VFW」でデスクトップをキャプチャしていたのだが、PCを初期化したので環境を整えなおして録画してみたところうまく動作しなくなった。

    なお動画サイズを640×480などのサイズにするとうまくいくので多分走査線的なものがずれている。

    AMV4→AviUtl(+x264guiEx)

    H.264を使わずにAMV4で録画する。

    まずAMV4に切り替える

    AMV4で録画してからH.264に変換するためにAviUtlを使うが、x264guiExを導入しなければいけない。

    AviUtl

    http://spring-fragrance.mints.ne.jp/aviutl/

    x264guiEx

    https://github.com/rigaya/x264guiEx/releases

    x264guiExを導入すればH.264に変換できる。

    glm::closestPointOnLine

    glmの、ある点に最も近い線分上の点を求める関数。

    公式マニュアル:

    https://glm.g-truc.net/0.9.9/api/a00310.html

    計算・描画

    static float z = 3.f;
    {
      z -= 0.1;
    
      glm::vec3 p(1, z, 0); //どこか頂点
      glm::vec3 a(0, -2, 0);//線分の始点
      glm::vec3 b(0, 2, 0); //線分の終点
    
      // 点に最も近い直線上の点を求めるのに必要
      // #include <glm/gtx/closest_point.hpp>
      glm::vec3 kk = glm::closestPointOnLine(p, a, b);
    
      glLineWidth(3);//線分
      glBegin(GL_LINES);
      glVertex3fv(glm::value_ptr(a));
      glVertex3fv(glm::value_ptr(b));
      glEnd();
    
      glPointSize(7);//どこか頂点
      glColor3d(1, 0, 0);
      glBegin(GL_POINTS);
      glVertex3fv(glm::value_ptr(p));
      glEnd();
    
      glPointSize(7);//線分上の点
      glColor3d(0, 1, 0);
      glBegin(GL_POINTS);
      glVertex3fv(glm::value_ptr(kk));
      glEnd();
    }
    

    Blender Cyclesでマテリアルにwireframeを設定するPythonスクリプトを作成

    import bpy
    
    # マテリアルにワイヤフレームを追加する
    def set_wireframe(mat):
    
        nodetree = mat.node_tree
    
        nodes = nodetree.nodes
    
        MaterialOutput = nodes['Material Output']
    
        # MaterialOutputにつながっているノードを取得。
        # backup -- (wireframe) -- MaterialOutput と挟み込む
        backup = MaterialOutput.inputs[0].links[0].from_node
    
        # ワイヤフレームに必要なノードを追加
        wireframe = nodes.new('ShaderNodeWireframe')
        diffuse = nodes.new('ShaderNodeBsdfDiffuse')
        mixnode = nodes.new('ShaderNodeMixShader')
    
        # ワイヤフレームの色を黒に設定
        diffuse.inputs["Color"].default_value[0] =0
        diffuse.inputs["Color"].default_value[1] =0
        diffuse.inputs["Color"].default_value[2] =0
    
        # mix , diffuse , wireframe の三つをつなげる
        nodetree.links.new(wireframe.outputs[0],mixnode.inputs[0])
        nodetree.links.new(diffuse.outputs[0],mixnode.inputs[2])
        # mixにこれまで指定されていたノードをつなぐ
        nodetree.links.new(backup.outputs[0],mixnode.inputs[1])
    
        # mixをMaterialOutputへ繋げる
        nodetree.links.new(mixnode.outputs[0],MaterialOutput.inputs[0])
    
        # 位置調整
        
        # MaterialOutputを少し右へずらし、その位置にmixを入れ、同じ位置にdiffuseとwireframeを入れる
        MaterialOutput.location.x = MaterialOutput.location.x + 200
        mixnode.location.x = MaterialOutput.location.x - 200
        wireframe.location.x = mixnode.location.x
        diffuse.location.x =  mixnode.location.x
    
        # mix,wireframe,diffuseの高さを変えてそれぞれ配置する
        mixnode.location.y = MaterialOutput.location.y
        wireframe.location.y = mixnode.location.y + 200
        diffuse.location.y = mixnode.location.y - 200
    
        # ワイヤフレームの線の太さを設定
        wireframe.inputs["Size"].default_value = 0.05
    
    
    set_wireframe(
        bpy.context.active_object.material_slots["Material"].material)