码迷,mamicode.com
首页 > Windows程序 > 详细

WorldWind源码剖析系列:相机类[未完]

时间:2015-05-31 23:17:45      阅读:1089      评论:0      收藏:0      [点我收藏+]

标签:

PluginSDK中的相机类CameraBase是三维计算机图形学中的概念。观察者在三维场景中漫游时,通过眼睛看到的场景和相机拍摄过程非常一致。实际上,Direct3D和OpenGL都是先通过对现实世界中的场景先进行世界变换,再通过设置观察矩阵以在场景中安置一个虚拟相机,构建一个视景体来裁剪场景的可见区域,然后在通过投影变换(平行投影或透视投影),获取三维场景的“像”,最后再通过视口变换,将场景的“像”光栅化输出到二维显示屏幕上。如下图所示。

技术分享 

在三维地形系统中,通常定义一个虚拟相机来实现对三维场景的漫游等功能。可以通过操纵虚拟相机来实现在虚拟场景中切换和漫游。这种方式实质上是通过不断改变虚拟相机的相关参数(如位置和朝向等),然后通过这些参数重新构造世界矩阵、观察矩阵或投影矩阵来完成场景漫游的。

相机类的类图如下。由CameraBase派生出WorldCamera类,再派生出MomentumCamera类。

技术分享

其中,基类CameraBase主要成员有:地形高程、(所观察的)星球半径(单位为米)、相机所在经度角度_longitude、纬度角度_latitude、相机的朝向角度_heading、_tilt倾斜角度、_bank横滚角度、_distance眼睛到目标的距离、_altitude相机到海平面的高度、四元数m_Orientation、视景体对象_viewFrustum、从星球设置参数获取的相机视场角,相机的_position向量。

同时设置相机的最小倾斜角度为0度,最大倾斜角度为85度。最小高度为10度,最大高度为无穷大。

m_ProjectionMatrix投影变换矩阵、m_ViewMatrix观察变换矩阵、m_WorldMatrix世界变换矩阵。viewRange可视范围角度,trueViewRange真实的可视范围角度,viewPort视口窗口结构体。lastStepZoomTickCount最后一步缩放计数器(与Environment.TickCount结合),cameraUpVector相机的向上向量,初始化默认为Point3d(0,0,1)。ReferenceCenter相机的参考中心,初始化默认为Point3d(0,0,0),lastResetTime最后的重置时间,DoubleTapDelay双Tap延迟。

       m_absoluteViewMatrix、m_absoluteWorldMatrix、m_absoluteProjectionMatrix三个绝对矩阵不清楚与上面的三个相应矩阵有什么区别?还为它们定义了只读的属性AbsoluteViewMatrix、AbsoluteWorldMatrix、AbsoluteProjectionMatrix。

属性Altitude和TargetAltitude分别表示高出海平面的高度和经过移动后目标高出海平面的高度。

属性AltitudeAboveTerrain表示高出地表物体高程的高度。属性TerrainElevation用于设置或获取地表物体高程的高度。

属性Distance和TargetDistance分别表示到目标位置的距离和经过移动后到目标位置的距离。

ComputeDistance( double altitude, Angle tilt )用给定的相机高度和相机倾斜角计算距离。

方法ComputeAltitude( double distance, Angle tilt )的计算示意图如下所示。

技术分享 

方法ComputeTilt(_altitude, _distance) 的计算示意图如上所示。

 

ComputeAbsoluteMatrices()方法里面的矩阵我知道意义,但不太理解其运算的含义。为啥要那样运算?

虚方法Update(Device device)用相机新的世界矩阵、观察矩阵、投影矩阵更新当前场景,同时也更新了视景体的参数、可视范围角度,真实的可视范围角度和World.Settings中关于相机的参数。

虚方法Reset() 用于重置相机的参数。调用了虚方法SetPosition()。

虚方法PointGoto(double lat, double lon)设置相机位置。调用了虚方法SetPosition()。

虚方法SetPosition(double lat, double lon, double heading, double _altitude, double tilt, double bank)真正的被设计用来设置设置相机位置,有三种重载形式。

虚方法virtual void PickingRayIntersection(int screenX, int screenY,out Angle latitude,out Angle longitude)用给定的屏幕像素坐标计算对应位置的经度角度和纬度角度。用构造的向量Vector3 v1 = newVector3(screenX, screenY, Viewport. MinZ)和Vector3 v2 = newVector3(screenX, screenY, Viewport. MinZ)调用了Vector3. Unproject(object viewport, Matrix projection, Matrix view, Matrix world)方法拟向将一个向量从屏幕空间投影到目标空间。然后再用一元二次方程的判别式(Why?)决定经度角度和纬度角度的取值情况。如果判别式>0,则再通过方法MathEngine.CartesianToSphericalD()计算出点对象Point3d p1 = new Point3d(v1.X, v1.Y, v1.Z)和Point3d p2 = new Point3d(v2.X, v2.Y, v2.Z)所对应的球面坐标,最后调用Angle.FromRadians返回以度表示的经度角度和纬度角度。

虚方法ComputeProjectionMatrix(Viewport viewport)计算投影矩阵,用于将三维相机或观察空间坐标转换为二维的屏幕空间坐标。

虚方法RotationYawPitchRoll(Angle yaw, Angle pitch, Angle roll)使相机按照给定的航偏角yaw、倾斜角pitch和横滚角roll旋转,实际上是给相机的经度角度_longitude、纬度角度_latitude、相机的朝向角度_heading重新赋值。如下图所示。

技术分享 

虚方法ZoomStepped通过键盘或鼠标缩放场景。

虚方法Zoom(float percent)在目标距离方向上按指定的百分比缩放。

虚方法Pan(Angle lat, Angle lon)按指定的经、纬度偏移漫游场景。

方法Vector3 Project( Vector3 point ) 用于将世界空间中的三维点转换为二维的屏幕坐标。

静态方法static Angle[] getViewBoundingBox()以度为单位计算可见的外包围盒。

 

WorldWind源码剖析系列:相机类[未完]

标签:

原文地址:http://www.cnblogs.com/rainbow70626/p/4542826.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!