源码 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 any
InitializeHMDDevice();
// Initialize attached eye tracking devices, if any
InitializeEyeTrackingDevice();
}
....................
}
//获得
//
//
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 feature
FName 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 line
FString ExplicitHMDName;
bool bUseExplicitHMDDevice = FParse::Value(FCommandLine::Get(), TEXT("hmd="), ExplicitHMDName);
// Sort modules by priority
HMDModules.Sort(IHeadMountedDisplayModule::FCompareModulePriority());
// Select first module with a connected HMD able to create a device
IHeadMountedDisplayModule* 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 line
if (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 available
if (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 line
else 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 IXRSystemIdentifier
class XRBASE_API FXRTrackingSystemBase : public IXRTrackingSystem
这个是定义一个vr设备,比如头盔 手柄 追踪器等 能获得位置等各种功能。
有这么多设备
这里基本两个大类已经出现了
在看代码的过程中,发现两个比较重要的module 一个是HeadMountedDisplay 另外一个就是XRBase
是以plugin的形式存在
它是一个普通的module,但是里面定义了很多基础的类比如FXRTrackingSystemBase 还有派生类FHeadMountedDisplayBase
这俩module是基础
接下来就是OpenXR的插件,几乎所有的厂商都有类似OpenXR插件的厂商插件比如国内厂商Pico
openXR插件定义了多个module和depend XRBase插件