2015-04-15 190 views
0

我想用攪拌機制作簡單的3D機器人手臂。目前我可以導入obj文件和紋理,旋轉,平移和縮放。OpenGL簡單的3D機器人手臂

問題: 爲了簡化,機器人手臂將有3個部件,底座(圓筒旋轉)和兩個長方體。我沒有旋轉Cilinder和長方體的問題。但是這兩個長方體必須連接,我不知道如何去做。我可以使用簡單的正弦函數和餘弦函數來計算第一個長方體的位置,但是我不知道如何測量對象的長度。

第二個問題: 我可以將所有3個對象導出到一個obj文件中並稍後在openGL中進行分割嗎?

my_solution

+0

這似乎並沒有成爲一個「我寫的代碼,我有這個代碼的問題」問題,這幾乎使得它超出了這個特定SE網站的範圍。你可以試試blender.stackexchange.com –

+0

嘿,我幾年前也做過同樣的事情。我不會打擾做一個單一的文件。我分開導出所有部分,然後跟蹤旋轉。我做了一個試驗性的方法來找到數字的長度,但這隻需要做一次(我硬編碼)。在你的情況下,如果手很簡單,這不會太困難。[這是我最終的結果](https://www.youtube.com/watch?v=uJO5sLP_vKY&feature=plcp)。如果你有興趣,當我回家時我可以發佈我的代碼(現在真的需要運行)。 – Mewa

回答

0

你有沒有考慮索具的對象,你會一個人的手臂?這樣,這些對象全部鏈接起來,不會失去同步。然後將動畫作爲一個整體應用於鑽塔。更少的計算,更容易。

例子(從該網站其他頁面是有用的爲好): http://www.blender.org/api/htmlI/x7613.html http://www.blender.org/api/htmlI/x7891.html

參考: http://wiki.blender.org/index.php/Doc:2.6/Manual/Rigging

+0

對不起,但我正在考慮解決方案。您可以記住當前位置,並將旋轉設置位置設置爲0或更改乘法的順序。但我正在研究其他想法。假設我們有3個武器。我可以先旋轉第三個手臂,然後移動到他的位置,然後再次旋轉第三個手臂與第二個手臂的角度相同,然後移動到第二個位置,再次旋轉第三個手臂的角度與第一個手臂的角度相同,然後在xyz軸上移動。 – Szczepan

1

您還沒有迴應發表評論,但我想我會張貼此代碼反正。我寫這個來渲染OpenGL中的3D機器人手。我有用於所有手指和手的攪拌器模型文件(由其他人制作),我將它們分別導出到.obj文件。

最終結果可見here。如您所見,我還添加了使用鼠標更改視點的功能。我通過試錯法確定手指指骨的偏移量,但也許您可以按照here所述使用Blender找到各點之間的偏移量。我現在無法測試此功能,因爲我的工作計算機上沒有Blender。

下面的代碼描述了我實現這一點。我把它分解了,這樣我就可以寫出一些解釋,但將所有的部分按順序放置將產生我完整的功能,以便將一個手指附着在手上。

我的繪圖功能啓動爲:

double t_x, t_y, t_z; 
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // Clear screen and depth buffer 
glLoadIdentity(); 

// Set viewpoint: 
gluLookAt(eyex+3.0f, eyey+3.0f, eyez+3.0f, focusx, focusy, focusz, 0, 1, 0); 
glPushMatrix(); 

glRotatef(g_xRotation, 0,1,0); // Rotate with mouse (g_x and g_y are determined elsewhere) 
glRotatef(g_yRotation, 1,0,0); 

現在我們是在原點(旋轉,指示鼠標)成立,我們可以通過繪製手掌開始。不需要移位(它在原點)。

// DRAW PALM 
glColor3f(1.0f, 1.0f, 1.0f); // Use proper color - white 
palmHand -> draw(); 

手掌被渲染後,我們移動繪製第一根手指。翻譯中的1.87f是通過實驗確定的。這裏的價值也取決於我從Blender出口產品的質量,但一旦您出口一次,它不會改變。 (我實際上對我爲自己留下的相當自鳴得意的評論感到驚訝 - 這個代碼是幾年前的)。指骨僅圍繞一個軸旋轉,旋轉值(角度)存儲在f_p[]中。

// DRAW FINGER 1 
// CONSTANT: Move to first vertex 
glTranslatef(0.0f, 0.0f, 1.87f); 

glRotatef(f_p[0].theta, 0, 0, 1); // Do rotation for phalanx 1 with specified angle 
glColor3f(16.0f/255.0f, 78.0f/255.0f, 139.0f/255.0f); // Use proper color - blue 
phalanx1Hand -> draw(); 

// CONSTANT: Necessary adjustment because of model file offset (nobody's perfect, okay?) 
glTranslatef(0.0f, 0.03f, 0.0f); 

繪製第二(中間)方陣遵循相同的過程作爲一個底部,但它圍繞不同的軸線旋轉。

// CONSTANT: Move to second vertex 
glTranslatef(1.3f, 0.0f, 0.0f); 

glRotatef(f_p[1].theta, 0, 1, 0); // Do rotation for phalanx 2 with specified angle 
phalanx2Hand -> draw(); 

有沒有額外的方陣#2偏移,因爲我想,當我從攪拌機出口,我正確地列隊模型。

// CONSTANT: Rotate to third vertex 
glRotatef(-90.0f, 0, 1, 0); 

// CONSTANT: Move to third vertex 
glTranslatef(2.0f, 0.0f, 0.0f); 

glRotatef(f_p[2].theta, 0, 1, 0); // Do rotation for phalanx 3 with specified angle 
phalanx3Hand -> draw(); 

完成繪製單個手指。現在我們將所有的旋轉和翻譯都轉換回起始位置(因爲旋轉的方式太多了,您必須確保順序保持一致,否則您最終會到達其他地方並且手指都會變成全部在那個地方)。

// CONSTANT: Return to origin 
// Undo rotations and translations in proper order 
glRotatef((-1.0f*f_p[2].theta), 0, 1, 0); // Phalanx 3 rotation 
glTranslatef(-2.0f, 0.0f, 0.0f); // Phalanx 3 translation 
glRotatef(90.0f, 0, 1, 0); // Rotation to Phalanx 3 
glRotatef((-1.0f*f_p[1].theta), 0, 1, 0); // Phalanx 2 
glTranslatef(-1.3f, -0.03f, 0.0f); // Phalanx 2 translation and adjustment 
glRotatef((-1.0f*f_p[0].theta), 0, 0, 1); // Rotation to Phalanx 1 
glTranslatef(0.0f, 0.0f, -1.87f); // Phalanx 1 translation 

最後,由於我的模型有一側的兩個手指,一個在其他,我有其他兩個手指書寫之前旋轉:

// CONSTANT: Keep parts right side up 
glRotatef(90.0f, 0, 0, 1); 

在這一點上,我將跟隨手指2和3的相同過程(基本上是從// DRAW FINGER 1評論開始的代碼)。你可能不需要這樣做,因爲我認爲你的模型沒有所有這些額外的部分。在這一點上,你可以放棄所有的轉/翻譯回到原點,只是與完成:

glPopMatrix(); 

,並返回到不管你做之前(等待用戶輸入,等等)。

draw()函數我使用的是使用從.obj文件中提取的數據繪製三角形的標準函數。

+0

傳統OpenGL作爲答案?真? –

+0

@FelixK,我不明白爲什麼不。 OP永遠不會回答,這是一個有效的解決方案。這不像它被接受。 – Mewa

+0

因爲它可能會導致其他程序員使用已棄用的OpenGL。 –

0

要了解更多有關解決方案請參見denavit hartenberg notation

我的解決辦法很簡單。我有課kineticChain是我存儲的位置,所有模型的方向向量。我使用for循環遍歷此類中的所有元素,並乘以每個元素的位置和旋轉。

假設我們有3種元素在此鏈 位置的最後一個元素的將是(在僞代碼):

currentElementposition * currentElementorientation 

位置第二元件的:第一元件的

(currentElementPosition*currentElementorientation)*positionOfPreviousElement 

位置:

(currentElementPosition*currentElementorientation)*positionOfPreviousElement 

而後來的對象被縮放。

移動和旋轉是4x4矩陣

glm::mat4 rotate; 
glm::mat4 move; 

功能,我使用:

void Model::moveModel(std::vector<glm::vec3> & positions, std::vector<glm::vec3> & orienations, int id) 
{ 
    try 
    { 
     if (positions.size() != orienations.size()) throw "Size of positions vector should be equal to orienations vector"; 

     glm::mat4 objPosition; 

     for (int i = id ; i >= 0 ; --i) 
     { 
      rotate = glm::eulerAngleYXZ(orienations[i].y, orienations[i].x, orienations[i].z); 
      move = glm::translate(glm::mat4(), positions[i]); 
      objPosition = (move * rotate) * objPosition; 
     } 

     objScale = scale(glm::mat4(), objSize); // scaling object 
     objPosition = objPosition * objScale; 

     glUniformMatrix4fv(objPositionID, 1, GL_FALSE, &objPosition[0][0]); 
     glUniformMatrix4fv(perspectiveGL, 1, GL_FALSE, &perspective[0][0]); 
     glUniformMatrix4fv(lookAtGL, 1, GL_FALSE, &lookAt[0][0]); 
     glUniform3f(lightPositionGL, lightPosition.x, lightPosition.y, lightPosition.z); // przesłanie 3 liczb float 
    } 
    catch(char const * errorMsg) 
    { 
     std::cout << errorMsg << std::endl; 
    } 
}