OpenGL 缩放三角形网格到单位立方体
OpenGL Scale Triangle Mesh To Unit Cube
我正在尝试从 .off 文件加载三角形网格并显示以原点为中心并缩放以适合单位立方体的三角形网格。但出于某种原因,我偏离了一个很大的因素,它看起来像
我这样做的方法是找到网格的极值,并使用它来将曲面偏移该量。
float avgX = (maxX + minX) / 2;
float avgY = (maxY + minY) / 2;
float avgZ = (maxZ + minZ) / 2;
Vector3f center(avgX, avgY, avgZ);
Vector3f offset = Vector3f(0, 0, 0) - center;
Translation3f translation(offset);
cout << "offset is: " << endl << offset << endl;
double d_theta = (M_PI / 180);
AngleAxisf rotation(d_theta, Vector3f(0, 0, 1));
float scaleX = (float) 1 / (abs(maxX - minX));
float scaleY = (float) 1 / (abs(maxY - minY));
float scaleZ = (float) 1 / (abs(maxZ - minZ));
AlignedScaling3f scale = AlignedScaling3f(scaleX, scaleY, scaleZ);
然后我将其放入具有
的曲面向量中
Vector3f translatedCenter = translation * rotation * scale * center;
VertexBufferObject VBO;
VBO.init();
VBO.update(Vertices);
program.bindVertexAttribArray("position", VBO);
VertexBufferObject VBO_N;
VBO_N.init();
VBO_N.update(FlatNormals);
program.bindVertexAttribArray("normals", VBO_N);
cout << "updated normals" << endl;
VertexBufferObject VBO_C;
VBO_C.init();
VBO_C.update(C);
program.bindVertexAttribArray("color",VBO_C);
cout << "updated color " << endl;
Surface* s = new Surface(VBO, Vertices, translation, rotation, scale, percentScale, translatedCenter, SmoothNormals, FlatNormals, C);
然后我将它作为 "model"
传递给顶点着色器
Affine3f model = s->getTranslation() * s->getRotation() * s->getScale();
glUniformMatrix4fv(program.uniform("model"), 1, GL_FALSE, model.data());
这一切都是使用 Eigen 库完成的 (https://eigen.tuxfamily.org/dox/group__TutorialGeometry.html#TutorialGeoTransform)
无论我尝试什么,我都会偏离一点点。我做错了什么?
交换平移和旋转:
Affine3f model = s->getRotation() * s->getTranslation() * s->getScale();
请注意,平移会将对象的中心移动到视图的中心。之后旋转矩阵围绕这个中心旋转。
如果您没有任何投影矩阵,则视图 space 是归一化设备 space,其中每个坐标都在 [-1, 1] 范围内。这意味着边的长度是 2 = 1 - (-1)
。计算比例时必须遵守这一点:
float scaleX = (float) 2 / (abs(maxX - minX));
float scaleY = (float) 2 / (abs(maxY - minY));
float scaleZ = (float) 2 / (abs(maxZ - minZ));
我正在尝试从 .off 文件加载三角形网格并显示以原点为中心并缩放以适合单位立方体的三角形网格。但出于某种原因,我偏离了一个很大的因素,它看起来像
我这样做的方法是找到网格的极值,并使用它来将曲面偏移该量。
float avgX = (maxX + minX) / 2;
float avgY = (maxY + minY) / 2;
float avgZ = (maxZ + minZ) / 2;
Vector3f center(avgX, avgY, avgZ);
Vector3f offset = Vector3f(0, 0, 0) - center;
Translation3f translation(offset);
cout << "offset is: " << endl << offset << endl;
double d_theta = (M_PI / 180);
AngleAxisf rotation(d_theta, Vector3f(0, 0, 1));
float scaleX = (float) 1 / (abs(maxX - minX));
float scaleY = (float) 1 / (abs(maxY - minY));
float scaleZ = (float) 1 / (abs(maxZ - minZ));
AlignedScaling3f scale = AlignedScaling3f(scaleX, scaleY, scaleZ);
然后我将其放入具有
的曲面向量中Vector3f translatedCenter = translation * rotation * scale * center;
VertexBufferObject VBO;
VBO.init();
VBO.update(Vertices);
program.bindVertexAttribArray("position", VBO);
VertexBufferObject VBO_N;
VBO_N.init();
VBO_N.update(FlatNormals);
program.bindVertexAttribArray("normals", VBO_N);
cout << "updated normals" << endl;
VertexBufferObject VBO_C;
VBO_C.init();
VBO_C.update(C);
program.bindVertexAttribArray("color",VBO_C);
cout << "updated color " << endl;
Surface* s = new Surface(VBO, Vertices, translation, rotation, scale, percentScale, translatedCenter, SmoothNormals, FlatNormals, C);
然后我将它作为 "model"
传递给顶点着色器Affine3f model = s->getTranslation() * s->getRotation() * s->getScale();
glUniformMatrix4fv(program.uniform("model"), 1, GL_FALSE, model.data());
这一切都是使用 Eigen 库完成的 (https://eigen.tuxfamily.org/dox/group__TutorialGeometry.html#TutorialGeoTransform)
无论我尝试什么,我都会偏离一点点。我做错了什么?
交换平移和旋转:
Affine3f model = s->getRotation() * s->getTranslation() * s->getScale();
请注意,平移会将对象的中心移动到视图的中心。之后旋转矩阵围绕这个中心旋转。
如果您没有任何投影矩阵,则视图 space 是归一化设备 space,其中每个坐标都在 [-1, 1] 范围内。这意味着边的长度是 2 = 1 - (-1)
。计算比例时必须遵守这一点:
float scaleX = (float) 2 / (abs(maxX - minX));
float scaleY = (float) 2 / (abs(maxY - minY));
float scaleZ = (float) 2 / (abs(maxZ - minZ));