c++ - 我如何在世界空间中移动这些顶点而不是在本地空间中移动?
问题描述
我正在使用“Dynamic Batch Renderer System”,并且我有一个具有函数的“Object.cpp”,当它被调用时,它返回批处理在屏幕上渲染“Quad”所需的数据(我也是我会提到这是在 3D 空间中,所以存在 Z 移动、Z 缩放和 XY 旋转)。
对于数学计算,我使用的是GLM 库。
渲染效果很好,批次也很好,问题是运动。旋转实际上按照我想要的方式工作,但是我不满意的是运动,因为它在对象的“局部空间”中移动。这意味着,例如,如果我在 Y 轴上将批次内的对象旋转 90°,则 X 移动变为 Z 移动,并且 Z 移动变为 X 移动。
我一直在寻找答案,但我找不到任何东西。我认为问题可能来自允许对象正确旋转的“rotationMatrix”,但我不知道是否需要添加额外的“功能”才能将对象移动到“世界空间”而不是“本地空间”,如果有,我不知道“功能”是什么。
现在我将把“Object.cpp”的整个代码放在这里,这样你们就可以看到它是如何工作的。
Object::Object(glm::vec3 pos, glm::vec3 rot, glm::vec3 sca, int ObjId)
: translationMatrix(glm::mat4(0)), rotationMatrix(glm::mat4(0))
{
id = ObjId;
position = pos;
lastPosition = pos + glm::vec3(1.0f);
scale = sca;
rotation = rot;
lastRotation = rot + glm::vec3(1.0f);
}
glm::mat4 One(1.0f);
Vertex* Object::UpdateObject(Vertex* target)
{
if (lastPosition != position)
{
translationMatrix = glm::translate(glm::identity<glm::mat4>(), -position);
lastPosition = position;
}
if (lastRotation != rotation)
{
glm::mat4 rotMatrixTemp(1.0f);
rotMatrixTemp = glm::rotate(rotMatrixTemp, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f));
rotMatrixTemp = glm::rotate(rotMatrixTemp, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
rotMatrixTemp = glm::rotate(rotMatrixTemp, glm::radians(rotation.z + 180.0f), glm::vec3(0.0f, 0.0f, 1.0f));
rotationMatrix = -translationMatrix * rotMatrixTemp * translationMatrix;
lastRotation = rotation;
}
float x = 1.0f, y = 1.0f;
if (flipX)
x *= -1;
if (flipY)
y *= -1;
target->position = rotationMatrix * glm::vec4(position.x - 0.5f * scale.x, position.y + 0.5f * scale.y, position.z, 1.0f);
target->color = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
target->texcoord = glm::vec2(0.0f, y);
target++;
target->position = rotationMatrix * glm::vec4(position.x - 0.5f * scale.x, position.y - 0.5f * scale.y, position.z, 1.0f);
target->color = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
target->texcoord = glm::vec2(0.0f, 0.0f);
target++;
target->position = rotationMatrix * glm::vec4(position.x + 0.5f * scale.x, position.y - 0.5f * scale.y, position.z, 1.0f);
target->color = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
target->texcoord = glm::vec2(x, 0.0f);
target++;
target->position = rotationMatrix * glm::vec4(position.x + 0.5f * scale.x, position.y + 0.5f * scale.y, position.z, 1.0f);
target->color = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
target->texcoord = glm::vec2(x, y);
target++;
return target;
}
所以,回顾一下,我想要完成的是在“世界空间”而不是“局部空间”中移动这些对象(同时,如果可能的话,将旋转系统保持在“局部空间”中。因为否则对象的中心总是 (0, 0, 0) 而不是它自己的位置)。
解决方案
要在世界中以给定的方向定位对象,通常先应用旋转,然后再应用平移,除非您确实在平移后尝试围绕原点旋转对象。所以要么检查一下,要么确保你有充分的理由让 translationMatrix 在
rotationMatrix = -translationMatrix * rotMatrixTemp * translationMatrix
因为看起来你在 if 块内外都有翻译逻辑
推荐阅读
- excel - 仅选择excel中某个范围的开始以输入总和
- database - 使用数据库时无法执行事务块。科特林,暴露
- recharts - 重新绘制指针处的值以显示在工具提示中?
- node.js - 邮递员(NodeJS):不保存从 api 返回的 cookie
- java - 在 Java 中给定 JSON 路径/JSON 指针,获取 JSON 文件的行号
- powershell - Powershell 使用 SQL 查询循环和 IN 子句将变量传递给函数
- python - 使用 python 对 Key 进行编码并使用请求获取一些数据的 API 密钥无效
- assembly - 找不到源 initsect.cpp
- python - 使用 pytorch 使用保存在 gpu 上的 pickle 文件绘制图形
- php - Eventbrite API - OAuth 设置 - 正确的 URL?