| 
					
				 | 
			
			
				@@ -0,0 +1,174 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { Component, OnInit } from '@angular/core'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import * as BABYLON from "@babylonjs/core/Legacy/legacy"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { Engine, Scene } from "@babylonjs/core"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { FreeCamera } from "@babylonjs/core/Cameras/freeCamera"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { HemisphericLight } from "@babylonjs/core/Lights/hemisphericLight"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { Vector3 } from "@babylonjs/core/Maths/math.vector"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { CreateGround } from "@babylonjs/core/Meshes/Builders/groundBuilder"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { CreateSphere } from "@babylonjs/core/Meshes/Builders/sphereBuilder"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import { GridMaterial } from "@babylonjs/materials/grid/gridMaterial"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import "@babylonjs/loaders/glTF"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Component({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  selector: 'app-babylon', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  templateUrl: './babylon.page.html', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  styleUrls: ['./babylon.page.scss'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+export class BabylonPage implements OnInit { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  private engine: BABYLON.Engine|undefined; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  private scene: BABYLON.Scene|undefined; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CharacterMap:any = {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CharacterMeshList = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    {name:"古风少女", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    dirPath:"https://nova-cloud.obs.cn-south-1.myhuaweicloud.com/storage/3d/model/ancient-chinese-woman/gltf/", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    filePath:"scene.gltf"}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    {name:"中国象棋", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    dirPath:"https://nova-cloud.obs.cn-south-1.myhuaweicloud.com/storage/3d/model/chinese-chess/gltf/", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    filePath:"scene.gltf"}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    {name:"卡通异瞳少女", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    dirPath:"https://nova-cloud.obs.cn-south-1.myhuaweicloud.com/storage/3d/model/vtuber-selen/gltf/", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    filePath:"scene.gltf"}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    {name:"中国老杯子", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    dirPath:"https://nova-cloud.obs.cn-south-1.myhuaweicloud.com/storage/3d/model/chinese-iron-cup/", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    filePath:"scene.gltf"}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    {name:"中国城市lowpoly", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    dirPath:"https://nova-cloud.obs.cn-south-1.myhuaweicloud.com/storage/3d/model/chinese-city-lowpoly/gltf/", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    filePath:"scene.gltf"}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  constructor() { } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ngOnInit() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.initBabylon() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  initBabylon(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Get the canvas element from the DOM. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const canvas:any = document.getElementById("renderCanvas"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Set the canvas size to match the device pixel ratio 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const devicePixelRatio = window.devicePixelRatio || 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    canvas.width = window.innerWidth * devicePixelRatio; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    canvas.height = window.innerHeight * devicePixelRatio; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.engine = new BABYLON.Engine(canvas, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.scene = new BABYLON.Scene(this.engine); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Create a basic light, aiming 0,1,0 - meaning, to the sky. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const light = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(0, 1, 0), this.scene); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 加载粒子效果覆盖地面 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.loadGroundParticle() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 设置初始相机 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Add an ArcRotateCamera to the scene and attach it to the canvas 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // let initPositon = new BABYLON.Vector3(0,12,0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let initPositon = new BABYLON.Vector3(0,0,0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let beta = Math.PI / 2.5 // 镜头初始 纬度 Math.PI / 3 斜下45度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let radius = 20 // 镜头初始半径 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const camera = new BABYLON.ArcRotateCamera('camera1', Math.PI / 2, beta, radius, initPositon, this.scene); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    camera.attachControl(canvas, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Load the FBX model 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.CharacterMeshList.forEach(character=>{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      BABYLON.SceneLoader.ImportMesh('', character.dirPath, character.filePath, this.scene, (meshes, particleSystems, skeletons) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        console.log(meshes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // characterMesh.isVisible 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        meshes.forEach(mesh=>mesh.isVisible=false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.CharacterMap[character?.name] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          meshes:meshes, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          particleSystems:particleSystems, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          skeletons:skeletons 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (skeletons.length > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.scene?.beginAnimation(skeletons[0], 0, 100, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setTimeout(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.showCharacter("机器人") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 3000); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Register a render loop to repeatedly render the scene. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.engine.runRenderLoop(() => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.scene?.render(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 开启调试层,用于抓取角度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.scene.debugLayer.show(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Watch for browser/canvas resize events 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    window.addEventListener('resize', () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.engine?.resize(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  showCharacter(name?:string){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(!name) return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Object.keys(this.CharacterMap).forEach(tempname=>{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      let character = this.CharacterMap[tempname]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if(tempname==name){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(character.meshes?.length){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          character.meshes.forEach((mesh:any)=>mesh.isVisible=true) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(character.meshes?.length){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          character.meshes.forEach((mesh:any)=>mesh.isVisible=false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  loadGroundParticle(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if(!this.scene) return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // 创建粒子系统 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const particleSystem = new BABYLON.ParticleSystem("particles", 2000, this.scene); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // 纹理 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      particleSystem.particleTexture = new BABYLON.Texture("textures/flare.png", this.scene); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // 发射器 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      particleSystem.emitter = new BABYLON.Vector3(0, 0, 0); // 发射器位置 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      particleSystem.minEmitBox = new BABYLON.Vector3(-300, 0, -300); // 最小发射范围 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      particleSystem.maxEmitBox = new BABYLON.Vector3(300, 0, 300); // 最大发射范围 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // 粒子颜色 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      particleSystem.color1 = new BABYLON.Color4(1, 1, 1, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      particleSystem.color2 = new BABYLON.Color4(0.5, 0.5, 1, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      particleSystem.colorDead = new BABYLON.Color4(0, 0, 0.2, 0.5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // 粒子大小 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      particleSystem.minSize = 0.1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      particleSystem.maxSize = 0.5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // 粒子生命周期 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      particleSystem.minLifeTime = 0.3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      particleSystem.maxLifeTime = 1.5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // 发射速率 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      particleSystem.emitRate = 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // 粒子方向 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      particleSystem.direction1 = new BABYLON.Vector3(-1, 1, -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      particleSystem.direction2 = new BABYLON.Vector3(1, 1, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // 重力 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      particleSystem.gravity = new BABYLON.Vector3(0, -9.81, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // 粒子速度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      particleSystem.minEmitPower = 0.5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      particleSystem.maxEmitPower = 1.5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      particleSystem.updateSpeed = 0.01; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // 开始粒子系统 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      particleSystem.start(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 |