在UE4虚幻引擎下使用VRPN接入optitrack(Motive)的实时数据
好记性不如烂笔头,前两天刚刚实现了功能,现在把主要过程都记录一下以防忘记,写个博客记录一下,同时也供大家参考。
这个测试工程的目的在于在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)的实时数据相关推荐
- UE4虚幻引擎开发手机游戏
该文章来自用户转载 点击阅读原文 UE4虚幻引擎作为游戏开发引擎之一,在很多项目中都会使用到.下面就给大家分享下如何使用UE4开发高品质的手机游戏. 作者介绍 大纲 •介绍 •UE4 针对3A级手游的 ...
- 关于 UE4 (虚幻引擎4) 4.25.1版本提示“无法定位程序输入点 DXGIGetDebugInterface1 于动态链接库dxgi.dll上”的错误的解决办法
关于 UE4 (虚幻引擎4) 4.25.1版本提示"无法定位程序输入点 DXGIGetDebugInterface1 于动态链接库dxgi.dll上"的错误的解决办法: 1.原因: ...
- UE4虚幻引擎UI界面动画制作!
UE4虚幻引擎UI界面动画制作! 创建一个动画 然后选择某个控件! 找到某些属性!然后key帧! 关于怎么播放动画呢! 这样子呢!当你开始 可以自定义函数,外部MainUI调用!
- UE4 虚幻引擎,3D数学(二),3D嵌套坐标系。Relative相对位置与World世界位置,Relative相对旋转与World世界坐标旋转。
在UE4虚幻引擎中,常见的嵌套坐标系有Skeletal骨骼,以及嵌套多节点(子节点,父节点)Actor.本文中,以嵌套多节点Actor为例. Skeletal骨骼,嵌套坐标系. 1.Relative相 ...
- UE4虚幻引擎 LiveLink Face连接不上的问题
PS:IphoneX以上的手机型号才可以连接Live Link. LiveLinkFace连接不上的几个原因. 1.IP地址不对 设置IP地址捕捉,设置-->Live Link-->添加目 ...
- ue4怎么用虚幻商城场景_【更新】UE4虚幻引擎野外场景制作零基础入门教程
原标题:[更新]UE4虚幻引擎野外场景制作零基础入门教程 作为一套零基础入门教程,可以帮助虚幻4引擎的新手了解到环境制作流程和相关软件的配合.本教学适合零基础入门用户,不适合有一定经验的UE使用者. ...
- UE4虚幻引擎关于小地图制作教程
UE4虚幻引擎关于小地图制作教程 首先,要做一个这样子的效果! 怎么做呢! 首先,我们要准备UI! 小地图,我们的分辨率是512x512 记住参数! 然后在MainUI当中!我们就可以这么设置! 一个 ...
- UE4虚幻引擎,怎么更改视图,场景中的图标大小
UE4虚幻引擎中,视图界面的图标,如SkyLight,Player Start的图标.默认缩放为1 一.打开编辑器偏好设置 二.打开Viewports视口,找到Billboard Scale公告板缩放 ...
- UE4虚幻引擎关于事件分发器的使用!
UE4虚幻引擎关于事件分发器的使用! 首先,这次就讲一下,事件分发器,在UI,Pawn,子actor如何进行事件传递! 首先!我们如果要使用事件分发器的原因是什么! 第一,肯定是方便,快! 第二,为了 ...
最新文章
- MPO文件类型解码(四)3D图像整体结构
- ceph对象存储折腾记
- 不同测试阶段,不同测试类型的区别于联系
- 常用的函数式接口_Consumer接口练习_字符串拼接输出
- centos7.2源码安装openssl1.0.2
- 河北师范大学计算机专业保研率,河北省内13所高校2021届保研率一览
- 16进制的两位数转换不了 matlab_跟小黑学漏洞利用开发之16进制字符转换
- 廖雪峰JavaScript学习笔记(基础及数据类型、变量)
- vue项目调用jssip_JsSIP和FreeSWITCH整合
- Q Learning学习笔记
- 通过计算机控制手机,用电脑控制手机的方法
- TFS2010中如何添加用户
- 高保真扬声器系统的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告的全球与中国市场
- 网上流行护眼色的RGB值和颜色代码汇总
- Android开发-基本概念小整理(四)为了面试的小伙伴们所准备~~
- github官网进不去解决方案
- NewStarCTF 公开赛wp
- BLAST原理和用法总结(一)
- SPA(单页面web应用)和MPA(多页面web应用)
- Serial Box for Mac(软件序列号查询工具)