瀏覽代碼

更新一波

xzw 3 年之前
父節點
當前提交
bb960e70c1
共有 3 個文件被更改,包括 909 次插入621 次删除
  1. 122 52
      public/SuperTwo/js/Hot.js
  2. 141 470
      public/SuperTwo/js/main_2020_show.js
  3. 646 99
      public/SuperTwo/js/manage.js

+ 122 - 52
public/SuperTwo/js/Hot.js

@@ -1,6 +1,6 @@
  
 //合并热点和展览 
-
+g_currentHot = null
 
 window.initHot = function(model){
     
@@ -34,7 +34,7 @@ window.initHot = function(model){
         opacity: 0.8,
         side:THREE.DoubleSide
     })
-    
+    var autoSizeInfo = {minSize : 120,  maxSize : 600,   nearBound : 1 , farBound :  15}
 
     var hotGroup = new THREE.Object3D;  hotGroup.name = "hotGroup"
     model.add(hotGroup);   model.hotGroup = hotGroup
@@ -398,6 +398,7 @@ window.initHot = function(model){
                     }
                     this.changeShineTex(this.styleImg)
                 }
+                this.info.texSrc = null
             }
             if(this.material_.map){
                 /*  this.material_.map.minFilter = THREE.LinearFilter;
@@ -741,7 +742,7 @@ window.initHot = function(model){
              
             let maxCount = browser.isMobile() ? 2000 : 5000
             let c = model.panos.list.length * model.colliders.length
-            if(settings.isEdit || c < maxCount){  
+            if(window.isEdit ||  c < maxCount){  //编辑页面保险起见还是全部算完后才可浏览,就能保证保存全部的visiblePano
                 this.info.visiblePanos = common.getVisiblePano(customPositions,  model.panos.list, {
                     model: model.colliders , posAtPanos  
                 })  
@@ -771,8 +772,8 @@ window.initHot = function(model){
         
             
         updateVisible(panos, visibility) { 
-            if(settings.isEdit && editTool.hotpoint.editSpot == this){
-                return true
+            if(window.isEdit && editTool.hotpoint.editSpot == this){
+                return this.visible = true
             }
             
             this.visible = visibility != void 0 ? visibility : (!this.info.visiblePanos || !!panos.find(pano=>this.info.visiblePanos.includes(pano.id)))
@@ -901,7 +902,7 @@ window.initHot = function(model){
         
         inSight(){
             //return true
-            if(settings.isEdit)return true // 太容易move了
+            if(window.isEdit)return true // 太容易move了
              
             if(player.mode == 'panorama'){
                 if(!player.camera) return
@@ -950,10 +951,21 @@ window.initHot = function(model){
                 this.quaternion.copy(player.camera.quaternion)
             }
             
-            
+            this.updateScale()
         }
                     
-                    
+        updateScale(e, t) {//自适应调节大小 
+            if(!DATA.autoAdjustHotScale || this.texType != 'shine' )return
+            //let renderSize = player.sceneRenderer.renderer.domElement 
+            let renderSize = player.sceneRenderer.renderer.getSize()
+            
+            var scale = convertTool.getScaleForConstantSize($.extend(autoSizeInfo,{
+                camera:player.camera,  resolution:{x:renderSize.width, y:renderSize.height},
+                position: this.position.clone() ,
+            }))
+            this.plane.scale.set(scale,scale,scale)
+            
+        }                
 
 
         switchPlay(state){//手动播放暂停 
@@ -1072,47 +1084,67 @@ window.initHot = function(model){
             var i = []
               , n = []
               , r = this.mesh.getWorldPosition();
-            /* if (e === "panorama") {
-                var o = t.position.clone().sub(r).normalize();
-                n.push(function(t, i) {//scoreFunctions.direction
+            if (e === "panorama") {
+                /* var o = t.position.clone().sub(r).normalize();
+                n.push(function(t, i) {//scoreFunctions.direction 最好这个漫游点在currentPano到热点之间的路径上。但是这样的话可能就看不到热点正面,所以删掉
                     return function(e) {
-                        return e.position.clone().sub(t).normalize().dot(i) * window._settings.navigation.directionFactor
+                        return e.position.clone().sub(t).normalize().dot(i) * window._settings.navigation.directionFactor 
                     }}(r, o)
-                )
-            } */
+                ) */  
+            }
             var a = new THREE.Vector3;
             i.push(function(e) {
                     return Math.abs(e.position.x - r.x) > window._settings.tags.visibility.cameraClearance   || Math.abs(e.position.z - r.z) > window._settings.tags.visibility.cameraClearance  
-                }, function(e) {
+                },
+
+                function(e) {
                     a.copy(r).sub(e.position);
                     var t = -THREE.Math.radToDeg(Math.atan(a.y / Math.sqrt(a.x * a.x + a.z * a.z)))
                       , i = window._settings.tags.navigate.tiltTolerance 
                     return window._settings.insideLookLimitDown - i < t && t < window._settings.insideLookLimitUp + i
-                }, 
+                },
+                
                 (pano)=>{ // add
                     return player.checkHasNeighbor(pano) 
-                }
-     
-            ),
-            n.push(  function(t, i) {//scoreFunctions.distanceSquared
-                    return i = i || a.navigation.distanceFactor,
-                    function(e) {
-                        return t ? t.position.distanceToSquared(e.position) * i : 0
+                },
+                
+                (pano)=>{ // add
+                    return this.info.visiblePanos.includes(pano.id)
+                }    
+            )
+            n.push(
+                (function(hot, i) {   //scoreFunctions.distanceSquared
+                    return  function(pano) {
+                        //i = a.navigation.distanceFactor
+                        return hot ? hot.position.distanceToSquared(pano.position) * i : 0
                     }
-                }(this, -2));
+                })(this, -2)
+                ,
+                
+                (pano)=>{//尽量正对hot
+                    let dir = new THREE.Vector3(0,0,1).applyQuaternion(this.quaternion)
+                    let dir2 = new THREE.Vector3().subVectors(pano.position, this.position).normalize();
+                    let s = dir.dot(dir2) * 10;
+                    //console.log(pano.id + ":" + s)
+                    return s
+                } 
+            
+            );
+                
+                
             var s = t.model.panos.sortByScore(i, n);
-            /* if (s && window._settings.tags.navigate.lineOfSight) {
-                for (var l = 0; l < s.length; l++) {
-                    var c = s[l].pano
-                      , h = c.position.distanceTo(r);
-                    p.set(c.position, r.clone().sub(c.position).normalize());
-                    var u = p.intersectObjects(t.model.colliders);
-                    if (0 === u.length || u[0].distance > h)
-                        return console.log(l),
-                        c
-                }
-                return null
-            } */
+             
+                                                    
+                                     
+                                                     
+                                                                             
+                                                                  
+                                                            
+                                              
+                         
+                 
+                           
+                
             return s && 0 < s.length && s[0].pano
         }
          
@@ -1171,12 +1203,8 @@ window.initHot = function(model){
                     div.appendChild(exit);
                     div.appendChild(myElement)
                     
+                    SoundManager.play('hot')
                     
-                    if(g_bgAudio && !g_bgAudio.paused){
-                        manage.switchBgmState(false); 
-                        g_bgAudio.pauseByHot = true
-                    } 
-                    if(g_tourAudio)g_tourAudio.pause()
                     
                 }
                 
@@ -1195,11 +1223,7 @@ window.initHot = function(model){
                 popup.style.display = "block",
                 popup.classList.add("wait");
                 var n = document.createElement("iframe");
-                if(g_bgAudio && !g_bgAudio.paused){
-                    manage.switchBgmState(false); 
-                    g_bgAudio.pauseByHot = true
-                } 
-                if(g_tourAudio)g_tourAudio.pause()
+                SoundManager.play('hot')
                 var src = getLink(this.info.link   )
                 n.src = src;
                 n.id = "id1",
@@ -1237,7 +1261,7 @@ window.initHot = function(model){
                 return;
             }
         
-            var c = /* m.tags.navigate.nearestPano && */ this.closestPanoTowardTag(player.mode, player.currentPano) || player.currentPano
+            var c = this.closestPanoTowardTag(player.mode, player.currentPano) || player.currentPano
               , h = this.mesh.getWorldPosition();
             player.flyingToTag = !0;
             
@@ -1381,7 +1405,7 @@ window.initHot = function(model){
             
             if(type == 'photo'){
                 if(this.photoHasRequestLoad || this.texType != 'photo')return;
-                console.log('overlay beginDownload : ' + this.sid)
+                //console.log('overlay beginDownload : ' + this.sid)
                 
                  
                 /* this.material_.map =  */Texture.load(this.info.texSrc, (tex)=>{ 
@@ -1397,14 +1421,14 @@ window.initHot = function(model){
                         if(e.info.texSrc == this.info.texSrc && e.info.texType == type){ 
                             e.material_.color.set("#FFFFFF") 
                             e.material_.opacity = 1;
-                            console.log('overlay loaded: ' + e.sid + " - " + this.info.texSrc.split('/').pop());
+                            //console.log('overlay loaded: ' + e.sid + " - " + this.info.texSrc.split('/').pop());
                         
                         
                              
                             e.texMedia = tex.image
 
                             {//animation不同致使的不能使用同一个texture 
-                                if(settings.isEdit){
+                                if(window.isEdit){
                                     if(animateTexSrcs[e.info.texSrc]){
                                         e.material_.map = tex.clone(); //编辑动画直接不用一个texture, 故而animation也不同
                                         e.material_.map.needsUpdate = true
@@ -1497,7 +1521,7 @@ window.initHot = function(model){
     }
     
     Hot.beginShineHot = function(){  
-        if(!settings.isEdit && shineMats.length == 0)return
+        if(!window.isEdit && shineMats.length == 0)return
         
         
         transitions.trigger({
@@ -1626,8 +1650,54 @@ window.initHot = function(model){
     }  
      */
      
+    //判断是否是移动端,如果是给关闭按钮添加touchstart事件
     
-
+    
+     
+    
+    Hot.closePopup = ()=>{// 关闭热点页面
+        if(!g_currentHot) return;
+        g_currentHot = null;
+        var hotPop = document.getElementById('popup'); 
+            hotPop.style.display = "none";
+        document.querySelector(".popup-content").removeChild(document.getElementById("id1"));
+        $("#popup iframe:last").remove();
+         
+        
+        SoundManager.pause('hot', true)//自动播放被中断的音频 (bgm
+        
+         
+        return false
+    }  
+        
+ 
+    if(browser.isMobile()){
+        $('#closepop').on("touchstart",Hot.closePopup); 
+    }else{
+        $('#closepop').on("click",Hot.closePopup); 
+    }
+    
+    
+    
+    Hot.createHotList = function() {
+        var docFragment = document.createDocumentFragment();
+        var hots = hotGroup.children.filter(hot=>hot.info.actionType.openHot);
+        hots = hots.sort((a,b)=>{return a.order - b.order});
+        hots.forEach((hot)=>{
+            var li = document.createElement('li');
+            var span = document.createElement('span');
+            span.innerHTML = hot.info.title || '热点';
+            // console.log(span.innerHTML);
+            li.hot = hot;   // 列表每一项对应一个热点
+            li.appendChild(span);
+            docFragment.appendChild(li);
+             
+        })  
+        var ul = document.querySelector('#hotListContent ul');
+        ul && ul.appendChild(docFragment);
+         
+    }
+            
 }
 
 

+ 141 - 470
public/SuperTwo/js/main_2020_show.js

@@ -2,322 +2,9 @@
 另外 	所有"matter"字样已被我删除				原因:删除matterport信息
   */
  
-
-window.common = null;  
-window.MathLight = null;
-window.math = null
-window.easing = null
-window.lerp = null
-window.transitions = null
-window.browser = null
-window.momentTourBlackNewType = 0//=  number == 'TEST'//true
-
-g_playAudio = null
-
-g_tourAudio = new Audio 
-g_tourAudio.loop = !1 
-g_tourAudio.crossOrigin = "anonymous" 
-g_tourAudio.addEventListener("ended", function() {
-    var e = document.createEvent("MouseEvent");
-    e.initEvent("tourAudioEnded", !0, !0),
-    window.dispatchEvent(e)
-}) 
-
-g_tourAudio.oncanplaythrough = function() {
-    g_tourAudio.play();
-    if(g_bgAudio && !g_bgAudio.paused){
-        manage.switchBgmState(false); 
-        g_bgAudio.pauseByTour = true
-    }
-    g_playAudio = g_tourAudio;  
-}
-
-
-var dealMap = (map)=>{//使不resize  when   image is not power of two
-    map.wrapS = map.wrapT = THREE.ClampToEdgeWrapping;
-    map.minFilter = THREE.LinearFilter;
-    map.magFilter = THREE.LinearFilter;
-    map.generateMipmaps = true;  
-    
-}  
- 
- 
-  
-var dom = {//许钟文add
-	getOffset: function(type, element, parent) { 
-		left = (type == "left") ? element.offsetLeft : element.offsetTop;
-		if (!parent) parent = $("body")[0];
-		while (element = element.offsetParent) { 
-			if (element == parent) break;
-			left += (type == "left") ? element.offsetLeft : element.offsetTop;
-		}
-		return left;
-	}  
-};
-
-
-var getTransformSid = function(){
-    var name
-    if(player.mode == 'panorama'){
-        name = player.currentPano ? player.currentPano.id : 'outside'
-    }else{
-        name = 'outside'
-    }
-    return name
-} 
- 
-
-
-/* 
-var addMagnifier = function(){ 
-
-    class Magnifier extends THREE.Object3D {
-        constructor () {
-            super()
-            
-            let circleGeo = new THREE.CircleGeometry(0.1,  100);
-            
-            
-            this.camera = new THREE.PerspectiveCamera(50, 1, 0.1, 1);  //fov aspect near far
-         
-            this.renderTarget = new THREE.WebGLRenderTarget(256,256, { 
-                minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter,
-                format: THREE.RGBAFormat ,
-                //type: THREE.FloatType,
-                //minFilter: THREE.NearestFilter,
-                //magFilter: THREE.NearestFilter, 
-                
-            } )
-            
-            
-            this.mesh = new THREE.Mesh(circleGeo, new THREE.MeshBasicMaterial({
-                side: THREE.DoubleSide , 
-                map: this.renderTarget.texture ,
-                transparent:true,
-                depthTest: !1,
-                depthWrite: !1,
-            }))
-            this.overlayMesh = new THREE.Mesh(circleGeo, new THREE.MeshBasicMaterial({
-                side: THREE.DoubleSide , 
-                map: Texture.load('images/crosshair.png') ,
-                transparent:true,
-                depthTest: !1,
-                depthWrite: !1,
-            }))
-            this.add(this.mesh)
-            this.add(this.overlayMesh)
-            
-            player.model.add(this);
-            player.magnifier = this;
-            
-        }
-        
-        update(aimPos){
-            
-            const magDistance_ = 0.3; 
-            
-            var playerPos = player.position
-            var vec = playerPos.clone().sub(aimPos).normalize().multiplyScalar(magDistance_)
-            this.camera.position.copy(aimPos.clone().add(vec)) 
-            this.camera.lookAt(aimPos)
-            
-            
-            var playerCamera = player.camera
-            this.quaternion.copy(playerCamera.quaternion);
-      
-            var pos2d = player.mouse.clone();
-            var shift = 400;
-            var clientHeight = player.domElement.clientHeight 
-            var clientY = - (pos2d.y - 1) * clientHeight / 2;
-            pos2d.y = clientY < 300 ?  pos2d.y - shift/clientHeight : pos2d.y + shift/clientHeight
-            let newPos = new THREE.Vector3(pos2d.x,pos2d.y,0.7).unproject(playerCamera);        
-            this.position.copy(newPos)
-             
-             
-            var renderer = player.sceneRenderer.renderer
-            var oldAutoClear = renderer.autoClear 
-            renderer.autoClear = false
-            //renderer.clear( true, true, true );
-            renderer.render(player.sceneRenderer.scene, this.camera, this.renderTarget,  true)
-            
-            renderer.autoClear = oldAutoClear
-            
-             
-        }
-    }
-
-
-
-
-    new Magnifier() 
-}
-  */
- 
-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){//检测某点在视线中是否被mesh遮挡 
-		var ori = player.position
-        var dir = pos3d.clone().sub(ori).normalize()
-        var ray = new THREE.Raycaster(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;
-	} 
-}
-
  
 
 
-
-
-
-
 !function() {
     "use strict";
     function t(t, i) {
@@ -4786,7 +4473,7 @@ window.Modernizr = function(n, e, t) {
                 if (this.currentItem = null,
                 this.destinationItem = null,
                 this.tourIsPlaying = !1,
-				this.bgmReplay(),//xzw
+				//this.bgmReplay(),//xzw
                 this.transitionStage = y.None,
                 this.nextFunc = null,
                 this.onTheBus = !1,
@@ -4819,11 +4506,11 @@ window.Modernizr = function(n, e, t) {
                 })
             }
             ,
-            n.prototype.checkAndHandleWalkingtourInterruption = function(e) {
-                return e === u.WALK && (this.interrupt(g.NONE),
+            n.prototype.checkAndHandleWalkingtourInterruption = function(e) {//快速停止。 改:去掉判断nextWarpStyle,因为这个属性改乱了,导致点击停止按钮不执行
+                return /* e === u.WALK && ( */this.interrupt(g.NONE),
                 this.pauseWalkingSection(),
                 this.player.fastForwardActivePanoFlight(),
-                !0)
+                !0/* ) */
             }
             ,
             n.prototype.handlePlayerMove = function(e) {
@@ -5030,33 +4717,35 @@ window.Modernizr = function(n, e, t) {
             }
             ,
             n.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;
-                    
-                    let audioSrc1 = g_tourAudio.src.split('/').pop();
-                    let audioSrc2 = o.split('/').pop();
+                    let src = musicInfo.music.includes(g_Prefix.slice(-10)) ? musicInfo.music :  g_Prefix + musicInfo.music;
+                    let audioObj = SoundManager.list.find(e=>e.name == 'tour')
+                    let audioSrc1 = common.getFileNameFromUrl(audioObj.src);  
+                    let audioSrc2 = common.getFileNameFromUrl(src)
+               
+                                                                     
+                                                       
                
                     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()
+                            SoundManager.play('tour',null,0)  // currentTime = 0; 
+                        }else if( audioObj.audio.paused && audioObj.audio.currentTime < audioObj.audio.duration   ){//未播完
+                            SoundManager.play('tour')//继续播。为什么会有暂停的情况?如果手动切换到bgm了呢?
                         } 
                         
                     }else{//很可能是该folder的起始
-                        g_tourAudio.src = manage.dealURL(o);
-                        g_tourAudio.load()  
+                         
+                        SoundManager.play('tour', manage.dealURL(src))
+                                            
                     }
                     
-                    if(g_bgAudio && !g_bgAudio.paused){
-                        manage.switchBgmState(false); 
-                        g_bgAudio.pauseByTour = true
-                    }
+                     
+                                                      
+                                                    
                 }
-                //}
                 if (this.onTheBus = !0,
                 this.emit("update.controls"),
                 this.player.updateLastView(),
@@ -5077,10 +4766,11 @@ window.Modernizr = function(n, e, t) {
                       , a1 = null;
                     if (r.isPano()) {
                     
+                    
                         //var s = 0 === this.destinationItem || e ? u.BLACK : this.nextWarpStyle;
                         //var walk = window.DATA.black ? 'black' : 'walk';
-                     
-                        var s = this.getMomentTour(this.destinationItem)   //window.DATA.momentTour || "walk";
+                        //若是点击item,直接瞬间过渡。
+                        var s = e ? 'black' : this.getMomentTour(this.destinationItem)   //window.DATA.momentTour || "walk";
                         a1 = this.player.warpToPanoByHeroIndex.bind(this.player, this.destinationItem, v.Show, m.Slow,  s, true, i, this.actionComplete.bind(this)),
                         o = this.arrivedAtDestination.bind(this, !0)
                     
@@ -5136,30 +4826,25 @@ window.Modernizr = function(n, e, t) {
                     this.goToDestination()) : this.goNext()))
             } 
 			,
-			n.prototype.bgmReplay = function() {//xzw add  结束tour后可能要继续播放背景音乐
-				//if(g_tourAudio && g_tourAudio.paused && g_bgAudio && g_bgAudio.paused){
-                if(g_bgAudio && g_bgAudio.paused && g_bgAudio.pauseByTour){
-                    g_playAudio = g_bgAudio;
-                    g_tourAudio && g_tourAudio.pause();
-                    //window.tourAudio && window.tourAudio.pause(); 
-                    manage.switchBgmState(true); 
-				}
-			}
-			,
+			/* n.prototype.bgmReplay = function() {//xzw add  结束tour后可能要继续播放背景音乐
+			  
+                
+			} */
+			 
+                                                                    
             n.prototype.stopTour = function(isAutoStop) {//停止导览        isAutoStop 希望仅在飞完结束自动停止时的stopTour不停止tourSound, 这样才能完整播放tourSound.  不过似乎会在倒数第二个片段点击按钮停止导览时也视作自动结束的(执行this.interrupt() )。
                 this.isInterrupted() || this.transitionStage === y.Moving && this.checkAndHandleWalkingtourInterruption(this.nextWarpStyle) || (this.tourIsPlaying && (this.player.zoomEnabled = this.wasZoomEnabled),
-                this.tourIsPlaying = !1,
-				(!isAutoStop || g_tourAudio && g_tourAudio.paused )&&this.bgmReplay(),//xzw
+                this.tourIsPlaying = !1, 
+                                                                               
                 this.interrupt(),
                 this.clearWalkingSectionPaused(),
                 this.resetSpecialTransition(),
                 this.emit("update.controls"))
-                //window.tourAudio && window.tourAudio.pause();
-                if(!isAutoStop && g_tourAudio && g_tourAudio.paused == false )
-                {
-                    g_tourAudio.pause();
-                    //g_tourAudio.src = ""
-                }
+                
+                                                                              
+                 
+                                        
+                                          
             }
             ,
             n.prototype.endTourProgress = function() {
@@ -5178,7 +4863,7 @@ window.Modernizr = function(n, e, t) {
                     this.clearWalkingSectionPaused(),
                     this.setDestinationItem(e),
                     this.useSpecialTransition("Hilight"),
-                    this.goToDestination(),
+                    this.goToDestination(true),//add true
                     h.trackAlways("reach_highlight", {
                         reach_source: "thumb"
                     })
@@ -14749,6 +14434,18 @@ window.Modernizr = function(n, e, t) {
                     })
                     
                 }
+                
+                {//初始化导览时间
+                    if(DATA.tourBlackSpeed == void 0)DATA.tourBlackSpeed = 100  
+                    window._settings.warp.teleportTime = settings.teleportTime / DATA.tourBlackSpeed * 100;
+                    
+                    
+                    if(DATA.tourWalkSpeed == void 0)DATA.tourWalkSpeed = 100 
+                    
+                    if(DATA.tourRotTime == '' || DATA.tourRotTime == void 0){
+                        DATA.tourRotTime = settings.tourRotTime; //默认停留2秒
+                    }
+                }
             }).fail(e=>{
                 alert("缺少someData文件,请检查场景码是否正确。")
             })
@@ -15136,14 +14833,22 @@ window.Modernizr = function(n, e, t) {
                 }
                 //czj 判断someData 有没有backgroundMusic 添加音乐
                 if (window.DATA.backgroundMusic) {
-                    if(window.isLocal) g_bgAudio.src = manage.dealURL(window.DATA.backgroundMusic) ;
-                    //else g_bgAudio.src = window.DATA.backgroundMusic.substr(0,4)=="http" ? window.DATA.backgroundMusic : "//" + window.DATA.backgroundMusic;
-                    else g_bgAudio.src = window.DATA.backgroundMusic
-                    
+                    if(window.isLocal){
+                        SoundManager.setSrc('bgm', manage.dealURL(window.DATA.backgroundMusic))
+                    }else{
+                        SoundManager.setSrc('bgm', window.DATA.backgroundMusic )
+                    }  
                     $("#volume").show();
+                    
+                 
                 }else if (g_version === "one"){
-                    g_bgAudio.src = g_Prefix+"/audio/"+"audio"+window.number + "/background.mp3";
-                    //g_bgAudio.src = manage.dealURL(src) ;
+                    SoundManager.setSrc('bgm', manage.dealURL( g_Prefix+"/audio/"+"audio"+window.number + "/background.mp3"))
+                    
+                    
+                    $("#volume").show();
+                                               
+                                                                                                 
+                                                           
                 }
 
                 //隐藏公司logo
@@ -17832,6 +17537,8 @@ window.Modernizr = function(n, e, t) {
                         }
                         var item = new s(l);
                         item.momentTour = info.momentTour
+                        item.dontRot = info.dontRot
+                        item.rotTime = info.rotTime
                         container.push(item) 
                         return item
                     }
@@ -18231,39 +17938,23 @@ window.Modernizr = function(n, e, t) {
 				})  
             },
             
-            n.prototype.createHotItem = function() {
-                var docFragment = document.createDocumentFragment();
-                
-                this.hotGroup.children.forEach(hot=>{
-                    if(hot.info.actionType.openHot){/* hot.texType == 'shine' */
-                        var li = document.createElement('li');
-                        var span = document.createElement('span');
-                        span.innerHTML = hot.info.title || '热点';
-                        // console.log(span.innerHTML);
-                        li.hot = hot;   // 列表每一项对应一个热点
-                        li.appendChild(span);
-                        docFragment.appendChild(li);
-                    }
-                })
-                  
-                var ul = document.querySelector('#hotListContent ul');
-                ul.appendChild(docFragment);
-                 
-            }
-				
+             
 
-           /*  n.prototype.loadOverlays = function(overlays){
-                var overlays = window.data2 && window.data2.overlays  
-                  
-                
-                overlays && overlays.forEach((info)=>{ 
-                    new Overlay(info)  
-                })
-                
-                
-                Overlay.load()
-            }
-             */
+           
+           
+           
+           
+           
+           
+           
+           
+           
+           
+           
+           
+           
+           
+           
                 
 			n.prototype.loadhots = function() {//xzw 
                 initHot(this)
@@ -18297,7 +17988,7 @@ window.Modernizr = function(n, e, t) {
                                 new Hot(info, 'byOverlay')  
                             })
                         } 
-                        this.createHotItem( ); 
+                        Hot.createHotList(); 
                         Hot.startLoad()  
                          
                         
@@ -19588,7 +19279,7 @@ window.Modernizr = function(n, e, t) {
             }
             ,
             n.prototype.build1 = function() {
-                this.floor = this.floor || this.model.floors.get(this.floorIndex) || this.raycastToFindFloor() || this.model.getFloorAtPoint(this.position),
+                this.floor = this.floor || this.model.floors.get(this.floorIndex) || (this.model.floors.list.length == 1 ? this.model.floors.list[0] :  this.raycastToFindFloor()) || this.model.getFloorAtPoint(this.position),
                 this.floor.addPano(this),
                 this.floorPosition = this.floorPosition || this.raycastFloorPosition(),
                 this.neighbourPanos = this.neighbourPanos || this.findNeighourPanos(),
@@ -21479,17 +21170,20 @@ window.Modernizr = function(n, e, t) {
                   , s = new r.Vector3
                   , h = new r.Vector3
                   , u = function(e, t) {
+                    //导览速度
                     var i = Math.min(this.player.position.distanceTo(e.position), c.transition.flytimeMaxDistanceThreshold)
-                      , r = i * c.transition.flytimeDistanceMultiplier + c.transition.flyTime;
+                    //  , r = i * c.transition.flytimeDistanceMultiplier + c.transition.flyTime;
+                      , r = i * c.warp.flytimeDistanceMultiplier + c.warp.flyTime;
+                    
                     h.copy(A.FORWARD),
                     this.player.getDirection(h),
                     s.copy(t).sub(e.position).normalize();
                     var l = s.dot(h)
                       , u = Math.acos(l)
                       , d = u / r;
-                    return d > n && (r *= d / n,
-                    u < o && (r *= a)),
-                    r
+                      d > n && (r *= d / n,
+                    u < o && (r *= a)) 
+                    return r   / DATA.tourWalkSpeed  * 100 // 改
                 };
                 return function(e, t, i) {
                     if (this.warpInterrupted)
@@ -22160,30 +21854,7 @@ window.Modernizr = function(n, e, t) {
                 str += ( '"camera_position":['+ info.camera_position + '],"camera_quaternion":['+info.camera_quaternion+'], "zoom":' + info.zoom + '}');
 				return str; 
 			}
-			//------end	 
-			n.prototype.closePopup = function() {//xzw  关闭热点页面
-				if(!g_currentHot) return;
-				g_currentHot = null;
-				var hotPop = document.getElementById('popup'); 
-				hotPop.style.display = "none";
-				document.querySelector(".popup-content").removeChild(document.getElementById("id1"));
-				$("#popup iframe:last").remove();
-                var _bgaudio = document.getElementById("bgaudio");
-                //判断音乐是否暂停或者是否存在
-                /* if(g_bgAudio && g_bgAudio.paused && g_bgAudio.readyState != 0 && g_play === 1)
-                {
-                    //g_bgAudio.play();
-                    manage.switchBgmState(true)
-                }; */
-                
-                if(g_bgAudio && g_bgAudio.pauseByHot){
-                    manage.switchBgmState(true)
-                }
-                
-                
-				//$('#player').off("click",this.closePopup);
-                return false
-			}  
+			 
 				 
 			 
 			
@@ -22308,26 +21979,22 @@ window.Modernizr = function(n, e, t) {
                 return .5
             }
             ,
-			n.prototype.changeMusic = function() {//xzw add
-				/* if(!this.director.tourIsPlaying && g_play && g_bgAudio){
-					g_playAudio = g_bgAudio; 
-					//g_bgAudio.play();
-                    manage.switchBgmState(true)
-				}else{
-					if(!g_play){
-						g_playAudio =  g_bgAudio; 
-					}else{//防止再次播放时重播一遍
-						g_playAudio = null;
-					}
-				}  */  
-                 
-                /* if(!this.director.tourIsPlaying && g_bgAudio){
-                    manage.switchBgmState(true)
-                } */
-                
-                if(!this.director.tourIsPlaying) this.director.bgmReplay()
-			}
-			,
+			 
+			 
+             
+             
+             
+             
+             
+             
+             
+             
+             
+             
+             
+             
+             
+             
             n.prototype.bindEvents = function(e) {
                 e !== document && e.setAttribute("tabindex", -1),
                 e.addEventListener("mousedown", this.onMouseDown.bind(this)),
@@ -22350,17 +22017,13 @@ window.Modernizr = function(n, e, t) {
                 this.cameraControls.on(_.Pinch, this.handleControlPinch.bind(this)),
                 this.cameraControls.on(_.Scroll, this.handleControlScroll.bind(this)),
                 window.addEventListener("snapshotBegin", this.getWrapShot.bind(this)),//xzw add
-				window.addEventListener("tourAudioEnded", this.changeMusic.bind(this));//xzw add
+				//window.addEventListener("tourAudioEnded", this.changeMusic.bind(this));//xzw add
                 
                 // lzb
                 window.getSeft && getSeft(this);
 
-                //判断是否是移动端,如果是给关闭按钮添加touchstart事件
-                if(/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)){
-                    $('#closepop').on("touchstart",this.closePopup.bind(this)); 
-                }else{
-                    $('#closepop').on("click",this.closePopup.bind(this)); 
-                }
+				//window.addEventListener("tourAudioEnded", this.changeMusic.bind(this));//xzw add
+                
             }
             ,
             n.prototype.onMouseDown = function(e) {
@@ -22667,11 +22330,7 @@ window.Modernizr = function(n, e, t) {
                 this.updateHotVisible()
                 Hot.updateVisibles([this.currentPano])
                 this.modeTran = "panorama-panorama"
-                setTimeout(()=>{
-                    for(var i in this.model.hots){
-                        this.model.hots[i].updateTitle()
-                    } 
-                },1000)
+                
                 return this.mode = u.PANORAMA,
                 e.floor.enter(this.mode),
                 this.emit(w.PanoChosen, this.currentPano, this.currentPano),
@@ -23087,7 +22746,7 @@ window.Modernizr = function(n, e, t) {
                     e.cameraChanged = !a;
                     
                     if(e.cameraChanged){//
-                        e.cameraChanged2 = !MathLight.closeTo(this.quaternion, this.previousState.quaternion, 3) || !MathLight.closeTo(this.position, this.previousState.position, 4)  
+                        e.cameraChanged2 = !MathLight.closeTo(this.quaternion, this.previousState.quaternion, 3) || !MathLight.closeTo(this.position, this.previousState.position, 4)  || !this.camera.projectionMatrix.equals(this.previousState.projectionMatrix)
                     }else e.cameraChanged2 = false 
                     
                     
@@ -23772,8 +23431,8 @@ window.Modernizr = function(n, e, t) {
             
             
             n.prototype.fastForwardActivePanoFlight = function(e) {
-                e = e || f.transition.fastForwardFactor / 10 * 4 + 1,
-                y.adjustSpeed(V.FlyToPano, e),
+                e = e || f.transition.fastForwardFactor / 10 * 4 + 1 
+                y.adjustSpeed(V.FlyToPano, e) 
                 y.adjustSpeed(V.LookTransition, e)
             }
             ,
@@ -23798,7 +23457,7 @@ window.Modernizr = function(n, e, t) {
             }
             ,
             n.prototype.flyDirection = function(e, t, i) {
-				this.closePopup();//xzw add
+				Hot.closePopup();//xzw add
                 var n = $.Deferred();
                 this.history.invalidate();
                 var r = this.closestPanoInDirection(e, t, i);
@@ -24020,6 +23679,7 @@ window.Modernizr = function(n, e, t) {
             }
             ,
             n.prototype.flyToNewMode = function(e, t) {
+                Hot.closePopup();//xzw add                        
                 e = e || {};
                 var i = e.mode
                   , n = e.pano
@@ -24385,30 +24045,39 @@ window.Modernizr = function(n, e, t) {
                 this.history.invalidate();
                 this.path.discardSlow();
 				//xzw:  
+                var defaultRotTime = DATA.tourRotTime * 1000
+                var timeEachItem = 2e3 / (DATA.tourWalkSpeed + DATA.tourBlackSpeed) * 200 //预估时间假设每个item飞的时间(如果距离远就少了)
+                 
                 var currentLocation = this.model.heroLocations[this.director.currentItem[0]] 
                 var rotTime
                 if(currentLocation.rotTime == void 0 || currentLocation.rotTime == ''){
                     var restChildCount = currentLocation.heroLocations ? (currentLocation.heroLocations.length-this.director.currentItem[1]-1) : 0
-                    var current = g_tourAudio ? 1e3 * g_tourAudio.currentTime : 0
-                    rotTime = currentLocation && currentLocation.musicInfo.music ? currentLocation.musicInfo.time - current : 2e3;  
+                    var hasMusic = currentLocation && currentLocation.musicInfo.music
+                    if(hasMusic){
+                        var audioObj = SoundManager.list.find(e=>e.name == 'tour') 
+                        var current = audioObj.audio.currentTime * 1e3 // || 0  //g_tourAudio ? 1e3 * g_tourAudio.currentTime : 0
+                        rotTime = currentLocation.musicInfo.time - current
                     
-                    if(restChildCount){//如果当前folder中还有剩下的item,平分一下时间
-                        var timeEachItem = 2000;//假设每个item飞的时间
-                        var rotTime = (rotTime-timeEachItem*restChildCount) / (restChildCount+1);
-                         
+                        if(restChildCount){//如果当前folder中还有剩下的item,平分一下时间
+                                                                              
+                            rotTime = (rotTime-timeEachItem*restChildCount) / (restChildCount+1);   
+                        }  
+                    }else{
+                        rotTime = defaultRotTime
                     } 
                     rotTime = Math.max(0, rotTime)
-                    console.log("rotTime "+rotTime +" at item "+this.director.currentItem + ",musicCurrentTime:"+current) 
+                    Log("rotTime "+rotTime +" at item "+this.director.currentItem + (hasMusic ? (",musicCurrentTime:"+current+'音乐总长:'+currentLocation.musicInfo.time) : ''),"#E8E") 
                 }else{
                     rotTime = currentLocation.rotTime * 1000
-                    console.log("rotTime "+rotTime +" at item "+this.director.currentItem) 
+                    Log("rotTime "+rotTime +" at item "+this.director.currentItem,"#E8E") 
                 }
+                 
 
                 this.path.waitNextStep(e, function() {
                     t && t()
                 }.bind(this), rotTime)
             }
-            ,
+            ,    
             n.prototype.stopInterlude = function() {
                 this.interruptAndFastForward(null, 0)
             }
@@ -26929,7 +26598,7 @@ window.Modernizr = function(n, e, t) {
                 blur: 0.8,
                 movementEasing: "easeInOutQuad",
                 blendEasing: "easeInOutQuad",
-                fastForwardFactor: 3//r.valueFromHash("mfis", 3)
+                fastForwardFactor: 4,//r.valueFromHash("mfis", 3) //快速停止导览的速度,原先是3
             },
             show360Views: {
                 enabled: !0,
@@ -31374,8 +31043,10 @@ window.Modernizr = function(n, e, t) {
                 }).sort(function(e, t) {
                     return t.score - e.score;
                 });
-            } 
- 
+            } ,
+             getFileNameFromUrl:function(url){
+                return url.split('/').pop();
+            }
             
         },
         Math.sign = function(e) {

+ 646 - 99
public/SuperTwo/js/manage.js

@@ -1,9 +1,362 @@
+  
+var g_ProjectName=window.location.pathname.substring(window.location.pathname.indexOf("/")+1,window.location.pathname.lastIndexOf("/"));
+var g_Prefix="https://super.4dage.com/";
+// var g_Prefix=window.location.href.substring(0,window.location.href.indexOf("/index.html")+1);
+var s = window.location.href.split('/');
+    s.pop();
+//var g_Prefix = s.join('/');
+var g_index=null;
+var g_modeldata=null;
+
+var g_weixinTitle=null;
+
+var g_Hots=null;
+var g_HotMeshes=[];
+var g_HotMeshSize = {
+    g_HotMeshWidth: 0.3,
+    g_HotMeshHeight:0.3
+};
+
+//add表示添加,delete表示删除
+var g_HotStatus=null;
+var g_newHot = [];//存储新加热点
+var g_HotImage= {
+	"point":"https://super.4dage.com/images/4dagePoint2.png",
+	"point2":"https://super.4dage.com/images/4dagePoint.png"
+};	
+var g_saveHot=false;
+
+var g_TextColor=0x7777ff;
+var g_Text=null;
+var g_TextPlaneMesh=[];
+var g_TextIconMesh=[];
+var g_TextIcon="./images/text.png";
+var g_SelectTextIndex=null;
+var g_TextShow=null;
+var g_audioPlay=false;
+var g_background=null; 
+var g_roof=null;
+
+var g_data2 = null;//加载的data2.js的内容
+var g_bgAudio=null;//背景音乐
+var g_tourAudio=null;//导览音乐
+var g_play = 1;//表示播放图标状态
+var g_playAudio = null;//当前在播放或当继续播放时应该播放的,是g_bgAudio或g_tourAudio 
+var g_currentHot = null;//当前打开的热点 
+//var g_Texture=null;
+//var g_ChunknameTexture={};   //chunkname和贴图名称对应
+var g_NormalTexture=false;
+var g_SpecularTexture=false;
+var g_DirectionalLight=null;  
+  
+var g_snapShotWidth = 200; //截图下载图片的大小
+var g_snapShotHeight = 140;
+
+//微信分享
+var g_weixinObj = {
+  "title": document.querySelector("head title").innerHTML,
+  "lineLink" : window.location.href,
+  "imgUrl" : "https://www.4dmodel.com/SuperPanoramic/images/weixintitle.jpg",
+  "desc" : "四维时代提供技术支持",
+}
+
+var settings = {
+    hotClickEvent:{
+        video:{
+            playAndPause:true,
+            examine:false,
+            openHot:false 
+        },
+        photo:{
+            examine:false,
+            openHot:false 
+        },
+        shine:{
+            examine:true,
+            openHot:true  
+        }
+    },
+    //默认的:
+    teleportTime:  1500,//瞬间过渡的时间 
+    /* flytimeDistanceMultiplier:150, 
+    flyTime:750,  */
+    tourRotTime:2,  //默认停留2秒
+    //dontExamHot:true  
+    transparentBg: false,
+    bgImg:  null 
+}
+if(window.number == '725'||window.number == '724'){
+    settings.mobileNavHigh = true
+}
+
+
+//共用函数:
+
+
+window.common = null;  
+window.MathLight = null;
+window.math = null
+window.easing = null
+window.lerp = null
+window.transitions = null
+window.browser = null
+window.momentTourBlackNewType = 0//=  number == 'TEST'//true
+ 
+
+
+
+
+
+
+
+
+
+var dealMap = (map)=>{//使不resize  when   image is not power of two
+    map.wrapS = map.wrapT = THREE.ClampToEdgeWrapping;
+    map.minFilter = THREE.LinearFilter;
+    map.magFilter = THREE.LinearFilter;
+    map.generateMipmaps = true;  
+    
+}  
+ 
+ 
+  
+var dom = { 
+	getOffset: function(type, element, parent) { 
+		left = (type == "left") ? element.offsetLeft : element.offsetTop;
+		if (!parent) parent = $("body")[0];
+		while (element = element.offsetParent) { 
+			if (element == parent) break;
+			left += (type == "left") ? element.offsetLeft : element.offsetTop;
+		}
+		return left;
+	}  
+};
+
+
+var getTransformSid = function(){
+    var name
+    if(player.mode == 'panorama'){
+        name = player.currentPano ? player.currentPano.id : 'outside'
+    }else{
+        name = 'outside'
+    }
+    return name
+} 
+ 
+
+
+ 
+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){//检测某点在视线中是否被mesh遮挡 
+		var ori = player.position
+        var dir = pos3d.clone().sub(ori).normalize()
+        var ray = new THREE.Raycaster(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;
+	} ,
+    
+    getScaleForConstantSize : function(op={}){ //获得规定二维大小的mesh的scale值。可以避免因camera的projection造成的mesh视觉大小改变。  来源:tag.updateDisc
+        var w;  
+        var i = new THREE.Vector3, o = new THREE.Vector3, l = new THREE.Vector3, c = new THREE.Vector3, h = new THREE.Vector3
+         
+        if(op.width2d) w = op.width2d //如果恒定二维宽度
+        else{//否则考虑上距离,加一丢丢近大远小的效果
+            var currentDis, nearBound, farBound
+            if(op.camera.type == "OrthographicCamera"){
+                currentDis = (op.camera.right - op.camera.left) / op.camera.zoom
+            }else{
+                currentDis = op.position.distanceTo(op.camera.position);
+            } 
+            w = op.maxSize - ( op.maxSize -  op.minSize) * THREE.Math.smoothstep(currentDis,  op.nearBound,  op.farBound);
+            //maxSize : mesh要表现的最大像素宽度;   nearBound: 最近距离,若比nearBound近,则使用maxSize
+        }
+        i.copy(op.position).project(op.camera),  //tag中心在屏幕上的二维坐标
+        o.set(op.resolution.x / 2, op.resolution.y / 2, 1).multiply(i), //转化成px   -w/2 到 w/2的范围
+        l.set(w / 2, 0, 0).add(o),  //加上tag宽度的一半
+        c.set(2 / op.resolution.x, 2 / op.resolution.y, 1).multiply(l), //再转回  -1 到 1的范围
+        h.copy(c).unproject(op.camera);//再转成三维坐标,求得tag边缘的位置
+        var g = h.distanceTo(op.position)//就能得到tag的三维半径
+    
+        return g  //可能NAN  当相机和position重叠时
+         
+    } 
+    
+    
+    
+}
+
+ 
+
+
+
+
+
+
+
+
+
+
+
+//--------------------------------------
 //管理js文件 获取modeldata.js 判断是否有特殊的字段,如果有就先加载SpecialScene.js 里面有对特殊场景处理的代码 否则就直接加载main
+
+
+
 var Manage = function(){
     this.weixinURL = "https://res.wx.qq.com/open/js/jweixin-1.2.0.js",
     this.time = "?"+new Date().getTime();
     this.loadAudio();
-    // this.loadWeixin();
+    this.loadWeixin();
 }
 //动态加载js文件
 Manage.prototype.LoadJs = function(_files, succes){
@@ -105,98 +458,6 @@ Manage.prototype.loadWeixin = function() {
 
 }
 
-Manage.prototype.loadAudio = function() { //相关:g_tourAudio \  g_playAudio
-    g_bgAudio = new Audio;
-    g_bgAudio.loop = true;
-    g_bgAudio.autoplay = true;
-    g_bgAudio.id = "bgaudio";
-    
-    //https://www.cnblogs.com/interdrp/p/4211883.html   部分资料
-    g_bgAudio.load();	// iOS 9   还需要额外的 load 一下, 否则直接 play 无效
-    var play = function(){
-        //if(window.tourAudioSta) return;
-         
-        if(this.bgmShouldPlay){
-            this.switchBgmState(true)
-        }
-        
-        document.removeEventListener("touchstart",play);
-        document.removeEventListener("click",play);
-        $('#player')[0].removeEventListener("touchstart", play);
-    }.bind(this);
-    
-    g_bgAudio.oncanplay = ()=>{ 
-        this.switchBgmState(true)
-    }
-    document.addEventListener("WeixinJSBridgeReady", ()=> {
-        this.switchBgmState(true)
-    }, false);
-    
-    document.addEventListener("touchstart", play);//ios需要加个事件才能播放 不能自动播放;如果还有浏览器不行,换成别的交互事件
-    document.addEventListener("click", play);
-     $('#player')[0].addEventListener("touchstart", play);
-    g_bgAudio.addEventListener('ended', ()=>{ 
-        this.switchBgmState(true)
-    }); 
-    
-    
-    
-    $("#volume").find("a").on("click", ()=> { 
-         
-        if($("#volume img")[0].src.indexOf("btn_on.png")>-1)
-        { 
-            this.switchBgmState(true); 
-        }
-        else if($("#volume img")[0].src.indexOf("btn_off.png")>-1)
-        {
-            this.switchBgmState(false);    
-        }
-    }) 
-
-    
-    
-}   
-Manage.prototype.switchBgmState = function(state){
-    if(!g_bgAudio || !g_bgAudio.src) return;
-    this.bgmShouldPlay = state
-    
-    var played = function(){
-        console.log('begin play bgm');
-        g_play = 1; 
-        g_playAudio = g_bgAudio;
-        $("#volume a img").attr("src", "./images/Volume btn_off.png")
-        $("#volume").attr("title", "关闭声音");
-        g_tourAudio && g_tourAudio.pause()
-    }
-    var paused = function(){ 
-        g_play = 0;
-        g_playAudio == g_bgAudio && (g_playAudio =  null)
-        $("#volume a img").attr("src", "./images/Volume btn_on.png")
-        $("#volume").attr("title", "打开声音");
-    }
-    
-    if(state ){
-        g_bgAudio.play(); 
-        if(g_bgAudio.paused){
-            paused()
-        }else{
-            played()
-            return true
-        }            
-    }else{
-        g_bgAudio.pause();
-        paused()
-    } 
-    
-    
-    g_bgAudio.pauseByHot = false
-    g_bgAudio.pauseByTour = false
-}    
-    
- 
-
- 
-
 
  
 
@@ -204,7 +465,7 @@ Manage.prototype.switchBgmState = function(state){
 Manage.prototype.weixinShare = function() {
     console.log("weixinShare")
     $.ajax({    
-        url: 'https://www.4dage.com/wechat/jssdk/share/',
+        url:'https://www.4dage.com/wechat/jssdk/', 
         type: "post",
         data : {
             'url' : location.href.split('#')[0]
@@ -404,7 +665,6 @@ Manage.prototype.showInfo = function (o) { // ({result:true, title:"发布成功
 
 
 
-var manage = new Manage();
 
 //公用的函数
 
@@ -429,7 +689,7 @@ function showLogo(){
 //czj 添加随机的时间
 function randomTime(){
     return new Date()
-}
+};
 function matcher(data){
     if(!data || !g_version ) return data;
     delete data.model.vision_version;
@@ -655,8 +915,8 @@ var ifSame = function(object1, object2){
 
 
 
-var SoundPriority = {//暂不支持同时播放
-    currentPlay:null,//当前正在播放list中的哪一个
+/* var SoundManager = {//暂不支持同时播放
+    currentAudio:null,//当前正在播放list中的哪一个
     list:[
         {
             name:"bg", 
@@ -686,15 +946,294 @@ var SoundPriority = {//暂不支持同时播放
         
         
     ],
+    switchPlay:function(){
+        
+    },
     register:function(){
         
         
         
-    }
+    } 
+    
+}
+ */
+ 
+ 
+ 
+//最好能知道应该播放到的currentTime
+var SoundManager = {//暂不支持同时播放
+    currentAudio:null,//当前正在播放list中的哪一个
+    enableSound:true,//是否允许有声音
+    
     
+    playHistory:[],//被打断的加入播放历史
     
+    list:[ ],//同一级别可以互相打断 //暂时不做多级别
+    
+     
+    
+    play:function(name, src, currentTime){
+        var object = this.list.find(e=>e.name == name)
+        if(object){
+            if(this.currentAudio){ 
+                this.pause(this.currentAudio.name, false, true)
+                
+            }
+            
+            {//将当前要播放的播放历史中清除
+                let index = this.playHistory.indexOf(object)
+                if(index>-1)this.playHistory.splice(index,1);
+                
+            }
+               
+            
+            this.currentAudio = object
+            if(src){ 
+                this.setSrc(name, src)
+            }
+            if(currentTime!=void 0){
+                object.audio.currentTime = currentTime
+            }
+            if(object.audio){
+                object.audio.load();	// iOS 9   还需要额外的 load 一下, 否则直接 play 无效 *///https://www.cnblogs.com/interdrp/p/4211883.html   部分资料
+                object.audio.play();
+                object.callback && object.callback(true)
+            }
+            Log(name + '  播放 '  )
+        }
+        
+    },
+    
+    
+    pause:function(name, autoReplayLast, isInterrupt){//需要能自动恢复上一个被打算的音频。恢复前判断是否还需要播放
+        var object = this.list.find(e=>e.name == name)
+        if(object){
+            this.currentAudio = null
+            
+            
+            if(object.audio){
+                object.audio.pause()
+                object.callback && object.callback(false)
+                Log(name + ' 中断音频 '+  "("+common.getFileNameFromUrl(object.audio.src)+')' )
+            }
+            
+            
+            
+            if(isInterrupt){//一般主动调用不需要加这个
+                this.playHistory.push(object)//如果是被中断的,加入播放历史,等待恢复播放
+            }
+             
+            
+            if(autoReplayLast){ //播放之前的音频。它们是被打断过的。
+                while(this.playHistory.length){ 
+                    var last = this.playHistory.pop();
+                    if(last.src && last.canplay(last.audio)){
+                        this.play(last.name )
+                    }
+                    
+                }
+                
+            }
+            
+            
+        }
+        
+    },
+    
+ 
+    
+    setSrc : function(name, src){//不能直接给audio赋src!一定要用这个函数!因为我要拿这里的src来判断有无src,因为貌似audio的src会自动变,''时会变成html的链接
+        var object = this.list.find(e=>e.name == name)
+        object.src = src
+        object.audio.src = src
+        Log(`${object.name} 设置src: ${src}`)
+    },
+    
+    createAudio:function(object={}){//name, level, canplay
+        if(!object.fake){
+            object.audio = new Audio(); 
+            object.audio.loop = !!object.loop;
+            //object.audio.autoplay = true;
+        
+            
+            object.audio.addEventListener('ended', ()=>{ 
+                if(object.loop){//循环
+                    Log(`${object.name} 播放完毕,重新播放`)
+                    object.audio.play()
+                }else{
+                    this.pause(object.name, true);//停止后的后续处理
+                }
+            });
+            
+            
+            object.audio.oncanplaythrough = ()=>{ 
+                Log(`${object.name} canplaythrough  `) 
+            }
+        }
+        
+        this.list.push(object)
+        
+    },
+    
+    
+    
+    initAutoPlay:function(){  //处理设备自动播放限制
+        let play = function(){  
+            if(this.currentAudio && this.currentAudio.audio){
+                this.currentAudio.audio.play() 
+                Log(`${this.currentAudio.name} 自动播放成功`) //即使设置src在这之后好像也能成功播放
+            }else{
+                
+            }
+            document.removeEventListener("touchstart",play);
+            document.removeEventListener("click",play);
+            $('#player')[0].removeEventListener("touchstart", play);
+        }.bind(this);
+        
+        
+        document.addEventListener("WeixinJSBridgeReady", play, false);
+        document.addEventListener("touchstart", play);//ios需要加个事件才能播放 不能自动播放;如果还有浏览器不行,换成别的交互事件
+        document.addEventListener("click", play);
+        $('#player')[0].addEventListener("touchstart", play); 
+            
+         
+    }
 }
 
+
+function Log(value, color, fontSize){
+    color = color || '#13f'
+    fontSize = fontSize || 14
+    console.warn(`%c${value}`, `color:${color};font-size:${fontSize}px`) 
+}
+
+
+
+
+
+
+Manage.prototype.loadAudio = function() { //相关:g_tourAudio \  g_playAudio
+    
+     
+    
+    
+    //热点页面因为挡住了界面,所以暂时不存在别的音频阻止热点音频的可能
+    //box视频都静音,所以暂时不考虑
+    
+    SoundManager.createAudio({
+        name:'bgm',
+        level:0, 
+        src:'',
+        loop:true,
+        canplay:(audio)=>{
+            return this.bgmShouldPlay
+        },
+        callback:(state)=>{//play或pause时随之触发的函数(即使还没开始播放)
+            if(state){
+                $("#volume a img").attr("src", "./images/Volume btn_off.png")
+                $("#volume").attr("title", "关闭声音");
+            }else{
+                $("#volume a img").attr("src", "./images/Volume btn_on.png")
+                $("#volume").attr("title", "打开声音");
+            }
+        }
+    })  
+    SoundManager.createAudio({
+        name:'tour',
+        level:0, 
+        src:'',
+        loop:false,
+        canplay:(audio)=>{
+            return player.director && player.director.tourIsPlaying && player.director.getAudio()
+        }
+    })
+    SoundManager.createAudio({
+        name:'hot',
+        fake:true,//实际上没有audio. 只是为了来停止和续播其他音频
+        level:1, 
+        src:'',
+        loop:false,
+        canplay:(audio)=>{
+            
+        }
+    })
+     
+    
+    $("#volume").find("a").on("click", ()=> {  
+        if($("#volume img")[0].src.indexOf("btn_on.png")>-1)
+        { 
+            this.switchBgmState(true); 
+        }
+        else if($("#volume img")[0].src.indexOf("btn_off.png")>-1)
+        {
+            this.switchBgmState(false);    
+        }
+    })  
+    
+    this.switchBgmState(true);//初始设置允许播放bgm 
+    SoundManager.initAutoPlay()
+    
+    
+}  
+
+
+ 
+Manage.prototype.switchBgmState = function(state){//按钮的状态完全代表是否应该播放bgm,即使还没加载完
+    this.bgmShouldPlay = state
+    
+    
+    if(state){
+        
+        SoundManager.play('bgm')
+    }else{
+        
+        SoundManager.pause('bgm')
+    }
+    
+    
+    /* if(!g_bgAudio || !g_bgAudio.src) return;
+    
+    
+    var played = function(){
+        console.log('begin play bgm');
+        g_play = 1; 
+        g_playAudio = g_bgAudio;
+        
+        g_tourAudio && g_tourAudio.pause()
+    }
+    var paused = function(){ 
+        g_play = 0;
+        g_playAudio == g_bgAudio && (g_playAudio =  null)
+        
+    }
+    
+    if(state ){
+        g_bgAudio.play(); 
+        if(g_bgAudio.paused){
+            paused()
+        }else{
+            played()
+            return true
+        }            
+    }else{
+        g_bgAudio.pause();
+        paused()
+    } 
+    
+    
+    g_bgAudio.pauseByHot = false
+    g_bgAudio.pauseByTour = false */
+}    
+    
+    
+    
+    
+
+
+
+ 
+
+
 $('.bch').click(()=>{
     window.parent.postMessage({
             source: "backhome",
@@ -709,6 +1248,14 @@ if (Object.prototype.toString.call(res.data) == "[object Object]") {
     }
     }
 })
+
+
+    
+var manage = new Manage();
+
+ 
+
+
 //兼容一代的場景
 //請求地址統一管理
 var g_onePregix = "https://bigscene.4dage.com/" //对应一代  http://www.4dmodel.com/SuperPanoramic/index.html?m=55