Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Getting Started with WebVR Contents Creation for Oculus Quest

Getting Started with WebVR Contents Creation for Oculus Quest

Slide deck of tutorial seminar which is going to be held 23 June for WebVR contents creation for Oculus Quest.

357c9e58ecce2865f9eb748192e5143f?s=128

TakashiYoshinaga

June 21, 2019
Tweet

More Decks by TakashiYoshinaga

Other Decks in Technology

Transcript

  1. Getting Started with WebVR Contents Creation for Oculus Quest

  2. Please Download Sample Data http://arfukuoka.lolipop.jp/quest/Sample.zip

  3. 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.
  4. Experience Access to the official site of A-Frame (https://aframe.io/)

  5. Experience Sample demos are shown on the left column. サンプル

  6. Experience Let’s see the most primitive sample Hello WebVR. Hello

    WebVR
  7. Experience See around VR environment by mouse/key controll. Click inside

    the screen Rotation:drag & move a mouse Left/Right:[←][→] key Forward/Back:[↑][↓] key
  8. Another Example 360°Images also work with A-Frame easily. 360°Image RICOH

    Theta
  9. Of course you can play on Oculus Quest

  10. The Goal of This Tutorial https://youtu.be/J-AQpvOawJ0

  11. Let’s Experience on Oculus Quest! https://quest-demo.glitch.me

  12. 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
  13. Today’s Tutorial Step1: Learning basic usage of A-Frame Step2: Making

    the simple VR environment. Step3: Writing script to achieve interaction.
  14. Today’s Tutorial Step1: Learning basic usage of A-Frame Step2: Making

    the simple VR environment. Step3: Writing script to achieve interaction.
  15. Please log in your account of Glitch https://glitch.com/

  16. Getting Sample Code Click the link shown as GET STARTED

    GET STARTED
  17. Remixing the Sample Code Description of Hello WebVR Hello WebVR

  18. Remixing the Sample Code Click remix the starter example on

    Glitch Click
  19. Remixing the Sample Code Click “Remix your own” button shown

    on the right bottom of preview image. Click
  20. Click index.html to view the sample code. Click

  21. Explanation of the Sample Code <html> <head> <title>Hello, WebVR! -

    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>
  22. Explanation of the Sample Code <a-scene background="color: #ECECEC"> <a-box 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-scene>  Primitive objects are defined as a-xxx https://aframe.io/docs/0.9.0/primitives /a-box.html (ex. Detail of a-box)
  23. Run ①Show ②Next to The Code

  24. Run

  25. How to Modify Objects? You can change parameters of components.

    For example...  position: x y z are used to modify the position of a CG. (0 1.25 -5)
  26. 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) 原点
  27. <a-scene background="color: #FAFAFA "> <a-box 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-scene> Let’s Try to Edit Components #AAAAAA position="-1 0.5 -2" rotation="0 0 0" position="0 1.25 -4" radius="0.7" position="1 0.75 -2 height="0.7" position="0 0 0" width="10" height="10"
  28. Today’s Tutorial Step1: Learning basic usage of A-Frame Step2: Making

    the simple VR environment. Step3: Writing script to achieve interaction.
  29. Today’s Tutorial Step1: Learning basic usage of A-Frame Step2: Making

    the simple VR environment. Step3: Writing script to achieve interaction.
  30. Applying Texture Image

  31. Applying Texture Image ①assets ②Add Asset → Upload

  32. Applying Texture Image ①back.png ②Open

  33. Applying Texture Image Click

  34. Applying Texture Image ①Click ②Click out of the dialog

  35. Applying Texture Image index.html

  36. Applying Texture Image <a-scene background="color: #AAAAAA"> <a-box position="-1 0.5 -2"

    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
  37. Applying Texture Image <a-scene background="color: #AAAAAA"> <a-box position="-1 0.5 -2"

    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.
  38. Duplication of Textured Plane <a-scene background="color: #AAAAAA"> <a-box position="-1 0.5

    -2" 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-plane position="0 5 0" rotation="90 0 0" width="10" height="10" src=“URL" shadow></a-plane> </a-scene> Copy & Paste
  39. Duplication of Textured Plane <a-plane position="0 0 0" rotation="-90 0

    0" width="10" height="10" src="URL"></a-plane> <a-plane position="0 5 0" rotation="90 0 0" width="10" height="10" src="URL"></a-plane> <a-plane position="0 2.5 -5" rotation="0 0 0" width="10" height="5" src="URL"></a-plane> <a-plane position="0 2.5 5" rotation="0 180 0" width="10" height="5" src="URL"></a-plane> <a-plane position="5 2.5 0" rotation="0 -90 0" width="10" height="5" src="URL"></a-plane> <a-plane position="-5 2.5 0" rotation="0 90 0" width="10" height="5" src="URL"></a-plane> Make 4 walls with the same procedure.
  40. Modify URL of Your VR Content Click Text Modify a

    name
  41. Modify URL of Your VR Content https://XXXX-XXXX.glitch.me

  42. Test on Oculus Quest You will be immersed in the

    VR space you created.
  43. Adding Controller Entity <a-plane position="0 0 0" rotation="-90 0 0"

    width="10" height="10" src="URL" shadow> </a-plane> <a-plane position="0 5 0" rotation="90 0 0" width="10" height="10" src="URL" shadow> </a-plane> <a-plane position="0 2.5 -5" rotation="0 0 0" width="10" height="5" src="URL" shadow> </a-plane> <a-plane position="0 2.5 5" rotation="0 180 0" width="10" height="5" src="URL" shadow> </a-plane> <a-plane position="5 2.5 0" rotation="0 -90 0" width="10" height="5" src="URL" shadow> </a-plane> <a-plane position="-5 2.5 0" rotation="0 90 0" width="10" height="5" src="URL" shadow> </a-plane> <a-entity laser-controls="hand: left"> </a-entity> <a-entity laser-controls="hand: right"> </a-entity> <a-entity> enables us to define original entity instead pre-defined primitive entities.
  44. Before Test on Oculus Quest... Reload!

  45. Test on Oculus Quest Oculus Touch’s controller, not Quest’s, will

    appear.
  46. Today’s Tutorial Step1: Learning basic usage of A-Frame Step2: Making

    the simple VR environment. Step3: Writing script to achieve interaction.
  47. Today’s Tutorial Step1: Learning basic usage of A-Frame Step2: Making

    the simple VR environment. Step3: Writing script to achieve interaction.
  48. Definition of Input Behavior <a-plane position="0 2.5 -5" rotation="0 0

    0" width="10" height="10" src="URL"> </a-plane> <a-plane position="0 2.5 5" rotation="0 180 0" width="10" height="10" src="URL"> </a-plane> <a-plane position="5 2.5 0" rotation="0 -90 0" width="10" height="10" src="URL"> </a-plane> <a-plane position="-5 2.5 0" rotation="0 90 0" width="10" height="10" src="URL"> </a-plane> <a-entity laser-controls="hand: left" input-listen> </a-entity> <a-entity laser-controls="hand: right" input-listen> </a-entity> Add input-listen component to describe behavior when input of controller is received. From next page, source code of input-listen is explained.
  49. Definition of Input Behavior <script> AFRAME.registerComponent('input-listen', { init:function () {

    //Initialization } , tick: function () { //Update } }); </script> <a-scene background="color: #AAAAAA"> <a-box position="-1 0.5 -2" rotation="0 0 0" color="#4CC3D9" shadow></a-box> <!--source code is omitted in this document--> <a-entity laser-controls="hand: left" input-listen> </a-entity> <a-entity laser-controls="hand: right" input-listen> </a-entity> </a-scene> 1.txt
  50. 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
  51. Visualization of Input Info with Text <a-scene background="color: #AAAAAA"> <!--Source

    is omitted in this slide.--> <a-plane position="-5 2.5 0" rotation="0 90 0" width="10" height="5" src="URL" shadow></a-plane> <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-scene> 3.txt
  52. 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
  53. Before the Test on Oculus Quest Reload!!

  54. Test on Oculus Quest Each action of grip or a-button

    will appear.
  55. 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.
  56. Duplication of the Project Remix Project I recommend to preserve

    this code as the primitive project. Click the content name
  57. Modification of URL of the New Content Click the content

    name Replace the name as you like
  58. 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"); });
  59. Enabling Teleportation to the Content <html> <head> <meta charset="utf-8"> <title>Hello,

    WebVR! • A-Frame</title> <meta name="description" content="Hello, WebVR! • A-Frame"> <script src="https://aframe.io/releases/0.9.2/aframe.min.js"></script> <script src="https://rawgit.com/fernandojsg/aframe-teleport- controls/master/dist/aframe-teleport-controls.min.js"></script> </head> 5.txt
  60. Enabling Teleportation to the Content <a-scene background="color: #AAAAAA"> <!—Source code

    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.
  61. Enabling Teleportation to the Content <a-scene background="color: #AAAAAA"> <!--Source code

    is omitted in this slide.--> <a-entity id="cameraRig"> <a-entity id="head" 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 teleport-controls= "cameraRig: #cameraRig; teleportOrigin:#head; startEvents: teleportstart; endEvents: teleportend" laser-controls="hand: left" input-listen> </a-entity> <a-entity laser-controls="hand: right" input-listen> </a-entity> </a-entity> </a-scene> Next, teleportation function will be added to left-hand controller.
  62. Enabling Teleportation to the Content <a-scene background="color: #AAAAAA"> <!--中略--> <a-entity

    id="cameraRig"> <a-entity id="head" 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 teleport-controls= "cameraRig: #cameraRig; teleportOrigin:#head; startEvents: teleportstart; endEvents: teleportend" laser-controls="hand: left" input-listen> </a-entity> <a-entity laser-controls="hand: right" input-listen> </a-entity> </a-entity> </a-scene> Add teleport-controls component to left-hand controller. 6.txt
  63. Supplementation 1 <a-scene background="color: #AAAAAA"> <!--中略--> <a-entity id="cameraRig"> <a-entity id="head"

    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 teleport-controls= "cameraRig: #cameraRig; teleportOrigin:#head; startEvents: teleportstart; endEvents: teleportend" laser-controls="hand: left" input-listen> </a-entity> <a-entity laser-controls="hand: right" input-listen> </a-entity> </a-entity> </a-scene> It means to allow jumpping #CameraRig and its children from #head
  64. Supplementation 2 <a-scene background="color: #AAAAAA"> <!--Omitted--> <a-entity id="cameraRig"> <a-entity id="head"

    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 teleport-controls= "cameraRig: #cameraRig; teleportOrigin:#head; startEvents: teleportstart; endEvents: teleportend" laser-controls="hand: left" input-listen> </a-entity> <a-entity laser-controls="hand: right" input-listen> </a-entity> </a-entity> teleportstart is called to start pointing destination. teleportend is called to jump to pointed position.
  65. 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.*/ }
  66. Check the URL Before Starting Test Remember the project name

    https://XXX-XXX.glitch.me
  67. Test on Oculus Quest Teleportation will be available.

  68. Text Step: Manipulation raycaster Checking intersection intersect Gripdown Manipulate!

  69. Adding Raycaster Component <a-scene background="color: #AAAAAA"> <!--中略--> <a-entity id="cameraRig"> <a-entity

    id="head" 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 teleport-controls= "cameraRig: #cameraRig; teleportOrigin:#head; startEvents: teleportstart; endEvents: teleportend" laser-controls="hand: left" input-listen> </a-entity> <a-entity laser-controls="hand: right" input-listen> </a-entity> </a-entity> </a-scene> Find controllers
  70. Adding Raycaster Component <a-scene background="color: #AAAAAA"> <!--中略--> <a-entity id="cameraRig"> <a-entity

    id="head" 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 teleport-controls= "cameraRig: #cameraRig; teleportOrigin:#head; startEvents: teleportstart; endEvents: teleportend“ raycaster="objects: .collidable; far:1.2;" laser-controls="hand: left" input-listen> </a-entity> <a-entity laser-controls="hand: right" input-listen> </a-entity> Raycaster will interact with collidable entity.(see next page) It just works when distance between controller & object is in 1.2m
  71. Adding Raycaster Component <a-scene background="color: #AAAAAA"> <!--中略--> <a-entity id="cameraRig"> <a-entity

    id="head" 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 teleport-controls= "cameraRig: #cameraRig; teleportOrigin:#head; startEvents: teleportstart; endEvents: teleportend" raycaster="objects: .collidable; far:1.2;" laser-controls="hand: left" input-listen> </a-entity> <a-entity raycaster="objects: .collidable; far:1.2;" laser-controls="hand: right" input-listen> </a-entity> Raycaster will interact with collidable entity.(see next page) It just works when distance between controller & object is in 1.2m
  72. Setting Entities as Collidable Object <a-scene background="color: #AAAAAA"> <a-box class="collidable"

    position="-1 0.5 -2" rotation="0 0 0" color="#4CC3D9" shadow> </a-box> <a-sphere class="collidable" position="0 1.25 -4" radius="0.7" color="#EF2D5E" shadow> </a-sphere> <a-cylinder class="collidable" position="1 0.75 -2" radius="0.5" height="0.6" color="#FFC65D" shadow></a-cylinder> <a-plane position="0 0 0" rotation="-90 0 0" width="10" height="10" src="URL" shadow></a-plane> <!—Omitted in this slide --> </a-scene> Checking intersection with raycaster is ON Floor and walls are not checked intersection
  73. Condition of Manipulation (1/2) init:function () { const txt =

    document.getElementById("txt"); this.el.grip=false; this.el.addEventListener('xbuttondown', function (e) { this.emit('teleportstart'); }); this.el.addEventListener('xbuttonup', function (e) { this.emit('teleportend'); }); this.el.addEventListener('gripdown', function (e) { this.grip=true; }); this.el.addEventListener('gripup', function (e) { this.grip=false; }); } , Holding grip is pressed or not.
  74. 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
  75. 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. }
  76. 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
  77. Test on Oculus Quest 3D objects will become manipulatable

  78. Reference of raycaster https://github.com/aframevr/aframe/blob/master/docs/co mponents/raycaster.md You can read more detail

    of raycaster below.
  79. Next Step:Shooting Bullet(ball) Press Trigger

  80. Import Library of Physics <head> <meta charset="utf-8"> <title>Hello, WebVR! •

    A-Frame</title> <meta name="description" content="Hello, WebVR! • A-Frame"> <script src="https://aframe.io/releases/0.9.2/aframe.min.js"></script> <script src="https://rawgit.com/fernandojsg/aframe-teleport- controls/master/dist/aframe-teleport-controls.min.js"></script> <script src="//cdn.rawgit.com/donmccurdy/aframe-physics- system/v3.3.0/dist/aframe-physics-system.min.js"></script> </head> <body> <script> All script is omitted in this slide.</script> <a-scene background="color: #AAAAAA"> /*Omitted*/ </a-entity> </body> 9.txt physics="gravity: 0; restitution: 0.9;"
  81. 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) { }); }
  82. 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
  83. Test on Oculus Quest Ball will appear on the hand

    position but not be shot yet.
  84. 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
  85. 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
  86. Test on Oculus Quest Balls are shot but through the

    wall.
  87. Enabling Collision Detection <a-scene physics="debug: false; gravity: 0; restitution: 0.9;

    " background="color: #AAAAAA"> <a-box static-body class="collidable" --omitted-- ></a-box> <a-sphere static-body class="collidable" --omitted-- ></a-sphere> <a-cylinder static-body class="collidable" --omitted-- ></a-cylinder> <a-plane static-body position="0 0 0" --omitted-- ></a-plane> <a-plane static-body position="0 5 0" --omitted-- ></a-plane> <a-plane static-body position="0 2.5 -5" --omitted-- ></a-plane> <a-plane static-body position="0 2.5 5" --omitted-- ></a-plane> <a-plane static-body position="5 2.5 0" --omitted-- ></a-plane> <a-plane static-body position= "-5 2.5 0" --omitted-- ></a-plane> <a-entity id="cameraRig">--omitted--</a-entity> box, sphere, cylinder, planeにstatic-bodyを追加
  88. 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
  89. Completed!

  90. None