|
@@ -0,0 +1,171 @@
|
|
|
|
+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-case-babylon',
|
|
|
|
+ templateUrl: './case-babylon.page.html',
|
|
|
|
+ styleUrls: ['./case-babylon.page.scss'],
|
|
|
|
+})
|
|
|
|
+export class CaseBabylonPage 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();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|