2015-04-15 2 views
0

Я хочу сделать простую трехмерную роботизированную руку, используя блендер. На данный момент я могу импортировать файлы и текстуры obj, вращать, переводить и масштабировать.OpenGL простой трехмерный роботизированный рычаг

Проблема: Для упрощения роботизированная рука будет иметь 3 части, основание (цилиндр для вращения) и два кубика. У меня нет проблем с вращающимся цилиндром и кубоидами. Но эти два кубоида должны быть связаны, и я не знаю, как это сделать. Я могу использовать простые функции синуса и косинуса для вычисления положения второго кубоида при первом повороте, но я не знаю, как измерить часть объекта.

Вторая проблема: Можно ли экспортировать все 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

Вы не ответили на комментарий, но я полагал, что я этот пост код в любом случае. Я написал это, чтобы сделать 3D роботизированную руку в OpenGL. У меня были файлы модели blender для всех пальцев и руки (сделанные кем-то еще), которые я экспортировал отдельно в файлы .obj.

Окончательный результат можно увидеть here. Как вы можете видеть, я также добавил функциональность для изменения точки обзора с помощью мыши. Я определил смещения для фалангов пальцев методом проб и ошибок, но, возможно, вы можете найти смещение между точками, используя Blender, как описано here. Я не могу проверить это прямо сейчас, так как у меня нет 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, потому что я думаю, когда я экспортировал его из Blender экстры, я выстроен модель должным образом.

// 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

Legacy OpenGL как ответ? В самом деле? –

+0

@ Феликс., Я не понимаю, почему нет. OP никогда не отвечал в любом случае, и это действительное решение. Не похоже, что это было принято. – Mewa

+0

Потому что это может заставить других программистов использовать устаревший OpenGL. –

0

Чтобы узнать больше о решении, пожалуйста, обратитесь к denavit hartenberg notation

Мое решение было просто. У меня есть класс kinematicChain, я сохранил векторы с позициями, ориентациями всех моделей. Я повторяю все элементы этого класса, используя для цикла, и умножаю положение и поворот каждого элемента.

Предположим, у нас было 3 элемента Позиция последнего элемента в этой цепи будет (в псевдокоде):

currentElementposition * currentElementorientation 

Позиция второго элемента:

(currentElementPosition*currentElementorientation)*positionOfPreviousElement 

Позиция первого элемента:

(currentElementPosition*currentElementorientation)*positionOfPreviousElement 

И далее объект масштабируется.

Перемещение и поворот 4х4 матрица

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; 
    } 
} 
Смежные вопросы