旋转由其法线和距离定义的平面

时间:2015-02-24 20:24:21

标签: opengl rotation collision-detection physics normals

我一直在尝试在3D空间中旋转飞机,但我一直在打死路。以下是这种情况:

我有一个物理引擎,我在一个立方体内模拟一个移动的球体。为了简化操作,我只绘制了顶部和底部平面并垂直移动了球体。我按如下方式定义了我的两架飞机:

CollisionPlane* p = new CollisionPlane(glm::vec3(0.0, 1.0, 0.0), -5.0);
CollisionPlane* p2 = new CollisionPlane(glm::vec3(0.0, -1.0, 0.0), -5.0);

vec3定义平面的法线,第二个参数定义平面与法线的距离。我将距离定义为-5的原因是因为我在所有轴上按10缩放了代表我的两个平面的模型,所以现在距离原点的距离是5到顶部如果这有任何意义的话,那就是底部。

为了给你一些参考,我创建了我的两个平面作为两个线循环,我有一个模型,它模拟这两个线循环,如下所示:

top plane:
std::shared_ptr<Mesh> f1 = std::make_shared<Mesh>(GL_LINE_LOOP);
std::vector<Vertex> verts = { Vertex(glm::vec3(0.5, 0.5, 0.5)), Vertex(glm::vec3(0.5, 0.5, -0.5)), Vertex(glm::vec3(-0.5, 0.5, -0.5)), Vertex(glm::vec3(-0.5, 0.5, 0.5)) };
f1->BufferVertices(verts);

bottom plane:
std::shared_ptr<Mesh> f2 = std::make_shared<Mesh>(GL_LINE_LOOP);
std::vector<Vertex> verts2 = { Vertex(glm::vec3(0.5, -0.5, 0.5)), Vertex(glm::vec3(0.5, -0.5, -0.5)), Vertex(glm::vec3(-0.5, -0.5, -0.5)), Vertex(glm::vec3(-0.5, -0.5, 0.5)) };
f2->BufferVertices(verts2);

std::shared_ptr<Model> faceModel = std::make_shared<Model>(std::vector<std::shared_ptr<Mesh>> {f1, f2 });

就像我说的那样,我按照10缩放模型。

现在我有一个向上和向下移动的球体,并与每个面部碰撞,同时也实现了碰撞响应。enter image description here

我面临的问题是当我试图旋转飞机时。当我围绕Z轴旋转时似乎工作正常,但是当我围绕X轴旋转时,它似乎不起作用。以下显示围绕Z旋转的结果:

enter image description here

然而,如果我尝试围绕X旋转,球会穿透底部平面,就像碰撞平面向下移动一样:

enter image description here

以下是我试图旋转法线和平面的代码:

for (int i = 0; i < m_entities.size(); ++i)
    {
        glm::mat3 normalMatrix = glm::mat3_cast(glm::angleAxis(glm::radians(6.0f), glm::vec3(0.0, 0.0, 1.0)));

        CollisionPlane* p = (CollisionPlane*)m_entities[i]->GetCollisionVolume();
        glm::vec3 normalDivLength = p->GetNormal() / glm::length(p->GetNormal());
        glm::vec3 pointOnPlane = normalDivLength * p->GetDistance();
        glm::vec3 newNormal = normalMatrix * normalDivLength;

        glm::vec3 newPointOnPlane = newNormal * (normalMatrix * (pointOnPlane - glm::vec3(0.0)) + glm::vec3(0.0));

        p->SetNormal(newNormal);
        float newDistance = newPointOnPlane.x + newPointOnPlane.y + newPointOnPlane.z;
        p->SetDistance(newDistance);
    }

除了将glm::vec3(0.0, 0.0, 1.0)更改为glm::vec3(1.0, 0.0, 0.0)

之外,我在X周围做了同样的事情。

m_entites基本上是我的物理实体,它拥有不同的碰撞形状(球体平面等)。我的代码基于Rotating plane with normal and distance

的答案

当我围绕Z旋转时,我似乎无法弄清楚为什么它会起作用,但是当我绕X旋转时,我无法理解它。我错过了一些至关重要的东西吗?

0 个答案:

没有答案