var _musicMaxWeight = 8//M
function reData(data,type) {
return JSON.stringify(data) == type ? null : data
}
//新编辑界面
var EditTools = function (n) {
//main2018 里面的主要对象
this.n = n;
//当前状态
this.atPanel = null;
//场景信息
this.sceneInformation = new SceneInformation();
//热点
this.hotpoint = new Hotpoint();
//导览
this.editGuide = new EditGuide();
//音乐
this.editMiuse = new EditMiuse();
//初始化界面
this.init();
}
EditTools.prototype.init = function () {
this.hotpoint.init(this.n);
var that = this;
this.saveAll();
this.active();
//请求数据someData.js
$.ajax(g_Prefix + "data/" + window.number + "/someData.json" + "?" + Date.now(), { dataType: "json" })
.done(function (data) {
//创建导览
that.editMiuse.init(data);
//请求完someData.js 之后再请求data2.js
data2(data, that.sceneInformation.init);
})
//请求热点数据 data2.js
function data2(data, callback) {
$.ajax(g_Prefix + "data/" + window.number + "/data2.js" + "?" + Date.now(), { dataType: "json" })
.done(function (data2) {
callback(data, data2);
// fyz 初始化导览需要两部分数据, 其中data2为data.js中的数据
that.editGuide.init(data, data2);
}).fail(
callback(data, data2)
)
}
$("body").on("click", function () {
$(".DelConfirm").removeClass("active");
})
}
//点击的时候激活状态
EditTools.prototype.active = function () {
var that = this;
var confirmSnap = $(".confirmSnap.innerBtn");
var snapshotGui = $(".snapshotGui.overlayGui");
$('.toolBottom .toolLeft li').click(function () {
var name = $(this).data("name");
$('.toolLeft li[data-name=' + name + ']').addClass("active").siblings().removeClass("active");
$('.toolRight .' + name).removeClass("hide").siblings().addClass("hide");
if(name == that.atPanel)return;
console.log(`atPanel ${that.atPanel} name ${name}`)
switch(that.atPanel){//退出
case "panoVisible":
permitTranMode(true)
panoVisiSet.finishSetPanoVisible()
break;
case "screen":
confirmSnap.addClass("hide").removeClass("unable");
snapshotGui.hide();
break;
case "overlay":
EditOverlay.leave()
break;
case "hotpoint":
$("#hotpointDetail").hasClass("atRight") || $("#hotpointDetail a.close").click()
break;
}
switch(name){
case "panoVisible":
var enter = function(){
if(player.modeTran.split('-')[1] != "floorplan"){
setTimeout(panoVisiSet.beginSetPanoVisible.bind(panoVisiSet), 300)//提前一点出现
}
player.flyToMode("floorplan", panoVisiSet.beginSetPanoVisible.bind(panoVisiSet));
}
$(".toolLeft").addClass("unable")
permitTranMode(false)
if(!player.modeTran){
player.afterCModeFuc = ()=>{
enter()
}
}else enter()
break;
case "screen":
confirmSnap.removeClass("hide");
$('#camera-start').text("点此设置为初始画面")
snapshotGui.show();
if(player.modeTran.split("-")[1] != "panorama")$(".confirmSnap").addClass("unable")
break;
case "overlay":
EditOverlay.enter()
break;
}
that.atPanel = name;
/* if(name != "hotpoint"){
$("#hotpointDetail").hasClass("atRight") || $("#hotpointDetail a.close").click()
} */
})
//滚动阻止事件
$(".toolRight div.content").on("mousewheel", function (event) {
event.stopPropagation()
});
// 输入框阻止事件
$('.toolRight').on('keydown', function (ev) {
ev.stopPropagation();
})
}
//保存按钮
EditTools.prototype.saveAll = function () {
var that = this;
$('#save').on('click', function () {
$(".edit-loading").removeClass("hide");
//导览的数据
var guides = Array.from($('.tourList ul li')).map(function (dom) {
return dom.data
})
var hots = {}
// 热点数据
Array.from($('.spotList ul li')).forEach(function (dom) {
if(dom.infoAttribute){
delete dom.infoAttribute.position;
delete dom.infoAttribute.quaternion;
}
hots[dom.hotAttribute.belongHot.sid] = {
position: {
x: dom.hotAttribute.position.x,
y: dom.hotAttribute.position.y,
z: dom.hotAttribute.position.z
},
rotation: {
x: dom.hotAttribute.rotation.x,
y: dom.hotAttribute.rotation.y,
z: dom.hotAttribute.rotation.z
},
infoAttribute: dom.infoAttribute
}
})
var info = {
name: $('#pjtName').val(),
summary: $('#info-summary').val(),
weixinDesc:$('#weixin-summary').val(),
backgroundMusic: $('#query-bgm').attr('href'),
hoticon: JSON.parse($(".hotStyle-item li.active").attr("data-val")),
camera_start: $('#camera-start')[0].data,
loadlogo: $("#loadlogo").is(':checked'),
special: $("#g_specialScene").is(':checked'),
vision_version: $("#twoData").is(':checked') ? "1.1.562.17209" : false,
/************************************** 方奕卓 场景可配置项 ******************************************/
hotImageScale: $("#hotImgScale").is(':checked'), // 热点图片可放大
hideFloorMarker: $("#hideFloorMarker").is(':checked'), // 地面标记
hideMouseMarker: $("#hideMouseMarker").is(':checked'), // 鼠标标记
floorMarkerColor: $('#floorMarkerColor').val(), // 地面/导览标志颜色
mouseMarkerColor: $('#mouseMarkerColor').val(), // 鼠标标志颜色
momentTour: $('#tourSwitch input').is(':checked') ? 'black' : 'walk', // 导览瞬间过渡
showHotListSta: $('#hotListSwitch input').is(':checked'), // 开启热点列表
hotIconScale: $('#hotIconScale input').val(), // 热点缩放
supportsVR: $('#VRSwitch input').is(':checked'), // 开启VR功能
}
var overlayInfo = []
player.overlayGroup.children.forEach((overlay)=>{
var info = EditOverlay.getSavingInfo(overlay)
if(info)overlayInfo.push(info);
})
$.ajax({
method: 'POST',
headers:{
'Content-Type':'application/json',
token:token
},
dataType:'json',
contentType:'application/json',
url: ceshi + '/manage/scene/edit',
data: JSON.stringify({
sceneCode:number,
hots: reData(hots,'{}') ,
name: number,
guides: reData(guides,'[]'),
info: info,
tourAudio: reData(that.editGuide.tourAudio,'{}'),
overlays: reData(overlayInfo,'[]')
}),
success: function (data) {
if (data.code === 0) {
location.reload()
}
if (data.code === 5001) {
alert('请重新登录')
localStorage.dcj_token = ''
location.reload()
}
}
})
});
}
//场景信息编辑
var SceneInformation = function () {
}
SceneInformation.prototype.init = function (data, data2) {
var $options = $('.hotStyle-item li');
var $loadlogo = $("#loadlogo");
var $hotImageScale = $("#hotImgScale");
var $hideFloorMarker = $("#hideFloorMarker");
var $hideMouseMarker = $("#hideMouseMarker");
var $g_specialScene = $("#g_specialScene");
var $twoData = $("#twoData");
/*******************方奕卓 其他项需要用到data来初始化, 故一并放到这里 ******************/
let momentTour = $('#tourSwitch input'); // 导览瞬间过渡开关
let hotListSwitch = $('#hotListSwitch input'); // 热点列表开关
let hotIconScale = $('#hotIconScale input'); // 热点图标缩放
let VRSwitch = $('#VRSwitch input'); // VR功能开启
/***********************************************************************************/
$(".model-title2").text(data.name);
$('#pjtName').val(data.name);
$('#info-summary').val(data.summary);
//if (data2) $('#weixin-summary').val(data2.weixinDesc);
$('#weixin-summary').val(data.weixinDesc);
for (var i = 0; i < $options.length; i++) {
if ($options.eq(i).attr('data-val') === JSON.stringify(data.hoticon)) {
$options.eq(i).addClass("active").siblings().removeClass("active");
}
}
$('#camera-start')[0].data = data.camera_start;
$(".shotImg.innerBtn").on("click",()=>{
var EntryInfo = $('#camera-start')[0].data
if(EntryInfo){
var to = player.model.panos.get(EntryInfo.pano.uuid);
var q = new THREE.Quaternion().fromArray(EntryInfo.camera.quaternion);
var lookAtPoint = new THREE.Vector3(0, 0, -1).applyQuaternion(q).add(to.position);
player.flyToPano({ pano: to, lookAtPoint: lookAtPoint })
}
})
/*************方奕卓 其他项的初始化操作 ************/
initColorElem(data);
addListener(); // 给其他元素绑定事件
if (data.momentTour === 'black') {
momentTour.prop('checked', true);
}
if (data.showHotListSta && data.showHotListSta != "false") {
hotListSwitch.prop('checked', true);
}
if (data.hotIconScale && parseFloat(data.hotIconScale) <= 1.5 && parseFloat(data.hotIconScale) >= 0.3) {
hotIconScale.val(parseFloat(data.hotIconScale));
}
if (data.supportsVR) {
VRSwitch.prop('checked', true);
}
/************************************************/
//隐藏公司logo
if (data.loadlogo) {
$loadlogo[0].checked = true
showLogo();
}
// 热点图片放大
if (data.hotImageScale && data.hotImageScale != "false") {
$hotImageScale[0].checked = true
}
// 隐藏地面标记
if (data.hideFloorMarker && data.hideFloorMarker != "false") {
$hideFloorMarker[0].checked = true
}
// 隐藏鼠标标记
if (data.hideMouseMarker && data.hideMouseMarker != "false") {
$hideMouseMarker[0].checked = true
}
//特殊大场景
if (data.special === "true" || data.special) {
$g_specialScene[0].checked = true
}
//启动二代的数据
if (data.vision_version === "1.1.562.17209" || data.vision_version) {
$twoData[0].checked = true
}
}
/**
* 初始化颜色选择的html元素
* @param {*} data
* @param {*} elem
*/
function initColorElem(data, elem) {
let $floorMarkerColor = $('#floorMarkerColor');
let $mouseMarkerColor = $('#mouseMarkerColor');
let $floorMarkerColorTex = $('#floorMarkerColorTex');
let $mouseMarkerColorTex = $('#mouseMarkerColorTex');
var colorRe = /^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/;
// 判断data中是否有存在的颜色值, 否则设置默认值
data.floorMarkerColor ? $floorMarkerColor.val(data.floorMarkerColor) : $floorMarkerColor.val('#4bcdfc');
data.mouseMarkerColor ? $mouseMarkerColor.val(data.mouseMarkerColor) : $mouseMarkerColor.val('#4bcdfc');
// 事件监听
$floorMarkerColor.on('change', function (e) {
$('#floorMarkerColorTex').attr('placeholder', e.target.value)
})
$floorMarkerColorTex.on('blur keydown', function (e) {
(e.type === 'blur' || e.type === 'keydown' && e.keyCode === 13) && setColor(e, $floorMarkerColor, this);
})
$mouseMarkerColor.on('change', function (e) {
$('#mouseMarkerColorTex').attr('placeholder', e.target.value)
})
$mouseMarkerColorTex.on('blur keydown', function (e) {
(e.type === 'blur' || e.type === 'keydown' && e.keyCode === 13) && setColor(e, $mouseMarkerColor, this);
})
// 设置颜色值
function setColor(e, colorElem, inputElem) {
var isColor = colorRe.test(e.target.value);
isColor && colorElem.val(e.target.value);
// isColor ? colorElem.val(e.target.value): (inputElem.placeholder = colorElem.val());
}
}
function addListener() {
}
//设置初始界面
function getSeft(seft) {
$('#camera-start').on('click', function () {
if(panoVisiSet.setPanoVisible){
return panoVisiSet.savePanoVisibles()
}
// 这部分内容需要配合main_2018.js中来进行修改
var snap = JSON.parse("{" + seft.getSnapAngleInfo() + "}")
this.data = {
camera :{
position : snap.metadata.camera_position,
quaternion : snap.metadata.camera_quaternion // 相机朝向
},
pano:{
uuid : snap.metadata.scan_id // 起始点位的id
}
}
var ev = document.createEvent("MouseEvent");//点击截取视图
g_snapShotWidth = 240;
g_snapShotHeight = 118;
window.screenSta = 'startScreen';
ev.initMouseEvent("snapshotBegin", true, true, document.defaultView, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
ev.__callback = (imgData, info)=>{
uploadImg(imgData, (rs)=>{
if (rs.code === 0) {
$(".shotImg.innerBtn").css("background-image", "url(" + rs.data + ")")
this.data.thumbImg = rs.data;
}
})
}
window.dispatchEvent(ev);
});
}
//热点编辑
var Hotpoint = function () {
this.spotList = $(".spotList");
this.hotpointDetail = $("#hotpointDetail"); // fyz 导览编辑页面同样采取热点编辑的样式, 这里确保只查找到热点编辑
}
Hotpoint.prototype.init = function (n) {
this.active();
this.addmedia(); // 添加多媒体
this.addMusic(); // 添加音乐
this.addModel(); // 添加模型
this.addwebPack(); // 添加外链
this.saveHot(); // 保存热点
var that = this;
let hotIconScale = $('#hotIconScale');
//点击添加热点按钮
$('#addHotSpots').on("click", function () {//点击添加热点
g_HotStatus = g_HotStatus === "add" ? null : "add";
$("#player").css("cursor", "cell");
});
//点击热点列表弹出按钮
this.spotList.on("click", function (e) {
var target = $(e.target);
if (target.hasClass("del")) {
e.stopPropagation();
target.siblings(".DelConfirm").addClass("active");
that.spotList.find("i").text(that.spotList.find("ul li").length);
} else {
if (target.hasClass("DelConfirm")) {
e.stopPropagation();
that.remHot(target, n);
} else {
//点击热点列表弹出编辑热点窗口
if (target.hasClass("title") || target.hasClass("icon")) {
that.editHot(target)
}
}
}
});
//点击热点编辑窗口右上角的关闭按钮
this.hotpointDetail.find("a.close, button.cancel").on("click", function () {
var spot_id = that.hotpointDetail.attr("data-id");
var info = that.hotpointDetail[0].targetDOM.infoAttribute;
if(info){
var hot = player.model.hots[spot_id];
info.position && hot.mesh.position.copy(info.position)
info.quaternion && hot.mesh.quaternion.copy(info.quaternion)
}
that.hotpointDetail.addClass("atRight");
transformControls.detach()
});
//遍历热点 初始话加载热点数据
for (var i = 0; i < g_HotMeshes.length; i++) {
this.spotList.children("ul").append(this.addHotList(g_HotMeshes[i], i));
}
this.spotList.find("i").text(g_HotMeshes.length);
// 初始话的时候把热点信息添加到对应的热点中
$.ajax(g_Prefix + "data/" + window.number + "/hot/js/data.js" + "?" + Date.now(), { dataType: "json" })
.then(function (infos) {
that.infos = infos ;
Object.keys(infos).forEach(function (key) {
//sxm增加热点列表可读性,方便查看删除操作等
that.spotList.find("ul li[data-spid=" + key + "]")[0] && (that.spotList.find("ul li[data-spid=" + key + "]")[0].infoAttribute = infos[key])&& (that.spotList.find("ul li[data-spid=" + key + "] .title").html(infos[key].title));
})
})
}
/**
* 显示编辑热点的窗口和初始化热点窗口的数据
*/
Hotpoint.prototype.editHot = function (target) {
this.hotpointDetail.removeClass("atRight");
$("#hotpointDetail .audio.mediaUpload").find("input").val(''); // 点击编辑导览清空上一次文件
var playIcon = '139.159.225.37:85/images/play.png';
var $layout = $("#hotpointDetail")[0];
$layout.targetDOM = target.closest("li")[0];//closest匹配选择器的第一个祖先元素
//编辑时将热点列表唯一标识带入,以便后期保存使用识别
var li_id = $($layout.targetDOM).attr("data-spid");
this.hotpointDetail.attr("data-id",li_id);
var info = $layout.targetDOM.infoAttribute || {}
transformControls.transCtlChangeMode("translate")
// 参数初始化
info.title = info.title || '';
info.content = info.content || '';
info.iframe = info.iframe || [];
info.model = info.model || [];
info.images = info.images || [];
info.video = info.video || [];
try{
transformControls.attach(player.model.hots[li_id].mesh)
player.model.hots[li_id].examine(player,{dontOpen:true})//add
info.position = player.model.hots[li_id].mesh.position.clone()
info.quaternion = player.model.hots[li_id].mesh.quaternion.clone()
}catch(e){}
initStyle(player.model.hots[li_id])
var iframesHTML = info.iframe.map(function (iframe) {
return this.inputList("请填写网页链接", iframe)
}.bind(this))
var modulesHTML = info.model.map(function (module) {
return this.inputList("请填写网页链接", module)
}.bind(this))
var imagesHTML = info.images.map(function (image) {
return '
'))
div.addClass('slider')
if(o.unitStr){
div.find(".BarTxt").append($('
'+ o.unitStr +''));
}
o.root.append(div);
this.line = $(".scrollBar", div);
this.knot = $(".scroll_Thumb", div);
o.noValue || (this.textArea = $(".scrollBarTxt", div));
this.track = $(".scroll_Track", div);
this.unitStr = o.unitStr;//unitStr是单位字符串,比如角度的°。不能是数字
this.onchange = o.onchange;
this.percent = null;
this.dragStart = false;
this.offsetToBody = null;
this.getOffset();
this.checkError();
this.percent = this.getPercent();
o.noValue || this.displayValue();
this.moveKnot();
this.knotWidth = 0;
this.lineWidth = 0;
//this.waitValue;//等待要触发事件的值,防止崩溃
this.avoidCrash = o.avoidCrash;
this.realMax = !this.noValue ? o.realMax : null;//如果传入realMax,代表可以通过输入数字修改最大值范围,最大值不可以超过realMax。
this.scrollUnit = (scope.max - scope.min) * 0.001;
if(this.precision != void 0){
var prec = Math.pow(10,-this.precision);
this.scrollUnit < prec && (this.scrollUnit = prec);
}else{//默认化为整数
this.scrollUnit < 1 && (this.scrollUnit = 1);
}
this.dragStartEvent = o.dragStartEvent;
this.line.on( "mousedown touchstart", function (event) {
scope.dragStart = true;
scope.dragChange(event);
if(scope.dragStartEvent)scope.dragStartEvent()
//if(o.avoidCrash && isMobile)scope.dealInterval();
});
!window.isMobile && this.line.on( "mousewheel DOMMouseScroll wheel", function (event) {
event.preventDefault();
var v = event.originalEvent.deltaY>0 ? -scope.scrollUnit : scope.scrollUnit;
scope.setValue(scope.value + v);
});
this.dragEndEvent = o.dragEndEvent;
var stop = function(){
if (scope.dragStart) {
scope.dragStart = false;
if(scope.dragEndEvent)scope.dragEndEvent()
}
}
$(document).on("mouseup touchend",stop)
/* isMobile || */$("#player").on("mouseup",stop)
var lastChangeTime = 0;
$(document).on("mousemove touchmove",function(){
if (scope.dragStart) {
/* if(isMobile && o.avoidCrash){
scope.lastDragEvent = event;
}else */scope.dragChange(event);
}
})
o.noValue || this.textArea.on("change", function () {
var v = parseFloat(scope.textArea.val());
if (v != v)//NaN
return;
scope.setValueFromOutside(v);
});
}
SlideBar.prototype.dealInterval = function(){
this.interval = setInterval(function(){
this.lastDragEvent && this.dragChange(this.lastDragEvent);
this.lastDragEvent = null
if(!this.dragStart) clearInterval(this.interval)
}.bind(this),90)
}
SlideBar.prototype.changeLimit = function (o) {
if(o.min) this.min = o.min;
if(o.max) this.max = o.max;
}
SlideBar.prototype.getOffset = function () { //为了检测鼠标位置需要获得相对body的offset
var left = this.line[0].offsetLeft;
var element = this.line[0];
while (element = element.offsetParent) {
left += element.offsetLeft;
}
this.offsetToBody = (left == 0) ? (this.offsetToBody || 0) : left;
//如果left为0,很可能是它不可见,那么最好使用旧的offsetToBody
}
SlideBar.prototype.InitOffset = function () {
//如果一开始scroller没有显示,要在显示时获取一下offset
this.getOffset();
this.getWidth();
this.moveKnot();
}
SlideBar.prototype.checkError = function () {
if (this.min >= this.max) {
console.log("scrollbar值有误 " + name);
return;
}
}
SlideBar.prototype.getPercent = function () {
return (this.value - this.min) / (this.max - this.min);
}
SlideBar.prototype.displayValue = function (value) {
//this.textArea.val(this.value + (this.unitStr ? " " + this.unitStr : ""));
if(value != void 0)this.value = value;
this.textArea.val(this.value)
}
SlideBar.prototype.getWidth = function () {
this.knotWidth = this.knot.width();
this.lineWidth = this.line.width() - this.knotWidth
}
SlideBar.prototype.moveKnot = function () {
//this.getWidth();
var width = this.percent * this.lineWidth;
this.knot.css('left',width + "px")
if (this.track)this.track.css('width', (width + this.knotWidth / 2) + "px")
}
SlideBar.prototype.bind = function (f) {
this.onchange = f;
}
SlideBar.prototype.setValue = function (v, noEvent, changeMax) {//设置数值并改变knot位置 noEvent为true的话就可以不触发回调函数,仅仅改变显示
//if(this.value==v)return; //因为换选材质需要执行后面onchange才会带动preview的改变,所以这里一样还是执行,而拉动滑动条的部分值不变就不执行
if(this.precision != void 0){
this.value = parseFloat(v.toFixed(this.precision))
}else{//默认化为整数
this.value = Math.round(v);
}
if(changeMax && this.realMax!=void 0){
if(this.value>this.oriMax){
this.value = Math.min(this.value, this.realMax);
this.changeLimit({max:this.value})
}else{
this.changeLimit({max:this.oriMax})
}
}
this.percent = this.getPercent();
var makeit = true;
if (this.onchange && !noEvent ){
var result = this.onchange(this.value); //如果执行的函数不允许这个值,就不能变
if(result === false){
makeit = false;
}
}
if(makeit){
this.moveKnot();
//console.log("SlideBarV-"+this.name + " : "+this.value)
this.noValue || this.displayValue();
}
}
SlideBar.prototype.dragChange = function (event) {//拖动时触发 计算数值
//this.getWidth();
//if(!this.offsetToBody || isNaN(this.offsetToBody)this.getOffset();
if (event.clientX != void 0) {
this.percent = (event.clientX - this.knotWidth / 2 - this.offsetToBody) / this.lineWidth;
} else {
if(event.touches != void 0){
this.percent = (event.touches[0].clientX - this.knotWidth / 2 - this.offsetToBody) / this.lineWidth;
}
else this.percent = (event.originalEvent.touches[0].clientX - this.knotWidth / 2 - this.offsetToBody) / this.lineWidth;
}
if (this.percent < 0)
this.percent = 0;
else if (this.percent > 1)
this.percent = 1;
//var v = this.percent * this.max;
var v = this.percent * (this.max - this.min) + this.min;
//var v = Math.round(this.percent * this.max * 10)/10; //精度为0.1
if (this.value == v)
return;
this.setValue(v);
}
SlideBar.prototype.setValueFromOutside = function (v) { //外面的事件触发的
if (this.line.width() == 0)
return;
//不可见就不执行。
//v = Math.round(v*10)/10;
if(this.realMax!=void 0){
v = THREE.Math.clamp(v, this.min, this.realMax);
if(v>this.max)this.changeLimit({max:v});
}else v = THREE.Math.clamp(v, this.min, this.max);
this.setValue(v);
}
//-----------------------------------------------------
var LineDraw = {
createLine: function (posArr, o) {
var e = new THREE.BufferGeometry
, p = new Float32Array(6);
e.addAttribute("position", new THREE.BufferAttribute(p, 3));
//这句新旧版写法不同 旧版这样:e.addAttribute("position",Float32Array,2,3);
var p = e.attributes.position.array;
for (var i = 0; i < 2; i++) {
p[i * 3] = posArr[i].x;
p[i * 3 + 1] = posArr[i].y;
p[i * 3 + 2] = posArr[i].z;
}
var mat = new THREE[o.deshed ? "LineDashedMaterial" : "LineBasicMaterial"]({
linewidth: o.width || 1,
//windows无效。 似乎mac/ios上粗细有效 ?
color: o.color || defaultColor,
transparent: o.dontAlwaysSeen ? false : true,
depthTest: o.dontAlwaysSeen ? true : false
})
var line = new THREE.Line(e, mat);
line.renderOrder = o.renderOrder || 4
//同tagStem; //如果不加高,可能会部分被model遮住
return line;
}
}
var toPrecision = function(e, t) {
function i(e, t) {
var i = Math.pow(10, t);
return Math.round(e * i) / i
}
if (e instanceof Array) {
for (var n = 0; n < e.length; n++)
e[n] = i(e[n], t);
return e
}
return i(e, t)
}
var transformControls;
var initTransformCtl = function(THREE){
TransformControls.init(THREE)
TransformControls.prototype.transCtlChangeMode = function(mode){
//if(!this.editing)return;
if(mode && this.mode != mode){
this.mode = mode;
$(".MenuOptions[name='transform'] li").removeClass("chosen");
$(".MenuOptions[name='transform'] li[index='"+ mode +"']").addClass("chosen");
}
},
transformControls = new TransformControls( player.camera, player.domElement, {
player:player,
dontHideWhenFaceCamera:true,
scaleAxis:["x","y"], //隐藏了z轴。虽然参数没用上
NoScaleZ:true//整体缩放时只缩放xy轴。
});
transformControls.setSize(1.5)
player.model.add(transformControls)
$(".MenuOptions[name='transform'] li").on("click",(e)=>{
transformControls.transCtlChangeMode($(e.target).attr("index"))
})
}
var EditOverlay = {
editing: false,
overlayMaxCount: 10,
scroller:{
videoDepth : new SlideBar({
root: $('#videoDepth').eq(0),
value: settings.overlay.depth * 100,
min: 0 * 100,
max: 1 * 100,
name: "videoDepth",
unitStr:"cm",
avoidCrash:true,
onchange:function (s) {
if(s == 0){
EditOverlay.editPlane.addBox(false)
}else{
EditOverlay.editPlane.addBox(true)
EditOverlay.editPlane.scale.z = s/100 / settings.overlay.depth ;
}
},
dragEndEvent:function(){
}
})
},
init: function(THREE){
var mat = new THREE.MeshBasicMaterial({wireframe:true, opacity:0.5, color:"#57e4f3", transparent:true})
var wireframeModel = this.wireframeModel = new THREE.Object3D; wireframeModel.name = 'wireframeModel'
player.model.chunks.forEach((mesh)=>{
var chunk = mesh.clone();
chunk.material = mat;
wireframeModel.add(chunk)
})
wireframeModel.visible = false
player.model.add(wireframeModel)
//------------------------------
$('.overlay .addBtn button').on("click",this.beginToAddPlane.bind(this))
$("#overlayProp a.close").on("click",()=>{this.closeOverlayPanel("cancel")})
$("#overlayProp button.submit").on("click",(e)=>{
this.SaveOverlay()
})
$("#overlayProp button.delete").on("click",(e)=>{
this.DeleteOverlay();
})
$('#overlayUpload [name="useImgRatio"] button').on("click", this.useImgRatio.bind(this));
var uploadInput = $('
');
$('#overlayUpload [name="upload"] button').on('click',()=>{
uploadInput.click()
})
uploadInput.on("change", (e)=>{
inputMedia({
enableTypes:[/* "photo", */"video"],
videoDone:(file, video)=>{
var plane = this.editPlane.plane
$(video).css('width','100%')
$(video).css('height','100%')
plane.material.map = new THREE.VideoTexture( video );
plane.material.map.image.play();
plane.material.map.minFilter = THREE.LinearFilter;
this.editPlane.overlayType = "video";
$('#overlayUpload .preview video').remove();
//$('#overlayUpload .preview').css('background-image',"").append($(video));
video.autoplay = true;
video.loop = true;
video.volume = 0
video.muted = true
this.useImgRatio() //自适应比例
this.editPlane.file = file;
plane.material.opacity = 1;
plane.material.color = new THREE.Color(1,1,1)
plane.material.needsUpdate = true;
}
}, "video", e);
})
player.overlayGroup.children.forEach((overlay)=>{
this.getOverlayInfo(overlay)
this.addToList(overlay)
})
},
enter : function(){
this.editing = true;
this.wireframeModel.visible = true;
},
leave : function(){
if(!this.editing)return;
this.editing = false
$("#overlayProp a.close").click();
this.endAddPlane();
this.wireframeModel.visible = false;
},
beginToAddPlane: function(){
player.reticule.visible = false;
this.objCursorType = 'overlay';
player.currentCursor = 'url(images/edit/box_video.png), auto'
$('#player').css('cursor', player.currentCursor)
$('.overlay .addBtn button').addClass("unable")//可以加多个视频时的按钮
},
endAddPlane : function(){
this.objCursorType = null;
player.currentCursor = '';
$('#player').css('cursor','')
$('.overlay .addBtn button').removeClass("unable")
player.reticule.visible = true
},
addPlane : function(o){
var pos = o.intersect.point;
var overlay = new Overlay({sid:new Date().getTime()+""})
overlay.position.copy(pos);
if(player.getMouseDirection().angleTo(o.intersect.face.normal) < Math.PI/2) {
overlay.lookAt(o.intersect.face.normal.clone().negate().add(pos));
overlay.position.add(o.intersect.face.normal.clone().negate().multiplyScalar(0.01))//avoid mesh crash with chunks 模型的精度可能和floorplan的不一样,所以chunk即使材质经过处理还是会闪烁但是wallmesh不会
}else{
overlay.lookAt(o.intersect.face.normal.clone().add(pos));
overlay.position.add(o.intersect.face.normal.clone().multiplyScalar(0.01))
}
overlay.isNew = true
player.clickOverlay(overlay)
transformControls.transCtlChangeMode("translate")
this.addToList(overlay)
},
updateOverlayScaleDisplay : function(){
var overlay = this.editPlane;
var maxWidth = 193, maxHeight = maxWidth//maxWidth/2;
var ratioW = Math.abs(overlay.width) / maxWidth;
var ratioH = Math.abs(overlay.height) / maxHeight;
var ratio = 1/Math.max(ratioW,ratioH);//缩放比例
var w = Math.round(Math.abs(overlay.width)*ratio)
var h = Math.round(Math.abs(overlay.height)*ratio)
$('#overlayUpload .preview').css({
"width": w + 'px',
"height": h + 'px',
});
$('#overlayUpload .preview [attr-type="width"]').text(toPrecision(overlay.width, 2))
$('#overlayUpload .preview [attr-type="height"]').text(toPrecision(overlay.height, 2))
}
,
updateOverlayPanel : function(overlay){
this.editPlane = overlay;
var plane = overlay.plane
var src = plane.material.map && plane.material.map.image.src;
$('#overlayUpload .preview video').remove();
if(overlay.overlayType == "video"){
var video = plane.material.map.image
$('#overlayUpload .preview').css('background-image',"").append(video);
}else{
$('#overlayUpload .preview').css({
'background-image': src ? ("url(" + src + ")") : ""
})
}
if(overlay.overlayType){
$('#overlayUpload [name="useImgRatio"]').removeClass("hide")
$('#overlayUpload .preview').addClass('uploaded')
}else{
$('#overlayUpload [name="useImgRatio"]').addClass("hide")
$('#overlayUpload .preview').removeClass('uploaded')
}
this.updateOverlayScaleDisplay()
if(overlay.hasBox){
this.scroller.videoDepth.setValue(overlay.scale.z * settings.overlay.depth * 100,true)
}else{
this.scroller.videoDepth.setValue(0,true)
}
setTimeout(()=>{
this.scroller.videoDepth.InitOffset()
},201)
}
,
closeOverlayPanel : function(type){
if(!this.editPlane)return;
if(type == 'cancel'){
if(!this.editPlane.isNew && !this.editPlane.needDelete)this.editPlane.setFromInfo(this.editPlane.info) //this.setOverlayFromInfo(this.editPlane, this.editPlane.info);//恢复
else this.disposeOverlay(this.editPlane); //删除
}
this.editPlane = null;
transformControls.detach()
$("#overlayProp").addClass("atRight");
//if(player.model.overlayPlanes.length < this.overlayMaxCount) this.beginToAddPlane()
}
,
useImgRatio : function(o){
var plane = this.editPlane.plane;
if(!plane.material.map)return;
var img = plane.material.map.image;
var mintranRatio = 200;//default is 200 , 防止图片太小时在墙上依旧很大
var width = this.editPlane.overlayType == "video" ? img.videoWidth : img.width;
var height = this.editPlane.overlayType == "video" ? img.videoHeight : img.height;
if(o == "suitSize"){
var boundWidth = Math.min(Math.max(width,height)/mintranRatio, 1)
if(width > height){
var w = boundWidth;
var h = boundWidth * height / width
}else{
var h = boundWidth;
var w = boundWidth * width / height;
}
}else{
//假设不变总面积
var k = Math.sqrt(Math.abs(this.editPlane.width * this.editPlane.height) / (width * height))
var w = k * width * (this.editPlane.width<0?-1:1);
var h = k * height * (this.editPlane.height<0?-1:1);
}
this.editPlane.scale.setX(w/settings.overlay.width)
this.editPlane.scale.setY(h/settings.overlay.height)
this.editPlane.width = w;
this.editPlane.height = h;
this.updateOverlayPanel(this.editPlane)
},
getOverlayInfo : function(overlay){
//2 编辑前, 从当前状态获取info
var plane = overlay.plane;
overlay.info = {
width: overlay.width,
height: overlay.height,
depth: settings.overlay.depth * overlay.scale.z,
pos: overlay.position.clone(),
qua: overlay.quaternion.clone(),
media: plane.material.map.image,
file: overlay.file,
type: overlay.overlayType,
hasBox: overlay.hasBox
}
}
,
getSavingInfo : function(overlay){
if(!overlay.file && (!overlay.plane.material.map ||!overlay.plane.material.map.image)){
return;
}
var info = {
width: toPrecision(overlay.width, 4),
height: toPrecision(overlay.height, 4),
depth: toPrecision(settings.overlay.depth * overlay.scale.z, 4),
pos: toPrecision(overlay.position.toArray(),4),
qua: toPrecision(overlay.quaternion.toArray(),4),
sid: overlay.sid,
hasBox: overlay.hasBox ? 1 : 0,
media: [overlay.overlayType],
file: overlay.fileSrc || overlay.plane.material.map.image.src
}
return info
},
SaveOverlay : function(){
var overlay = this.editPlane;
if(!overlay.file && (!overlay.plane.material.map ||!overlay.plane.material.map.image)){
alert("请上传视频");return;
}
var saveInfo = ()=>{
//overlay.savingInfo = JSON.stringify(info)//准备写入的info
//saveDone:
overlay.isNew = false;
this.getOverlayInfo(overlay);
this.closeOverlayPanel()
$('.waiting').removeClass('showloading');
}
if(!overlay.info || overlay.file != overlay.info.file){
$('.waiting').addClass('showloading');
uploadFile(overlay.file, 'overlay', function (rs) {
if (rs.code === 0) {
overlay.fileSrc = rs.data;
saveInfo()
};
} )
}else saveInfo();
}
,
disposeOverlay : function(overlay){
var plane = overlay.plane
if(overlay == player.hoveringPlane){
player.hoverOverlay(null,"soon");
}
if(plane.material.map){//删除视频src
//overlay.info && common.destroyBlob(overlay.info.media.src)
//common.destroyBlob(plane.material.map.image.src)
}
plane.material.dispose();
overlay.parent.remove(overlay);
this.removeFromList(overlay)
//this.beginToAddPlane()
}
,
DeleteOverlay : function(){
var overlay = this.editPlane;
if(!overlay.isNew){
if(confirm("确定删除该视频?")){
overlay.needDelete = true;
$("#overlayProp a.close").click()//this.closeOverlayPanel()
}
}else{//刚创建时的删除按钮等同于取消按钮
$("#overlayProp a.close").click()//this.closeOverlayPanel()
}
}
,
addToList : function(overlay){
var li = $(`
${overlay.sid}
`)
$(".overlayList ul").append(li);
li.on("click",()=>{
player.clickOverlay(overlay)
})
overlay.domLi = li;
},
removeFromList : function(overlay){
overlay.domLi.remove();
}
}
//----------------漫游可见性---------------------------------
var panoVisiSet = {
setPanoVisible : false,
//漫游可见性
panoVLines : {},//线条
panoVTemp:null, //修改后还没保存的临时数据
//热点可见性
$confirmSnap : $("#camera-start"),
colors:{green: "#00c8ae"},
init : function(){
this.meshGroup = new THREE.Object3D; this.meshGroup.name = "setVisible-group"
player.model.add(this.meshGroup)
},
beginSetPanoVisible : function () {
if (this.setPanoVisible ) return;
$(".toolLeft").removeClass("unable")
this.setPanoVisible = true;
this.panoVTemp = {};
this.SetOnePanoVisible(player.currentPano)//先设置currentPano
this.$confirmSnap.text('保存当前设置').removeClass("hide")
//objects.tagManager.hideAllTags();
this.updateFootIconSize()//更新一下大小,尤其是上次换了中心点然后退出又进入但是镜头没有变化的话
},
SetOnePanoVisible : function (pano) { //点击某个pano后就对该pano点进行设置
if (this.panoVsetting == pano) return;
//if (this.panoVsetting) saveLastPanoVi(this.panoVsetting);
this.panoVsetting = pano; //记录正在修改的
this.delVisibleLines(); //删除线
this.showFootIcons(pano, true);
this.createPanoVisiLines(pano); //创线
},
saveLastPanoVi : function () { //保存刚设置过的pano
var change = [];
for (var r in this.panoVLines) {
var line = this.panoVLines[r];
if (line.name.indexOf("new") > -1 && line.visible) { //新设置为visible且没有取消
change.push({
type: "add",
id: r
})
} else if (line.name.indexOf("new") == -1 && !line.visible) { //旧的且已经取消
change.push({
type: "sub",
id: r
})
}
}
if (change.length) { //添加双向的neighbour:
var self = this.searchNeib(this.panoVsetting.id)
//var seeMarkers_self = self.seeMarkers;
var neighbourUUIDs_self = self.neighbourUUIDs
var neighbourPanos_self = self.neighbourPanos;
for (var i = 0; i < change.length; i++) {
var other = this.searchNeib(change[i].id)
//var seeMarkers = other.seeMarkers;
var neighbourUUIDs = other.neighbourUUIDs;
var neighbourPanos = other.neighbourPanos;
if (change[i].type == "add") {
//seeMarkers.push(this.panoVsetting.id);
neighbourUUIDs.push(this.panoVsetting.id);
neighbourPanos[this.panoVsetting.id] = true;
//seeMarkers_self.push(change[i].id);
neighbourUUIDs_self.push(change[i].id);
neighbourPanos_self[change[i].id] = true;
} else {
//var index = seeMarkers.indexOf(this.panoVsetting.id);
//index > -1 && seeMarkers.splice(index, 1);
var index = neighbourUUIDs.indexOf(this.panoVsetting.id);
index > -1 && neighbourUUIDs.splice(index, 1);
neighbourPanos[this.panoVsetting.id] = false;
//var index = seeMarkers_self.indexOf(change[i].id);
//index > -1 && seeMarkers_self.splice(index, 1);
var index = neighbourUUIDs_self.indexOf(change[i].id);
index > -1 && neighbourUUIDs_self.splice(index, 1);
neighbourPanos_self[change[i].id] = false;
}
this.panoVTemp[change[i].id] = { //后面两个是作为保存到后台的数据存储,临时需要用到的是第一个
neighbourPanos: neighbourPanos,
//seeMarkers: seeMarkers,
neighbourUUIDs: neighbourUUIDs
}
}
this.panoVTemp[this.panoVsetting.id] = {//加上自己
neighbourPanos: neighbourPanos_self,
//seeMarkers: seeMarkers_self,
neighbourUUIDs: neighbourUUIDs_self
}
}
},
pauseSetPanoVisible : function (type) { //暂停 因为点击了保存设置 但没有退出设置
if (!this.setPanoVisible) return;
if(type == "unsaved"){//中途点击pano从而停止一个热点的设置
this.saveLastPanoVi();
}else{
this.panoVTemp = {}; //清空数据
}
this.delVisibleLines();
this.showFootIcons();//清空选择
var lastPanoSetting = this.panoVsetting;
this.panoVsetting = null;
lastPanoSetting && this.changeFIconState2(lastPanoSetting.footIcon, this.checkHasNeighbor(lastPanoSetting))//这句要放在this.panoVsetting = null后。 根据可见性更改透明度
},
//按理说改变了neighbourPano,tag的初始visible也要改。但是这样还要考虑已经改过的tag。。很麻烦
finishSetPanoVisible : function () { //结束 退出这个设置
if (!this.setPanoVisible)
return; //否则会加多个侦听
this.setPanoVisible = false;
this.hideFootIcons();
this.delVisibleLines();
//objects.tagManager.showAllTags();
this.recoverAllState2();
this.panoVsetting = null;
this.panoVTemp = {};
player.flyoutType = null
this.$confirmSnap.addClass("hide")
},
recoverAllState2 : function(){//为了热点可视恢复成pano全部可见
for (var i = 0; i < this.footIcons.length; i++) {
this.footIcons[i].material.uniforms.opacity.value = 1;
this.footIcons[i].material.uniforms.map.value = footTex1;
}
},
afterSavePanoVisibles : function(){ //实施:
var panos = player.model.panos;
for (var i in this.panoVTemp) {
var pano = panos.index[i];
//pano.seeMarkers = this.panoVTemp[i].seeMarkers;
pano.neighbourUUIDs = this.panoVTemp[i].neighbourUUIDs;
pano.neighbourPanos = this.panoVTemp[i].neighbourPanos;
}
if(!this.checkHasNeighbor(player.currentPano)){//currentPano变为孤立点 就要换一个防止飞入
var list = panos.sortByScore([pano=>{return this.checkHasNeighbor(pano)}],
[function(pano){return -pano.position.distanceTo(player.currentPano.position)}])
if(list && list.length){
player.currentPano = list[0].pano;//找最近的一非孤立点
//this.noPanoHasNeighbor = false; //更新状态
}else{
//this.noPanoHasNeighbor = true; //更新状态
}
}else{
//this.noPanoHasNeighbor = false; //更新状态
}
//dataDeal.done();
//暂时:
this.pauseSetPanoVisible()
this.updateFootIconSize()//更新一下center大小 写在最后
},
//最佳推荐操作顺序: 先设置pano可见性 再创建热点 这样热点的visible正确些,否则之后再设置热点可见性会改更多
savePanoVisibles : function () { //保存
if (this.panoVsetting) this.saveLastPanoVi(this.panoVsetting); //获取最后设置的那个热点的改动
var PanoData = [];
for (var i in this.panoVTemp) {
PanoData.push({//希望算法部不会更改index排序,或者更改后能将visible信息一并更改
panoID: i,
//visibles: this.turnToPanoIndex(this.panoVTemp[i].seeMarkers),
visibles3: this.turnToPanoIndex(this.panoVTemp[i].neighbourUUIDs)
})
}
if (PanoData.length == 0) {//没改变
alert("保存成功")
return;
}
/* this.afterSavePanoVisibles()
alert("保存成功")
console.log(JSON.stringify(PanoData)) */
$.ajax({
method: 'POST',
url: ceshi + '/manage/scene/roamViable',
headers:{
'Content-Type':'application/json',
token:token
},
contentType:'application/json',
data: JSON.stringify({
data: JSON.stringify(PanoData),
sceneCode: window.number
}),
success: (data)=>{
if (data.code === 0) {
this.afterSavePanoVisibles()
alert("保存漫游可行成功")
}else alert("保存漫游可行失败")
if (data.code === 5001) {
alert('请重新登录')
localStorage.dcj_token = ''
location.reload()
}
},
fail:function(){
alert("保存漫游可行失败")
}
})
/* var o = {
name_t: "panoVisible",
f: this.pauseSetPanoVisible,
url: Config.prefixEditProPCApi+"/saveLinkPano",
dialog: i18n.get('设置'),
data: { data: JSON.stringify(PanoData) }
}
var dataDeal = uploadsSaving.saveFucforPC(o);
dataDeal.group[0] = function () {
//实施:
for (var i in player.panoVTemp) {
var pano = player.model.panos.index[i];
pano.seeMarkers = player.panoVTemp[i].seeMarkers;
pano.neighbourUUIDs = player.panoVTemp[i].neighbourUUIDs;
pano.neighbourPanos = player.panoVTemp[i].neighbourPanos;
}
if(!player.model.checkHasNeighbor(player.currentPano)){//currentPano变为孤立点 就要换一个防止飞入
var list = player.model.panos.sortByScore([function(pano){return player.model.checkHasNeighbor(pano)}],
[function(pano){return -pano.position.distanceTo(player.currentPano.position)}])
if(list && list.length){
player.currentPano = list[0].pano;//找最近的一非孤立点
player.model.noPanoHasNeighbor = false; //更新状态
}else{
player.model.noPanoHasNeighbor = true; //更新状态
}
}else{
player.model.noPanoHasNeighbor = false; //更新状态
}
dataDeal.done();
player.model.updateFootIconSize(player.cameraControls.activeControl)//更新一下center大小 写在最后
} */
},
searchNeib : function (panoId) {//寻找某pano的相关neighbour 可能是修改过的
var panos = player.model.panos;
var o = {};
if (this.panoVTemp[panoId]) {
//o.seeMarkers = this.panoVTemp[panoId].seeMarkers;
o.neighbourUUIDs = this.panoVTemp[panoId].neighbourUUIDs;
o.neighbourPanos = this.panoVTemp[panoId].neighbourPanos;
} else {
//o.seeMarkers = panos.index[panoId].seeMarkers.slice(0);
o.neighbourUUIDs = panos.index[panoId].neighbourUUIDs.slice(0);
o.neighbourPanos = CloneObject(panos.index[panoId].neighbourPanos);
}
return o;
},
turnToPanoIndex : function (panoArr) {
var panos = player.model.panos;
var array = [];
for (var i = 0; i < panoArr.length; i++) {
var pano = panos.index[panoArr[i]];
var index = panos.list.indexOf(pano)
array.push(index);
}
return array;
},
setDisplay : function(state){
var panos = player.model.panos;
if(state){
player.model.panos.forEach((pano)=>{
if(pano.hasVideo){
pano.marker.visible = false;
pano.flagSpot.disc.visible = false;
pano.flagSpot.markGroup.hide();
}
})
player.model.cadFloorPlane.changeCadVisible(false)
}else{
player.model.panos.forEach((pano)=>{
if(pano.hasVideo){
pano.marker.visible = true;
pano.flagSpot.disc.visible = true;
pano.flagSpot.markGroup.show();
}
})
player.model.cadFloorPlane.changeCadVisible(null,{autoJudge:true})
}
player.defaultRoomLabels.forEach(function(label){ label.update()})
player.path.currentPanoMarker.mesh.visible = !state;
objects.overlayManager.group.visible = !state;
player.reticule.visible = !state;
},
delVisibleLines : function () {
//xzw add 所有线都删除
for (var i in this.tagsVLines) {
this.tagsVLines[i].geometry.dispose();
this.tagsVLines[i].material.dispose();
this.meshGroup.remove(this.tagsVLines[i]);
delete this.tagsVLines[i];
}
for (var i in this.panoVLines) {
this.panoVLines[i].geometry.dispose();
this.panoVLines[i].material.dispose();
this.meshGroup.remove(this.panoVLines[i]);
delete this.panoVLines[i];
}
},
//--------panoVisible
createPanoVisiLines : function (pano) {
// pano可见性线条
var neighbours = this.panoVTemp[pano.id] && this.panoVTemp[pano.id].neighbourPanos || pano.neighbourPanos;
for (var r in neighbours) {
if (neighbours[r] && r != pano.id) {
this.createPanoSingleLine(pano, "old", r)
}
}
},
createPanoSingleLine : function (pano, type, id) {//pano是中心
var panos = player.model.panos;
var p2 = panos.index[id].floorPosition.clone()/* .sub(player.model.position) */
var line = LineDraw.createLine([pano.floorPosition.clone()/* .sub(this.position) */, p2], {
color: this.colors.green
});
this.meshGroup.add(line);
line.name = "PanoVL-" + type + "-" + id;
this.panoVLines[id] = line;
this.changeFIconState(panos.index[id].footIcon, "linked")
},
dealPanoVisible : function (id) { //外部调用
var panos = player.model.panos;
if (this.panoVsetting) {
if (id == this.panoVsetting.id) {//关闭当前pano设置
this.pauseSetPanoVisible('unsaved')
}else{
var link;//结果是否连接
if(this.panoVLines[id]){
this.panoVLines[id].visible = !this.panoVLines[id].visible;
link = this.panoVLines[id].visible;
this.changeFIconState(panos.index[id].footIcon, this.panoVLines[id].visible?"linked":false)
}else{
this.createPanoSingleLine(this.panoVsetting, "new", id)
link = true;
}
if(link){//如果连接上了,直接判断该点是可见的(有附近点),(不能通过checkHasNeighbor来判断,因为新增的线条可能不在它的neighbour中
this.changeFIconState2(panos.index[id].footIcon, true)
this.changeFIconState2(panos.index[this.panoVsetting.id].footIcon, true)
}else{//否则需要checkHasNeighbor
this.changeFIconState2(panos.index[id].footIcon, this.checkHasNeighbor(panos.index[id]))
this.changeFIconState2(panos.index[this.panoVsetting.id].footIcon, this.checkHasNeighbor(this.panoVsetting))
}
}
}else {//点击开始设置要设置的pano
this.SetOnePanoVisible(panos.index[id])
}
this.updateFootIconSize()
},
showFootIcons : function (pano, isPanovisible) {
if (!this.footIcons) {
footTex1 = Texture.load("images/edit/End_128.png"); //Store.FootIcon);
footTex2 = Texture.load("images/edit/End_unable_128.png"); //Store.FootIcon_unable);
this.footIcons = [];
var scale = 0.4;
scale *= 40 / Math.sqrt(Math.min($("#player").width(), $("#player").height()));//屏幕越小,放得越大
scale = THREE.Math.clamp(scale, 0.3, 0.7)
//console.log("scale"+scale)
var geo = new THREE.PlaneGeometry(scale, scale, 1, 1)
var panos = player.model.panos;
for (var r in panos.index) {
var t = THREE.UniformsUtils.clone(shaders.waypoint.uniforms);
t.map.value = footTex1
t.color.value.set("#ffffff");
var mat = new THREE.RawShaderMaterial({
vertexShader: shaders.waypoint.vertexShader,
fragmentShader: shaders.waypoint.fragmentShader,
uniforms: t,
side: THREE.DoubleSide,
transparent: !0,
depthWrite: !1,
depthTest: false,
name: "footIcon"
})
var foot = new THREE.Mesh(geo, mat)
foot.position.copy(panos.index[r].floorPosition.clone()/* .sub(player.model.position) */)
foot.lookAt(foot.position.clone().add(new THREE.Vector3(0, 1, 0)));
foot.name = panos.index[r].id;
foot.visible = false;
foot.renderOrder = 6,
panos.index[r].footIcon = foot;
this.meshGroup.add(foot);
this.footIcons.push(foot)
}
}
for (var i = 0; i < this.footIcons.length; i++) {
this.footIcons[i].visible = true;
this.changeFIconState(this.footIcons[i], false)
var panos = player.model.panos;
if(isPanovisible){
this.changeFIconState2(this.footIcons[i], this.checkHasNeighbor(panos.index[this.footIcons[i].name], "showFoot"))
}
if (pano && (this.footIcons[i].name == pano.id)) {
//pano为中心 或者 currentPano 所以放大一点
this.footIcons[i].oriScale = new THREE.Vector3(1.5, 1.5, 1.5)
if (isPanovisible) {
//currentPano特殊些:
this.changeFIconState(this.footIcons[i], "center")
//this.footIcons[i].Unclick = true;//不让点击和hover
}
} else {
this.footIcons[i].oriScale = new THREE.Vector3(1, 1, 1)
}
}
},
checkHasNeighbor : function(pano, state){ //检查当前状态pano点是否有可通行点
var neighbours = this.panoVTemp && this.panoVTemp[pano.id] ? this.panoVTemp[pano.id].neighbourPanos : pano.neighbourPanos;
if(state != "showFoot" && pano == this.panoVsetting){//是中心点的话。state == "showFoot"代表是showFootIcon时, 这时候线还没创建,无法用线判断中心点有几个相邻点,直接用neighbourPanos
for(var i in this.panoVLines){
if(this.panoVLines[i].visible){
return true; //有一条线即可
}
}
return;
}
for(var i in neighbours ){
if(i == pano.id)continue;
if(neighbours[i]){
if(this.panoVsetting && this.panoVsetting.id == i && this.panoVLines[pano.id] && !this.panoVLines[pano.id].visible) continue;
return true;
}
}
return false;
},
/* ifAllPanoNoNeighbor : function(){//检查是否全是孤立点
var panos = player.model.panos;
for(var i in panos.index){
if(this.checkHasNeighbor(panos.index[i])){
return false;
}
}
this.noPanoHasNeighbor = true;
return true;//是全部没有neighbour
}, */
changeFIconState : function (footIcon, state) {
var color = state == "linked" ? this.colors.green :(state == "center" ? /* "#d7f244" */ "#d5f12e": "#ffffff") ;
footIcon.material.uniforms.color.value.set(color)
},
changeFIconState2 : function(footIcon, state){//是可见点还是不可见点
if(state){
footIcon.material.uniforms.map.value = footTex1;
if(this.panoVsetting){
if(this.panoVsetting.id != footIcon.name){
footIcon.material.uniforms.opacity.value = 1;
}else{
//this.changeVisiBtnState(true)
}
}
}else{//不可见
footIcon.material.uniforms.map.value = footTex2;
if(!this.panoVsetting || this.panoVsetting.id != footIcon.name){//非中心点时
footIcon.material.uniforms.opacity.value = 0.5;
}else{//变为中心点时
footIcon.material.uniforms.opacity.value = 1;
//this.changeVisiBtnState(false)
}
}
},
hideFootIcons : function () {
if (!this.footIcons) return;
for (var i = 0; i < this.footIcons.length; i++) {
this.footIcons[i].visible = false;
}
},
updateFootIconSize : function () {//根据相机位置 改变footIcon大小,使在范围内看到的热点大小一致,防止太小点击不到
if (!this.footIcons) return;
var s = player.cameraControls.controls.floorplan.absoluteScale * 2.8;
s = THREE.Math.clamp(s, 0.5, 1.4);
this.footIcons.forEach(function (f) {
try{
f.scale.copy(f.oriScale).multiplyScalar(s);
}catch(e){console.log(e)}
})
}
}
function permitTranMode(state){
state ? $(".pinBottom.left").removeClass('hide') : $(".pinBottom.left").addClass('hide');
}
CloneObject = function (copyObj, result, isSimpleCopy) {//isSimpleCopy只复制最外层
//复制json result的可能:普通数字或字符串、普通数组、复杂对象
result = result || {};
if (copyObj instanceof Array) {
if (copyObj[0] instanceof Object) {
//不支持含有 [[Object]] 这样二级数组里面还是复杂数据的,普通和复杂的数据混合可能也不支持
console.error("不支持含有 [[Object]] 这样二级数组里面还是复杂数据的...")
}
return copyObj.slice(0);
//如果是数组,直接复制返回(排除数组内是object
}
for (var key in copyObj) {
if (copyObj[key] instanceof Object && !isSimpleCopy)
result[key] = CloneObject(copyObj[key]);
else
result[key] = copyObj[key];
//如果是函数类同基本数据,即复制引用
}
return result;
};
function randomWord(randomFlag, min, max) {//随机字符串
var str = "",
range = min,
arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
if (randomFlag) { // 随机长度
range = Math.round(Math.random() * (max - min)) + min;
}
for (var i = 0; i < range; i++) {
var pos = Math.round(Math.random() * (arr.length - 1));
str += arr[pos];
}
return str;
}
function getRandomSid() {//5-7位随机字符串 + 6位时间 为热点准备
var pre = randomWord(true, 5, 7);
var post = new Date().getTime() + "";
var len = post.length;
post = post.substring(len - 8, len - 5) + post.substring(len - 3, len)//其实还是有可能重复的....
return pre + post;
}
//})();