我想用攪拌機制作簡單的3D機器人手臂。目前我可以導入obj文件和紋理,旋轉,平移和縮放。OpenGL簡單的3D機器人手臂
問題: 爲了簡化,機器人手臂將有3個部件,底座(圓筒旋轉)和兩個長方體。我沒有旋轉Cilinder和長方體的問題。但是這兩個長方體必須連接,我不知道如何去做。我可以使用簡單的正弦函數和餘弦函數來計算第一個長方體的位置,但是我不知道如何測量對象的長度。
第二個問題: 我可以將所有3個對象導出到一個obj文件中並稍後在openGL中進行分割嗎?
我想用攪拌機制作簡單的3D機器人手臂。目前我可以導入obj文件和紋理,旋轉,平移和縮放。OpenGL簡單的3D機器人手臂
問題: 爲了簡化,機器人手臂將有3個部件,底座(圓筒旋轉)和兩個長方體。我沒有旋轉Cilinder和長方體的問題。但是這兩個長方體必須連接,我不知道如何去做。我可以使用簡單的正弦函數和餘弦函數來計算第一個長方體的位置,但是我不知道如何測量對象的長度。
第二個問題: 我可以將所有3個對象導出到一個obj文件中並稍後在openGL中進行分割嗎?
你有沒有考慮索具的對象,你會一個人的手臂?這樣,這些對象全部鏈接起來,不會失去同步。然後將動畫作爲一個整體應用於鑽塔。更少的計算,更容易。
例子(從該網站其他頁面是有用的爲好): 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或更改乘法的順序。但我正在研究其他想法。假設我們有3個武器。我可以先旋轉第三個手臂,然後移動到他的位置,然後再次旋轉第三個手臂與第二個手臂的角度相同,然後移動到第二個位置,再次旋轉第三個手臂的角度與第一個手臂的角度相同,然後在xyz軸上移動。 – Szczepan
您還沒有迴應發表評論,但我想我會張貼此代碼反正。我寫這個來渲染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文件中提取的數據繪製三角形的標準函數。
傳統OpenGL作爲答案?真? –
@FelixK,我不明白爲什麼不。 OP永遠不會回答,這是一個有效的解決方案。這不像它被接受。 – Mewa
因爲它可能會導致其他程序員使用已棄用的OpenGL。 –
要了解更多有關解決方案請參見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;
}
}
這似乎並沒有成爲一個「我寫的代碼,我有這個代碼的問題」問題,這幾乎使得它超出了這個特定SE網站的範圍。你可以試試blender.stackexchange.com –
嘿,我幾年前也做過同樣的事情。我不會打擾做一個單一的文件。我分開導出所有部分,然後跟蹤旋轉。我做了一個試驗性的方法來找到數字的長度,但這隻需要做一次(我硬編碼)。在你的情況下,如果手很簡單,這不會太困難。[這是我最終的結果](https://www.youtube.com/watch?v=uJO5sLP_vKY&feature=plcp)。如果你有興趣,當我回家時我可以發佈我的代碼(現在真的需要運行)。 – Mewa