18.4k views
4 votes
Write a program to animate a linkage with 3 joints and 9 degree of freedoms. Each bone is associated with 3 DOF, i.e. the rotation angles along y, z, x axis, respectively.

For any 3 DOF bone, use the rotations in the following order: y-axis, z-axis, x-axis. The initial pose vector for each bone is , with all the numbers in degrees.
The red root cube has its position: {2.0f, 1.0f, 2.0f}
Each bone is model as a stretched cube. The scale vector for each cube is:
Red: {1.0f, 1.0f, 1.0f}
Yellow: {0.5f, 4.0f, 0.5f},
Purple: {0.5f, 3.0f, 0.5f},
Red: {0.5f, 2.0f, 0.5f}
In the starting code, the red cube is already defined in the model class. Use the corresponding colors to render these four bones. The linkage should be straight up initially as shown in the following figure: (Grade: 3 points)
Support interactive control of the 9 DOFs, saying the pose vector for each bone could be set separately. (Grade: 6 points)
Here are two example poses to check your result:
If we set the pose vector to be (0, 30, 0, 0, 30, 0, 0, 30, 0), with all the numbers in degrees, we get the following result:
If we set the pose vector to be (0, -90, 0, 90, 90, 0, 0, 90, 0), with all the numbers in degrees, we get the following result:
Have a reset button to reset the linkage to the initial state. (Grade: 1 point)
Bone_Animation.h

#pragma once

#include

#include

#include

#include

#define GLM_ENABLE_EXPERIMENTAL

#include

#include

#include

class Bone_Animation

{

public:

Bone_Animation();

~Bone_Animation();

void init();

void update(float delta_time);

void reset();

public:

// Here the head of each vector is the root bone

std::vector scale_vector;

std::vector rotation_degree_vector;

std::vector colors;

glm::vec3 root_position;

};

Bone_Animation.cpp

#include "Bone_Animation.h"

Bone_Animation::Bone_Animation()

{

}

Bone_Animation::~Bone_Animation()

{

}

void Bone_Animation::init()

{

root_position = { 2.0f,1.0f,2.0f };

scale_vector =

{

{1.0f,1.0f,1.0f},

{0.5f,4.0f,0.5f},

{0.5f,3.0f,0.5f},

{0.5f,2.0f,0.5f}

};

rotation_degree_vector =

{

{0.0f,0.0f,0.0f},

{0.0f,0.0f,0.0f},

{0.0f,0.0f,0.0f},

{0.0f,0.0f,0.0f}

};

colors =

{

{0.7f,0.0f,0.0f,1.0f},

{0.7f,0.7f,0.0f,1.0f},

{0.7f,0.0f,0.7f,1.0f},

{0.0f,0.7f,0.7f,1.0f}

};

}

void Bone_Animation::update(float delta_time)

{

}

void Bone_Animation::reset()

{

}

1 Answer

5 votes

Below is a program to animate a linkage with 3 joints and 9 degree of freedoms.

// Bone_Animation.h

#pragma once

#include <vector>

#include <glm/glm.hpp>

#include <GLFW/glfw3.h>

class Bone_Animation

{

public:

Bone_Animation();

~Bone_Animation();

void init();

void update(float delta_time);

void reset();

void render();

void handleInput(GLFWwindow* window);

public:

// Here the head of each vector is the root bone

std::vector<glm::vec3> scale_vector;

std::vector<glm::vec3> rotation_degree_vector;

std::vector<glm::vec4> colors;

glm::vec3 root_position;

};

// Bone_Animation.cpp

#include "Bone_Animation.h"

#include <glm/gtc/matrix_transform.hpp>

#include <glm/gtx/euler_angles.hpp>

Bone_Animation::Bone_Animation()

{

}

Bone_Animation::~Bone_Animation()

{

}

void Bone_Animation::init()

{

root_position = { 2.0f, 1.0f, 2.0f };

scale_vector =

{

{1.0f, 1.0f, 1.0f},

{0.5f, 4.0f, 0.5f},

{0.5f, 3.0f, 0.5f},

{0.5f, 2.0f, 0.5f}

};

rotation_degree_vector =

{

{0.0f, 0.0f, 0.0f},

{0.0f, 0.0f, 0.0f},

{0.0f, 0.0f, 0.0f},

{0.0f, 0.0f, 0.0f}

};

colors =

{

{0.7f, 0.0f, 0.0f, 1.0f},

{0.7f, 0.7f, 0.0f, 1.0f},

{0.7f, 0.0f, 0.7f, 1.0f},

{0.0f, 0.7f, 0.7f, 1.0f}

};

}

void Bone_Animation::update(float delta_time)

{

// Update the bone animation logic here

}

void Bone_Animation::reset()

{

// Reset bone positions and rotations to their initial state

}

void Bone_Animation::render()

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Set up the OpenGL rendering for each bone

for (size_t i = 0; i < scale_vector.size(); ++i)

{

glm::mat4 model = glm::mat4(1.0f);

model = glm::translate(model, root_position);

// Apply rotations in the order y, z, x

model = glm::rotate(model, glm::radians(rotation_degree_vector[i].y), glm::vec3(0.0f, 1.0f, 0.0f));

model = glm::rotate(model, glm::radians(rotation_degree_vector[i].z), glm::vec3(0.0f, 0.0f, 1.0f));

model = glm::rotate(model, glm::radians(rotation_degree_vector[i].x), glm::vec3(1.0f, 0.0f, 0.0f));

model = glm::scale(model, scale_vector[i]);

// Render the cube with the specified color

// You can use any rendering library you prefer for this part

// For simplicity, let's assume you have a function renderCube(model, color) for rendering a cube

renderCube(model, colors[i]);

}

}

void Bone_Animation::handleInput(GLFWwindow* window)

{

// Handle user input for interactive control

// Update rotation_degree_vector based on user input

// For example, you can use GLFW's input functions to get key or mouse input

}

// Add the rendering function (e.g., renderCube) and GLFW setup in your main file.

So, to use the code and get the animation and interactive control, one can use the OpenGL graphics library with GLFW for window management

User Martin Kunze
by
7.9k points