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.
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
A-Frame</title> <meta name="description" content="Hello, WebVR! - A-Frame"> <script src="https://aframe.io/releases/0.9.2/aframe.min.js"> </script> </head> <body> <a-scene background="color: #FAFAFA"> Description of 3D contents are written here. </a-scene> </body> </html> A-Frame library is imported between <head></head> Description of 3D objects are written between<a-scene></a-scene>
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) 原点
rotation="0 0 0" color="#4CC3D9"> </a-box> <a-sphere position="0 1.25 -4" radius="0.7" color="#EF2D5E"> </a-sphere> <a-cylinder position="1 0.75 -2" radius="0.5" height="0.7" color="#FFC65D"></a-cylinder> <a-plane position="0 0 0" rotation="-90 0 0" width="10" height="10" color="#7BC8A4" shadow></a-plane> </a-scene> Replace the a-sphere’s material to src instead color. To be continued to the next page... Delete color
rotation="0 0 0" color="#4CC3D9"> </a-box> <a-sphere position="0 1.25 -4" radius="0.7" color="#EF2D5E"> </a-sphere> <a-cylinder position="1 0.75 -2" radius="0.5" height="0.7" color="#FFC65D"></a-cylinder> <a-plane position="0 0 0" rotation="-90 0 0" width="10" height="10" src="URL" shadow></a-plane> </a-scene> 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.
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
//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
//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"); });
is omitted in this slide.--> <a-entity id="cameraRig"> <a-entity camera position="0 1.6 0"> <a-text id="txt" value=" " position="0 0 -1" scale="0.5 0.5 0.5" align="center" color="#FFFFFF"> </a-text> </a-entity> <a-entity laser-controls="hand: left" input-listen> </a-entity> <a-entity laser-controls="hand: right" input-listen> </a-entity> </a-entity> </a-scene> <a-entity id="head" camera position="0 1.6 0"> Append camera and controller as children of <a-entity id="cameraRig"> </a-entity> to get them to be allowed jumping together to th destination.
= 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.*/ }
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
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. }
} 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
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) { }); }
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
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
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
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