|
@@ -19,7 +19,198 @@ var getVisiblePano = function(position, options={}){
|
|
|
return visiblePanos
|
|
|
}
|
|
|
|
|
|
+var convertTool = {
|
|
|
+ getPos2d : function(point, camera, dom){//获取一个三维坐标对应屏幕中的二维坐标
|
|
|
+ var camera = camera || player.camera;
|
|
|
+ var dom = dom || player.domElement;
|
|
|
+ var pos = point.clone().project(camera) //比之前hotspot的计算方式写得简单 project用于3转2(求法同shader); unproject用于2转3 :new r.Vector3(e.x, e.y, -1).unproject(this.camera);
|
|
|
+
|
|
|
+ var x,y;
|
|
|
+ x = (pos.x + 1) / 2 * dom.clientWidth;
|
|
|
+ y = (1 - (pos.y + 1) / 2) * dom.clientHeight;
|
|
|
|
|
|
+ var inSight = x <= dom.clientWidth && x >= 0 //是否在屏幕中
|
|
|
+ && y <= dom.clientHeight && y >= 0
|
|
|
+
|
|
|
+
|
|
|
+ return {
|
|
|
+ pos: new THREE.Vector2(x,y), // 屏幕像素坐标
|
|
|
+ vector: pos, //(范围 -1 ~ 1)
|
|
|
+ trueSide : pos.z<1, //trueSide为false时,即使在屏幕范围内可见,也是反方向的另一个不可以被渲染的点 参见Tag.update
|
|
|
+ inSight : inSight //在屏幕范围内可见
|
|
|
+ };
|
|
|
+ },
|
|
|
+
|
|
|
+ ifShelter: function(pos3d, pos2d){//检测某点在视线中是否被mesh遮挡
|
|
|
+ if(!pos2d) pos2d = this.getPos2d(pos3d);
|
|
|
+ var player = player;
|
|
|
+ var ori = new THREE.Vector3(pos2d.x, pos2d.y, -1).unproject(player.camera); //找到视线原点
|
|
|
+ var dir = pos3d.clone().sub(ori).normalize();
|
|
|
+ ray.set(ori, dir)//由外向里 因为模型从内侧是可见的所以从外侧
|
|
|
+
|
|
|
+
|
|
|
+ /* if(config.isEdit && publicObjectSet.editor.mainDesign.editing){
|
|
|
+ var o = ray.intersectObjects(publicObjectSet.editor.mainDesign.wallMeshes);
|
|
|
+ }else{ */
|
|
|
+ var o = ray.intersectObjects(player.model.colliders);
|
|
|
+ //}
|
|
|
+ var len = pos3d.distanceTo(ori);
|
|
|
+ if (o && o.length) {
|
|
|
+ for(var i=0;i<o.length;i++){
|
|
|
+ if(o[i].distance < len){ return true; }//有遮挡
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ /*
|
|
|
+ 拖拽时,获取鼠标在拖拽面上的位置(需要借助另一个intersectPlane面来计算,即和相机方向一样的面,可保证铺满屏幕)
|
|
|
+ 但是不一定能获取到,比如鼠标射线不朝向拖拽面时,即使获取也会是一个意外的反方向的交点。
|
|
|
+ */
|
|
|
+ getPosAtPlane : function(pos, info/* , mouse, camera */){ //pos:与intersectPlane的交点 见笔记
|
|
|
+ var A = pos;
|
|
|
+ var player = player;
|
|
|
+ var mouse = player.mouse;
|
|
|
+ var O = new THREE.Vector3(mouse.x, mouse.y, -1).unproject(player.camera);
|
|
|
+
|
|
|
+
|
|
|
+ if(info.y != void 0){//地面线的
|
|
|
+
|
|
|
+ var y = info.y;
|
|
|
+
|
|
|
+ if(player.mode == "floorplan"/* || Math.abs(O.x-pos.x)<0.0001 && Math.abs(O.z-pos.z)<0.0001) */){
|
|
|
+ //intersectPlane和地面平行,无交点
|
|
|
+ var x = pos.x, z = pos.z;
|
|
|
+
|
|
|
+ }else{
|
|
|
+
|
|
|
+ if(y<player.camera.position.y && O.y <= A.y /* || y>player.camera.position.y && O.y >= A.y */)return null; //鼠标射线向上。因为相机一定位于地面以上(地面不会抬高到相机上吧?),所以无交点。
|
|
|
+ if(O.y == A.y){console.log('一样??');return;}
|
|
|
+ if(A.y == y){console.log('一样2??');return;}
|
|
|
+ var r = (O.y-y)/(A.y-y);
|
|
|
+ var x = (r*A.x-O.x)/(r-1);
|
|
|
+ var z = (r*A.z-O.z)/(r-1);
|
|
|
+ }
|
|
|
+ }else{//垂直的也有越过消失点以后反向变化的情况,但使用时影响不大
|
|
|
+ var N = info.normalVec;
|
|
|
+ var P = info.pullPos;
|
|
|
+ if(N.y != 0 ){console.log('N.y != 0');return;} //仅仅支持垂直于地面的的墙壁,目前都是
|
|
|
+ if(O.z==A.z){console.log('O.z==A.z?');return;}
|
|
|
+ if(N.z!=0 && N.x != 0){//直接用这个通用的也可以,支持斜线的墙
|
|
|
+ //console.log('N.z==0 && N.x == 0?');
|
|
|
+ var c = ( N.x*(A.x-O.x) + N.y*(A.y-O.y) + N.z*(A.z-O.z));
|
|
|
+ if(c == 0){console.log("分母为0?? return;");return;}
|
|
|
+ var t = -((N.x*O.x + N.y*O.y + N.z*O.z) - (P.x*N.x + P.y*N.y + P.z*N.z) ) / c
|
|
|
+ var x = t * (A.x - O.x) + O.x;
|
|
|
+ var y = t * (A.y - O.y) + O.y;
|
|
|
+ var z = t * (A.z - O.z) + O.z;
|
|
|
+ /*原理: 已知空间直线L:(x-a)/m=(x-b)/n=(z-c)/p和空间平面π:Ax+By+Cz+D=0;
|
|
|
+ 求直线L与平面π的交点的坐标。
|
|
|
+ 把直线方程改写成参数形式:设(x-a)/m=(x-b)/n=(z-c)/p=t;
|
|
|
+ 则x=mt+a;y=nt+b;z=pt+c;代入平面π的方程得:
|
|
|
+ A(mt+a)+B(nt+b)+C(pt+c)+D=0
|
|
|
+ 由此解得t=-(Aa+Bb+Cc+D)/(Am+Bn+Cp)
|
|
|
+ 再代入参数方程即得交点的坐标(x,y,z). */
|
|
|
+ }else if(N.x ==0 ){ //z与pullPos相等
|
|
|
+ var z = P.z;
|
|
|
+ if(O.y == A.y){console.log('一样??');return;}
|
|
|
+ if(A.y == y){console.log('一样2??');return;}
|
|
|
+ if(A.z == z){console.log('一样3??');return;}
|
|
|
+ var r = (O.z-z)/(A.z-z);
|
|
|
+ var x = (r*A.x-O.x)/(r-1);
|
|
|
+ var y = (r*A.y-O.y)/(r-1);
|
|
|
+ }else if(N.z == 0){//x与pullPos相等
|
|
|
+ var x = P.x;
|
|
|
+ if(O.y == A.y){console.log('一样??');return;}
|
|
|
+ if(A.y == y){console.log('一样2??');return;}
|
|
|
+ if(A.x == x){console.log('一样3??');return;}
|
|
|
+ var r = (O.x-x)/(A.x-x);
|
|
|
+ var y = (r*A.y-O.y)/(r-1);
|
|
|
+ var z = (r*A.z-O.z)/(r-1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return new THREE.Vector3(x,y,z);
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ getMouseIntersect : function(camera, meshes, mouse){//获取鼠标和meshes交点
|
|
|
+ var raycaster = new THREE.Raycaster;
|
|
|
+ camera.updateMatrixWorld();
|
|
|
+ var origin = new THREE.Vector3(mouse.x,mouse.y,-1).unproject(camera)
|
|
|
+ , end = new THREE.Vector3(mouse.x,mouse.y,1).unproject(camera);
|
|
|
+ var dir = end.sub(origin).normalize()
|
|
|
+ raycaster.set(origin, dir);
|
|
|
+ var n = raycaster.intersectObjects(meshes);
|
|
|
+ if (0 === n.length)
|
|
|
+ return null;
|
|
|
+ return n[0];
|
|
|
+
|
|
|
+ },
|
|
|
+ ifIntersectChunks : function(A,B,options={}){//获取某个线段/射线和meshes的交点
|
|
|
+ var dir = B.clone().sub(A).normalize();
|
|
|
+ var len = options.InfinityLen ? Infinity : A.distanceTo(B) + (options.extLen||0);
|
|
|
+ var ray = new THREE.Raycaster(A.clone(), dir, 0, len);
|
|
|
+
|
|
|
+ var o = ray.intersectObjects(options.model || player.model.colliders);
|
|
|
+ if (o && o.length)return o;
|
|
|
+
|
|
|
+ if(options.throughWidth){ //允许最小宽度,防止穿过极小的缝隙导致撞墙感
|
|
|
+ var normal = math.getNormal({points:[{x:A.x, y:A.z},{x:B.x, y:B.z}]});//线段法线
|
|
|
+ normal.multiplyScalar(options.throughWidth)
|
|
|
+ var normalVec3 = new THREE.Vector3(normal.x, 0, normal.y);
|
|
|
+
|
|
|
+ var A2 = A.clone().add(normalVec3)
|
|
|
+ ray.set(A2, dir);
|
|
|
+ var o2 = ray.intersectObjects(options.model || player.model.colliders);
|
|
|
+ ray.set(A.clone().add(normalVec3.negate()), dir);
|
|
|
+ if (o2 && o2.length)return o2;
|
|
|
+ var o3 = ray.intersectObjects(options.model || player.model.colliders);
|
|
|
+ if (o3 && o3.length)return o3;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ },
|
|
|
+ getPosAtSphere : function(pos3d, toPanoPos){
|
|
|
+ var dir = pos3d.clone().sub(toPanoPos);
|
|
|
+ dir.normalize();//然后计算在球中
|
|
|
+ dir.multiplyScalar(Constants.skyRadius);
|
|
|
+ dir.add(toPanoPos);
|
|
|
+ return dir;
|
|
|
+ },
|
|
|
+ getVisiblePano: function(position,options){//获取某个坐标的可见pano。即没有遮挡的位置。
|
|
|
+ options = options || {}
|
|
|
+ var visiblePanos = [];
|
|
|
+ var wallDepth = 0.075, discScale = 0.06;
|
|
|
+ var B = position.clone();
|
|
|
+ var panos = player.model.panos.index;
|
|
|
+
|
|
|
+ for (var i in panos) {
|
|
|
+ if(!panos[i].isAligned())continue;
|
|
|
+ var A = panos[i].position.clone();
|
|
|
+
|
|
|
+ var ray = new THREE.Raycaster(A.clone(), B.clone().sub(A).normalize(), 0, A.distanceTo(B) - discScale / 2 - wallDepth);
|
|
|
+ var o = ray.intersectObjects(options.model || player.model.colliders,true);
|
|
|
+
|
|
|
+ /* if(this.snapInfo){
|
|
|
+ ray.set(A, C.clone().sub(A).normalize());
|
|
|
+ ray.far = A.distanceTo(C) - this.discScale / 2 - wallDepth
|
|
|
+ var o2 = ray.intersectObjects(this.model.colliders);
|
|
|
+ if (!o || !o.length || !o2 || !o2.length) {
|
|
|
+ this.visiblePanos.push(panos[i].id);
|
|
|
+ }
|
|
|
+ //是否要将o2的删除 如果热点准确些不会到房子外面的话。 或者如果o的可见没有时采用2
|
|
|
+
|
|
|
+ }else{ */
|
|
|
+ if (!o || !o.length)visiblePanos.push(panos[i].id);
|
|
|
+ //}
|
|
|
+ }
|
|
|
+ return visiblePanos
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
|
|
|
g_playAudio = null
|
|
|
|
|
@@ -4620,30 +4811,49 @@ function o(a, s, l) {
|
|
|
,
|
|
|
t.prototype.goToDestination = function(e, t, i, n) {
|
|
|
//音频
|
|
|
- if(this.destinationItem[1] == 0){//如果是每个folder的起始
|
|
|
- var musicInfo = this.model.heroLocations[this.destinationItem[0]].musicInfo
|
|
|
- if(musicInfo && musicInfo.music){
|
|
|
- var o = musicInfo.music.includes(g_Prefix.slice(-10)) ? musicInfo.music : g_Prefix + musicInfo.music;
|
|
|
- g_tourAudio.src = manage.dealURL(o);
|
|
|
+
|
|
|
+ var musicInfo = this.model.heroLocations[this.destinationItem[0]].musicInfo
|
|
|
+ if(musicInfo && musicInfo.music){
|
|
|
+ var o1 = musicInfo.music.includes(g_Prefix.slice(-10)) ? musicInfo.music : g_Prefix + musicInfo.music;
|
|
|
+
|
|
|
+ let audioSrc1 = g_tourAudio.src.split('/').pop();
|
|
|
+ let audioSrc2 = o1.split('/').pop();
|
|
|
+
|
|
|
+ if(audioSrc1 == audioSrc2){//应该是继续播放该folder
|
|
|
+ if(this.destinationItem[1] == 0){//从头开始播放 因为可能暂停后然后再点该缩略图播
|
|
|
+ g_tourAudio.currentTime = 0; g_tourAudio.play();
|
|
|
+ }else if(g_tourAudio.paused && g_tourAudio.currentTime < g_tourAudio.duration){//未播完
|
|
|
+ g_tourAudio.play()
|
|
|
+ }
|
|
|
+
|
|
|
+ }else{//很可能是该folder的起始
|
|
|
+ g_tourAudio.src = manage.dealURL(o1);
|
|
|
g_tourAudio.load()
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
|
|
|
if (this.onTheBus = !0,
|
|
|
this.emit("update.controls"),
|
|
|
this.player.updateLastView(),
|
|
|
- n || !this.atDestinationPano())
|
|
|
+ n || !this.atDestinationPano()){
|
|
|
if (this.player.flying || this.player.isWarping())
|
|
|
m.warn("Cannot go to new destination while player is flying or warping.");
|
|
|
else {
|
|
|
var a = this.model.getHeroDescriptorByIndex(this.destinationItem)
|
|
|
, s = null
|
|
|
, l = null;
|
|
|
- if (a.isPano()) {
|
|
|
- o = this.getMomentTour(this.destinationItem) //window.MP_PREFETCHED_MODELDATA.momentTour || "walk";
|
|
|
- l = this.player.warpToPanoByHeroIndex.bind(this.player, this.destinationItem, g.Show, f.Slow, o, !0, i, this.actionComplete.bind(this)),
|
|
|
+ if (a.isPano()) {
|
|
|
+ o1 = this.getMomentTour(this.destinationItem) //window.MP_PREFETCHED_MODELDATA.momentTour || "walk";
|
|
|
+ l = this.player.warpToPanoByHeroIndex.bind(this.player, this.destinationItem, g.Show, f.Slow, o1, !0, i, this.actionComplete.bind(this)),
|
|
|
s = this.arrivedAtDestination.bind(this, !0)
|
|
|
+
|
|
|
+ //add
|
|
|
+ if(a.zoom && a.zoom != this.player.zoomLevel){
|
|
|
+ this.player.smoothZoomFovTo(null, a.zoom, r.warp.teleportTime) //瞬间过渡的时间
|
|
|
+ }
|
|
|
+
|
|
|
} else{
|
|
|
l = this.player.warpToNonPanoByHeroIndex.bind(this.player, this.destinationItem, this.actionComplete.bind(this)),
|
|
|
s = this.arrivedAtDestination.bind(this, !1);
|
|
@@ -4656,8 +4866,15 @@ function o(a, s, l) {
|
|
|
.bind(this), s),
|
|
|
this.emit("update.controls")
|
|
|
}
|
|
|
- else
|
|
|
+ }else{
|
|
|
+ //add
|
|
|
+ var a = this.model.getHeroDescriptorByIndex(this.destinationItem)
|
|
|
+ if(a.zoom && a.zoom != this.player.zoomLevel){
|
|
|
+ this.player.smoothZoomFovTo(null, a.zoom, r.warp.teleportTime) //瞬间过渡的时间
|
|
|
+ }
|
|
|
+
|
|
|
this.arrivedAtDestination(!0)
|
|
|
+ }
|
|
|
}
|
|
|
,
|
|
|
t.prototype.tourInterlude = function() {
|
|
@@ -4919,7 +5136,7 @@ function o(a, s, l) {
|
|
|
} */
|
|
|
|
|
|
|
|
|
- var momentTour = this.getMomentTour(this.destinationItem);
|
|
|
+ /* var momentTour = this.getMomentTour(this.destinationItem);
|
|
|
if ( "black" === momentTour) { // 方奕卓 瞬间过渡, 相机缩放至1
|
|
|
var i = this.player.zoomLevel;
|
|
|
this.player.zoomEnabled = !0;
|
|
@@ -4928,23 +5145,26 @@ function o(a, s, l) {
|
|
|
}
|
|
|
.bind(this);
|
|
|
o.start(t, 1500, function() {}, 0, h.easeOutQuad, "zoom")
|
|
|
- }
|
|
|
+ } */
|
|
|
this.goToDestination()
|
|
|
}
|
|
|
,
|
|
|
- t.prototype.getMomentTour = function(destinationItem) {//add
|
|
|
- /* if(!item) return window.MP_PREFETCHED_MODELDATA.momentTour || "walk";
|
|
|
- var currentLocation = this.model.heroLocations[item[0]];
|
|
|
- var currentChildNum = currentLocation.heroLocations ? currentLocation.heroLocations.length : 1
|
|
|
- if(item[1]>=currentChildNum-1){//子目录中最后一个
|
|
|
- return window.MP_PREFETCHED_MODELDATA.momentTour || "walk";
|
|
|
- }else{
|
|
|
- return currentLocation.momentTour || "walk";
|
|
|
- } */
|
|
|
- if(!destinationItem || destinationItem[1] == 0) return window.MP_PREFETCHED_MODELDATA.momentTour || "walk";
|
|
|
+ t.prototype.getMomentTour = function(destinationItem) {//add
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ var wholeMomentTour = window.MP_PREFETCHED_MODELDATA.momentTour || "walk"; //最外层
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if(!destinationItem) return wholeMomentTour
|
|
|
else{
|
|
|
- var currentLocation = this.model.heroLocations[destinationItem[0]];
|
|
|
- return currentLocation.momentTour || "walk";
|
|
|
+ var currentLocation = this.model.getHeroDescriptorByIndex(destinationItem)//最内层。 如果有使用最内层
|
|
|
+ if(currentLocation.momentTour)return currentLocation.momentTour;
|
|
|
+
|
|
|
+ var currentLocation_ = this.model.heroLocations[destinationItem[0]];
|
|
|
+ return currentLocation_.heroLocations ? currentLocation_.momentTour : wholeMomentTour; //如果有中间层,使用中间层,否则使用最外层
|
|
|
}
|
|
|
}
|
|
|
,
|
|
@@ -16753,6 +16973,7 @@ function o(a, s, l) {
|
|
|
sid: n.sid
|
|
|
}
|
|
|
var item = new p(l);
|
|
|
+ item.momentTour = n.momentTour
|
|
|
container.push(item)
|
|
|
return item
|
|
|
}
|
|
@@ -18518,9 +18739,9 @@ function o(a, s, l) {
|
|
|
this.removeTextSprite();
|
|
|
var i = document.createElement("canvas")
|
|
|
, n = i.getContext("2d");
|
|
|
- i.width = 256,
|
|
|
- i.height = 256;
|
|
|
- n.font = "bold 60px Arial",
|
|
|
+ i.width = 1024,
|
|
|
+ i.height = i.width / ratio;
|
|
|
+ n.font = " 30px Arial",
|
|
|
n.fillStyle = "white";
|
|
|
var r = n.measureText(e).width;
|
|
|
n.fillText(e, (i.width - r) / 2, (i.height + 60) / 2);
|
|
@@ -18533,6 +18754,9 @@ function o(a, s, l) {
|
|
|
this.text3d = new s.Sprite(a),
|
|
|
this.text3d.position.copy(this.skyboxMesh.position),
|
|
|
this.floor.add(this.text3d)
|
|
|
+ var scale = 3
|
|
|
+ this.text3d.scale.y = scale/ratio
|
|
|
+ this.text3d.scale.x = scale
|
|
|
}
|
|
|
,
|
|
|
r.prototype.removeTextSprite = function() {
|
|
@@ -19102,7 +19326,7 @@ function o(a, s, l) {
|
|
|
,
|
|
|
t.prototype.getHeroDescriptorByHeroIndex = function(e) {
|
|
|
var t = this.model.heroCount();
|
|
|
- if (null !== this.warpDestHeroLoc && t < 2)
|
|
|
+ if (null !== this.warpDestHeroLoc && t < 1)
|
|
|
return H.info("ShowPath.getHeroDescriptorByHeroIndex() -> Only one hero location is available."),
|
|
|
this.model.getHeroDescriptorByIndex(0);
|
|
|
var i = this.model.getHeroDescriptorByIndex(e);
|
|
@@ -19597,6 +19821,7 @@ function o(a, s, l) {
|
|
|
var n = this.playerControls.cameras[O.PANORAMA];
|
|
|
a.setFromQuaternion(n.quaternion, D.warp.eOrder);
|
|
|
var r = i * l / o;
|
|
|
+ r = Math.sign(r) * Math.max(r, 0.0001) //add 如果音频长的话,使旋转可见,否则以为停住了
|
|
|
a.y += r,
|
|
|
s.set(0, 0, -1),
|
|
|
s.applyEuler(a),
|
|
@@ -21744,38 +21969,54 @@ function o(a, s, l) {
|
|
|
}
|
|
|
hots[index].mesh.visible = visible;
|
|
|
}
|
|
|
- },
|
|
|
+ }
|
|
|
|
|
|
-
|
|
|
+ var getQuaByAim = function (aim, center) {
|
|
|
+ return new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(0, 0, -1), aim.clone().sub(center).normalize())
|
|
|
+ //或var _ = (new THREE.Matrix4).lookAt(pano.position, aim, new THREE.Vector3(0,1,0)); aimQua = (new THREE.Quaternion).setFromRotationMatrix(_);
|
|
|
+ }
|
|
|
+
|
|
|
t.prototype.flyToPano = function(e, t) {
|
|
|
|
|
|
- //e.duration = 100
|
|
|
-
|
|
|
- var i, n = e.pano, r = e.lookAtPoint, o = e.duration, a = e.aimDuration, s = e.maxDistanceOverride, l = e.skipWarpingCheck, c = e.constantMoveSpeed, h = null, u = null;
|
|
|
+ var i, n = e.pano, aim = e.lookAtPoint, aimQua = e.quaternion,//ADD
|
|
|
+ o = e.duration, a = e.aimDuration, s = e.maxDistanceOverride,
|
|
|
+ l = e.skipWarpingCheck, c = e.constantMoveSpeed, h = null, u = null
|
|
|
+ if (aim) aimQua = getQuaByAim(aim, n.position)
|
|
|
+ else aimQua = aimQua
|
|
|
+
|
|
|
+ var zoomLevel = e.zoomLevel || 1 //add
|
|
|
+
|
|
|
|
|
|
+ if(this.flying) return t && t(e)
|
|
|
if (window.specialScene && specialScene.special().specifySpot && specialScene.special().specifySpot(n),
|
|
|
this.isWarping() && !l && (this.path.activeTransType === R.BLACK || this.path.activeTransType === R.STD))
|
|
|
return Y.warn("Player.flyToPano() -> Cannot fly when warping"),
|
|
|
t && t(),
|
|
|
!1;
|
|
|
- if (this.updateLastView(),
|
|
|
- this.mode !== V.PANORAMA)
|
|
|
- return r && (i = (new B.Quaternion).setFromUnitVectors(T.FORWARD, r.sub(n.position).normalize())),
|
|
|
+
|
|
|
+ this.updateLastView()
|
|
|
+ if (this.mode !== V.PANORAMA)
|
|
|
+
|
|
|
void this.flyToNewMode({
|
|
|
mode: V.PANORAMA,
|
|
|
pano: n,
|
|
|
duration: o,
|
|
|
- quaternion: i,
|
|
|
+ quaternion: aimQua,
|
|
|
callback: t
|
|
|
});
|
|
|
- if (!n || (h = x.deepExtend(e),
|
|
|
- u = function() {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (!n || (h = x.deepExtend(e), u = function() {
|
|
|
j.delayOneFrame(function() {
|
|
|
this.flyToPano(h, t)
|
|
|
- }
|
|
|
- .bind(this))
|
|
|
- }
|
|
|
- .bind(this),
|
|
|
+
|
|
|
+ }.bind(this))
|
|
|
+
|
|
|
+ }.bind(this),
|
|
|
+
|
|
|
+
|
|
|
!this.checkAndWaitForPanoLoad(n, "high", "low", this.basePanoSize, u))) {
|
|
|
var d = function(e) {
|
|
|
t && t(e)
|
|
@@ -21790,40 +22031,44 @@ function o(a, s, l) {
|
|
|
var f = s || k.transition.flytimeMaxDistanceThreshold;
|
|
|
p = Math.min(this.currentPano.position.distanceTo(n.position), f) * k.transition.flytimeDistanceMultiplier + k.transition.flyTime
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
if (.01 < k.transition.flySpeed && (p = 1e3 * this.currentPano.position.distanceTo(n.position) / k.transition.flySpeed),
|
|
|
- 1 !== this.zoomLevel)
|
|
|
+ zoomLevel !== this.zoomLevel)
|
|
|
switch (k.zoom.transitionStyle) {
|
|
|
case 1:
|
|
|
- this.smoothZoomToDefault(p / 2);
|
|
|
+ this.smoothZoomFovTo(null, zoomLevel, zoomLevel == 1 ? p / 2 : p); //改
|
|
|
break;
|
|
|
case 2:
|
|
|
return h = x.deepExtend(e),
|
|
|
u = this.flyToPano.bind(this, h, t),
|
|
|
- void this.smoothZoomToDefault(k.zoom.restoreTime * (this.zoomLevel - 1), u)
|
|
|
+ void this.smoothZoomFovTo(null, zoomLevel, k.zoom.restoreTime * (this.zoomLevel - 1), u)
|
|
|
}
|
|
|
- if (r) {
|
|
|
+
|
|
|
+
|
|
|
+ if (aimQua) {
|
|
|
G.cancelById(q.LookTransition),
|
|
|
p *= k.transition.aimSlowFactor;
|
|
|
- var g = this.cameraControls.activeControl.camera.quaternion.clone()
|
|
|
- , m = (new B.Matrix4).lookAt(n.position, r, T.UP)
|
|
|
- , v = (new B.Quaternion).setFromRotationMatrix(m)
|
|
|
+ var g = this.cameraControls.activeControl.camera.quaternion.clone()
|
|
|
+
|
|
|
+
|
|
|
, y = g.clone()
|
|
|
, A = new B.Vector3;
|
|
|
if (n === this.currentPano) {
|
|
|
var C = T.FORWARD.clone().applyQuaternion(g)
|
|
|
- , I = T.FORWARD.clone().applyQuaternion(v)
|
|
|
+ , I = T.FORWARD.clone().applyQuaternion(aimQua)
|
|
|
, E = C.angleTo(I);
|
|
|
return null != a || (a = 1 * Math.sqrt(E) / k.tags.navigate.rotateSpeedFactor * 1e3),
|
|
|
void G.start(function(e) {
|
|
|
y.copy(g),
|
|
|
- H.quaternion(y, v)(e),
|
|
|
+ H.quaternion(y, aimQua)(e),
|
|
|
A.copy(T.FORWARD).applyQuaternion(y).add(this.cameraControls.activeControl.camera.position),
|
|
|
this.cameraControls.activeControl.lookAt(A)
|
|
|
}
|
|
|
.bind(this), a, d, 0, z[k.transition.movementEasing], null, q.LookTransition)
|
|
|
}
|
|
|
}
|
|
|
- if (n === this.currentPano || this.flying)
|
|
|
+ if (n === this.currentPano )
|
|
|
return void d();
|
|
|
this.flying = !0;
|
|
|
var _ = this.position.clone()
|
|
@@ -21840,9 +22085,9 @@ function o(a, s, l) {
|
|
|
|
|
|
|
|
|
|
|
|
- r && G.start(function(e) {
|
|
|
+ aimQua && G.start(function(e) {
|
|
|
y.copy(g),
|
|
|
- H.quaternion(y, v)(e),
|
|
|
+ H.quaternion(y, aimQua)(e),
|
|
|
A.copy(T.FORWARD).applyQuaternion(y).add(this.cameraControls.activeControl.camera.position),
|
|
|
this.cameraControls.activeControl.lookAt(A)
|
|
|
}
|
|
@@ -21878,9 +22123,6 @@ function o(a, s, l) {
|
|
|
}
|
|
|
,
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
window._transitionPosId = 9999
|
|
|
|
|
|
t.prototype.transitionPos = function(o={}) {//渐变overlay和热点的位置
|
|
@@ -22245,7 +22487,7 @@ function o(a, s, l) {
|
|
|
this.transitionPos({type:"beforeFlyOut", dur:p/2})//add
|
|
|
}
|
|
|
if(this.mode == 'panorama'){
|
|
|
- this.overlayGroup.visible = false;
|
|
|
+ //this.overlayGroup.visible = false;
|
|
|
this.overlayGroup.children.forEach((overlay)=>{
|
|
|
overlay.overlayType == "video" && overlay.plane.material.map.image.pause()
|
|
|
})
|
|
@@ -22349,7 +22591,7 @@ function o(a, s, l) {
|
|
|
this.overlayGroup.visible = true;
|
|
|
Overlay.updateVisibles([this.currentPano])
|
|
|
}else{
|
|
|
- //Overlay.updateVisibles(true)
|
|
|
+ Overlay.updateVisibles(true)
|
|
|
}
|
|
|
|
|
|
c && u !== V.PANORAMA && i === V.PANORAMA ? this.startWarp(M.Retain, S.Retain, R.BLACK, null, null, a) : (a && a(),
|
|
@@ -22522,20 +22764,20 @@ function o(a, s, l) {
|
|
|
var currentLocation = this.model.heroLocations[this.director.currentItem[0]]
|
|
|
var restChildCount = currentLocation.heroLocations ? (currentLocation.heroLocations.length-this.director.currentItem[1]-1) : 0
|
|
|
var current = g_tourAudio ? 1e3 * g_tourAudio.currentTime : 0
|
|
|
- var waitTime = currentLocation && currentLocation.musicInfo.music ? currentLocation.musicInfo.time - current : 2e3;
|
|
|
+ var rotTime = currentLocation && currentLocation.musicInfo.music ? currentLocation.musicInfo.time - current : 2e3;
|
|
|
|
|
|
if(restChildCount){//如果当前folder中还有剩下的item,平分一下时间
|
|
|
var timeEachItem = 2000;//假设每个item飞的时间
|
|
|
- var waitTime = Math.max(0, (waitTime-timeEachItem*restChildCount) / (restChildCount+1));
|
|
|
+ var rotTime = (rotTime-timeEachItem*restChildCount) / (restChildCount+1);
|
|
|
|
|
|
}
|
|
|
-
|
|
|
- console.log("waitTime "+waitTime +" at item "+this.director.currentItem + ",musicCurrentTime:"+current)
|
|
|
+ rotTime = Math.max(0, rotTime)
|
|
|
+ console.log("rotTime "+rotTime +" at item "+this.director.currentItem + ",musicCurrentTime:"+current)
|
|
|
|
|
|
this.path.waitNextStep(e, function() {//等待音乐播放一段时间再下一步,此时镜头会缓慢旋转
|
|
|
t && t()
|
|
|
}
|
|
|
- .bind(this), waitTime)
|
|
|
+ .bind(this), rotTime)
|
|
|
}
|
|
|
,
|
|
|
t.prototype.stopInterlude = function() {
|
|
@@ -22660,6 +22902,22 @@ function o(a, s, l) {
|
|
|
G.start(r, e, o, null, 0, z[k.transition.blendEasing])
|
|
|
}
|
|
|
,
|
|
|
+ t.prototype.smoothZoomFovTo = function (fov, zoomLevel, dur, callback) {//add
|
|
|
+
|
|
|
+ var i,
|
|
|
+ n = this.zoomLevel,
|
|
|
+ aimLevel = zoomLevel || this.baseFov / fov
|
|
|
+
|
|
|
+ if (n == aimLevel) return
|
|
|
+
|
|
|
+ var fun = function (e) {
|
|
|
+ e > 1 && (e = 1), (i = n * (1 - e) + e * aimLevel), this.zoomTo(i, !0)
|
|
|
+ }.bind(this)
|
|
|
+
|
|
|
+ G.start(fun, dur, callback, null, 0, z[k.transition.easeInCubic])
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
t.prototype.updateZoomPano = function() {
|
|
|
if (!this.panoRenderer.zoomPanoRenderingDisabled && this.mode === V.PANORAMA) {
|
|
|
var e = this.currentPano;
|
|
@@ -23331,7 +23589,7 @@ function o(a, s, l) {
|
|
|
e.visible = !1
|
|
|
})),
|
|
|
i.cursor.visible = e,
|
|
|
- i.setSize(window.innerWidth, window.innerHeight),
|
|
|
+ i.setSize($("#player").width(), $("#player").height()),
|
|
|
window._vrEnabled = e,
|
|
|
setTimeout(function() {
|
|
|
console.log(player.cameraControls.activeControl.camera.fov)
|
|
@@ -29014,11 +29272,33 @@ function o(a, s, l) {
|
|
|
extend: function(e, t) {
|
|
|
for (var i in t.prototype)
|
|
|
e.prototype[i] = t.prototype[i]
|
|
|
+ },
|
|
|
+ getVisiblePano : function(position, options={}){//add
|
|
|
+ var visiblePanos = [];
|
|
|
+ var B = position.clone();
|
|
|
+ var panos = options.panos || player.model.panos.list;
|
|
|
+
|
|
|
+ panos.forEach((pano)=>{
|
|
|
+ if(!pano.isAligned())return;
|
|
|
+ var A = pano.position.clone();
|
|
|
+
|
|
|
+ var ray = new THREE.Raycaster(A.clone(), B.clone().sub(A).normalize(), 0, A.distanceTo(B) - (options.tolerance||0) )
|
|
|
+ var o = ray.intersectObjects(options.model || player.model.colliders, true);
|
|
|
+
|
|
|
+
|
|
|
+ if (!o || !o.length)visiblePanos.push(pano );
|
|
|
+
|
|
|
+
|
|
|
+ })
|
|
|
+
|
|
|
+ return visiblePanos
|
|
|
+
|
|
|
}
|
|
|
},
|
|
|
Math.sign = function(e) {
|
|
|
return e < 0 ? -1 : 1
|
|
|
}
|
|
|
+ window.common = t.exports
|
|
|
}
|
|
|
, {
|
|
|
three: 217
|
|
@@ -29456,6 +29736,7 @@ function o(a, s, l) {
|
|
|
};
|
|
|
},
|
|
|
}
|
|
|
+ window.math = t.exports
|
|
|
}
|
|
|
, {
|
|
|
"../constants": 8,
|