Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New xr actions #657

Draft
wants to merge 33 commits into
base: development
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
fa06090
Saving the work
galibzon Jan 5, 2024
abafb99
Saving the work
galibzon Jan 6, 2024
2b9150e
Saving the work
galibzon Jan 11, 2024
cdad2d4
Saving the work.
galibzon Jan 12, 2024
c20959f
Saving the work
galibzon Jan 13, 2024
20244e6
Saving the work.
galibzon Jan 16, 2024
c94f992
saving the work.
galibzon Jan 17, 2024
2c5c9ba
Saving the work.
galibzon Jan 18, 2024
bd55fb6
Saving the work.
galibzon Jan 18, 2024
bbde231
Saving the work.
galibzon Jan 19, 2024
d4f248e
Saving the work.
galibzon Jan 19, 2024
5174e42
Saving the work.
galibzon Jan 19, 2024
2482a97
Saving the work
galibzon Jan 20, 2024
442f7c1
Saving the work
galibzon Jan 22, 2024
54a8430
Saving the work
galibzon Jan 23, 2024
f7ed8d5
Saving the work.
galibzon Jan 24, 2024
0ca01ba
All the fundamentals are working.
galibzon Jan 26, 2024
dcfda4e
file renaming to OpenXRVk...
galibzon Jan 26, 2024
1faabeb
Working with action sets, and actions with Lua works fine.
galibzon Jan 27, 2024
aee1bc2
Haptics working from Lua
galibzon Jan 28, 2024
ae485ef
VisualizedSpace to ReferenceSpace
galibzon Jan 28, 2024
1fe0382
almost done with ActionSets Asset validation
galibzon Jan 28, 2024
e30cf21
Saving thw work.
galibzon Jan 29, 2024
668e8ef
Saving the work. 99% done with asset validation.
galibzon Jan 29, 2024
847209b
Saving the work
galibzon Jan 29, 2024
fc103fb
Added more comments.
galibzon Jan 30, 2024
79bb67d
Saving the work.
galibzon Jan 31, 2024
811ba64
Saving the work.
galibzon Jan 31, 2024
ceb797c
Saving the work.
galibzon Feb 1, 2024
3f275d0
Saving the work
galibzon Feb 1, 2024
e04ea36
Saving the work.
galibzon Feb 1, 2024
852b9d0
Saving the work.
galibzon Feb 1, 2024
d637392
Saving the work
galibzon Feb 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions Gems/OpenXRVk/Assets/OpenXRVk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# About system.xrprofiles and default.xractions

Both of these assets are editable via the `Asset Editor` UI. The `Asset Editor` is a tool provided by the O3DE Editor.

`system.xrprofiles` defines a list of standard OpenXR interaction profiles that have been tested with O3DE.
For more information read the header file: `.../Gems/OpenXRVk/Code/Include/OpenXRVk/OpenXRVkInteractionProfilesAsset.h`.

`default.xraction` depends on `system.xrprofiles` and it defines a set of actions that your application can use
to read user input or drive haptic feedback signals. This is the default asset that the OpenXRVk Gem will load, but can be overriden with help of the following Registry Key:
**"/O3DE/Atom/OpenXR/ActionSetsAsset"**. If this key is not defined, the application will default to: **"openxrvk/default.xractions"**.

Here is an example of an application named `AdventureVR` that customizes the Action Sets asset:
- ActionSet Asset Location: \<AdventureVR\>/Assets/AdventureVR/adventurevr.xractions
- Registry File Location: \<AdventureVR\>/Registry/adventurevr.setreg, with the following content:
```json
{
"O3DE": {
"Atom": {
"OpenXR": {
"ActionSetsAsset": "adventurevr/adventurevr.xractions"
}
}
}
}
```
182 changes: 182 additions & 0 deletions Gems/OpenXRVk/Assets/OpenXRVk/Scripts/xr_camera_move.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
-- Basic camera movement that uses the default OpenXR ActionSets asset
-- that ships with the OpenXRVk Gem.
-- This script can be used as an alternative to XrCameraMovementComponent.
local xr_camera_move = {
Properties = {
cameraEntity = {default = EntityId(),
description = "The entity with a camera component"},
cameraSpeed = { default = 1.0,
suffix= "ms-1",
description="Camera speed."},
rotationStepSize = {
default = 30.0,
suffix = "deg",
description = "Rotation step size in degrees around Up(Z) Axis. Each time the user moves the right hand thumbstick to the left or to the right the camera will Yaw rotate by this amount of degrees."
}
}
}

local function DumpActionHandle(name, actionHandle)
if actionHandle:IsValid() then
Debug.Log("Action [" ..name .. "] has index=[" .. actionHandle:GetIndex().. "]")
else
Debug.Log("Action [" ..name .. "] is invalid")
end
end

local function GetActionHandle(actionSetName, actionName)
local actionHandle = OpenXRActions.GetActionHandle(actionSetName, actionName)
DumpActionHandle(actionName, actionHandle)
assert(actionHandle:IsValid(), "Failed to get action handle [" .. actionName .. "] from action set[" .. actionSetName .. "]")
return actionHandle
end

local function FilterDeadZone(value, deadzoneMagnitude)
deadzoneMagnitude = deadzoneMagnitude or 0.05
if math.abs(value) < deadzoneMagnitude then
return 0.0
end
return value
end

function xr_camera_move:OnActivate()
assert(EntityId.IsValid(self.Properties.cameraEntity), "xr_camera_move:OnActivate. Invalid camera entity.")

-- Cache all action handles
local actionSetName = "main_action_set"
self._moveFrontwaysHandle = GetActionHandle(actionSetName, "move_frontways")
self._moveSidewaysHandle = GetActionHandle(actionSetName, "move_sideways")
self._yawRotateHandle = GetActionHandle(actionSetName, "shift_yaw_rotate")
self._moveUpHandle = GetActionHandle(actionSetName, "move_up")
self._moveDownHandle = GetActionHandle(actionSetName, "move_down")
self._aClickHandle = GetActionHandle(actionSetName, "a_button_click")
self._bClickHandle = GetActionHandle(actionSetName, "b_button_click")

self._cameraMovementStates = Vector3(0.0, 0.0, 0.0)
self._cameraYawRotationState = 0.0
self._AbsRange = 0.9
self.tickBusHandler = TickBus.Connect(self);

end

function xr_camera_move:OnDeactivate()
if self.tickBusHandler ~= nil then
self.tickBusHandler:Disconnect()
end
end

function xr_camera_move:_DumpPoses(deltaTime, timePoint)
local outcome = OpenXRReferenceSpaces.GetReferenceSpacePose(self._mySpaceName, "Local")
if outcome:IsSuccess() then
local tm = outcome:GetValue()
Debug.Log("Current transform for <" .. self._mySpaceName .. "> == " .. tostring(tm))
end

local headTm = OpenXRReferenceSpaces.GetViewSpacePose()
Debug.Log("View space pose=\n" .. tostring(headTm))

local eyeCount = OpenXRReferenceSpaces.GetViewCount()
Debug.Log("Eye count=\n" .. tostring(eyeCount))
for idx=1, eyeCount do
local eyeTm = OpenXRReferenceSpaces.GetViewPose(idx - 1)
Debug.Log("Eye[" .. tostring(idx) .. "] transform=\n" .. tostring(eyeTm))
end

local viewPoses = OpenXRReferenceSpaces.GetViewPoses()
local size = viewPoses:Size()
Debug.Log("Got the following list with " .. tostring(size) .. " eye poses")
for idx=1, size do
local eyeTm = viewPoses:At(idx)
Debug.Log("Eye pose[" .. tostring(idx) .. "] transform=\n" .. tostring(eyeTm))
end
end

function xr_camera_move:_ReadActionStates(deltaTime, timePoint)
self._cameraMovementStates = Vector3(0.0, 0.0, 0.0)

local outcome = OpenXRActions.GetActionStateFloat(self._moveFrontwaysHandle)
if outcome:IsSuccess() then
self._cameraMovementStates.y = FilterDeadZone(outcome:GetValue())
end

outcome = OpenXRActions.GetActionStateFloat(self._moveSidewaysHandle)
if outcome:IsSuccess() then
self._cameraMovementStates.x = FilterDeadZone(outcome:GetValue())
end

outcome = OpenXRActions.GetActionStateBoolean(self._moveUpHandle)
if outcome:IsSuccess() then
if outcome:GetValue() then
self._cameraMovementStates.z = 1.0
end
end

outcome = OpenXRActions.GetActionStateBoolean(self._moveDownHandle)
if outcome:IsSuccess() then
if outcome:GetValue() then
self._cameraMovementStates.z = -1.0
end
end

-- Smooth rotation around the Up (Z) axis, also known as Yaw rotation,
-- is prone to motion sickness for most users.
-- So we'll do a rather snappy rotation changes in angular increments.
outcome = OpenXRActions.GetActionStateFloat(self._yawRotateHandle)
if not outcome:IsSuccess() then
return
end
local newYawState = FilterDeadZone(outcome:GetValue())
if newYawState >= self._AbsRange then
if not self._canRotate then
self._canRotate = true
self._cameraYawRotationState = -1.0
end
elseif newYawState <= -self._AbsRange then
if not self._canRotate then
self._canRotate = true
self._cameraYawRotationState = 1.0
end
else
self._canRotate = false
end

end

function xr_camera_move:_MoveCamera(deltaTime, timePoint)
local distance = self.Properties.cameraSpeed * deltaTime
local cameraTm = TransformBus.Event.GetWorldTM(self.Properties.cameraEntity)
local upVector = cameraTm:GetBasisZ()
local forwardVector = cameraTm:GetBasisY()
local camVx = cameraTm:GetBasisX() * self._cameraMovementStates.x * distance
local camVy = forwardVector * self._cameraMovementStates.y * distance
local camVz = upVector * self._cameraMovementStates.z * distance
local camDeltaTranslation = camVx + camVy + camVz

if self._cameraYawRotationState == 0.0 then
TransformBus.Event.SetWorldTranslation(self.Properties.cameraEntity, cameraTm:GetTranslation() + camDeltaTranslation)
return
end

-- change the camera orientation
local angleRads = math.rad(self.Properties.rotationStepSize) * self._cameraYawRotationState
local rotQuat = Quaternion.CreateFromAxisAngle(upVector, angleRads)
local newForward = rotQuat * forwardVector
newForward:Normalize()
local newBasisX = newForward:Cross(upVector)
newBasisX:Normalize()

local newLocation = cameraTm:GetTranslation() + camDeltaTranslation
local mat33 = Matrix3x3.CreateFromColumns(newBasisX, newForward, upVector)
local newTm = Transform.CreateFromMatrix3x3AndTranslation(mat33, newLocation)

TransformBus.Event.SetWorldTM(self.Properties.cameraEntity, newTm)
self._cameraYawRotationState = 0.0
end

function xr_camera_move:OnTick(deltaTime, timePoint)
-- self:_DumpPoses(deltaTime, timePoint)
self:_ReadActionStates(deltaTime, timePoint)
self:_MoveCamera(deltaTime, timePoint)
end

return xr_camera_move
85 changes: 85 additions & 0 deletions Gems/OpenXRVk/Assets/OpenXRVk/Scripts/xr_spaces_api_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
-- this LUA script shows how to use the OpenXRReferenceSpaces API.
-- It creates a custom reference space called 'MySpace', and prints
-- its pose, along with the pose of the `View` Reference Space pose,
-- and each Eye pose during OnTick().
local xr_spaces_api_test = {
Properties = {
}
}

function xr_spaces_api_test:OnActivate()
local spaces = OpenXRReferenceSpaces.GetReferenceSpaceNames()
local size = spaces:Size()
Debug.Log("xr_spaces_api_test:OnActivate Got the following list with " .. tostring(size) .. " spaces")
for idx=1, size do
local name = spaces:At(idx)
Debug.Log("space[" .. tostring(idx) .. "]=" .. name)
end

local newSpaceName = "MySpace"
local tm = Transform.CreateTranslation(Vector3(0.0, 1.0, 0.0))
local outcome = OpenXRReferenceSpaces.AddReferenceSpace(OpenXRReferenceSpaces.ReferenceSpaceIdView, newSpaceName, tm)
if outcome:IsSuccess() then
Debug.Log("Sucessfully created space named " .. newSpaceName)
self._mySpaceName = newSpaceName
self.tickBusHandler = TickBus.Connect(self);
else
Debug.Log("Failed to create space named " .. newSpaceName .. ". Reason: " .. outcome:GetError())
end

local baseSpaceForViewSpaceName = OpenXRReferenceSpaces.GetBaseSpaceForViewSpacePose()
Debug.Log("FYI: [" .. OpenXRReferenceSpaces.ReferenceSpaceNameView .. "] space will be located with base space [" .. baseSpaceForViewSpaceName .. "]")

local leftEyeIndex = OpenXRReferenceSpaces.LeftEyeViewId
local rightEyeIndex = OpenXRReferenceSpaces.RightEyeViewId
Debug.Log("FYI: LeftEyeIndex=[" .. tostring(leftEyeIndex) .. "], RightEyeIndex=[" .. tostring(rightEyeIndex) .. "]")

end

function xr_spaces_api_test:OnDeactivate()
if self._mySpaceName ~= nil then
local outcome = OpenXRReferenceSpaces.RemoveReferenceSpace(self._mySpaceName)
if outcome:IsSuccess() then
Debug.Log("Sucessfully removed space named " .. self._mySpaceName)
else
Debug.Log("Failed to remove space named " .. self._mySpaceName .. ". Reason: " .. outcome:GetError())
end
self._mySpaceName = nil
end

if self.tickBusHandler ~= nil then
self.tickBusHandler:Disconnect()
end
end

function xr_spaces_api_test:_DumpPoses(deltaTime, timePoint)
local outcome = OpenXRReferenceSpaces.GetReferenceSpacePose(self._mySpaceName, "Local")
if outcome:IsSuccess() then
local tm = outcome:GetValue()
Debug.Log("Current transform for <" .. self._mySpaceName .. "> == " .. tostring(tm))
end

local headTm = OpenXRReferenceSpaces.GetViewSpacePose()
Debug.Log("View space pose=\n" .. tostring(headTm))

local eyeCount = OpenXRReferenceSpaces.GetViewCount()
Debug.Log("Eye count=\n" .. tostring(eyeCount))
for idx=1, eyeCount do
local eyeTm = OpenXRReferenceSpaces.GetViewPose(idx - 1)
Debug.Log("Eye[" .. tostring(idx) .. "] transform=\n" .. tostring(eyeTm))
end

local viewPoses = OpenXRReferenceSpaces.GetViewPoses()
local size = viewPoses:Size()
Debug.Log("Got the following list with " .. tostring(size) .. " eye poses")
for idx=1, size do
local eyeTm = viewPoses:At(idx)
Debug.Log("Eye pose[" .. tostring(idx) .. "] transform=\n" .. tostring(eyeTm))
end
end

function xr_spaces_api_test:OnTick(deltaTime, timePoint)
self:_DumpPoses(deltaTime, timePoint)
end

return xr_spaces_api_test
Loading