使用 C++/OpenGL。
例如,在光标位置缩放相机:
Vector3 target = GetScreenToWorldPosition(in_position);
Matrix4 s(MATRIX4_IDENTITY);
s.SetScale(0.12648); /// Arbitrary value for simplicity sake.
Matrix4 t(MATRIX4_IDENTITY);
t.SetTranslation(target);
Matrix4 tMinus(MATRIX4_IDENTITY);
tMinus.SetTranslation(-target);
Camera *camera = GetCurrentCamera();
Matrix4 matrix = camera->GetWorldMatrix();
matrix *= t * s * tMinus;
l_camera->SetScale(1, 1, 1);
l_camera->SetTranslation(?);
l_camera->SetRotation(?);
Run Code Online (Sandbox Code Playgroud)
有没有办法在保持绝对平移/旋转的同时重置比例?
Matrix4:
float m[16];
Row-Major:
m[00], m[01], m[02], m[03]
m[04], m[05], m[06], m[07]
m[08], m[09], m[10], m[11]
m[12], m[13], m[14], m[15]
m[00], m[04], m[08] = Cross vector
m[01], m[05], m[09] = Up vector
m[02], m[06], m[10] = Normal vector
m[12], m[13], m[14] = Translation vector
Run Code Online (Sandbox Code Playgroud)
基于rabbid76 的建议:
Vector3 l_scale;
l_scale.x = sqrt(m[0] * m[0] + m[4] * m[4] + m[8] * m[8]);
l_scale.y = sqrt(m[1] * m[1] + m[5] * m[5] + m[9] * m[9]);
l_scale.z = sqrt(m[2] * m[2] + m[6] * m[6] + m[10] * m[10]);
m[0] /= l_scale.x;
m[4] /= l_scale.y;
m[8] /= l_scale.z;
m[1] /= l_scale.x;
m[5] /= l_scale.y;
m[9] /= l_scale.z;
m[2] /= l_scale.x;
m[6] /= l_scale.y;
m[10] /= l_scale.z;
Run Code Online (Sandbox Code Playgroud)
它看起来很有希望,但到目前为止,过去放大的东西现在缩小了,反之亦然。此外,还有一些摆动效果表明有些地方不太对劲。
知道矩阵,您可以计算每个轴的比例。下面cm
是矩阵:
float scaleX = sqrt(cm[0][0]*cm[0][0] + cm[0][1]*cm[0][1] + cm[0][2]*cm[0][2]);
float scaleY = sqrt(cm[1][0]*cm[1][0] + cm[1][1]*cm[1][1] + cm[1][2]*cm[1][2]);
float scaleZ = sqrt(cm[2][0]*cm[2][0] + cm[2][1]*cm[2][1] + cm[2][2]*cm[2][2]);
Run Code Online (Sandbox Code Playgroud)
如果要“重置”比例,同时保持绝对平移和旋转,则需要对轴进行标准化。归一化向量(单位向量)的长度为 1:
for (int i = 0; i < 3; ++i)
{
cm[0][i] /= scaleX;
cm[1][i] /= scaleY;
cm[2][i] /= scaleZ;
}
Run Code Online (Sandbox Code Playgroud)
如果 3 轴的比例相同,则scaleX
, scaleY
,的结果scaleZ
也将相同。因此,您可以调整代码并仅计算一种比例。
不要更改矩阵的平移。字段 12-14 包含绝对翻译。如果你改变它,立方体就会“移动”。
矩阵乘法不可交换。如果你有 2 个尺度矩阵和一个平移矩阵,并按以下顺序将它们相乘:
m = scale2 * translate * scale1
Run Code Online (Sandbox Code Playgroud)
然后translate
与 进行缩放scale2
,但不与 进行缩放scale1
。因此,您无法重置平移缩放,因为此信息将会丢失。矩阵不保存其创建历史。
归档时间: |
|
查看次数: |
292 次 |
最近记录: |