理解EV-Globe体系结构的基本概念
2023-01-03 09:58:09
154次阅读
0个评论
最后修改时间:2023-01-03 11:16:45


理解EV-Globe体系结构的基本概念

工作空间

工作空间是用户的工作环境,用于保存用户的工作环境和工作过程中操作和处理的所有数据,包括数据源、地图配置、三维场景配置、图层属性等内容。

工作空间存放了数据源名称、地图及场景配置等信息。由于工作空间存放的是数据源的相对路径和名称,而没有存储和拷贝整个数据源,因此工作空间文件可以和数据源(文件)分开存放,工作空间中使用的空间数据仍然存储于数据源中。

地图由一系列有序图层构成。工作空间中的地图存储了地图中每个图层对应的数据源和数据集、地图的显示风格、显示比例、专题地图和图层的状态信息(显示、选择、编辑)等。

三维场景中存储了三维场景的一些设置信息,如相机参数、环境光、自然环境、海水、光源、纯色地形等配置信息,同时也存储了场景中的图层使用的数据集信息、风格设置、可见距离(级别)控制、状态信息等。;

作为用户的工作环境,同时只允许有一个工作空间。因此:

1)不要在同一个应用程序中加载超过一个工作空间控件。

2)打开一个工作空间文件之前,必须关闭当前工作空间文件。

此外还需要注意的是:

1)由于地图、三维场景中设置的参数等都是直接保存在工作空间中的,所以如果他们之中有修改,必须要保存工作空间。

2)如果使用的是文件型数据源,那么在复制或者移动工作空间文件时,还必须连同数据源文件一起复制或者移动, 并保持两者的相对路径不变。

数据源

数据源是存储空间数据和三维场景数据的场所。所有的空间和三维场景数据都存储于数据源而不是工作空间,任何对空间数据或三维场景数据的操作都需要先获得并且打开数据源。

EV-Globe SDK的数据源分为文件型数据源、数据库型数据源、网络数据源。文件型数据源是把空间、属性、三维场景的数据直接存储到文件中;数据库型数据源是把空间、属性、三维场景数据一体化存储到关系型数据库中;网络数据源是通过EV-Server提供的服务直接获得空间、属性、三维场景数据。EV-Globe SDK的文件型数据源和数据库型数据源又分别支持多种文件格式和数据库。一个工作空间中可以打开多个数据源,各种数据源通过不同的别名进行标识。

数据集

数据集是 EV-Globe SDK数据的基本组织单位之一。一个数据源通常由一个或多个不同类型的数据集组成,同时数据集也是图层的数据来源。

其中每种数据源所能包含的数据集种类也是不一样的,EV-Globe SDK下各种数据源所包含的数据集种类如下:


图层

当相应的数据集被加载到地图或三维场景窗口中显示时被称为图层,因此图层是数据集的可视化定义。通俗的讲,图层就像是含有文字或图形等元素的胶片,一张张按顺序叠放在一起,组合起来形成最终的效果。

一般情况下,一个图层对应着一个数据集。同一个数据集可以被多次添加到不同的地图窗口或三维场景中,而且可以赋予不同的显示风格,因此,同一个数据集可能对应不同地图或三维场景上的多个图层。

图层状态是可以控制的,比如可以设置显示或隐藏、可选择或不可选择、可编辑或不可编辑、有的图层之间的上下顺序也可以被改变(比如地图中的矢量图层,三维场景中的影像或Dem图层),对于三维数据集,还可以设置三维模型拉伸系数以及显示风格等。

其中地图图层支持矢量、栅格、海图、网络矢量数据集,三维场景图层支持矢量、KML、模型、特效、海图、网络矢量瓦片、影像、DEM数据集。


地图

一个或者多个数据集(包括矢量、栅格、海图、网络矢量数据集)被赋予一定的显示风格而显示在一个地图控件中,就成为地图。

地图定义了各图层的名称、显示风格、可见范围、图层状态和图层顺序等信息,保存地图时这些信息都将一起保存在工作空间中。

地图中的数据集来源于各数据源。在制作地图并保存后,如将对应的数据源删除,则相应的地图就会失去数据来源,打开工作空间中的地图将会出现没有数据的情况。此外,在制作地图后,如对相应数据集中的对象进行了编辑修改,则地图刷新后也会相应更新。

场景

场景这里指的是三维场景,一个或者多个数据集(包括KML、模型、特效、矢量、影像、DEM数据集)按照一定的空间组织结构叠加在一个地球上,在一个地球控件窗口中显示,就成为场景。

场景定义了场景的名称、自然环境配置、海水配置、地形参数、光照参数、各图层的名称、显示风格、可见范围、图层状态和图层顺序等信息,保存场景时这些信息都将一起保存在工作空间中。

场景中的数据集来源于各数据源。在制作场景并保存后,如将对应的数据源删除,则相应的场景就会失去数据来源,打开工作空间中的场景将会出现没有数据的情况。  

几何对象

几何对象是空间要素的基本组成部分,也是进行增删改操作、空间分析和属性查询的基本单位。EV-Globe SDK提供了十余种几何对象,除常见的点、线、面、几何对象之外,还提供了复杂的几何对象如多点类型、曲线环、圆弧、椭圆弧、圆面、三角面、矩形面、贝赛尔曲线、贝赛尔曲面等几何对象。

场景管理器

场景管理器对象应该是场景中最重要的部分了。场景管理器控制场景中的所有内容,它还负责组织创建管理所有的摄像机、可移动的对象、光源和材质等,并且管理场景中静态的部分,比如:整个场景地形、影像。

当你想要为场景创建一个摄像机或是在场景中添加或者删除一个光源时,你必须通过场景管理器来实现。你没有必要在你的应用程序中维护这些对象的列表,场景管理器管理着场景中所有的对象,你只需要通过这些对象的名称就可以在场景管理器中获取该对象。

当需要绘制场景时,只要将可移动对象挂接到了场景节点上,场景管理器会将场景送到渲染系统对象中去自动绘制。如果你创建了自己的帧监听器对象,你还可以在程序运行的过程中动态修改场景中的内容。

虚拟相机

场景中的虚拟相机,是场景中的眼睛,最主要的工作就是定义产生一个截头体来处理渲染工作。

更细致一点说,它是一个包含眼睛所能看到所有内容的盒子”,相机利用这个盒子的的六个面来剔出场景中不可见的物体,从而达到眼睛一样的效果。

同时相机也是场景中的可移动物体,所以它也可以有移动、旋转等操作(截头体也一同被操作)。从而可以达到在不同位置和角度来展现场景的目的。


渲染系统

EV-Globe SDK的渲染系统(RenderSystem)主要是针对场景而言,场景中渲染出来的东西最终都是通过它来实现的,渲染系统隔离了对底层Direct3DOpenGL原生态接口的直接访问,它负责设置所有的渲染参数并且传送渲染指令给底层的API,因此其具体实现依赖于某个具体底层三维图形库如Directx3D,OpenGLAPI接口。

然而,一个通常意义上的应用程序不会直接操作渲染系统对象,你需要渲染的所有对象和场景设定都可以由场景管理器、材质或其它面向场景的类来完成。只有当你想要自己创建渲染窗口或者想要访问其它高级特性时,你才需要访问渲染系统。

渲染目标

    顾名思义,渲染目标(RenderTarget)就是渲染结果显示的地方。其中既包括硬件的缓存(包括帧缓存以及其他),也包括诸如纹理一样的储存区域。在渲染到硬件缓存的时候,渲染目标表示的就是你应用程序使用的窗口。当渲染到纹理的时候,你可以在程序的任何地方如同普通纹理一样使用它。

    目前EV-Globe SDK支持三种不同的渲染目标类型,包括:窗口渲染目标“RenderWindow”、纹理渲染目标“RenderTexture”以及用于绑定多个渲染目标的“MultiRenderTarget”类型。

    同时,我们也可以向渲染目标对象中注册自己的监听者实例,这时候渲染目标就是一个事件源(可以参考设计模式中的观察者模式)。不论是渲染开始或者结束,以及渲染设置和对象可见性的改变都会让渲染目标向你的监听者实例中调用相应的事件处理。同时它也可以把视口层的变化事件提供给用户,其中包括视口的增加和移除事件。

视口

视口(Viewport)是这样一个矩形区域,它把从摄像机得到的内容映射到渲染目标上面。在同一个渲染目标中可以包含一个或者更多的视口。视口在初始化的时候需要得到一个摄像机对象的实例,但是它们并没有被静态绑定,所以你可以在任何时候把视口和另外的摄像机重新绑定到一起。

视口是渲染目标和摄像机唯一的通道。换句话说,它是渲染系统和场景管理器与其内容的唯一入口。视口可以被称为“场景中的窗户”。

虽然大多数时候,视口会占据你渲染目标的全部空间。但这并不是必要的,你可以用一些非占据全部空间的“小”视口实现相当有趣的效果。比如你可以在一个赛车游戏中,用一个小视口代表赛车中后视的效果,“镜子”里面的视口包含面向后方或者的摄像机的渲染结果。另外的例子是,在一些战争模拟游戏中,通过一个更接近目标的摄像来机实现画中画放大的视口效果。

可移动对象

可移动对象(MovableObject)是场景中渲染不可或缺的一个重要对象,它由场景管理器创建,并且绑定到场景节点上,最后再由场景管理器销毁。因为这些内容独立于场景图,所以可以根据需要随时从场景节点上分离或者挂接,也可以在一个节点上挂接多个活动物体。不过需要注意的是同一时间内一个活动物体只能被挂接到一个场景节点上。

通过它可以直接操作所有几何体和渲染属性。它并不是场景节点的子类,而是挂接到场景节点中(可以理解为通过组合代替继承)。这意味着如果你需要,程序中的场景节点可以不用了解与之相关的可渲染对象的任何细节。也意味着你可以扩展、改变、重写场景图的实现,而不会影响场景内容接口的设计和实现,它起到了一个场景节点和具体的渲染对象中间桥梁的作用。

可渲染对象

EV-Globe SDK中最基本的渲染单元被称为可渲染对象(Renderable),可移动对象通过聚合可渲染对象,然后挂接到场景节点上(场景节点描述请参见1.1.16章节),才能渲染出我们想要的几何体。可渲染对象通过不同的渲染状态被分类传递到渲染队列中去。当渲染到不同的材质或者模型的时候都会导致渲染状态的改变,而每次改变都会引起新的绘图操作(新的绘图批次)。绘图操作是一个耗费时间的过程,如同画家在绘制新作品前要清洗调色板一样,图形硬件也需要进行顶点和纹理的更新操作。为了渲染效率的提高,程序设计者要尽量减少渲染状态的改变,换句话说也就是减少绘图批次的数量。

场景节点对象

场景管理器用场景节点来定义场景图的结构。这些场景节点以层次的结构组织在场景管理器中:一个场景节点可以有一个父节点和任意数量的子节点。你可以对场景管理器中的节点进行挂接或者摘除操作;这里提供一个简单的办法来关闭场景中的某个部分:只要把不希望渲染部分的根节点从场景图中摘除下来,这个部分就不会被渲染了。场景节点必须通过创建它们的场景管理器来销毁。

在场景管理器创建的时候,会给整个场景提供一个总的父节点:场景的根节点是场景中唯一没有父节点的场景节点。根节点的概念对整个场景图至关重要,所以用户无权销毁它。对于场景图来说,根节点的显式作用可以用来挂接所有场景中存在的其他节点;隐式作用是场景图用它来挂接静态物体和整个世界地图。尽管你可以移动根节点,但尽量不要这么做,因为大多数时候都需要保持根节点的稳定性。

场景中新建立的节点必须作为子节点挂接在已经存在的节点上面。这就意味着,第一个放入场景的节点,必须挂到根节点上面,然后再不断挂接扩充,直至形成一个你所需要的场景树状结构图。

在你创建了一个场景节点之后,场景管理器不会往上面挂接任何内容。当你需要的时候,应该自己创建内容并向需要操作的节点挂接。不过并没有要求场景中存在的节点一定要有绑定内容在上面,你可以挂接一个空节点,并可以根据需要随时挂接内容到它上面。单独的节点上面并没有限制绑定内容的数量。你可以把所有内容对象都绑定到一个节点上面,不过这也就意味着无法单独的移动它们(如同连体婴一般)。

就像我们之前所说,场景内容独立于场景节点。你可以把场景内容从场景节点中分离出来,这样的操作并不会引起场景内容的销毁或者删除。但还是不能把一个场景内容同时挂接到两个以及两个以上的场景节点上面,也不能让一个场景节点同时挂接到两个父节点上面,这些操作都会引起异常。

在这里你必须了解:在场景图中有三个重要的空间操作(移动、旋转、缩放),它们的操作目标都是场景节点,而不是场景内容。换句话说,用户操作场景节点,场景内容跟随着所挂接节点一同移动、旋转和缩放。

场景图

场景图主要是负责场景结构的维护,场景图的操作维持在接口级别;它并不关心去操作图形的具体算法实现,它只是通过信号(它们的方法)来操作场景图,进而忽略了具体的算法实现。其次,场景图的节点中没有包含任何固有的内容和管理方法。具体的内容被放置到可渲染(Renderable)对象之中,它提供了场景中全部几何图形(包括活动的的或者其他所有的)。它们的渲染的属性(也可以说是材质)被包含在实体(Entity)对象中,在实体对象里面同样包含着一个或多个子实体(SubEntity)对象,这些子实体才是真正可以被渲染的对象。注意:尽管场景节点挂接到场景图上面;但场景图仍然没有任何节点状态的直接操作。

其中活动对象MovableObject可以直接操作所有几何体和渲染属性。它并不是场景节点的子类,而是挂接到场景节点中(可以理解为通过组合代替继承)。这意味着如果你需要,程序中的场景节点可以不用了解与之相关的可渲染对象的任何细节。也意味着你可以扩展,改变,重写,或者其他改变场景图的实现,而不会影响场景内容接口的设计和实现;他们彻底独立于场景图。场景图甚至可以完全修改而不会影响任何内容类。


收藏 0 0

登录 后评论。没有帐号? 注册 一个。

周峰

研发
  • 0 回答
  • 0 粉丝
  • 0 关注