This page has been translated automatically.
视频教程
界面
要领
高级
实用建议
基础
专业(SIM)
UnigineEditor
界面概述
资源工作流程
Version Control
设置和首选项
项目开发
调整节点参数
Setting Up Materials
设置属性
照明
Sandworm
使用编辑器工具执行特定任务
如何擴展編輯器功能
嵌入式节点类型
Nodes
Objects
Effects
Decals
光源
Geodetics
World Nodes
Sound Objects
Pathfinding Objects
Players
编程
基本原理
搭建开发环境
使用范例
C++
C#
UnigineScript
统一的Unigine着色器语言 UUSL (Unified UNIGINE Shader Language)
Plugins
File Formats
材质和着色器
Rebuilding the Engine Tools
GUI
双精度坐标
应用程序接口
Animations-Related Classes
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
VR-Related Classes
创建内容
内容优化
材质
Material Nodes Library
Miscellaneous
Input
Math
Matrix
Textures
Art Samples
Tutorials

处理用户定义的数据包

Simulations often require extended communication, which is not covered by standard packets included in a certain communication standard or protocol (DIS, CIGI, etc.). So, custom (user-defined) packets are needed.模拟通常需要扩展的通信,而某些通信标准或协议(DIS,CIGI等)中包含的标准数据包并未涵盖这些通信。因此,需要自定义(用户定义)的数据包。

Such custom packets make it possible to extend basic functionality and add more flexibility to the system (e.g. when you need to display some avionics data).这种自定义数据包可以扩展基本功能并为系统增加更多的灵活性(例如,当您需要显示一些航空电子数据时)。

UNIGINE IG enables you to define and process custom (user-defined) packets. The workflow is simple and similar for all communication protocols:UNIGINE IG使您能够定义和处理自定义(用户定义)数据包。对于所有通信协议,工作流程都非常简单且相似:

  • Set a callback on receiving a certain packet. When IG receives a packet from the network, it creates an object of the appropriate class and passes it to the callback function.在接收到某个数据包时设置回调。 IG从网络接收到数据包时,它将创建适当类的对象,并将其传递给回调函数。
  • Inside the callback function, read and interpret the data of the class instance passed to it (depending on what was written to the packet on the host).在回调函数中,读取并解释传递给它的类实例的数据(取决于在主机上写入数据包的内容)。
  • Create and send a corresponding response packet, if necessary.如有必要,创建并发送相应的响应数据包。

User-Defined CIGI Packets
用户定义的CIGI数据包#

Just like with all other types of packets, to receive user-defined ones, we should add a callback for CIGI_OPCODE >= 201 (in accordance with CIGI ICD). On receiving such a packet, the callback shall be executed with CigiHostUserDefined * packet passed to it.就像所有其他类型的数据包一样,要接收用户定义的数据包,我们应该为CIGI_OPCODE >= 201添加一个回调(根据CIGI ICD)。收到这样的数据包后,回调函数应以CigiHostUserDefined * packet传递给它。

The CigiHostUserDefined class has the getData() method, which returns a set of bytes to be read and interpreted by the user (depending on what was written to the packet on the host).CigiHostUserDefined类具有getData()方法,该方法返回一组要由用户读取和解释的字节(取决于在主机上写入数据包的内容)。

The same situation is with sending packets. First, we ask the CIGIConnector to create a packet with a certain CIGI_OPCODE. If the code is equal to 201 or greater, a CigiIGUserDefined instance shall be returned. You can set bytes to be sent by calling the CigiIGUserDefined::setData() method.发送数据包也是如此。首先,我们要求CIGIConnector创建一个具有特定CIGI_OPCODE的数据包。如果代码等于或大于201,则应返回CigiIGUserDefined实例。您可以通过调用CigiIGUserDefined::setData()方法来设置要发送的字节。

注意
Bytes are read and written starting from the 2nd byte (not from the 4th). If you want to align bytes starting from the 4th one, you should add a couple of bytes in the beginning. The CIGI ICD recommends to start reading/writing bytes starting from the 4th one (see Data before the Data Block 1 shown in the images below), although it is mentioned, that it is possible to start from the 2nd.从第2个字节(不是从第4个字节)开始读取和写入字节。如果要从第4个字节开始对齐字节,则应在开头添加几个字节。 CIGI ICD建议从第4个字节开始读取/写入字节(请参见下图所示的Data Block 1之前的数据),尽管已提及,但也可以从第2个字节开始。

General User-Defined Packet Structure

Below is an example of working with user-defined CIGI packets: 以下是使用用户定义的CIGI数据包的示例:

源代码 (C++)
using namespace Plugins;

int AppWorldLogic::init()
{
	// ....

	int index = Engine::get()->findPlugin("CIGIConnector");
	// check CIGIConnector plugin load
	if (index != -1)
	{

		// getting the CIGI interface
		cigi = Unigine::Plugins::IG::CIGI::Connector::get();
               // adding a callback for OPCODE = 202
		cigi->addOnReceivePacketCallback(202, MakeCallback(this, &AppWorldLogic::on_recv_user_packet));
	}
	return 1;
}

// ....

void AppWorldLogic::on_recv_user_packet(Unigine::Plugins::IG::CIGI::CigiHostPacket  * host_packet)
{
	Log::error("AppWorldLogic::on_recv_user_packet\n");
	CigiHostUserDefined * packet = dynamic_cast<CigiHostUserDefined *>(host_packet);
	unsigned char * request_data = packet->getData();  // read
	// ... 
        // creating a new IG user packet with opcode 203
	CigiIGPacket * response_packet = cigi->createIGPacket(203);
	CigiIGUserDefined * user_defined = dynamic_cast < CigiIGUserDefined *>(response_packet);

	user_defined->setData(response_data, size_of_data); // write
	cigi->addIGPacket(response_packet);
}

Custom DIS PDUs
自定义DIS PDU#

In case of using DIS, custom Protocol Data Units (PDUs) are processed the same way as user-defined CIGI packets.如果使用DIS,则自定义协议数据单元(PDU)的处理方式与用户定义的CIGI数据包

注意
Basic level of DIS support is implemented using the KDIS library v2.9.0, DIS_VERSION 7, so don't forget to download it from here and add an additional include directory in your project to the KDIS/include/ folder.DIS支持的基本级别是使用KDIS库v2.9.0、DIS_VERSION 7实现的,因此请不要忘记从中下载在此处,并将项目中的其他包含目录添加到KDIS/include/文件夹。

Below is an example of working with custom PDUs: 以下是使用自定义PDU的示例:

源代码 (C++)
#include <PDU/Header.h>
#include <DataTypes/EntityType.h>
#include <PDU/Entity_Info_Interaction/Entity_State_PDU.h>
using namespace Plugins;
// ...

int AppWorldLogic::init()
{
	// ....

	int index = Engine::get()->findPlugin("DISConnector");
	
	// check DISConnector plugin load
	if (index != -1)
	{
		// getting the DIS interface
		dis = Unigine::Plugins::IG::DIS::Connector::get();
        // adding a callback for all packets
		
		dis->addReceivePacketCallback(KDIS::DATA_TYPE::ENUMS::Entity_State_PDU_Type, MakeCallback(this, &AppWorldLogic::on_recv_entitystate_packet));
        dis->addReceivePacketCallback(KDIS::DATA_TYPE::ENUMS::Other_PDU_Type, MakeCallback(this, &AppWorldLogic::on_recv_other_packet));

	}
	return 1;
}

// ....
 
void AppWorldLogic::on_recv_entitystate_packet(KDIS::PDU::Header *pdu)
{
	if (pdu->GetPDUType() == KDIS::DATA_TYPE::ENUMS::Entity_State_PDU_Type)
	{
		KDIS::PDU::Entity_State_PDU *entity_state_pdu = static_cast<KDIS::PDU::Entity_State_PDU *>(pdu);
		
		auto location = entity_state_pdu->GetEntityLocation();
		auto linear_velocity = entity_state_pdu->GetEntityLinearVelocity();
		auto appearance = entity_state_pdu->GetEntityAppearance();
		// ...
	}
	
}
void AppWorldLogic::on_recv_other_packet(KDIS::PDU::Header *pdu)
{
    // ...
}
注意
The callbacks receive only packets with the Exercise ID, as well as Site ID, matching on the server and IG. These parameters are set in the configuration file.回调仅接收具有练习ID和站点ID且与服务器和IG匹配的数据包。这些参数在配置文件
最新更新: 2024-12-13
Build: ()