Skip to content

Commit

Permalink
feat: path and callbacks
Browse files Browse the repository at this point in the history
fix: improve types
fixed race when disconnected comes first on steam vr
  • Loading branch information
saitonakamura committed Jan 11, 2023
1 parent c0211c9 commit d748d6e
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 45 deletions.
62 changes: 31 additions & 31 deletions src/libs/MotionControllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,18 @@ interface GamepadIndices {
yAxis?: number
}

type ComponentState = 'default' | 'touched' | 'pressed'

type ComponentProperty = 'button' | 'xAxis' | 'yAxis' | 'state'

type ValueNodeProperty = 'transform' | 'visibility'

type ComponentType = 'trigger' | 'squeeze' | 'touchpad' | 'thumbstick' | 'button'

interface VisualResponseDescription {
componentProperty: string
states: string[]
valueNodeProperty: string
componentProperty: ComponentProperty
states: ComponentState[]
valueNodeProperty: ValueNodeProperty
valueNodeName: string
minNodeName?: string
maxNodeName?: string
Expand All @@ -22,7 +30,7 @@ interface VisualResponseDescription {
type VisualResponses = Record<string, VisualResponseDescription>

interface ComponentDescription {
type: string
type: ComponentType
gamepadIndices: GamepadIndices
rootNodeName: string
visualResponses: VisualResponses
Expand Down Expand Up @@ -58,28 +66,28 @@ const MotionControllerConstants = {
NONE: 'none',
LEFT: 'left',
RIGHT: 'right',
}),
} as const),

ComponentState: Object.freeze({
DEFAULT: 'default',
TOUCHED: 'touched',
PRESSED: 'pressed',
}),
} as const),

ComponentProperty: Object.freeze({
BUTTON: 'button',
X_AXIS: 'xAxis',
Y_AXIS: 'yAxis',
STATE: 'state',
}),
} as const),

ComponentType: Object.freeze({
TRIGGER: 'trigger',
SQUEEZE: 'squeeze',
TOUCHPAD: 'touchpad',
THUMBSTICK: 'thumbstick',
BUTTON: 'button',
}),
} as const),

ButtonTouchThreshold: 0.05,

Expand All @@ -88,7 +96,7 @@ const MotionControllerConstants = {
VisualResponseProperty: Object.freeze({
TRANSFORM: 'transform',
VISIBILITY: 'visibility',
}),
} as const),
}

/**
Expand Down Expand Up @@ -184,8 +192,15 @@ async function fetchProfile(
return { profile, assetPath }
}

interface ComponentValues {
button: number | undefined
state: ComponentState
xAxis: number | undefined
yAxis: number | undefined
}

/** @constant {Object} */
const defaultComponentValues = {
const defaultComponentValues: ComponentValues = {
xAxis: 0,
yAxis: 0,
button: 0,
Expand Down Expand Up @@ -235,10 +250,10 @@ function normalizeAxes(
*/
class VisualResponse implements VisualResponseDescription {
value: number | boolean
componentProperty: string
states: string[]
componentProperty: ComponentProperty
states: ComponentState[]
valueNodeName: string
valueNodeProperty: string
valueNodeProperty: ValueNodeProperty
minNodeName?: string
maxNodeName?: string
valueNode: Object3D | undefined
Expand Down Expand Up @@ -268,17 +283,7 @@ class VisualResponse implements VisualResponseDescription {
* @param {number | undefined} button - The reported value of the component's button
* @param {string} state - The component's active state
*/
updateFromComponent({
xAxis,
yAxis,
button,
state,
}: {
xAxis?: number
yAxis?: number
button?: number
state: string
}): void {
updateFromComponent({ xAxis, yAxis, button, state }: ComponentValues): void {
const { normalizedXAxis, normalizedYAxis } = normalizeAxes(xAxis, yAxis)
switch (this.componentProperty) {
case MotionControllerConstants.ComponentProperty.X_AXIS:
Expand All @@ -305,14 +310,9 @@ class VisualResponse implements VisualResponseDescription {

class Component implements ComponentDescription {
id: string
values: {
state: string
button: number | undefined
xAxis: number | undefined
yAxis: number | undefined
}
values: ComponentValues

type: string
type: ComponentType
gamepadIndices: GamepadIndices
rootNodeName: string
visualResponses: Record<string, VisualResponse>
Expand Down
2 changes: 2 additions & 0 deletions src/webxr/OculusHandModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class OculusHandModel extends Object3D {
this.xrInputSource = null

controller.addEventListener('connected', (event) => {
console.log('OculusHandModel connected')
const xrInputSource = event.data

if (xrInputSource.hand && !this.motionController) {
Expand All @@ -45,6 +46,7 @@ class OculusHandModel extends Object3D {
})

controller.addEventListener('disconnected', () => {
console.log('OculusHandModel disconnected')
this.dispose()
})
}
Expand Down
39 changes: 25 additions & 14 deletions src/webxr/XRControllerModelFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,9 @@ class XRControllerModelFactory {
gltfLoader: GLTFLoader
path: string
private _assetCache: Record<string, { scene: Object3D } | undefined>
constructor(gltfLoader: GLTFLoader = null) {
constructor(gltfLoader: GLTFLoader = null, path = DEFAULT_PROFILES_PATH) {
this.gltfLoader = gltfLoader
this.path = DEFAULT_PROFILES_PATH
this.path = path
this._assetCache = {}

// If a GLTFLoader wasn't supplied to the constructor create a new one.
Expand All @@ -169,6 +169,17 @@ class XRControllerModelFactory {
const controllerModel = new XRControllerModel()
let scene: Object3D | null = null

const onDisconnected = (): void => {
controllerModel.motionController = null
controller.dispatchEvent({
type: 'motionControllerDestroyed',
})
if (scene) {
controllerModel.remove(scene)
}
scene = null
}

const onConnected = (event: any): void => {
const xrInputSource = event.data

Expand All @@ -179,8 +190,11 @@ class XRControllerModelFactory {
if (!assetPath) {
throw new Error('no asset path')
}

controllerModel.motionController = new MotionController(xrInputSource, profile, assetPath)
controller.dispatchEvent({
type: 'motionControllerCreated',
data: controllerModel.motionController,
})

const assetUrl = controllerModel.motionController.assetUrl

Expand All @@ -189,6 +203,10 @@ class XRControllerModelFactory {
scene = cachedAsset.scene.clone()

addAssetSceneToControllerModel(controllerModel, scene)
controller.dispatchEvent({
type: 'motionControllerLinkedToScene',
data: controllerModel.motionController,
})
} else {
if (!this.gltfLoader) {
throw new Error('GLTFLoader not set.')
Expand All @@ -208,6 +226,10 @@ class XRControllerModelFactory {
scene = asset.scene.clone()

addAssetSceneToControllerModel(controllerModel, scene)
controller.dispatchEvent({
type: 'motionControllerLinkedToScene',
data: controllerModel.motionController,
})
},
null,
() => {
Expand All @@ -222,17 +244,6 @@ class XRControllerModelFactory {
}

controller.addEventListener('connected', onConnected)

const onDisconnected = (): void => {
controller.removeEventListener('connected', onConnected)
controller.removeEventListener('disconnected', onDisconnected)
controllerModel.motionController = null
if (scene) {
controllerModel.remove(scene)
}
scene = null
}

controller.addEventListener('disconnected', onDisconnected)

return controllerModel
Expand Down

0 comments on commit d748d6e

Please sign in to comment.