Skip to content
Snippets Groups Projects
Commit 63bb2224 authored by Bernd Hentschel's avatar Bernd Hentschel
Browse files

Merge branch 'feature/#310_switching_scenes' into 'develop'

Feature/#310 switching scenes

See merge request VR-Group/Project_Phoenix!87
parents a30436a7 f9b9baba
Branches
Tags
1 merge request!87Feature/#310 switching scenes
......@@ -25,8 +25,8 @@
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <utility>
#include <vector>
#include "phx/logger.hpp"
#include "phx/scene.hpp"
......@@ -91,11 +91,18 @@ void Engine::SetScene(const std::shared_ptr<Scene>& new_scene) {
if (scene_ != nullptr) {
scene_->engine_ = nullptr;
}
scene_changed_signal_(scene_, new_scene);
// attach to new scene
scene_ = new_scene;
scene_->engine_ = this;
}
boost::signals2::connection Engine::AddSceneChangedCallback(
const std::function<void(std::shared_ptr<Scene>, std::shared_ptr<Scene>)>&
callback) {
return scene_changed_signal_.connect(callback);
}
void Engine::UpdateOrder::MoveToFront(System* system) const {
auto it = FindSystem(system);
if (it == engine_->systems_.end()) {
......
......@@ -32,6 +32,12 @@
#include <utility>
#include <vector>
SUPPRESS_WARNINGS_BEGIN
#define BOOST_BIND_NO_PLACEHOLDERS
#include "boost/signals2/connection.hpp"
#include "boost/signals2/signal.hpp"
SUPPRESS_WARNINGS_END
#include "phx/behavior.hpp"
#include "phx/export.hpp"
#include "phx/frame_timer.hpp"
......@@ -89,6 +95,10 @@ class PHOENIX_EXPORT Engine final : public Loggable {
void SetScene(const std::shared_ptr<Scene>& new_scene);
std::shared_ptr<Scene> GetScene() const;
// Parameters to the callback are: (old scene, new scene)
boost::signals2::connection AddSceneChangedCallback(
const std::function<void(std::shared_ptr<Scene>, std::shared_ptr<Scene>)>&
callback);
const FrameTimer& GetFrameTimer();
......@@ -133,6 +143,8 @@ class PHOENIX_EXPORT Engine final : public Loggable {
bool is_running_ = false;
std::shared_ptr<Scene> scene_;
boost::signals2::signal<void(std::shared_ptr<Scene>, std::shared_ptr<Scene>)>
scene_changed_signal_;
FrameTimer frame_timer_;
UpdateOrder update_order_ = UpdateOrder(this);
......
......@@ -22,6 +22,7 @@
#include "tracking_system.hpp"
#include <memory>
#include <string>
#include "display_system.hpp"
......@@ -36,20 +37,35 @@ namespace phx {
TrackingSystem::TrackingSystem(Engine* engine, DisplaySystem* display_system)
: System(engine) {
if (!display_system) error("TrackingSystem needs a valid DisplaySystem.");
CreateRuntimeEntities();
if (display_system->GetHMD()) {
CreateRuntimeEntities(engine->GetScene().get());
scene_changed_connection_ = engine->AddSceneChangedCallback(
[this](std::shared_ptr<Scene> old_scene,
std::shared_ptr<Scene> new_scene) {
OnSceneChanged(old_scene, new_scene);
});
}
}
TrackingSystem::~TrackingSystem() {
scene_changed_connection_.disconnect();
}
void TrackingSystem::Update(const FrameTimer::TimeInfo&) {
const auto hmd = engine_->GetSystem<DisplaySystem>()->GetHMD();
if (hmd == nullptr) return;
if (hmd == nullptr) {
return;
}
hmd->UpdateTrackedDevices();
const auto head_transformation = hmd->GetHeadTransformation();
if (hmd_entity_ != nullptr) {
hmd_entity_->GetFirstComponent<Transform>()->SetLocalMatrix(
head_transformation);
const auto left_eye_transformation = hmd->GetEyeToHeadMatrix(HMD::LEFT_EYE);
left_eye_entity_->GetFirstComponent<Transform>()->SetLocalMatrix(
left_eye_transformation);
const auto right_eye_transformation = hmd->GetEyeToHeadMatrix(HMD::RIGHT_EYE);
const auto right_eye_transformation =
hmd->GetEyeToHeadMatrix(HMD::RIGHT_EYE);
right_eye_entity_->GetFirstComponent<Transform>()->SetLocalMatrix(
right_eye_transformation);
......@@ -59,13 +75,9 @@ void TrackingSystem::Update(const FrameTimer::TimeInfo&) {
right_controller_entity_->GetFirstComponent<Transform>()->SetLocalMatrix(
hmd->GetRightControllerTransformation());
}
void TrackingSystem::CreateRuntimeEntities() {
const auto hmd = engine_->GetSystem<DisplaySystem>()->GetHMD();
if (hmd == nullptr) {
return;
}
auto scene = engine_->GetScene();
void TrackingSystem::CreateRuntimeEntities(Scene* scene) {
if (scene == nullptr) {
return;
}
......@@ -108,6 +120,20 @@ void TrackingSystem::CreateRuntimeEntities() {
}
}
void TrackingSystem::RemoveRuntimeEntities(Scene* scene) {
scene->RemoveEntity(hmd_entity_);
scene->RemoveEntity(left_eye_entity_);
scene->RemoveEntity(right_eye_entity_);
scene->RemoveEntity(left_controller_entity_);
scene->RemoveEntity(right_controller_entity_);
}
void TrackingSystem::OnSceneChanged(std::shared_ptr<Scene> old_scene,
std::shared_ptr<Scene> new_scene) {
RemoveRuntimeEntities(old_scene.get());
CreateRuntimeEntities(new_scene.get());
}
std::string TrackingSystem::ToString() const { return "Tracking System"; }
} // namespace phx
......@@ -23,6 +23,7 @@
#ifndef LIBRARY_PHX_TRACKING_SYSTEM_HPP_
#define LIBRARY_PHX_TRACKING_SYSTEM_HPP_
#include <memory>
#include <string>
#include "phx/display_system.hpp"
......@@ -30,6 +31,11 @@
#include "phx/export.hpp"
#include "phx/system.hpp"
SUPPRESS_WARNINGS_BEGIN
#define BOOST_BIND_NO_PLACEHOLDERS
#include "boost/signals2/connection.hpp"
SUPPRESS_WARNINGS_END
namespace phx {
class PHOENIX_EXPORT TrackingSystem : public System {
......@@ -37,7 +43,7 @@ class PHOENIX_EXPORT TrackingSystem : public System {
TrackingSystem() = delete;
TrackingSystem(const TrackingSystem&) = delete;
TrackingSystem(TrackingSystem&&) = default;
~TrackingSystem() = default;
~TrackingSystem();
TrackingSystem& operator=(const TrackingSystem&) = delete;
TrackingSystem& operator=(TrackingSystem&&) = default;
......@@ -50,17 +56,22 @@ class PHOENIX_EXPORT TrackingSystem : public System {
TrackingSystem(Engine* engine, DisplaySystem* display_system);
private:
void CreateRuntimeEntities();
template <typename SystemType, typename... SystemArguments>
friend SystemType* Engine::CreateSystem(SystemArguments&&... arguments);
explicit TrackingSystem(Engine* engine);
void CreateRuntimeEntities(Scene* scene);
void RemoveRuntimeEntities(Scene* scene);
void OnSceneChanged(std::shared_ptr<Scene> old_scene,
std::shared_ptr<Scene> new_scene);
Entity* hmd_entity_ = nullptr;
Entity* left_eye_entity_ = nullptr;
Entity* right_eye_entity_ = nullptr;
Entity* left_controller_entity_ = nullptr;
Entity* right_controller_entity_ = nullptr;
boost::signals2::connection scene_changed_connection_;
};
} // namespace phx
......
......@@ -177,11 +177,26 @@ SCENARIO("The active scene in an engine can be switched",
GIVEN("An engine") {
phx::Engine engine;
auto first_scene = std::make_shared<phx::Scene>();
// setup a way to test the scene changed signal
phx::Scene* s1;
phx::Scene* s2;
engine.AddSceneChangedCallback(
[&s1, &s2](std::shared_ptr<phx::Scene> param_s1,
std::shared_ptr<phx::Scene> param_s2) {
s1 = param_s1.get();
s2 = param_s2.get();
});
engine.SetScene(first_scene);
THEN("It has a scene") {
REQUIRE(engine.GetScene() != nullptr);
REQUIRE(engine.GetScene()->GetEngine() == &engine);
}
THEN("The old scene is nullptr.") { REQUIRE(s1 == nullptr); }
THEN("The new scene is the one we just set.") {
REQUIRE(s2 == first_scene.get());
}
WHEN("The scene is exchanged for a new scene") {
auto new_scene = std::make_shared<phx::Scene>();
engine.SetScene(new_scene);
......@@ -194,6 +209,10 @@ SCENARIO("The active scene in an engine can be switched",
REQUIRE(first_scene->GetEngine() == nullptr);
}
THEN("The signal is triggered with the appropriate values.") {
REQUIRE(s1 == first_scene.get());
REQUIRE(s2 == new_scene.get());
}
}
}
}
......
......@@ -56,164 +56,259 @@ void SetGlmToArrayMatrix_3_4(glm::mat4 m, float* array) {
}
}
SCENARIO(
"The tracking system tracks hardware and updates their software "
"counterparts.",
"[phx][phx::TrackingSystem]") {
OPENVR_MOCK_ALLOW_ANY_CALL;
SDL_MOCK_ALLOW_ANY_CALL;
template <typename ComponentType>
bool HasComponent(phx::Entity *entity) {
return entity->GetFirstComponent<ComponentType>() != nullptr;
}
phx::Engine engine;
auto display_system = engine.CreateSystem<phx::DisplaySystem>();
bool HasUserPlatform(phx::Entity *entity) {
return HasComponent<phx::RuntimeComponent<phx::USER_PLATFORM>>(entity);
}
GIVEN(
"The display system has an HMD and the engine has a scene with a "
"user platform.") {
display_system->CreateHMD();
auto scene = std::make_shared<phx::Scene>();
engine.SetScene(scene);
auto platform_trans_mat =
glm::mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 1.0f, -1.0f, 0.5f, 1.0f);
scene
->GetEntitiesWithComponents<
phx::RuntimeComponent<phx::USER_PLATFORM>>()[0]
->GetFirstComponent<phx::Transform>()
->SetLocalMatrix(platform_trans_mat);
WHEN("A tracking system is created and initialized.") {
auto tracking_system =
engine.CreateSystem<phx::TrackingSystem>(display_system);
THEN("The HMD and the user's eyes are represented in the scene.") {
auto entities = scene->GetEntitiesWithComponents<phx::Transform>();
bool platform_present = false;
bool hmd_present = false;
bool left_eye_present = false;
bool right_eye_present = false;
bool left_controller_present = false;
bool right_controller_present = false;
for (auto entity : entities) {
if (entity->GetFirstComponent<
phx::RuntimeComponent<phx::USER_PLATFORM>>()) {
bool HasHMD(phx::Entity *entity) {
return HasComponent<phx::RuntimeComponent<phx::HEAD>>(entity);
}
bool HasTransform(phx::Entity *entity) {
return HasComponent<phx::Transform>(entity);
}
bool HasLeftEye(phx::Entity *entity) {
return HasComponent<phx::RuntimeComponent<phx::LEFT_EYE>>(entity);
}
bool HasRightEye(phx::Entity *entity) {
return HasComponent<phx::RuntimeComponent<phx::RIGHT_EYE>>(entity);
}
bool HasProjection(phx::Entity *entity) {
return HasComponent<phx::Projection>(entity);
}
bool HasLeftController(phx::Entity *entity) {
return HasComponent<phx::RuntimeComponent<phx::LEFT_CONTROLLER>>(entity);
}
bool HasRightController(phx::Entity *entity) {
return HasComponent<phx::RuntimeComponent<phx::RIGHT_CONTROLLER>>(entity);
}
bool ValidateUserPlatform(phx::Entity *entity, bool platform_present) {
if (HasUserPlatform(entity)) {
THEN("There is only one virtual platform.") {
REQUIRE(platform_present == false);
}
platform_present = true;
return true;
}
return false;
}
if (entity->GetFirstComponent<phx::RuntimeComponent<phx::HEAD>>()) {
bool ValidateHMD(phx::Entity *entity, bool hmd_present) {
if (HasHMD(entity)) {
THEN("There is only one HMD.") { REQUIRE(hmd_present == false); }
THEN("The HMD has a transform component.") {
REQUIRE(entity->GetFirstComponent<phx::Transform>());
REQUIRE(HasTransform(entity));
}
THEN(
"The parent of the HMD's transform is the platform's "
"transform.") {
REQUIRE(
entity->GetFirstComponent<phx::Transform>()->GetParent() !=
REQUIRE(entity->GetFirstComponent<phx::Transform>()->GetParent() !=
nullptr);
REQUIRE(entity->GetFirstComponent<phx::Transform>()
REQUIRE(
entity->GetFirstComponent<phx::Transform>()
->GetParent()
->GetEntity()
->GetFirstComponent<
phx::RuntimeComponent<phx::USER_PLATFORM>>());
->GetFirstComponent<phx::RuntimeComponent<phx::USER_PLATFORM>>());
}
hmd_present = true;
return true;
}
if (entity
->GetFirstComponent<phx::RuntimeComponent<phx::LEFT_EYE>>()) {
THEN("There is only one left eye.") {
REQUIRE(left_eye_present == false);
return false;
}
bool ValidateLeftEye(phx::Entity *entity, bool left_eye_present) {
if (HasLeftEye(entity)) {
THEN("There is only one left eye.") { REQUIRE(left_eye_present == false); }
THEN("The left eye has a transform component.") {
REQUIRE(entity->GetFirstComponent<phx::Transform>());
REQUIRE(HasTransform(entity));
}
THEN("The left eye has a projection component.") {
REQUIRE(entity->GetFirstComponent<phx::Projection>());
REQUIRE(HasProjection(entity));
}
THEN(
"The parent of the left eye's transform is the HMD's "
"transform.") {
REQUIRE(
entity->GetFirstComponent<phx::Transform>()->GetParent() !=
REQUIRE(entity->GetFirstComponent<phx::Transform>()->GetParent() !=
nullptr);
REQUIRE(
entity->GetFirstComponent<phx::Transform>()
REQUIRE(entity->GetFirstComponent<phx::Transform>()
->GetParent()
->GetEntity()
->GetFirstComponent<phx::RuntimeComponent<phx::HEAD>>());
}
left_eye_present = true;
return true;
}
if (entity->GetFirstComponent<
phx::RuntimeComponent<phx::RIGHT_EYE>>()) {
return false;
}
bool ValidateRightEye(phx::Entity *entity, bool right_eye_present) {
if (HasRightEye(entity)) {
THEN("There is only one right eye.") {
REQUIRE(right_eye_present == false);
}
THEN("The right eye has a transform component.") {
REQUIRE(entity->GetFirstComponent<phx::Transform>());
REQUIRE(HasTransform(entity));
}
THEN("The right eye has a projection component.") {
REQUIRE(entity->GetFirstComponent<phx::Projection>());
REQUIRE(HasProjection(entity));
}
THEN(
"The parent of the right eye's transform is the HMD's "
"transform.") {
REQUIRE(
entity->GetFirstComponent<phx::Transform>()->GetParent() !=
REQUIRE(entity->GetFirstComponent<phx::Transform>()->GetParent() !=
nullptr);
REQUIRE(
entity->GetFirstComponent<phx::Transform>()
REQUIRE(entity->GetFirstComponent<phx::Transform>()
->GetParent()
->GetEntity()
->GetFirstComponent<phx::RuntimeComponent<phx::HEAD>>());
}
right_eye_present = true;
return true;
}
return false;
}
if (entity->GetFirstComponent<
phx::RuntimeComponent<phx::LEFT_CONTROLLER>>()) {
bool ValidateLeftController(phx::Entity *entity, bool left_controller_present) {
if (HasLeftController(entity)) {
THEN("There is only one left controller.") {
REQUIRE(left_controller_present == false);
}
THEN("The left controller has a transform component.") {
REQUIRE(entity->GetFirstComponent<phx::Transform>());
REQUIRE(HasTransform(entity));
}
THEN(
"The parent of the left controller's transform is the "
"platform's transform.") {
REQUIRE(
entity->GetFirstComponent<phx::Transform>()->GetParent() !=
REQUIRE(entity->GetFirstComponent<phx::Transform>()->GetParent() !=
nullptr);
REQUIRE(entity->GetFirstComponent<phx::Transform>()
REQUIRE(
entity->GetFirstComponent<phx::Transform>()
->GetParent()
->GetEntity()
->GetFirstComponent<
phx::RuntimeComponent<phx::USER_PLATFORM>>());
->GetFirstComponent<phx::RuntimeComponent<phx::USER_PLATFORM>>());
}
return true;
}
left_controller_present = true;
return false;
}
if (entity->GetFirstComponent<
phx::RuntimeComponent<phx::RIGHT_CONTROLLER>>()) {
bool ValidateRightController(phx::Entity *entity,
bool right_controller_present) {
if (HasRightController(entity)) {
THEN("There is only one right controller.") {
REQUIRE(right_controller_present == false);
}
THEN("The right controller has a transform component.") {
REQUIRE(entity->GetFirstComponent<phx::Transform>());
REQUIRE(HasTransform(entity));
}
THEN(
"The parent of the right controller's transform is the "
"platform's transform.") {
REQUIRE(
entity->GetFirstComponent<phx::Transform>()->GetParent() !=
REQUIRE(entity->GetFirstComponent<phx::Transform>()->GetParent() !=
nullptr);
REQUIRE(entity->GetFirstComponent<phx::Transform>()
REQUIRE(
entity->GetFirstComponent<phx::Transform>()
->GetParent()
->GetEntity()
->GetFirstComponent<
phx::RuntimeComponent<phx::USER_PLATFORM>>());
->GetFirstComponent<phx::RuntimeComponent<phx::USER_PLATFORM>>());
}
return true;
}
right_controller_present = true;
return false;
}
bool ValidatePlatformTransform(phx::Entity *entity,
glm::mat4 platform_trans_mat) {
if (HasUserPlatform(entity)) {
THEN("The platform transformation did not change.") {
REQUIRE(
test_utilities::Approx<glm::mat4>(
entity->GetFirstComponent<phx::Transform>()->GetLocalMatrix()) ==
platform_trans_mat);
}
return true;
}
return false;
}
bool ValidateHMDTransform(phx::Entity *entity, glm::mat4 hmd_trans_mat) {
if (HasHMD(entity)) {
THEN(
"The hmd transformation changes to the one provided by "
"OpenVR.") {
REQUIRE(
test_utilities::Approx<glm::mat4>(
entity->GetFirstComponent<phx::Transform>()->GetLocalMatrix()) ==
hmd_trans_mat);
}
return true;
}
return false;
}
bool ValidateLeftEyeTransform(phx::Entity *entity,
glm::mat4 left_eye_trans_mat) {
if (HasLeftEye(entity)) {
THEN(
"The left eye transformation changes to the one provided "
"by OpenVR.") {
REQUIRE(
test_utilities::Approx<glm::mat4>(
entity->GetFirstComponent<phx::Transform>()->GetLocalMatrix()) ==
left_eye_trans_mat);
}
return true;
}
return false;
}
bool ValidateRightEyeTransform(phx::Entity *entity,
glm::mat4 right_eye_trans_mat) {
if (HasRightEye(entity)) {
THEN(
"The right eye transformation changes to the one provided "
"by OpenVR.") {
REQUIRE(
test_utilities::Approx<glm::mat4>(
entity->GetFirstComponent<phx::Transform>()->GetLocalMatrix()) ==
right_eye_trans_mat);
}
return true;
}
return false;
}
void TestRuntimeEntityStructure(std::shared_ptr<phx::Scene> scene) {
THEN("The HMD and the user's eyes are represented in the scene.") {
auto entities = scene->GetEntitiesWithComponents<phx::Transform>();
bool platform_present = false;
bool hmd_present = false;
bool left_eye_present = false;
bool right_eye_present = false;
bool left_controller_present = false;
bool right_controller_present = false;
for (auto entity : entities) {
platform_present |= ValidateUserPlatform(entity, platform_present);
hmd_present |= ValidateHMD(entity, hmd_present);
left_eye_present |= ValidateLeftEye(entity, left_eye_present);
right_eye_present |= ValidateRightEye(entity, right_eye_present);
left_controller_present |=
ValidateLeftController(entity, left_controller_present);
right_controller_present |=
ValidateLeftController(entity, right_controller_present);
}
THEN(
"There are six entities: The platform, the HMD, the left and "
"the right eyes, the left and right controllers.") {
......@@ -226,22 +321,35 @@ SCENARIO(
REQUIRE(right_controller_present);
}
}
WHEN("The tracking system is then updated.") {
auto hmd_trans_mat =
glm::mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.5f, 1.8f, 0.2f, 1.0f);
auto left_eye_trans_mat =
glm::mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, -0.04f, 0.0f, 0.0f, 1.0f);
auto right_eye_trans_mat =
glm::mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.04f, 0.0f, 0.0f, 1.0f);
SetGlmToArrayMatrix_3_4(hmd_trans_mat,
openvr_mock.head_transformation_);
SetGlmToArrayMatrix_3_4(left_eye_trans_mat,
openvr_mock.eye_to_head_left_);
SetGlmToArrayMatrix_3_4(right_eye_trans_mat,
openvr_mock.eye_to_head_right_);
}
void InitMatrices(glm::mat4 *platform_trans_mat, glm::mat4 *hmd_trans_mat,
glm::mat4 *left_eye_trans_mat,
glm::mat4 *right_eye_trans_mat) {
*platform_trans_mat =
glm::mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 1.0f, -1.0f, 0.5f, 1.0f);
*hmd_trans_mat = glm::mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 1.8f, 0.2f, 1.0f);
*left_eye_trans_mat =
glm::mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 0.0f, -0.04f, 0.0f, 0.0f, 1.0f);
*right_eye_trans_mat =
glm::mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.04f, 0.0f, 0.0f, 1.0f);
SetGlmToArrayMatrix_3_4(*hmd_trans_mat, openvr_mock.head_transformation_);
SetGlmToArrayMatrix_3_4(*left_eye_trans_mat, openvr_mock.eye_to_head_left_);
SetGlmToArrayMatrix_3_4(*right_eye_trans_mat, openvr_mock.eye_to_head_right_);
}
void TestRuntimeEntityUpdate(std::shared_ptr<phx::Scene> scene,
phx::TrackingSystem *tracking_system) {
glm::mat4 platform_trans_mat, hmd_trans_mat, left_eye_trans_mat,
right_eye_trans_mat;
InitMatrices(&platform_trans_mat, &hmd_trans_mat, &left_eye_trans_mat,
&right_eye_trans_mat);
WHEN("The tracking system is updated.") {
tracking_system->Update(phx::FrameTimer::TimeInfo());
THEN(
"It sets the transforms of all the runtime entities to the "
......@@ -253,56 +361,20 @@ SCENARIO(
bool right_eye_present = false;
bool left_controller_present = false;
bool right_controller_present = false;
for (auto entity : entities) {
if (entity->GetFirstComponent<
phx::RuntimeComponent<phx::USER_PLATFORM>>()) {
THEN("The platform transformation did not change.") {
REQUIRE(test_utilities::Approx<glm::mat4>(
entity->GetFirstComponent<phx::Transform>()
->GetLocalMatrix()) == platform_trans_mat);
}
platform_present = true;
}
if (entity->GetFirstComponent<phx::RuntimeComponent<phx::HEAD>>()) {
THEN(
"The hmd transformation changes to the one provided by "
"OpenVR.") {
REQUIRE(test_utilities::Approx<glm::mat4>(
entity->GetFirstComponent<phx::Transform>()
->GetLocalMatrix()) == hmd_trans_mat);
}
hmd_present = true;
}
if (entity->GetFirstComponent<
phx::RuntimeComponent<phx::LEFT_EYE>>()) {
THEN(
"The left eye transformation changes to the one provided "
"by OpenVR.") {
REQUIRE(test_utilities::Approx<glm::mat4>(
entity->GetFirstComponent<phx::Transform>()
->GetLocalMatrix()) == left_eye_trans_mat);
}
left_eye_present = true;
}
if (entity->GetFirstComponent<
phx::RuntimeComponent<phx::RIGHT_EYE>>()) {
THEN(
"The right eye transformation changes to the one provided "
"by OpenVR.") {
REQUIRE(test_utilities::Approx<glm::mat4>(
entity->GetFirstComponent<phx::Transform>()
->GetLocalMatrix()) == right_eye_trans_mat);
}
right_eye_present = true;
}
if (entity->GetFirstComponent<
phx::RuntimeComponent<phx::LEFT_CONTROLLER>>()) {
left_controller_present = true;
}
if (entity->GetFirstComponent<
phx::RuntimeComponent<phx::RIGHT_CONTROLLER>>()) {
right_controller_present = true;
}
platform_present |=
ValidatePlatformTransform(entity, platform_trans_mat);
hmd_present |= ValidateHMDTransform(entity, hmd_trans_mat);
left_eye_present |=
ValidateLeftEyeTransform(entity, left_eye_trans_mat);
right_eye_present |=
ValidateRightEyeTransform(entity, right_eye_trans_mat);
left_controller_present |= HasLeftController(entity);
right_controller_present |= HasRightController(entity);
}
THEN(
"There are still six entities: The platform, the HMD, the "
......@@ -318,5 +390,79 @@ SCENARIO(
}
}
}
SCENARIO(
"The tracking system tracks hardware and updates their software "
"counterparts.",
"[phx][phx::TrackingSystem]") {
OPENVR_MOCK_ALLOW_ANY_CALL;
SDL_MOCK_ALLOW_ANY_CALL;
phx::Engine engine;
auto display_system = engine.CreateSystem<phx::DisplaySystem>();
GIVEN(
"The display system has an HMD and the engine has a scene with a "
"user platform.") {
display_system->CreateHMD();
auto first_scene = std::make_shared<phx::Scene>();
engine.SetScene(first_scene);
auto platform_trans_mat =
glm::mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 1.0f, -1.0f, 0.5f, 1.0f);
first_scene
->GetEntitiesWithComponents<
phx::RuntimeComponent<phx::USER_PLATFORM>>()[0]
->GetFirstComponent<phx::Transform>()
->SetLocalMatrix(platform_trans_mat);
WHEN("A tracking system is created and initialized.") {
auto tracking_system =
engine.CreateSystem<phx::TrackingSystem>(display_system);
TestRuntimeEntityStructure(first_scene);
TestRuntimeEntityUpdate(first_scene, tracking_system);
WHEN("The scene is then changed.") {
auto new_scene = std::make_shared<phx::Scene>();
new_scene
->GetEntitiesWithComponents<
phx::RuntimeComponent<phx::USER_PLATFORM>>()[0]
->GetFirstComponent<phx::Transform>()
->SetLocalMatrix(platform_trans_mat);
engine.SetScene(new_scene);
THEN(
"The first scene does not contain runtime entities except for "
"exactly one user platform.") {
REQUIRE(first_scene
->GetEntitiesWithComponents<
phx::RuntimeComponent<phx::USER_PLATFORM>>()
.size() == 1);
REQUIRE(first_scene
->GetEntitiesWithComponents<
phx::RuntimeComponent<phx::HEAD>>()
.size() == 0);
REQUIRE(first_scene
->GetEntitiesWithComponents<
phx::RuntimeComponent<phx::LEFT_EYE>>()
.size() == 0);
REQUIRE(first_scene
->GetEntitiesWithComponents<
phx::RuntimeComponent<phx::RIGHT_EYE>>()
.size() == 0);
REQUIRE(first_scene
->GetEntitiesWithComponents<
phx::RuntimeComponent<phx::LEFT_CONTROLLER>>()
.size() == 0);
REQUIRE(first_scene
->GetEntitiesWithComponents<
phx::RuntimeComponent<phx::RIGHT_CONTROLLER>>()
.size() == 0);
}
TestRuntimeEntityStructure(new_scene);
TestRuntimeEntityUpdate(new_scene, tracking_system);
}
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment