Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /**
  2. * @file MARTINS.js WebAR demo with three.js
  3. * @version 1.1.0
  4. * @author Alexandre Martins (https://github.com/alemart)
  5. * @license LGPL-3.0-or-later
  6. */
  7. window.addEventListener('load', () => {
  8. const my = { };
  9. async function initialize(ar)
  10. {
  11. // add lights
  12. const ambientLight = new THREE.AmbientLight(0xb7b7b7);
  13. const directionalLight = new THREE.DirectionalLight(0xffffff, 0.4);
  14. directionalLight.position.set(0, 0, -1);
  15. directionalLight.target.position.set(0, 0, 0);
  16. ar.scene.add(directionalLight);
  17. ar.scene.add(ambientLight);
  18. // create a group of objects as a child of ar.root
  19. const group = createGroup('in-front');
  20. //const group = createGroup('on-top'); // try this option!
  21. ar.root.add(group);
  22. // create cubes
  23. const cubeA = createCube(-0.75, 0, 0xffff00);
  24. const cubeB = createCube(0.75, 0, 0x00ff00);
  25. group.add(cubeA, cubeB);
  26. // create the ground
  27. const ground = createGround(0x3d5afe);
  28. group.add(ground);
  29. // load a 3D model
  30. const modelURL = '../assets/my-3d-model.glb';
  31. const model = await loadModel(modelURL);
  32. group.add(model);
  33. // export objects
  34. my.cubes = [ cubeA, cubeB ];
  35. my.group = group;
  36. my.model = model;
  37. my.ground = ground;
  38. }
  39. function animate(ar)
  40. {
  41. const ROTATION_CYCLES_PER_SECOND = 1.0;
  42. const TWO_PI = 2.0 * Math.PI;
  43. const delta = ar.session.time.delta;
  44. // rotate the cubes
  45. for(const cube of my.cubes)
  46. cube.rotateY(TWO_PI * ROTATION_CYCLES_PER_SECOND * delta);
  47. }
  48. function createGroup(mode = 'in-front')
  49. {
  50. const group = new THREE.Group();
  51. if(mode == 'in-front') {
  52. group.rotation.set(-Math.PI/2, 0, 0);
  53. group.position.set(0, -0.5, 0.5);
  54. }
  55. else if(mode == 'on-top') {
  56. group.rotation.set(0, 0, 0);
  57. group.position.set(0, 0, 0);
  58. }
  59. return group;
  60. }
  61. function createCube(x, y, color, length = 0.25)
  62. {
  63. const geometry = new THREE.BoxGeometry(length, length, length);
  64. const material = new THREE.MeshPhongMaterial({ color });
  65. const cube = new THREE.Mesh(geometry, material);
  66. cube.position.set(x, y, 1.25);
  67. return cube;
  68. }
  69. function createGround(color)
  70. {
  71. const geometry = new THREE.RingGeometry(0.001, 1, 8);
  72. const material = new THREE.MeshPhongMaterial({ color: color, side: THREE.DoubleSide });
  73. const ground = new THREE.Mesh(geometry, material);
  74. material.transparent = true;
  75. material.opacity = 0.75;
  76. return ground;
  77. }
  78. async function loadModel(filepath)
  79. {
  80. const loader = new THREE.GLTFLoader();
  81. const gltf = await loader.loadAsync(filepath);
  82. const model = gltf.scene;
  83. return model;
  84. }
  85. async function startARSession()
  86. {
  87. if(!Martins.isSupported()) {
  88. throw new Error(
  89. 'Use a browser/device compatible with WebGL2 and WebAssembly. ' +
  90. 'Your user agent is ' + navigator.userAgent
  91. );
  92. }
  93. //Martins.Settings.powerPreference = 'low-power';
  94. const tracker = Martins.Tracker.ImageTracker();
  95. await tracker.database.add([{
  96. name: 'my-reference-image',
  97. image: document.getElementById('my-reference-image')
  98. }]);
  99. const viewport = Martins.Viewport({
  100. container: document.getElementById('ar-viewport'),
  101. hudContainer: document.getElementById('ar-hud')
  102. });
  103. const video = document.getElementById('my-video');
  104. const useWebcam = (video === null);
  105. const source = useWebcam ?
  106. Martins.Source.Camera({ resolution: 'md' }) :
  107. Martins.Source.Video(video);
  108. const session = await Martins.startSession({
  109. mode: 'immersive',
  110. viewport: viewport,
  111. trackers: [ tracker ],
  112. sources: [ source ],
  113. stats: true,
  114. gizmos: true,
  115. });
  116. const scan = document.getElementById('scan');
  117. tracker.addEventListener('targetfound', event => {
  118. session.gizmos.visible = false;
  119. if(scan)
  120. scan.hidden = true;
  121. });
  122. tracker.addEventListener('targetlost', event => {
  123. session.gizmos.visible = true;
  124. if(scan)
  125. scan.hidden = false;
  126. });
  127. return session;
  128. }
  129. // link MARTINS.js to THREE.js
  130. linkMartinsToTHREE(startARSession, animate, initialize);
  131. });