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:"阳台", 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(); } }