c-frame / aframe-super-hands-component

👐All-in-one natural hand controller, pointer, and gaze interaction library for A-Frame
https://c-frame.github.io/aframe-super-hands-component/examples/
MIT License
354 stars 71 forks source link

progressive-controls doesn't work with GearVR #82

Closed vincentfretin closed 6 years ago

vincentfretin commented 6 years ago

Hi @wmurphyrd, do you have tested yourself on a GearVR or Daydream? With GearVR, the progressive-controls doesn't work at all for me.

I'm trying to use

        <a-entity id="cameraRig" progressive-controls="objects: .cube">
          <a-camera />
          <a-entity
            class="right-controller"
            teleport-controls="cameraRig: #cameraRig; button: trigger; maxLength: 200; type: line; collisionEntities: .environmentGround, .environmentDressing, .cube"
          />
        </a-entity>

I have my right hand with the GearVR controller, a ray is casting. I have a ray on the ground for the dead left hand. We only have one hand on GearVR/Daydream, so we should probably only configure one hand on point mode. Anyway the raycaster is not working, I hover on my cubes, it doesn't change state. I can't grab.

Now if I configure it manually like this:

        <a-entity id="cameraRig">
          <a-camera />
          <a-entity
            class="right-controller"
            teleport-controls="cameraRig: #cameraRig; button: trigger; maxLength: 200; type: line; collisionEntities: .environmentGround, .environmentDressing, .cube"
            laser-controls
            raycaster="objects: .cube"
            super-hands="colliderEvent: raycaster-intersection; colliderEventProperty: els; colliderEndEvent: raycaster-intersection-cleared; colliderEndEventProperty: clearedEls; colliderState:"
            static-body="shape: sphere; sphereRadius: 0.02"
          />
        </a-entity>

(Note, I'm already using aframe master with https://github.com/wmurphyrd/aframe-super-hands-component/pull/80 here) it works. When I have the right ray on the cube, the hover state is applied, I can grab.

I'll try to add some console.log in progressive-controls to know what's going on.

vincentfretin commented 6 years ago

With or without the teleport-controls component attached, it doesn't matter.

wmurphyrd commented 6 years ago

I don't have one to test myself, but I've received positive feedback on slack and elsewhere. Since #80 isn't passing CI, I'd start there for why it doesn't auto-config properly.

vincentfretin commented 6 years ago

I should actually started by that, the examples in this project doesn't work for me with GearVR at all. Maybe it worked at one point and now it doesn't? Well, don't waste your time on it, I'll figure it out now I have a better understand of the framework with my latest contributions.

vincentfretin commented 6 years ago

I confirm, "Progressive controls with physics" and "Gaze and laser pointer controls without physics" from https://wmurphyrd.github.io/aframe-super-hands-component/examples/ which currently uses aframe 0.7.0 doesn't work with GearVR. trigger and trackpad have no effect on the cubes.

vincentfretin commented 6 years ago

I put a console.log in

        const rayConfig = AFRAME.utils.styleParser.stringify(AFRAME.utils          
            .extend({objects: this.data.objects, showLine: true},               
            laserConfig.raycaster || {}));                                      
        console.log('rayConfig', rayConfig);

I got: rayConfig objects:.cube;showLine:true;origin:[object Object] Please not the [object Object] for origin here.

Now if I remove AFRAME.utils.styleParser.stringify, I get the raycaster working. In the console I get:

objects: ".cube"
origin: Object
  x: 0
  y: 0.0005
  z: 0
  __proto__: Object
showLine: true
useWorldCoordinates: false
__proto__: Object
vincentfretin commented 6 years ago

When I look at the laser-controls component, there is no AFRAME.utils.styleParser.stringify

vincentfretin commented 6 years ago

There is one other weird thing. Like I said, I'm testing with aframe master and #80 here. When I don't use progressive-controls but configure all manually, my ray is cut at the intersection point of the cube, with the latest fixes from aframe master, so great. Now with progressive-controls, the ray pass through the cube.

vincentfretin commented 6 years ago

Ok, I'm starting to have something working well, so with the correct ray cut at cube intersection and no left ray on the ground with the following code, were I use the laser-controls component explicitly (and not just the config you previously used in your code):

        <a-entity id="cameraRig" progressive-controls="objects: .cube">
          <a-entity
            class="right-controller"
            teleport-controls="cameraRig: #cameraRig; button: trigger; maxLength: 200; type: line; collisionEntities: .environmentGround, .environmentDressing, .cube"
            laser-controls
          />
        </a-entity>

and:

      case 1:                                                                   
        hands.forEach(h => {                                                    
          h.setAttribute('super-hands', this.superHandsRaycasterConfig);        
          h.setAttribute('raycaster', 'objects: ' + this.data.objects);         
          //h.setAttribute('laser-controls');                                   
          if (physicsAvail) {                                                   
            h.setAttribute('static-body', this.data.physicsBody);               
          }                                                                     
        });                                                                     
        break;                                                                  
      case 2:

laser-controls is taking care of showing and hiding the line. Now h.setAttribute('laser-controls'); doesn't currently work because the controllerconnected listener which call createRay is not called in the laser-controls component. This is normal because setLevel is called in the controllerconnected. I'll try now to modify the code to pass the evt from detectLevel to setLevel so I can call createRay(evt) from the laser-controls component.

vincentfretin commented 6 years ago

Ah no I can't call createRay, this is private.

vincentfretin commented 6 years ago

Ah it's simpler that that, with my previous change and replacing in init

      ['daydream-controls', 'gearvr-controls', 'oculus-touch-controls',
          'vive-controls', 'windows-motion-controls']
          .forEach(ctrlr => this[hand].setAttribute(ctrlr, 'hand: ' + hand));

by

this[hand].setAttribute('laser-controls', 'hand: ' + hand);

the code:

<a-entity id="cameraRig" progressive-controls="objects: .cube">
          <a-entity
            class="right-controller"
            teleport-controls="cameraRig: #cameraRig; button: trigger; maxLength: 200; type: line; collisionEntities: .environmentGround, .environmentDressing, .cube"
//            laser-controls
          />
        </a-entity>

works perfectly.

vincentfretin commented 6 years ago

Cool, patch is in PR #85 and tests are passing.

vincentfretin commented 6 years ago

Ah shoot, it will show a ray now for level 2 I guess. We can maybe just use this[h].removeAttribute('raycaster') there? (and maybe cursor, I don't know) I don't have access to a positional tracking device. Can you please test that?

wmurphyrd commented 6 years ago

Ahh, they've made significant changes to laser-controls since last I looked, so that's a big part of the problem when I was stealing some config options from its prototype.

Would you consider contributing a MoCap recording with your GearVR so I can properly test it in the machinima tests? Right now I'm just using a recording from a Vive controller in point mode, but a real GearVR recording would help catch changes like this.

vincentfretin commented 6 years ago

Sure, I can try, you mean with the https://github.com/dmarcos/aframe-motion-capture-components right? I didn't play with it yet. Dumb question, how do you press space to toggle the recording in GearVR? :) I will need to call startRecording() after the scene has loaded and add a setTimeout to call stopRecording() maybe? Is there a better way?

wmurphyrd commented 6 years ago

The readme on that repo is a bit out of date here's the procedure:

  1. In the super-hands project directory, run npm run record
  2. In the browser window that pops up add "progressive-laser.html" to he base url
  3. In that scene, open inspector with CTRL-ALT-I
  4. Open the motion capture ui by cliking the camera icon or pressing "m"
  5. Ensure the box for using controller is checked
  6. Press the red record icon
  7. Exit inspector
  8. Enter VR
  9. Press one controller button and watch the countdown timer
  10. Do stuff
  11. Rapidly press controller button 5 times to end recording
  12. Go back into inspector and find the download recording button

Except that still requires a keyboard to access the inspector, doesn't it? Would it work with Firefox remote debug?

vincentfretin commented 6 years ago

Thanks. I am debugging via wifi, so I have a chrome debugger on my machine to see the logs from the oculus browser on the phone. But I don't think I can type commands in the console, I'll verify. Worst case scenario, I create a small component that start and stop the record when I press the trigger button of the controller.