This page has been translated automatically.
视频教程
界面
要领
高级
实用建议
UnigineEditor
界面概述
资产工作流程
设置和首选项
项目开发
调整节点参数
Setting Up Materials
Setting Up Properties
照明
Landscape Tool
Sandworm
使用编辑器工具执行特定任务
Extending Editor Functionality
嵌入式节点类型
Nodes
Objects
Effects
Decals
光源
Geodetics
World Nodes
Sound Objects
Pathfinding Objects
Players
编程
基本原理
搭建开发环境
Usage Examples
C++
C#
UnigineScript
UUSL (Unified UNIGINE Shader Language)
Plugins
File Formats
Rebuilding the Engine Tools
GUI
双精度坐标
应用程序接口
Containers
Common Functionality
Controls-Related Classes
Engine-Related Classes
Filesystem Functionality
GUI-Related Classes
Math Functionality
Node-Related Classes
Objects-Related Classes
Networking Functionality
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
IG Plugin
CIGIConnector Plugin
Rendering-Related Classes
创建内容
Content Optimization
Materials
Material Nodes Library
Miscellaneous
Input
Math
Matrix
Textures
Art Samples
Tutorials
注意! 这个版本的文档是过时的,因为它描述了一个较老的SDK版本!请切换到最新SDK版本的文档。
注意! 这个版本的文档描述了一个不再受支持的旧SDK版本!请升级到最新的SDK版本。

IG应用模板

Image Generator(IG)渲染了虚拟世界的场景,提供了逼真的模拟视图,可以将其视为仿真虚拟世界的视口。模拟器可能具有一个或多个IG通道,呈现“窗外”视图,并且可能具有代表各种传感器的几个其他视图:电光(EO),红外(IR)和夜视(NV);有时是雷达。这些视图的显示方式可能从简单的台式机显示器到多台投影机的球型显示器不等。

IG使用 地形数据库 和一组 实体 (飞机,车辆等)来渲染从指定的角度来看场景,天空,天气和视觉效果,并将视频信号发送到用户界面内的相应显示器。

IG从网络中的所有其他主机接收更新和事件,这些主机可能是车辆/飞机模拟主机,教练操作员站(IOS),物理模拟主机等。IG还响应其他主机的请求以检查路口 根据地形确定车辆/飞机是否撞上任何物体或是否与另一个实体有视线。

模拟器和IG可以集成到单个应用程序中,其中模拟器使用 API调用来控制IG。或者,模拟器可以通过网络连接连接到IG,并通过发送/接收由接口控制文档(例如 CIGI (通用图像生成器接口))指定的消息进行通信。或者,可以使用分布式仿真网络进行连接,并使用 DIS HLA 等通信协议传递消息。

Communication Protocols

HLA是模拟之间互操作性的标准。 HLA定义了一种具有一组应用程序接口(API)标准的体系结构,而不是像DIS这样的网络协议(有线标准)。仿真应用程序(称为联邦)通过调用HLA API进行通信。一种称为运行时基础结构(RTI)的软件实现了HLA API,并负责将数据从一个联合体传输到另一个联合体。

Entity是可以由主机创建,操纵和销毁的静态或动态仿真对象。虚拟世界充满了实体,它们代表现实世界的某些对象(例如飞机,车辆,轮船等)

Terrain Database(或简称为Database)是进行模拟的景观的虚拟模型。它的特性,质量和内容定义了在仿真环境中可以完成的工作。地形数据库内容的分辨率和详细程度定义了环境中可能发生的交互作用的保真度。 UNIGINE支持双精度坐标,使您能够扩展地形的地理覆盖范围,该范围定义了可以进行模拟的区域的大小,直至整个地球表面。

除了地形数据库实体天空,大气之外,场景中还有更多的场景。 IG还负责吸引环境中的这些空灵部分。由于它们的外观会根据天气和一天中的时间变化很大,因此实现了一些模型来模拟环境:

  • 星历表模型确定太阳和月亮的位置,它们都根据给定的坐标和日期/时间将光线投射到场景中。
  • IG中的或由外部天气模拟提供的天气模型,可提供云层覆盖以及具有方向和强度的全球风概念,从而影响植被的动画和环境。

UNIGINE的IG通过其基于插件的体系结构设计为简单,易用且可扩展 IG插件是操纵系统,实体,铰接的零件,组件模板等的主要框架插件,它以UNIGINE引擎(节点,NodeReferences等)的形式运行,并且不受任何特定的通信协议的约束。 IG插件还有一组额外的插件,称为 connectors ,用于将IG术语与每个特定协议(例如CIGI,HLA,DIS)的链接。基本上,体系结构如下所示:

IG

在IG中,所有实体,灯光,数据库等均通过ID进行引用。根据 XML定义对实体的零件进行简单的表达,不需要建模者准备任何动画。

UNIGINE IG当前被实现为 IG模板

当前支持的CIGI数据包

Type Supported Not Supported
ig_control Byte Swap, Database Number Timestamp, Extrapolation/Interpolation Enable, IG Mode
entity_control PARTIAL Alpha, Extrapolation/Interpolation Enable
entity_clamped_control FULL
component_control Component classes: ENTITY, VIEW, GROUP SENSOR, REG_WATER, REG_TERRAIN, REG_WEATHER, GLOBAL_WATER, GLOBAL_TERRAIN, GLOBAL_WEATHER, ATMOSPHERE, CELESTIAL, EVENT, SYSTEM,
SYMBOL_SURFACE, SYMBOL
component_short_control Component classes: ENTITY, VIEW, GROUP SENSOR, REG_WATER, REG_TERRAIN, REG_WEATHER, GLOBAL_WATER, GLOBAL_TERRAIN, GLOBAL_WEATHER, ATMOSPHERE, CELESTIAL, EVENT, SYSTEM,
SYMBOL_SURFACE, SYMBOL
articulated_control FULL
articulated_short_control FULL
rate_control FULL
celestial_control FULL
atmosphere_control Visibility Range, Wind speed and direction Global Humidity, Global Air Temperature, Global Barometric Pressure
environment_control NOT SUPPORTED Merge Weather Properties, Merge Aerosol Concentrations, Merge Maritime Surface Conditions, Merge Terrestrial Surface Conditions
weather_control Layer ID (1-5), Weather Enable, Random Lightning Enable, Cloud Type (not regional clouds), Scope(0-1), Visibility Range, Coverage(for cloud), Base Elevation, Thickness, Horizontal Wind Speed, Vertical Wind Speed, Wind Direction, Aerosol Concentration (for precipitation) Entity ID, Severity, Air Temperature, Scud Frequency, Barometric Pressure
maritime_control FULL
wave_control NOT SUPPORTED
terrestrial_control NOT SUPPORTED
view_control FULL
sensor_control NOT SUPPORTED
tracker_control NOT SUPPORTED
earth_model_def NOT SUPPORTED
trajectory_def NOT SUPPORTED
view_def FULL
segment_def FULL
volume_def FULL
hat_hot_request FULL, with Extended Response and Update Period parameter
los_segment_request PARTIAL, with Extended Response and Update Period parameter Alpha Threshold, Color
los_vector_request PARTIAL, with Extended Response and Update Period parameter Alpha Threshold
position_request FULL, with Update Period parameter
environment_request NOT SUPPORTED
symbol_surface_def PARTIAL
symbol_text_def PARTIAL
symbol_circle_def PARTIAL
symbol_line_def PARTIAL
symbol_clone NOT SUPPORTED
symbol_control PARTIAL
symbol_short_control PARTIAL

插值和外推#

Unigine IG使用内插快照(IS)解决IG与主机之间的数据包丢失的问题。它通过采取两个旧的但已知的位置并在它们之间插入对象来工作。通过缓冲接收到的位置和旋转以及它们代表的时间来实现。通常,我们将当前本地时间减去一些预定义的时间-插值周期(默认为 40 ms),然后进入缓冲区,找到之前和之后的两个索引在这段时间之后进行插值。

如果我们在寻找的时间内没有收到位置和旋转信息,则使用外推(猜测)。它也有时间限制-外推期(默认为 200 ms)。如果推断期已结束,但仍未收到任何数据包,则所有对象将冻结。

在大多数情况下,此方法为每个从属设备提供了非常准确的世界表示,因为通常只渲染远程对象的已知位置,在极少数情况下,系统会尝试推断(猜测)对象所在的位置。但是,这是有代价的,因为我们总是在当前时间之后渲染 40 毫秒(插值周期),以便新数据包有时间到达数据。

也可以看看#

  • IG插件API 部分提供了有关通过代码(C ++)管理IG的更多详细信息。
  • 设置属性文章,为调整新实体的属性提供了更多详细信息。
  • IG配置文章,提供有关设置IG的更多详细信息。
  • 环境设置文章提供了有关配置天空和天气参数的更多详细信息。

使用IG模板#

基本工作流程如下:

  1. 打开SDK浏览器,转到项目标签,然后使用 IG 模板创建新项目

    Create a Project

  2. 点击打开编辑器,在UnigineEditor中打开世界。

    Open the UnigineEditor

  3. 使用景观工具生成地形

    Generate a Terrain

    注意
    地理参考地形生成视频教程中显示了地形生成的过程。
  4. 添加模型(作为节点引用)以表示模拟中使用的实体(飞机,车辆等)。 分配属性(灯光,起落架,车轮,控制器,效果等)到相应的节点,并根据需要调整其参数。

    Add Models and Adjust Properties

  5. 保存您的世界并关闭Unigine编辑器。
  6. 打开配置文件ig_config.xml)并为所有实体添加定义,指定必要的系统设置和连接器参数。

    Add Models and Adjust Properties

  7. 通过单击运行启动IG应用程序。

    Run the Application

    注意
    默认情况下,您的应用程序将使用 IG,CIGIConnector 插件启动。如果要更改此设置,请在项目的 Project 标签上单击项目的 Run 按钮下的省略号后,修改启动选项。 SDK浏览器。
  8. 启动您的主机应用程序或CIGI主机仿真器以与IG通信。

IG同步系统#

IG拥有自己的同步系统,其中 Syncker插件已自动初始化。要使用 Multi-IG 配置,您应该指定其他启动命令行参数。主站和从站都有通用的参数,也有特定的参数。 IG网络配置的所有可用参数的列表在 Syncker特定选项文章中给出。

IG的启动顺序无关紧要(您可以先运行主设备,然后运行从设备,反之亦然)。重要的是您应该通过 -sync_count 参数为主设备指定正确的IG数量。请注意,这是IG主机的总数,而不是从站的数量(例如:如果您具有 1 主站和 2 从站,则应指定: -sync_count 3 )。

IG使用唯一的端口(Syncker使用的端口): UDP 8890

这意味着控制台中必须出现两条报告连接成功的消息。

对于从设备,其外观如下:

输出
IG::Manager::on_ig_connected(): Connection to "IG Master" (ip:port) has been established //< - message from IG
Syncker::Slave::connect_to_master(): connection to "ip" accepted in 0.00 seconds //<- message from Syncker

对于母版,其外观如下:

输出
IG::Manager::on_ig_connected(): Connection to "IG Slave" (ip:port) has been established <- from IG
Syncker::Master::check_new_connections(): connection from "ip" "slave" accepted in 0.00 seconds <- from Syncker
IG::Manager::on_ig_connected(): all connections established. Session started <- from IG

最后一条消息表示主机已建立所有必要的连接并准备工作。

如果使用连接器启动IG,则连接器将立即开始使用IG API,而无需等待所有连接。因此,主服务器切换到阻止模式(不刷新窗口),并向控制台打印以下消息:

输出
IG::Manager::wait_for_all_connections(): waiting for all connections within a minute…

因此,您有1分钟的时间连接所有IG。如果在此期间没有主机连接到IG,则主机将关闭向控制台的报告,报告未建立连接。

因此,在两台计算机上启动IG所需的最少参数数目如下所示:

主:

命令行
-extern_plugin "IG,CIGIConnector" -sync_master 1 -sync_count 2

奴隶:

命令行
-extern_plugin "IG" -sync_master 0

请注意,没有明确指定IP地址,IG会尝试自动定义地址。

注意
IG主站和IG从站必须位于同一隔离子系统中。如果网络中有多个IG Master,则应明确指定其IP地址,因为自动检测不可用。

这是启动IG主机时的典型参数数量:

Master:

命令行
-extern_plugin "IG,CIGIConnector" -sync_master 1 -sync_count 3 -sync_view left

Slave 1:

命令行
-extern_plugin "IG" -sync_master 0 -sync_view center

Slave 2:

命令行
-extern_plugin "IG" -sync_master 0 -sync_view right

扩展模板的功能#

UNIGINE的IG提供以下定制机会:

  • IG可以内置到Qt / WinForm / WPF应用程序中,并具有自定义界面(例如,在最简单的情况下在摄像机之间切换)。
  • 主机可以连接多个IG,并且如有必要,可以将每个运行的IG编程为具有自己的逻辑。
  • 可以对辅助静态对象(例如,沿着特定路线的建筑物或船舶上的广告牌)进行动画处理,并可以通过CIGI / HLA请求其位置,旋转或其他特定参数。
  • 可以创建新的视觉效果以创建更逼真的图像。
  • 用户可以添加自己的自定义组件,并通过修改 ig_config.xml 文件进行处理。
  • 您可以扩展IG功能以支持其他协议(例如ALSP,TENA,CTIA等),为此,您必须编写自己的连接器

添加自定义连接器#

连接器实际上是一个自定义的 C ++插件,用于在主机和IG之间传递消息。该插件读取包并调用 IG插件(在 include / plugins / UnigineIG.h 中列出)的相应方法。

下面列出的文件可用作您的自定义连接器的模板:

  • 插件包含文件放入include/plugins文件夹:

    CUSTOMConnectorInterface.h

    源代码 (C++)
    #ifndef __CUSTOM_CONNECTOR_INTERFACE_H__
    #define __CUSTOM_CONNECTOR_INTERFACE_H__
    
    namespace IG
    {
    	namespace CUSTOM
    	{
    		class ConnectorInterface
    		{
    		public:
    			virtual ~ConnectorInterface() {}
    			
    			// client initialization
    			virtual int init(/*initialization parameters*/) = 0;
    			// client shutdown
    			virtual int shutdown() = 0;
    			
    			// other methods
    			// ...
    			
    			// callbacks
    			//virtual void setConnectCallback(Unigine::CallbackBase* func) = 0;
    			//virtual Unigine::CallbackBase* getConnectCallback() const = 0;
    			// ...
    		};
    	}
    }
    
    #endif /* __CUSTOM_CONNECTOR_INTERFACE_H__ */
  • 要放入source/custom_connector文件夹的插件源文件:

    CUSTOMConnectorPlugin.cpp

    源代码 (C++)
    #include <UniginePlugin.h>
    
    #include "CUSTOMConnector.h"
    #include "CUSTOMConnectorInterpreter.h"
    
    using namespace Unigine;
    
    //////////////////////////////////////////////////////////////////////////
    // CUSTOMConnectorPlugin
    //////////////////////////////////////////////////////////////////////////
    
    class CUSTOMConnectorPlugin : public Plugin
    {
    public:
    	CUSTOMConnectorPlugin();
    	virtual ~CUSTOMConnectorPlugin();
    
    	const char *get_name() override;
    	void *get_data() override;
    
    	int init() override;
    	int shutdown() override;
    	void update() override;
    
    private:
    	IG::CUSTOM::Connector *connector;
    };
    
    CUSTOMConnectorPlugin::CUSTOMConnectorPlugin()
    	: connector(nullptr)
    {
    }
    
    CUSTOMConnectorPlugin::~CUSTOMConnectorPlugin()
    {
    	CUSTOMConnectorInterpreterShutdown();
    	delete connector;
    }
    
    const char *CUSTOMConnectorPlugin::get_name()
    {
    	return "CUSTOMConnector";
    }
    
    void *CUSTOMConnectorPlugin::get_data()
    {
    	return static_cast<IG::CUSTOM::ConnectorInterface *>(connector);
    }
    
    int CUSTOMConnectorPlugin::init()
    {
    	connector = new IG::CUSTOM::Connector();
    	connector->init();
    	CUSTOMConnectorInterpreterInit();
    	return 1;
    }
    
    int CUSTOMConnectorPlugin::shutdown()
    {
    	connector->shutdown();
    	return 1;
    }
    
    void CUSTOMConnectorPlugin::update()
    {
    	connector->update();
    }
    
    //////////////////////////////////////////////////////////////////////////
    // Plugin export
    //////////////////////////////////////////////////////////////////////////
    
    extern "C" UNIGINE_EXPORT void *CreatePlugin()
    {
    	return new CUSTOMConnectorPlugin();
    }
    
    extern "C" UNIGINE_EXPORT void ReleasePlugin(void *plugin)
    {
    	delete static_cast<CUSTOMConnectorPlugin *>(plugin);
    }

    CUSTOMConnector.h

    源代码 (C++)
    #ifndef __CUSTOM_CONNECTOR_H__
    #define __CUSTOM_CONNECTOR_H__
    
    #include <plugins/CUSTOMConnectorInterface.h>
    #include <plugins/UnigineIG.h>
    #include <UnigineInterface.h>
    #include <UnigineLogic.h>
    
    namespace IG
    {
    namespace CUSTOM
    {
    	class CUSTOMWorldLogic;
    
    	class Connector : public ConnectorInterface
    	{
    	public:
    		Connector();
    		virtual ~Connector() {}
    		// singleton
    		static Connector *get() 
    		{
    			if (connector == nullptr)
    				Log::fatal("%s:: CUSTOM connector is NULL\n", __FUNCTION__);
    			return connector;
    		};
    
    		// automatic initialization on plugin load
    		void init();		
    
    		// update/shutdown client
    		void update();
    		void shutdown();
    		
    		// methods to be called by the CUSTOMWorldLogic class at the corresponding stages of the execution sequence
    		void onWorldInit();
    		void onWorldShutdown();
    	private:
    		static Connector *connector;
    		IG::Manager *ig_manager = nullptr;
    		CUSTOMWorldLogic *world_logic;
    	};
    	
    	// WorldLogic class
    	class CUSTOMWorldLogic : public Unigine::WorldLogic
    	{
    	public:
    		CUSTOMWorldLogic() {}
    		virtual ~CUSTOMWorldLogic() {}
    
    		virtual UNIGINE_INLINE int init() override { Connector::get()->onWorldInit(); return 1; }
    		virtual UNIGINE_INLINE int shutdown() override { Connector::get()->onWorldShutdown(); return 1; }
    	};
    }
    }
    
    #endif /* __CUSTOM_CONNECTOR_H__ */

    CUSTOMConnector.cpp

    源代码 (C++)
    #include "CUSTOMConnector.h"
    #include <UnigineEngine.h>
    #include <UnigineNode.h>
    
    using namespace Unigine;
    using namespace Math;
    using namespace IG;
    using namespace CUSTOM;
    
    Connector::Connector() {
    	world_logic = new CUSTOMWorldLogic();
    	Engine::get()->addWorldLogic(world_logic);
    }
    
    void Connector::init()
    {
    	const auto host = "127.0.0.1";
    	const auto port = 3000;
    	
    	int ig_plugin_index = Engine::get()->findPlugin("IG");
    	if (ig_plugin_index == -1)
    	{
    		Log::error("IG::CUSTOM::Connector::init(): IG plugin isn't loaded\n");
    		return;
    	}
    	ig_manager = (IG::Manager*)Engine::get()->getPluginData(ig_plugin_index);
    	
    	// IG setup
    	ig_manager->setCoordinateSystem(IG::Manager::COORDINATE_SYSTEM::NED);
    	
    }
    
    void Connector::update()
    {
    	// read & write packets
    }
    
    void Connector::shutdown() 
    {
    	// shutdown client
    	shutdown();
    	
    	// clear static link
    	connector = nullptr;
    	
    	// ...
    }
    
    void Connector::onWorldInit() 
    {
    	// actions to be performed when a new world is loaded
    }
    
    void Connector::onWorldShutdown() 
    {
    	// actions to be performed when current world is closed
    }

    CUSTOMConnectorInterpreter.h

    源代码 (C++)
    #ifndef __CUSTOM_CONNECTOR_INTERPRETER_H__
    #define __CUSTOM_CONNECTOR_INTERPRETER_H__
    
    #include <UnigineBase.h>
    
    void CUSTOMConnectorInterpreterInit();
    void CUSTOMConnectorInterpreterShutdown();
    
    #endif /* __CUSTOM_CONNECTOR_INTERPRETER_H__ */

    CUSTOMConnectorInterpreter.cpp

    源代码 (C++)
    #include <UnigineEngine.h>
    #include <UnigineInterface.h>
    
    #include <plugins/CUSTOMConnectorInterface.h>
    #include "CUSTOMConnector.h"
    
    using namespace Unigine;
    using namespace IG;
    
    void CUSTOMConnectorInterpreterInit()
    {
    	int id = Interpreter::addGroup("CUSTOMConnectorInterpreter");
    
    	// defines
    	Interpreter::addExternDefine("HAS_CUSTOM_CONNECTOR", id);
    
    	// enums
    	// Interpreter::addExternVariable("CUSTOM_VERSION_10", MakeExternConstant<int>(CUSTOM_VERSION_10), id);
    
    	// functions
    	Connector *connector = Connector::get();
    	Interpreter::addExternLibrary("engine.custom", id);
    	//Interpreter::addExternFunction("engine.custom.init", MakeExternObjectFunction(connector, &Connector::init), id);
    	//Interpreter::addExternFunction("engine.custom.shutdown", MakeExternObjectFunction(connector, &Connector::shutdown), id);
    }
    
    void CUSTOMConnectorInterpreterShutdown()
    {
    	Interpreter::removeGroup("CUSTOMConnectorInterpreter");
    }

    CUSTOMConnectorWrapper.cpp

    源代码 (C++)
    //push ignore deprecated warnings
    #ifdef __GNUC__
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
    #elif defined(_MSC_VER)
    #pragma warning(push)
    #pragma warning(disable: 4996)
    #endif
    
    #include <UnigineEngine.h>
    #include <plugins/CUSTOMConnectorInterface.h>
    
    using namespace Unigine;
    
    extern "C" 
    {
    	//UNIGINE_EXPORT void CUSTOMConnector_method(CUSTOMConnector *self) { if (self) self->method(); }
    }
    
    //pop ignore deprecated warnings
    #ifdef __GNUC__
    #pragma GCC diagnostic pop
    #elif defined(_MSC_VER)
    #pragma warning(pop)
    #endif
最新更新: 2021-12-13
Build: ()