What will I have?
I'll easily toggle the mouse events from the mouse cursor when not in VR mode to gaze cursors in VR mode. See also pseudo code below:
Example 1
scene.addEventListener('enter-vr', function() {
// use gaze cursors to toggle mouse events
});
scene.addEventListener('exit-vr', function() {
// use mouse cursor to toggle mouse events
});
Why?
By research I've seen by people that uses VR for the first time, preferences the mouse cursors. Entering VR mode, this cursor isn't available and by further research, the gaze cursor is the best option. With controllers from the HTC, Oculus, GearVR and Daydream aren't users not conversant to use it.
Conclusion:
- Inside VR mode: the gaze cursors is the best option.
- Outside VR mode: the mouse cursors is the best option.
What I've made
Research
I've found inside the documentation to change the camera:
When the active property gets toggled, the component will notify the camera system to change the current camera used by the renderer:
var secondCameraEl = document.querySelector('#second-camera'); secondCameraEl.setAttribute('camera', 'active', true);
My code
Here is my code I've made
Example 2
var scene = document.getElementById('scene');
scene.addEventListener('enter-vr', function() {
var secondCameraEl = document.querySelector('#vr-camera');
secondCameraEl.setAttribute('camera', 'active', true);
});
scene.addEventListener('exit-vr', function() {
var fistCameraEl = document.querySelector('#pc-camera');
fistCameraEl.setAttribute('camera', 'active', true);
});
var box = document.getElementById('box');
box.addEventListener('click', function() {
alert('click');
});
<script src="https://aframe.io/releases/0.5.0/aframe.min.js"></script>
<a-scene id="scene">
<a-box id="box" class="clickable" position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
<a-sky color="#ECECEC"></a-sky>
<a-entity id="camera">
<a-camera id="vr-camera">
<a-entity position="0 0 -1" geometry="primitive: ring; radiusOuter: 0.07;radiusInner: 0.05;" material="color: red; shader: flat" cursor="maxDistance: 1; fuse: true" raycaster="objects: .clickable">
<a-animation begin="click" easing="ease-in" attribute="scale" fill="backwards" from="0.1 0.1 0.1" to="1 1 1" dur="150"></a-animation>
<a-animation begin="fusing" easing="ease-in" attribute="scale" fill="forwards" from="1 1 1" to="0.1 0.1 0.1" dur="1500"></a-animation>
</a-entity>
</a-camera>
<a-camera id="pc-camera" active="true"></a-camera>
</a-entity>
</a-scene>
Click on cardboard icon to enter VR, pers Escape to exit VR.
Problems and working things
So you can see there are several errors inside my code:
- The fist camera that's active is
#vr-camera
. This must be#pc-camera
- When you exit VR, the
#pc-camera
doesn't trigger mouse events from the mouse pointer. - The cursor of
#vr-camera
stays visible when going outside VR mode. - See point 7.
This is working:
- Change the camera back to
#pc-camera
when exit VR. - Gaze cursor of the
#vr-camera
.
Question
Is it possible to switch the cursors (gaze ↔ mouse) dependent if you're in VR mode or not?
Update
Take @Piotr answer using just one camera and change the property fuse
to true
when enter VR and change to false
when exit VR. From his anwser I've made code below.
Example 3
var scene = document.getElementById('scene');
var camera = document.querySelector('#camera')[0];
scene.addEventListener('enter-vr', function() {
camera.setAttribute('cursor', 'maxDistance: 1; fuse: true');
});
scene.addEventListener('exit-vr', function() {
camera.setAttribute('cursor', 'maxDistance: 1; fuse: false');
});
var box = document.getElementById('box');
box.addEventListener('click', function() {
alert('click');
});
<script src="https://aframe.io/releases/0.5.0/aframe.min.js"></script>
<a-scene id="scene">
<a-box id="box" class="clickable" position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
<a-sky color="#ECECEC"></a-sky>
<a-camera id="camera">
<a-entity position="0 0 -1" geometry="primitive: ring; radiusOuter: 0.07;radiusInner: 0.05;" material="color: red; shader: flat" cursor="maxDistance: 1; fuse: false" raycaster="objects: .clickable">
<a-animation begin="click" easing="ease-in" attribute="scale" fill="backwards" from="0.1 0.1 0.1" to="1 1 1" dur="150"></a-animation>
<a-animation begin="fusing" easing="ease-in" attribute="scale" fill="forwards" from="1 1 1" to="0.1 0.1 0.1" dur="1500"></a-animation>
</a-entity>
</a-camera>
</a-scene>
The bug are here:
- When the cursor is standing on the yellow cilinder, the click event of the blue cube doesn't trigger. You must set the cursor to the blue cube to trigger the click event (happens also by the second example).
- Continuing on 7, when you replace the cursor and place it back the click event is triggered directly.
- On VR mode there is no
fuseTimeout
by default it must be 1500 milliseconds.