制作ADI

地平仪(ADI, Attitude Direction Indicator)用于让飞行器驾驶员知道飞行器的俯仰角和翻滚角。

目的

GLS-地平仪ADI制作_教程

最终效果图

设置工作环境

​ 使用VS2010创建一个名为”_adi”的工程,将GL Studio安装目录下的教程内adi教程的子文件夹”textures”全部复制当前工程下,具体目录结构如下图所示:

GLS-地平仪ADI制作_虚拟仪表_02

GL仪表单元开发

step 1: 打开上述”_adi.gls”文件,后清空GL的Geometry窗口的所有Object。

step 2: 打开Application窗口,命名window title为adi,并设置窗口的初始大小为512 X 512。

​ step 3:点击工具栏中工具GLS-地平仪ADI制作_教程_03上的箭头,在打开窗口中按下述图中红框圈中的内容进行设置。

GLS-地平仪ADI制作_教程_04

创建遮光板

​ 遮光板由一个多边形object和其纹理构成。

step 1: 在工具栏中选中工具GLS-地平仪ADI制作_地平仪_05

step 2: 在”Graphical”窗口拖拽该工具创建出一个512 x 512的矩形,需同时按着”shift”键,让创建的矩形恰好覆盖”Graphical”窗口。

step 3: 在”Geometry”窗口选中刚创建的的矩形,并重名为”adi_panel”。

step 4: 将”Object Properties”选项卡中的”Draw Mode”属性更改为”filled”,这样可以消除绘制在多边形外部区段的轮廓。

step 5:选中刚绘制的矩形”adi_panel”,在”Object Properties”中找到下图红框圈中的选项框,点击省略号按钮,

GLS-地平仪ADI制作_地平仪_06

Texture Chooser的省略号按钮

后进入”Texture Chooser”对话框,

GLS-地平仪ADI制作_虚拟仪表_07

Texture Chooser对话框

点击”Add Texture”按钮,将该工程目录下的texture文件夹下的两个文件’’adi.png’’和‘’adi_ball.png’’全部加载进来,后选中纹理’’adi.png’’,并点击OK。

step 6: 点击下图中圈中的按钮,使纹理恢复其实际尺寸(1:1),

GLS-地平仪ADI制作_GLS_08

使用工具栏中GLS-地平仪ADI制作_虚拟仪表_09功能(Texture Placement Mode),将纹理调整到”adi_panel”矩形的正中央。

GLS-地平仪ADI制作_虚拟仪表_10

纹理的贴图效果

step 7: 在选中”adi_panel”的状态下,修改下图圈中部分的为”unpickable”。

GLS-地平仪ADI制作_GLS_11

​ 这样做的目的是因为,该背光板并不需要与用户之间进行交互。当程序在运行时,若在场景内有用户pick事件发生,则可无需考虑该object,显然这样增加了效率。

创建ADI Ball

​ 创建ADI Ball需要使用球形object。

​ step 1: 使用工具栏中的 GLS-地平仪ADI制作_虚拟仪表_12 功能创建一个球,球的中心应尽量靠近遮光板的中心。

​ step 2: 对其重命名为”adi_ball”。

​ step 3: 在”Object properties”选项卡中对”adi_ball”的属性进行调整,调整如下:

GLS-地平仪ADI制作_ADI_13

​ 设置‘’Mapping Technique’’ 的状态为’‘Modulate’’, 可以确保lighting和Gouraud Shading得到合适的绘制,这样可以呈现逼真的阴影效果。

​ 把”Enable Lighting”设置为ON,会使绘制的球一片漆黑,这是因为场景中尚未有光源来照射该object。这里暂时先不要打开!!!

step 4: 为该球形object设置纹理为”adi_ball.png”。

GLS-地平仪ADI制作_虚拟仪表_14

​ 若纹理没有在球上延展开来,则点击下图中的”Stretch To Fit”, 后调整贴图到合适位置。

GLS-地平仪ADI制作_地平仪_15

​ ”Stretch To Fit”操作可以确保纹理以实际尺寸完整地映射到object上。

GLS-地平仪ADI制作_ADI_16

​ step 5: 在确保 GLS-地平仪ADI制作_地平仪_17 功能为开启的情况下,使用 GLS-地平仪ADI制作_地平仪_18 将”adi_ball”旋转到正确的角度上,如下图示:

GLS-地平仪ADI制作_地平仪_19

​ 当object被旋转之后,DCS坐标同样被旋转了相同的角度,因此需要调整DCS坐标系与世界坐标系相匹配,方法如下:

GLS-地平仪ADI制作_地平仪_20

​ step 6: 在”Geometry”选项卡内点击鼠标右键,选择”Split View”,然后将左侧的view设置为”Y/Z”,而后将”adi_ball” object向Z的负半轴移动,移动到下图位置示:

GLS-地平仪ADI制作_地平仪_21

​ Then, 在选中adi_ball的情况下,点击GLS-地平仪ADI制作_虚拟仪表_22 ,将adi_ball置于遮光板的绘制顺序后面。最后鼠标右键选中”Collapse View”, 将左侧视口销毁。

创造一个光源

​ 场景内需要一个光源来照亮adi_ball。

​ step 1: 将”adi_ball”的”Enable Lighting”属性置为ON。

​ step 2: 在工具栏中选中GLS-地平仪ADI制作_教程_23,可随意在”Geometry”选项卡窗口放置光源。

​ step 3: 在”Geometry”选项卡窗口中使用”Y/Z”视口,并调整光源的位置使其在Z的正半轴能正对”adi_ball”,并保持一定的距离,如下图示。其他视口应尽量照着”adi_ball”的正中央。

GLS-地平仪ADI制作_ADI_24

​ step 4: 做下图调整:(将光源的恒定衰减设为0.7,光源类型设为局部的)

GLS-地平仪ADI制作_地平仪_25

局部的光源更像是一个电灯泡,向四面八方发出光线,这也就使得ADI显得更加逼真。而若使用”Infinite”模式的光源,更像是太阳一样发出的平行光。

创建水平bar

​ step1: 使用GLS-地平仪ADI制作_GLS_26工具在”adi_ball”上粗略的绘制一个能覆盖地平线中心并有足有宽度的矩形,并重命名为”horizon_line”。(仔细看清下图矩形的覆盖范围)

GLS-地平仪ADI制作_教程_27

​ step 2: 改变”horizon_line”的”Draw Mode” 为“Filled”。使用”adi.png”纹理,且需使用”Actual Size”, 后在纹理放置模式( GLS-地平仪ADI制作_虚拟仪表_28)下,调整纹理中的水平线部分放置成下图样式:

GLS-地平仪ADI制作_GLS_29

编译并运行

​ 返回到VS平台,使用组合键”Ctrl+F5”, 运行程序,可以看到部分效果,但尚不能看到ADI动画效果。

代码开发

​ 代码部分就是为仪表定义一些行为。

添加测试属性

​ step 1: 在”Code”选项卡窗口的任意地方右键”Add->Property”, 这将为当前仪表创建一个新的属性。

​ step 2: 将该属性的”Type”改为”bool”型的,改其”name”为”Testing”,改其”Initial Value”为”true”。

GLS-地平仪ADI制作_GLS_30

添加属性来处理Pitch/Roll

​ “Pitch”属性来处理object关于x轴的旋转,”Roll”属性来处理关于z轴的。

​ step 1: 创建一个名为”Pitch”的float型属性,并拥有为0.0f的初始值。

​ step 2: 将下属代码添加到属性的设置函数内(即void Pitch( const float& value )):

\1. //Clamp the incoming values to a range between -90.0f and 90.0f

\2. _pitch = CLAMP_VALUE(value, -90.0f, 90.0f);

\3. adi_ball->DynamicRotate(_pitch, X_AXIS);

该段代码将可以实现”adi_ball”以x轴为中心在(-90.0f, 90.0f)的范围内动态旋转的功能。

​ step 3: 创建一个名为”Roll”的float型属性,并拥有为0.0f的初始值。

​ step 4: 同样将下属代码添加到属性的设置函数内:

\1. // Clamp the incoming values to a range between -180.0f and 180.0f

\2. _roll = CLAMP_VALUE(value, -180.0f, 180.0f);

\3. adi_ball->DynamicRotate(_roll, Z_AXIS);

计算

​ 函数Calculate()用于周期性地驱动仪表,且在每帧渲染前被调用。若函数体过大,就会对程序的实时性造成了一定的影响。

step 1: 展开”Class Method”后选中Calculate()函数,在代码输入框中追加下属代码:

\1. if (Testing())

\2. {

\3. // Exercise the Pitch and Roll properties with

\4. // input values generated from RampFloat.

\5. Pitch( RampFloat(time / 2, -25, 40) );

\6. Roll( RampFloat(time / 3, -30, 30) );

\7. }

包含glsutil.h的效用函数

因为Calculate()函数中用到了ramping函数,而这些函数包含在头文件”glsutil.h”内,故该头文件需要被添加到我们的类中。

step 1: 在”Code”选项卡中选中”file _adiApp.h”选项,在代码输入框内输入如下内容:

\1. #include <glsutil.h>

编译+运行+测试

mpFloat(time / 3, -30, 30) );

\7. }

包含glsutil.h的效用函数

因为Calculate()函数中用到了ramping函数,而这些函数包含在头文件”glsutil.h”内,故该头文件需要被添加到我们的类中。

step 1: 在”Code”选项卡中选中”file _adiApp.h”选项,在代码输入框内输入如下内容:

\1. #include <glsutil.h>

编译+运行+测试

​ ADI动画般的动起来,就是通过效用函数RampFloat()传递到Pitch和Roll的值。

GLS-地平仪ADI制作_ADI_31