Skip to content

Commit a149534

Browse files
committed
Allow spaces and layers to be positioned in vsg coordinate space
1 parent 6919faf commit a149534

File tree

12 files changed

+174
-33
lines changed

12 files changed

+174
-33
lines changed

examples/composition_layer_quad/game.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,19 @@ void Game::initVR()
7979

8080
// A quad positioned in the world (scene reference space)
8181
// auto quadLayer = vsgvr::CompositionLayerQuad::create(_vr->getInstance(), _vr->getTraits(), _vr->getSession()->getSpace(), 1920, 1080);
82-
// quadLayer->pose.position = { 0.0, 1.0, -4.0 };
82+
// quadLayer->setPose(
83+
// {0.0, 4.0, 1.0},
84+
// vsg::dquat(vsg::radians(25.0), {1.0, 0.0, 0.0})
85+
// );
8386

8487
// A quad positioned in front of the user's face
85-
auto faceLockedSpace = vsgvr::ReferenceSpace::create(_vr->getSession()->getSession(), XrReferenceSpaceType::XR_REFERENCE_SPACE_TYPE_VIEW);
86-
auto quadLayer = vsgvr::CompositionLayerQuad::create(_vr->getInstance(), _vr->getTraits(), faceLockedSpace, 1920, 1080);
87-
quadLayer->pose.position = { 0.0, 0.0, -4.0 };
88+
auto faceLockedSpace = vsgvr::ReferenceSpace::create(_vr->getSession()->getSession(), XrReferenceSpaceType::XR_REFERENCE_SPACE_TYPE_VIEW);
89+
90+
auto quadLayer = vsgvr::CompositionLayerQuad::create(_vr->getInstance(), _vr->getTraits(), faceLockedSpace, 1920, 1080);
91+
quadLayer->setPose(
92+
{0.0, 4.0, 0.0},
93+
{0.0, 0.0, 0.0, 1.0}
94+
);
8895

8996
/*auto rot = vsg::quat({0.0f, 5.0f, 2.5f}, {0.0f, 0.0f, 2.5f});
9097
quadLayer->pose.orientation = {

examples/composition_layer_quad/game.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
#include <vsgvr/actions/ActionPoseBinding.h>
99
#include <vsgvr/actions/SpaceBinding.h>
1010

11+
#include <vsgvr/app/CompositionLayerProjection.h>
12+
#include <vsgvr/app/CompositionLayerQuad.h>
13+
1114
#include "interaction.h"
1215

1316
#include <memory>

readme.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,22 @@ In addition the Vulkan runtime must satisfy the requirements of OpenXR. These re
5454

5555
As features are implemented vsgvr will use more extensions if available, to support common features such as additional composition layers. If specific extensions are not present, or not requested by the application these features will be inoperable.
5656

57+
### Coordinate Spaces
58+
59+
In OpenXR various coordinate spaces are available, and follow a Y-up convention: x-right, y-up, z-out (backwards from user's perspective).
60+
61+
While it may be modified, VulkanSceneGraph by default follows a Z-up convention: x-right, y-forward, z-up.
62+
63+
vsgvr exposes both of these in some way, but by default follows the vsg Z-up convention:
64+
* Any API exposing vsg::mat4, vsg::vec3, vsg::quat, etc - Z-up
65+
* Any API exposing OpenXR types such as XrPosef - Y-up
66+
67+
Most classes use OpenXR types internally, but expose both vsg and OpenXR types in their interfaces. Where possible the vsg types should be used within applications.
68+
69+
This results in a logical mapping to the scene graph for world-based coordinate spaces (STAGE, LOCAL, VIEW).
70+
71+
Action spaces are mapped using an `ActionPoseBinding`, which presents a vsg matrix for its transform - Any action related spaces are positioned within the OpenXR Session's space, which results in the transform being mapped to the overall 'world' space of the scenne graph automatically. Advanced users may query the action space directly and re-locate against a different XrSpace if desired.
72+
5773
## Setup
5874

5975
If you don't have a VR headset there's a couple of options.

vsgvr/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ set( HEADERS_XR
2525
include/vsgvr/xr/Swapchain.h
2626
include/vsgvr/xr/Traits.h
2727
include/vsgvr/xr/ViewMatrix.h
28+
include/vsgvr/xr/Pose.h
2829
)
2930

3031
set( SOURCES
@@ -46,6 +47,7 @@ set( SOURCES
4647
src/vsgvr/xr/Session.cpp
4748
src/vsgvr/xr/Swapchain.cpp
4849
src/vsgvr/xr/Traits.cpp
50+
src/vsgvr/xr/Pose.cpp
4951
)
5052

5153
if( ANDROID )

vsgvr/include/vsgvr/app/CompositionLayerQuad.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ namespace vsgvr {
3535
CompositionLayerQuad() = delete;
3636
CompositionLayerQuad(vsg::ref_ptr<vsgvr::Instance> instance, vsg::ref_ptr<vsgvr::Traits> xrTraits, vsg::ref_ptr<vsgvr::ReferenceSpace> referenceSpace);
3737
CompositionLayerQuad(vsg::ref_ptr<vsgvr::Instance> instance, vsg::ref_ptr<vsgvr::Traits> xrTraits, vsg::ref_ptr<vsgvr::ReferenceSpace> referenceSpace, uint32_t inWidthPixels, uint32_t inHeightPixels);
38+
CompositionLayerQuad(vsg::ref_ptr<vsgvr::Instance> instance, vsg::ref_ptr<vsgvr::Traits> xrTraits, vsg::ref_ptr<vsgvr::ReferenceSpace> referenceSpace, uint32_t inWidthPixels, uint32_t inHeightPixels, uint32_t inNumSamples, vsg::dvec3 position, vsg::dquat orientation, XrExtent2Df inSizeMeters, XrCompositionLayerFlags inFlags, XrEyeVisibility inEyeVisibility);
3839
CompositionLayerQuad(vsg::ref_ptr<vsgvr::Instance> instance, vsg::ref_ptr<vsgvr::Traits> xrTraits, vsg::ref_ptr<vsgvr::ReferenceSpace> referenceSpace, uint32_t inWidthPixels, uint32_t inHeightPixels, uint32_t inNumSamples, XrPosef inPose, XrExtent2Df inSizeMeters, XrCompositionLayerFlags inFlags, XrEyeVisibility inEyeVisibility);
3940
virtual ~CompositionLayerQuad();
4041
XrCompositionLayerBaseHeader* getCompositionLayerBaseHeaderPtr() override { return reinterpret_cast<XrCompositionLayerBaseHeader*>(&_compositionLayer); }
@@ -43,6 +44,8 @@ namespace vsgvr {
4344
std::vector<SwapchainImageRequirements> getSwapchainImageRequirements() override;
4445
void render(vsg::ref_ptr<vsgvr::Session> session, XrFrameState frameState, vsg::ref_ptr<vsg::FrameStamp> frameStamp) override;
4546

47+
void setPose(vsg::dvec3 position, vsg::dquat orientation);
48+
4649
/// Image properties for the rendered quad
4750
uint32_t widthPixels = 1920;
4851
uint32_t heightPixels = 1080;

vsgvr/include/vsgvr/xr/Pose.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
Copyright(c) 2022 Gareth Francis
3+
4+
Permission is hereby granted, free of charge, to any person obtaining a copy of
5+
this software and associated documentation files (the "Software"), to deal in
6+
the Software without restriction, including without limitation the rights to
7+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8+
the Software, and to permit persons to whom the Software is furnished to do so,
9+
subject to the following conditions:
10+
11+
The above copyright notice and this permission notice shall be included in all
12+
copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20+
*/
21+
22+
#pragma once
23+
24+
#include <vsgvr/xr/Common.h>
25+
#include <vsg/core/Inherit.h>
26+
27+
namespace vsgvr {
28+
class VSGVR_DECLSPEC Pose : public vsg::Inherit<vsg::Object, Pose>
29+
{
30+
public:
31+
Pose(XrPosef pose);
32+
Pose(vsg::dvec3 position, vsg::dquat orientation);
33+
Pose(vsg::vec3 position, vsg::quat orientation);
34+
virtual ~Pose();
35+
36+
void setPose(XrPosef pose);
37+
void setPose(vsg::dvec3 position, vsg::dquat orientation);
38+
void setPose(vsg::vec3 position, vsg::quat orientation);
39+
40+
XrPosef getPose() const { return _pose; }
41+
42+
// TODO
43+
// vsg::dmat4 getTransform() const;
44+
// vsg::dvec3 getPosition() const;
45+
// vsg::dquat getOrientation() const;
46+
private:
47+
XrPosef _pose;
48+
};
49+
}

vsgvr/include/vsgvr/xr/ReferenceSpace.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ namespace vsgvr {
3535
public:
3636
ReferenceSpace() = delete;
3737
ReferenceSpace(XrSession session, XrReferenceSpaceType referenceSpaceType);
38+
ReferenceSpace(XrSession session, XrReferenceSpaceType referenceSpaceType, vsg::dvec3 position, vsg::dquat orientation);
39+
3840
/// Note: XrPosef is in the OpenXR coordinate system - X-right, Y-up, Z-back
3941
ReferenceSpace(XrSession session, XrReferenceSpaceType referenceSpaceType, XrPosef poseInReferenceSpace);
4042
virtual ~ReferenceSpace();

vsgvr/src/vsgvr/actions/ActionPoseBinding.cpp

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -74,27 +74,16 @@ namespace vsgvr
7474
{
7575
_transformValid = true;
7676

77-
// In the same way as ViewMatrix, poses need some conversion for the VSG space
78-
// OpenXR space: x-right, y-up, z-back
79-
// VSG/Vulkan space: x-right, y-forward, z-up
80-
// * Invert y -> To flip the handedness (x-right, y-back, z-up)
81-
// * Rotate clockwise around x -> To move into vsg space (x-right, y-up, z-back)
82-
// After this, models are built for vsg space, and default concepts in the api map across
83-
//
84-
// TODO: Need to double check this, but here the action spaces needed to be un-rotated,
85-
// to compensate for the rotation in ViewMatrix. Not entirely sure why..
86-
auto worldRotateMat = vsg::rotate(vsg::PI / 2.0, 1.0, 0.0, 0.0);
87-
77+
vsg::dmat4 xrToVsg;
78+
vsg::transform(vsg::CoordinateConvention::Y_UP, vsg::CoordinateConvention::Z_UP, xrToVsg);
8879
auto q = vsg::dquat(
8980
location.pose.orientation.x,
9081
location.pose.orientation.y,
9182
location.pose.orientation.z,
9283
location.pose.orientation.w
9384
);
94-
auto rotateMat = vsg::rotate(q);
9585
auto p = vsg::dvec3(location.pose.position.x, location.pose.position.y, location.pose.position.z);
96-
auto translateMat = vsg::translate(p);
97-
auto transform = worldRotateMat * translateMat * rotateMat;
86+
auto transform = xrToVsg * vsg::translate(p) * vsg::rotate(q);
9887

9988
_transform = transform;
10089
}

vsgvr/src/vsgvr/actions/SpaceBinding.cpp

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,27 +48,16 @@ namespace vsgvr
4848
{
4949
_transformValid = true;
5050

51-
// In the same way as ViewMatrix, poses need some conversion for the VSG space
52-
// OpenXR space: x-right, y-up, z-back
53-
// VSG/Vulkan space: x-right, y-forward, z-up
54-
// * Invert y -> To flip the handedness (x-right, y-back, z-up)
55-
// * Rotate clockwise around x -> To move into vsg space (x-right, y-up, z-back)
56-
// After this, models are built for vsg space, and default concepts in the api map across
57-
//
58-
// TODO: Need to double check this, but here the action spaces needed to be un-rotated,
59-
// to compensate for the rotation in ViewMatrix. Not entirely sure why..
60-
auto worldRotateMat = vsg::rotate(vsg::PI / 2.0, 1.0, 0.0, 0.0);
61-
51+
vsg::dmat4 xrToVsg;
52+
vsg::transform(vsg::CoordinateConvention::Y_UP, vsg::CoordinateConvention::Z_UP, xrToVsg);
6253
auto q = vsg::dquat(
6354
location.pose.orientation.x,
6455
location.pose.orientation.y,
6556
location.pose.orientation.z,
6657
location.pose.orientation.w
6758
);
68-
auto rotateMat = vsg::rotate(q);
6959
auto p = vsg::dvec3(location.pose.position.x, location.pose.position.y, location.pose.position.z);
70-
auto translateMat = vsg::translate(p);
71-
auto transform = worldRotateMat * translateMat * rotateMat;
60+
auto transform = xrToVsg * vsg::translate(p) * vsg::rotate(q);
7261

7362
_transform = transform;
7463
}

vsgvr/src/vsgvr/app/CompositionLayerQuad.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2323

2424
#include <vsgvr/xr/Swapchain.h>
2525
#include <vsgvr/xr/Session.h>
26+
#include <vsgvr/xr/Pose.h>
2627

2728
#include <vsg/core/Exception.h>
2829
#include "../xr/Macros.cpp"
@@ -39,6 +40,17 @@ namespace vsgvr {
3940
, widthPixels(inWidthPixels)
4041
, heightPixels(inHeightPixels)
4142
{}
43+
CompositionLayerQuad::CompositionLayerQuad(vsg::ref_ptr<vsgvr::Instance> instance, vsg::ref_ptr<vsgvr::Traits> xrTraits, vsg::ref_ptr<vsgvr::ReferenceSpace> referenceSpace, uint32_t inWidthPixels, uint32_t inHeightPixels, uint32_t inNumSamples, vsg::dvec3 position, vsg::dquat orientation, XrExtent2Df inSizeMeters, XrCompositionLayerFlags inFlags, XrEyeVisibility inEyeVisibility)
44+
: Inherit(instance, xrTraits, referenceSpace)
45+
, widthPixels(inWidthPixels)
46+
, heightPixels(inHeightPixels)
47+
, numSamples(inNumSamples)
48+
, sizeMeters(inSizeMeters)
49+
, flags(inFlags)
50+
, eyeVisibility(inEyeVisibility)
51+
{
52+
setPose(position, orientation);
53+
}
4254
CompositionLayerQuad::CompositionLayerQuad(vsg::ref_ptr<vsgvr::Instance> instance, vsg::ref_ptr<vsgvr::Traits> xrTraits, vsg::ref_ptr<vsgvr::ReferenceSpace> referenceSpace, uint32_t inWidthPixels, uint32_t inHeightPixels, uint32_t inNumSamples, XrPosef inPose, XrExtent2Df inSizeMeters, XrCompositionLayerFlags inFlags, XrEyeVisibility inEyeVisibility)
4355
: Inherit(instance, xrTraits, referenceSpace)
4456
, widthPixels(inWidthPixels)
@@ -118,4 +130,9 @@ namespace vsgvr {
118130
};
119131
_compositionLayer.subImage.imageArrayIndex = 0;
120132
}
133+
134+
void CompositionLayerQuad::setPose(vsg::dvec3 position, vsg::dquat orientation)
135+
{
136+
pose = Pose(position, orientation).getPose();
137+
}
121138
}

0 commit comments

Comments
 (0)