@mingo_zh/data-room-ui
Version:
207 lines (164 loc) • 7.4 kB
text/typescript
import { ArcRotateCamera, Color3, Tools, Engine, HemisphericLight, MeshBuilder, Scene, StandardMaterial, SceneLoader, Texture, Vector3, Animation, AbstractMesh , ActionManager, ExecuteCodeAction, AnimationGroup, Mesh} from "babylonjs";
import {AdvancedDynamicTexture, Button, TextBlock} from 'babylonjs-gui';
import 'babylonjs-loaders'
export default class SkyBox {
engine: Engine
scene: Scene
camera: ArcRotateCamera | undefined;
table: AbstractMesh[] | undefined;
chair: AbstractMesh[] | undefined;
animationGroup: AnimationGroup | undefined;
constructor(private readonly canvas: boolean) {
this.engine = new Engine(this.canvas);
this.scene = this.CreateScene();
this.engine.runRenderLoop(() => {
this.scene.render();
})
}
CreateScene(): Scene {
const scene = new Scene(this.engine);
this.camera = new ArcRotateCamera('camera', 5, 1.3, 50, new Vector3(0, 0, 0), scene)
this.camera.attachControl(this.canvas, true)
this.camera.lowerBetaLimit = Tools.ToRadians(0)
this.camera.upperBetaLimit = Tools.ToRadians(80)
this.camera.lowerRadiusLimit = 15
const light = new HemisphericLight('light', new Vector3(1, 1, 0), scene)
light.diffuse = new Color3(1, 1, 1)
SceneLoader.ImportMeshAsync('', '/Meshes/', 'house.glb', this.scene).then((result) => {
const plane = MeshBuilder.CreatePlane('plane', { size: 1 })
plane.parent = result.meshes[0]
plane.position.y = 3
plane.position.z = 9.5
plane.position.x = -0.5
const advancedTexture = AdvancedDynamicTexture.CreateForMesh(plane, 128, 128, false)
advancedTexture.renderScale = 1
const button = Button.CreateSimpleButton('button', '进入房间')
button.width = 1
button.height = 0.5
button.color = 'white'
button.background = 'green'
button.onPointerClickObservable.add(() => {
const cameraAnimation = new Animation('cameraAnimation', 'radius', 30,
Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CONSTANT)
const Keys = [
{ frame: 0, value: this.camera!.radius },
{ frame: 60, value: 6.5 }
]
cameraAnimation.setKeys(Keys)
this.camera!.animations = []
this.camera!.animations.push(cameraAnimation)
this.camera!.lowerRadiusLimit = 3
scene.beginAnimation(this.camera, 0, 60, false, 0.6, () => {
this.camera!.upperRadiusLimit = 6.8
})
})
advancedTexture.addControl(button)
const LogoPlane = MeshBuilder.CreatePlane('logo', { width: 3, height: 1.5 }, this.scene)
LogoPlane.rotation.y = Math.PI / 2
LogoPlane.position.x = 5.9
LogoPlane.position.y = 2
LogoPlane.position.z = 1
const LogoMaterial = new StandardMaterial('logoMaterial', scene)
LogoMaterial.diffuseTexture = new Texture('/Meshes/gwise.png', scene)
LogoMaterial.emissiveColor = new Color3(0.5, 0.5, 0.5)
LogoPlane.material = LogoMaterial
})
SceneLoader.ImportMeshAsync('', '/Meshes/', 'chair.glb', this.scene).then((result) => {
this.chair = result.meshes
this.chair[0].position.x = 1.5
this.chair.forEach((mesh) => {
console.log(mesh.name)
mesh.actionManager = new ActionManager(this.scene)
mesh.actionManager.registerAction(
new ExecuteCodeAction(ActionManager.OnPickTrigger, () => {
this.animationGroup!.play(false)
})
)
})
this.createAnimation(this.chair[0])
const LinePoints = [
new Vector3(0, 0.5, 0),
new Vector3(0, 1.5, 0)
]
const line = MeshBuilder.CreateDashedLines('dashedLine', {
points: LinePoints,
dashSize: 0.5,
gapSize: 0.2,
dashNb: 20
}, this.scene)
line.parent = this.chair[0]
const disc = MeshBuilder.CreateDisc('circle', { radius: 0.3, tessellation: 60 }, this.scene)
disc.parent = this.chair[0]
disc.position.y = 1.6
disc.rotation.x = Math.PI
const advancedTexture = AdvancedDynamicTexture.CreateForMesh(disc, 128, 128, false)
advancedTexture.renderScale = 1
const textBlock = new TextBlock()
textBlock.text = '点击椅子'
textBlock.color = 'white'
textBlock.fontSize = 16
textBlock.fontWeight = '800'
advancedTexture.addControl(textBlock)
})
SceneLoader.ImportMeshAsync('', '/Meshes/', 'table.glb', this.scene).then((result) => {
this.table = result.meshes
this.table[0].position.x = -1
this.table[0].scaling = new Vector3(1.4, 1.4, 1.4)
})
return scene;
}
createAnimation(mesh: any) {
// 创建动画并作用于position属性
const positionAnimation = new Animation('move', 'position', 30,
Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CYCLE)
// 定义关键帧
let Keys = [
{ frame: 0, value: new Vector3(1.5, 0, 0) },
{ frame: 20, value: new Vector3(1, 0, -1) },
{ frame: 40, value: new Vector3(-0.5, 0, -1.5) },
{ frame: 60, value: new Vector3(-0.6, 0, -0.8) }
]
positionAnimation.setKeys(Keys)
const rotationAnimation = new Animation('rotation', 'rotation', 30,
Animation.ANIMATIONTYPE_VECTOR3, Animation.ANIMATIONLOOPMODE_CYCLE)
Keys = [
{ frame: 0, value: new Vector3(0, Math.PI, 0) },
{ frame: 20, value: new Vector3(0, Math.PI + Math.PI / 10, 0) },
{ frame: 40, value: new Vector3(0, Math.PI + Math.PI / 5, 0) },
{ frame: 60, value: new Vector3(0, Math.PI + Math.PI / 3.6) }
]
rotationAnimation.setKeys(Keys)
this.animationGroup = new AnimationGroup('Animation Group')
this.animationGroup.addTargetedAnimation(positionAnimation, mesh)
this.animationGroup.addTargetedAnimation(rotationAnimation, mesh)
this.animationGroup.normalize(0, 60)
this.animationGroup.speedRatio = 0.5
const plane = MeshBuilder.CreatePlane('plane', { size: 0.3 })
plane.parent = this.table![0]
plane.position.y = 1
plane.billboardMode = Mesh.BILLBOARDMODE_ALL
const advancedTexture = AdvancedDynamicTexture.CreateForMesh(plane, 128, 128, false)
advancedTexture.renderScale = 1
const button = Button.CreateSimpleButton('button', '离开房间')
button.width = 1
button.height = 0.5
button.color = 'white'
button.background = 'green'
button.onPointerClickObservable.add(() => {
const cameraAnimation = new Animation('cameraAnimation', 'radius', 30,
Animation.ANIMATIONTYPE_FLOAT, Animation.ANIMATIONLOOPMODE_CONSTANT)
const Keys = [
{ frame: 0, value: this.camera!.radius },
{ frame: 60, value: 50 }
]
cameraAnimation.setKeys(Keys)
this.camera!.animations = []
this.camera!.animations.push(cameraAnimation)
this.camera!.upperRadiusLimit = 60
this.scene.beginAnimation(this.camera, 0, 60, false, 0.6, () => {
this.camera!.lowerRadiusLimit = 15
})
})
advancedTexture.addControl(button)
}
}