定制app开发Vue集成three.js,并加载glb、gltf、FBX、json模型

定制app开发最近刚开始做的一个项目,定制app开发后面有个模块要通过three.js实现3D的场景,定制app开发因为之前也没接触过3D这块,定制app开发就提前学了一下,做个记录。

定制app开发先上几个网址

官方: 

ThreeJS文档:  

定制app开发免费模型网:  

定制app开发接下来就我做的一个demo开始 

安装

  1. npm i three
  2. npm i three-orbitcontrols
  3. npm i stats.js // 性能监测

定制app开发组件中引入 

  1. import * as THREE from 'three'
  2. import * as Stats from 'stats.js'
  3. import OrbitControls from 'three-orbitcontrols'
  4. import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
  5. import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'
  6. import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'

基本使用 

1.创建场景 

this.scene = new THREE.Scene();

2.相机 

  1. this.camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000);
  2. // 定制app开发设置摄像机位置,定制app开发相机方向逆X轴方向,定制app开发倾斜向下看
  3. this.camera.position.set(360, 360, 360);
  4. // 指向场景中心
  5. this.camera.lookAt(this.scene.position);

3. 渲染器

  1. this.renderer = new THREE.WebGLRenderer({ antialias: true });
  2. // 设置环境
  3. this.renderer.setClearColor(new THREE.Color("#f1f9fb"));
  4. // 设置场景大小
  5. this.renderer.setSize(window.innerWidth / window.innerHeight);
  6. // 渲染器开启阴影效果
  7. this.renderer.shadowMap.enabled = true;

4.创建纹理加载器 

this.textureLoader = new THREE.TextureLoader();

5.创建组合对象 

加载外部模型的时候,基本上都是一个组合对象,因为外部模型都是比较大的,把零散的模型组合到一块便于操作,可以使用THREE.Group来操作一组对象,包括旋转,缩放,移动等,里面的子对象都会受到影响。THREE.Group继承自THREE.Object3D对象,并且和THREE.Object3D对象没有任何区别,仅仅是名字上的差异

this.groupBox = new THREE.Group();

6.添加坐标轴,辅助判断位置 

  1. let axes = new THREE.AxesHelper(1000);
  2. this.scene.add(axes);

7.点光源 

  1. // 点光源
  2. let point = new THREE.PointLight(0xffffff);
  3. point.position.set(500, 300, 400); // 点光源位置
  4. this.scene.add(point); // 点光源添加到场景中

8.环境光 

  1. // 环境光
  2. let ambient = new THREE.AmbientLight(0x999999);
  3. this.scene.add(ambient);

9.性能监测 

  1. //创建性能监测
  2. this.stats = new Stats()
  3. this.stats.showPanel(0) // 0: fps, 1: ms, 2: mb, 3+: custom
  4. this.stats.domElement.style.position = 'absolute'; //绝对坐标 this.stats.domElement.style.left = '0px';// (0,0)px,左上角
  5. this.stats.domElement.style.top = '0px';
  6. $('#stats').appendChild(this.stats.domElement)

10.相机控件 

  1. //创建相机控件
  2. this.control = new OrbitControls(this.camera, this.renderer.domElement)
  3. this.control.enableDamping = true
  4. // 动态阻尼系数 就是鼠标拖拽旋转灵敏度,阻尼越小越灵敏
  5. this.control.dampingFactor = 0.5;
  6. // 是否可以缩放
  7. this.control.enableZoom = true;
  8. // 是否自动旋转
  9. this.control.autoRotate = false;
  10. // 设置相机距离原点的最近距离
  11. this.control.minDistance = 20;
  12. // 设置相机距离原点的最远距离
  13. this.control.maxDistance = 1000;
  14. // 是否开启右键拖拽
  15. this.control.enablePan = true;
  16. // 上下翻转的最大角度
  17. this.control.maxPolarAngle = 1.5;
  18. // 上下翻转的最小角度
  19. this.control.minPolarAngle = 0.0;
  20. // 是否可以旋转
  21. this.enableRotate = true;

11.渲染canvas到容器 

$('#container').appendChild(this.renderer.domElement);

12.加载glb、gltf模型 

  1. loadGlbModel() {
  2. const loader = new GLTFLoader()
  3. // const dracoLoader = new DRACOLoader()
  4. // dracoLoader.setDecoderPath('/draco/')
  5. // dracoLoader.preload()
  6. // loader.setDRACOLoader(dracoLoader)
  7. loader.load(`${this.publicPath}model/12OJJ6MOWT722N61Z5N92KA9C.glb`, (gltf) => {
  8. console.log(gltf, 'gltf----->>>')
  9. gltf.scene.scale.set(100,100,100) // 设置模型大小缩放
  10. gltf.scene.position.set(0,0,0)
  11. let axis = new THREE.Vector3(0,1,0);//向量axis
  12. gltf.scene.rotateOnAxis(axis,Math.PI/2);
  13. //绕axis轴逆旋转π/16
  14. gltf.scene.rotateOnAxis(axis,Math.PI/-20);
  15. gltf.scene.rotateOnAxis(axis,Math.PI/50);
  16. // gltf.rotateY(Math.PI / 2);
  17. // this.groupBox.add(gltf);
  18. this.scene.add(gltf.scene)
  19. }, (xhr) => {
  20. console.log((xhr.loaded / xhr.total) * 100 + '% loaded')
  21. }, (error) => {
  22. console.error(error)
  23. })
  24. },

13.加载FBX模型 

  1. // 加载 FBX 模型
  2. loadFbxModel() {
  3. const loader = new FBXLoader();
  4. loader.load(`${this.publicPath}model/glbxz.com6031.FBX`, object => {//加载路径fbx文件
  5. console.log(object, 'object----->>>')
  6. object.traverse( child => {
  7. if ( child.isMesh ){
  8. child.castShadow = true;
  9. child.receiveShadow = true;
  10. }
  11. });
  12. this.scene.add(object);//模型
  13. })
  14. },

14.加载json模型 

  1. //加载 JSON格式 模型
  2. loadJsonModel() {
  3. //设置相机位置
  4. this.camera.position.z = 130
  5. this.camera.position.y = 80
  6. const loader = new THREE.ObjectLoader()
  7. loader.load(`${this.publicPath}model/xxxx.json`, json => {
  8. //处理加载模型为黑色问题
  9. json.traverse(child => {
  10. if (child.isMesh) {
  11. child.material.emissive = child.material.color
  12. child.material.emissiveMap = child.material.map
  13. }
  14. })
  15. this.scene.add(group)
  16. }, xhr => {
  17. // called while loading is progressing
  18. console.log(`${( xhr.loaded / xhr.total * 100 )}% loaded`);
  19. }, error => {
  20. // called when loading has errors
  21. console.error('An error happened', error);
  22. })
  23. },

15.创建材质 

  1. // 创建材质
  2. createMaterial() {
  3. // 创建三维用到的材质
  4. /**
  5. *
  6. * MeshBasicMaterial: 网格基础材质
  7. * MeshDepthMaterial: 网格深度材质
  8. * MeshNormalMaterial: 网格法向材质
  9. * MeshLambertMaterial: 网格Lambert 材质
  10. * MeshPhongMaterial: 网格 Phong式材质
  11. * MeshStandardMaterial: 网格标准材质
  12. * MeshPhysicalMaterial: 网格物理材质
  13. * MeshToonMaterial: 网格卡通材质
  14. * ShadowMaterial: 阴影材质
  15. * ShaderMaterial: 着色器材质
  16. * LineBasicMaterial: 直线基础材质
  17. * LineDashMaterial: 虚线材质
  18. */
  19. // 外墙
  20. let wallMaterial = new THREE.MeshLambertMaterial({ color: 0x00ffff });
  21. let wallGeo = new THREE.BoxGeometry(439 + 2 + 2, 120, 376.5 + 2 + 2); // 创建几何体
  22. let wallMesh = new THREE.Mesh(wallGeo, wallMaterial);
  23. wallMesh.position.set(0, 60, 0); //(0, 60, -14.95);
  24. this.scene.add(wallMesh) // 添加结果到场景中
  25. // 内墙
  26. let wallInnerMaterial = new THREE.MeshLambertMaterial({
  27. color: 0x2d1bff,
  28. });
  29. let wallInnerGeo = new THREE.BoxGeometry(439, 120, 376.5); //(270, 120, 390);
  30. let wallInnerMesh = new THREE.Mesh(wallInnerGeo, wallInnerMaterial);
  31. wallInnerMesh.position.set(0, 60, 0); //(0, 60, -14.95);
  32. this.scene.add(wallInnerMesh) // 添加结果到场景中
  33. // 门
  34. let doorTexture = this.textureLoader.load(
  35. require("../../../../assets/img/1.png") // 暂时注掉
  36. );
  37. let boxTextureMaterial = new THREE.MeshStandardMaterial({
  38. map: doorTexture,
  39. metalness: 0.2,
  40. roughness: 0.07,
  41. side: THREE.DoubleSide,
  42. });
  43. //let doorInnerMaterial = new THREE.MeshLambertMaterial({color: 0x2D1BFF});
  44. let doorGeo = new THREE.BoxGeometry(2, 80, 74.5);
  45. let doorMesh = new THREE.Mesh(doorGeo, boxTextureMaterial);
  46. doorMesh.position.set(-220.5, 40, 0);
  47. this.scene.add(doorMesh); // 添加结果到场景中
  48. /**
  49. * threeBSP - 引用还有问题
  50. */
  51. // //转BSP
  52. // let wallBSP = new ThreeBSP(wallMesh);
  53. // let wallInnerBSP = new ThreeBSP(wallInnerMesh);
  54. // let doorBSP = new ThreeBSP(doorMesh);
  55. // // let window1BSP = new ThreeBSP(this.createWindowRight());
  56. // //let window2BSP = new ThreeBSP(this.createWindowRight());// createWindowLeft
  57. // let wallResultBSP = wallBSP.subtract(wallInnerBSP);
  58. // wallResultBSP = wallResultBSP.subtract(doorBSP);
  59. // // wallResultBSP = wallResultBSP.subtract(window1BSP);
  60. // //wallResultBSP = wallResultBSP.subtract(window2BSP);
  61. // let wallResultMesh = wallResultBSP.toMesh();
  62. // //转换后的Mesh配置属性
  63. // let wallTexture = this.textureLoader.load(require("../../../../assets/img/3.jpg")); // 暂时注掉
  64. // let wallTextureMaterial = new THREE.MeshStandardMaterial({
  65. // map: wallTexture,
  66. // metalness: 0.2,
  67. // roughness: 0.07,
  68. // side: THREE.DoubleSide,
  69. // });
  70. // let wallInnerTexture = this.textureLoader.load(
  71. // require("../../../../assets/img/6.jpg") // 暂时注掉
  72. // );
  73. // let wallInnerTextureMaterial = new THREE.MeshStandardMaterial({
  74. // map: wallInnerTexture,
  75. // metalness: 0.2,
  76. // roughness: 0.07,
  77. // side: THREE.DoubleSide,
  78. // });
  79. // let wallResultMeshMaterial = [];
  80. // wallResultMeshMaterial.push(wallTextureMaterial);
  81. // wallResultMeshMaterial.push(wallInnerTextureMaterial);
  82. // //wallResultMeshMaterial.push(boxTextureMaterial);
  83. // wallResultMesh.material = wallResultMeshMaterial;
  84. // // console.log(wallResultMesh.geometry.faces, 112233);
  85. // wallResultMesh.geometry.faces.forEach((item, i) => {
  86. // if (i < 160) {
  87. // item.materialIndex = 0;
  88. // } else {
  89. // item.materialIndex = 1;
  90. // }
  91. // });
  92. // wallResultMesh.geometry.computeFaceNormals();
  93. // wallResultMesh.geometry.computeVertexNormals();
  94. // //添加结果到场景中
  95. // this.scene.add(wallResultMesh);
  96. },

16.进行渲染 

  1. render() {
  2. let animate = () => {
  3. //循环调用函数
  4. this.clearAnim = requestAnimationFrame(animate)
  5. //更新相机控件
  6. this.control.update()
  7. // 更新性能插件
  8. this.stats.update()
  9. //渲染界面
  10. this.renderer.render(this.scene, this.camera)
  11. }
  12. animate()
  13. }

17.为模型绑定事件 

这里以点击事件为例 

this.renderer.domElement.addEventListener('click', this.modelMouseClick, false)
  1. // 模型的点击事件
  2. modelMouseClick( event ) {
  3. var raycaster = new THREE.Raycaster();
  4. var mouse = new THREE.Vector2();
  5. // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
  6. mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
  7. mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
  8. raycaster.setFromCamera(mouse, this.camera);
  9. const intersects = raycaster.intersectObjects(this.scene.children);
  10. // 根据它来判断点击的什么,length为0即没有点击到模型
  11. console.log(intersects, 'intersects----->>>')
  12. }

完整代码 

  1. <template>
  2. <div id="import-template">
  3. <!-- 放性能监测的容器 -->
  4. <div id="stats"></div>
  5. <!-- 3D模型容器 -->
  6. <div id="container"></div>
  7. </div>
  8. </template>
  9. <script>
  10. // import '@/utils/ThreeBSP.js' // 不可以这么引
  11. import * as THREE from 'three'
  12. import * as Stats from 'stats.js'
  13. // import * as dat from 'dat.gui'
  14. import OrbitControls from 'three-orbitcontrols'
  15. import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
  16. import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'
  17. import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'
  18. const $ = name => document.querySelector(name)
  19. export default {
  20. data() {
  21. return {
  22. scene: null, // 场景
  23. camera: null, // 照相机
  24. renderer: null, // 渲染器
  25. mesh: null, // 网格
  26. textureLoader: null, // 纹理加载器
  27. mixer: null,
  28. groupBox: null,
  29. stats: null, // 性能监测
  30. control: null, // 相机控件
  31. publicPath: process.env.BASE_URL,
  32. clearAnim: null,
  33. clock: null
  34. }
  35. },
  36. created() {
  37. // this.init()
  38. },
  39. mounted() {
  40. this.init()
  41. },
  42. destroyed() {
  43. cancelAnimationFrame(this.clearAnim) // 清除requestAnimationFrame
  44. this.renderer.domElement.removeEventListener('click', this.modelMouseClick, false)
  45. this.scene = null, // 场景
  46. this.camera = null, // 照相机
  47. this.renderer = null, // 渲染器
  48. this.mesh = null, // 网格
  49. this.textureLoader = null, // 纹理加载器
  50. this.mixer = null,
  51. this.groupBox = null,
  52. this.stats = null, // 性能监测
  53. this.control = null, // 相机控件
  54. this.publicPath = process.env.BASE_URL,
  55. this.clock = null
  56. },
  57. methods: {
  58. //初始化
  59. init() {
  60. // 场景
  61. this.scene = new THREE.Scene();
  62. // 1.2 相机
  63. this.camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000);
  64. // 设置摄像机位置,相机方向逆X轴方向,倾斜向下看
  65. this.camera.position.set(360, 360, 360);
  66. //this.camera.position.set(-20, 40 ,30)
  67. // 指向场景中心
  68. this.camera.lookAt(this.scene.position);
  69. // 1.3 渲染器
  70. this.renderer = new THREE.WebGLRenderer({ antialias: true });
  71. // 创建纹理加载器
  72. this.textureLoader = new THREE.TextureLoader();
  73. // 创建一个组合对象
  74. this.groupBox = new THREE.Group();
  75. // 添加坐标轴,辅助判断位置
  76. let axes = new THREE.AxesHelper(1000);
  77. this.scene.add(axes);
  78. // 设置环境
  79. this.renderer.setClearColor(new THREE.Color("#f1f9fb"));
  80. // 设置场景大小
  81. this.renderer.setSize(
  82. $('#container').getBoundingClientRect().width,
  83. $('#container').getBoundingClientRect().height
  84. );
  85. // 渲染器开启阴影效果
  86. this.renderer.shadowMap.enabled = true;
  87. // 点光源
  88. let point = new THREE.PointLight(0xffffff);
  89. point.position.set(500, 300, 400); // 点光源位置
  90. this.scene.add(point); // 点光源添加到场景中
  91. // 环境光
  92. let ambient = new THREE.AmbientLight(0x999999);
  93. this.scene.add(ambient);
  94. //创建性能监测
  95. this.stats = new Stats()
  96. this.stats.showPanel(0) // 0: fps, 1: ms, 2: mb, 3+: custom
  97. this.stats.domElement.style.position = 'absolute'; //绝对坐标
  98. this.stats.domElement.style.left = '0px';// (0,0)px,左上角
  99. this.stats.domElement.style.top = '0px';
  100. $('#stats').appendChild(this.stats.domElement)
  101. // 渲染div到canvas
  102. $('#container').appendChild(this.renderer.domElement);
  103. //创建相机控件
  104. this.control = new OrbitControls(this.camera, this.renderer.domElement)
  105. this.control.enableDamping = true
  106. // 动态阻尼系数 就是鼠标拖拽旋转灵敏度,阻尼越小越灵敏
  107. this.control.dampingFactor = 0.5;
  108. // 是否可以缩放
  109. this.control.enableZoom = true;
  110. // 是否自动旋转
  111. this.control.autoRotate = false;
  112. // 设置相机距离原点的最近距离
  113. this.control.minDistance = 20;
  114. // 设置相机距离原点的最远距离
  115. this.control.maxDistance = 1000;
  116. // 是否开启右键拖拽
  117. this.control.enablePan = true;
  118. // 上下翻转的最大角度
  119. this.control.maxPolarAngle = 1.5;
  120. // 上下翻转的最小角度
  121. this.control.minPolarAngle = 0.0;
  122. // 是否可以旋转
  123. this.enableRotate = true;
  124. this.loadGlbModel(); // 加载 glb、gltf模型
  125. // this.loadFbxModel() // 加载 FBX 模型
  126. // this.loadJsonModel() // 加载 json 模型
  127. // this.createMaterial() // 创建材质
  128. // 最后进行渲染
  129. this.render()
  130. },
  131. // 最后的渲染
  132. render() {
  133. let animate = () => {
  134. //循环调用函数
  135. this.clearAnim = requestAnimationFrame(animate)
  136. //更新相机控件
  137. this.control.update()
  138. // 更新性能插件
  139. this.stats.update()
  140. //渲染界面
  141. this.renderer.render(this.scene, this.camera)
  142. }
  143. animate()
  144. // 为模型绑定点击事件
  145. this.renderer.domElement.addEventListener('click', this.modelMouseClick, false)
  146. },
  147. // 创建材质
  148. createMaterial() {
  149. // 创建三维用到的材质
  150. /**
  151. *
  152. * MeshBasicMaterial: 网格基础材质
  153. * MeshDepthMaterial: 网格深度材质
  154. * MeshNormalMaterial: 网格法向材质
  155. * MeshLambertMaterial: 网格Lambert 材质
  156. * MeshPhongMaterial: 网格 Phong式材质
  157. * MeshStandardMaterial: 网格标准材质
  158. * MeshPhysicalMaterial: 网格物理材质
  159. * MeshToonMaterial: 网格卡通材质
  160. * ShadowMaterial: 阴影材质
  161. * ShaderMaterial: 着色器材质
  162. * LineBasicMaterial: 直线基础材质
  163. * LineDashMaterial: 虚线材质
  164. */
  165. // 外墙
  166. let wallMaterial = new THREE.MeshLambertMaterial({ color: 0x00ffff });
  167. let wallGeo = new THREE.BoxGeometry(439 + 2 + 2, 120, 376.5 + 2 + 2); // 创建几何体
  168. let wallMesh = new THREE.Mesh(wallGeo, wallMaterial);
  169. wallMesh.position.set(0, 60, 0); //(0, 60, -14.95);
  170. this.scene.add(wallMesh)
  171. // 内墙
  172. let wallInnerMaterial = new THREE.MeshLambertMaterial({
  173. color: 0x2d1bff,
  174. });
  175. let wallInnerGeo = new THREE.BoxGeometry(439, 120, 376.5); //(270, 120, 390);
  176. let wallInnerMesh = new THREE.Mesh(wallInnerGeo, wallInnerMaterial);
  177. wallInnerMesh.position.set(0, 60, 0); //(0, 60, -14.95);
  178. this.scene.add(wallInnerMesh)
  179. // 门
  180. let doorTexture = this.textureLoader.load(
  181. require("../../../../assets/img/1.png") // 暂时注掉
  182. );
  183. let boxTextureMaterial = new THREE.MeshStandardMaterial({
  184. map: doorTexture,
  185. metalness: 0.2,
  186. roughness: 0.07,
  187. side: THREE.DoubleSide,
  188. });
  189. //let doorInnerMaterial = new THREE.MeshLambertMaterial({color: 0x2D1BFF});
  190. let doorGeo = new THREE.BoxGeometry(2, 80, 74.5);
  191. let doorMesh = new THREE.Mesh(doorGeo, boxTextureMaterial);
  192. doorMesh.position.set(-220.5, 40, 0);
  193. this.scene.add(doorMesh);
  194. /**
  195. * threeBSP - 引用还有问题
  196. */
  197. // //转BSP
  198. // let wallBSP = new ThreeBSP(wallMesh);
  199. // let wallInnerBSP = new ThreeBSP(wallInnerMesh);
  200. // let doorBSP = new ThreeBSP(doorMesh);
  201. // // let window1BSP = new ThreeBSP(this.createWindowRight());
  202. // //let window2BSP = new ThreeBSP(this.createWindowRight());// createWindowLeft
  203. // let wallResultBSP = wallBSP.subtract(wallInnerBSP);
  204. // wallResultBSP = wallResultBSP.subtract(doorBSP);
  205. // // wallResultBSP = wallResultBSP.subtract(window1BSP);
  206. // //wallResultBSP = wallResultBSP.subtract(window2BSP);
  207. // let wallResultMesh = wallResultBSP.toMesh();
  208. // //转换后的Mesh配置属性
  209. // let wallTexture = this.textureLoader.load(require("../../../../assets/img/3.jpg")); // 暂时注掉
  210. // let wallTextureMaterial = new THREE.MeshStandardMaterial({
  211. // map: wallTexture,
  212. // metalness: 0.2,
  213. // roughness: 0.07,
  214. // side: THREE.DoubleSide,
  215. // });
  216. // let wallInnerTexture = this.textureLoader.load(
  217. // require("../../../../assets/img/6.jpg") // 暂时注掉
  218. // );
  219. // let wallInnerTextureMaterial = new THREE.MeshStandardMaterial({
  220. // map: wallInnerTexture,
  221. // metalness: 0.2,
  222. // roughness: 0.07,
  223. // side: THREE.DoubleSide,
  224. // });
  225. // let wallResultMeshMaterial = [];
  226. // wallResultMeshMaterial.push(wallTextureMaterial);
  227. // wallResultMeshMaterial.push(wallInnerTextureMaterial);
  228. // //wallResultMeshMaterial.push(boxTextureMaterial);
  229. // wallResultMesh.material = wallResultMeshMaterial;
  230. // // console.log(wallResultMesh.geometry.faces, 112233);
  231. // wallResultMesh.geometry.faces.forEach((item, i) => {
  232. // if (i < 160) {
  233. // item.materialIndex = 0;
  234. // } else {
  235. // item.materialIndex = 1;
  236. // }
  237. // });
  238. // wallResultMesh.geometry.computeFaceNormals();
  239. // wallResultMesh.geometry.computeVertexNormals();
  240. // //添加结果到场景中
  241. // this.scene.add(wallResultMesh);
  242. },
  243. // 加载 GLTF 模型
  244. loadGlbModel() {
  245. const loader = new GLTFLoader()
  246. // const dracoLoader = new DRACOLoader()
  247. // dracoLoader.setDecoderPath('/draco/')
  248. // dracoLoader.preload()
  249. // loader.setDRACOLoader(dracoLoader)
  250. loader.load(`${this.publicPath}model/12OJJ6MOWT722N61Z5N92KA9C.glb`, (gltf) => {
  251. console.log(gltf, 'gltf----->>>')
  252. gltf.scene.scale.set(100,100,100) // 设置模型大小缩放
  253. gltf.scene.position.set(0,0,0)
  254. let axis = new THREE.Vector3(0,1,0);//向量axis
  255. gltf.scene.rotateOnAxis(axis,Math.PI/2);
  256. //绕axis轴逆旋转π/16
  257. gltf.scene.rotateOnAxis(axis,Math.PI/-20);
  258. gltf.scene.rotateOnAxis(axis,Math.PI/50);
  259. // gltf.rotateY(Math.PI / 2);
  260. // this.groupBox.add(gltf);
  261. this.scene.add(gltf.scene)
  262. }, (xhr) => {
  263. console.log((xhr.loaded / xhr.total) * 100 + '% loaded')
  264. }, (error) => {
  265. console.error(error)
  266. })
  267. },
  268. // 加载 FBX 模型
  269. loadFbxModel() {
  270. const loader = new FBXLoader();
  271. loader.load(`${this.publicPath}model/glbxz.com6031.FBX`, object => {//加载路径fbx文件
  272. console.log(object, 'object----->>>')
  273. object.traverse( child => {
  274. if ( child.isMesh ){
  275. child.castShadow = true;
  276. child.receiveShadow = true;
  277. }
  278. });
  279. this.scene.add(object);//模型
  280. })
  281. },
  282. //加载 JSON格式 模型
  283. loadJsonModel() {
  284. //设置相机位置
  285. this.camera.position.z = 130
  286. this.camera.position.y = 80
  287. const loader = new THREE.ObjectLoader()
  288. loader.load(`${this.publicPath}model/xxxx.json`, json => {
  289. //处理加载模型为黑色问题
  290. json.traverse(child => {
  291. if (child.isMesh) {
  292. child.material.emissive = child.material.color
  293. child.material.emissiveMap = child.material.map
  294. }
  295. })
  296. this.scene.add(group)
  297. }, xhr => {
  298. // called while loading is progressing
  299. console.log(`${( xhr.loaded / xhr.total * 100 )}% loaded`);
  300. }, error => {
  301. // called when loading has errors
  302. console.error('An error happened', error);
  303. })
  304. },
  305. // 模型的点击事件
  306. modelMouseClick( event ) {
  307. var raycaster = new THREE.Raycaster();
  308. var mouse = new THREE.Vector2();
  309. // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
  310. mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
  311. mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
  312. raycaster.setFromCamera(mouse, this.camera);
  313. const intersects = raycaster.intersectObjects(this.scene.children);
  314. // 根据它来判断点击的什么,length为0即没有点击到模型
  315. console.log(intersects, 'intersects----->>>')
  316. }
  317. }
  318. }
  319. </script>
  320. <style scoped>
  321. #import-template {
  322. width: 100%;
  323. height: 100%;
  324. }
  325. #stats {
  326. width: 100%;
  327. height: 50px;
  328. position: relative;
  329. }
  330. #container {
  331. width: 100%;
  332. height: calc(100% - 50px);
  333. }
  334. </style>

效果 

  

最后再补充一下,有个threeBSP,,到现在还没知道怎么去引用,搞这个东西才两天,很多还需要慢慢摸索 ,好像这个threBSP不支持npm装,而且必须要引在THREE后面。。。慢慢再搞

<script src="https://johnson2heng.github.io/three.js-demo/lib/threebsp.js"></script>

 这个是threeBSP在线的包,如果向上面例子按需引入THREE,那应该怎么去引这个包呢,, 

不断学习中。。。

补充 

接上面的问题,【已解决】ThreeBSP引入问题 

见下篇博文  

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发