What’s A-Frame JS library to create VR apps which work on web browser. 3D objects can be placed by writing HTML tags. VR apps work on web browser. (ex. Chrome, Firefox) Also available on WinMR, HTC Vive and Oculus Quest.
Experience See around VR environment by mouse/key controll. Click inside the screen Rotation:drag & move a mouse Left/Right:[←][→] key Forward/Back:[↑][↓] key
You can See Also... Primitive sample of getting input from controllers https://github.com/TakashiYoshinaga/Oculus- Quest-Input-Sample Source code of the goal of today’s tutorial. https://github.com/TakashiYoshinaga/Oculus- Quest-Interaction-Sample
How to Modify Objects? Examples of components position:x y z are used to modify the position. rotation:x y z means rotation of each axis. color:color code are used to define the color. There are some parameters for each primitive object. X Z Y (0 1.25 -5) 【Others】 radius width height depth src (image file) 原点
color="#FFC65D"> width="10" height="10" src="URL" shadow> Paste the URL Add src Change the a-sphere’s material to src instead color. Paste the URL of the texture image on the right side of src.
Definition of Input Behavior init:function () { //Initialization //Called when x button begin to be pressed (for Left Hand) this.el.addEventListener('xbuttondown', function (e) { /*Do something*/ }); //Called when x button is released (for Left Hand) this.el.addEventListener('xbuttonup', function (e) { }); //Called when grip button begin to be pressed (for Both Hand) this.el.addEventListener('gripdown', function (e) { }); //Called when grip button released. (for Both Hand) this.el.addEventListener('gripup', function (e) { }); } , 2.txt
Visualization of Input Info with Text const txt = document.getElementById("txt"); //Called when x button begin to be pressed (for Left Hand) this.el.addEventListener('xbuttondown', function (e) { txt.setAttribute("value", "x pressed"); }); //Called when x button is released (for Left Hand) this.el.addEventListener('xbuttonup', function (e) { txt.setAttribute("value", "x released"); }); //Called when grip button begin to be pressed (for Both Hand) this.el.addEventListener('gripdown', function (e) { txt.setAttribute("value", "grip pressed"); }); //Called when grip button released. (for Both Hand) this.el.addEventListener('gripup', function (e) { txt.setAttribute("value", "grip released"); }); 4.txt
Reference https://aframe.io/docs/0.9.0/components/oculus-touch-controls.html ①Oculus-touch-controls ②Events Info of events are explained in the official reference in detail.
Delete Lines of Visualization of Input const txt = document.getElementById("txt"); //Called when x button begin to be pressed (for Left Hand) this.el.addEventListener('xbuttondown', function (e) { txt.setAttribute("value", "x pressed"); }); //Called when x button is released (for Left Hand) this.el.addEventListener('xbuttonup', function (e) { txt.setAttribute("value", "x released"); }); //Called when grip button begin to be pressed (for Both Hand) this.el.addEventListener('gripdown', function (e) { txt.setAttribute("value", "grip pressed"); }); //Called when grip button released. (for Both Hand) this.el.addEventListener('gripup', function (e) { txt.setAttribute("value", "grip released"); });
Enabling Teleportation to the Content init:function () { const txt = document.getElementById("txt"); ////Called when x button begin to be pressed this.el.addEventListener('xbuttondown', function (e) { //Start to point destination this.emit('teleportstart'); }); // //Called when x button is released this.el.addEventListener('xbuttonup', function (e) { //Jump to pointed position. this.emit('teleportend'); }); /*Following code is omitted in this slide.*/ }
"cameraRig: #cameraRig; teleportOrigin:#head; startEvents: teleportstart; endEvents: teleportend“ raycaster="objects: .collidable; far:1.2;" laser-controls="hand: left" input-listen> laser-controls="hand: right" input-listen> Raycaster will interact with collidable entity.(see next page) It just works when distance between controller & object is in 1.2m
"cameraRig: #cameraRig; teleportOrigin:#head; startEvents: teleportstart; endEvents: teleportend" raycaster="objects: .collidable; far:1.2;" laser-controls="hand: left" input-listen> laser-controls="hand: right" input-listen> Raycaster will interact with collidable entity.(see next page) It just works when distance between controller & object is in 1.2m
Condition of Manipulation (2/2) init:function () { /*Source code is omitted in this slide.*/ this.el.addEventListener('gripup', function (e) { this.grip=false; }); //called when raycaster intersected with something this.el.addEventListener('raycaster-intersection', function (e) { //Holding 1st object of detected entity as selected object. this.selectedObj = e.detail.els[0]; }); //called when raycaster intersection is cleared. this.el.addEventListener('raycaster-intersection-cleared', function (e) { //Reset selected object. this.selectedObj = null; }); } , Checking raycaster is intersected with CG or not 7.txt
Manipulation init:function () { /* Omitted in this slide */ this.el.addEventListener('raycaster-intersection', function (e) { this.selectedObj = event.detail.els[0]; }); this.el.addEventListener('raycaster-intersection-cleared', function (e) { this.selectedObj = null; }); }, //Update tick: function () { if (!this.el.selectedObj) { return; } if (!this.el.grip) { return; } //Make selected object to follow the tip of raycaster when //raycaster intersected object and grip is pressed. }
Manipulation //update tick: function () { if (!this.el.selectedObj) { return; } if (this.el.grip == false) { return; } //Getting direction of raycaster attached on this controller. var ray = this.el.getAttribute("raycaster").direction; //Calculate 1.2m forward position relative to controller var p = new THREE.Vector3(ray.x, ray.y, ray.z); p.normalize(); p.multiplyScalar(1.2); //Convert local position to world position. this.el.object3D.localToWorld(p); //put the selected object on the tip of the raycaster this.el.selectedObj.object3D.position.set(p.x, p.y, p.z); } 8.txt
Adding Event of Trigger Down init:function () { /*Source code is omitted in this slide.*/ //Raycaster intersected with something. this.el.addEventListener('raycaster-intersection', function (e) { this.selectedObj = event.detail.els[0]; }); //Raycaster intersection is finished. this.el.addEventListener('raycaster-intersection-cleared', function (e) { this.selectedObj = null; }); //Calles when the trigger button begin to be pressed. this.el.addEventListener('triggerdown', function (e) { }); }
Instantiation of Ball this.el.addEventListener('triggerdown', function (e) { //Getting the current position of the controller. var point = this.object3D.getWorldPosition(); //Instantiation of ball entity. var ball = document.createElement('a-sphere'); ball.setAttribute('class', 'ball'); ball.setAttribute('scale', '0.2 0.2 0.2'); ball.setAttribute('position', point); //Adding dynamic-body and its property to enable physics. ball.setAttribute('dynamic-body', 'shape: sphere; sphereRadius:0.2; '); //Generate ball entity in a-scene var scene = document.querySelector('a-scene'); scene.appendChild(ball); }); 10.txt
Calculation of Shooting Vector this.el.addEventListener('triggerdown', function (e) { /*Source code is omitted in this slide.*/ //Generating ball entity in a-scene var scene = document.querySelector('a-scene'); scene.appendChild(ball); //Getting direction of raycaster component of the controller. var dir = this.getAttribute("raycaster").direction; //Setting direction and magnitude of shoot vector. var force = new THREE.Vector3(); force.set(dir.x, dir.y, dir.z); force.multiplyScalar(2000); //Declare and set force vecter. ball.force = this.object3D.localToWorld(force); }); 11.txt
Shooting Bullet this.el.addEventListener('triggerdown', function (e) { /*Source code is omitted in this slide.*/ ball.force = this.object3D.localToWorld(force); //Shoot after finishing to load physics on ball ball.addEventListener('body-loaded', function (e) { //Getting position of ball var p = this.object3D.position; //Add force var f = this.force; this.body.applyForce( new CANNON.Vec3(f.x, f.y, f.z), new CANNON.Vec3(p.x, p.y, p.z) ); }); }); 12.txt
Remove Balls by Pressing A-Button init:function () { /*Source code is omitted in this slide.*/ //called when trigger button is started to be pressed this.el.addEventListener('triggerdown', function (e) { /*Source code is omitted in this slide.*/ }); //Called when pressing a-button is began. this.el.addEventListener('abuttondown', function (e) { //Obtain all entity of being ball class var els = document.querySelectorAll('.ball'); //Remove each balls from a-scene. for (var i = 0; i < els.length; i++) { els[i].parentNode.removeChild(els[i]); } }); } , 13.txt