点以圆形路径而不是直线移动 - OPENGL
Point moving in circular path instead of straight line- OPENGL
我试图让一个点在 2d 中跟随光标。该点应始终位于光标正下方。我试过使用光线投射,但点在圆形路径而不是 2d 直线上移动。
我想也许我需要用一个平面来限制点的移动,但我不知道该怎么做。
protected override void OnMouseMove(MouseMoveEventArgs e)
{
MouseState mstate = Mouse.GetCursorState();
mousePos1 = this.PointToClient(new Point(mstate.X, mstate.Y));
}
protected override void OnRenderFrame(FrameEventArgs e)
{
Matrix4 projectionM = Matrix4.CreateOrthographicOffCenter(-1.05f, 1.05f, -1.25f, 1.25f,
-100f, 100.0f);
Matrix4 viewM = Matrix4.Identity ;
Vector3 cursorPos = raycasting(mousePos1.x, mousePos1.y, projectionM, viewM);
float[] cursors = new float[] { cursorPos.X, cursorPos.Y,cursorPos.Z};
//binding buffer arrays//
shader4.Use();
GL.UniformMatrix4(0, false, ref viewM);
GL.UniformMatrix4(1, false, ref projectionM);
shader4.SetFloat("color", new Vector4(1.0f, 1.0f, 1.0f, 1));
GL.BindVertexArray(_vao);
GL.PointSize(5);
GL.DrawArrays(PrimitiveType.Points, 0, 1);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.BindVertexArray(0);
shader4.Unbind();
}
private Vector3 raycasting(float X, float Y, Matrix4 proj, Matrix4 vi)
{
float x = (2.0f * X) /(float) this.Width - 1.0f;
float y = 1.0f;
float z = 1.0f;
Vector3 normalized_device_coordinates_ray = new Vector3(x, y, z);
// Homogeneous Clip Coordinates
Vector4 homogeneous_clip_coordinates_ray = new Vector4(normalized_device_coordinates_ray.X, normalized_device_coordinates_ray.Y, -1.0f, 1.0f);
// 4D Eye (Camera) Coordinates
Vector4 camera_ray = Matrix4.Invert(proj) * homogeneous_clip_coordinates_ray;
camera_ray = new Vector4(camera_ray.X, camera_ray.Y, -1.0f, 0.0f);
// 4D World Coordinates
Vector3 world_coordinates_ray = (Matrix4.Invert(vi) * camera_ray).Xyz;
world_coordinates_ray.Normalize();
return world_coordinates_ray;
}
这有两个主要问题:
- 正如我所说,点以圆周或径向移动而不是像光标那样直线移动
- 该点不在光标正下方。
标准化设备坐标在 [-1, 1] 范围内。从 window 坐标中获取 NDC 坐标,如下所示:
float x = 2.0f * X / (float)this.Width - 1.0f;
float y = 1.0f - 2.0f * Y / (float)this.Height;
一般情况下,你必须在逆投影矩阵(Perspective divide)变换后除以xyz
分量除以w分量。您可以跳过它,因为您使用正交投影并且 w 分量为 1。
但是由于您使用的是正交投影,因此您计算的不是射线,而是点。因此 world_coordinates_ray
的规范化是错误的。
Vector3 world_coordinates_ray = (Matrix4.Invert(vi) * camera_ray).Xyz;
// world_coordinates_ray.Normalize(); <--- DELETE
我试图让一个点在 2d 中跟随光标。该点应始终位于光标正下方。我试过使用光线投射,但点在圆形路径而不是 2d 直线上移动。
我想也许我需要用一个平面来限制点的移动,但我不知道该怎么做。
protected override void OnMouseMove(MouseMoveEventArgs e)
{
MouseState mstate = Mouse.GetCursorState();
mousePos1 = this.PointToClient(new Point(mstate.X, mstate.Y));
}
protected override void OnRenderFrame(FrameEventArgs e)
{
Matrix4 projectionM = Matrix4.CreateOrthographicOffCenter(-1.05f, 1.05f, -1.25f, 1.25f,
-100f, 100.0f);
Matrix4 viewM = Matrix4.Identity ;
Vector3 cursorPos = raycasting(mousePos1.x, mousePos1.y, projectionM, viewM);
float[] cursors = new float[] { cursorPos.X, cursorPos.Y,cursorPos.Z};
//binding buffer arrays//
shader4.Use();
GL.UniformMatrix4(0, false, ref viewM);
GL.UniformMatrix4(1, false, ref projectionM);
shader4.SetFloat("color", new Vector4(1.0f, 1.0f, 1.0f, 1));
GL.BindVertexArray(_vao);
GL.PointSize(5);
GL.DrawArrays(PrimitiveType.Points, 0, 1);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.BindVertexArray(0);
shader4.Unbind();
}
private Vector3 raycasting(float X, float Y, Matrix4 proj, Matrix4 vi)
{
float x = (2.0f * X) /(float) this.Width - 1.0f;
float y = 1.0f;
float z = 1.0f;
Vector3 normalized_device_coordinates_ray = new Vector3(x, y, z);
// Homogeneous Clip Coordinates
Vector4 homogeneous_clip_coordinates_ray = new Vector4(normalized_device_coordinates_ray.X, normalized_device_coordinates_ray.Y, -1.0f, 1.0f);
// 4D Eye (Camera) Coordinates
Vector4 camera_ray = Matrix4.Invert(proj) * homogeneous_clip_coordinates_ray;
camera_ray = new Vector4(camera_ray.X, camera_ray.Y, -1.0f, 0.0f);
// 4D World Coordinates
Vector3 world_coordinates_ray = (Matrix4.Invert(vi) * camera_ray).Xyz;
world_coordinates_ray.Normalize();
return world_coordinates_ray;
}
这有两个主要问题:
- 正如我所说,点以圆周或径向移动而不是像光标那样直线移动
- 该点不在光标正下方。
标准化设备坐标在 [-1, 1] 范围内。从 window 坐标中获取 NDC 坐标,如下所示:
float x = 2.0f * X / (float)this.Width - 1.0f;
float y = 1.0f - 2.0f * Y / (float)this.Height;
一般情况下,你必须在逆投影矩阵(Perspective divide)变换后除以xyz
分量除以w分量。您可以跳过它,因为您使用正交投影并且 w 分量为 1。
但是由于您使用的是正交投影,因此您计算的不是射线,而是点。因此 world_coordinates_ray
的规范化是错误的。
Vector3 world_coordinates_ray = (Matrix4.Invert(vi) * camera_ray).Xyz;
// world_coordinates_ray.Normalize(); <--- DELETE