babylon.page.ts 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import { Component, OnInit } from '@angular/core';
  2. import * as BABYLON from "@babylonjs/core/Legacy/legacy";
  3. import { Engine, Scene } from "@babylonjs/core";
  4. import { FreeCamera } from "@babylonjs/core/Cameras/freeCamera";
  5. import { HemisphericLight } from "@babylonjs/core/Lights/hemisphericLight";
  6. import { Vector3 } from "@babylonjs/core/Maths/math.vector";
  7. import { CreateGround } from "@babylonjs/core/Meshes/Builders/groundBuilder";
  8. import { CreateSphere } from "@babylonjs/core/Meshes/Builders/sphereBuilder";
  9. import { GridMaterial } from "@babylonjs/materials/grid/gridMaterial";
  10. import "@babylonjs/loaders/glTF";
  11. @Component({
  12. selector: 'app-babylon',
  13. templateUrl: './babylon.page.html',
  14. styleUrls: ['./babylon.page.scss'],
  15. })
  16. export class BabylonPage implements OnInit {
  17. private engine: BABYLON.Engine|undefined;
  18. private scene: BABYLON.Scene|undefined;
  19. CharacterMap:any = {}
  20. CharacterMeshList = [
  21. {name:"卧室",
  22. dirPath:"https://nova-cloud.obs.cn-south-1.myhuaweicloud.com/storage/3d/model/ancient-chinese-woman/gltf/",
  23. filePath:"scene.gltf"},
  24. {name:"厨房",
  25. dirPath:"https://nova-cloud.obs.cn-south-1.myhuaweicloud.com/storage/3d/model/chinese-chess/gltf/",
  26. filePath:"scene.gltf"},
  27. {name:"客厅",
  28. dirPath:"https://nova-cloud.obs.cn-south-1.myhuaweicloud.com/storage/3d/model/vtuber-selen/gltf/",
  29. filePath:"scene.gltf"},
  30. {name:"卫生间",
  31. dirPath:"https://nova-cloud.obs.cn-south-1.myhuaweicloud.com/storage/3d/model/chinese-iron-cup/",
  32. filePath:"scene.gltf"},
  33. {name:"阳台",
  34. dirPath:"https://nova-cloud.obs.cn-south-1.myhuaweicloud.com/storage/3d/model/chinese-city-lowpoly/gltf/",
  35. filePath:"scene.gltf"},
  36. ]
  37. constructor() { }
  38. ngOnInit() {
  39. this.initBabylon()
  40. }
  41. initBabylon(){
  42. // Get the canvas element from the DOM.
  43. const canvas:any = document.getElementById("renderCanvas");
  44. // Set the canvas size to match the device pixel ratio
  45. const devicePixelRatio = window.devicePixelRatio || 1;
  46. canvas.width = window.innerWidth * devicePixelRatio;
  47. canvas.height = window.innerHeight * devicePixelRatio;
  48. this.engine = new BABYLON.Engine(canvas, true);
  49. this.scene = new BABYLON.Scene(this.engine);
  50. // Create a basic light, aiming 0,1,0 - meaning, to the sky.
  51. const light = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(0, 1, 0), this.scene);
  52. // 加载粒子效果覆盖地面
  53. this.loadGroundParticle()
  54. // 设置初始相机
  55. // Add an ArcRotateCamera to the scene and attach it to the canvas
  56. // let initPositon = new BABYLON.Vector3(0,12,0)
  57. let initPositon = new BABYLON.Vector3(0,0,0)
  58. let beta = Math.PI / 2.5 // 镜头初始 纬度 Math.PI / 3 斜下45度
  59. let radius = 20 // 镜头初始半径
  60. const camera = new BABYLON.ArcRotateCamera('camera1', Math.PI / 2, beta, radius, initPositon, this.scene);
  61. camera.attachControl(canvas, true);
  62. // Load the FBX model
  63. this.CharacterMeshList.forEach(character=>{
  64. BABYLON.SceneLoader.ImportMesh('', character.dirPath, character.filePath, this.scene, (meshes, particleSystems, skeletons) => {
  65. console.log(meshes)
  66. // characterMesh.isVisible
  67. meshes.forEach(mesh=>mesh.isVisible=false)
  68. this.CharacterMap[character?.name] = {
  69. meshes:meshes,
  70. particleSystems:particleSystems,
  71. skeletons:skeletons
  72. }
  73. if (skeletons.length > 0) {
  74. this.scene?.beginAnimation(skeletons[0], 0, 100, true);
  75. }
  76. });
  77. })
  78. setTimeout(() => {
  79. this.showCharacter("机器人")
  80. }, 3000);
  81. // Register a render loop to repeatedly render the scene.
  82. this.engine.runRenderLoop(() => {
  83. this.scene?.render();
  84. });
  85. // 开启调试层,用于抓取角度
  86. this.scene.debugLayer.show();
  87. // Watch for browser/canvas resize events
  88. window.addEventListener('resize', () => {
  89. this.engine?.resize();
  90. });
  91. }
  92. showCharacter(name?:string){
  93. if(!name) return
  94. Object.keys(this.CharacterMap).forEach(tempname=>{
  95. let character = this.CharacterMap[tempname];
  96. if(tempname==name){
  97. if(character.meshes?.length){
  98. character.meshes.forEach((mesh:any)=>mesh.isVisible=true)
  99. }
  100. }else{
  101. if(character.meshes?.length){
  102. character.meshes.forEach((mesh:any)=>mesh.isVisible=false)
  103. }
  104. }
  105. })
  106. }
  107. loadGroundParticle(){
  108. if(!this.scene) return
  109. // 创建粒子系统
  110. const particleSystem = new BABYLON.ParticleSystem("particles", 2000, this.scene);
  111. // 纹理
  112. particleSystem.particleTexture = new BABYLON.Texture("textures/flare.png", this.scene);
  113. // 发射器
  114. particleSystem.emitter = new BABYLON.Vector3(0, 0, 0); // 发射器位置
  115. particleSystem.minEmitBox = new BABYLON.Vector3(-300, 0, -300); // 最小发射范围
  116. particleSystem.maxEmitBox = new BABYLON.Vector3(300, 0, 300); // 最大发射范围
  117. // 粒子颜色
  118. particleSystem.color1 = new BABYLON.Color4(1, 1, 1, 1);
  119. particleSystem.color2 = new BABYLON.Color4(0.5, 0.5, 1, 1);
  120. particleSystem.colorDead = new BABYLON.Color4(0, 0, 0.2, 0.5);
  121. // 粒子大小
  122. particleSystem.minSize = 0.1;
  123. particleSystem.maxSize = 0.5;
  124. // 粒子生命周期
  125. particleSystem.minLifeTime = 0.3;
  126. particleSystem.maxLifeTime = 1.5;
  127. // 发射速率
  128. particleSystem.emitRate = 1000;
  129. // 粒子方向
  130. particleSystem.direction1 = new BABYLON.Vector3(-1, 1, -1);
  131. particleSystem.direction2 = new BABYLON.Vector3(1, 1, 1);
  132. // 重力
  133. particleSystem.gravity = new BABYLON.Vector3(0, -9.81, 0);
  134. // 粒子速度
  135. particleSystem.minEmitPower = 0.5;
  136. particleSystem.maxEmitPower = 1.5;
  137. particleSystem.updateSpeed = 0.01;
  138. // 开始粒子系统
  139. particleSystem.start();
  140. }
  141. }