Created
June 25, 2019 13:27
-
-
Save Adamcbrz/087d5d9393064d2bfe71bb7927a3f1a1 to your computer and use it in GitHub Desktop.
Vive Tracker without HMD in Unreal Engine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Fill out your copyright notice in the Description page of Project Settings. | |
#include "Tracker.h" | |
// Sets default values | |
ATracker::ATracker() | |
{ | |
// 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; | |
// Initialize VR | |
vr::EVRInitError peError; | |
vrSystem = vr::VR_Init(&peError, vr::EVRApplicationType::VRApplication_Other); | |
// Setup trackerID to -1 so we can test when it is set | |
trackerID = -1; | |
// Create Components | |
sceneComponent = CreateAbstractDefaultSubobject<USceneComponent>(TEXT("Scene")); | |
RootComponent = sceneComponent; | |
cameraComponent = CreateAbstractDefaultSubobject<UCameraComponent>(TEXT("Camera")); | |
cameraComponent->AttachTo(sceneComponent); | |
} | |
// Called when the game starts or when spawned | |
void ATracker::BeginPlay() | |
{ | |
Super::BeginPlay(); | |
// Grab player controller so we can setup the camera and enable input | |
APlayerController* playerController = UGameplayStatics::GetPlayerController(this, 0); | |
EnableInput(playerController); // This is probably not needed unless you need to receive input like keyboard events. | |
playerController->SetViewTargetWithBlend(this, 0); | |
fieldOfView = cameraComponent->FieldOfView; | |
cameraOffset = cameraComponent->RelativeLocation; | |
cameraRotation = cameraComponent->RelativeRotation; | |
} | |
vr::HmdMatrix34_t ATracker::UpdateTracker(int id) | |
{ | |
//Get Tracker Pose | |
vr::VRControllerState_t *state = new vr::VRControllerState_t(); | |
vr::TrackedDevicePose_t *pose = new vr::TrackedDevicePose_t(); | |
vrSystem->GetControllerStateWithPose(vr::ETrackingUniverseOrigin::TrackingUniverseStanding, id, state, sizeof(vr::VRControllerState_t), pose); | |
//Get Pose Position | |
vr::HmdMatrix34_t posMat = pose->mDeviceToAbsoluteTracking; | |
if (trackerID != -1) | |
{ | |
//Build Quaternion From Matrix | |
float w = FGenericPlatformMath::Sqrt(1.0 + posMat.m[0][0] + posMat.m[1][1] + posMat.m[2][2]) / 2.0; | |
float w4 = (4.0 * w); | |
float x = (posMat.m[2][1] - posMat.m[1][2]) / w4; | |
float y = (posMat.m[0][2] - posMat.m[2][0]) / w4; | |
float z = (posMat.m[1][0] - posMat.m[0][1]) / w4; | |
// Postion and Rotate Actor | |
sceneComponent->SetWorldLocationAndRotationNoPhysics( | |
FVector(-posMat.m[2][3] * 100, posMat.m[0][3] * 100, posMat.m[1][3] * 100), | |
FQuat(z, -x, -y, w).Rotator()); | |
} | |
return posMat; | |
} | |
// Called every frame | |
void ATracker::Tick(float DeltaTime) | |
{ | |
Super::Tick(DeltaTime); | |
// Find Tracker if trackerID is -1 else update tracker | |
if (trackerID == -1) | |
{ | |
// Loop through tracker ids skipping the first one because that is our null HMD. | |
for (uint32_t i = 1; i <= 8; i++) { | |
vr::HmdMatrix34_t posMat = UpdateTracker(i); | |
// Verify the postion of the tracker isn't vector zero. | |
if (posMat.m[0][3] != 0 && posMat.m[1][3] != 0 && posMat.m[2][3] != 0) | |
{ | |
trackerID = i; | |
break; | |
} | |
} | |
} | |
else | |
{ | |
UpdateTracker(trackerID); | |
} | |
} | |
float ATracker::GetFieldOfView() const | |
{ | |
return fieldOfView; | |
} | |
void ATracker::SetFieldOfView(float fov) | |
{ | |
fieldOfView = fov; | |
cameraComponent->SetFieldOfView(fieldOfView); | |
} | |
FVector ATracker::GetCameraOffset() const | |
{ | |
return cameraOffset; | |
} | |
void ATracker::SetCameraOffset(FVector offset) | |
{ | |
cameraOffset = offset; | |
cameraComponent->SetRelativeLocation(offset); | |
} | |
FRotator ATracker::GetCameraRotation() const | |
{ | |
return cameraRotation; | |
} | |
void ATracker::SetCameraRotation(FRotator rotation) | |
{ | |
cameraRotation = rotation; | |
cameraComponent->SetRelativeRotation(rotation); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Fill out your copyright notice in the Description page of Project Settings. | |
#pragma once | |
#include "CoreMinimal.h" | |
#include "GameFramework/Actor.h" | |
#include "openvr.h" | |
#include "Runtime/Engine/Classes/Camera/CameraComponent.h" | |
#include "Runtime/Core/Public/GenericPlatform/GenericPlatformMath.h" | |
#include "Kismet/GameplayStatics.h" | |
#include "Tracker.generated.h" | |
UCLASS() | |
class TRACKEREXAMPLE_API ATracker : public AActor | |
{ | |
GENERATED_BODY() | |
public: | |
// Sets default values for this actor's properties | |
ATracker(); | |
protected: | |
// Called when the game starts or when spawned | |
virtual void BeginPlay() override; | |
// Our connnection to the VR System | |
vr::IVRSystem* vrSystem; | |
// ID for which tracker to utilize | |
uint32_t trackerID; | |
// I always add a scene component as my root object as default | |
USceneComponent* sceneComponent; | |
// Method to update the tracker and returns the position of the tracker. | |
vr::HmdMatrix34_t UpdateTracker(int id); | |
public: | |
// Called every frame | |
virtual void Tick(float DeltaTime) override; | |
// I am attahing a camera to my scene component to use as a virtual camera. | |
UPROPERTY(VisibleAnywhere) | |
UCameraComponent* cameraComponent; | |
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera", BlueprintGetter = GetFieldOfView, BlueprintSetter = SetFieldOfView) | |
float fieldOfView; | |
UFUNCTION(BlueprintGetter) | |
float GetFieldOfView() const; | |
UFUNCTION(BlueprintSetter) | |
void SetFieldOfView(float fov); | |
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera", BlueprintGetter = GetCameraOffset, BlueprintSetter = SetCameraOffset) | |
FVector cameraOffset; | |
UFUNCTION(BlueprintGetter) | |
FVector GetCameraOffset() const; | |
UFUNCTION(BlueprintSetter) | |
void SetCameraOffset(FVector offset); | |
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera", BlueprintGetter = GetCameraRotation, BlueprintSetter = SetCameraRotation) | |
FRotator cameraRotation; | |
UFUNCTION(BlueprintGetter) | |
FRotator GetCameraRotation() const; | |
UFUNCTION(BlueprintSetter) | |
void SetCameraRotation(FRotator rotation); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Fill out your copyright notice in the Description page of Project Settings. | |
using UnrealBuildTool; | |
public class TrackerExample : ModuleRules | |
{ | |
public TrackerExample(ReadOnlyTargetRules Target) : base(Target) | |
{ | |
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; | |
PublicDependencyModuleNames.AddRange(new string[] { | |
"Core", | |
"CoreUObject", | |
"Engine", | |
"InputCore", | |
"OpenVR", | |
"SteamVR", | |
"SteamVRController", | |
"HeadMountedDisplay", | |
"UMG", | |
"Slate", | |
"SlateCore" | |
}); | |
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 true | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment