index.html 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. <html lang="en">
  2. <head>
  3. <meta charset="UTF-8">
  4. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  5. <title>3D Tiles Loader: RealityCapture</title>
  6. <style>
  7. * {
  8. margin: 0;
  9. padding: 0;
  10. }
  11. body {
  12. width: 100vw;
  13. height: 100vh;
  14. overflow: hidden;
  15. }
  16. #canvas-parent {
  17. width: 100vw;
  18. height: 100vh;
  19. touch-action: none;
  20. }
  21. #guide {
  22. position: fixed;
  23. top: 0;
  24. right: 0;
  25. width: 300px;
  26. padding: 1rem 2rem;
  27. font-family:'Courier New', Courier, monospace;
  28. line-height: 1.2;
  29. background-color: white;
  30. color: black;
  31. }
  32. #guide p {
  33. margin-top: 10px;
  34. }
  35. #stats-widget {
  36. position: absolute;
  37. top: 70px;
  38. left: 10px;
  39. background-color: rgb(255 255 255 / 83%);
  40. padding: 10px;
  41. width: 300px;
  42. word-break: break-all;
  43. visibility: hidden;
  44. }
  45. #button {
  46. position: fixed;
  47. bottom: 16px;
  48. right: 16px;
  49. padding: 12px;
  50. border-radius: 50%;
  51. margin-bottom: 0px;
  52. background-color: #FFF;
  53. opacity: .9;
  54. z-index: 999;
  55. box-shadow: 0 0 4px rgb(0 0 0 / 15%);
  56. }
  57. @media (max-width:480px) {
  58. #guide, #stats-widget { display: none; }
  59. }
  60. </style>
  61. </head>
  62. <body>
  63. <div id='canvas-parent'></div>
  64. <div id="stats-widget"></div>
  65. <div id="guide">
  66. <span id="example-desc">
  67. <b>Freeman Alley, New York.</b> Captured using iPhone 12 Pro Max and processed via RealityCapture.
  68. </span>
  69. <p>Use arrow/WASD keys or mouse wheel/trackpad to move around, and click and drag to turn/rotate the camera.</p>
  70. <p>
  71. <u>Available URL parameters:</u>
  72. <ul>
  73. <li><b>tilesetUrl</b>: Load another tileset json.</li>
  74. <li><b>sse</b>: Change the maximum screen space error.</li>
  75. </ul>
  76. </p>
  77. </div>
  78. <script src="../../resource/js/vconsole.min.js"></script>
  79. <script>
  80. // VConsole 默认会挂载到 `window.VConsole` 上
  81. var vConsole = new window.VConsole();
  82. </script>
  83. <!-- <script async src="https://ga.jspm.io/npm:es-module-shims@1.4.4/dist/es-module-shims.js"></script> -->
  84. <script async src="../../resource/js/es-module-shims.js"></script>
  85. <script type="importmap">
  86. {
  87. "imports": {
  88. "three": "../../resource/js/three.js",
  89. "three/examples/jsm/loaders/GLTFLoader.js": "../../resource/js/GLTFLoader.js",
  90. "three/examples/jsm/loaders/DRACOLoader.js": "../../resource/js/DRACOLoader.js",
  91. "three/examples/jsm/loaders/KTX2Loader.js": "../../resource/js/KTX2Loader.js",
  92. "three/examples/jsm/libs/stats.module.js": "../../resource/js/stats.module.js",
  93. "three/examples/jsm/controls/OrbitControls": "../../resource/js/OrbitControls.js",
  94. "@probe.gl/stats" : "../../resource/js/stats.js",
  95. "@probe.gl/stats-widget" : "../../resource/js/stats-widget.js",
  96. "three-loader-3dtiles" : "../../../dist/three-loader-3dtiles.esm.js",
  97. "gsap": "../../resource/js/gsap.js",
  98. "three-story-controls" : "../../resource/js/three-story-controls.js"
  99. }
  100. }
  101. </script>
  102. <script type='module'>
  103. import {
  104. Scene,
  105. PerspectiveCamera,
  106. WebGLRenderer,
  107. Clock,
  108. Matrix4,
  109. Euler,
  110. sRGBEncoding,
  111. Math as ThreeMath
  112. } from 'three';
  113. import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
  114. import { Loader3DTiles } from 'three-loader-3dtiles';
  115. import { CameraRig, FreeMovementControls } from 'three-story-controls'
  116. import Stats from 'three/examples/jsm/libs/stats.module.js';
  117. import StatsWidget from '@probe.gl/stats-widget';
  118. const queryParams = new URLSearchParams(document.location.search);
  119. const canvasParent = document.querySelector('#canvas-parent');
  120. const statsParent = document.querySelector('#stats-widget')
  121. const scene = new Scene();
  122. const camera = new PerspectiveCamera(
  123. 35,
  124. 1,
  125. 0.01,
  126. 1000,
  127. );
  128. const renderer = new WebGLRenderer();
  129. renderer.outputEncoding = sRGBEncoding;
  130. const clock = new Clock()
  131. const rig = new CameraRig(camera, scene)
  132. let controls = undefined;
  133. if (queryParams.get('orbit')) {
  134. controls = new OrbitControls( camera, canvasParent);
  135. controls.listenToKeyEvents( document.body );
  136. camera.position.set(0,200,0);
  137. controls.update();
  138. } else {
  139. controls = new FreeMovementControls(rig, {
  140. panDegreeFactor: 2,
  141. wheelScaleFactor: 0.01,
  142. keyboardScaleFactor: 0.015,
  143. keyboardDampFactor: 0
  144. });
  145. controls.enable();
  146. }
  147. canvasParent.appendChild(renderer.domElement);
  148. const threeJsStats = new Stats();
  149. threeJsStats.domElement.style.position = 'absolute';
  150. threeJsStats.domElement.style.top = '10px';
  151. threeJsStats.domElement.style.left = '10px';
  152. canvasParent.appendChild( threeJsStats.domElement );
  153. let tilesRuntime = undefined;
  154. let statsRuntime = undefined;
  155. if (queryParams.get('tilesetUrl')) {
  156. document.querySelector('#example-desc').style.display = 'none';
  157. }
  158. loadTileset();
  159. async function loadTileset() {
  160. const result = await Loader3DTiles.load(
  161. {
  162. url:
  163. queryParams.get('tilesetUrl') ??
  164. //'https://int.nyt.com/data/3dscenes/ONA360/TILESET/0731_FREEMAN_ALLEY_10M_A_36x8K__10K-PN_50P_DB/tileset_tileset.json',
  165. 'https://testgis.4dage.com/LVBADUI_qp/tileset.json',
  166. renderer: renderer,
  167. options: {
  168. dracoDecoderPath: 'https://cdn.jsdelivr.net/npm/three@0.137.0/examples/js/libs/draco',
  169. basisTranscoderPath: 'https://cdn.jsdelivr.net/npm/three@0.137.0/examples/js/libs/basis',
  170. maximumScreenSpaceError: queryParams.get('sse') ?? 48,
  171. }
  172. }
  173. );
  174. const {model, runtime} = result;
  175. model.rotation.set(-Math.PI / 2, 0, Math.PI / 2);
  176. if (!queryParams.get('tilesetUrl')) {
  177. model.position.set(-1, 4, -16);
  178. }
  179. tilesRuntime = runtime;
  180. scene.add(model);
  181. statsRuntime = new StatsWidget(runtime.getStats(), {container: statsParent });
  182. statsParent.style.visibility = 'visible';
  183. }
  184. function render(t) {
  185. const dt = clock.getDelta()
  186. controls.update(t);
  187. if (tilesRuntime) {
  188. tilesRuntime.update(dt, renderer, camera);
  189. }
  190. if (statsRuntime) {
  191. statsRuntime.update();
  192. }
  193. renderer.render(scene, camera);
  194. threeJsStats.update();
  195. window.requestAnimationFrame(render);
  196. }
  197. onWindowResize();
  198. function onWindowResize() {
  199. renderer.setSize(canvasParent.clientWidth, canvasParent.clientHeight);
  200. camera.aspect = canvasParent.clientWidth / canvasParent.clientHeight;
  201. camera.updateProjectionMatrix();
  202. }
  203. window.addEventListener('resize', onWindowResize)
  204. render();
  205. </script>
  206. <a id="button" target="_blank" href="https://github.com/nytimes/three-loader-3dtiles/blob/master/examples/demos/realitycapture/index.html" title="View source code for demo" style=""><img src="../ic_code_black_24dp.svg"></a>
  207. </body>
  208. </html>