-
-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Emit event when oculus or vive controllers are connected #2505
Conversation
@@ -150,6 +150,7 @@ module.exports.Component = registerComponent('oculus-touch-controls', { | |||
controller: 0, | |||
rotationOffset: data.rotationOffset !== -999 ? data.rotationOffset : isRightHand ? -90 : 90 | |||
}); | |||
el.emit('controller-connected', {type: 'oculus-touch-controller'}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no dashes controllerconnected
is the convention
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's move these events to tracked-controls
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
won't work as there is no context provided to distinguish which component injected the tracked-controls
. if that is provided to tracked-controls
when injected, then I agree e.g. by expanding schema with something like source
that is name of injecting component oculus-touch-controls
, vive-controls
, daydream-controller
(which maybe should have been -controls), gearvr-controls
and then providing source
in the controllerconnected
data
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we were to expand the tracked-controls
schema, would the data be available when componentinitialized
is fired for tracked-controls
? or is it only available in subsequent update
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can add the el
reference to the details of the event
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the case @fernandojsg has is same element with both oculus and vive components, need to know which injected; really the component reference, not the element
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is why I asked about moving the event to tracked-controls
. tracked-controls
will pass the Gamepad ID and el
as details of the event. @fernandojsg would that work for you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the idea was to avoid the ambiguity of having to know correspondence from gamepad.id
to controller component. Another approach is to listen for componentinitialized
or updated of tracked-controls
, and look at .controllerPresent
on the controller components -- but then not sure how to handle emulation (separate discussion)
(1) shouldn't this actually be done in the tracked-controls system that finds new controllers? |
+1 for using gamepad ID rather than a new string. And if a new string is needed, we should be consistent on |
if the general idea is to have the components re-emit their own version of |
I needed this feature to detect when a gamepad is connected and determine (without need to redo most of the work done already by the core components) if it's an oculus or a vive controller. |
@fernandojsg I see, so by |
Looks like there may be stale documentation If the name & id of the source/parent component doing the injection were available as part of as well as injected name/id/data, then this pattern would be generalizable to listening for and filtering |
Maybe no changes are required? |
@fernandojsg would the example that @machenmusik points out in the codepen work for you? |
the @machenmusik proposal probably could works in most of the cases but I feel we're adding some extra steps that are not really necessary: adding a new component |
066da71
to
225edad
Compare
I've updated my PR with the component code of @machenmusik included directly on the |
c14b13a
to
e71e9a6
Compare
src/components/tracked-controls.js
Outdated
const component = self.el.components[name]; | ||
if (component.controllerPresent) { | ||
// Emit controllerpresent event. | ||
self.el.emit('controllerpresent', {name: name, component: component}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with this is that if the controller is not there when the component is initialized you won't be notified
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this is the case when you include directly tracked-controls
instead of vive-controls
or oculus-controls
the specific controls inject tracked controls when the controllers is already available, but if you just inject tracked-controls
by yourself you won't get 100% of the cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A controller could become available after the component / application is initialized
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, so what do to? Going back to the original approach to inject it when the controller is being injected? https://github.com/aframevr/aframe/blob/master/src/components/vive-controls.js#L94
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
vive-controls
and oculus-touch-controls
listen to gamepadconnected
. I think everything should happen through tracked-controls
. oculus-touch-controls
and vive-controls
should set tracked-controls
on init and wait for an event when the controller becomes available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can then have trackedcontrollerconnected
\ trackedcontrollerdisconnected
. We can have a separate gamepad
component?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, tracked controller is really a controller with pose, so IMO we should stick with controllerconnected
and controllerdisconnected
(that would also fire for gamepads) -- oculus, vive, daydream can do their usual checking for ID prefix and pose (and maybe hand)... other (future) gamepad controls could attach to same event mechanism
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to @fernandojsg 's original question though... which component should actually fire controllerpresent
(which is when a higher-level component recognizes the actual presence of its controller, not just when a controller connected event is seen) -- the higher-level component after it injects (original PR), or by tracked-controls
as per the latest here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's the goal of sceneEl.systems['tracked-controls'].subscribeToController(el, data, callback);
you subscribe to the particular controller you're looking for so you don't have to manually check from a generic event
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so the a-blast use case is kinda like hand-controls
usage -- I think it's called shoot-controls
-- but it needs to specifically know which higher-level controller component (oculus-touch-controls
and vive-controls
) to adjust model pose, etc.
I don't follow how oculus-touch-controls
and vive-controls
doing the subscription helps shoot-controls
, and that subscription wouldn't help shoot-controls
since it only knows oculus-touch-controls
and vive-controls
, it doesn't know the details of how they recognize what controller/gamepad.
So where did we end up with this one after all? Looking at it again, I think @fernandojsg proposal would work, and if other third-party components obey the
True but if you inject
For |
Let's make |
I'm not sure how that actually helps the original use case @fernandojsg was trying to solve (need to know whether oculus-touch-controls or vive-controls is actually connected) -- the upper level enjoys the abstraction of not having to know the raw gamepad id strings, but only the higher-level component abstractions,.. |
I was trying to solve duplicated code and emitting the event in one sweep. There's an easy way to emit the higher level event by passing the component to |
my recollection is that some components need to do their own filtering using getGamepadsByPrefix |
thinking about problems separately, to solve "how do i know which component injected this tracked-controls" just add a string to schema that higher level components fill in with their name when injecting. then you can read it even if you missed the event. to fire an event when you see a new controller would ideally be gamepadconnected/disconnected from browser, but in practice i have not seen that work correctly so systems component would probably have to fire - perhaps on scene as we were discussing previously. but putting the two together is slightly trickier as for fernando's use case, you only want the event AFTER you can read which component injected. So maybe fire event from tracked-controls schema update on that property. |
My main concern with moving the logic from So to follow with the PR with @dmarcos proposal, we should move |
And so the |
c5aa5ce
to
dcd3fd7
Compare
I've refactored the code and moved all the inject and add/remove eventlistener to a new function in The test are still not passing, as in |
@fernandojsg if you look at the vive-tracker PR, you can see a change to the way tests are mocked -- just change the system controllers list to what you need it to look like |
8663956
to
a2bd1a6
Compare
@machenmusik thanks! I've used your implementation and it's working as expected 👍 |
src/components/gearvr-controls.js
Outdated
}, | ||
|
||
pause: function () { | ||
// Note that due to gamepadconnected event propagation issues, we don't rely on events. | ||
window.removeEventListener('gamepaddisconnected', this.checkIfControllerPresent, false); | ||
this.removeControllersUpdateListener(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you want to keep these calls in the pause
@@ -57,5 +57,13 @@ | |||
<a-entity light="type: ambient; color: #f4f4f4; intensity: 0.4;" position="-8 10 -18"></a-entity> | |||
</a-entity> | |||
</a-scene> | |||
<script> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can get rid of these logs
src/utils/tracked-controls.js
Outdated
} | ||
if (isPresent && queryObject.index) { | ||
isPresent = index === queryObject.index; // need to use count of gamepads with idPrefix | ||
if (gamepads) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can return early and save one level of indentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
452a359
to
b4a7bac
Compare
Thank you! That's x2 bonus points for a PR that removes more code than adds. |
I've a question, Do we need to call |
i believe that due to issues with gsmepadconnected/disconnected propagation, that is still needed to reliably detect controllers, but would be happy to be proven wrong |
b4a7bac
to
390efb5
Compare
@machenmusik ok thanks, I've just keep them by now to keep the consistency between all the controllers components, we could address that later if needed. @dmarcos fixed the issue with the |
390efb5
to
f62a860
Compare
Thanks! |
@machenmusik I used false as I saw that we're initializing |
disable everGotGamepadEvent usage, seeing issues with latest Nightly make sure vive-controls doesn't match tracker bring in line with latest aframevr#2513 work around Nightly bug to get both controllers and trackers working at the same time bring vive-tracker in line with aframevr#2513 fix tests per separate discussion, use controllers list from system not getGamepadsByPrefix bring in line with aframevr#2505 make sure that queryObject values are used even if falsy e.g. index 0 tracked-controls needs to know about hand to filter properly and find vive trackers, given current Nightly bug. since empty string is always changed to default value (even when default is undefined), need to use 'none' to indicate empty-string hand re-clone tracker tests from controls use newly committed vive-tracker model add rotation property, which applies if no rotationOffset and allows full 3DOF rotation correct pose orientation for tracker to be what is generally expected of controllers fix default vive-tracker rotation correction, per discussion updateControllerModel for all tracked controls components; use fixed vive tracker model until published to CDN use new tracker model from CDN add rotation parameter apply rotationOffset the old way, to avoid precision issues add rotation offset test, with EPSILON change sentinel hand value to avoid node test failure zero pivot point update tracked-controls hand docs per discussion on PR fix duplicate play/pause presumably from botched merge
disable everGotGamepadEvent usage, seeing issues with latest Nightly make sure vive-controls doesn't match tracker bring in line with latest aframevr#2513 work around Nightly bug to get both controllers and trackers working at the same time bring vive-tracker in line with aframevr#2513 fix tests per separate discussion, use controllers list from system not getGamepadsByPrefix bring in line with aframevr#2505 make sure that queryObject values are used even if falsy e.g. index 0 tracked-controls needs to know about hand to filter properly and find vive trackers, given current Nightly bug. since empty string is always changed to default value (even when default is undefined), need to use 'none' to indicate empty-string hand re-clone tracker tests from controls use newly committed vive-tracker model add rotation property, which applies if no rotationOffset and allows full 3DOF rotation correct pose orientation for tracker to be what is generally expected of controllers fix default vive-tracker rotation correction, per discussion updateControllerModel for all tracked controls components; use fixed vive tracker model until published to CDN use new tracker model from CDN add rotation parameter apply rotationOffset the old way, to avoid precision issues add rotation offset test, with EPSILON change sentinel hand value to avoid node test failure zero pivot point update tracked-controls hand docs per discussion on PR fix duplicate play/pause presumably from botched merge
I didn't include any extra information as it can be accessed directly by the target