浏览代码

更新钟文的代码

shaogen1995 3 年之前
父节点
当前提交
7eba5a73ec
共有 5 个文件被更改,包括 296 次插入244 次删除
  1. 二进制
      images/add/imgMo.png
  2. 2 1
      index.html
  3. 17 6
      js/Hot.js
  4. 34 236
      js/main_2020_show.js
  5. 243 1
      js/manage.js

二进制
images/add/imgMo.png


+ 2 - 1
index.html

@@ -158,7 +158,8 @@
                 margin-bottom: 15px;
             }
             .myBacImg .img{
-                display: none !important;
+                background: url('./images//add/imgMo.png');
+                background-size: 100% 100%;
                 width: 80vw;
                 height: 80vw;
             }

+ 17 - 6
js/Hot.js

@@ -28,7 +28,7 @@ window.initHot = function(model){
         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
     
@@ -929,11 +929,22 @@ 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){//手动播放暂停 
             this.pausedByUser = !state
@@ -1334,10 +1345,10 @@ window.initHot = function(model){
         requestDownload(type,callback) { 
             var plane = this.plane;
              
+            
             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)=>{ 
                     callback && callback()

+ 34 - 236
js/main_2020_show.js

@@ -1,218 +1,6 @@
 /* 许钟文修改的  标记 xzw    
 另外 	所有"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
- 
-
-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 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";
@@ -4715,11 +4503,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) {
@@ -4972,8 +4760,8 @@ window.Modernizr = function(n, e, t) {
                     
                         //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)
                         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)
                     
@@ -5059,8 +4847,8 @@ window.Modernizr = function(n, e, t) {
                         return;
                     this.clearWalkingSectionPaused(),
                     this.setDestinationItem(e),
-                    this.useSpecialTransition("Hilight"),
-                    this.goToDestination(),
+                    this.useSpecialTransition("Hilight")
+                    this.goToDestination(true),//add true
                     h.trackAlways("reach_highlight", {
                         reach_source: "thumb"
                     })
@@ -14647,6 +14435,9 @@ window.Modernizr = function(n, e, t) {
                     
                     
                     if(DATA.tourWalkSpeed == void 0)DATA.tourWalkSpeed = 100 
+                    if(DATA.tourRotTime == '' || DATA.tourRotTime == void 0){
+                        DATA.tourRotTime = settings.tourRotTime; //默认停留2秒
+                    }
                 }
                 
             }).fail(e=>{
@@ -17248,6 +17039,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
                     }
@@ -17661,7 +17454,7 @@ window.Modernizr = function(n, e, t) {
                 const myArr4 =[]
                 const myArr5 =[]
                 this.hotGroup.children.forEach((hot,index)=>{
-                    console.log(99999,index,hot.info.title)
+                    // console.log(99999,index,hot.info.title)
                     if(hot.info.actionType.openHot){/* hot.texType == 'shine' */
                         if(index<=17||index===51||index===53) myArr1.push(hot)
                         else if((index>17&&index<=25)||index===52) myArr2.push(hot)
@@ -19085,7 +18878,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(),
@@ -22548,7 +22341,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 
                     
                     
@@ -23230,8 +23023,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)
             }
             ,
@@ -23846,24 +23639,28 @@ 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 audioObj = SoundManager.list.find(e=>e.name == 'tour')
-                    var current = audioObj.audio.currentTime * 1e3 // || 0  //g_tourAudio ? 1e3 * g_tourAudio.currentTime : 0
-                    rotTime = currentLocation && currentLocation.musicInfo.music ? currentLocation.musicInfo.time - current : timeEachItem;  
-                    
-                    if(restChildCount){//如果当前folder中还有剩下的item,平分一下时间
-                        var rotTime = (rotTime-timeEachItem*restChildCount) / (restChildCount+1);
-                    } 
+                     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,平分一下时间
+                             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() {
@@ -23875,7 +23672,8 @@ window.Modernizr = function(n, e, t) {
                 this.interruptAndFastForward(null, 0)
             }
             ,
-            n.prototype.interruptAndFastForward = function(e, t) {
+            n.prototype.interruptAndFastForward = function(e, t) { 
+                //Log('interruptAndFastForward' , '#f00')
                 this.isWarping() && this.emit(w.WarpInterrupted, this.path.activeTransType, e, t),
                 this.flying && this.emit(w.FlyingInterrupted),
                 this.path.interruptAndFastForward(e, t)
@@ -26391,7 +26189,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,

+ 243 - 1
js/manage.js

@@ -80,7 +80,7 @@ var settings = {
     teleportTime:  1500,//瞬间过渡的时间 
     /* flytimeDistanceMultiplier:150, 
     flyTime:750,  */
-    
+    tourRotTime:2,  //默认停留2秒
     //dontExamHot:true  
     transparentBg: false,
     bgImg:  null 
@@ -90,8 +90,250 @@ if(window.number == '725'||window.number == '724'){
 }
 
 
+//共用函数:
+
+
+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重叠时
+         
+    } 
+    
+    
+    
+}