这章我们先讲第一人称漫游的实现.在openTK里,我们用函数Matrix4.LookAt(caram.Eye,caram.Target,Vector3.UnitY)来放置摄像机,其中三个参数分别与摄像机位置,摄像机朝向,摄像机向上的向量.与opengl里的glulookat其实是一样的.

本来为了查找漫游的功能,在网上找了些,发现相关讲解都很少,更多只是写出了代码,花了一些时间查找相关概念与调试,其中把我的理解会说明上,有不对的地方欢迎大家指出.

漫游最基本的功能,我们包括相关步进,前进,后退,左进,右进.还有就是视角旋转,包含水平方向旋转,以及垂直方向上的旋转.在讲下面之前,我们先来看下什么是球面坐标系.

引用维基百科里的Opengl绘制我们的小屋(二)第一人称漫游

数学里,球坐标系英语Spherical coordinate system)是一种利用球坐标 Opengl绘制我们的小屋(二)第一人称漫游 表示一个点 p 在三维空间的位置的三维正交坐标系

右图显示了球坐标的几何意义:原点与点 P 之间的径向距离 Opengl绘制我们的小屋(二)第一人称漫游 ,原点到点 P 的连线与正 z-轴之间的天顶角 Opengl绘制我们的小屋(二)第一人称漫游 ,以及原点到点 P 的连线,在 xy-平面的投影线,与正 x-轴之间的方位角 Opengl绘制我们的小屋(二)第一人称漫游

Opengl绘制我们的小屋(二)第一人称漫游Opengl绘制我们的小屋(二)第一人称漫游Opengl绘制我们的小屋(二)第一人称漫游

上面的这些大家都好理解,我们的漫游模型可以根据这个来,eye是摄像机位置,p摄像机朝向向量.但是我们的坐标应该是这样的.

Opengl绘制我们的小屋(二)第一人称漫游

根据上面的我们来完成我们摄像机类,如下.

 1     type Camera() = 
 2         let mutable eye = Vector3.Zero
 3         let mutable eyeLength = 1.
 4         let mutable yangle = 0.
 5         let mutable xangle= Math.PI/2.
 6         member this.Eye 
 7             with get() = eye 
 8             and set value = eye <- value
 9         member this.EyeLength 
10             with get() = eyeLength 
11             and set value = 
12                 if value < 0. then eyeLength <- 0.1
13                 eyeLength <- value
14         member this.YAngle 
15             with get() = yangle
16             and set value = 
17                 if value > Math.PI then yangle <- 0.
18                 //elif value < 0. then yangle <- Math.PI 
19                 else yangle <- value
20         member this.XAngle 
21             with get() = xangle
22             and set value = 
23                 printfn "xangle:%f" value
24                 if value > 2.* Math.PI then xangle <- 0.
25                 elif value < 0. then xangle <- 2. * Math.PI
26                 else xangle <- value
27         member this.Target 
28             with get() = 
29                 //printfn "%f" this.XAngle 
30                 let xyLength = Math.Cos(this.YAngle)
31                 let x:float =float eye.X + eyeLength * xyLength * Math.Cos(this.XAngle)
32                 let y:float =float eye.Y + eyeLength * Math.Sin(this.YAngle)
33                 let z:float =float eye.Z + eyeLength * xyLength * Math.Sin(this.XAngle)
34                 Vector3(float32 x,float32 y,float32 z)
35         member this.Transelt (x,y,z) = 
36             let sinX = Math.Sin(this.XAngle)
37             let cosX = Math.Cos(this.XAngle)
38             let x1 = float this.Eye.X + x * sinX + z * cosX
39             let y1 = float this.Eye.Y + y
40             let z1 = float this.Eye.Z + z * sinX - x * cosX
41             printfn "angle:%f, sinx:%f, cosx:%f" this.XAngle sinX cosX
42             printfn "x:%f, y:%f, z:%f" x1 y1 z1
43             this.Eye <- new Vector3(float32 x1,float32 y1,float32 z1)
44         member this.UpAndDown y =
45             let ya = this.YAngle + y
46             this.YAngle <- ya
47         member this.RightAndLeft x =
48             let xa = this.XAngle + x
49             this.XAngle <- xa
50         member this.Rotate (x,y) =
51             let xa = this.XAngle + x
52             let ya = this.YAngle + y
53             this.YAngle <- ya
54             this.XAngle <- xa
View Code

相关文章: