背景
我目前正在尝试根据我的鼠标位置进行光线投射,然后将其用于确定它与我的对象相交的位置。到目前为止,我所拥有的是一条连接相机中心和原点的线,这将始终是我的焦点。我能够取消我的鼠标以获得它的x,y,z坐标。我也能够从那个未投影的位置创建一条线,该线与我用相机和原点创建的线平行。
问题
我遇到的问题是新行无法正确投射到我的对象中。我相信这是因为我在投影模式下查看所有内容,从而使一切看起来都是收敛的。我的问题是,如果有办法调整我的线投影以考虑正在发生的收敛?
在上图中,橙色线代表我的新光线,绿色圆圈代表光标所在的位置。通过数学证实,它确实与我的相机与原点矢量平行,但显然不会出现这种情况。我相信这是我正在谈论的融合,但如果你不相信这是真正的问题,请纠正我。
据说我的屏幕上应该出现一个点,因为我点击的投影线将以相同的角度进入屏幕。如果我的所有假设都是真的,那么我该如何解释这种差异呢?
证明我的线条是平行的
为了证明我的线条是平行的,我保存了我的原始矢量和我的新矢量,绘制它们,然后旋转以查看它们的位置。黄线代表从我的相机到原点的线,橙色是新线。我查了一下,黄线的长度等于橙色的长度。此外绿色和紫色相等,这证明我的线是平行的
我的抽奖活动
Private Sub GlControl1_Paint(ByVal sender As System.Object,ByVal e As System.Windows.Forms.PaintEventArgs)处理GlControl1.Paint
GL.Clear(ClearBufferMask.ColorBufferBit)
GL.Clear(ClearBufferMask.DepthBufferBit)
GL.DepthMask(True)
GL.Enable(EnableCap.DepthTest)
GL.ClearDepth(1.0F)
GL.MatrixMode(MatrixMode.Modelview)
GL.LoadIdentity()
Dim lightColor0 As Single() = {intensity, intensity, intensity, 1.0F}
Dim lightPos0 As Single() = {camx, camy, camz, 1.0F}
GL.Light(LightName.Light0, LightParameter.Diffuse, lightColor0)
GL.Light(LightName.Light0, LightParameter.Position, lightPos0)
GL.Enable(EnableCap.Light0)
Dim mat_specular As Single() = {1.0F, 1.0F, 1.0F, 1.0F}
Dim mat_shininess As Single() = {50.0F}
GL.Material(MaterialFace.Front, MaterialParameter.Specular, mat_specular)
GL.Material(MaterialFace.Front, MaterialParameter.Shininess, mat_shininess)
GL.Disable(EnableCap.Lighting)
GL.Begin(PrimitiveType.Lines)
GL.Color3(Color.Red)
GL.Vertex3(0, 0, 0)
GL.Vertex3(100, 0, 0)
GL.Color3(Color.Green)
GL.Vertex3(0, 0, 0)
GL.Vertex3(0, 100, 0)
GL.Color3(Color.Blue)
GL.Vertex3(0, 0, 0)
GL.Vertex3(0, 0, 100)
GL.End()
GL.Begin(PrimitiveType.Lines)
GL.Color3(Color.DarkRed)
GL.Vertex3(0, 0, 0)
GL.Vertex3(-100, 0, 0)
GL.Color3(Color.DarkGreen)
GL.Vertex3(0, 0, 0)
GL.Vertex3(0, -100, 0)
GL.Color3(Color.DarkBlue)
GL.Vertex3(0, 0, 0)
GL.Vertex3(0, 0, -100)
GL.End()
Dim projmatrix As Matrix4
GL.GetFloat(GetPName.ProjectionMatrix, projmatrix)
Dim modelmatrix As Matrix4
GL.GetFloat(GetPName.ModelviewMatrix, modelmatrix)
Dim mouse_ As New Vector2(_mouseStartX, _mouseStartY)
Dim returnvec As Vector4
returnvec = UnProject(projmatrix, modelmatrix, GlControl1.Size, mouse_)
GL.Begin(PrimitiveType.Lines)
GL.Color3(Color.Orange)
Dim XL0, YL0, ZL0 As Single
XL0 = camx
YL0 = camy
ZL0 = camz
'origin is at 0,0,0
'
Dim XL1, YL1, ZL1 As Single
XL1 = 0
YL1 = 0
ZL1 = 0
Dim XS, YS, ZS As Single
XS = XL1 - XL0
YS = YL1 - YL0
ZS = ZL1 - ZL0
Dim length As Single = Sqrt(XS * XS + YS * YS + ZS * ZS)
XS /= length
YS /= length
ZS /= length
Dim origin As New Vector3(0, 0, 0)
Dim mouse_position As New Vector3(returnvec.X, returnvec.Y, returnvec.Z)
Dim camera_position As New Vector3(cam.Position.X, cam.Position.Y, cam.Position.Z)
Dim newpoint As Vector3
newpoint = mouse_position + (origin - camera_position).Normalized * length
Dim newxs, newys, newzs As Single
newxs = newpoint.X - returnvec.X
newys = newpoint.Y - returnvec.Y
newzs = newpoint.Z - returnvec.Z
Dim newlength As Single = Sqrt(newxs * newxs + newys * newys + newzs * newzs)
newxs /= newlength
newys /= newlength
newzs /= newlength
GL.Vertex3(newpoint.X, newpoint.Y, newpoint.Z)
GL.Vertex3(mouse_position.X, mouse_position.Y, mouse_position.Z)
GL.End()
GL.LineWidth(2.0F)
GL.Begin(PrimitiveType.Lines)
GL.Color3(Color.Yellow)
GL.Vertex3(0, 0, 0)
GL.Vertex3(camloc(0), camloc(1), camloc(2))
GL.End()
GL.Begin(PrimitiveType.Lines)
GL.Color3(Color.LimeGreen)
GL.Vertex3(mouse_position.X, mouse_position.Y, mouse_position.Z)
GL.Vertex3(camloc(0), camloc(1), camloc(2))
GL.End()
GL.Begin(PrimitiveType.Lines)
GL.Color3(Color.Purple)
GL.Vertex3(newpoint.X, newpoint.Y, newpoint.Z)
GL.Vertex3(0, 0, 0)
GL.End()
Label4.Text = "green length = " & Sqrt((camloc(0) - mouse_position.X) ^ 2 + (camloc(1) - mouse_position.Y) ^ 2 + (camloc(2) - mouse_position.Z) ^ 2) & _
" purple length = " & Sqrt((newpoint.X) ^ 2 + (newpoint.Y) ^ 2 + (newpoint.Z) ^ 2)
Label3.Text = "yellow length = " & Sqrt((camloc(0)) ^ 2 + (camloc(1)) ^ 2 + (camloc(2)) ^ 2) & _
" orange length = " & Sqrt((newpoint.X - mouse_position.X) ^ 2 + (newpoint.Y - mouse_position.Y) ^ 2 + (newpoint.Z - mouse_position.Z) ^ 2)
GL.Enable(EnableCap.Lighting)
draw_extras()
GL.Flush()
GlControl1.SwapBuffers()
Label1.Text = distance
End Sub
我的非项目功能
Public Shared Function UnProject(ByRef projection As Matrix4, view As Matrix4, viewport As Size, mouse As Vector2) As Vector4
Dim vec As Vector4
vec.X = 2.0F * mouse.X / CSng(viewport.Width) - 1
vec.Y = -(2.0F * mouse.Y / CSng(viewport.Height) - 1)
vec.Z = 0
vec.W = 1.0F
Dim viewInv As Matrix4 = Matrix4.Invert(view)
Dim projInv As Matrix4 = Matrix4.Invert(projection)
Vector4.Transform(vec, projInv, vec)
Vector4.Transform(vec, viewInv, vec)
If vec.W > Single.Epsilon OrElse vec.W < Single.Epsilon Then
vec.X /= vec.W
vec.Y /= vec.W
vec.Z /= vec.W
End If
Return vec
End Function
SetupViewport功能
Public Sub SetupViewport()
Dim w As Integer = GlControl1.Width
Dim h As Integer = GlControl1.Height
Dim perspective1 As Matrix4 = cam.GetViewMatrix() * Matrix4.CreatePerspectiveFieldOfView(1.3F, ClientSize.Width / CSng(ClientSize.Height), 0.1F, 200.0F)
GL.MatrixMode(MatrixMode.Projection)
GL.LoadIdentity()
GL.LoadMatrix(perspective1)
GL.MatrixMode(MatrixMode.Modelview)
GL.LoadIdentity()
GL.Viewport(0, 0, w, h)
GL.Enable(EnableCap.DepthTest)
GL.DepthFunc(DepthFunction.Less)
End Sub
答案 0 :(得分:0)
在您的取消投影功能更改
中vec.X = 2.0F * mouse.X / CSng(viewport.Width) - 1
vec.Y = -(2.0F * mouse.Y / CSng(viewport.Height) - 1)
到
vec.X = 2.0F * mouse.X / CSng(viewport.Width) - 1
vec.Y = 2.0F * mouse.Y / CSng(viewport.Height) - 1