2017-10-12 12 views
0

私は、本体とそれに別の場所で「添付」する部分を含めて約7+の部分を持つオブジェクトを作成しました。私の目標はオブジェクト全体を回転させることです。私はオブジェクト全体を構築する前にglRotatef(angle, 0, 1, 0)を呼び出すことを試みましたが、翻訳にかかわらず、これが原点の周りに「すべて」回転するように思えます。次のコードは、本体自体を回転させ、付属部品を回転させる試みでした。マルチパートオブジェクトを回転させる

// glRotatef(angle, 0, 1, 0); //old way of rotating the object 

// body 
glPushMatrix(); 
    // movement 
    glTranslatef(subx, suby + y, subz); 
    //rotating the body itself 
    glRotatef(angle, 0, 1, 0); 
    // starting position of the body 
    glScalef(9.0, 1.75, 1.75); 
    glTranslatef(-subx, -suby, -subz); 
    glTranslatef(subx, suby, subz); 
    glutSolidSphere(1.0, 50, 50); 
glPopMatrix(); 

// attached part 
glPushMatrix(); 
    // movement 
    glTranslatef(rot1x, rot1y + y, rot1z); 
    // attempting to rotate the part while 'attached to' the body 
    glRotatef(angle, 0, 1, 0); 
    //placing the part on the object in starting position 
    glRotatef(rot1angle, rot1xrot, rot1yrot, rot1zrot); 
    glTranslatef(-rot1x, -rot1y, -rot1z); 
    glTranslatef(rot1x, rot1y, rot1z); 
    gluPartialDisk(gluNewQuadric(), 0, 1, 50, 1, 0, 100.0); 
glPopMatrix(); 

私は、オブジェクトの身体に適切に回転させるように、オブジェクトの小さな部品のために発生する必要があるもののまわりで私の頭を包むように見えることはできません(固定点?)。

答えて

1

マトリックススタック上での演算は、相互に基づいています。各操作の参照システムは、現在の変換です。束のオブジェクトで構成されるオブジェクトを変換する場合は、各サブオブジェクトの相対位置をオブジェクトユニオンの参照位置に知る必要があります。次に、次の手順を実行する必要があります。

  • 各オブジェクトを世界の共通の位置に移動します(glTranslate)。
  • glTranslateのドキュメントを参照してくださいオブジェクト組合

// dynamic position in the world 
float refPosX, refPosY, refPosZ; 

// dynamic orientation 
float angle; 

// constant positions of the sub object relative to the object union 
float subPosX[], subPosY[], subPosZ[]; 


for (int i = 0 i < noOfObj, ++i) // for each object 
{ 
    glPushMatrix(); 
    glTranslatef(refPosX, refPosY, refPosZ); 
    glRotatef(angle, 0, 1, 0); 
    glTranslatef(subPosX[i], subPosY[i], subPosZ[i]); 
    glScalef(9.0, 1.75, 1.75); 

    ..... // draw the object here 

    glPopMatrix(); 
} 


におけるその相対位置に移動

  • glRotate)各オブジェクトをオブジェクトを配向:

    glTranslate pro x y zによって翻訳されます。現在の行列は(glMatrixModeを参照)、製品は現在の行列を交換すると、この変換行列を乗じ

    glRotateの文書を参照され:

    glRotate周り角度の回転を生成しますベクターx y z。現在の行列が(glMatrixModeを参照)、現在の行列を置き換える製品と回転行列で


    注意を乗算され、平行移動行列は次のようになります。

    Matrix4x4 translate; 
    
    translate[0] : (1, 0, 0, 0) 
    translate[1] : (0, 1, 0, 0) 
    translate[2] : (0, 0, 1, 0) 
    translate[3] : (tx, ty, tz, 1) 
    

    そして周りの回転行列をY軸は、次のようになります。

    Matrix4x4 rotate; 
    float  angle; 
    
    rotate[0] : (cos(angle), 0, sin(angle), 0) 
    rotate[1] : (0,   1, 0,   0) 
    rotate[2] : (-sin(angle), 0, cos(angle), 0) 
    rotate[3] : (0,   0, 0,   1) 
    

    行列乗算は、次のように動作します。

    Matrix4x4 A, B, C; 
    
    // C = A * B 
    for (int k = 0; k < 4; ++ k) 
        for (int l = 0; l < 4; ++ l) 
         C[k][l] = A[0][l] * B[k][0] + A[1][l] * B[k][1] + A[2][l] * B[k][2] + A[3][l] * B[k][3]; 
    


    translate * rotateの結果はこれです:

    model[0] : (cos(angle), 0, sin(angle), 0) 
    model[1] : (0,   1, 0,   0) 
    model[2] : (-sin(angle), 0, cos(angle), 0) 
    model[3] : (tx,   ty, tz,   1) 
    

    translate * rotate


    注、rotate * translateの結果は次のようになります

    model[0] : (cos(angle),      0, sin(angle),      0) 
    model[1] : (0,        1, 0,        0) 
    model[2] : (-sin(angle),     0, cos(angle),      0) 
    model[3] : (cos(angle)*tx - sin(angle)*tx, ty, sin(angle)*tz + cos(angle)*tz, 1) 
    

    rotate * translate

  • 2
    1. あなたはglMatrixMode通話だけGL_MODELVIEW(最後にアクティブに設定されている場合)、それは動作しますが、あなたのコードが長く成長したときに、あなたがこれを破ったと、突然かもしれない他の呼び出しを追加よりもを使用している場合

      が欠落していますあなたのコードは期待どおりに動作しません(そして非常にデバッグするのは難しいです)。したがって、コードの変換チャンクの前にglMatrixMode(GL_MODELVIEW);を追加する方が良いです。

    2. あなたは間違って

      行列があまりにも入れ子にする必要がありますので、あなたのオブジェクトがネストされているINGのpush/popです。つまり、オーナーパーツにアタッチされているパーツは、オーナーパーツマトリックスから始める必要があります。したがって、部品の階層構造(アセンブリ順序)を持つ必要がありますので、どの部品がどの部品にどこに取り付けられているかを知ることができます。 (numは、リストのサイズです)、それに接続され

      List<int> part[noOfObj]; 
      

      ので、任意のpart[i], i=<0,noOfObj-1>が持っている子供の部品part[i][0,1,2...,part[i].num-1]

      はそうあなたはどの部分に接続されている部品のリスト...のようなものを持っている必要があります。そして、part[0]が主要部分です。それは、物事を少し変更しますが、単純な再帰ができます:今すぐ

      void part_draw(int ix) // this is just recursion call used by the main function do not use it directly 
      { 
      glMatrixMode(GL_MODELVIEW); 
      glPushMatrix(); 
      glTranslatef(subPosX[ix], subPosY[ix], subPosZ[ix]); 
      
      glPushMatrix();   // this should not be here 
      glScalef(9.0, 1.75, 1.75); // this should not be here 
      ..... // draw the object ix here 
      glMatrixMode(GL_MODELVIEW);// this should not be here 
      glPopMatrix();    // this should not be here 
      
      for (int iy=0;iy<part[ix].num,iy++) 
          part_draw(part[ix][iy]); 
      
      glMatrixMode(GL_MODELVIEW); 
      glPopMatrix(); 
      } 
      
      void mesh_draw() // this is the main rendering routine which you should use 
      { 
      glMatrixMode(GL_MODELVIEW); 
      glPushMatrix(); 
      glTranslatef(refPosX, refPosX, refPosZ); 
      glRotatef(angle, 0, 1, 0); 
      
      part_draw(0); 
      
      glMatrixMode(GL_MODELVIEW); 
      glPopMatrix(); 
      } 
      

      subPosX/Y/Z位置が親部分にシステム座標なければならないことに注意してください。また、これは循環的にネストされたオブジェクト(ループ)のために無限ループにつながり、スタックオーバーフローを引き起こします。

    関連する問題