123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- import CharactorManager from "./CharactorManager.js";
- import common from "./common.js";
- import houseShader from "./houseShader.js";
- import settings from "./settings.js";
- export default class App {
- constructor(engine) {
-
- var scene = new BABYLON.Scene(engine);
- this.scene = scene
- scene.collisionsEnabled = true;
-
- var camera1 = new BABYLON.ArcRotateCamera("camera1", 0, Math.PI / 2, 10, new BABYLON.Vector3(0, 0, 0), scene);
- scene.activeCamera = camera1;
- scene.activeCamera.attachControl(scene.canvas, true);
- camera1.inertia = 0
- camera1.minZ = 0
- camera1.fov = Math.PI / 2
- camera1.fovMode = BABYLON.ArcRotateCamera.FOVMODE_HORIZONTAL_FIXED
- camera1.lowerBetaLimit = Math.PI / 2
- camera1.upperBetaLimit = Math.PI / 2
- camera1.lowerRadiusLimit = settings.camera.distanceFromCharactor;
- camera1.upperRadiusLimit = settings.camera.distanceFromCharactor;
- camera1.wheelDeltaPercentage = 0.01;
- camera1.angularSensibilityX /= 2;
- // camera1.targetScreenOffset = new BABYLON.Vector2(0, -1.65)
- this.camera = camera1
- this.lastCameraAlpha = 0
- // camera1.checkCollisions = true;
- // camera1.collisionRadius = new BABYLON.Vector3(0.1, 0.1, 0.1)
-
- // let self = this
- // var ray = new BABYLON.Ray(new BABYLON.Vector3(0,0,0), new BABYLON.Vector3(0,0,1), 50);
- // BABYLON.RayHelper.CreateAndShow(ray, scene, new BABYLON.Color3(1, 0.1, 0.1));
- // camera1.onCollide = function(mesh) {
- // let targetPos = camera1.position.clone()
- // targetPos.y = 1
- // ray.origin = self.charactorManager.charactor.mesh.position
- // ray.direction = BABYLON.Vector3.Normalize( targetPos.subtract(ray.origin) )
- // var info = ray.intersectsMesh(mesh);
- // if(!info.distance) return
- // camera1.lowerRadiusLimit = Math.max(info.distance - 0.5, 0.2)
- // camera1.upperRadiusLimit = Math.max(info.distance - 0.5, 0.2)
- // console.error(info.distance)
- // }
- // console.error(camera1)
-
- var ray = new BABYLON.Ray(new BABYLON.Vector3(0,0,0), new BABYLON.Vector3(0,0,1), 50);
- BABYLON.RayHelper.CreateAndShow(ray, scene, new BABYLON.Color3(1, 0.1, 0.1));
- this.ray = ray
-
- // Lights
- var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, -1, 0), scene);
- light.intensity = 1.0;
- light.specular = BABYLON.Color3.Black();
-
- var light2 = new BABYLON.HemisphericLight("dir01", new BABYLON.Vector3(0, 1, 0), scene);
- light2.intensity = 0.1;
- light2.position = new BABYLON.Vector3(0, 5, 5);
-
- // Skybox
- var skybox = BABYLON.MeshBuilder.CreateBox("skyBox", { size: 1000.0 }, scene);
- var skyboxMaterial = new BABYLON.StandardMaterial("skyBox", scene);
- skyboxMaterial.backFaceCulling = false;
- skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture("textures/environment.env", scene);
- skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
- skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0);
- skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
- skybox.material = skyboxMaterial;
- this.init()
- this.bindEvents()
- }
- init() {
- let self = this
- BABYLON.SceneLoader.ImportMesh("", "../scenes/house/", "000.glb", this.scene, function (newMeshes, particleSystems, skeletons, animationGroups) {
-
- self.house = newMeshes
- self.house[0].position = new BABYLON.Vector3(0.6, 2.1, 1.5)
- newMeshes.forEach(m => {
- // m.scaling.scaleInPlace(1.4);
- m._geometry && (m.checkCollisions = true)
- if(m.material)
- {
- BABYLON.Effect.ShadersStore['aFragmentShader'] = houseShader.fragment;
- BABYLON.Effect.ShadersStore['aVertexShader'] = houseShader.vertex;
-
- let shaderMaterial = new BABYLON.ShaderMaterial("shader", scene, { vertex: "a", fragment: "a", }, {
- attributes: houseShader.attributes,
- uniforms: houseShader.uniforms,
- defines: houseShader.defines
- });
-
- let videoTexture = new BABYLON.VideoTexture("", document.getElementById("houseTexture0"), scene)
- // document.getElementById("houseTexture0").play()
- // document.getElementById("houseTexture0").loop = "loop"
- shaderMaterial.setTexture("texture_video", videoTexture)
- shaderMaterial.setVector3("focal_width_height", new BABYLON.Vector3(735, settings.video.width, settings.video.height)) // 1100 470 860
- shaderMaterial.setFloat("isYUV", 0)
- m.material = shaderMaterial
- }
- });
- self.charactorManager = new CharactorManager(self)
- self.charactorManager.importCharactorModel("../scenes/charactors/", "man_YXL.glb")
- });
- }
- bindEvents() {
- this.scene.onPointerObservable.add((pointerInfo) => {
- switch (pointerInfo.type) {
- case BABYLON.PointerEventTypes.POINTERDOWN:
- this.pointDown = true
- break;
- case BABYLON.PointerEventTypes.POINTERUP:
- this.pointDown = false
- break;
- case BABYLON.PointerEventTypes.POINTERMOVE:
- if(this.pointDown) this.rotateCamera()
- break;
- case BABYLON.PointerEventTypes.POINTERWHEEL:
- break;
- case BABYLON.PointerEventTypes.POINTERPICK:
- break;
- case BABYLON.PointerEventTypes.POINTERTAP:
- if(pointerInfo.pickInfo.hit && this.house.indexOf(pointerInfo.pickInfo.pickedMesh)) {
- this.charactorManager.clickHouse()
- }
- break;
- case BABYLON.PointerEventTypes.POINTERDOUBLETAP:
- break;
- }
- });
- this.scene.onBeforeAnimationsObservable.add(() => {
- if(this.charactorManager && this.charactorManager.charactor)
- this.charactorManager.onBeforeAnimation()
- })
- this.scene.onBeforeRenderObservable.add(() => {
- this.updateCameraPos()
- })
- }
- updateCameraPos() {
- if(!this.charactorManager || !this.charactorManager.charactor) return
-
- // 实时更新相机target
- let cameraTarget = this.charactorManager.charactor.mesh.position.clone()
- cameraTarget.y = 1.5
- this.camera.target = cameraTarget
- // 相机碰撞检测
- this.ray.origin = cameraTarget
- this.ray.direction = BABYLON.Vector3.Normalize( this.camera.position.clone().subtract(cameraTarget) )
- let info = this.ray.intersectsMeshes(this.house)[0];
- const offset = 0.5
- if(info.distance > settings.camera.distanceFromCharactor + offset) return
- this.camera.lowerRadiusLimit = Math.max( info.distance - offset, 0.1 )
- this.camera.upperRadiusLimit = Math.max( info.distance - offset, 0.1 )
- // console.error(info.pickedPoint, this.camera.position)
- // let r = this.cameraCollision()
- // this.camera.lowerRadiusLimit = Math.max( r, 0.1 )
- // this.camera.upperRadiusLimit = Math.max( r, 0.1 )
- }
- rotateCamera() {
- if(!this.charactorManager || !this.charactorManager.charactor) return
- let charactor = this.charactorManager.charactor
- if(charactor.actionType.split("-")[1] == "Walking") {
- // 行走时旋转相机,行走停止
- charactor.startWalk([], this.charactorManager)
- }
- // 根据单个点位视频的总帧数,计算每一帧的度数,只在度数至少到达一帧时,才去请求视频
- else if(Math.abs(this.camera.alpha - this.lastCameraAlpha) >= Math.PI * 2 / settings.rotateVideoFrame)
- {
- this.lockCamera(true)
- let currentPath = charactor.walkData.pathArr[charactor.walkData.currentPoint]
- let startPoint = (currentPath && currentPath.point) || charactor.mesh.position
- let sendData = {
- type: "RotateCamera",
- point: { x: startPoint.x, y: startPoint.z },
- dirc: {
- from: this.lastCameraAlpha % (Math.PI * 2),
- to: this.camera.alpha % (Math.PI * 2)
- }
- }
- setTimeout(() => {
- // this.lastCameraAlpha = this.camera.alpha
- this.lockCamera(false)
- }, 10)
- // todo 发送数据
- // common.postData("", sendData).then(response => {
-
- // this.updateHouseVideo(response[0].video)
- // // this.lastCameraAlpha = this.camera.alpha
- // this.lockCamera(false)
- // })
- this.lastCameraAlpha = this.camera.alpha
- }
- }
- lockCamera(isTrue) {
- this.camera.lowerAlphaLimit = isTrue ? this.camera.alpha : null
- this.camera.upperAlphaLimit = isTrue ? this.camera.alpha : null
- }
- updateHouseVideo(video) {
- let videoTexture = new BABYLON.VideoTexture("", video, this.scene)
- this.house.forEach(mesh => {
- mesh.material && mesh.material.setTexture("texture_video", videoTexture)
- })
- video.play()
- }
- // cameraCollision() {
- // // if(this.cameraAngle) {
- // // let {info, point, normal} = this.getRayInfoOnCircle(this.cameraAngle)
- // // if(
- // // Math.abs(info.distance - point.clone().subtract(this.ray.origin).length()) < 1 &&
- // // this.ray.origin.clone().subtract(info.pickedPoint).addInPlace(normal).length() <= 3.5
- // // ) {
- // // return this.ray.origin.clone().subtract(info.pickedPoint).addInPlace(normal).length()
- // // }
- // // else {
- // // this.cameraAngle = null
- // // return 3.5
- // // }
- // // }
- // for(let i = 0; i < Math.PI * 2; i += Math.PI / 8) {
- // let {info, point, normal} = this.getRayInfoOnCircle(i)
- // if(
- // Math.abs(info.distance - point.clone().subtract(this.ray.origin).length()) < 0.5 &&
- // (this.ray.origin.clone().subtract(info.pickedPoint).addInPlace(normal).length() - 3.5) < 0.5
- // ) {
- // // this.cameraAngle = i
- // return this.ray.origin.clone().subtract(info.pickedPoint).addInPlace(normal).length()
- // }
- // }
- // // this.cameraAngle = null
- // return 3.5
- // }
- // getRayInfoOnCircle(angle) {
- // let normal = new BABYLON.Vector3(0, 0, 0.5)
- // normal.rotateByQuaternionToRef(BABYLON.Quaternion.RotationAxis(new BABYLON.Vector3(0, 1, 0), angle), normal)
- // let point = this.camera.position.clone().addInPlace(normal) // 圆上的点坐标
- // let direction = BABYLON.Vector3.Normalize( point.clone().subtract(this.ray.origin) )
- // var ray = new BABYLON.Ray(this.ray.origin, direction, 50);
- // let info = ray.intersectsMeshes(this.house)[0];
- // return { info: info, point: point, normal: normal }
- // }
- }
|