tremble 2 tahun lalu
melakukan
4bf57317fe
100 mengubah file dengan 421956 tambahan dan 0 penghapusan
  1. 3 0
      .browserslistrc
  2. 18 0
      .eslintrc.js
  3. 23 0
      .gitignore
  4. 201 0
      LICENSE
  5. 24 0
      README.md
  6. 5 0
      babel.config.js
  7. 27838 0
      package-lock.json
  8. 28 0
      package.json
  9. TEMPAT SAMPAH
      public/audio/10ce.mp3
  10. TEMPAT SAMPAH
      public/audio/10ce1.mp3
  11. TEMPAT SAMPAH
      public/audio/10zheng.mp3
  12. TEMPAT SAMPAH
      public/audio/1ce.mp3
  13. TEMPAT SAMPAH
      public/audio/1ce1.mp3
  14. TEMPAT SAMPAH
      public/audio/1zheng.mp3
  15. TEMPAT SAMPAH
      public/audio/2ce.mp3
  16. TEMPAT SAMPAH
      public/audio/2ce1.mp3
  17. TEMPAT SAMPAH
      public/audio/2zheng.mp3
  18. TEMPAT SAMPAH
      public/audio/3ce.mp3
  19. TEMPAT SAMPAH
      public/audio/3ce1.mp3
  20. TEMPAT SAMPAH
      public/audio/3zheng.mp3
  21. TEMPAT SAMPAH
      public/audio/4ce.mp3
  22. TEMPAT SAMPAH
      public/audio/4ce1.mp3
  23. TEMPAT SAMPAH
      public/audio/4zheng.mp3
  24. TEMPAT SAMPAH
      public/audio/5ce.mp3
  25. TEMPAT SAMPAH
      public/audio/5ce1.mp3
  26. TEMPAT SAMPAH
      public/audio/5zheng.mp3
  27. TEMPAT SAMPAH
      public/audio/6ce.mp3
  28. TEMPAT SAMPAH
      public/audio/6ce1.mp3
  29. TEMPAT SAMPAH
      public/audio/6zheng.mp3
  30. TEMPAT SAMPAH
      public/audio/7ce.mp3
  31. TEMPAT SAMPAH
      public/audio/7ce1.mp3
  32. TEMPAT SAMPAH
      public/audio/7zheng.mp3
  33. TEMPAT SAMPAH
      public/audio/8ce.mp3
  34. TEMPAT SAMPAH
      public/audio/8ce1.mp3
  35. TEMPAT SAMPAH
      public/audio/8zheng.mp3
  36. TEMPAT SAMPAH
      public/audio/9ce.mp3
  37. TEMPAT SAMPAH
      public/audio/9ce1.mp3
  38. TEMPAT SAMPAH
      public/audio/9zheng.mp3
  39. 7 0
      public/css/animate.min.css
  40. TEMPAT SAMPAH
      public/images/temp.jpg
  41. TEMPAT SAMPAH
      public/images/video.png
  42. 27 0
      public/index.html
  43. TEMPAT SAMPAH
      public/model/shadow.jpg
  44. TEMPAT SAMPAH
      public/model/wl48-biaochi.png
  45. TEMPAT SAMPAH
      public/model/wl48-he.glb
  46. 31 0
      public/model/wl48-he.mtl
  47. 337033 0
      public/model/wl48-he.obj
  48. TEMPAT SAMPAH
      public/model/wl48-he1_BaseColor.jpg
  49. 4 0
      public/package/jquery-2.1.1.min.js
  50. 131 0
      public/package/js/InfiniteGridHelper.js
  51. 624 0
      public/package/js/MTLLoader.js
  52. 834 0
      public/package/js/OBJLoader.js
  53. 1051 0
      public/package/js/OrbitControl.js
  54. 13 0
      public/package/js/dat.gui.min.js
  55. 4054 0
      public/package/js/glTFLoader.js
  56. 4 0
      public/package/js/jquery-2.1.1.min.js
  57. 111 0
      public/package/js/label.js
  58. 486 0
      public/package/js/objViewer.js
  59. 132 0
      public/package/js/shaders.js
  60. 47365 0
      public/package/js/three95.min.js
  61. 755 0
      public/package/js/tweenjs.min.js
  62. 503 0
      public/package/js/utils.js
  63. 1 0
      public/package/jweixin-1.6.0.js
  64. 13 0
      public/package/swiper-bundle.min.css
  65. 14 0
      public/package/swiper-bundle.min.js
  66. 49 0
      src/App.vue
  67. TEMPAT SAMPAH
      src/assets/images/close.png
  68. TEMPAT SAMPAH
      src/assets/images/fanzhuan.png
  69. TEMPAT SAMPAH
      src/assets/images/icon/collection.png
  70. TEMPAT SAMPAH
      src/assets/images/icon/collection_active.png
  71. TEMPAT SAMPAH
      src/assets/images/icon/history.png
  72. TEMPAT SAMPAH
      src/assets/images/icon/history_active.png
  73. TEMPAT SAMPAH
      src/assets/images/icon/info.png
  74. TEMPAT SAMPAH
      src/assets/images/icon/info_active.png
  75. TEMPAT SAMPAH
      src/assets/images/icon/pic.png
  76. TEMPAT SAMPAH
      src/assets/images/icon/pic_active.png
  77. TEMPAT SAMPAH
      src/assets/images/icon/point.png
  78. TEMPAT SAMPAH
      src/assets/images/icon/point_active.png
  79. TEMPAT SAMPAH
      src/assets/images/info_bg.png
  80. TEMPAT SAMPAH
      src/assets/images/logo.png
  81. TEMPAT SAMPAH
      src/assets/images/point.png
  82. 6 0
      src/assets/images/point.svg
  83. TEMPAT SAMPAH
      src/assets/images/point_active.png
  84. 6 0
      src/assets/images/point_active.svg
  85. TEMPAT SAMPAH
      src/assets/images/pop.png
  86. TEMPAT SAMPAH
      src/assets/images/tab.png
  87. 6 0
      src/assets/images/tab.svg
  88. TEMPAT SAMPAH
      src/assets/images/temp.jpg
  89. TEMPAT SAMPAH
      src/assets/images/title.png
  90. TEMPAT SAMPAH
      src/assets/images/video.png
  91. 61 0
      src/components/introduce.vue
  92. 72 0
      src/components/loading.vue
  93. 146 0
      src/components/menu.vue
  94. 27 0
      src/components/verticaltip/build.js
  95. 64 0
      src/components/verticaltip/index.vue
  96. 93 0
      src/kit/Label.js
  97. 36 0
      src/kit/RoomLabel.js
  98. 11 0
      src/main.js
  99. 46 0
      src/mixins/index.js
  100. 0 0
      src/router/index.js

+ 3 - 0
.browserslistrc

@@ -0,0 +1,3 @@
+> 1%
+last 2 versions
+not dead

+ 18 - 0
.eslintrc.js

@@ -0,0 +1,18 @@
+module.exports = {
+  root: true,
+  env: {
+    node: true
+  },
+  'extends': [
+    'plugin:vue/essential',
+    'eslint:recommended'
+  ],
+  parserOptions: {
+    parser: 'babel-eslint'
+  },
+  rules: {
+    'no-unused-vars': 'off',
+    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
+    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
+  }
+}

+ 23 - 0
.gitignore

@@ -0,0 +1,23 @@
+.DS_Store
+node_modules
+/dist
+
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 201 - 0
LICENSE

@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 24 - 0
README.md

@@ -0,0 +1,24 @@
+# project
+
+## Project setup
+```
+npm install
+```
+
+### Compiles and hot-reloads for development
+```
+npm run serve
+```
+
+### Compiles and minifies for production
+```
+npm run build
+```
+
+### Lints and fixes files
+```
+npm run lint
+```
+
+### Customize configuration
+See [Configuration Reference](https://cli.vuejs.org/config/).

+ 5 - 0
babel.config.js

@@ -0,0 +1,5 @@
+module.exports = {
+  presets: [
+    '@vue/cli-plugin-babel/preset'
+  ]
+}

File diff ditekan karena terlalu besar
+ 27838 - 0
package-lock.json


+ 28 - 0
package.json

@@ -0,0 +1,28 @@
+{
+  "name": "project",
+  "version": "0.1.0",
+  "private": true,
+  "scripts": {
+    "serve": "vue-cli-service serve",
+    "build": "vue-cli-service build",
+    "lint": "vue-cli-service lint"
+  },
+  "dependencies": {
+    "core-js": "^3.6.5",
+    "three": "^0.140.1",
+    "vue": "^2.6.11",
+    "vue-router": "^3.2.0"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "~4.5.14",
+    "@vue/cli-plugin-eslint": "~4.5.14",
+    "@vue/cli-plugin-router": "~4.5.14",
+    "@vue/cli-service": "~4.5.14",
+    "babel-eslint": "^10.1.0",
+    "eslint": "^6.7.2",
+    "eslint-plugin-vue": "^6.2.2",
+    "less": "^3.0.4",
+    "less-loader": "^5.0.0",
+    "vue-template-compiler": "^2.6.11"
+  }
+}

TEMPAT SAMPAH
public/audio/10ce.mp3


TEMPAT SAMPAH
public/audio/10ce1.mp3


TEMPAT SAMPAH
public/audio/10zheng.mp3


TEMPAT SAMPAH
public/audio/1ce.mp3


TEMPAT SAMPAH
public/audio/1ce1.mp3


TEMPAT SAMPAH
public/audio/1zheng.mp3


TEMPAT SAMPAH
public/audio/2ce.mp3


TEMPAT SAMPAH
public/audio/2ce1.mp3


TEMPAT SAMPAH
public/audio/2zheng.mp3


TEMPAT SAMPAH
public/audio/3ce.mp3


TEMPAT SAMPAH
public/audio/3ce1.mp3


TEMPAT SAMPAH
public/audio/3zheng.mp3


TEMPAT SAMPAH
public/audio/4ce.mp3


TEMPAT SAMPAH
public/audio/4ce1.mp3


TEMPAT SAMPAH
public/audio/4zheng.mp3


TEMPAT SAMPAH
public/audio/5ce.mp3


TEMPAT SAMPAH
public/audio/5ce1.mp3


TEMPAT SAMPAH
public/audio/5zheng.mp3


TEMPAT SAMPAH
public/audio/6ce.mp3


TEMPAT SAMPAH
public/audio/6ce1.mp3


TEMPAT SAMPAH
public/audio/6zheng.mp3


TEMPAT SAMPAH
public/audio/7ce.mp3


TEMPAT SAMPAH
public/audio/7ce1.mp3


TEMPAT SAMPAH
public/audio/7zheng.mp3


TEMPAT SAMPAH
public/audio/8ce.mp3


TEMPAT SAMPAH
public/audio/8ce1.mp3


TEMPAT SAMPAH
public/audio/8zheng.mp3


TEMPAT SAMPAH
public/audio/9ce.mp3


TEMPAT SAMPAH
public/audio/9ce1.mp3


TEMPAT SAMPAH
public/audio/9zheng.mp3


File diff ditekan karena terlalu besar
+ 7 - 0
public/css/animate.min.css


TEMPAT SAMPAH
public/images/temp.jpg


TEMPAT SAMPAH
public/images/video.png


+ 27 - 0
public/index.html

@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html lang="">
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+    <link rel="icon" href="<%= BASE_URL %>logo.png">
+    <title>南京博物馆</title>
+  </head>
+  <body>
+    <div id="app"></div>
+    <!-- built files will be auto injected -->
+  <script type="text/javascript" src="./package/js/jquery-2.1.1.min.js"></script>
+  <script type="text/javascript" src="./package/js/three95.min.js"></script>
+  <script type="text/javascript" src="./package/js/utils.js"></script>
+  <script type="text/javascript" src="./package/js/MTLLoader.js"></script>
+  <script type="text/javascript" src="./package/js/OBJLoader.js"></script>
+  <script type="text/javascript" src="./package/js/tweenjs.min.js"></script>
+  <!-- <script type="text/javascript" src="./package/js/shaders.js"></script> -->
+  <script type="text/javascript" src="./package/js/OrbitControl.js"></script>
+  <script type="text/javascript" src="./package/js/InfiniteGridHelper.js"></script>
+  <script type="text/javascript" src="./package/js/label.js"></script>
+
+  <script type="text/javascript" src="./package/js/objViewer.js"></script>
+
+  </body>
+</html>

TEMPAT SAMPAH
public/model/shadow.jpg


TEMPAT SAMPAH
public/model/wl48-biaochi.png


TEMPAT SAMPAH
public/model/wl48-he.glb


+ 31 - 0
public/model/wl48-he.mtl

@@ -0,0 +1,31 @@
+# 3ds Max Wavefront OBJ Exporter v0.99 - (c)2007 guruware
+# �������ļ�:28.09.2022 11:46:40
+
+newmtl Material__1
+	Ns 10.0000
+	Ni 1.5000
+	d 1.0000
+	Tr 0.0000
+	Tf 1.0000 1.0000 1.0000 
+	illum 2
+	Ka 0.5880 0.5880 0.5880
+	Kd 0.5880 0.5880 0.5880
+	Ks 0.0000 0.0000 0.0000
+	Ke 0.0000 0.0000 0.0000
+	map_Ka wl48-he1_BaseColor.jpg
+	map_Kd wl48-he1_BaseColor.jpg
+
+newmtl Material__2
+	Ns 10.0000
+	Ni 1.5000
+	d 1.0000
+	Tr 0.0000
+	Tf 1.0000 1.0000 1.0000 
+	illum 2
+	Ka 0.5880 0.5880 0.5880
+	Kd 0.5880 0.5880 0.5880
+	Ks 0.0000 0.0000 0.0000
+	Ke 0.0000 0.0000 0.0000
+	map_Ka wl48-biaochi.png
+	map_Kd wl48-biaochi.png
+	map_d wl48-biaochi.png

File diff ditekan karena terlalu besar
+ 337033 - 0
public/model/wl48-he.obj


TEMPAT SAMPAH
public/model/wl48-he1_BaseColor.jpg


File diff ditekan karena terlalu besar
+ 4 - 0
public/package/jquery-2.1.1.min.js


+ 131 - 0
public/package/js/InfiniteGridHelper.js

@@ -0,0 +1,131 @@
+// Author: Fyrestar https://mevedia.com (https://github.com/Fyrestar/THREE.InfiniteGridHelper)
+ 
+
+class InfiniteGridHelper extends THREE.Mesh{
+     
+    constructor(size1, size2, color, distance, opacity1=0.2, opacity2=1){
+        
+        color = color || new THREE.Color('white');
+        size1 = size1 || 10;
+        size2 = size2 || 100;
+
+        distance = distance || 8000; //可视距离?越远越模糊
+
+        const geometry = new THREE.PlaneBufferGeometry(2, 2, 1, 1);
+
+        const material = new THREE.ShaderMaterial({
+
+            side: THREE.DoubleSide,
+
+            uniforms: {
+                uSize1: {
+                    value: size1
+                },
+                uSize2: {
+                    value: size2
+                },
+                
+                opacity1:{//线条1的
+                    value: opacity1
+                },
+                opacity2:{//线条2的
+                    value: opacity2
+                },
+                
+                uColor: {
+                    value: color
+                },
+                uDistance: {
+                    value: distance
+                }
+            },
+            transparent: true,
+            vertexShader: `
+               
+               varying vec3 worldPosition;
+               
+               uniform float uDistance;
+               
+               void main() {
+               
+                    vec3 pos = position.xyz * uDistance;
+                    pos.xy += cameraPosition.xy;
+                    
+                    worldPosition = pos;
+                    
+                    gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
+               
+               }
+               `,
+
+
+            fragmentShader: `
+               
+               varying vec3 worldPosition;
+               
+               uniform float uSize1;
+               uniform float uSize2;
+               uniform float opacity1;
+               uniform float opacity2;
+               uniform vec3 uColor;
+               uniform float uDistance;
+                
+                
+                
+                float getGrid(float size) {
+                
+                    vec2 r = worldPosition.xy / size;
+                    
+                    
+                    vec2 grid = abs(fract(r - 0.5) - 0.5) / fwidth(r);
+                    float line = min(grid.x, grid.y);
+                    
+                
+                    return 1.0 - min(line, 1.0);
+                }
+                //为何侧面看不到线,因为mesh的正侧面都看不到?
+
+               void main() {
+               
+                    
+                      float d = 1.0 - min(distance(cameraPosition.xy, worldPosition.xy) / uDistance, 1.0);
+                    
+                      float g1 = getGrid(uSize1);
+                      float g2 = getGrid(uSize2);
+                      
+                      
+                      gl_FragColor = vec4(uColor.rgb, mix(g2, g1, g1) * pow(d, 3.0));
+                      //gl_FragColor.a = mix(0.5 * gl_FragColor.a, gl_FragColor.a, g2);
+                        gl_FragColor.a = mix(opacity1 * gl_FragColor.a, opacity2 * gl_FragColor.a, g2);
+                        
+                        
+                      if ( gl_FragColor.a <= 0.0 ) discard;
+                    
+               
+               }
+               
+               `,
+
+            extensions: {
+                derivatives: true
+            }
+            
+            
+            
+        })
+        
+        
+        super(geometry, material)
+        this.frustumCulled = false;
+
+    }
+
+
+    
+
+    
+
+};
+
+
+ 

+ 624 - 0
public/package/js/MTLLoader.js

@@ -0,0 +1,624 @@
+/**
+ * Loads a Wavefront .mtl file specifying materials
+ *
+ * @author angelxuanchang
+ */
+
+/* import {
+	Color,
+	DefaultLoadingManager,
+	FileLoader,
+	FrontSide,
+	Loader,
+	LoaderUtils,
+	MeshPhongMaterial,
+	RepeatWrapping,
+	TextureLoader,
+	Vector2
+} from "../../../build/three.module.js"; */
+
+(function(){
+	var Color = THREE.Color;
+	var DefaultLoadingManager = THREE.DefaultLoadingManager;
+	var FileLoader = THREE.FileLoader;
+	var FrontSide = THREE.FrontSide;
+	var Loader = THREE.Loader;
+	var LoaderUtils = THREE.LoaderUtils;
+	var MeshPhongMaterial = THREE.MeshPhongMaterial;
+    var MeshStandardMaterial = THREE.MeshStandardMaterial
+	var RepeatWrapping = THREE.RepeatWrapping;
+	var TextureLoader = THREE.TextureLoader;
+	var Vector2 = THREE.Vector2; 
+	
+	
+	
+var MTLLoader = function ( manager ) {
+
+	this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
+
+};
+THREE.MTLLoader = MTLLoader;
+
+MTLLoader.prototype = {
+
+	constructor: MTLLoader,
+
+	crossOrigin: 'anonymous',
+
+	/**
+	 * Loads and parses a MTL asset from a URL.
+	 *
+	 * @param {String} url - URL to the MTL file.
+	 * @param {Function} [onLoad] - Callback invoked with the loaded object.
+	 * @param {Function} [onProgress] - Callback for download progress.
+	 * @param {Function} [onError] - Callback for download errors.
+	 *
+	 * @see setPath setResourcePath
+	 *
+	 * @note In order for relative texture references to resolve correctly
+	 * you must call setResourcePath() explicitly prior to load.
+	 */
+	load: function ( url, onLoad, onProgress, onError ) {
+
+		var scope = this;
+
+		var path = ( this.path === undefined ) ? LoaderUtils.extractUrlBase( url ) : this.path;
+
+		var loader = new FileLoader( this.manager );
+		loader.setPath( this.path );
+		loader.load( url, function ( text ) {
+
+			onLoad( scope.parse( text, path ) );
+
+		}, onProgress, onError );
+
+	},
+
+	/**
+	 * Set base path for resolving references.
+	 * If set this path will be prepended to each loaded and found reference.
+	 *
+	 * @see setResourcePath
+	 * @param {String} path
+	 * @return {MTLLoader}
+	 *
+	 * @example
+	 *     mtlLoader.setPath( 'assets/obj/' );
+	 *     mtlLoader.load( 'my.mtl', ... );
+	 */
+	setPath: function ( path ) {
+
+		this.path = path;
+		return this;
+
+	},
+
+	/**
+	 * Set base path for additional resources like textures.
+	 *
+	 * @see setPath
+	 * @param {String} path
+	 * @return {MTLLoader}
+	 *
+	 * @example
+	 *     mtlLoader.setPath( 'assets/obj/' );
+	 *     mtlLoader.setResourcePath( 'assets/textures/' );
+	 *     mtlLoader.load( 'my.mtl', ... );
+	 */
+	setResourcePath: function ( path ) {
+
+		this.resourcePath = path;
+		return this;
+
+	},
+
+	setTexturePath: function ( path ) {
+
+		console.warn( 'THREE.MTLLoader: .setTexturePath() has been renamed to .setResourcePath().' );
+		return this.setResourcePath( path );
+
+	},
+
+	setCrossOrigin: function ( value ) {
+
+		this.crossOrigin = value;
+		return this;
+
+	},
+
+	setMaterialOptions: function ( value ) {
+
+		this.materialOptions = value;
+		return this;
+
+	},
+
+	/**
+	 * Parses a MTL file.
+	 *
+	 * @param {String} text - Content of MTL file
+	 * @return {MTLLoader.MaterialCreator}
+	 *
+	 * @see setPath setResourcePath
+	 *
+	 * @note In order for relative texture references to resolve correctly
+	 * you must call setResourcePath() explicitly prior to parse.
+	 */
+	parse: function ( text, path ) {
+
+		var lines = text.split( '\n' );
+		var info = {};
+		var delimiter_pattern = /\s+/;
+		var materialsInfo = {};
+
+		for ( var i = 0; i < lines.length; i ++ ) {
+
+			var line = lines[ i ];
+			line = line.trim();
+
+			if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
+
+				// Blank line or comment ignore
+				continue;
+
+			}
+
+			var pos = line.indexOf( ' ' );
+
+			var key = ( pos >= 0 ) ? line.substring( 0, pos ) : line;
+			key = key.toLowerCase();
+
+			var value = ( pos >= 0 ) ? line.substring( pos + 1 ) : '';
+			value = value.trim();
+
+			if ( key === 'newmtl' ) {
+
+				// New material
+
+				info = { name: value };
+				materialsInfo[ value ] = info;
+
+			} else {
+
+				if ( key === 'ka' || key === 'kd' || key === 'ks' || key === 'ke' ) {
+
+					var ss = value.split( delimiter_pattern, 3 );
+					info[ key ] = [ parseFloat( ss[ 0 ] ), parseFloat( ss[ 1 ] ), parseFloat( ss[ 2 ] ) ];
+
+				} else {
+
+					info[ key ] = value;
+
+				}
+
+			}
+
+		}
+
+		var materialCreator = new MTLLoader.MaterialCreator( this.resourcePath || path, this.materialOptions );
+		materialCreator.setCrossOrigin( this.crossOrigin );
+		materialCreator.setManager( this.manager );
+		materialCreator.setMaterials( materialsInfo );
+		return materialCreator;
+
+	}
+
+};
+
+/**
+ * Create a new THREE-MTLLoader.MaterialCreator
+ * @param baseUrl - Url relative to which textures are loaded
+ * @param options - Set of options on how to construct the materials
+ *                  side: Which side to apply the material
+ *                        FrontSide (default), THREE.BackSide, THREE.DoubleSide
+ *                  wrap: What type of wrapping to apply for textures
+ *                        RepeatWrapping (default), THREE.ClampToEdgeWrapping, THREE.MirroredRepeatWrapping
+ *                  normalizeRGB: RGBs need to be normalized to 0-1 from 0-255
+ *                                Default: false, assumed to be already normalized
+ *                  ignoreZeroRGBs: Ignore values of RGBs (Ka,Kd,Ks) that are all 0's
+ *                                  Default: false
+ * @constructor
+ */
+
+MTLLoader.MaterialCreator = function ( baseUrl, options ) {
+
+	this.baseUrl = baseUrl || '';
+	this.options = options;
+	this.materialsInfo = {};
+	this.materials = {};
+	this.materialsArray = [];
+	this.nameLookup = {};
+
+	this.side = ( this.options && this.options.side ) ? this.options.side : FrontSide;
+	this.wrap = ( this.options && this.options.wrap ) ? this.options.wrap : RepeatWrapping;
+
+};
+
+MTLLoader.MaterialCreator.prototype = {
+
+	constructor: MTLLoader.MaterialCreator,
+
+	crossOrigin: 'anonymous',
+
+	setCrossOrigin: function ( value ) {
+
+		this.crossOrigin = value;
+		return this;
+
+	},
+
+	setManager: function ( value ) {
+
+		this.manager = value;
+
+	},
+
+	setMaterials: function ( materialsInfo ) {
+
+		this.materialsInfo = this.convert( materialsInfo );
+		this.materials = {};
+		this.materialsArray = [];
+		this.nameLookup = {};
+
+	},
+
+	convert: function ( materialsInfo ) {
+
+		if ( ! this.options ) return materialsInfo;
+
+		var converted = {};
+
+		for ( var mn in materialsInfo ) {
+
+			// Convert materials info into normalized form based on options
+
+			var mat = materialsInfo[ mn ];
+
+			var covmat = {};
+
+			converted[ mn ] = covmat;
+
+			for ( var prop in mat ) {
+
+				var save = true;
+				var value = mat[ prop ];
+				var lprop = prop.toLowerCase();
+
+				switch ( lprop ) {
+
+					case 'kd':
+					case 'ka':
+					case 'ks':
+
+						// Diffuse color (color under white light) using RGB values
+
+						if ( this.options && this.options.normalizeRGB ) {
+
+							value = [ value[ 0 ] / 255, value[ 1 ] / 255, value[ 2 ] / 255 ];
+
+						}
+
+						if ( this.options && this.options.ignoreZeroRGBs ) {
+
+							if ( value[ 0 ] === 0 && value[ 1 ] === 0 && value[ 2 ] === 0 ) {
+
+								// ignore
+
+								save = false;
+
+							}
+
+						}
+
+						break;
+
+					default:
+
+						break;
+
+				}
+
+				if ( save ) {
+
+					covmat[ lprop ] = value;
+
+				}
+
+			}
+
+		}
+
+		return converted;
+
+	},
+
+	preload: function () {
+
+		for ( var mn in this.materialsInfo ) {
+
+			this.create( mn );
+
+		}
+
+	},
+
+	getIndex: function ( materialName ) {
+
+		return this.nameLookup[ materialName ];
+
+	},
+
+	getAsArray: function () {
+
+		var index = 0;
+
+		for ( var mn in this.materialsInfo ) {
+
+			this.materialsArray[ index ] = this.create( mn );
+			this.nameLookup[ mn ] = index;
+			index ++;
+
+		}
+
+		return this.materialsArray;
+
+	},
+
+	create: function ( materialName ) {
+
+		if ( this.materials[ materialName ] === undefined ) {
+
+			this.createMaterial_( materialName );
+
+		}
+
+		return this.materials[ materialName ];
+
+	},
+
+	createMaterial_: function ( materialName ) {
+
+		// Create material
+
+		var scope = this;
+		var mat = this.materialsInfo[ materialName ];
+		var params = {
+
+			name: materialName,
+			side: this.side,
+			//增加些默认值add
+			// color:new THREE.Color(window.setting.material.color),
+			// roughness: window.setting.material.roughness,
+			// metalness: window.setting.material.metalness,
+		};
+
+		function resolveURL( baseUrl, url ) {
+
+			if ( typeof url !== 'string' || url === '' )
+				return '';
+
+			// Absolute URL
+			if ( /^https?:\/\//i.test( url ) ) return url;
+
+			return baseUrl + url;
+
+		}
+
+		function setMapForType( mapType, value ) {
+
+			if ( params[ mapType ] ) return; // Keep the first encountered texture
+
+			var texParams = scope.getTextureParams( value, params );
+			var map = scope.loadTexture( resolveURL( scope.baseUrl, texParams.url ) );
+
+			map.repeat.copy( texParams.scale );
+			map.offset.copy( texParams.offset );
+
+			map.wrapS = scope.wrap;
+			map.wrapT = scope.wrap;
+
+			params[ mapType ] = map;
+
+		}
+
+		for ( var prop in mat ) {
+
+			var value = mat[ prop ];
+			var n;
+
+			if ( value === '' ) continue;
+
+			switch ( prop.toLowerCase() ) {
+
+				// Ns is material specular exponent
+
+				case 'kd':
+
+					// Diffuse color (color under white light) using RGB values
+
+					params.color = new Color().fromArray( value );
+
+					break;
+
+				case 'ks':
+
+					// Specular color (color when light is reflected from shiny surface) using RGB values
+					params.specular = new Color().fromArray( value );
+                    
+					break;
+
+				case 'ke':
+
+					// Emissive using RGB values
+					params.emissive = new Color().fromArray( value );
+
+					break;
+
+				case 'map_kd':
+
+					// Diffuse texture map
+
+					setMapForType( "map", value );
+
+					break;
+
+				case 'map_ks':
+
+					// Specular map
+
+					//setMapForType( "specularMap", value );
+                    setMapForType( "roughnessMap", value ); //glossnessMap
+                    
+					break;
+                case 'map_refl'://xzw add
+  
+                    setMapForType( "metalnessMap", value );
+                    
+					break;
+				case 'map_ke':
+
+					// Emissive map
+
+					setMapForType( "emissiveMap", value );
+
+					break;
+
+				case 'norm':
+
+					setMapForType( "normalMap", value );
+
+					break;
+
+				case 'map_bump':
+				case 'bump':
+
+					// Bump texture map
+
+					setMapForType( "bumpMap", value );
+
+					break;
+
+				case 'map_d':
+
+					// Alpha map
+
+					setMapForType( "alphaMap", value );
+					params.transparent = true;
+
+					break;
+
+				case 'ns':
+
+					// The specular exponent (defines the focus of the specular highlight)
+					// A high exponent results in a tight, concentrated highlight. Ns values normally range from 0 to 1000.
+
+					params.shininess = parseFloat( value );
+                    
+					break;
+
+				case 'd':
+					n = parseFloat( value );
+
+					if ( n < 1 ) {
+
+						params.opacity = n;
+						params.transparent = true;
+
+					}
+
+					break;
+
+				case 'tr':
+					n = parseFloat( value );
+
+					if ( this.options && this.options.invertTrProperty ) n = 1 - n;
+
+					if ( n > 0 ) {
+
+						params.opacity = 1 - n;
+						params.transparent = true;
+
+					}
+
+					break;
+
+				default:
+					break;
+
+			}
+
+		}
+
+		this.materials[ materialName ] = new MeshStandardMaterial(params)//MeshPhongMaterial( params );
+		return this.materials[ materialName ];
+
+	},
+
+	getTextureParams: function ( value, matParams ) {
+
+		var texParams = {
+
+			scale: new Vector2( 1, 1 ),
+			offset: new Vector2( 0, 0 )
+
+		 };
+
+		var items = value.split( /\s+/ );
+		var pos;
+
+		pos = items.indexOf( '-bm' );
+
+		if ( pos >= 0 ) {
+
+			matParams.bumpScale = parseFloat( items[ pos + 1 ] );
+			items.splice( pos, 2 );
+
+		}
+
+		pos = items.indexOf( '-s' );
+
+		if ( pos >= 0 ) {
+
+			texParams.scale.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) );
+			items.splice( pos, 4 ); // we expect 3 parameters here!
+
+		}
+
+		pos = items.indexOf( '-o' );
+
+		if ( pos >= 0 ) {
+
+			texParams.offset.set( parseFloat( items[ pos + 1 ] ), parseFloat( items[ pos + 2 ] ) );
+			items.splice( pos, 4 ); // we expect 3 parameters here!
+
+		}
+
+		texParams.url = items.join( ' ' ).trim();
+		return texParams;
+
+	},
+
+	loadTexture: function ( url, mapping, onLoad, onProgress, onError ) {
+
+		var texture;
+		var loader = Loader.Handlers.get( url );
+		var manager = ( this.manager !== undefined ) ? this.manager : DefaultLoadingManager;
+
+		if ( loader === null ) {
+
+			loader = new TextureLoader( manager );
+
+		}
+
+		if ( loader.setCrossOrigin ) loader.setCrossOrigin( this.crossOrigin );
+		texture = loader.load( url, onLoad, onProgress, onError );
+
+		if ( mapping !== undefined ) texture.mapping = mapping;
+
+		return texture;
+
+	}
+
+};
+})()
+//export { MTLLoader };

+ 834 - 0
public/package/js/OBJLoader.js

@@ -0,0 +1,834 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+/* import {
+	BufferGeometry,
+	DefaultLoadingManager,
+	FileLoader,
+	Float32BufferAttribute,
+	Group,
+	LineBasicMaterial,
+	LineSegments,
+	Material,
+	Mesh,
+	MeshPhongMaterial,
+	NoColors,
+	Points,
+	PointsMaterial,
+	VertexColors
+} from "../../../build/three.module.js"; */
+
+
+
+
+THREE.OBJLoader = ( function () {
+	var BufferGeometry = THREE.BufferGeometry;
+	var DefaultLoadingManager = THREE.DefaultLoadingManager;
+	var FileLoader = THREE.FileLoader;
+	var Float32BufferAttribute = THREE.Float32BufferAttribute;
+	var Group = THREE.Group;
+	var LineBasicMaterial = THREE.LineBasicMaterial;
+	var LineSegments = THREE.LineSegments;
+	var Material = THREE.Material;
+	var Mesh = THREE.Mesh;
+	var MeshPhongMaterial = THREE.MeshPhongMaterial;
+	var NoColors = THREE.NoColors;
+	var PointsMaterial = THREE.PointsMaterial;
+	var VertexColors = THREE.VertexColors;
+ 
+
+	// o object_name | g group_name
+	var object_pattern = /^[og]\s*(.+)?/;
+	// mtllib file_reference
+	var material_library_pattern = /^mtllib /;
+	// usemtl material_name
+	var material_use_pattern = /^usemtl /;
+
+	function ParserState() {
+
+		var state = {
+			objects: [],
+			object: {},
+
+			vertices: [],
+			normals: [],
+			colors: [],
+			uvs: [],
+
+			materialLibraries: [],
+
+			startObject: function ( name, fromDeclaration ) {
+
+				// If the current object (initial from reset) is not from a g/o declaration in the parsed
+				// file. We need to use it for the first parsed g/o to keep things in sync.
+				if ( this.object && this.object.fromDeclaration === false ) {
+
+					this.object.name = name;
+					this.object.fromDeclaration = ( fromDeclaration !== false );
+					return;
+
+				}
+
+				var previousMaterial = ( this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined );
+
+				if ( this.object && typeof this.object._finalize === 'function' ) {
+
+					this.object._finalize( true );
+
+				}
+
+				this.object = {
+					name: name || '',
+					fromDeclaration: ( fromDeclaration !== false ),
+
+					geometry: {
+						vertices: [],
+						normals: [],
+						colors: [],
+						uvs: []
+					},
+					materials: [],
+					smooth: true,
+
+					startMaterial: function ( name, libraries ) {
+
+						var previous = this._finalize( false );
+
+						// New usemtl declaration overwrites an inherited material, except if faces were declared
+						// after the material, then it must be preserved for proper MultiMaterial continuation.
+						if ( previous && ( previous.inherited || previous.groupCount <= 0 ) ) {
+
+							this.materials.splice( previous.index, 1 );
+
+						}
+
+						var material = {
+							index: this.materials.length,
+							name: name || '',
+							mtllib: ( Array.isArray( libraries ) && libraries.length > 0 ? libraries[ libraries.length - 1 ] : '' ),
+							smooth: ( previous !== undefined ? previous.smooth : this.smooth ),
+							groupStart: ( previous !== undefined ? previous.groupEnd : 0 ),
+							groupEnd: - 1,
+							groupCount: - 1,
+							inherited: false,
+
+							clone: function ( index ) {
+
+								var cloned = {
+									index: ( typeof index === 'number' ? index : this.index ),
+									name: this.name,
+									mtllib: this.mtllib,
+									smooth: this.smooth,
+									groupStart: 0,
+									groupEnd: - 1,
+									groupCount: - 1,
+									inherited: false
+								};
+								cloned.clone = this.clone.bind( cloned );
+								return cloned;
+
+							}
+						};
+
+						this.materials.push( material );
+
+						return material;
+
+					},
+
+					currentMaterial: function () {
+
+						if ( this.materials.length > 0 ) {
+
+							return this.materials[ this.materials.length - 1 ];
+
+						}
+
+						return undefined;
+
+					},
+
+					_finalize: function ( end ) {
+
+						var lastMultiMaterial = this.currentMaterial();
+						if ( lastMultiMaterial && lastMultiMaterial.groupEnd === - 1 ) {
+
+							lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3;
+							lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart;
+							lastMultiMaterial.inherited = false;
+
+						}
+
+						// Ignore objects tail materials if no face declarations followed them before a new o/g started.
+						if ( end && this.materials.length > 1 ) {
+
+							for ( var mi = this.materials.length - 1; mi >= 0; mi -- ) {
+
+								if ( this.materials[ mi ].groupCount <= 0 ) {
+
+									this.materials.splice( mi, 1 );
+
+								}
+
+							}
+
+						}
+
+						// Guarantee at least one empty material, this makes the creation later more straight forward.
+						if ( end && this.materials.length === 0 ) {
+
+							this.materials.push( {
+								name: '',
+								smooth: this.smooth
+							} );
+
+						}
+
+						return lastMultiMaterial;
+
+					}
+				};
+
+				// Inherit previous objects material.
+				// Spec tells us that a declared material must be set to all objects until a new material is declared.
+				// If a usemtl declaration is encountered while this new object is being parsed, it will
+				// overwrite the inherited material. Exception being that there was already face declarations
+				// to the inherited material, then it will be preserved for proper MultiMaterial continuation.
+
+				if ( previousMaterial && previousMaterial.name && typeof previousMaterial.clone === 'function' ) {
+
+					var declared = previousMaterial.clone( 0 );
+					declared.inherited = true;
+					this.object.materials.push( declared );
+
+				}
+
+				this.objects.push( this.object );
+
+			},
+
+			finalize: function () {
+
+				if ( this.object && typeof this.object._finalize === 'function' ) {
+
+					this.object._finalize( true );
+
+				}
+
+			},
+
+			parseVertexIndex: function ( value, len ) {
+
+				var index = parseInt( value, 10 );
+				return ( index >= 0 ? index - 1 : index + len / 3 ) * 3;
+
+			},
+
+			parseNormalIndex: function ( value, len ) {
+
+				var index = parseInt( value, 10 );
+				return ( index >= 0 ? index - 1 : index + len / 3 ) * 3;
+
+			},
+
+			parseUVIndex: function ( value, len ) {
+
+				var index = parseInt( value, 10 );
+				return ( index >= 0 ? index - 1 : index + len / 2 ) * 2;
+
+			},
+
+			addVertex: function ( a, b, c ) {
+
+				var src = this.vertices;
+				var dst = this.object.geometry.vertices;
+
+				dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
+				dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );
+				dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );
+
+			},
+
+			addVertexPoint: function ( a ) {
+
+				var src = this.vertices;
+				var dst = this.object.geometry.vertices;
+
+				dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
+
+			},
+
+			addVertexLine: function ( a ) {
+
+				var src = this.vertices;
+				var dst = this.object.geometry.vertices;
+
+				dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
+
+			},
+
+			addNormal: function ( a, b, c ) {
+
+				var src = this.normals;
+				var dst = this.object.geometry.normals;
+
+				dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
+				dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );
+				dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );
+
+			},
+
+			addColor: function ( a, b, c ) {
+
+				var src = this.colors;
+				var dst = this.object.geometry.colors;
+
+				dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
+				dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );
+				dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );
+
+			},
+
+			addUV: function ( a, b, c ) {
+
+				var src = this.uvs;
+				var dst = this.object.geometry.uvs;
+
+				dst.push( src[ a + 0 ], src[ a + 1 ] );
+				dst.push( src[ b + 0 ], src[ b + 1 ] );
+				dst.push( src[ c + 0 ], src[ c + 1 ] );
+
+			},
+
+			addUVLine: function ( a ) {
+
+				var src = this.uvs;
+				var dst = this.object.geometry.uvs;
+
+				dst.push( src[ a + 0 ], src[ a + 1 ] );
+
+			},
+
+			addFace: function ( a, b, c, ua, ub, uc, na, nb, nc ) {
+
+				var vLen = this.vertices.length;
+
+				var ia = this.parseVertexIndex( a, vLen );
+				var ib = this.parseVertexIndex( b, vLen );
+				var ic = this.parseVertexIndex( c, vLen );
+
+				this.addVertex( ia, ib, ic );
+
+				if ( ua !== undefined && ua !== '' ) {
+
+					var uvLen = this.uvs.length;
+					ia = this.parseUVIndex( ua, uvLen );
+					ib = this.parseUVIndex( ub, uvLen );
+					ic = this.parseUVIndex( uc, uvLen );
+					this.addUV( ia, ib, ic );
+
+				}
+
+				if ( na !== undefined && na !== '' ) {
+
+					// Normals are many times the same. If so, skip function call and parseInt.
+					var nLen = this.normals.length;
+					ia = this.parseNormalIndex( na, nLen );
+
+					ib = na === nb ? ia : this.parseNormalIndex( nb, nLen );
+					ic = na === nc ? ia : this.parseNormalIndex( nc, nLen );
+
+					this.addNormal( ia, ib, ic );
+
+				}
+
+				if ( this.colors.length > 0 ) {
+
+					this.addColor( ia, ib, ic );
+
+				}
+
+			},
+
+			addPointGeometry: function ( vertices ) {
+
+				this.object.geometry.type = 'Points';
+
+				var vLen = this.vertices.length;
+
+				for ( var vi = 0, l = vertices.length; vi < l; vi ++ ) {
+
+					this.addVertexPoint( this.parseVertexIndex( vertices[ vi ], vLen ) );
+
+				}
+
+			},
+
+			addLineGeometry: function ( vertices, uvs ) {
+
+				this.object.geometry.type = 'Line';
+
+				var vLen = this.vertices.length;
+				var uvLen = this.uvs.length;
+
+				for ( var vi = 0, l = vertices.length; vi < l; vi ++ ) {
+
+					this.addVertexLine( this.parseVertexIndex( vertices[ vi ], vLen ) );
+
+				}
+
+				for ( var uvi = 0, l = uvs.length; uvi < l; uvi ++ ) {
+
+					this.addUVLine( this.parseUVIndex( uvs[ uvi ], uvLen ) );
+
+				}
+
+			}
+
+		};
+
+		state.startObject( '', false );
+
+		return state;
+
+	}
+
+	//
+
+	function OBJLoader( manager ) {
+
+		this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
+
+		this.materials = null;
+
+	}
+
+	OBJLoader.prototype = {
+
+		constructor: OBJLoader,
+
+		load: function ( url, onLoad, onProgress, onError ) {
+
+			var scope = this;
+
+			var loader = new FileLoader( scope.manager );
+			loader.setPath( this.path );
+			loader.load( url, function ( text ) {
+
+				onLoad( scope.parse( text ) );
+
+			}, onProgress, onError );
+
+		},
+
+		setPath: function ( value ) {
+
+			this.path = value;
+
+			return this;
+
+		},
+
+		setMaterials: function ( materials ) {
+
+			this.materials = materials;
+
+			return this;
+
+		},
+
+		parse: function ( text ) {
+
+			console.time( 'OBJLoader' );
+
+			var state = new ParserState();
+
+			if ( text.indexOf( '\r\n' ) !== - 1 ) {
+
+				// This is faster than String.split with regex that splits on both
+				text = text.replace( /\r\n/g, '\n' );
+
+			}
+
+			if ( text.indexOf( '\\\n' ) !== - 1 ) {
+
+				// join lines separated by a line continuation character (\)
+				text = text.replace( /\\\n/g, '' );
+
+			}
+
+			var lines = text.split( '\n' );
+			var line = '', lineFirstChar = '';
+			var lineLength = 0;
+			var result = [];
+
+			// Faster to just trim left side of the line. Use if available.
+			var trimLeft = ( typeof ''.trimLeft === 'function' );
+
+			for ( var i = 0, l = lines.length; i < l; i ++ ) {
+
+				line = lines[ i ];
+
+				line = trimLeft ? line.trimLeft() : line.trim();
+
+				lineLength = line.length;
+
+				if ( lineLength === 0 ) continue;
+
+				lineFirstChar = line.charAt( 0 );
+
+				// @todo invoke passed in handler if any
+				if ( lineFirstChar === '#' ) continue;
+
+				if ( lineFirstChar === 'v' ) {
+
+					var data = line.split( /\s+/ );
+
+					switch ( data[ 0 ] ) {
+
+						case 'v':
+							state.vertices.push(
+								parseFloat( data[ 1 ] ),
+								parseFloat( data[ 2 ] ),
+								parseFloat( data[ 3 ] )
+							);
+							if ( data.length >= 7 ) {
+
+								state.colors.push(
+									parseFloat( data[ 4 ] ),
+									parseFloat( data[ 5 ] ),
+									parseFloat( data[ 6 ] )
+
+								);
+
+							}
+							break;
+						case 'vn':
+							state.normals.push(
+								parseFloat( data[ 1 ] ),
+								parseFloat( data[ 2 ] ),
+								parseFloat( data[ 3 ] )
+							);
+							break;
+						case 'vt':
+							state.uvs.push(
+								parseFloat( data[ 1 ] ),
+								parseFloat( data[ 2 ] )
+							);
+							break;
+
+					}
+
+				} else if ( lineFirstChar === 'f' ) {
+
+					var lineData = line.substr( 1 ).trim();
+					var vertexData = lineData.split( /\s+/ );
+					var faceVertices = [];
+
+					// Parse the face vertex data into an easy to work with format
+
+					for ( var j = 0, jl = vertexData.length; j < jl; j ++ ) {
+
+						var vertex = vertexData[ j ];
+
+						if ( vertex.length > 0 ) {
+
+							var vertexParts = vertex.split( '/' );
+							faceVertices.push( vertexParts );
+
+						}
+
+					}
+
+					// Draw an edge between the first vertex and all subsequent vertices to form an n-gon
+
+					var v1 = faceVertices[ 0 ];
+
+					for ( var j = 1, jl = faceVertices.length - 1; j < jl; j ++ ) {
+
+						var v2 = faceVertices[ j ];
+						var v3 = faceVertices[ j + 1 ];
+
+						state.addFace(
+							v1[ 0 ], v2[ 0 ], v3[ 0 ],
+							v1[ 1 ], v2[ 1 ], v3[ 1 ],
+							v1[ 2 ], v2[ 2 ], v3[ 2 ]
+						);
+
+					}
+
+				} else if ( lineFirstChar === 'l' ) {
+
+					var lineParts = line.substring( 1 ).trim().split( " " );
+					var lineVertices = [], lineUVs = [];
+
+					if ( line.indexOf( "/" ) === - 1 ) {
+
+						lineVertices = lineParts;
+
+					} else {
+
+						for ( var li = 0, llen = lineParts.length; li < llen; li ++ ) {
+
+							var parts = lineParts[ li ].split( "/" );
+
+							if ( parts[ 0 ] !== "" ) lineVertices.push( parts[ 0 ] );
+							if ( parts[ 1 ] !== "" ) lineUVs.push( parts[ 1 ] );
+
+						}
+
+					}
+					state.addLineGeometry( lineVertices, lineUVs );
+
+				} else if ( lineFirstChar === 'p' ) {
+
+					var lineData = line.substr( 1 ).trim();
+					var pointData = lineData.split( " " );
+
+					state.addPointGeometry( pointData );
+
+				} else if ( ( result = object_pattern.exec( line ) ) !== null ) {
+
+					// o object_name
+					// or
+					// g group_name
+
+					// WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869
+					// var name = result[ 0 ].substr( 1 ).trim();
+					var name = ( " " + result[ 0 ].substr( 1 ).trim() ).substr( 1 );
+
+					state.startObject( name );
+
+				} else if ( material_use_pattern.test( line ) ) {
+
+					// material
+
+					state.object.startMaterial( line.substring( 7 ).trim(), state.materialLibraries );
+
+				} else if ( material_library_pattern.test( line ) ) {
+
+					// mtl file
+
+					state.materialLibraries.push( line.substring( 7 ).trim() );
+
+				} else if ( lineFirstChar === 's' ) {
+
+					result = line.split( ' ' );
+
+					// smooth shading
+
+					// @todo Handle files that have varying smooth values for a set of faces inside one geometry,
+					// but does not define a usemtl for each face set.
+					// This should be detected and a dummy material created (later MultiMaterial and geometry groups).
+					// This requires some care to not create extra material on each smooth value for "normal" obj files.
+					// where explicit usemtl defines geometry groups.
+					// Example asset: examples/models/obj/cerberus/Cerberus.obj
+
+					/*
+					 * http://paulbourke.net/dataformats/obj/
+					 * or
+					 * http://www.cs.utah.edu/~boulos/cs3505/obj_spec.pdf
+					 *
+					 * From chapter "Grouping" Syntax explanation "s group_number":
+					 * "group_number is the smoothing group number. To turn off smoothing groups, use a value of 0 or off.
+					 * Polygonal elements use group numbers to put elements in different smoothing groups. For free-form
+					 * surfaces, smoothing groups are either turned on or off; there is no difference between values greater
+					 * than 0."
+					 */
+					if ( result.length > 1 ) {
+
+						var value = result[ 1 ].trim().toLowerCase();
+						state.object.smooth = ( value !== '0' && value !== 'off' );
+
+					} else {
+
+						// ZBrush can produce "s" lines #11707
+						state.object.smooth = true;
+
+					}
+					var material = state.object.currentMaterial();
+					if ( material ) material.smooth = state.object.smooth;
+
+				} else {
+
+					// Handle null terminated files without exception
+					if ( line === '\0' ) continue;
+
+					throw new Error( 'THREE.OBJLoader: Unexpected line: "' + line + '"' );
+
+				}
+
+			}
+
+			state.finalize();
+
+			var container = new Group();
+			container.materialLibraries = [].concat( state.materialLibraries );
+
+			for ( var i = 0, l = state.objects.length; i < l; i ++ ) {
+
+				var object = state.objects[ i ];
+				var geometry = object.geometry;
+				var materials = object.materials;
+				var isLine = ( geometry.type === 'Line' );
+				var isPoints = ( geometry.type === 'Points' );
+				var hasVertexColors = false;
+
+				// Skip o/g line declarations that did not follow with any faces
+				if ( geometry.vertices.length === 0 ) continue;
+
+				var buffergeometry = new BufferGeometry();
+
+				buffergeometry.addAttribute( 'position', new Float32BufferAttribute( geometry.vertices, 3 ) );
+
+				if ( geometry.normals.length > 0 ) {
+
+					buffergeometry.addAttribute( 'normal', new Float32BufferAttribute( geometry.normals, 3 ) );
+
+				} else {
+
+					buffergeometry.computeVertexNormals();
+
+				}
+
+				if ( geometry.colors.length > 0 ) {
+
+					hasVertexColors = true;
+					buffergeometry.addAttribute( 'color', new Float32BufferAttribute( geometry.colors, 3 ) );
+
+				}
+
+				if ( geometry.uvs.length > 0 ) {
+
+					buffergeometry.addAttribute( 'uv', new Float32BufferAttribute( geometry.uvs, 2 ) );
+
+				}
+
+				// Create materials
+
+				var createdMaterials = [];
+
+				for ( var mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {
+
+					var sourceMaterial = materials[ mi ];
+					var material = undefined;
+
+					if ( this.materials !== null ) {
+
+						material = this.materials.create( sourceMaterial.name );
+
+						// mtl etc. loaders probably can't create line materials correctly, copy properties to a line material.
+						if ( isLine && material && ! ( material instanceof LineBasicMaterial ) ) {
+
+							var materialLine = new LineBasicMaterial();
+							Material.prototype.copy.call( materialLine, material );
+							materialLine.color.copy( material.color );
+							materialLine.lights = false;
+							material = materialLine;
+
+						} else if ( isPoints && material && ! ( material instanceof PointsMaterial ) ) {
+
+							var materialPoints = new PointsMaterial( { size: 10, sizeAttenuation: false } );
+							Material.prototype.copy.call( materialPoints, material );
+							materialPoints.color.copy( material.color );
+							materialPoints.map = material.map;
+							materialPoints.lights = false;
+							material = materialPoints;
+
+						}
+
+					}
+
+					if ( ! material ) {
+
+						if ( isLine ) {
+
+							material = new LineBasicMaterial();
+
+						} else if ( isPoints ) {
+
+							material = new PointsMaterial( { size: 1, sizeAttenuation: false } );
+
+						} else {
+
+							material = new MeshPhongMaterial();
+
+						}
+
+						material.name = sourceMaterial.name;
+
+					}
+
+					material.flatShading = sourceMaterial.smooth ? false : true;
+					material.vertexColors = hasVertexColors ? VertexColors : NoColors;
+
+					createdMaterials.push( material );
+
+				}
+
+				// Create mesh
+
+				var mesh;
+
+				if ( createdMaterials.length > 1 ) {
+
+					for ( var mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {
+
+						var sourceMaterial = materials[ mi ];
+						buffergeometry.addGroup( sourceMaterial.groupStart, sourceMaterial.groupCount, mi );
+
+					}
+
+					if ( isLine ) {
+
+						mesh = new LineSegments( buffergeometry, createdMaterials );
+
+					} else if ( isPoints ) {
+
+						mesh = new Points( buffergeometry, createdMaterials );
+
+					} else {
+
+						mesh = new Mesh( buffergeometry, createdMaterials );
+
+					}
+
+				} else {
+
+					if ( isLine ) {
+
+						mesh = new LineSegments( buffergeometry, createdMaterials[ 0 ] );
+
+					} else if ( isPoints ) {
+
+						mesh = new Points( buffergeometry, createdMaterials[ 0 ] );
+
+					} else {
+
+						mesh = new Mesh( buffergeometry, createdMaterials[ 0 ] );
+
+					}
+
+				}
+
+				mesh.name = object.name;
+
+				container.add( mesh );
+
+			}
+
+			console.timeEnd( 'OBJLoader' );
+
+			return container;
+
+		}
+
+	};
+
+	return OBJLoader;
+
+} )();
+
+//export { OBJLoader };
+ 

File diff ditekan karena terlalu besar
+ 1051 - 0
public/package/js/OrbitControl.js


File diff ditekan karena terlalu besar
+ 13 - 0
public/package/js/dat.gui.min.js


File diff ditekan karena terlalu besar
+ 4054 - 0
public/package/js/glTFLoader.js


File diff ditekan karena terlalu besar
+ 4 - 0
public/package/js/jquery-2.1.1.min.js


+ 111 - 0
public/package/js/label.js

@@ -0,0 +1,111 @@
+class Label2D extends THREE.EventDispatcher {
+    constructor(o = {}) {
+        super()
+        this.title = o.title
+        this.position = o.position
+        console.log(o);
+        this.elem = $(`<div class="room-label ${o.labeltype ? o.labeltype : ''} ${o.posi == 'right' ? 'right' : ''}" >
+        <a><p>
+        <span>${o.title}</span>
+        ${o.labeltype ? `
+        <div class="sline"></div>
+        <span class="enspan">${o.entitle}</span>` : ''}
+        </p></a>
+        
+        ${o.labeltype ? `<div class="picdetail">
+        <div class="header">
+          <span>岁寒三友</span>
+          <img src="images/video.png" alt="">
+        </div>
+        <div class="pinfo">
+          <img src="images/temp.jpg" alt="">
+          <p>南宋赵孟坚经历丧国的痛楚,把松竹梅在一起创作出《岁寒三友图》,借用“岁寒三友”来比喻自己为身处乱世不变其节的忠贞之士。</p>
+        </div>
+      </div>`: ''}
+        </div>`);
+
+        $(".widgets-doll-labels").append(this.elem)
+        this.pos2d = new THREE.Vector3
+
+        this.elem.css({ position: 'absolute', 'z-index': 999 })
+        this.clickFun = o.clickFun;
+        this.clickFun && this.elem.on('click', this.clickFun.bind(this))
+
+        {
+            let update = (e) => {
+                this.update()
+            }
+            viewer.addEventListener("view.changed", update) //确保player存在
+            this.addEventListener('dispose', (e) => { })
+        }
+        this.visible = true
+        this.shelterByModel = o.shelterByModel
+        this.update()
+    }
+
+
+
+
+
+    update() {
+        if (!this.position || !this.visible) return
+
+        var p = convertTool.getPos2d(this.position, viewer.camera, $("#player")[0]);
+        if (!p || !p.trueSide) {
+            this.elem.css('display', 'none'); return;
+        }
+
+        //判断label是否被模型遮挡,遮挡则消失(如果是漫游模式最好提前计算visiblePanos)
+
+        if (this.shelterByModel && convertTool.ifShelter(this.position, p.vector, viewer.camera, viewer.model.children, 0.05)) {
+            this.elem.css('display', 'none'); return;
+        }
+
+
+        this.elem.css({
+            left: p.pos.x + 'px',
+            top: p.pos.y + 'px'
+        })
+
+        /* if(settings.vrEnabled){
+            this.elem.css({transform:'rotate('+window.screenFaceOrient+'deg)'})
+        }else{
+            this.elem.css({transform:''})
+        } */
+
+        this.elem.css('display', 'block');
+        this.pos2d = p.vector;
+
+
+
+    }
+
+    setVisible(visi, reason, level = 0, type) {
+        convertTool.updateVisible(this, reason, visi, level, type)
+
+        if (!this.visible) {
+            this.elem.css('display', 'none');
+        } else {
+            this.update()
+        }
+    }
+
+    setTitle(title) {
+        this.title = title || ''
+        this.elem.html(`<a><p><span>${this.title}</span></p></a>`)
+    }
+    setPos(pos) {
+        this.position = pos;
+        this.update()
+    }
+
+    dispose() {
+        this.elem.remove();
+        this._listeners = {}
+        this.dispatchEvent({ type: 'dispose' })
+    }
+
+
+}
+
+

+ 486 - 0
public/package/js/objViewer.js

@@ -0,0 +1,486 @@
+
+let texLoader = new THREE.TextureLoader;
+
+
+
+let camera, scene, renderer, stats, gui;
+const mouse = new THREE.Vector2();
+const raycaster = new THREE.Raycaster(); raycaster.linePrecision = 0;//不检测boxHelper
+const Transitions = {
+    doubleClick: 0,
+    helperOpa: 1,
+}
+let labelIndex = 0
+
+
+
+
+var Viewer = function (index, dom) {
+    THREE.EventDispatcher.call(this)
+    this.index = index;
+    this.dom = dom
+    this.camera = new THREE.PerspectiveCamera();
+    this.camera.position.set(0, 0, 0.78);
+    this.control = new THREE.OrbitControls(this.camera, this.dom)
+    this.control.enableDamping = true;
+    this.control.dampingFactor = 0.4;
+    this.control.minDistance = 0.3;
+    this.control.maxDistance = 2;
+
+    this.control.enablePan = true;
+    this.control.enableZoom = true;
+
+    this.setRenderer()
+    this.scene = new THREE.Scene;
+
+    this.pointerDownPos
+    this.textures = [];
+    this.labels = []
+    this.active = false;
+    this.antialias = true;
+    this.clickTime = new Date().getTime();
+
+    this.updateClock = new THREE.Clock;
+    this.init()
+}
+
+Viewer.prototype = Object.create(THREE.EventDispatcher.prototype)
+Viewer.constructor = Viewer
+
+
+Viewer.prototype.bindEvents = function () {
+    this.renderer.domElement.addEventListener('pointerdown', this.onPointerDown.bind(this), false);
+    this.renderer.domElement.addEventListener('pointerup', this.onPointerUp.bind(this), false);
+}
+
+Viewer.prototype.setRenderer = function () {
+    try {
+
+        this.renderer = new THREE.WebGLRenderer(
+            {
+                canvas: $(this.dom).find("canvas")[0],
+                antialias: true,
+                alpha: true
+            }
+        ),//许钟文 添加个抗锯齿,否则添加的线条锯齿严重,
+
+            this.renderer.setClearAlpha(0);
+        //this.renderer.autoClear = !0,
+        this.renderer.setPixelRatio(window.devicePixelRatio ? window.devicePixelRatio : 1)
+        // this.renderer.autoClear = false
+        //this.emit(Events.ContextCreated) 
+
+
+    } catch (e) {
+        console.error("Unable to create a WebGL rendering context")
+    }
+}
+
+Viewer.prototype.update = function (deltaTime) {//绘制的时候同时更新 
+    //if(!this.active)return;
+    this.setSize()
+    this.control.update(deltaTime)
+    transitions.update(deltaTime)
+    var needsUpdate = 1;
+
+    if (needsUpdate) {
+        //this.renderer.autoClear = true
+        this.renderer.render(this.scene, this.camera)
+
+    }
+}
+
+
+
+Viewer.prototype.hasChanged = function () {//判断画面是否改变了,改变后需要更新一些东西
+    var copy = function () {
+        this.previousState = {
+            projectionMatrix: this.camera.projectionMatrix.clone(),//worldMatrix在control时归零了所以不用了吧,用position和qua也一样
+            position: this.camera.position.clone(),
+            quaternion: this.camera.quaternion.clone(),
+            //mouse: this.mouse.clone(), 
+            fov: this.camera.fov
+        };
+    }.bind(this)
+
+
+    if (!this.previousState) {
+        copy()
+        return { cameraChanged: !0, changed: !0 };
+    }
+    var cameraChanged =
+        !this.camera.projectionMatrix.equals(this.previousState.projectionMatrix) ||
+        !this.camera.position.equals(this.previousState.position) ||
+        !this.camera.quaternion.equals(this.previousState.quaternion)
+
+
+    var changed = cameraChanged //|| !this.mouse.equals(this.previousState.mouse)  
+
+    copy()
+
+    return { cameraChanged, changed };
+}
+
+Viewer.prototype.setSize = function () {
+    var w, h, pixelRatio;
+    return function () {
+        if (w != this.dom.clientWidth || h != this.dom.clientHeight || pixelRatio != window.devicePixelRatio) {
+            w = this.dom.clientWidth;
+            h = this.dom.clientHeight;
+
+            pixelRatio = window.devicePixelRatio;
+
+            this.camera.aspect = w / h;
+            this.camera.updateProjectionMatrix();
+            this.renderer.setSize(w, h, false, pixelRatio);
+        }
+    }
+}()
+
+Viewer.prototype.init = function () {
+    this.meshGroup = new THREE.Object3D();
+    this.scene.add(this.meshGroup);
+    this.meshGroup.name = "viewerMeshGroup";
+
+    var buildScene = () => {
+        this.animate()
+    }
+    this.loadOBJ(() => {
+        this.bindEvents()
+        //this.loadLabels()
+    })
+
+
+    buildScene()
+}
+
+
+
+Viewer.prototype.animate = function () {
+    var deltaTime = Math.min(1, this.updateClock.getDelta());
+    this.update(deltaTime)
+    //bus.emit('player/position/change', {x:this.position.x, y:this.position.z, lon: this.cameraControls.controls.panorama.lon})
+
+    let changed = this.hasChanged()
+    if (changed.cameraChanged) {
+        this.dispatchEvent({ type: 'view.changed' })
+
+        let label_ = this.labels.filter(e => e.elem[0].style.display == 'block')
+        label_.sort((a, b) => b.pos2d.z - a.pos2d.z)
+        label_.forEach((e, index) => e.elem.css('z-index', index + 1000));
+
+    }
+
+    window.requestAnimationFrame(this.animate.bind(this));
+},
+
+
+
+
+    Viewer.prototype.loadOBJ = function (done) {
+
+        var startTime = new Date().getTime();
+        window.objs = [];
+        var group = new THREE.Object3D;
+        this.meshGroup.add(group);
+
+        function onProgress(xhr) {
+            if (xhr.lengthComputable) {
+                var percentComplete = xhr.loaded / xhr.total * 100;
+                console.log('model ' + Math.round(percentComplete, 2) + '% downloaded');
+            }
+        }
+
+        function onError() { }
+
+        var MTLLoader = new THREE.MTLLoader();
+        var OBJLoader = new THREE.OBJLoader()
+
+
+        var loadModel = () => {
+            var info = {//凳子
+                path: 'model/',
+                mtl: 'wl48-he.mtl',
+                obj: 'wl48-he.obj',
+                position: [0, 0],
+                rotation: 0,
+                height: 1
+            };
+
+            if (!info) {
+                console.log("加载持续时间:" + (new Date().getTime() - startTime))
+                return;
+            }
+
+
+            MTLLoader.setPath(info.path).load(info.mtl, (materials) => {
+
+                materials.preload();
+
+                OBJLoader.setMaterials(materials)
+                    .setPath(info.path)
+                    .load(info.obj, (object) => {
+
+                        group.add(object);
+                        object.traverse(function (child) {
+                            if (child.isMesh) {
+                                console.log(child);
+                                // if (child.name == "WL48_ping") {
+                                //     let textrueLoader = new THREE.TextureLoader();
+                                //     var emissiveTexture = textrueLoader.load("model/shadow.jpg");
+                                //     // emissiveTexture.encoding = THREE.LinearEncoding;
+                                //     child.material.emissiveMap = emissiveTexture;
+                                //     child.material.emissiveIntensity = 0;
+                                //     // let step = 1
+                                //     // setInterval(() => {
+
+                                //     //     if (child.material.emissiveIntensity > 0.3) {
+                                //     //         step = -1
+
+                                //     //     }
+
+                                //     //     if (child.material.emissiveIntensity < 0) {
+                                //     //         step = 1
+                                //     //     }
+
+                                //     //     child.material.emissiveIntensity += 0.01 * step;
+
+                                //     // }, 50);
+                                //     child.material.emissive = new THREE.Color(0xffffff);
+                                // }
+                                /* if(child.geometry){
+                                    child.geometry.computeBoundingBox();
+                                    bound.union(child.geometry.boundingBox) 
+                                } */
+                            }
+                        });
+
+
+                        this.model = object
+                        let s = 0.010
+                        object.scale.set(s, s, s)
+
+                        done && done()
+                        console.log("加载持续时间:" + (new Date().getTime() - startTime))
+                        setTimeout(() => {
+                            this.dispatchEvent({ type: 'hadLoaded' })
+                        });
+                    }, onProgress, onError);
+            });
+        }
+
+        loadModel()
+
+        var light1 = new THREE.AmbientLight(16777215);
+        light1.intensity = 2.8;
+        this.scene.add(light1)
+
+        var light2 = new THREE.SpotLight(0xffffff, 1);
+        light2.position.set(0, 0, 3)
+        light2.intensity = 0.2;
+
+        var light3 = new THREE.SpotLight(0xffffff, 1);
+        light3.position.set(0, 0, -3)
+        light3.intensity = 0.4;
+
+
+        // let spotLightHelper = new THREE.SpotLightHelper(light2);
+        // let spotLightHelper3 = new THREE.SpotLightHelper(light3);
+        this.scene.add(light2)
+        this.scene.add(light3)
+        // this.scene.add( spotLightHelper );
+        // this.scene.add( spotLightHelper3 );
+
+    }
+
+
+
+
+Viewer.prototype.onPointerMove = function (event) {
+
+    if (event.isPrimary === false) return;
+
+    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
+    mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
+
+    if (!this.pointerDownPos) this.checkIntersection();
+
+}
+Viewer.prototype.onPointerDown = function (event) {
+    if (event.isPrimary === false) return;
+    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
+    mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
+    this.pointerDownPos = mouse.clone()
+}
+
+Viewer.prototype.onPointerUp = function (event) {
+
+    if (event.isPrimary === false) return;
+    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
+    mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
+    if (mouse.distanceTo(this.pointerDownPos) < 0.006) {//click
+        this.checkIntersection()
+
+        // if (this.intersects.length) {
+        //     console.log(this.intersects[0].point);
+        //     this.addLabel({ position: this.intersects[0].point })
+        // }
+
+        var time = new Date().getTime();
+        if (time - this.clickTime < 300) {
+            if (this.intersects.length) {
+                console.log('doubleClick');
+                transitions.cancelById(0)
+                transitions.start(lerp.vector(this.control.target, this.intersects[0].point), 600, null, 0/* Delay */, easing.easeInOutQuad, null, Transitions.doubleClick);
+            }
+        }
+        this.clickTime = time;
+    }
+    this.pointerDownPos = null
+}
+
+
+
+Viewer.prototype.checkIntersection = function () {
+
+    raycaster.setFromCamera(mouse, this.camera);
+
+    const intersects = raycaster.intersectObject(this.model/* this.meshGroup */, true);
+    this.intersects = intersects;
+}
+
+/* Viewer.prototype.adjustModelPos = function(){ //固定地板高度的情况下,调整模型的position.y
+     
+    this.meshGroup.updateMatrixWorld();
+    this.model.updateMatrixWorld();
+    var bound = this.model.bound.clone().applyMatrix4(this.model.matrixWorld)
+    var center = bound.getCenter() 
+    
+    
+    //为了让最低点在地面上:
+    this.meshGroup.position.y +=  floorY - bound.min.y
+    //居中:
+    this.meshGroup.position.x +=  0 - center.x
+    this.meshGroup.position.z +=  0 - center.z
+   
+     
+}  */
+
+
+Viewer.prototype.removeAllLabels = function (data) {
+    this.labels.forEach(label=>{
+        label.dispose()
+        label = null
+    })
+    this.labels = []
+}
+
+Viewer.prototype.loadLabelsFromData = function (data) {
+ 
+    data.forEach(info => {
+        info.position = new THREE.Vector3().fromArray(info.posInModel).applyMatrix4(this.model.matrixWorld)
+        this.addLabel(info)
+
+    })
+}
+
+Viewer.prototype.addLabel = function (o) {
+
+    labelIndex++
+    o.title = o.title || ('default' + labelIndex)
+    o.shelterByModel = true
+    let label = new Label2D(o)
+    this.labels.push(label)
+
+}
+
+Viewer.prototype.removeLabel = function (label) {
+    label.dispose()
+    let index = this.labels.indexOf(label)
+    index > -1 && this.labels.splice(index)
+    label.li.remove()
+}
+
+
+Viewer.prototype.setAddLabelState = function (state) {
+    this.addingLabel = !!state
+    $('#addLabel').text(state ? '停止加标签' : '添加标签')
+}
+
+
+
+Viewer.prototype.exportLabelData = function () {
+    let data = this.labels.map(label => {
+        let inv = new THREE.Matrix4().getInverse(this.model.matrixWorld)
+        let posInModel = label.position.clone().applyMatrix4(inv)
+
+        let info = {
+            title: label.title,
+            posInModel: convertTool.toPrecision(posInModel.toArray(), 4),
+
+        }
+        return info
+    })
+
+    $('textarea').css('display', 'block').text(JSON.stringify(data))
+    console.log(data)
+    return data
+}
+
+
+Viewer.prototype.getCLabel = function () { //获取最接近中心的label
+
+    let disSquairs = this.labels.filter(e => e.elem[0].style.display == 'block').map((label) => {
+        return {
+            label,
+            disSquair: label.pos2d.x * label.pos2d.x + label.pos2d.y * label.pos2d.y
+        }
+    })
+    disSquairs.sort((e1, e2) => { return e1.disSquair - e2.disSquair })
+    return disSquairs[0] && disSquairs[0].label
+}
+
+
+
+//============
+
+var startTime = new Date().getTime();
+
+function dataURLtoBlob(dataurl) {//将base64转换blob
+    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
+        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
+    while (n--) {
+        u8arr[n] = bstr.charCodeAt(n);
+    }
+    return new Blob([u8arr], { type: mime });
+}
+
+/* 
+
+    MeshStandardMaterial(pbr)代替Phong
+    优点 : 能量守恒、更容易调节出真实感。  metalnessMap只用到一个通道,颜色信息整合到albedo贴图里,省数据。
+    缺点:可能,mtl里的值只能用到一部分, specular用不到。 (会降低对specular的控制)
+        另外不知道大部分模型用的是哪种模式,是否使用metalnessMap。
+    
+    aoMap r
+    roughnessMap alphaMap g
+    metalnessMap b
+    
+    normalMap  ?
+    bumpMap : 黑白?
+
+主要是光滑度or粗糙度(可贴图)  还有 金属性(可贴图)  还有颜色(可贴图),透明度(in颜色贴图),法线贴图or凹凸贴图  
+    
+    
+    
+    贴图的属性 rotation  offset  repeat (当wrapS = THREE.RepeatWrapping,wrapT = THREE.RepeatWrapping)
+    
+    
+ */
+
+
+
+
+
+
+

File diff ditekan karena terlalu besar
+ 132 - 0
public/package/js/shaders.js


File diff ditekan karena terlalu besar
+ 47365 - 0
public/package/js/three95.min.js


+ 755 - 0
public/package/js/tweenjs.min.js

@@ -0,0 +1,755 @@
+/**
+ * Tween.js - Licensed under the MIT license
+ * https://github.com/sole/tween.js
+ * ----------------------------------------------
+ *
+ * See https://github.com/sole/tween.js/graphs/contributors for the full list of contributors.
+ * Thank you all, you're awesome!
+ */
+
+// Date.now shim for (ahem) Internet Explo(d|r)er
+if ( Date.now === undefined ) {
+
+	Date.now = function () {
+
+		return new Date().valueOf();
+
+	};
+
+}
+
+var TWEEN = TWEEN || ( function () {
+
+	var _tweens = [];
+
+	return {
+
+		REVISION: '14',
+
+		getAll: function () {
+
+			return _tweens;
+
+		},
+
+		removeAll: function () {
+
+			_tweens = [];
+
+		},
+
+		add: function ( tween ) {
+
+			_tweens.push( tween );
+
+		},
+
+		remove: function ( tween ) {
+
+			var i = _tweens.indexOf( tween );
+
+			if ( i !== -1 ) {
+
+				_tweens.splice( i, 1 );
+
+			}
+
+		},
+
+		update: function ( time ) {
+
+			if ( _tweens.length === 0 ) return false;
+
+			var i = 0;
+
+			time = time !== undefined ? time : ( typeof window !== 'undefined' && window.performance !== undefined && window.performance.now !== undefined ? window.performance.now() : Date.now() );
+
+			while ( i < _tweens.length ) {
+
+				if ( _tweens[ i ].update( time ) ) {
+
+					i++;
+
+				} else {
+
+					_tweens.splice( i, 1 );
+
+				}
+
+			}
+
+			return true;
+
+		}
+	};
+
+} )();
+
+TWEEN.Tween = function ( object ) {
+
+	var _object = object;
+	var _valuesStart = {};
+	var _valuesEnd = {};
+	var _valuesStartRepeat = {};
+	var _duration = 1000;
+	var _repeat = 0;
+	var _yoyo = false;
+	var _isPlaying = false;
+	var _reversed = false;
+	var _delayTime = 0;
+	var _startTime = null;
+	var _easingFunction = TWEEN.Easing.Linear.None;
+	var _interpolationFunction = TWEEN.Interpolation.Linear;
+	var _chainedTweens = [];
+	var _onStartCallback = null;
+	var _onStartCallbackFired = false;
+	var _onUpdateCallback = null;
+	var _onCompleteCallback = null;
+	var _onStopCallback = null;
+
+	// Set all starting values present on the target object
+	for ( var field in object ) {
+
+		_valuesStart[ field ] = parseFloat(object[field], 10);
+
+	}
+
+	this.to = function ( properties, duration ) {
+
+		if ( duration !== undefined ) {
+
+			_duration = duration;
+
+		}
+
+		_valuesEnd = properties;
+
+		return this;
+
+	};
+
+	this.start = function ( time ) {
+
+		TWEEN.add( this );
+
+		_isPlaying = true;
+
+		_onStartCallbackFired = false;
+
+		_startTime = time !== undefined ? time : ( typeof window !== 'undefined' && window.performance !== undefined && window.performance.now !== undefined ? window.performance.now() : Date.now() );
+		_startTime += _delayTime;
+
+		for ( var property in _valuesEnd ) {
+
+			// check if an Array was provided as property value
+			if ( _valuesEnd[ property ] instanceof Array ) {
+
+				if ( _valuesEnd[ property ].length === 0 ) {
+
+					continue;
+
+				}
+
+				// create a local copy of the Array with the start value at the front
+				_valuesEnd[ property ] = [ _object[ property ] ].concat( _valuesEnd[ property ] );
+
+			}
+
+			_valuesStart[ property ] = _object[ property ];
+
+			if( ( _valuesStart[ property ] instanceof Array ) === false ) {
+				_valuesStart[ property ] *= 1.0; // Ensures we're using numbers, not strings
+			}
+
+			_valuesStartRepeat[ property ] = _valuesStart[ property ] || 0;
+
+		}
+
+		return this;
+
+	};
+
+	this.stop = function () {
+
+		if ( !_isPlaying ) {
+			return this;
+		}
+
+		TWEEN.remove( this );
+		_isPlaying = false;
+
+		if ( _onStopCallback !== null ) {
+
+			_onStopCallback.call( _object );
+
+		}
+
+		this.stopChainedTweens();
+		return this;
+
+	};
+
+	this.stopChainedTweens = function () {
+
+		for ( var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++ ) {
+
+			_chainedTweens[ i ].stop();
+
+		}
+
+	};
+
+	this.delay = function ( amount ) {
+
+		_delayTime = amount;
+		return this;
+
+	};
+
+	this.repeat = function ( times ) {
+
+		_repeat = times;
+		return this;
+
+	};
+
+	this.yoyo = function( yoyo ) {
+
+		_yoyo = yoyo;
+		return this;
+
+	};
+
+
+	this.easing = function ( easing ) {
+
+		_easingFunction = easing;
+		return this;
+
+	};
+
+	this.interpolation = function ( interpolation ) {
+
+		_interpolationFunction = interpolation;
+		return this;
+
+	};
+
+	this.chain = function () {
+
+		_chainedTweens = arguments;
+		return this;
+
+	};
+
+	this.onStart = function ( callback ) {
+
+		_onStartCallback = callback;
+		return this;
+
+	};
+
+	this.onUpdate = function ( callback ) {
+
+		_onUpdateCallback = callback;
+		return this;
+
+	};
+
+	this.onComplete = function ( callback ) {
+
+		_onCompleteCallback = callback;
+		return this;
+
+	};
+
+	this.onStop = function ( callback ) {
+
+		_onStopCallback = callback;
+		return this;
+
+	};
+
+	this.update = function ( time ) {
+
+		var property;
+
+		if ( time < _startTime ) {
+
+			return true;
+
+		}
+
+		if ( _onStartCallbackFired === false ) {
+
+			if ( _onStartCallback !== null ) {
+
+				_onStartCallback.call( _object );
+
+			}
+
+			_onStartCallbackFired = true;
+
+		}
+
+		var elapsed = ( time - _startTime ) / _duration;
+		elapsed = elapsed > 1 ? 1 : elapsed;
+
+		var value = _easingFunction( elapsed );
+
+		for ( property in _valuesEnd ) {
+
+			var start = _valuesStart[ property ] || 0;
+			var end = _valuesEnd[ property ];
+
+			if ( end instanceof Array ) {
+
+				_object[ property ] = _interpolationFunction( end, value );
+
+			} else {
+
+				// Parses relative end values with start as base (e.g.: +10, -3)
+				if ( typeof(end) === "string" ) {
+					end = start + parseFloat(end, 10);
+				}
+
+				// protect against non numeric properties.
+				if ( typeof(end) === "number" ) {
+					_object[ property ] = start + ( end - start ) * value;
+				}
+
+			}
+
+		}
+
+		if ( _onUpdateCallback !== null ) {
+
+			_onUpdateCallback.call( _object, value );
+
+		}
+
+		if ( elapsed == 1 ) {
+
+			if ( _repeat > 0 ) {
+
+				if( isFinite( _repeat ) ) {
+					_repeat--;
+				}
+
+				// reassign starting values, restart by making startTime = now
+				for( property in _valuesStartRepeat ) {
+
+					if ( typeof( _valuesEnd[ property ] ) === "string" ) {
+						_valuesStartRepeat[ property ] = _valuesStartRepeat[ property ] + parseFloat(_valuesEnd[ property ], 10);
+					}
+
+					if (_yoyo) {
+						var tmp = _valuesStartRepeat[ property ];
+						_valuesStartRepeat[ property ] = _valuesEnd[ property ];
+						_valuesEnd[ property ] = tmp;
+					}
+
+					_valuesStart[ property ] = _valuesStartRepeat[ property ];
+
+				}
+
+				if (_yoyo) {
+					_reversed = !_reversed;
+				}
+
+				_startTime = time + _delayTime;
+
+				return true;
+
+			} else {
+
+				if ( _onCompleteCallback !== null ) {
+
+					_onCompleteCallback.call( _object );
+
+				}
+
+				for ( var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++ ) {
+
+					_chainedTweens[ i ].start( time );
+
+				}
+
+				return false;
+
+			}
+
+		}
+
+		return true;
+
+	};
+
+};
+
+
+TWEEN.Easing = {
+
+	Linear: {
+
+		None: function ( k ) {
+
+			return k;
+
+		}
+
+	},
+
+	Quadratic: {
+
+		In: function ( k ) {
+
+			return k * k;
+
+		},
+
+		Out: function ( k ) {
+
+			return k * ( 2 - k );
+
+		},
+
+		InOut: function ( k ) {
+
+			if ( ( k *= 2 ) < 1 ) return 0.5 * k * k;
+			return - 0.5 * ( --k * ( k - 2 ) - 1 );
+
+		}
+
+	},
+
+	Cubic: {
+
+		In: function ( k ) {
+
+			return k * k * k;
+
+		},
+
+		Out: function ( k ) {
+
+			return --k * k * k + 1;
+
+		},
+
+		InOut: function ( k ) {
+
+			if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k;
+			return 0.5 * ( ( k -= 2 ) * k * k + 2 );
+
+		}
+
+	},
+
+	Quartic: {
+
+		In: function ( k ) {
+
+			return k * k * k * k;
+
+		},
+
+		Out: function ( k ) {
+
+			return 1 - ( --k * k * k * k );
+
+		},
+
+		InOut: function ( k ) {
+
+			if ( ( k *= 2 ) < 1) return 0.5 * k * k * k * k;
+			return - 0.5 * ( ( k -= 2 ) * k * k * k - 2 );
+
+		}
+
+	},
+
+	Quintic: {
+
+		In: function ( k ) {
+
+			return k * k * k * k * k;
+
+		},
+
+		Out: function ( k ) {
+
+			return --k * k * k * k * k + 1;
+
+		},
+
+		InOut: function ( k ) {
+
+			if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k * k * k;
+			return 0.5 * ( ( k -= 2 ) * k * k * k * k + 2 );
+
+		}
+
+	},
+
+	Sinusoidal: {
+
+		In: function ( k ) {
+
+			return 1 - Math.cos( k * Math.PI / 2 );
+
+		},
+
+		Out: function ( k ) {
+
+			return Math.sin( k * Math.PI / 2 );
+
+		},
+
+		InOut: function ( k ) {
+
+			return 0.5 * ( 1 - Math.cos( Math.PI * k ) );
+
+		}
+
+	},
+
+	Exponential: {
+
+		In: function ( k ) {
+
+			return k === 0 ? 0 : Math.pow( 1024, k - 1 );
+
+		},
+
+		Out: function ( k ) {
+
+			return k === 1 ? 1 : 1 - Math.pow( 2, - 10 * k );
+
+		},
+
+		InOut: function ( k ) {
+
+			if ( k === 0 ) return 0;
+			if ( k === 1 ) return 1;
+			if ( ( k *= 2 ) < 1 ) return 0.5 * Math.pow( 1024, k - 1 );
+			return 0.5 * ( - Math.pow( 2, - 10 * ( k - 1 ) ) + 2 );
+
+		}
+
+	},
+
+	Circular: {
+
+		In: function ( k ) {
+
+			return 1 - Math.sqrt( 1 - k * k );
+
+		},
+
+		Out: function ( k ) {
+
+			return Math.sqrt( 1 - ( --k * k ) );
+
+		},
+
+		InOut: function ( k ) {
+
+			if ( ( k *= 2 ) < 1) return - 0.5 * ( Math.sqrt( 1 - k * k) - 1);
+			return 0.5 * ( Math.sqrt( 1 - ( k -= 2) * k) + 1);
+
+		}
+
+	},
+
+	Elastic: {
+
+		In: function ( k ) {
+
+			var s, a = 0.1, p = 0.4;
+			if ( k === 0 ) return 0;
+			if ( k === 1 ) return 1;
+			if ( !a || a < 1 ) { a = 1; s = p / 4; }
+			else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI );
+			return - ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) );
+
+		},
+
+		Out: function ( k ) {
+
+			var s, a = 0.1, p = 0.4;
+			if ( k === 0 ) return 0;
+			if ( k === 1 ) return 1;
+			if ( !a || a < 1 ) { a = 1; s = p / 4; }
+			else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI );
+			return ( a * Math.pow( 2, - 10 * k) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) + 1 );
+
+		},
+
+		InOut: function ( k ) {
+
+			var s, a = 0.1, p = 0.4;
+			if ( k === 0 ) return 0;
+			if ( k === 1 ) return 1;
+			if ( !a || a < 1 ) { a = 1; s = p / 4; }
+			else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI );
+			if ( ( k *= 2 ) < 1 ) return - 0.5 * ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) );
+			return a * Math.pow( 2, -10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) * 0.5 + 1;
+
+		}
+
+	},
+
+	Back: {
+
+		In: function ( k ) {
+
+			var s = 1.70158;
+			return k * k * ( ( s + 1 ) * k - s );
+
+		},
+
+		Out: function ( k ) {
+
+			var s = 1.70158;
+			return --k * k * ( ( s + 1 ) * k + s ) + 1;
+
+		},
+
+		InOut: function ( k ) {
+
+			var s = 1.70158 * 1.525;
+			if ( ( k *= 2 ) < 1 ) return 0.5 * ( k * k * ( ( s + 1 ) * k - s ) );
+			return 0.5 * ( ( k -= 2 ) * k * ( ( s + 1 ) * k + s ) + 2 );
+
+		}
+
+	},
+
+	Bounce: {
+
+		In: function ( k ) {
+
+			return 1 - TWEEN.Easing.Bounce.Out( 1 - k );
+
+		},
+
+		Out: function ( k ) {
+
+			if ( k < ( 1 / 2.75 ) ) {
+
+				return 7.5625 * k * k;
+
+			} else if ( k < ( 2 / 2.75 ) ) {
+
+				return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75;
+
+			} else if ( k < ( 2.5 / 2.75 ) ) {
+
+				return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375;
+
+			} else {
+
+				return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375;
+
+			}
+
+		},
+
+		InOut: function ( k ) {
+
+			if ( k < 0.5 ) return TWEEN.Easing.Bounce.In( k * 2 ) * 0.5;
+			return TWEEN.Easing.Bounce.Out( k * 2 - 1 ) * 0.5 + 0.5;
+
+		}
+
+	}
+
+};
+
+TWEEN.Interpolation = {
+
+	Linear: function ( v, k ) {
+
+		var m = v.length - 1, f = m * k, i = Math.floor( f ), fn = TWEEN.Interpolation.Utils.Linear;
+
+		if ( k < 0 ) return fn( v[ 0 ], v[ 1 ], f );
+		if ( k > 1 ) return fn( v[ m ], v[ m - 1 ], m - f );
+
+		return fn( v[ i ], v[ i + 1 > m ? m : i + 1 ], f - i );
+
+	},
+
+	Bezier: function ( v, k ) {
+
+		var b = 0, n = v.length - 1, pw = Math.pow, bn = TWEEN.Interpolation.Utils.Bernstein, i;
+
+		for ( i = 0; i <= n; i++ ) {
+			b += pw( 1 - k, n - i ) * pw( k, i ) * v[ i ] * bn( n, i );
+		}
+
+		return b;
+
+	},
+
+	CatmullRom: function ( v, k ) {
+
+		var m = v.length - 1, f = m * k, i = Math.floor( f ), fn = TWEEN.Interpolation.Utils.CatmullRom;
+
+		if ( v[ 0 ] === v[ m ] ) {
+
+			if ( k < 0 ) i = Math.floor( f = m * ( 1 + k ) );
+
+			return fn( v[ ( i - 1 + m ) % m ], v[ i ], v[ ( i + 1 ) % m ], v[ ( i + 2 ) % m ], f - i );
+
+		} else {
+
+			if ( k < 0 ) return v[ 0 ] - ( fn( v[ 0 ], v[ 0 ], v[ 1 ], v[ 1 ], -f ) - v[ 0 ] );
+			if ( k > 1 ) return v[ m ] - ( fn( v[ m ], v[ m ], v[ m - 1 ], v[ m - 1 ], f - m ) - v[ m ] );
+
+			return fn( v[ i ? i - 1 : 0 ], v[ i ], v[ m < i + 1 ? m : i + 1 ], v[ m < i + 2 ? m : i + 2 ], f - i );
+
+		}
+
+	},
+
+	Utils: {
+
+		Linear: function ( p0, p1, t ) {
+
+			return ( p1 - p0 ) * t + p0;
+
+		},
+
+		Bernstein: function ( n , i ) {
+
+			var fc = TWEEN.Interpolation.Utils.Factorial;
+			return fc( n ) / fc( i ) / fc( n - i );
+
+		},
+
+		Factorial: ( function () {
+
+			var a = [ 1 ];
+
+			return function ( n ) {
+
+				var s = 1, i;
+				if ( a[ n ] ) return a[ n ];
+				for ( i = n; i > 1; i-- ) s *= i;
+				return a[ n ] = s;
+
+			};
+
+		} )(),
+
+		CatmullRom: function ( p0, p1, p2, p3, t ) {
+
+			var v0 = ( p2 - p0 ) * 0.5, v1 = ( p3 - p1 ) * 0.5, t2 = t * t, t3 = t * t2;
+			return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;
+
+		}
+
+	}
+
+};

+ 503 - 0
public/package/js/utils.js

@@ -0,0 +1,503 @@
+var lerp = {
+    vector: function (e, t, f) {//xzw change, add f
+        var i = e.clone();
+        return t = t.clone(),
+            function (n) {
+                e.set(i.x * (1 - n) + t.x * n, i.y * (1 - n) + t.y * n, i.z * (1 - n) + t.z * n)
+                f && f(e, n);
+            }
+    },
+    quaternion: function (e, t, f) {//xzw change, add f
+        var i = e.clone();
+        return function (n) {
+            e.copy(i).slerp(t, n);
+            f && f(e, n);
+        }
+    },
+    property: function (e, t, i, n) {
+        var r = e[t];
+        return function (o) {
+            e[t] = r * (1 - o) + i * o,
+                n && n(e[t])
+        }
+    },
+    uniform: function (e, t, i) {
+        var n = e.material.uniforms[t].value;
+        return function (r) {
+            try {
+                e.material.uniforms[t] && (e.material.uniforms[t].value = n * (1 - r) + i * r)
+            } catch (e) {
+                console.log(1)
+            }
+
+        }
+    },
+    matrix4: function (e, t) {
+        var i = e.clone();
+        return function (n) {
+            for (var r = e.elements, o = i.elements, a = t.elements, s = 0; s < 16; s++)
+                r[s] = o[s] * (1 - n) + a[s] * n
+        }
+    },
+    allUniforms: function (e, t, i) {
+        var n = e.map(function (e) {
+            return this.uniform(e, t, i)
+        }
+            .bind(this));
+        return function (e) {
+            n.forEach(function (t) {
+                t(e)
+            })
+        }
+    }
+};
+
+
+//////
+
+var easing = {};
+//渐变曲线函数,反应加速度的变化
+easing.linearTween = function (e, t, i, n) {
+    return i * e / n + t
+}
+    ,
+    easing.easeInQuad = function (e, t, i, n) {
+        return e /= n,
+            i * e * e + t
+    }
+    ,
+    easing.easeOutQuad = function (e, t, i, n) {
+        return e /= n,
+            -i * e * (e - 2) + t
+    }
+    ,
+    easing.easeInOutQuad = function (e, t, i, n) {
+        return e /= n / 2,
+            e < 1 ? i / 2 * e * e + t : (e--,
+                -i / 2 * (e * (e - 2) - 1) + t)
+    }
+    ,
+    easing.easeInCubic = function (e, t, i, n) {
+        return e /= n,
+            i * e * e * e + t
+    }
+    ,
+    easing.easeOutCubic = function (e, t, i, n) {
+        return e /= n,
+            e--,
+            i * (e * e * e + 1) + t
+    }
+    ,
+    easing.easeInOutCubic = function (e, t, i, n) {
+        return e /= n / 2,
+            e < 1 ? i / 2 * e * e * e + t : (e -= 2,
+                i / 2 * (e * e * e + 2) + t)
+    }
+    ,
+    easing.easeInQuart = function (e, t, i, n) {
+        return e /= n,
+            i * e * e * e * e + t
+    }
+    ,
+    easing.easeOutQuart = function (e, t, i, n) {
+        return e /= n,
+            e--,
+            -i * (e * e * e * e - 1) + t
+    }
+    ,
+    easing.easeInOutQuart = function (e, t, i, n) {
+        return e /= n / 2,
+            e < 1 ? i / 2 * e * e * e * e + t : (e -= 2,
+                -i / 2 * (e * e * e * e - 2) + t)
+    }
+    ,
+    easing.easeInQuint = function (e, t, i, n) {
+        return e /= n,
+            i * e * e * e * e * e + t
+    }
+    ,
+    easing.easeOutQuint = function (e, t, i, n) {
+        return e /= n,
+            e--,
+            i * (e * e * e * e * e + 1) + t
+    }
+    ,
+    easing.easeInOutQuint = function (e, t, i, n) {
+        return e /= n / 2,
+            e < 1 ? i / 2 * e * e * e * e * e + t : (e -= 2,
+                i / 2 * (e * e * e * e * e + 2) + t)
+    }
+    ,
+    easing.easeInSine = function (e, t, i, n) {
+        return -i * Math.cos(e / n * (Math.PI / 2)) + i + t
+    }
+    ,
+    easing.easeOutSine = function (e, t, i, n) {
+        return i * Math.sin(e / n * (Math.PI / 2)) + t
+    }
+    ,
+    easing.easeInOutSine = function (e, t, i, n) {
+        return -i / 2 * (Math.cos(Math.PI * e / n) - 1) + t
+    }
+    ,
+    easing.easeInExpo = function (e, t, i, n) {
+        return i * Math.pow(2, 10 * (e / n - 1)) + t
+    }
+    ,
+    easing.easeOutExpo = function (e, t, i, n) {
+        return i * (-Math.pow(2, -10 * e / n) + 1) + t
+    }
+    ,
+    easing.easeInOutExpo = function (e, t, i, n) {
+        return e /= n / 2,
+            e < 1 ? i / 2 * Math.pow(2, 10 * (e - 1)) + t : (e--,
+                i / 2 * (-Math.pow(2, -10 * e) + 2) + t)
+    }
+    ,
+    easing.easeInCirc = function (e, t, i, n) {
+        return e /= n,
+            -i * (Math.sqrt(1 - e * e) - 1) + t
+    }
+    ,
+    easing.easeOutCirc = function (e, t, i, n) {
+        return e /= n,
+            e--,
+            i * Math.sqrt(1 - e * e) + t
+    }
+    ,
+    easing.easeInOutCirc = function (e, t, i, n) {
+        return e /= n / 2,
+            e < 1 ? -i / 2 * (Math.sqrt(1 - e * e) - 1) + t : (e -= 2,
+                i / 2 * (Math.sqrt(1 - e * e) + 1) + t)
+    }
+    ,
+    easing.easeInElastic = function (e, t, i, n) {
+        var r = 1.70158
+            , o = 0
+            , a = i;
+        return 0 === e ? t : 1 === (e /= n) ? t + i : (o || (o = .3 * n),
+            a < Math.abs(i) ? (a = i,
+                r = o / 4) : r = o / (2 * Math.PI) * Math.asin(i / a),
+            -(a * Math.pow(2, 10 * (e -= 1)) * Math.sin((e * n - r) * (2 * Math.PI) / o)) + t)
+    }
+    ,
+    easing.easeOutElastic = function (e, t, i, n) {
+        var r = 1.70158
+            , o = 0
+            , a = i;
+        return 0 === e ? t : 1 === (e /= n) ? t + i : (o || (o = .3 * n),
+            a < Math.abs(i) ? (a = i,
+                r = o / 4) : r = o / (2 * Math.PI) * Math.asin(i / a),
+            a * Math.pow(2, -10 * e) * Math.sin((e * n - r) * (2 * Math.PI) / o) + i + t)
+    }
+    ,
+    easing.easeInOutElastic = function (e, t, i, n) {
+        var r = 1.70158
+            , o = 0
+            , a = i;
+        return 0 === e ? t : 2 === (e /= n / 2) ? t + i : (o || (o = n * (.3 * 1.5)),
+            a < Math.abs(i) ? (a = i,
+                r = o / 4) : r = o / (2 * Math.PI) * Math.asin(i / a),
+            e < 1 ? -.5 * (a * Math.pow(2, 10 * (e -= 1)) * Math.sin((e * n - r) * (2 * Math.PI) / o)) + t : a * Math.pow(2, -10 * (e -= 1)) * Math.sin((e * n - r) * (2 * Math.PI) / o) * .5 + i + t)
+    }
+    ,
+    easing.easeInBack = function (e, t, i, n, r) {
+        return void 0 === r && (r = 1.70158),
+            i * (e /= n) * e * ((r + 1) * e - r) + t
+    }
+    ,
+    easing.easeOutBack = function (e, t, i, n, r) {
+        return void 0 === r && (r = 1.70158),
+            i * ((e = e / n - 1) * e * ((r + 1) * e + r) + 1) + t
+    }
+    ,
+    easing.easeInOutBack = function (e, t, i, n, r) {
+        return void 0 === r && (r = 1.70158),
+            (e /= n / 2) < 1 ? i / 2 * (e * e * (((r *= 1.525) + 1) * e - r)) + t : i / 2 * ((e -= 2) * e * (((r *= 1.525) + 1) * e + r) + 2) + t
+    }
+    ,
+    easing.easeOutBounce = function (e, t, i, n) {
+        return (e /= n) < 1 / 2.75 ? i * (7.5625 * e * e) + t : e < 2 / 2.75 ? i * (7.5625 * (e -= 1.5 / 2.75) * e + .75) + t : e < 2.5 / 2.75 ? i * (7.5625 * (e -= 2.25 / 2.75) * e + .9375) + t : i * (7.5625 * (e -= 2.625 / 2.75) * e + .984375) + t
+    }
+    ,
+    easing.easeInBounce = function (e, t, i, r) {
+        return i - easing.easeOutBounce(r - e, 0, i, r) + t
+    }
+    ,
+    easing.easeInOutBounce = function (e, t, i, r) {
+        return e < r / 2 ? .5 * easing.easeInBounce(2 * e, 0, i, r) + t : .5 * easing.easeOutBounce(x, 2 * e - r, 0, i, r) + .5 * i + t
+    }
+
+
+
+
+
+/* 
+    渐变
+    
+
+ */
+
+var transitions = {
+    globalDone: null,
+    funcs: [],
+    counter: 0,
+    uniqueID: 0,
+    start: function (e, t, i, r, o, a, s, cancelFun) {
+        return r = r || 0,
+            this.funcs.push({
+                func: e,
+                current: -r * Math.abs(t),                      //当前时间
+                duration: (1 - Math.max(r, 0)) * Math.abs(t),   //总时长
+                done: i,
+                easing: o || easing.linearTween,                //渐变曲线
+                cycling: t < 0,
+                running: !0,
+                debug: r < 0,
+                name: a || "T" + this.counter,
+                id: void 0 === s ? this.counter : s,
+                paused: !1,
+                cancelFun: cancelFun,   //取消时执行的函数
+            }),
+            e(0, 16),
+            this.counter += 1,
+            e
+    },
+    trigger: function (e) {
+        var t = void 0 === e.delayRatio ? 0 : e.delayRatio
+            , i = e.func || function () { }
+            , r = void 0 === e.duration ? 0 : e.duration;
+        void 0 !== e.cycling && e.cycling && (r = -Math.abs(r));
+        var o = e.done || null
+            , a = e.easing || easing.linearTween
+            , s = e.name || "R" + this.counter
+            , l = void 0 === e.id ? this.counter : e.id;
+        return this.start(i, r, o, t, a, s, l)
+    },
+    setTimeout: function (e, t, i) {
+        var n = void 0 === i ? this.counter : i;
+        return this.trigger({
+            done: e,
+            duration: void 0 === t ? 0 : t,
+            name: "O" + this.counter,
+            id: n
+        })
+    },
+    pause: function () {
+        this.paused = !0
+    },
+    resume: function () {
+        this.paused = !1
+    },
+    update: function (e) {
+        this.funcs.forEach(function (t) {
+            if (!(t.paused || (t.current += 1e3 * e,
+                t.current < 0)))
+                if (t.current >= t.duration && !t.cycling) {
+                    var i = t.easing(1, 0, 1, 1);
+                    t.func(i, 1e3 * e),
+                        t.done && t.done(),
+                        t.running = !1
+                } else {
+                    var n = t.easing(t.current % t.duration / t.duration, 0, 1, 1)
+                        , r = t.func(n, 1e3 * e) || !1;
+                    r && (t.done && t.done(),
+                        t.running = !1)
+                }
+        });
+        var t = this.funcs.length;
+        this.funcs = this.funcs.filter(function (e) {
+            return e.running
+        });
+        var i = this.funcs.length;
+        if (t > 0 && 0 === i && this.globalDone) {
+            var n = this.globalDone;
+            this.globalDone = null,
+                n()
+        }
+    },
+    adjustSpeed: function (e, t) {
+        for (var i = this.getById(e), n = 0; n < i.length; n++) {
+            var r = i[n];
+            r.duration /= t,
+                r.current /= t
+        }
+    },
+    getById: function (e) {
+        return this.funcs.filter(function (t) {
+            return e === t.id
+        })
+    },
+    get: function (e) {
+        for (var t = 0; t < this.funcs.length; t += 1)
+            if (this.funcs[t].func === e)
+                return this.funcs[t];
+        return null
+    },
+    isRunning: function (e) {
+        var t = this.get(e);
+        return null !== t && t.running
+    },
+    countActive: function () {
+        for (var e = 0, t = 0; t < this.funcs.length; t += 1)
+            e += this.funcs[t].running;
+        return e
+    },
+    listActive: function () {
+        for (var e = [], t = 0; t < this.funcs.length; t += 1)
+            this.funcs[t].running && e.push(this.funcs[t].name);
+        return e
+    },
+    done: function (e) {
+        this.globalDone = e
+    },
+    cancelById: function (e, dealCancelFun) { //xzw add dealDone
+        var t = void 0 === e ? 0 : e;
+
+        this.funcs = this.funcs.filter(function (e) {
+            var is = e.id == t;
+
+            if (is && dealCancelFun) {
+                e.cancelFun && e.cancelFun()
+            }
+            return !is
+        })
+    },
+    cancel: function (e) {
+        this.funcs = this.funcs.filter(function (t) {
+            return t.func !== e
+        })
+    },
+    getUniqueId: function () {
+        return this.uniqueID -= 1,
+            this.uniqueID
+    }
+};
+
+
+let convertTool = {
+
+    getPos2d: function (point, camera, dom) {//获取一个三维坐标对应屏幕中的二维坐标
+
+
+
+        if (!camera) return
+        var pos = point.clone().project(camera)	//比之前hotspot的计算方式写得简单  project用于3转2(求法同shader); unproject用于2转3 :new r.Vector3(e.x, e.y, -1).unproject(this.camera);
+
+        var x, y;
+        x = (pos.x + 1) / 2 * dom.clientWidth;
+        y = (1 - (pos.y + 1) / 2) * dom.clientHeight;
+
+        var inSight = x <= dom.clientWidth && x >= 0    //是否在屏幕中   
+            && y <= dom.clientHeight && y >= 0
+
+
+        return {
+            pos: new THREE.Vector2(x, y),  // 屏幕像素坐标
+            vector: pos,   //(范围 -1 ~ 1)
+            trueSide: pos.z < 1, //trueSide为false时,即使在屏幕范围内可见,也是反方向的另一个不可以被渲染的点   参见Tag.update
+            inSight: inSight	//在屏幕范围内可见
+        };
+    },
+
+    ifShelter: function (pos3d, pos2d, camera, colliders, margin = 0) {
+        //检测某点在视线中是否被mesh遮挡
+        if (!pos2d) pos2d = convertTool.getPos2d(pos3d)
+        camera = camera || player.camera
+        var ori = new THREE.Vector3(pos2d.x, pos2d.y, -1).unproject(camera) //找到视线原点
+        var dir = pos3d.clone().sub(ori).normalize()
+        var ray = new THREE.Raycaster(ori, dir); //由外向里 因为模型从内侧是可见的所以从外侧
+        var o = ray.intersectObjects(colliders);
+
+        var len = pos3d.distanceTo(ori);
+        if (o && o.length) {
+            for (var i = 0; i < o.length; i++) {
+                if (o[i].distance < len - margin) { return true; }//有遮挡
+            }
+        }
+    },
+
+    updateVisible: function (object, reason, ifShow, level = 0, type) {//当所有加入的条件都不为false时才显示. reason='force'一般是强制、临时的
+        if (!object.unvisibleReasons) object.unvisibleReasons = []; //如果length>0代表不可见
+        if (!object.visibleReasons) object.visibleReasons = []; //在同级时,优先可见
+
+
+        var update = function () {
+
+            //先按从高到低的level排列
+            object.unvisibleReasons = object.unvisibleReasons.sort((a, b) => b.level - a.level)
+            object.visibleReasons = object.visibleReasons.sort((a, b) => b.level - a.level)
+            var maxVisiLevel = object.visibleReasons[0] ? object.visibleReasons[0].level : -1
+            var maxunVisiLevel = object.unvisibleReasons[0] ? object.unvisibleReasons[0].level : -1
+
+            var shouldVisi = maxVisiLevel >= maxunVisiLevel
+            var visiBefore = object.visible
+
+
+            if (visiBefore != shouldVisi) {
+                object.visible = shouldVisi
+                object.dispatchEvent({
+                    type: 'isVisible',
+                    visible: shouldVisi,
+                    reason,
+                })
+            }
+
+
+        }
+
+
+
+        if (ifShow) {
+
+            var index = object.unvisibleReasons.findIndex(e => e.reason == reason)
+            if (index > -1) {
+                type = 'cancel'
+                object.unvisibleReasons.splice(index, 1);
+            }
+
+            if (type == 'add') {
+                if (!object.visibleReasons.some(e => e.reason == reason)) {
+                    object.visibleReasons.push({ reason, level })
+                }
+            }
+        } else {
+            var index = object.visibleReasons.findIndex(e => e.reason == reason)
+            if (index > -1) {
+                type = 'cancel'
+                object.visibleReasons.splice(index, 1);
+            }
+
+            if (type != 'cancel') {
+                if (!object.unvisibleReasons.some(e => e.reason == reason)) {
+                    object.unvisibleReasons.push({ reason, level })
+                }
+            }
+        }
+
+        update()
+
+    },
+
+
+    toPrecision: function (e, t) {//xzw change 保留小数
+        var f = function (e, t) {
+            var i = Math.pow(10, t);
+            return Math.round(e * i) / i
+        }
+        if (e instanceof Array) {
+            for (var s = 0; s < e.length; s++) {
+                e[s] = f(e[s], t);
+            }
+            return e;
+        } else if (e instanceof Object) {
+            for (var s in e) {
+                e[s] = f(e[s], t);
+            }
+            return e;
+        } else return f(e, t)
+    },
+
+
+
+}

File diff ditekan karena terlalu besar
+ 1 - 0
public/package/jweixin-1.6.0.js


File diff ditekan karena terlalu besar
+ 13 - 0
public/package/swiper-bundle.min.css


File diff ditekan karena terlalu besar
+ 14 - 0
public/package/swiper-bundle.min.js


+ 49 - 0
src/App.vue

@@ -0,0 +1,49 @@
+<template>
+  <Home_pc />
+
+</template>
+
+<script>
+import Home_pc from "@/views/Home_pc.vue";
+// import Home_pc from "@/views/Home.vue";
+
+export default {
+  components: { Home_pc },
+  watch: {
+    g_isLandscape: {
+      immediate: true,
+      handler: function(newVal) {
+        if (this.isMobile) {
+        !newVal ? this.$showOrientationtip({ isLandscape: false }) : this.$hideOrientationtip();
+        }
+      },
+    },
+  },
+
+};
+</script>
+
+<style lang="less">
+html,
+body {
+  width: 100%;
+  height: 100%;
+}
+html {
+  background-color: #70474D;
+  background-repeat: repeat;
+  overflow: hidden;
+}
+
+* {
+  padding: 0;
+  box-sizing: border-box;
+  margin: 0;
+  -webkit-tap-highlight-color: rgba(255,255,255,0);
+   touch-action: pan-y;
+   user-select: none;
+}
+li{
+  list-style: none;
+}
+</style>

TEMPAT SAMPAH
src/assets/images/close.png


TEMPAT SAMPAH
src/assets/images/fanzhuan.png


TEMPAT SAMPAH
src/assets/images/icon/collection.png


TEMPAT SAMPAH
src/assets/images/icon/collection_active.png


TEMPAT SAMPAH
src/assets/images/icon/history.png


TEMPAT SAMPAH
src/assets/images/icon/history_active.png


TEMPAT SAMPAH
src/assets/images/icon/info.png


TEMPAT SAMPAH
src/assets/images/icon/info_active.png


TEMPAT SAMPAH
src/assets/images/icon/pic.png


TEMPAT SAMPAH
src/assets/images/icon/pic_active.png


TEMPAT SAMPAH
src/assets/images/icon/point.png


TEMPAT SAMPAH
src/assets/images/icon/point_active.png


TEMPAT SAMPAH
src/assets/images/info_bg.png


TEMPAT SAMPAH
src/assets/images/logo.png


TEMPAT SAMPAH
src/assets/images/point.png


+ 6 - 0
src/assets/images/point.svg

@@ -0,0 +1,6 @@
+<svg width="40" height="39" viewBox="0 0 40 39" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="point">
+<circle id="Ellipse 10" cx="20" cy="19.5" r="19" stroke="#A99979"/>
+<circle id="Ellipse 11" cx="20" cy="19.5" r="14.5" fill="#A99979"/>
+</g>
+</svg>

TEMPAT SAMPAH
src/assets/images/point_active.png


+ 6 - 0
src/assets/images/point_active.svg

@@ -0,0 +1,6 @@
+<svg width="40" height="39" viewBox="0 0 40 39" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="point">
+<circle id="Ellipse 10" cx="20" cy="19.5" r="19" stroke="white"/>
+<circle id="Ellipse 11" cx="20" cy="19.5" r="14.5" fill="white"/>
+</g>
+</svg>

TEMPAT SAMPAH
src/assets/images/pop.png


TEMPAT SAMPAH
src/assets/images/tab.png


File diff ditekan karena terlalu besar
+ 6 - 0
src/assets/images/tab.svg


TEMPAT SAMPAH
src/assets/images/temp.jpg


TEMPAT SAMPAH
src/assets/images/title.png


TEMPAT SAMPAH
src/assets/images/video.png


+ 61 - 0
src/components/introduce.vue

@@ -0,0 +1,61 @@
+<template>
+  <div class="infocon">
+    <div class="itrcon">
+      <div class="title">
+        <span>简介</span>
+      </div>
+      <div class="introduce" @click.stop>
+        梅瓶是古代瓷器中一种兼具使用和观赏功能的用具,小口、短颈、丰肩、肩以下逐渐收敛,体型修长亭亭玉立。它流行于宋、元、明、清。
+      </div>
+    </div>
+
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {};
+  },
+  mounted() {
+  
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.infocon {
+  .itrcon {
+    position: absolute;
+    top: 26%;
+    left: 10%;
+    width: 312px;
+    z-index: 99999;
+    color: #fff;
+
+    .title {
+      font-size: 30px;
+      width: 100%;
+      font-weight: bolder;
+      font-family: SimSun;
+      padding-bottom: 18px;
+    }
+
+    .introduce {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      border-top: 1px dashed rgba(169, 153, 121, .5);
+      width: 100%;
+      padding-top: 18px;
+      color: rgba(255, 255, 255, 0.8);
+      font-family: SimSun;
+      line-height: 2;
+      text-align: justify;
+    }
+  }
+
+
+}
+</style>
+

+ 72 - 0
src/components/loading.vue

@@ -0,0 +1,72 @@
+<template>
+  <div class="loadcon">
+    <div class="loading">
+      <img :src="require(`@/assets/images/logo.png`)" alt="" />
+      <div class="progress">
+        <div class="bar" :style="'width:' + barWidth + '%'"></div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  props: ["barWidth"],
+  data() {
+    console.log(this.barWidth);
+    return {};
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.loadcon {
+  background-color: #70474D;
+  background-repeat: repeat;
+  background-size: cover;
+  position: absolute;
+  top: 0;
+  left: 0;
+  z-index: 999999;
+  width: 100%;
+  height: 100%;
+  pointer-events: none;
+}
+.loading {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  width: 240px;
+  transform: translate(-50%, -50%);
+  text-align: center;
+  .progress {
+    width: 100%;
+    border-radius: 4px;
+    height: 8px;
+    border: 1px solid #a99979;
+    margin-top: 40px;
+    font-size: 0;
+    position: relative;
+  }
+
+  .bar {
+    height: 100%;
+    position: absolute;
+    border-radius: 4px;
+    left: -1px;
+    top: 0;
+    line-height: 1;
+    background: #a99979;
+  }
+  > img {
+    width: 60%;
+  }
+}
+
+@media screen and (max-width: 600px) {
+   .loading{
+    width: 50%;
+   }
+}
+
+</style>

+ 146 - 0
src/components/menu.vue

@@ -0,0 +1,146 @@
+<template>
+  <ul class="menu" :class="currentid">
+    <li :class="{active:currentid == item.id}" @click="onclick(item)" v-for="(item, i) in list" :key="i">
+      <img :src="
+        require(`@/assets/images/icon/${item.id+(currentid==item.id?'_active':'')}.png`)
+      " alt="" />
+      <p>{{item.name}}</p>
+    </li>
+  </ul>
+</template>
+
+<script>
+
+export default {
+  props: ["canMove", "canControls"],
+  data() {
+    return {
+      currentid: "",
+      list: [
+        {
+          id: "history",
+          name: "考古",
+        },
+        {
+          id: "info",
+          name: "简介",
+        },
+        {
+          id: "pic",
+          name: "纹饰",
+        },
+        {
+          id: "collection",
+          name: "关联文物",
+        }
+      ],
+    };
+  },
+  methods: {
+    onclick(item) {
+      if (this.currentid == item.id) {
+        return 
+      }
+      this.$emit("clickItem", item);
+      this.currentid = item.id;
+    },
+  },
+  mounted() {
+    this.$bus.$on("resetcurrent", () => {
+      this.currentid = "";
+    });
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.menu {
+  position: fixed;
+  left: 42px;
+  bottom: 20px;
+  z-index: 9999;
+  display: flex;
+  justify-content: center;
+  transition: 0.3s ease all;
+
+  >li {
+    list-style: none;
+    position: relative;
+    width: 80px;
+    display: inline-block;
+    margin: 0 10px;
+    text-align: center;
+    cursor: pointer;
+    color: #fff;
+    opacity: 0.7;
+
+    >p {
+      font-size: 14px;
+    }
+
+    &.active,
+    &:hover {
+      opacity: 1;
+    }
+  }
+}
+
+
+@media screen and (max-width: 1000px) {
+  .menu {
+    left: 6%;
+    pointer-events: auto;
+    transition: 0s ease all;
+
+    >li {
+      width: 6vw;
+      margin: 0 5px;
+      pointer-events: auto;
+
+      >img {
+        width: 100%;
+      }
+    }
+  }
+
+  .ming,
+  .sheng,
+  .yue,
+  .zhi {
+    top: 50%;
+    flex-direction: column;
+    margin: 5px 0;
+    left: 6%;
+
+    >li {
+      margin: 5px 0;
+    }
+  }
+}
+
+@keyframes fadeIn {
+  0% {
+    opacity: 0;
+  }
+
+  100% {
+    opacity: 1;
+    pointer-events: auto;
+  }
+}
+
+@keyframes fadeInOut {
+  0% {
+    opacity: 0;
+  }
+
+  50% {
+    opacity: 1;
+  }
+
+  100% {
+    opacity: 0;
+    pointer-events: none;
+  }
+}
+</style>

+ 27 - 0
src/components/verticaltip/build.js

@@ -0,0 +1,27 @@
+import Vue from "vue";
+import UIOrientationtip from "./index.vue";
+
+let Orientationtip = Vue.extend(UIOrientationtip);
+
+var orientationtipInstance = "";
+export function $showOrientationtip(data = {}) {
+  if (orientationtipInstance) {
+    return;
+  }
+  orientationtipInstance = new Orientationtip({
+    data,
+  }).$mount();
+
+  document.body.appendChild(orientationtipInstance.$el);
+
+  Vue.nextTick(() => {
+    orientationtipInstance.show = true;
+  });
+}
+
+export function $hideOrientationtip() {
+  if (orientationtipInstance) {
+    document.body.removeChild(orientationtipInstance.$el);
+    orientationtipInstance = "";
+  }
+}

+ 64 - 0
src/components/verticaltip/index.vue

@@ -0,0 +1,64 @@
+<template>
+  <div class="orientation-tip" >
+    <div>
+      <img :src="require('@/assets/images/fanzhuan.png')" alt="">
+      <p>请将手机旋转为横屏观看</p>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      show: true,
+      hideClose: false,
+      isLandscape: false,
+      isTip: false,
+    };
+  },
+  methods: {
+    close() {
+      this.$hideOrientationtip();
+    },
+  },
+ 
+};
+</script>
+
+<style lang="less" scoped>
+/*横屏体验*/
+.orientation-tip {
+  width: 100%;
+  height: 100%;
+  z-index: 1000000;
+  position: fixed;
+  top: 0;
+  left: 0;
+  backdrop-filter: blur(5px);
+  background-color: #70474D;
+  background-repeat: no-repeat;
+  background-size: cover;
+  > div {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    transform: translate(-50%, -50%);
+    text-align: center;
+    width: 80%;
+    > img {
+      width: 100%;
+    }
+    >p{
+      font-size: 16px;
+      color: #ac5b5b;
+      margin-top: 20px;
+    }
+  }
+}
+
+.isTip {
+  background: none;
+  backdrop-filter: none;
+}
+</style>

+ 93 - 0
src/kit/Label.js

@@ -0,0 +1,93 @@
+import * as THREE from "three";
+import convertTool from "@/utils";
+
+let labels = []
+
+class Label2D {
+  constructor(o = {}) {
+    this.position = o.position
+    this.elem = window.$(o.innerHTML || '<div ><a></a></div>');
+
+    window.$(o.domElement).append(this.elem)
+    this.pos2d = new THREE.Vector3
+
+    this.elem.css({ position: 'absolute', 'z-index': 999 })
+    this.clickFun = o.clickFun;
+    this.clickFun && this.elem.on('click', this.clickFun.bind(this))
+
+
+    this.visible = true
+    this.camera = o.camera
+    this.domElement = o.domElement
+    this.modelobj = o.modelobj
+
+    this.shelterByModel = o.shelterByModel
+
+    labels.push(this)
+
+    this.init()
+
+  }
+
+  init() {
+    this.update()
+  }
+
+
+
+  update() {
+    if (!this.position || !this.visible) return
+
+    var p = convertTool.getPos2d(this.position, this.camera, this.domElement);
+
+    if (!p || !p.trueSide) {
+      this.elem.css('display', 'none'); return;
+    }
+
+    //判断label是否被模型遮挡,遮挡则消失(如果是漫游模式最好提前计算visiblePanos)
+
+
+    if (this.shelterByModel && convertTool.ifShelter(this.position, p.vector, this.camera, this.modelobj,this.domElement)) {
+      this.elem.css('display', 'none'); return;
+    }
+
+    this.elem.css({
+      left: p.pos.x + 'px',
+      top: p.pos.y + 'px'
+    })
+
+
+    this.elem.css('display', 'block');
+    this.pos2d = p.vector;
+
+  }
+
+  setVisible(visi, reason, level = 0, type) {
+    convertTool.updateVisible(this, reason, visi, level, type)
+
+    if (!this.visible) {
+      this.elem.css('display', 'none');
+    } else {
+      this.update()
+    }
+  }
+
+
+  setPos(pos) {
+    this.position = pos;
+    this.update()
+  }
+
+  dispose() {
+    this.elem.remove();
+    this._listeners = {}
+    this.dispatchEvent({ type: 'dispose' })
+    let index = labels.indexOf(this)
+    index > -1 && labels.splice(index, 1)
+  }
+
+
+}
+
+
+export default Label2D

+ 36 - 0
src/kit/RoomLabel.js

@@ -0,0 +1,36 @@
+import * as THREE from "three";
+import Label2D from "./Label";
+
+class RoomLabel extends Label2D {
+  constructor(o) {
+    if (o.position instanceof Array) o.position = new THREE.Vector3().fromArray(o.position)
+    o.innerHTML = `<div class="room-label" ><a><p><span>${o.title}</span></p></a></div>`
+    o.domElement = window.$("#webgl")[0]
+    o.shelterByModel = true, o.autoUpdate = true
+
+    o.clickFun = () => {
+
+    }
+
+    super(o)
+    this.setTitle(o.title)
+  }
+
+  init() {
+    super.init()
+    // this.setStyle()
+  }
+
+  setStyle(oldMode, mode, duration) {
+    this.setVisible(true, 'isPanorama')
+  }
+
+
+  setTitle(title) {
+    this.title = title || ''
+    this.elem.html(`<a><p><span>window.${this.title}</span></p></a>`)
+  }
+
+}
+
+export default RoomLabel

+ 11 - 0
src/main.js

@@ -0,0 +1,11 @@
+import Vue from 'vue'
+import App from './App.vue'
+import '@/mixins'
+
+Vue.config.produzctionTip = false
+
+
+
+new Vue({
+  render: h => h(App)
+}).$mount('#app')

+ 46 - 0
src/mixins/index.js

@@ -0,0 +1,46 @@
+import browser from "@/utils/browser";
+import Vue from "vue";
+
+import { $showOrientationtip, $hideOrientationtip } from "@/components/verticaltip/build.js";
+
+
+
+Vue.prototype.$bus = new Vue();
+
+Vue.mixin({
+  data() {
+    return {
+      isMobile: browser.mobile,
+      g_isLandscape: window.orientation === 90 || window.orientation === -90,
+    };
+  },
+  methods:{
+    $showOrientationtip,
+    $hideOrientationtip
+  },
+  computed: {
+    theme() {
+      return this.$route.params.type;
+    },
+  },
+  mounted() {
+    if (this.isMobile || this.isiPad) {
+      // window.orientation:获取屏幕旋转方向
+      window.addEventListener(
+        "onorientationchange" in window ? "orientationchange" : "resize",
+        () => {
+          // 正常方向或屏幕旋转180度
+          if (window.orientation === 180 || window.orientation === 0) {
+            this.g_isLandscape = false;
+          }
+
+          // 屏幕顺时钟旋转90度或屏幕逆时针旋转90度
+          if (window.orientation === 90 || window.orientation === -90) {
+            this.g_isLandscape = true;
+            this.$bus.$emit("isShowHuDong", false);
+          }
+        }
+      );
+    }
+  },
+});

+ 0 - 0
src/router/index.js


Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini