这章我们先讲第一人称漫游的实现.在openTK里,我们用函数Matrix4.LookAt(caram.Eye,caram.Target,Vector3.UnitY)来放置摄像机,其中三个参数分别与摄像机位置,摄像机朝向,摄像机向上的向量.与opengl里的glulookat其实是一样的.
本来为了查找漫游的功能,在网上找了些,发现相关讲解都很少,更多只是写出了代码,花了一些时间查找相关概念与调试,其中把我的理解会说明上,有不对的地方欢迎大家指出.
漫游最基本的功能,我们包括相关步进,前进,后退,左进,右进.还有就是视角旋转,包含水平方向旋转,以及垂直方向上的旋转.在讲下面之前,我们先来看下什么是球面坐标系.
引用维基百科里的
在数学里,球坐标系(英语:Spherical coordinate system)是一种利用球坐标 表示一个点 p 在三维空间的位置的三维正交坐标系。
右图显示了球坐标的几何意义:原点与点 P 之间的径向距离 ,原点到点 P 的连线与正 z-轴之间的天顶角
,以及原点到点 P 的连线,在 xy-平面的投影线,与正 x-轴之间的方位角
。
、
、
。
上面的这些大家都好理解,我们的漫游模型可以根据这个来,eye是摄像机位置,p摄像机朝向向量.但是我们的坐标应该是这样的.
根据上面的我们来完成我们摄像机类,如下.
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