在 3D 模型上选择枢轴点后,我的模型移动到屏幕上的另一个位置。
我正在尝试使用 GL.LookAt 来实现绕枢轴点旋转功能。
GL.MatrixMode(MatrixMode.Modelview);
Matrix4d viewMatrix = Matrix4d.LookAt(cameraPosition, rotatePoint.point, up);
Matrix4d translateToPivot = Matrix4d.CreateTranslation(-rotatePoint.point);
Matrix4d translateBackFromPivot = Matrix4d.CreateTranslation(rotatePoint.point);
Matrix4d rotationX = Matrix4d.CreateRotationX(MathHelper.DegreesToRadians(-angleY));
Matrix4d rotationY = Matrix4d.CreateRotationY(MathHelper.DegreesToRadians(angleX));
Matrix4d rotationMatrix = rotationY * rotationX;
viewMatrix = translateToPivot * rotationMatrix * translateBackFromPivot * viewMatrix;
GL.LoadMatrix(ref viewMatrix);
SetupViewport();
pco.Render(point_size, ShowOctreeOutline, PointCloudColor, mFrustum);
设置Viewport函数:
int w = glControl1.ClientSize.Width;
int h = glControl1.ClientSize.Height;
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
float aspect = w / (float)h;
float n = scaling;
float left = -n * 0.5f, right = n * 0.5f, down = -n * 0.5f / aspect, up = n * 0.5f / aspect;
if (w <= h)
{
GL.Ortho(-1, 1, -aspect, aspect, -1, 1);
}
else
{
GL.Ortho(left, right, down, up, -10.0f, 10.0f);
}
GL.Viewport(0, 0, w, h);
在我的代码中,我没有保存先前的状态,然后将先前的状态乘以我之前所做的转换。
问题是我不断在原始状态上创建一个新的模型矩阵,这样当我在“新状态”上选择新的枢轴基础时,我的模型就会发生变化,但同时将状态重置为原点。必须保存之前的矩阵以便稍后使用,我执行以下步骤(示例代码):
// Global variable
Matrix4d prevModelMatrix = Matrix4d.Identity;
Matrix4d modelMatrix = Matrix4d.Identity;
function Render() {
GL.LoadMatrix(modelMatrix);
...
Transformation... (Use offset instead of using new rotate and translate value to avoid accumulating)
For example:
- GL.Rotate(offsetAngleX, 1,0,0);
...
prevModelMatrix = modelMatrix;
}
// Apply previous state before transforming
function MouseDown() {
Matrix4d offsetRotateMatrix = Matrix4d.Rotate(offsetAngleX, offsetAngleY, 0);
...
modelMatrix = translateToPivotMatrix * offsetRotateMatrix * translateBackFromPivotMatrix * prevModelMatrix;
...
}
// Reset offsets to 0 to avoid Render() function still use the offset to transform the scene
function MouseUp() {
offsetAngleX = 0;
...
}