ue xr 系统
源码 5.3
ue的xr系统分的模块比较碎
最基础的
Source--Runtime---HeadMountedDisplay
这个module是ue关于xr的抽象层,定义了基础的类和 基本的方法。
class IHeadMountedDisplayModule : public IModuleInterface, public IModularFeature
定义了所有扩展的xr的module
在Engine中
void UEngine::Init(IEngineLoop* InEngineLoop)
{.....................if (!FApp::IsProjectNameEmpty()){// Initialize the HMDs and motion controllers, if anyInitializeHMDDevice();// Initialize attached eye tracking devices, if anyInitializeEyeTrackingDevice();} ....................
}//获得
//
//
bool UEngine::InitializeHMDDevice()
{if (!IsRunningCommandlet()){static TAutoConsoleVariable<int32> CVarEmulateStereo(TEXT("r.EnableStereoEmulation"), 0, TEXT("Emulate stereo rendering"), ECVF_ReadOnly);if (FParse::Param(FCommandLine::Get(), TEXT("emulatestereo")) || CVarEmulateStereo.GetValueOnAnyThread() != 0){TSharedPtr<FFakeStereoRenderingDevice, ESPMode::ThreadSafe> FakeStereoDevice(new FFakeStereoRenderingDevice(GSystemResolution.ResX / 2, GSystemResolution.ResY));StereoRenderingDevice = FakeStereoDevice;}// No reason to connect an HMD on a dedicated server. Also fixes dedicated servers stealing the oculus connection.else if (!XRSystem.IsValid() && !FParse::Param(FCommandLine::Get(), TEXT("nohmd")) && !IsRunningDedicatedServer()){// Get a list of modules that implement this featureFName Type = IHeadMountedDisplayModule::GetModularFeatureName();IModularFeatures& ModularFeatures = IModularFeatures::Get();//获得所有继承于IHeadMountedDisplayModule的module//然后遍历,当HMDModule->IsHMDConnected() 就XRSystem = HMDModule->CreateTrackingSystem();TArray<IHeadMountedDisplayModule*> HMDModules = ModularFeatures.GetModularFeatureImplementations<IHeadMountedDisplayModule>(Type);// Check whether the user passed in an explicit HMD module on the command lineFString ExplicitHMDName;bool bUseExplicitHMDDevice = FParse::Value(FCommandLine::Get(), TEXT("hmd="), ExplicitHMDName);// Sort modules by priorityHMDModules.Sort(IHeadMountedDisplayModule::FCompareModulePriority());// Select first module with a connected HMD able to create a deviceIHeadMountedDisplayModule* HMDModuleSelected = nullptr;TArray<IHeadMountedDisplayModule*> HMDModulesDisconnected;for (auto HMDModuleIt = HMDModules.CreateIterator(); HMDModuleIt; ++HMDModuleIt){IHeadMountedDisplayModule* HMDModule = *HMDModuleIt;// Skip all non-matching modules when an explicit module name has been specified on the command lineif (bUseExplicitHMDDevice){TArray<FString> HMDAliases;HMDModule->GetModuleAliases(HMDAliases);HMDAliases.Add(HMDModule->GetModuleKeyName());bool bMatchesExplicitDevice = false;for (const FString& HMDModuleName : HMDAliases){if (ExplicitHMDName.Equals(HMDModuleName, ESearchCase::IgnoreCase)){bMatchesExplicitDevice = true;break;}}if (!bMatchesExplicitDevice){continue;}}if(HMDModule->IsHMDConnected()){XRSystem = HMDModule->CreateTrackingSystem();if (XRSystem.IsValid()){HMDModuleSelected = HMDModule;break;}}else{HMDModulesDisconnected.Add(HMDModule);}}// If no module selected yet, just select first module able to create a device, even if HMD is not connected.if (!HMDModuleSelected){for (auto HMDModuleIt = HMDModulesDisconnected.CreateIterator(); HMDModuleIt; ++HMDModuleIt){IHeadMountedDisplayModule* HMDModule = *HMDModuleIt;XRSystem = HMDModule->CreateTrackingSystem();if (XRSystem.IsValid()){HMDModuleSelected = HMDModule;break;}}}// Unregister modules which were not selected, since they will not be used.for (auto HMDModuleIt = HMDModules.CreateIterator(); HMDModuleIt; ++HMDModuleIt){IHeadMountedDisplayModule* HMDModule = *HMDModuleIt;if(HMDModule != HMDModuleSelected){ModularFeatures.UnregisterModularFeature(Type, HMDModule);}}// If we found a valid XRSystem, use it to get a stereo rendering device, if availableif (XRSystem.IsValid() && !FParse::Param(FCommandLine::Get(), TEXT("noxrstereo"))){StereoRenderingDevice = XRSystem->GetStereoRenderingDevice();const bool bShouldStartInVR = StereoRenderingDevice.IsValid() && !GIsEditor &&IStereoRendering::IsStartInVR();if (bShouldStartInVR){StereoRenderingDevice->EnableStereo(true);}}// Else log an error if we got an explicit module name on the command lineelse if (bUseExplicitHMDDevice){UE_LOG(LogInit, Error, TEXT("Failed to find or initialize HMD module named '%s'. HMD mode will be disabled."), *ExplicitHMDName);}}}return StereoRenderingDevice.IsValid();
}
看看 初级 继承于 都有哪些Module
ISimpleHMDPlugin算是一个例子,可以参考怎么做出一个xr插件
有pixstreaming像素流也可以用vr展示了
有苹果和谷歌的arkit和arcore
有openXR的
那么看看TrackingSystem是什么,是IXRTrackingSystem
TSharedPtr< class IXRTrackingSystem, ESPMode::ThreadSafe > XRSystem;class IXRSystemIdentifier
{
public:/*** Returns a unique identifier that's supposed to represent the third party * system that this object is part of (Vive, Oculus, PSVR, etc.).** @return A name unique to the system which this object belongs to.*/virtual FName GetSystemName() const = 0;
};class IXRTrackingSystem : public IModularFeature, public IXRSystemIdentifierclass XRBASE_API FXRTrackingSystemBase : public IXRTrackingSystem
这个是定义一个vr设备,比如头盔 手柄 追踪器等 能获得位置等各种功能。
有这么多设备
这里基本两个大类已经出现了
在看代码的过程中,发现两个比较重要的module 一个是HeadMountedDisplay 另外一个就是XRBase
是以plugin的形式存在
它是一个普通的module,但是里面定义了很多基础的类比如FXRTrackingSystemBase 还有派生类FHeadMountedDisplayBase
这俩module是基础
接下来就是OpenXR的插件,几乎所有的厂商都有类似OpenXR插件的厂商插件比如国内厂商Pico
openXR插件定义了多个module和depend XRBase插件