document.write(''); //2 创建视频融合 // 2.1 部分函数准备 var scratchSetViewQuaternion = new Cesium.Quaternion(); var scratchSetViewMatrix3 = new Cesium.Matrix3(); //h,p,r转matrix4 function hpr2m(obj, result) { // const inverseViewMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(position, headingPitchRoll, undefined, undefined, result); const inverseViewMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(obj.position, undefined, result); // const hpr = new Cesium.HeadingPitchRoll(heading - Cesium.Math.PI_OVER_TWO, pitch, roll); // var rotQuat = Cesium.Quaternion.fromHeadingPitchRoll(hpr, scratchSetViewQuaternion); // var rotMat = Cesium.Matrix3.fromQuaternion(rotQuat, scratchSetViewMatrix3); var rotMat = Cesium.Matrix3.fromRotationX(Cesium.Math.PI_OVER_TWO, scratchSetViewMatrix3); Cesium.Matrix4.multiplyByMatrix3(inverseViewMatrix, rotMat, inverseViewMatrix); rotMat = Cesium.Matrix3.fromRotationY(-obj.heading, scratchSetViewMatrix3); Cesium.Matrix4.multiplyByMatrix3(inverseViewMatrix, rotMat, inverseViewMatrix); rotMat = Cesium.Matrix3.fromRotationX(obj.pitch, scratchSetViewMatrix3); Cesium.Matrix4.multiplyByMatrix3(inverseViewMatrix, rotMat, inverseViewMatrix); rotMat = Cesium.Matrix3.fromRotationZ(-obj.roll, scratchSetViewMatrix3); Cesium.Matrix4.multiplyByMatrix3(inverseViewMatrix, rotMat, inverseViewMatrix); return inverseViewMatrix; } function createVideoElement(videoSrc,id) { var videoElement = document.createElement('video'); videoElement.id = 'video'+id; videoElement.src = videoSrc;//+'?t='+new Date().getTime(); // videoElement.type = 'video/mp4'; videoElement.style.position = 'absolute'; videoElement.style.zIndex = '-100'; videoElement.style.visibility = 'hidden'; videoElement.crossOrigin = 'anonymous'; videoElement.autoplay = true; videoElement.loop = true; videoElement.muted = true; document.getElementById("videoSource").appendChild(videoElement); return videoElement; } function destroyVideoElement(videoElement) { document.getElementById("videoSource").removeChild(videoElement); } var pmCollection = []; //2.2.2 创建视频 function createCameraVideo(node,videoElement) { var poiArr = node.camPosition.split(','); var positionCt3 = Cesium.Cartesian3.fromDegrees(poiArr[0],poiArr[1],poiArr[2]); // 2.2.2.2 准备inverseViewMatrix // 准备inverseViewMatrix是为了定义视频拍摄的相机的姿态(位置和方向) // 此处设定为当前相机的欧拉角(heading\pitch\roll)和位置信息 var inverseViewMatrix = hpr2m({ position: positionCt3, heading: Cesium.Math.toRadians(Number(node.camHeading)), pitch: Cesium.Math.toRadians(Number(node.camPitch)), roll: Cesium.Math.toRadians(Number(node.camRoll)), }); // 2.2.2.3 准备frustum, // frustum是为了定义投影体的形状 // frustum选填,可以直接置为undefined var frustum = new Cesium.PerspectiveFrustum({ fov: Cesium.Math.toRadians(Number(node.camFov)), aspectRatio: Number(node.camAspectratio), near: Number(node.camNear), far: Number(node.camFar), }); // 2.2.2.4 根据以上信息创建cameraVideo var cameraVideo = new Cesium.XbsjCameraVideo({ inverseViewMatrix: inverseViewMatrix, frustum: frustum, videoElement: videoElement, showHelperPrimitive: false, }); if(node.camHoles!=null){ if(node.camHoles.length != 0){ var alphamaterial = new Cesium.Material({ fabric: { type: 'XbsjCameraVideo', uniforms: { image: '', // Cesium有bug,此处不能直接赋值video alphaImage : node.camHoles, }, components : { diffuse : 'texture2D(image, fract(materialInput.st)).rgb', // alpha : 'texture2D(alphaImage, fract(repeat * materialInput.st)).a * color.a' alpha : 'texture2D(alphaImage, fract(materialInput.st)).r', } } }); alphamaterial.uniforms.image = videoElement; cameraVideo._primitive.appearance.material = alphamaterial; } } // 2.2.2.5 加入到场景中去 viewer.scene.primitives.add(cameraVideo); var pmObj = {}; pmObj.id = 'video'+node.id; pmObj.primitive = cameraVideo; pmCollection.push(pmObj); } //2.2.3 销毁视频 function destroyCameraVideo(vid) { for ( var i = 0; i < pmCollection.length; i++) { if(vid == pmCollection[i].id){ viewer.scene.primitives.remove(pmCollection[i].primitive); } } } //显示视频列表 var camera_marks = []; var videoTreeObjList = null; var cameraData = []; function showVideo_3D(data,count){ //构建目录树 setTree_class(); function setTree_class() { //Y 属性定义 checkbox 被勾选后的情况; //N 属性定义 checkbox 取消勾选后的情况; //"p" 表示操作会影响父级节点; //"s" 表示操作会影响子级节点。 var setting = { check : { enable : true, chkboxType : { "Y" : "s", "N" : "s" } }, data : { simpleData : { enable : true } }, callback : { onClick : zTreeOnClick_class, onCheck : zTreeOnCheck_class, }, view : { showIcon: showIconForTree } }; var treeListArray = []; for (var i = 0; i < data.length; i++) { var j = {}; j.id = data[i].id; j.pId = data[i].camPid; if(data[i].camAdd == "资源列表"){ j.name = data[i].camAdd+" (共"+count+"台)[右键结束视角锁定!]"; }else{ j.name = data[i].camAdd; } j.highlight = false; j.camUrl = data[i].camUrl; j.camPosition = data[i].camPosition; j.camIsnode = data[i].camIsnode; j.camFov = data[i].camFov; j.camHeading = data[i].camHeading; j.camPitch = data[i].camPitch; j.camRoll = data[i].camRoll; j.camNear = data[i].camNear; j.camFar = data[i].camFar; j.camAspectratio = data[i].camAspectratio; j.camHoles = data[i].camHoles; j.camRtsp = data[i].camRtsp; j.camPort = data[i].camPort; if (!data[i].camIsnode) { var position = data[i].camPosition.split(','); cameraData.push({ name : data[i].id, value :[Number(position[0]),Number(position[1]),Number(position[2])], type : data[i].camType }); }else{ if(data[i].camAdd == "资源列表"){ j.icon = "../images/treeicon/video.png"; }else{ j.icon = "../images/treeicon/site.png"; } j.nocheck = true; } treeListArray.push(j); } videoTreeObjList = $.fn.zTree.init($("#camTree"), setting, treeListArray); var url = Cesium.buildModuleUrl('../../images/camera1.png'); for (var i0 = 0;i0"; $("#"+videoContainerCurr).append(strrr); var treeNodeRecord = {"treeNodeTid":treeNode.tId,"vContainerId":videoContainerCurr}; treeNodesRecord.push(treeNodeRecord); }else{ var ifVideoNodeId = $("#"+videoContainerCurr).find('video').last().attr("id"); if(ifVideoNodeId){ var nodes = theVideoTreeObjList.getNodes(); var node = theVideoTreeObjList.getNodeByTId(ifVideoNodeId); node.checked = false; theVideoTreeObjList.updateNode(node); for(var i=0; i"; $("#"+videoContainerCurr).empty(); $("#"+videoContainerCurr).append(strrr); var treeNodeRecord = {"treeNodeTid":treeNode.tId,"vContainerId":videoContainerCurr}; treeNodesRecord.push(treeNodeRecord); }else{ var strrr = ""; $("#"+videoContainerCurr).append(strrr); var treeNodeRecord = {"treeNodeTid":treeNode.tId,"vContainerId":videoContainerCurr}; treeNodesRecord.push(treeNodeRecord); } } } //获取显示九宫格中哪个容器 var videoContainerCurr=null; var videoContainerPre = null; function getVideoAnalyzeContainer(videoContainerId){ videoContainerCurr = videoContainerId; if(videoContainerPre!=null){ $("#"+videoContainerPre).css("background","rgba(25,25,25,0.6)"); } $("#"+videoContainerId).css("background-color","#000"); videoContainerPre = videoContainerId; } //清除分析摄像头标签 function clearCameraAnalyzePin(){ for(var i1 = 0; i1 < camera_marks.length; i1++){ viewer.entities.remove(camera_marks[i1]); // 将标注从场景移除 } camera_marks.length=0; for ( var n = 1; n < 10; n++) { var videodomid = "#videoPy"+n; $(videodomid).empty(); } } //定点环视 function fixedView(lon,lat,height,camHeading,camPitch,camRoll){ viewer.camera.flyTo({ destination : Cesium.Cartesian3.fromDegrees(Number(lon), Number(lat), Number(height)), orientation : { heading : Cesium.Math.toRadians(Number(camHeading)), // 方向 pitch : Cesium.Math.toRadians(Number(camPitch)),// 倾斜角度 roll : Cesium.Math.toRadians(Number(camRoll)) } }); lockCamera(false); stopCamMoveListener(); startRotateOnCam(lon,lat,height,camHeading,camPitch,camRoll); } //锁定摄像机方法 function lockCamera(value){ viewer.scene._screenSpaceCameraController.enableLook = value; viewer.scene._screenSpaceCameraController.enableTranslate = value; viewer.scene._screenSpaceCameraController.enableRotate = value; viewer.scene._screenSpaceCameraController.enableZoom = value; viewer.scene._screenSpaceCameraController.enableTilt = value; } //鼠标拖动视角 var fixedHandler; function startRotateOnCam(lon,lat,height,camHeading,camPitch,camRoll){ var heading = Number(camHeading); var pitch = Number(camPitch); var startMousePosition; var mousePosition; var flags = false; fixedHandler = fixedHandler && fixedHandler.destroy(); fixedHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); fixedHandler.setInputAction(function(movement) { flags = true; mousePosition = startMousePosition = Cesium.Cartesian3.clone(movement.position); }, Cesium.ScreenSpaceEventType.LEFT_DOWN); fixedHandler.setInputAction(function(movement) { mousePosition = movement.endPosition; }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); fixedHandler.setInputAction(function(position) { flags = false; }, Cesium.ScreenSpaceEventType.LEFT_UP); fixedHandler.setInputAction(function(position) { flags = false; fixedHandler = fixedHandler && fixedHandler.destroy(); lockCamera(true); startCamMoveListener(); }, Cesium.ScreenSpaceEventType.RIGHT_UP); viewer.clock.onTick.addEventListener(function(clock) { if (flags) { var cwidth = viewer.canvas.clientWidth; var cheight = viewer.canvas.clientHeight; // Coordinate (0.0, 0.0) will be where the mouse was clicked. var x = (mousePosition.x - startMousePosition.x) / cwidth; var y = -(mousePosition.y - startMousePosition.y) / cheight; if(x>0.1){ heading += 3; }else if(x<-0.1){ heading -= 3; } if(y>0.1){ pitch += 1; }else if(y<-0.1){ pitch -= 1; } viewer.camera.setView({ destination : Cesium.Cartesian3.fromDegrees(Number(lon), Number(lat), Number(height)), orientation : { heading : Cesium.Math.toRadians(heading), // 方向 pitch : Cesium.Math.toRadians(pitch),// 倾斜角度 roll : Cesium.Math.toRadians(Number(camRoll)) } }); } }); } //移动到摄像机视角 function flytoCamView(treeNode){ var positionStr = treeNode.camPosition.split(","); viewer.camera.flyTo({ destination : Cesium.Cartesian3.fromDegrees( Number(positionStr[0]), Number(positionStr[1]), Number(positionStr[2]) ), orientation : { heading : Cesium.Math.toRadians(Number(treeNode.camHeading)), // 方向 pitch : Cesium.Math.toRadians(Number(treeNode.camPitch)),// 倾斜角度 roll : 0 } }); } //高亮选中图标 var videoTreeNodeId; function highlightVideoPin(id){ if(videoTreeNodeId!=""){ if(viewer.entities.getById(videoTreeNodeId)!=undefined){ viewer.entities.getById(videoTreeNodeId).billboard.color = Cesium.Color.WHITE; } } videoTreeNodeId="ca"+id; if(viewer.entities.getById(videoTreeNodeId)!=undefined){ viewer.entities.getById(videoTreeNodeId).billboard.color = Cesium.Color.YELLOW; } } //启动相机移动监听 var camMovehandler; var lockfunction; //超范围回弹标记,回弹坐标参数 var isCamLock = false; var camLockId; var pointLock; var headingLock; var pitchLock; function startCamMoveListener(){ camMovehandler = camMovehandler && camMovehandler.destroy(); camMovehandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); //屏蔽Cesium的默认双击追踪选中entity行为 viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); //根据相机画面的变化来判断相机的最佳视角 lockfunction = function(){ returntoLockPoi(); }; viewer.camera.moveEnd.addEventListener(lockfunction); //鼠标右键解除超范围回弹控制 camMovehandler.setInputAction(function(movement){ isCamLock = false; camLockId = ""; pointLock = ""; headingLock = ""; pitchLock = ""; },Cesium.ScreenSpaceEventType.RIGHT_CLICK); //鼠标经过标签显示视频投影范围 camMovehandler.setInputAction(function onMouseMove(movement){ if(!isCamLock){ var pickedFeature = viewer.scene.pick(movement.endPosition); //判断鼠标是否在三维场景内 if (Cesium.defined(pickedFeature)) { //判断鼠标是否触碰到标签 if(pickedFeature.id != undefined){ currentEntity = viewer.entities.getById(pickedFeature.id._id); //排除鼠标触碰到红线 if(currentEntity!=undefined){ if(currentEntity._name!=undefined){ for (var i = 0; i < preVideoScopePrimitiveArr.length; i++) { viewer.scene.primitives.remove(preVideoScopePrimitiveArr[i]); } getVideoScopeById_3D(currentEntity.id.substring(2)); } } }else{ closeAllVideoScope(); } } } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); } //停止相机移动监听 function stopCamMoveListener(){ camMovehandler = camMovehandler && camMovehandler.destroy(); viewer.camera.moveEnd.removeEventListener(lockfunction); } //限制查看视频的移动范围 function returntoLockPoi(){ if(isCamLock){ var camPoiR = viewer.camera.position; var camHeading = viewer.camera.heading; var camPitch = viewer.camera.pitch; if(cameraData.length>0){ $.each(cameraData, function() { var cameraPoints = Cesium.Cartesian3.fromDegrees(this.value[0], this.value[1], this.value[2]); var cameraDistance = Cesium.Cartesian3.distance(camPoiR,cameraPoints); //距离不超过10米 方向角度不超过1 倾斜角度不超过1 if(cameraDistance<15 && Math.abs(camHeading-Cesium.Math.toRadians(Number(this.value[3])))<0.3 && Math.abs(camPitch-Cesium.Math.toRadians(Number(this.value[4])))<0.3 ){ }else{ //超出设定范围回弹 if(this.name == camLockId){ viewer.camera.setView({ destination : pointLock, orientation : { heading : headingLock, // 方向 pitch : pitchLock,// 倾斜角度 roll : 0 } }); }else{ //注释掉的目的是同时手动打开多个视频 //videotheVideoTreeObjList.checkNode(videotheVideoTreeObjList.getNodeByParam("id",this.name,null), false, false); //videotheVideoTreeObjList.setting.callback.onCheck(null, videotheVideoTreeObjList.setting.treeId, videotheVideoTreeObjList.getNodeByParam("id",this.name,null)); } } }); } } } //创建视频投影的范围 var preVideoScopeElement = null; var preVideoScopePrimitiveArr = []; function createVideoScope(data){ if(preVideoScopeElement!=null){ destroyVideoElement(preVideoScopeElement); } preVideoScopeElement = createVideoElement("","videoScope"); var poiArr = data.camPosition.split(','); var positionCt3 = Cesium.Cartesian3.fromDegrees(poiArr[0],poiArr[1],poiArr[2]); // 2.2.2.2 准备inverseViewMatrix // 准备inverseViewMatrix是为了定义视频拍摄的相机的姿态(位置和方向) // 此处设定为当前相机的欧拉角(heading\pitch\roll)和位置信息 var inverseViewMatrix = hpr2m({ position: positionCt3, heading: Cesium.Math.toRadians(Number(data.camHeading)), pitch: Cesium.Math.toRadians(Number(data.camPitch)), roll: Cesium.Math.toRadians(Number(data.camRoll)), }); // 2.2.2.3 准备frustum, // frustum是为了定义投影体的形状 // frustum选填,可以直接置为undefined var frustum = new Cesium.PerspectiveFrustum({ fov: Cesium.Math.toRadians(Number(data.camFov)), aspectRatio: Number(data.camAspectratio), near: Number(data.camNear), far: Number(data.camFar), }); // 2.2.2.4 根据以上信息创建cameraVideo var cameraVideo = new Cesium.XbsjCameraVideo({ inverseViewMatrix: inverseViewMatrix, frustum: frustum, videoElement: preVideoScopeElement, showHelperPrimitive: true }); cameraVideo._primitive.appearance.material.uniforms.color = Cesium.Color.RED.withAlpha(0.2); viewer.scene.primitives.add(cameraVideo); preVideoScopePrimitiveArr.push(cameraVideo); } //气泡贴地方法 function putVideo(id,type){ if(type=="video"){ //调用zTree videoTreeObjList.checkNode(videoTreeObjList.getNodeByParam("id",id,null), true, false); videoTreeObjList.setting.callback.onCheck(null, videoTreeObjList.setting.treeId, videoTreeObjList.getNodeByParam("id",id,null)); closeVideoPop(id); stopCamMoveListener(); }else if(type=="emergency"){ $.each(rhpcListArray,function(){ if(this.id == id){ flytoCamView(this); startVideoConverter(this,null,false,""); } closeVideoPop(this.id); }); } } //移除白模方法 function closeAllVideoScope(){ for (var i = 0; i < preVideoScopePrimitiveArr.length; i++) { viewer.scene.primitives.remove(preVideoScopePrimitiveArr[i]); } }