[英]4x4 matrix reset scaling?
使用 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(?);
有沒有辦法在保持絕對平移/旋轉的同時重置比例?
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
基於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;
它看起來很有希望,但到目前為止,過去放大的現在正在縮小,反之亦然。 此外,還有一些擺動效果表明有些地方不太對勁。
知道矩陣,您可以計算每個軸的比例。 下面的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]);
如果要在保持絕對平移和旋轉的同時“重置”比例,則需要對軸進行歸一化。 歸一化向量(單位向量)的長度為 1:
for (int i = 0; i < 3; ++i)
{
cm[0][i] /= scaleX;
cm[1][i] /= scaleY;
cm[2][i] /= scaleZ;
}
如果 3 軸的比例相同,則scaleX
、 scaleY
、 scaleZ
的結果也將相同。 因此,您可以調整代碼並只計算一個比例。
不要改變矩陣的平移。 字段 12-14 包含絕對翻譯。 如果你改變它,立方體“移動”。
矩陣乘法不是可交換的。 如果您有 2 個比例矩陣和一個平移矩陣,並按以下順序將它們相乘:
m = scale2 * translate * scale1
然后translate
使用scale2
縮放,但不使用scale1
。 因此,您無法重置平移縮放,因為此信息將丟失。 矩陣不保存其創建歷史。
您可以將轉換存儲為 3 個向量/矩陣,用於平移、旋轉和縮放,並在需要時從它們創建一個矩陣:
void CreateMatrix(Matrix4 translation, Matrix4 rotation, Matrix4 scale, Matrix4& out) {
out = scale * rotation * translation;
}
void Translate(Matrix4 translate, Matrix4& translation, Matrix4& rotation, Matrix4& scale) {
translation *= translate;
}
void Rotate(Matrix4 rotate, Matrix4& translation, Matrix4& rotation, Matrix4& scale) {
translation *= rotate;
scale *= rotate;
rotation *= rotate;
}
void Scale(Matrix4 scaling, Matrix4& translation, Matrix4& rotation, Matrix4& scale) {
translation *= scaling;
scale *= scaling;
}
要重置比例,請將比例矩陣設置為身份/比例向量為零。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.