Skip to content

Instantly share code, notes, and snippets.

@Adamcbrz
Created June 25, 2019 13:27
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Adamcbrz/087d5d9393064d2bfe71bb7927a3f1a1 to your computer and use it in GitHub Desktop.
Save Adamcbrz/087d5d9393064d2bfe71bb7927a3f1a1 to your computer and use it in GitHub Desktop.
Vive Tracker without HMD in Unreal Engine
// 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);
}
// 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);
};
// 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