Reticulum
Reticulum copied to clipboard
A simple gaze interaction manager for VR in the browser with Three.js.
#Reticulum
A simple gaze interaction manager for VR with Three.js. See examples
##Purpose Reticulum attempts to follow Google's interactive pattern for the display reticle. It creates the illusion of depth by projecting spatially onto targeted objects while maintaining a fixed size so that it is easy to see at all times.
Features:
- Avoids double vision and depth issues by projecting spatially onto targeted objects
- Gaze and click events for targeted objects
onGazeOver
,onGazeOut
,onGazeLong
andonGazeClick
- Set different fuze durations for targeted objects
- Built in fuse support
- Display the reticle only when the camera can see a targeted object
- Works in the browser with Three.js (r73)
1. Getting Started
Load Three.js and include the Reticulum.js file. You might also want to use the Web VR boilerplate:
<script src="three.js"></script>
<script src="reticulum.js"></script>
2. Initiate and set options
Call the Reticulum initializer function and set your options. Options can be set globally or per targeted object.
Note: You must define the camera
... it is required.
Reticulum.init(camera, {
proximity: false,
clickevents: true,
near: null, //near factor of the raycaster (shouldn't be negative and should be smaller than the far property)
far: null, //far factor of the raycaster (shouldn't be negative and should be larger than the near property)
reticle: {
visible: true,
restPoint: 1000, //Defines the reticle's resting point when no object has been targeted
color: 0xcc0000,
innerRadius: 0.0001,
outerRadius: 0.003,
hover: {
color: 0xcc0000,
innerRadius: 0.02,
outerRadius: 0.024,
speed: 5,
vibrate: 50 //Set to 0 or [] to disable
}
},
fuse: {
visible: true,
duration: 2.5,
color: 0x00fff6,
innerRadius: 0.045,
outerRadius: 0.06,
vibrate: 100, //Set to 0 or [] to disable
clickCancelFuse: false //If users clicks on targeted object fuse is canceled
}
});
3. Define targeted objects and options
Add the three.js objects you want to be targeted objects. Override global options by setting local ones.
Reticulum.add( object, {
clickCancelFuse: true, // Overrides global setting for fuse's clickCancelFuse
reticleHoverColor: 0x00fff6, // Overrides global reticle hover color
fuseVisible: true, // Overrides global fuse visibility
fuseDuration: 1.5, // Overrides global fuse duration
fuseColor: 0xcc0000, // Overrides global fuse color
onGazeOver: function(){
// do something when user targets object
this.material.emissive.setHex( 0xffcc00 );
},
onGazeOut: function(){
// do something when user moves reticle off targeted object
this.material.emissive.setHex( 0xcc0000 );
},
onGazeLong: function(){
// do something user targetes object for specific time
this.material.emissive.setHex( 0x0000cc );
},
onGazeClick: function(){
// have the object react when user clicks / taps on targeted object
this.material.emissive.setHex( 0x0000cc );
}
});
You can also remove targeted objects.
Reticulum.remove( object );
4. Add to animation loop
Add Reticulum to your animation loop
Reticulum.update()
5. Add Camera to scene
If you require to display the reticle you will need to add the camera
to the scene
.
Note: See Known Issues below if ghosting occurs.
scene.add(camera);
Demos
- Basic
- Proximity - only display reticle if targeted object is visible
- Depth Test - hit moving targets
- Objects in Groups - hit object in group, get world values
- Fuse - selective objects have fuse
- Visibility - test for hitting only visible objects
- Gazeable - test for hitting only gazeable objects
Known Issues
- Ghosting occurs to the reticle and fuse when in VR mode. More details on the issue can found here. A quick workaround to this issue is adding
camera.updateMatrixWorld();
before the render call (e.g.manager.render(scene, camera, timestamp);
to the callback function of therequestAnimationFrame()
method.
Acknowledgements:
Reticulum was inspired by the work done by neuman
License
The MIT License (MIT)