Проблема отрисовки поворота 3д модели через кватернион или не правильное создание физической сферы
Всем привет, у меня проблема с отрисовкой поворота или не правильное создание физической сферы. Я с созданием сферы уверен полностью, но не исключаю что там может быть ошибка. Вот код создания сферы:
void setSphere(btDynamicsWorld* world, vector<btRigidBody*> bodies, btVector3 pos, float rad)
{
// это нужно чтобы нельзя было пересоздать объект если он уже создан
if (this->type == 0)
{
this->type = SPHERE_TYPE;
this->radius = rad;
btTransform transform;
transform.setIdentity();
transform.setOrigin(pos);
btSphereShape* sphere = new btSphereShape(rad);
btVector3 inertia(0, 0, 0);
if (this->mass != 0.0)
sphere->calculateLocalInertia(this->mass, inertia);
btMotionState* motion = new btDefaultMotionState(transform);
btRigidBody::btRigidBodyConstructionInfo info(this->mass, motion, sphere, inertia);
this->body = new btRigidBody(info);
world->addRigidBody(this->body);
bodies.push_back(this->body);
}
}
Вот код где я рисую 3д модель:
void draw(Program program, GLuint texture)
{
// get btTransform data
btTransform transform;
body->getMotionState()->getWorldTransform(transform);
// set varibles
glm::mat4 translate, rotate, scaling, matModel;
translate = rotate = scaling = matModel = glm::mat4(1.0f);
// scale
scaling = glm::scale(glm::mat4(1.0f), scale);
if (type == SPHERE_TYPE)
scaling = glm::scale(scaling, glm::vec3(radius));
else if (type == CYLINDER_TYPE)
{
btVector3 extent = ((btCylinderShape*)body->getCollisionShape())->getHalfExtentsWithMargin();
scaling = glm::scale(scaling, glm::vec3(extent.x(), extent.x(), extent.y()));
}
else if (type == CONE_TYPE)
{
float h = ((btConeShape*)body->getCollisionShape())->getHeight();
scaling = glm::scale(scaling, glm::vec3(1, h / 2.0, 1));
}
else if (type == PLANE_STATIC_TYPE && scale == glm::vec3(1.0f))
scaling = glm::scale(glm::mat4(1.0f), glm::vec3(100.0f, 0.1f, 100.0f));
// get quaternion
btQuaternion rotation = transform.getRotation();
// get position
btVector3 btPos = transform.getOrigin();
// rotate and translate
if (rotation.getAngle() > 0.0)
{
rotate = glm::mat4_cast(engine::math::bulletToGlm(rotation));
translate = glm::translate(glm::mat4(1.0f), glm::vec3(btPos.x(), btPos.y() + rotation.getY(), btPos.z()));
}
else
translate = glm::translate(glm::mat4(1.0f), glm::vec3(btPos.x(), btPos.y(), btPos.z()));
// get final 3d model matrix
matModel = translate * rotate * scaling;
// renderer
program.setMat4("model", matModel);
model->Draw(program, texture);
}
Мне кажется что проблема вот здесь:
if (rotation.getAngle() > 0.0)
{
rotate = glm::mat4_cast(engine::math::bulletToGlm(rotation)); // <-- проблема должна быть в этой строке
translate = glm::translate(glm::mat4(1.0f), glm::vec3(btPos.x(), btPos.y() + rotation.getY(), btPos.z()));
}
else
translate = glm::translate(glm::mat4(1.0f), glm::vec3(btPos.x(), btPos.y(), btPos.z()));
Вот картинка вращения, извините за качество
И ещё, у меня 2 сферы. Одна вращается правильно, а другая ( которая на картинке ) вращается странно. Вот код создания сфер:
// 3д модель вес изменение размера 3д модели
PhysicBody sphere(&sphereModel, 10.0f, glm::vec3(0.036f));
// мир физ. тела позиция радиус
sphere.setSphere(engine.world, engine.bodies, btVector3(5.2, 20, 5), 2.0f);
engine.physicBodies.push_back(sphere);
PhysicBody sphere2(&sphereModel, 150.0f, glm::vec3(0.036001f));
sphere2.setSphere(engine.world, engine.bodies, btVector3(5.6, 160, 5.1), 1.0f);
engine.physicBodies.push_back(sphere2);
Ответы (1 шт):
Автор решения: jdoseIOO
→ Ссылка
Я нашёл и понял проблему. Вопрос решён. Вот исправленный код:
// rotate
btQuaternion rotation = transform.getRotation();
rotation.normalize();
if (rotation.getAngle() > 0.0)
{
glm::quat q = glm::normalize(engine::math::bulletToGlm(rotation));
rotate = glm::mat4(1.0f) * glm::mat4_cast(q);
}
Ошибка была в отсуствии нормализации