|
@@ -13,7 +13,7 @@ export default class App {
|
|
|
|
|
|
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);
|
|
|
+ // scene.activeCamera.attachControl(scene.canvas, true);
|
|
|
camera1.inertia = 0
|
|
|
camera1.minZ = 0
|
|
|
camera1.fov = settings.camera.fov
|
|
@@ -25,28 +25,11 @@ export default class App {
|
|
|
camera1.angularSensibilityX /= 2;
|
|
|
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)
|
|
|
+ this.cameraControlEnable = true
|
|
|
|
|
|
// 人物相机射线
|
|
|
this.ray = new BABYLON.Ray(new BABYLON.Vector3(0,0,0), new BABYLON.Vector3(0,0,1), 50);
|
|
|
- BABYLON.RayHelper.CreateAndShow(this.ray, scene, new BABYLON.Color3(1, 0.1, 0.1));
|
|
|
+ // BABYLON.RayHelper.CreateAndShow(this.ray, scene, new BABYLON.Color3(1, 0.1, 0.1));
|
|
|
|
|
|
// Lights
|
|
|
var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, -1, 0), scene);
|
|
@@ -72,6 +55,7 @@ export default class App {
|
|
|
}
|
|
|
|
|
|
init() {
|
|
|
+
|
|
|
let self = this
|
|
|
BABYLON.SceneLoader.ImportMesh("", "../scenes/house/", "000.glb", this.scene, function (newMeshes, particleSystems, skeletons, animationGroups) {
|
|
|
|
|
@@ -79,6 +63,8 @@ export default class App {
|
|
|
self.house[0].position = new BABYLON.Vector3(0.6, 2.1, 1.5)
|
|
|
// self.house[0].position = new BABYLON.Vector3(-22, 0, 12)
|
|
|
|
|
|
+ let houseVideo = document.getElementById("houseTexture0")
|
|
|
+
|
|
|
newMeshes.forEach(m => {
|
|
|
// m.scaling.scaleInPlace(100);
|
|
|
m._geometry && (m.checkCollisions = true)
|
|
@@ -94,14 +80,13 @@ export default class App {
|
|
|
defines: houseShader.defines
|
|
|
});
|
|
|
|
|
|
- let videoTexture = new BABYLON.VideoTexture("", document.getElementById("houseTexture0"), scene)
|
|
|
+ let videoTexture = new BABYLON.VideoTexture("", houseVideo, 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.setVector3("focal_width_height", new BABYLON.Vector3(
|
|
|
- 735 * window.innerHeight / settings.video.height,
|
|
|
+ 864 * window.innerWidth / settings.video.width,
|
|
|
settings.video.width * window.innerHeight / settings.video.height,
|
|
|
window.innerHeight
|
|
|
))
|
|
@@ -122,15 +107,16 @@ export default class App {
|
|
|
|
|
|
switch (pointerInfo.type) {
|
|
|
case BABYLON.PointerEventTypes.POINTERDOWN:
|
|
|
- this.pointDown = true
|
|
|
+ this.lastFramePoint = new BABYLON.Vector2(pointerInfo.event.clientX, pointerInfo.event.clientY)
|
|
|
break;
|
|
|
|
|
|
case BABYLON.PointerEventTypes.POINTERUP:
|
|
|
- this.pointDown = false
|
|
|
+ this.lastFramePoint = null
|
|
|
+ this.lastDirc = 0
|
|
|
break;
|
|
|
|
|
|
case BABYLON.PointerEventTypes.POINTERMOVE:
|
|
|
- if(this.pointDown) this.rotateCamera()
|
|
|
+ if(this.lastFramePoint) this.cameraControl(pointerInfo)
|
|
|
break;
|
|
|
|
|
|
case BABYLON.PointerEventTypes.POINTERWHEEL:
|
|
@@ -178,73 +164,109 @@ export default class App {
|
|
|
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.6
|
|
|
+ const offset = 0 // 0.6
|
|
|
if(!info || info.distance > settings.camera.distanceFromCharactor + offset) return
|
|
|
let charactorVisi = this.charactorManager.charactor.visible
|
|
|
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)
|
|
|
|
|
|
// 根据相机位置更新人物显隐
|
|
|
if(info.distance - offset < 0.25 && charactorVisi) this.charactorManager.charactor.visible = false
|
|
|
if(info.distance - offset >= 0.25 && !charactorVisi) this.charactorManager.charactor.visible = true
|
|
|
|
|
|
- // 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
|
|
|
+ /**
|
|
|
+ * 鼠标移动时,计算xoffset,得到旋转方向
|
|
|
+ * xoffset越大,瞬时速度越快,转的角度就越大
|
|
|
+ * 指定xoffset大于一定值的帧,根据旋转方向和角度请求视频,相机animation改alpha与视频一致
|
|
|
+ * 视频旋转中,计算每帧的xoffset,如果方向没变,不再发出请求
|
|
|
+ * 如果方向相反,根据瞬时速度请求新视频,并停止当前动画,播放新动画
|
|
|
+ */
|
|
|
+ cameraControl(pointerInfo) {
|
|
|
+
|
|
|
+ if(!this.charactorManager || !this.charactorManager.charactor || !this.cameraControlEnable) return
|
|
|
|
|
|
let charactor = this.charactorManager.charactor
|
|
|
+ let currentFramePoint = new BABYLON.Vector2(pointerInfo.event.clientX, pointerInfo.event.clientY)
|
|
|
+ let pointerOffset = currentFramePoint.clone().subtract(this.lastFramePoint).length()
|
|
|
+ let dirc = Math.sign(this.lastFramePoint.x - currentFramePoint.x)
|
|
|
+ if(!this.lastDirc) this.lastDirc = 0
|
|
|
+
|
|
|
+ // 一般来说瞬时距离不会超过100,定100时转180度
|
|
|
+ let alphaOffset = pointerOffset / 100 * Math.PI
|
|
|
+ alphaOffset *= dirc
|
|
|
|
|
|
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)
|
|
|
+ else if(dirc != 0 && dirc * this.lastDirc <= 0) {
|
|
|
+
|
|
|
let currentPath = charactor.walkData.pathArr[charactor.walkData.currentPoint]
|
|
|
let startPoint = (currentPath && currentPath.point) || charactor.mesh.position
|
|
|
+
|
|
|
+ let pointData = this.charactorManager.getClosestPointData(startPoint)
|
|
|
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)
|
|
|
- }
|
|
|
+ video: [pointData.id],
|
|
|
+ reverse: dirc < 0
|
|
|
}
|
|
|
+ // window.connection.socket.emit("getPush", sendData)
|
|
|
|
|
|
- window.connection.socket.emit("RotateCamera", sendData)
|
|
|
+ this.rotateCamera(alphaOffset)
|
|
|
+ }
|
|
|
|
|
|
- // setTimeout(() => {
|
|
|
- // // this.lastCameraAlpha = this.camera.alpha
|
|
|
- // this.lockCamera(false)
|
|
|
- // }, 10)
|
|
|
+ this.lastFramePoint = currentFramePoint
|
|
|
+ this.lastDirc = dirc
|
|
|
+ }
|
|
|
|
|
|
- // todo 发送数据
|
|
|
- // common.postData("", sendData).then(response => {
|
|
|
+ rotateCamera(alphaOffset, func) {
|
|
|
+ // todo
|
|
|
+ let video0 = document.getElementById("houseTexture0")
|
|
|
+
|
|
|
+ let startTime = Math.abs(this.camera.alpha) % (Math.PI * 2) / (Math.PI * 2) * video0.duration
|
|
|
+ let durtime = Math.abs(alphaOffset / (Math.PI * 2) * video0.duration)
|
|
|
+
|
|
|
+ if(video0.paused) {
|
|
|
+ video0.currentTime = startTime
|
|
|
+ video0.play()
|
|
|
+
|
|
|
+ // if(dirc * this.lastDirc < 0) {
|
|
|
+ // 清除已有动画再播新动画
|
|
|
+ this.scene.stopAnimation(this.camera, "rotateCamera")
|
|
|
+ // }
|
|
|
+
|
|
|
+ const rotateAni = new BABYLON.Animation("rotateCamera", "alpha", settings.video.frameRate,
|
|
|
+ BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_RELATIVE);
|
|
|
+
|
|
|
+ let rotateCameraFrameNum = settings.video.frameRate * durtime
|
|
|
+ const rotateFrames = [{
|
|
|
+ frame: 0,
|
|
|
+ value: this.camera.alpha
|
|
|
+ },{
|
|
|
+ frame: rotateCameraFrameNum,
|
|
|
+ value: this.camera.alpha + alphaOffset
|
|
|
+ }];
|
|
|
+
|
|
|
+ rotateAni.setKeys(rotateFrames);
|
|
|
+
|
|
|
+ this.scene.beginDirectAnimation(this.camera, [rotateAni], 0, rotateCameraFrameNum, false, 1,
|
|
|
+ () => {
|
|
|
+ this.lastDirc = 0
|
|
|
+ video0.pause()
|
|
|
+ func && func()
|
|
|
+ });
|
|
|
|
|
|
- // this.updateHouseVideo(response[0].video)
|
|
|
-
|
|
|
- // // this.lastCameraAlpha = this.camera.alpha
|
|
|
- // this.lockCamera(false)
|
|
|
-
|
|
|
- // })
|
|
|
-
|
|
|
- this.lastCameraAlpha = this.camera.alpha
|
|
|
+ } else {
|
|
|
+ // console.error("-------------")
|
|
|
+ video0.pause()
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
lockCamera(isTrue) {
|
|
|
- this.camera.lowerAlphaLimit = isTrue ? this.camera.alpha : null
|
|
|
- this.camera.upperAlphaLimit = isTrue ? this.camera.alpha : null
|
|
|
+ this.cameraControlEnable = isTrue
|
|
|
+ // this.camera.lowerAlphaLimit = isTrue ? this.camera.alpha : null
|
|
|
+ // this.camera.upperAlphaLimit = isTrue ? this.camera.alpha : null
|
|
|
}
|
|
|
|
|
|
updateHouseVideo(video) {
|
|
@@ -255,42 +277,4 @@ export default class App {
|
|
|
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 }
|
|
|
- // }
|
|
|
}
|