ぬの部屋(仮)
nu-no-he-ya
  •    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
           
  • gluLookAtの自前実装

    以下の式をそのまま実装する。

    https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluLookAt.xml

     

    プログラム本体

    #include <gl/GLU.h>
    
    #pragma comment(lib,"glu32.lib")
    
    #pragma warning(disable:4996)
    
    //! @brief IxJ行列の i,j の要素にアクセスする
     //! @param [in] i 行番号
     //! @param [in] j 列番号
     //! @param [in] I 行数
    inline int matijI(const int i, const int j, const int I) {
      return i + I * j;
    }
    //! @brief IxJ行列 × JxK行列 の乗算関数
    //https://suzulang.com/cpp-multmatrix44/
    //! @param [out] C Cik 計算結果格納先
    //! @param [in] A Aijの行列
    //! @param [in] B Bjkの行列
    //! @param [in] I Aの行列の行数
    //! @param [in] J Aの行列の列数
    //! @param [in] K Bの行列の列数
    //! @return C
    template<
      typename real_tC,
      typename real_tA,
      typename real_tB>
    real_tC* mult_matrixIJK(real_tC* C, const real_tA* A, const real_tB* B, const int I, const int J, const int K) {
    
      for (int i = 0; i < I; i++)
        for (int k = 0; k < K; k++) {
          C[matijI(i, k, I)] = 0.0;
          for (int j = 0; j < J; j++) {
            C[matijI(i, k, I)] += A[matijI(i, j, I)] * B[matijI(j, k, J)];
          }
        }
    
      return C;
    }
    //! @brief 4x4行列の行列の積を計算する
    //! @param [out] C 結果の格納先
    //! @param [in] A 行列A
    //! @param [in] B 行列B
    //! @return Cへのポインタ
    template<
      typename real_tC,
      typename real_tA,
      typename real_tB>
    real_tC* mult_matrix44(
        real_tC* C,
        const real_tA* A,
        const real_tB* B){
      return mult_matrixIJK(C, A, B, 4, 4, 4);
    }
    //! @brief 移動行列を作成する
    //! @param [out] m 結果の格納先
    //! @param [in] x ベクトルのx成分
    //! @param [in] y ベクトルのy成分
    //! @param [in] z ベクトルのz成分
    //! @return なし
    template<typename real_t>
    void mytranslate(
      real_t* m,
      real_t x,
      real_t y,
      real_t z
    ) {
      m[0] = 1.0;
      m[1] = 0.0;
      m[2] = 0.0;
      m[3] = 0.0;
    
      m[4] = 0.0;
      m[5] = 1.0;
      m[6] = 0.0;
      m[7] = 0.0;
    
      m[8] = 0.0;
      m[9] = 0.0;
      m[10] = 1.0;
      m[11] = 0.0;
    
      m[12] = x;
      m[13] = y;
      m[14] = z;
      m[15] = 1.0;
    
    }
    //! @brief 単位行列を作成する
    //! @param [out] m 結果の格納先
    //! @return なし
    template<typename real_t>
    inline void loadidentity3(real_t* m){
      m[0] = 1.0;
      m[1] = 0.0;
      m[2] = 0.0;
      m[3] = 0.0;
    
      m[4] = 0.0;
      m[5] = 1.0;
      m[6] = 0.0;
      m[7] = 0.0;
    
      m[8] = 0.0;
      m[9] = 0.0;
      m[10] = 1.0;
      m[11] = 0.0;
    
      m[12] = 0;
      m[13] = 0;
      m[14] = 0;
      m[15] = 1.0;
    }
    //! @brief 配列にNANが入っているか確認
    //! @param [in] m 評価する配列
    //! @param [in] count 行列の要素数
    template<typename real_t>
    bool chek_array_nan(const real_t* m, const size_t count) {
      for (size_t i = 0; i < count; i++) {
        if (isnan(m[i]) == true)
          return true;
      }
      return false;
    }
    template<typename real_t>
    inline void Outer3(real_t* const dvec, real_t const* const svec1, real_t const* const svec2) {
    
      const real_t& x1 = svec1[0];
      const real_t& y1 = svec1[1];
      const real_t& z1 = svec1[2];
      const real_t& x2 = svec2[0];
      const real_t& y2 = svec2[1];
      const real_t& z2 = svec2[2];
    
      dvec[0] = static_cast<real_t>(y1 * z2 - z1 * y2);
      dvec[1] = static_cast<real_t>(z1 * x2 - x1 * z2);
      dvec[2] = static_cast<real_t>(x1 * y2 - y1 * x2);
    }
    template<typename real_t>
    real_t Inner3(real_t const* const vec1, real_t const* const vec2) {
      const int X = 0;
      const int Y = 1;
      const int Z = 2;
      return ((vec1[X]) * (vec2[X]) + (vec1[Y]) * (vec2[Y]) + (vec1[Z]) * (vec2[Z]));
    }
    template<typename real_t>
    real_t Length3(const real_t* const vec) {
      const int X = 0;
      const int Y = 1;
      const int Z = 2;
      return sqrt(vec[X] * vec[X] + vec[Y] * vec[Y] + vec[Z] * vec[Z]);
    }
    template<typename real_t>
    bool Normalize3(real_t * const pV)
    {
    
      const int X = 0;
      const int Y = 1;
      const int Z = 2;
    
      real_t len;
      real_t& x = pV[X];
      real_t& y = pV[Y];
      real_t& z = pV[Z];
    
      len = static_cast<real_t>(sqrt(x * x + y * y + z * z));
    
      if (len < static_cast<real_t>(1e-6)) return false;
    
      len = static_cast<real_t>(1.0) / len;
      x *= len;
      y *= len;
      z *= len;
    
      return true;
    }

    //! @brief gluLookAtの自前実装版 //! @param [out] M 結果の格納先 //! @param [out] eyeX カメラ位置 //! @param [out] eyeY カメラ位置 //! @param [out] eyeZ カメラ位置 //! @param [out] centerX //! @param [out] centerY //! @param [out] centerZ //! @param [out] upX //! @param [out] upY //! @param [out] upZ //! @return なし
    void
    myglulookat( GLdouble* M, GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, GLdouble centerX, GLdouble centerY, GLdouble centerZ, GLdouble upX, GLdouble upY, GLdouble upZ) { GLdouble f[3] = { centerX - eyeX, centerY - eyeY, centerZ - eyeZ }; Normalize3(f); GLdouble UP[3] = {upX,upY,upZ}; Normalize3(UP); GLdouble s[3]; Outer3(s, f, UP); Normalize3(s); GLdouble u[3]; Outer3(u, s, f); GLdouble M0[16]; M0[ 0] = s[0]; M0[ 1] = u[0]; M0[ 2] = -f[0]; M0[ 3] = 0; M0[ 4] = s[1]; M0[ 5] = u[1]; M0[ 6] = -f[1]; M0[ 7] = 0; M0[ 8] = s[2]; M0[ 9] = u[2]; M0[10] = -f[2]; M0[11] = 0; M0[12] = 0; M0[13] = 0; M0[14] = 0; M0[15] = 1; ///////////////////////////// ///////////////////////////// GLdouble E[16]; mytranslate(E, -eyeX, -eyeY, -eyeZ); mult_matrix44(M, M0, E); if (chek_array_nan(M, 16) == true) loadidentity3(M); }

    テスト用コード

    void test() {
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
    
      GLdouble ex = (rand() % 1000) / 1000.0 - 0.5;
      GLdouble ey = (rand() % 1000) / 1000.0 - 0.5;
      GLdouble ez = (rand() % 1000) / 1000.0 - 0.5;
      GLdouble cx = (rand() % 1000) / 1000.0 - 0.5;
      GLdouble cy = (rand() % 1000) / 1000.0 - 0.5;
      GLdouble cz = (rand() % 1000) / 1000.0 - 0.5;
      GLdouble ux = (rand() % 1000) / 1000.0 - 0.5;
      GLdouble uy = (rand() % 1000) / 1000.0 - 0.5;
      GLdouble uz = (rand() % 1000) / 1000.0 - 0.5;
      GLdouble M0[16];
      gluLookAt(ex, ey, ez, cx, cy, cz, ux, uy, uz);
      glGetDoublev(GL_MODELVIEW_MATRIX, M0);
      GLdouble M1[16];
      myglulookat(
        M1,
        ex, ey, ez,
        cx, cy, cz,
        ux, uy, uz);
      puts("------------------------");
      for (size_t i = 0; i < 16; i++) {
        printf("[%d] %lf\n", i, M0[i] - M1[i]);
      }
    
    }
    

    実行結果

    [0] -0.000000
    [1] 0.000000
    [2] -0.000000
    [3] 0.000000
    [4] -0.000000
    [5] 0.000000
    [6] -0.000000
    [7] 0.000000
    [8] -0.000000
    [9] -0.000000
    [10] 0.000000
    [11] 0.000000
    [12] 0.000000
    [13] 0.000000
    [14] -0.000000
    [15] 0.000000