]> git.tdb.fi Git - libs/game.git/commitdiff
Rewrite the VR code to match changes in mspvr
authorMikko Rasa <tdb@tdb.fi>
Thu, 30 Jan 2025 17:34:22 +0000 (19:34 +0200)
committerMikko Rasa <tdb@tdb.fi>
Thu, 30 Jan 2025 18:34:24 +0000 (20:34 +0200)
There now needs to be an entity tagged with a TrackingAnchor component
to designate the location of the tracking area within the game world.
A player character entity or something closely related should generally
be suitable.

source/game/trackinganchor.h [new file with mode: 0644]
source/gameview/motiontracker.cpp
source/gameview/motiontracker.h
source/gameview/presenter.cpp
source/gameview/presenter.h
source/gameview/renderer.cpp
source/gameview/renderer.h

diff --git a/source/game/trackinganchor.h b/source/game/trackinganchor.h
new file mode 100644 (file)
index 0000000..9297914
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef MSP_GAME_TRACKINGANCHOR_H_
+#define MSP_GAME_TRACKINGANCHOR_H_
+
+#include "component.h"
+
+namespace Msp::Game {
+
+class TrackingAnchor: public Component
+{
+public:
+       TrackingAnchor(Handle<Entity> p): Component(p) { }
+};
+
+} // namespace Msp::Game
+
+#endif
index b10633ec4b7a5109c40a94fc8997e16cae52d020..ef635ddf772dd3137e45a8a7f73b8a040476547a 100644 (file)
@@ -1,35 +1,36 @@
 #include "motiontracker.h"
 #include <msp/game/root.h>
 #include <msp/game/transform.h>
+#include <msp/vr/trackingarea.h>
 
 using namespace std;
 
 namespace Msp::GameView {
 
-MotionTracker::MotionTracker(Game::Stage &s):
+MotionTracker::MotionTracker(Game::Stage &s, const VR::TrackingArea &area):
        System(s)
 {
        declare_dependency<Game::Transform>(WRITE);
-}
-
-void MotionTracker::track(const VR::HeadTrackingCamera &cam)
-{
-       Part &part = get_or_create_part(TrackedElement::HEAD);
-       part.head = &cam;
-}
 
-void MotionTracker::track(const VR::MotionController &ctrl)
-{
-       TrackedElement::Role role;
-       switch(ctrl.get_role())
+       if(const GL::Camera *head = area.get_head())
        {
-       case VR::LEFT_HAND: role = TrackedElement::LEFT_HAND; break;
-       case VR::RIGHT_HAND: role = TrackedElement::RIGHT_HAND; break;
-       default: throw invalid_argument("MotionTracker::track");
+               Part &part = get_or_create_part(TrackedElement::HEAD);
+               part.head = head;
        }
 
-       Part &part = get_or_create_part(role);
-       part.controller = &ctrl;
+       for(const VR::MotionController *c: area.get_controllers())
+       {
+               TrackedElement::Role role;
+               switch(c->get_role())
+               {
+               case VR::LEFT_HAND: role = TrackedElement::LEFT_HAND; break;
+               case VR::RIGHT_HAND: role = TrackedElement::RIGHT_HAND; break;
+               default: continue;
+               }
+
+               Part &part = get_or_create_part(role);
+               part.controller = c;
+       }
 }
 
 auto MotionTracker::get_or_create_part(TrackedElement::Role role) -> Part &
index 36a66b43ada5147b54baf4de890dbbf608c91f66..c64e5555fb281b79375c01513864dae097679e26 100644 (file)
@@ -3,7 +3,7 @@
 
 #include <msp/game/owned.h>
 #include <msp/game/system.h>
-#include <msp/vr/headtrackingcamera.h>
+#include <msp/gl/camera.h>
 #include <msp/vr/motioncontroller.h>
 #include "trackedelement.h"
 
@@ -14,7 +14,7 @@ class MSPGAMEVIEW_API MotionTracker: public Game::System
 private:
        struct Part
        {
-               const VR::HeadTrackingCamera *head = nullptr;
+               const GL::Camera *head = nullptr;
                const VR::MotionController *controller = nullptr;
                Game::Owned<Game::Entity> entity;
                Game::Owned<TrackedElement> element;
@@ -23,10 +23,8 @@ private:
        std::vector<Part> parts;
 
 public:
-       MotionTracker(Game::Stage &);
+       MotionTracker(Game::Stage &, const VR::TrackingArea &);
 
-       void track(const VR::HeadTrackingCamera &);
-       void track(const VR::MotionController &);
 private:
        Part &get_or_create_part(TrackedElement::Role);
 
index abcb84efea3b80566e2c749c4736e30f9c68e9c2..a37684d3a7543095a61d641e1b8cd1e0fc710526 100644 (file)
@@ -17,7 +17,6 @@ Presenter::Presenter(Game::Director &d, GL::View &v):
        resources(director.get_resources()),
        event_observer(director.get_event_bus())
 {
-       event_observer.observe<Events::LocalPlayerArrived>([this](auto &e){ player_arrived(e); });
        event_observer.observe<Game::Events::StageActivated>([this](auto &e){ stage_activated(e); });
 
        if(Game::Stage *active_stage = director.get_active_stage())
@@ -33,25 +32,12 @@ Presenter::~Presenter()
 void Presenter::enable_vr(VR::System &vr_sys)
 {
        vr_system = &vr_sys;
+       vr_view = vr_sys.create_view(gl_view);
+       vr_tracking = vr_sys.create_tracking_area(VR::FIXED_ORIGIN);
        if(active_renderer)
                stage_activated({ active_renderer->get_stage() });
 }
 
-void Presenter::player_arrived(const Events::LocalPlayerArrived &event)
-{
-       Input::DeviceType VR_CONTROLLER = VR::MotionController::get_class_type();
-       for(unsigned i=0;; ++i)
-       {
-               Input::Device *dev = event.device.find_subdevice(VR_CONTROLLER, i);
-               if(!dev)
-                       break;
-
-               VR::MotionController *vr_ctrl = dynamic_cast<VR::MotionController *>(dev);
-               if(vr_ctrl)
-                       vr_controllers.push_back(vr_ctrl);
-       }
-}
-
 void Presenter::stage_activated(const Game::Events::StageActivated &event)
 {
        if(active_renderer)
@@ -60,29 +46,15 @@ void Presenter::stage_activated(const Game::Events::StageActivated &event)
        active_renderer = event.stage.get_system<Renderer>();
        if(!active_renderer)
                systems.push_back(active_renderer = &event.stage.add_system<Renderer>());
-       MotionTracker *tracker = nullptr;
-       if(vr_system)
-       {
-               tracker = event.stage.get_system<MotionTracker>();
-               if(!tracker)
-               {
-                       systems.push_back(tracker = &event.stage.add_system<MotionTracker>());
-                       for(VR::MotionController *c: vr_controllers)
-                               tracker->track(*c);
-               }
-       }
+       if(vr_system && !event.stage.get_system<MotionTracker>())
+               systems.push_back(&event.stage.add_system<MotionTracker>(*vr_tracking));
        if(event.stage.get_system<Game::Landscape>() && !event.stage.get_system<TerrainMeshCreator>())
                systems.push_back(&event.stage.add_system<TerrainMeshCreator>());
 
        if(active_renderer)
        {
-               if(vr_system)
-               {
-                       VR::StereoView *view = active_renderer->output_to_vr(*vr_system, gl_view);
-                       vr_system->set_tracking_view(view);
-                       if(const VR::HeadTrackingCamera *head = view->get_head_camera())
-                               tracker->track(*head);
-               }
+               if(vr_view)
+                       active_renderer->output_to_vr(*vr_view, vr_tracking.get());
                else
                        active_renderer->output_to_view(gl_view);
        }
index c64b8cf1a519030b81c73357450978325e452158..5c0cc6293a4c21bc073ea56ca0a75acc1bbb1f1c 100644 (file)
@@ -24,7 +24,8 @@ private:
        Game::EventObserver event_observer;
        std::vector<Game::System *> systems;
        Renderer *active_renderer = nullptr;
-       std::vector<VR::MotionController *> vr_controllers;
+       std::unique_ptr<VR::StereoView> vr_view;
+       std::unique_ptr<VR::TrackingArea> vr_tracking;
 
 public:
        Presenter(Game::Director &, GL::View &);
@@ -33,7 +34,6 @@ public:
        void enable_vr(VR::System &);
 
 private:
-       void player_arrived(const Events::LocalPlayerArrived &);
        void stage_activated(const Game::Events::StageActivated &);
 };
 
index 5d75b6045171f00d3a640d88fa1194f0aa312676..cd20ad90b010b00539916dbc79df2791b88c76e6 100644 (file)
@@ -51,23 +51,33 @@ void Renderer::output_to_view(GL::View &v)
                create_sequence();
 }
 
-VR::StereoView *Renderer::output_to_vr(VR::System &vr_sys, GL::View &view)
+void Renderer::output_to_vr(VR::StereoView &v, VR::TrackingArea *t)
 {
        cancel_output();
-       vr_view = vr_sys.create_view(view, gl_camera);
+       vr_view = &v;
+       vr_view->set_camera(&gl_camera);
+       vr_tracking = t;
+       if(vr_tracking)
+               vr_tracking->set_head(&gl_camera);
        if(active_camera)
-               create_sequence();
-       return vr_view.get();
+               camera_changed({ active_camera });
 }
 
 void Renderer::cancel_output()
 {
+       if(vr_view)
+       {
+               vr_view->set_content(nullptr);
+               vr_view->set_camera(nullptr);
+       }
        if(gl_view)
        {
                gl_view->set_content(nullptr);
                gl_view->set_camera(nullptr);
        }
        vr_view = nullptr;
+       vr_tracking = nullptr;
+       tracking_anchor = nullptr;
        sequence = nullptr;
 }
 
@@ -175,13 +185,24 @@ void Renderer::component_destroyed(const Game::Events::ComponentDestroyed &event
                                shadows_changed = true;
                }
        }
+
+       if(event.component==tracking_anchor)
+               tracking_anchor = nullptr;
 }
 
 void Renderer::camera_changed(const Game::Events::CameraChanged &event)
 {
        active_camera = event.camera;
-       if(active_camera && (gl_view || vr_view))
-               create_sequence();
+       if(active_camera)
+       {
+               tracking_anchor = nullptr;
+               for(Game::Handle<Game::Entity> e=active_camera->get_entity(); (e && !tracking_anchor); e=e->get_parent())
+                       tracking_anchor = e->get_component<Game::TrackingAnchor>();
+               if(gl_view || vr_view)
+                       create_sequence();
+       }
+       else
+               tracking_anchor = nullptr;
 }
 
 void Renderer::tick(Time::TimeDelta)
@@ -245,11 +266,14 @@ void Renderer::tick(Time::TimeDelta)
 
        if(active_camera)
        {
-               Game::Handle<Game::Transform> transform = active_camera->get_entity()->get_transform();
-               if(transform)
-                       gl_camera.set_object_matrix(transform->get_world_matrix());
-               else
-                       gl_camera.set_object_matrix(GL::Matrix());
+               if(!vr_tracking)
+               {
+                       Game::Handle<Game::Transform> transform = active_camera->get_entity()->get_transform();
+                       if(transform)
+                               gl_camera.set_object_matrix(transform->get_world_matrix());
+                       else
+                               gl_camera.set_object_matrix(GL::Matrix());
+               }
                if(active_camera->is_orthographic())
                {
                        const LinAl::Vector<float, 2> &size = active_camera->get_size();
@@ -264,7 +288,20 @@ void Renderer::tick(Time::TimeDelta)
        stage.iterate_objects<LightEmitter>([](LightEmitter &e){ e.update_matrix(); });
 
        if(vr_view)
+       {
+               if(vr_tracking)
+               {
+                       if(tracking_anchor)
+                       {
+                               const GL::Matrix &anchor_matrix = tracking_anchor->get_entity()->get_transform()->get_world_matrix();
+                               vr_tracking->set_position(anchor_matrix*GL::Vector3(0.0f, 0.0f, 0.0f));
+                               vr_tracking->set_up_direction((anchor_matrix*GL::Vector4(0.0f, 0.0f, 1.0f, 0.0f)).slice<3>(0));
+                               vr_tracking->set_forward_direction((anchor_matrix*GL::Vector4(1.0f, 0.0f, 0.0f, 0.0f)).slice<3>(0));
+                       }
+                       vr_tracking->update_for_render();
+               }
                vr_view->render();
+       }
        else if(gl_view)
                gl_view->render();
 }
index 4657e35998b6b409c7da30ba4f9fb9dbe6b03dcf..230912bdcafdea9facae4dbb37f8b1ee0a173b73 100644 (file)
@@ -6,6 +6,7 @@
 #include <msp/game/events.h>
 #include <msp/game/owned.h>
 #include <msp/game/system.h>
+#include <msp/game/trackinganchor.h>
 #include <msp/gl/camera.h>
 #include <msp/gl/light.h>
 #include <msp/gl/lighting.h>
@@ -58,14 +59,16 @@ private:
        unsigned shadow_base_size = 4096;
        bool shadows_changed = false;
        GL::View *gl_view = nullptr;
-       std::unique_ptr<VR::StereoView> vr_view;
+       VR::StereoView *vr_view = nullptr;
+       VR::TrackingArea *vr_tracking = nullptr;
+       Game::Handle<Game::TrackingAnchor> tracking_anchor;
 
 public:
        Renderer(Game::Stage &);
        ~Renderer();
 
        void output_to_view(GL::View &);
-       VR::StereoView *output_to_vr(VR::System &, GL::View &);
+       void output_to_vr(VR::StereoView &, VR::TrackingArea *);
        void cancel_output();
 private:
        void create_sequence();