Я пытаюсь создать базовую систему анимации с помощью OpenGL и C++, следуя этому руководству (тот же файл коллады).
https://www.youtube.com/ playlist?list=PLRIWtICgwaX2tKWCxdeB7Wv_rTET9JtWW
Моя проблема в том, что когда я запускаю программу, вместо изменения позы модели она просто деформируется в объект. Это происходит только тогда, когда я применяю матрицы преобразования и веса каждого соединения. Я попробовал использовать другой шейдер, который не просчитал новые позиции, и с моделью все в порядке.
Я пытался установить одну из поз из анимации, но модель все равно деформировалась, поэтому я начинаю думать, что, возможно, я неправильно рассчитал. Но даже если они не правы, модель должна меняться от позы к позе, верно? Или я что-то не так понимаю?
Вот мой текущий код. Спасибо всем за уделенное время.
#include "Animator.h"
Animator::Animator()
{
}
Animator::Animator(Animation* animation) {
currentAnimation = animation;
}
void Animator::StartNewAnimation(Animation* animation)
{
currentTime = 0.0f;
currentAnimation = animation;
progress = 0;
}
void Animator::Update(float deltaTime, Joint* rootJoint)
{
previousTime = currentTime;
IncreaseAnimationTime(deltaTime);
std::vector currentPose = CalculateCurrentPose();
/*for (size_t i = 0; i < currentPose.size(); ++i) {
std::cout SetTransformMatrix(currentTransform);
}
#include "JointTransform.h"
JointTransform::JointTransform()
{
}
JointTransform::JointTransform(glm::vec3 position, glm::quat rotation)
{
this->position = position;
this->rotation = rotation;
}
JointTransform JointTransform::Interpolate(JointTransform frame1, JointTransform frame2, float progress)
{
glm::vec3 newPosition = glm::mix(frame1.position, frame2.position, progress);
glm::quat newRotation = glm::slerp(frame1.rotation, frame2.rotation, progress);
//std::cout FirstChildElement("animation")->FirstChildElement("source")->FirstChildElement("float_array")->GetText();
std::stringstream ss(times);
std::vector stringKeyframesTime;
//Crear cada keyframe
while (getline(ss, auxString, ' ')) {
stringKeyframesTime.push_back(auxString);
}
for (std::string str : stringKeyframesTime) {
//cout FirstChildElement("library_animations")->FirstChildElement("animation");
int index = 0;
const char* matrixElements;
std::vector stringMatrixElements;
std::vector floatMatrixElements;
std::cout idCounter duration = keyframesTime[keyframesTime.size() - 1];
for (int j = 0; j < rootJoint->idCounter; j++) {
if (j != 0) {
currentJointAnimation = currentJointAnimation->NextSiblingElement("animation");
}
matrixElements = currentJointAnimation->FirstChildElement("source")->NextSiblingElement("source")->FirstChildElement("float_array")->GetText();
std::stringstream ss2(matrixElements);
while (getline(ss2, auxString, ' ')) {
stringMatrixElements.push_back(auxString);
}
for (std::string str : stringMatrixElements) {
//cout keyframes;
}
#include "Render.h"
#include "InputManager.h"
#include "Player.h";
const int MAX_JOINTS = 50;
Render::Render()
{
Render::r = this;
this->objectList = std::vector();
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
Render::r->camera->aspectRatio = (float) width / (float) height;
glViewport(0, 0, width, height);
}
void mouse_callback(GLFWwindow* window, double xPosIn, double yPosIn)
{
float xPos = static_cast(xPosIn);
float yPos = static_cast(yPosIn);
Camera* cam = Render::r->camera;
if (cam->firstMouse)
{
cam->lastX = xPos;
cam->lastY = yPos;
cam->firstMouse = false;
}
float xOffset = xPos - cam->lastX;
float yOffset = cam->lastY - yPos;
cam->lastX = xPos;
cam->lastY = yPos;
float sensitivity = 0.2f;
xOffset *= sensitivity;
yOffset *= sensitivity;
cam->yaw += xOffset;
cam->pitch += yOffset;
if (cam->pitch > 89.0f) cam->pitch = 89.0f;
if (cam->pitch < -89.0f) cam->pitch = -89.0f;
glm::vec3 front = glm::vec3(
cos(glm::radians(cam->yaw)) * cos(glm::radians(cam->pitch)),
sin(glm::radians(cam->pitch)),
sin(glm::radians(cam->yaw)) * cos(glm::radians(cam->pitch))
);
cam->front = glm::normalize(front);
}
void scroll_callback(GLFWwindow* window, double xOffset, double yOffset)
{
Render::r->camera->fov -= (float) yOffset;
if (Render::r->camera->fov < 1.0f) Render::r->camera->fov = 1.0f;
if (Render::r->camera->fov > 45.0f) Render::r->camera->fov = 45.0f;
}
void Render::initGL(const char* windowName, int sizeX, int sizeY)
{
if (glfwInit() != GLFW_TRUE)
{
std::cout window = glfwCreateWindow(sizeX, sizeY, windowName, NULL, NULL);
this->width = sizeX;
this->height = sizeY;
glfwMakeContextCurrent(window);
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwSetScrollCallback(window, scroll_callback);
int version = gladLoadGL(glfwGetProcAddress);
if (version == 0)
{
std::cout id);
}
}
void Render::setupObject(Object* object)
{
bufferObject_t bo;
glGenVertexArrays(1, &bo.bufferID);
glBindVertexArray(bo.bufferID);
glGenBuffers(1, &bo.vertexBufferID);
glGenBuffers(1, &bo.edgeBufferID);
glBindBuffer(GL_ARRAY_BUFFER, bo.vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_t) * object->vertexList.size(), object->vertexList.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bo.edgeBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * object->idList.size(), object->idList.data(), GL_STATIC_DRAW);
bufferObjectList[object->id] = bo;
}
void Render::drawGL(int id)
{
glm::mat4 M = this->objectList[id]->modelMatrix;
glm::mat4 V = this->camera->computeViewMatrix();
glm::mat4 P = this->camera->computeProjectionMatrix();
glm::mat4 MVP = P * V * M;
bufferObject_t bo = bufferObjectList[this->objectList[id]->id];
this->objectList[id]->prg->use();
glBindVertexArray(bo.bufferID);
glBindBuffer(GL_ARRAY_BUFFER, bo.vertexBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bo.edgeBufferID);
this->objectList[id]->prg->setMVP(MVP);
this->objectList[id]->prg->setMatrix("M", M);
if (typeid(*this->objectList[id]) == typeid(Player)) {
Player* player = dynamic_cast (this->objectList[id]);
//player->UpdateVertex();
std::vector list = player->GetJointTransforms();
//this->objectList[id]->prg->setMatrix("jointTransforms", &list[0][0][0]);
/*GLint jointTransformsLocation = glGetUniformLocation(this->objectList[id]->prg->programID, "jointTransforms");
if (jointTransformsLocation != -1) {
glUniformMatrix4fv(jointTransformsLocation, list.size(), GL_FALSE, &list[0][0][0]);
}
else {
std::cerr prg->setMatrix("jointTransforms[" + std::to_string(i) + "]", list);
}
}
this->objectList[id]->prg->setVertexAttribute("vPos", 4, GL_FLOAT, sizeof(vertex_t), (void*) offsetof(vertex_t, vertexPos));
this->objectList[id]->prg->setVertexAttribute("vColor", 4, GL_FLOAT, sizeof(vertex_t), (void*) offsetof(vertex_t, vertexColor));
this->objectList[id]->prg->setVertexAttribute("vNormal", 4, GL_FLOAT, sizeof(vertex_t), (void*) offsetof(vertex_t, vertexNormal));
this->objectList[id]->prg->setVertexAttribute("vUv", 4, GL_FLOAT, sizeof(vertex_t), (void*)offsetof(vertex_t, vertexUv));
this->objectList[id]->prg->setVertexAttribute("jointIndex", 4, GL_INT, sizeof(vertex_t), (void*)offsetof(vertex_t, idJoints));
this->objectList[id]->prg->setVertexAttribute("weightJoints", 4, GL_FLOAT, sizeof(vertex_t), (void*)offsetof(vertex_t, weightJoints));
this->objectList[id]->prg->setInteger("textureColor", 0);
if (this->objectList[id]->texture != nullptr)
{
this->objectList[id]->prg->setInteger("material.textureEnabled", 1);
this->objectList[id]->texture->bind(0);
}
else
{
this->objectList[id]->prg->setInteger("material.textureEnabled", 0);
}
glDrawElements(GL_TRIANGLES, this->objectList[id]->idList.size(), GL_UNSIGNED_INT, nullptr);
}
void Render::putObject(Object* object)
{
this->objectList.push_back(object);
setupObject(object);
}
void Render::putCamera(Camera* camera)
{
this->camera = camera;
}
void Render::move(float deltaTime)
{
for (auto& obj : this->objectList)
{
obj->move(deltaTime);
}
}
void Render::mainLoop()
{
double currentTime = 0.0f;
float lastTime = 0.0f;
float deltaTime = 0.0f;
while (!glfwWindowShouldClose(this->window) && !InputManager::keysState[GLFW_KEY_ESCAPE])
{
currentTime = glfwGetTime();
deltaTime = float(currentTime - lastTime);
lastTime = currentTime;
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
this->camera->move(deltaTime);
move(deltaTime);
drawObjects();
glfwPollEvents();
glfwSwapBuffers(window);
}
glfwTerminate();
}
#version 330 core
const int MAX_JOINTS = 50;
const int MAX_WEIGHTS = 4;
uniform mat4 MVP;
uniform mat4 M;
uniform mat4 jointTransforms[MAX_JOINTS];
in vec4 vPos;
in vec4 vColor;
in vec4 vNormal;
in vec4 vUv;
in ivec4 jointIndex;
in vec4 weightJoints;
out vec4 fColor;
out vec3 fPos;
out vec3 fNormal;
out vec2 fUv;
void main() {
vec4 totalPos = vec4(0.0);
vec3 totalNormal = vec3(0.0);
mat4 boneMatrix = mat4(1.0f);
for (int i = 0; i < MAX_WEIGHTS; i++) {
if (jointIndex == -1) {
break;
}
if (jointIndex >= MAX_JOINTS) {
totalPos = vPos;
break;
}
boneMatrix += jointTransforms[jointIndex] * weightJoints;
/*vec4 localPosition = (jointTransforms[jointIndex] * vPos);
totalPos += localPosition * weightJoints;*/
/*mat3 normalMatrix = mat3(jointTransforms[jointIndex]);
vec3 localNormal = normalize(normalMatrix * vNormal.xyz);
totalNormal += localNormal * weightJoints;*/
}
totalPos = boneMatrix * vPos;
fPos = (M * totalPos).xyz;
fNormal = (inverse(transpose(M)) * vNormal).xyz;
fNormal = normalize(fNormal);
fColor = vec4(totalPos.xyz, 1.0);
fUv = vUv.xy;
gl_Position = MVP * totalPos;
}
Подробнее здесь: https://stackoverflow.com/questions/793 ... object-ins
Система анимации в OpenGL не меняет позу модели, а вместо этого деформирует объект. ⇐ C++
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Система анимации в OpenGL не меняет позу модели, а вместо этого деформирует объект.
Anonymous » » в форуме C++ - 0 Ответы
- 5 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Установка вращения совместной иерархии в новую позу привязки с помощью кватернионов
Anonymous » » в форуме Python - 0 Ответы
- 4 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Установка вращения совместной иерархии в новую позу привязки с помощью кватернионов
Anonymous » » в форуме Python - 0 Ответы
- 8 Просмотры
-
Последнее сообщение Anonymous
-