您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

demo.js 4.6KB

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