ue xr 系统

发布于:2025-07-01 ⋅ 阅读:(22) ⋅ 点赞:(0)

源码 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插件

 


网站公告

今日签到

点亮在社区的每一天
去签到