好记性不如烂笔头,前两天刚刚实现了功能,现在把主要过程都记录一下以防忘记,写个博客记录一下,同时也供大家参考。

这个测试工程的目的在于在UE4中利用VRPN实时接入Optitrack的运动追踪数据(操作手柄刚体运动数据)并以此驱动一个方块根据追踪数据在场景中运动。

1.VRPN

VRPN的详细介绍网上有很多,就不赘述了,反正是一种通用的开源设备访问接口,可以把多种VR设备(基本都是交互设备,像是鼠标、ART、optitrack、诺亦腾什么的)的追踪信息转化为统一的格式,并用固定的方式去访问。我用的7.33,大体的配置和使用流程为:

(1)github下载编译源码

Windows下访问https://github.com/vrpn/vrpn网址获取最新的VRPN源码后用CMAKE打包成VS工程。如果仅仅是使用VRPN已经支持的设备就直接生成解决方案即可,然后需要在源码文件中找到下面这几个文件:

a. vrpn_server.exe程序。位于打包后生成的VRPN.sln所在目录下\server_src\Debug(如果编译选的Realease就是Realease)。这个是vrpn的服务器程序,用来直接与外部设备通信以获取信息,我们需要编写自己的client程序来与服务器程序,然后从服务器中获取处理好的程序。

b. vrpnd.lib。我是用Debug模式编译的,估计是因为这个所以才会是vrpnd.lib我看其他都是vrpn.lib估计他们是realease模式编译的,不过都能用。这个文件我是在VRPN.sln所在目录下\Debug文件夹找到的,如果找不到就直接搜索一下,反正我是搜出来的。

c.各种头文件。我也分不清,就在下载的CMAKE源码目录下把所有.h都拷贝出来了。

d.vrpn.cfg文件。在\server_src文件夹里。这是vrpn_server.exe服务器程序的配置文件,用来选定具体需要接入的设备,只用找到对应位置然后把#去掉就行,如果比较熟悉的话自己写一个这样的配置也可以。

现在我们拿到了所有需要的文件,可以先写一个Client的VS测试工程试一下获取一下鼠标的运动信息,网上很多随便搜一下就行,主要是确保找到的文件和开发环境没有问题。写好Client程序后,将vrpn.cfg文件放到vrpn_server.exe目录下,然后运行vrpn_server.exe,没有报错的话运行Client程序即可,如果失败可以检查一下防火墙。

2.Motive软件配置

Motive是Optrack的软件,他其中直接集成了VRPN的服务器程序,这样就简化了操作,我们不需要自己开启vrpn_server.exe并配置vrpn.cfg文件,直接在Motive中做好设置就可以了。

我的Motive版本为2.20,由于官网上的教程比较繁琐很多都用不到,我在此把需要用到的步骤记录一下。

a.首先我们需要添加一个刚体,开启软件后,在view下拉菜单中调出assset pane面板,然后将追踪刚体置于相机视野,等其中出现所有标记点后用鼠标选中所有标记点,右击创建刚体即可,随后就会在左侧assset pane中出现所创建的刚体。注意一点,刚体的名字要记好,后边写程序的时候需要用。

b.随后,点击View-Data Streaming Pane打开实时数据传输面板,这个面板其实就包含了VRPN Server配置,按照下图进行配置,主要是把Broadcast Frame打开、Local Interface选择loopback(我是从本地获取,如果是在网络中其他位置获取需要到官网上看一下配置方式)并且把VRPN打开。至此配置完成。

3.在UE4中写程序

现在是文章的主要内容了。本文使用的UE4版本为4.23,打开UE4创建一个C++工程,并创建一个C++类(我这叫VrpnActor),父类选择Actor(其他父类也不是不行,只不过我这边是打算控制一个actor进行运动,如果是想控制Character也可以用Character作为父类)。完成后我们开始准备写代码。

a.环境配置

UE4中配置环境添加头文件啥的是通过C#进行的,在UE4 Editor下双击创建的类进入VS工程。找到VrpnMotive.Build.cs文件(我的UE工程名称为VrpnMotive,大家请寻找自己工程对应的配置文件),这个文件是用来配置环境用的,头文件,lib等需要在这里添加。具体代码如下,解释直接写到注释了(!!!重点注意,我的注释是后来加的,为了便于理解。注释在使用的时候要删除或者改成英文的,UE4好像对中文支持有问题,注释是中文的都会报错),就不多说了。

// Fill out your copyright notice in the Description page of Project Settings.using UnrealBuildTool;
using System.IO;//需要自己添加,否则无法获取文件路径
public class VrpnMotive : ModuleRules
{public VrpnMotive(ReadOnlyTargetRules Target) : base(Target){PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });PrivateDependencyModuleNames.AddRange(new string[] {  });// Uncomment if you are using Slate UI// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });// Uncomment if you are using online features// PrivateDependencyModuleNames.Add("OnlineSubsystem");// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to trueAddThirdPartyDependencies(Target);//调用一下就行}
//添加相关配置的函数,里面把文件路径替换即可,其他不用动public void AddThirdPartyDependencies(ReadOnlyTargetRules ROTargetRules){string ThirdPartyPath = Path.GetFullPath(Path.Combine(ModuleDirectory, "../ThirdParty/"));string PathLib = string.Empty;string PathInc = string.Empty;// VRPNPathLib = Path.Combine(ThirdPartyPath, "Vrpn/Lib/x64");PathInc = Path.Combine(ThirdPartyPath, "Vrpn/Include/vrpn");PublicAdditionalLibraries.Add(Path.Combine(PathLib, "vrpn.lib"));PublicAdditionalLibraries.Add(Path.Combine(PathLib, "quat.lib"));PublicIncludePaths.Add(PathInc);}
}

b.程序编写

我们完成了环境的配置,现在开始编写程序。首先是MotiveActor.h文件。中文的注释是针对代码的说明。

// Fill out your copyright notice in the Description page of Project Settings.#pragma once
#include "vrpn_Connection.h"//头文件
#include "vrpn_Tracker.h"//头文件,这两个文件需要添加在上边,如果加在MotiveActor.generated.h后边会报错
#include "EngineUtils.h"
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MotiveActor.generated.h"UCLASS()
class VRPNMOTIVE_API AMotiveActor : public AActor
{GENERATED_BODY()
//添加一个可编辑的变量,用来指定刚体名称,需要跟Motive里设定的一致UPROPERTY(EditAnywhere, Category = "Optitrack")FString TargetName = TEXT("Tracker");
//添加一个可编辑的变量,用来设置ip地址UPROPERTY(EditAnywhere,Category = "Optitrack")FString ipAddress = TEXT("localhost:");
//添加一个可编辑的变量,用来设置端口  UPROPERTY(EditAnyWhere, Category = "Optitrack")int32  port = 3883;
//添加一个可见变量,用来显示最终的连接名称UPROPERTY(VisibleAnywhere, Category = "Optitrack")FString connectionName = TEXT("127.0.0.1:3883");public:    // Sets default values for this actor's propertiesAMotiveActor();
//初始化连接名称virtual void PostInitProperties() override;
//在连接参数变更时动态更新连接名称virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;public:   // Called every framevirtual void Tick(float DeltaTime) override;public://For Vrpn
//将获取的位置信息存入position,并设置在蓝图中可见UPROPERTY(EditAnywhere,BlueprintReadOnly,Category = "OptiTrack")FVector position;
//将获取的四元数存入quat,并设置在蓝图中可见UPROPERTY(EditAnywhere,BlueprintReadOnly, Category = "OptiTrack")FVector4 quat;
//连接变量vrpn_Connection* connection;
//追踪变量vrpn_Tracker_Remote* tracker;
//连接VRPN的函数,在蓝图中调用(可以在蓝图中手动设置连接,也可以在代码中直接默认连接,看具体需求)//UFUNCTION(BlueprintCallable,Category = "OptiTrack")void ConnectToMotive();};

然后是cpp文件。

// Fill out your copyright notice in the Description page of Project Settings.#include "MotiveActor.h"
AMotiveActor* MyMotiveActor;//用来存储指向自己的指针
// Sets default values
AMotiveActor::AMotiveActor()
{// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = true;
}// Called when the game starts or when spawned
void AMotiveActor::BeginPlay()
{Super::BeginPlay();ConnectToMotive();//直接在开始时连接VRPN
}// Called every frame
void AMotiveActor::Tick(float DeltaTime)
{Super::Tick(DeltaTime);
//每次循环,执行我们写的callback函数,更新positon和quat数据tracker->mainloop();connection->mainloop();}//Initialize the parameters
//利用设置的刚体名称,ip地址以及端口生成连接名称
void AMotiveActor::PostInitProperties() {Super::PostInitProperties();connectionName = ipAddress + FString::Printf(TEXT("%d"), port);}
//当参数变化时动态更新连接名称
#if WITH_EDITOR
void AMotiveActor::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) {connectionName = ipAddress + FString::Printf(TEXT("%d"), port);Super::PostEditChangeProperty(PropertyChangedEvent);
}#endif//Optitrack function
//回调函数,用来更新追踪数据
void VRPN_CALLBACK handle_pos(void* userdata, const vrpn_TRACKERCB t)
{   MyMotiveActor->position = FVector(t.pos[0], t.pos[1], t.pos[2]);MyMotiveActor->quat = FVector4(t.quat[0], t.quat[1], t.quat[2], t.quat[3]);
}
//连接函数,用来连接到VRPN
void AMotiveActor::ConnectToMotive() {connection = vrpn_get_connection_by_name(TCHAR_TO_ANSI(*connectionName));tracker = new vrpn_Tracker_Remote(TCHAR_TO_ANSI(*TargetName), connection);tracker->register_change_handler(NULL, handle_pos);MyMotiveActor = this;//this指代当前类,为了获取类中存储动捕数据的positon以及quat
}

4.使用测试

完成后进行编译,没问题了以后基于这个自建类创建一个蓝图,在蓝图中绑定一个方块,在蓝图中连接逻辑如下:

随后设置好刚体名称、ip地址等参数后在游戏中创建一个实例即可。

老的工程找不到了,从新用424做了一个,省得以后找不到,备份一份。

链接:https://pan.baidu.com/s/1Jcl983wYz6iQPvMCvgVrpw
提取码:qyyx

在UE4虚幻引擎下使用VRPN接入optitrack(Motive)的实时数据相关推荐

  1. UE4虚幻引擎开发手机游戏

    该文章来自用户转载 点击阅读原文 UE4虚幻引擎作为游戏开发引擎之一,在很多项目中都会使用到.下面就给大家分享下如何使用UE4开发高品质的手机游戏. 作者介绍 大纲 •介绍 •UE4 针对3A级手游的 ...

  2. 关于 UE4 (虚幻引擎4) 4.25.1版本提示“无法定位程序输入点 DXGIGetDebugInterface1 于动态链接库dxgi.dll上”的错误的解决办法

    关于 UE4 (虚幻引擎4) 4.25.1版本提示"无法定位程序输入点 DXGIGetDebugInterface1 于动态链接库dxgi.dll上"的错误的解决办法: 1.原因: ...

  3. UE4虚幻引擎UI界面动画制作!

    UE4虚幻引擎UI界面动画制作! 创建一个动画 然后选择某个控件! 找到某些属性!然后key帧! 关于怎么播放动画呢! 这样子呢!当你开始 可以自定义函数,外部MainUI调用!

  4. UE4 虚幻引擎,3D数学(二),3D嵌套坐标系。Relative相对位置与World世界位置,Relative相对旋转与World世界坐标旋转。

    在UE4虚幻引擎中,常见的嵌套坐标系有Skeletal骨骼,以及嵌套多节点(子节点,父节点)Actor.本文中,以嵌套多节点Actor为例. Skeletal骨骼,嵌套坐标系. 1.Relative相 ...

  5. UE4虚幻引擎 LiveLink Face连接不上的问题

    PS:IphoneX以上的手机型号才可以连接Live Link. LiveLinkFace连接不上的几个原因. 1.IP地址不对 设置IP地址捕捉,设置-->Live Link-->添加目 ...

  6. ue4怎么用虚幻商城场景_【更新】UE4虚幻引擎野外场景制作零基础入门教程

    原标题:[更新]UE4虚幻引擎野外场景制作零基础入门教程 作为一套零基础入门教程,可以帮助虚幻4引擎的新手了解到环境制作流程和相关软件的配合.本教学适合零基础入门用户,不适合有一定经验的UE使用者. ...

  7. UE4虚幻引擎关于小地图制作教程

    UE4虚幻引擎关于小地图制作教程 首先,要做一个这样子的效果! 怎么做呢! 首先,我们要准备UI! 小地图,我们的分辨率是512x512 记住参数! 然后在MainUI当中!我们就可以这么设置! 一个 ...

  8. UE4虚幻引擎,怎么更改视图,场景中的图标大小

    UE4虚幻引擎中,视图界面的图标,如SkyLight,Player Start的图标.默认缩放为1 一.打开编辑器偏好设置 二.打开Viewports视口,找到Billboard Scale公告板缩放 ...

  9. UE4虚幻引擎关于事件分发器的使用!

    UE4虚幻引擎关于事件分发器的使用! 首先,这次就讲一下,事件分发器,在UI,Pawn,子actor如何进行事件传递! 首先!我们如果要使用事件分发器的原因是什么! 第一,肯定是方便,快! 第二,为了 ...

最新文章

  1. MPO文件类型解码(四)3D图像整体结构
  2. ceph对象存储折腾记
  3. 不同测试阶段,不同测试类型的区别于联系
  4. 常用的函数式接口_Consumer接口练习_字符串拼接输出
  5. centos7.2源码安装openssl1.0.2
  6. 河北师范大学计算机专业保研率,河北省内13所高校2021届保研率一览
  7. 16进制的两位数转换不了 matlab_跟小黑学漏洞利用开发之16进制字符转换
  8. 廖雪峰JavaScript学习笔记(基础及数据类型、变量)
  9. vue项目调用jssip_JsSIP和FreeSWITCH整合
  10. Q Learning学习笔记
  11. 通过计算机控制手机,用电脑控制手机的方法
  12. TFS2010中如何添加用户
  13. 高保真扬声器系统的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告的全球与中国市场
  14. 网上流行护眼色的RGB值和颜色代码汇总
  15. Android开发-基本概念小整理(四)为了面试的小伙伴们所准备~~
  16. github官网进不去解决方案
  17. NewStarCTF 公开赛wp
  18. BLAST原理和用法总结(一)
  19. SPA(单页面web应用)和MPA(多页面web应用)
  20. Serial Box for Mac(软件序列号查询工具)

热门文章

  1. SAP 费用分摊分配用法
  2. linux medea 软件安装,大家用linux操作系统装ms4.3 or ms4.4的都用的什么操作系统?
  3. MYSQL常用SQL语句分享
  4. excel拆分实例:如何快速制作考勤统计分析表
  5. 李炎恢讲师Xhtml全套课程
  6. mac 系统office软件
  7. 七牛云上传图片报错处理
  8. 巴别鸟是如何用2个月时间让上市公司“爱上”它的?
  9. Geomesa时空大数据应用
  10. 23英寸显示器DELL U2312HM尺寸