首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GLM从vec3生成旋转矩阵

GLM从vec3生成旋转矩阵
EN

Stack Overflow用户
提问于 2015-12-19 02:30:54
回答 3查看 8.6K关注 0票数 7

我正在做一个游戏,我需要弹丸面对它的方向。我知道它的方向,我需要建立一个变换矩阵,允许我将弹丸模型的方向(1,0,0)或正X轴与任意的向量对齐。我怎么能在glm里这么做?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-12-21 16:50:13

嘿,我想出了答案,这个答案离@Mr_Pouet很近,但这里是:

代码语言:javascript
复制
const glm::vec3 a = ...;
const glm::vec3 b = ...; // in my case (1, 0, 0)
glm::vec3 v = glm::cross(b, a);
float angle = acos(glm::dot(b, a) / (glm::length(b) * glm::length(a)));
glm::mat4 rotmat = glm::rotate(angle, v);

你可以用你想要的任何东西替换a或b,其中a是你想要转换到的向量,b是你所处的位置。如果b是(1,0,0)或x轴,我们可以优化它,就像我的例子:

代码语言:javascript
复制
glm::vec3 v = glm::vec3(0, -a.z, a.y);
float angle = acos(a.x / glm::length(a));
glm::mat4 rotmat = glm::rotate(angle, v);

我希望这能帮上忙!

票数 7
EN

Stack Overflow用户

发布于 2015-12-19 03:25:33

你用什么来准确地表示方向?

你可以这样做:

代码语言:javascript
复制
glm::mat4 transform = glm::eulerAngleYXZ(euler.y, euler.x, euler.z);

或者通过四元数:

代码语言:javascript
复制
glm::quat rot = glm::angleAxis(glm::radians(angle_in_degrees), glm::vec3(x, y, z));
glm::mat4 rotMatrix = glm::mat4_cast(rot);

除非你在寻找像glm::lookAt这样简单的东西?

代码语言:javascript
复制
detail::tmat4x4<T> glm::gtc::matrix_transform::lookAt   
(   
    detail::tvec3< T > const &  eye,     // from
    detail::tvec3< T > const &  center,  // to
    detail::tvec3< T > const &  up       // up
)
票数 7
EN

Stack Overflow用户

发布于 2021-05-06 19:37:22

其他答案中没有一个是真正完整的答案,因为它们不处理像cross(.,.)=0up||at-eye这样的特殊情况。

这里有一个相当完整的解决方案,它应该适用于您不关心旋转对象的方向的每一种情况(即。(直线或钢瓶等):

代码语言:javascript
复制
glm::vec3 from;
glm::vec3 to;

glm::vec3 v = glm::cross(to, from);
float angle = acos(glm::dot(to, from) / (glm::length(to) * glm::length(from)));
glm::mat4 rotmat = glm::rotate(angle, v);

// special cases lead to NaN values in the rotation matrix
if (glm::any(glm::isnan(rotmat * glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)))) {
    if (angle < 0.1f) {
        rotmat = glm::mat4(1.0f);
    }
    else if (angle > 3.1f) {
        // rotate about any perpendicular vector
        rotmat = glm::rotate(angle, glm::cross(from,
                                      glm::vec3(from.y, from.z, from.x)));
    }
    else {
        assert(false);
    }
}

这个解决方案的另一个缺点是它非常‘快’,即。特例只在矩阵爆炸时触发。这可能导致在处理接近并行案例的案例时产生工件。通常,人们希望在重叠区域之间进行转换,并在每个区域中应用连续的解决方案。因此,我想,分解成欧拉角是可能的。如果有人跨过任何这样的算法,请张贴。我的意思是,这对学生来说也是一个体面的家庭作业。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34366655

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档