/* var ceshi = '';
// var ceshi = 'http://192.168.0.135:8105';
// var ceshi = 'http://47.107.252.54:8105';
// var token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsInJvbGUiOm51bGwsIm1hbmFnZXIiOm51bGwsImlkIjoxLCJ1c2VyTmFtZSI6ImFkbWluIiwiZXhwIjoxNTk2NzAxNjAyLCJpYXQiOjE1OTY2MTUyMDIsImp0aSI6Ijk0YjA5YTg1LWViY2ItNDE1Yy04OGVmLWU0MDM1M2UzYmIxYyJ9.Uzi95n0kYXp7bdpY77MdLtTpPL_Fq-jn0tE7gjg6AzA"
var token = window.localStorage.dcj_token
*/
var _musicMaxWeight = 8
//M
var cmp = getQueryVariable('cmp') || ''
var _hotNum = 0
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.initSaveAll();
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":
VisiSet.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();
VisiSet.finishSetTagVisible()
break;
}
switch (name) {
case "panoVisible":
VisiSet.enterSet(VisiSet.beginSetPanoVisible.bind(VisiSet))
$(".toolLeft").addClass("unable")
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.initSaveAll = function() {
var that = this;
$('#save').on('click', function() {
$(".edit-loading").removeClass("hide");
var $images = $(".information .edit-fun-images a.result");
new Promise(function(resolve, reject) {
upload($images, 'images', resolve)
}).then(function(imgUrls) {
//导览的数据
var guides = Array.from($('.tourList ul li')).map(function(dom) {
return dom.data
})
var hots = {}
// 热点数据
var hotLength = 0;
for (let i in player.model.hots) {
let hot = player.model.hots[i];
hots[i] = {
position: {
x: hot.mesh.position.x,
y: hot.mesh.position.y,
z: hot.mesh.position.z
},
//有的定制场景代码是旧的,只能使用rotation,所以不输出quaternion :
rotation: hot.isSprite ? new THREE.Euler().setFromQuaternion(hot.quaternion).toObject() : hot.mesh.rotation.toObject(),
isSprite: hot.isSprite ? 1 : 0,
noAction: hot.noAction ? 1 : 0,
linkType: hot.linkType,
infoAttribute: hot.infoAttribute,
order: hotLength++//因为热点保存后在hots里的顺序会被修改,所以使用order来记录顺序
}
if (hot.visiblePanos)
hots[sid].visiblePanos = hot.visiblePanos
if (hot.infoAttribute) {
delete hot.infoAttribute.position;
delete hot.infoAttribute.quaternion;
delete hot.infoAttribute.rotation;
}
}
var info = {
name: $('#pjtName').val(),
summary: $('#info-summary').val(),
weixinDesc: $('#weixin-summary').val(),
shareImgUrl: imgUrls[0] || '',
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功能
/**************** 陈志广 小地图可配置项 *********** */
cadSignColor: $('#cadSignColor').val(),
cadBorderColor: $('#cadBorderColor').val(),
cadBorderWidth: $('#cad-size').val(),
showCad: $('input[name="show-cad"]').is(':checked'),
}
var overlayInfo = []
player.overlayGroup.children.forEach((overlay)=>{
var info = EditOverlay.getSavingInfo(overlay)
if (info)
overlayInfo.push(info);
}
)
let url = cmp ? ('/api/scene/edit/' + cmp) : '/manage/scene/edit'
$.ajax({
method: 'POST',
headers: {
'Content-Type': 'application/json',
token: token
},
dataType: 'json',
contentType: 'application/json',
url: ceshi + url,
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
})
}
}
)
if(data.shareImgUrl){
var imagesHTML = '
'))
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.space = 'local'//为了在当前方向上平移
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() {
}
})
},
panoPosSwitch : $('#setOverlayPosForPano input') // 当前漫游点独立调整位置开关
,
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)
//------------------------------
this.panoPosSwitch.on("change", this.panoPosSwitchOnChange.bind(this))
$('.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 uploadInputs = {
video : $('
'),
photo : $('
')
}
$('#overlayUpload [name="upload"] button').on('click', ()=>{
uploadInputs[this.editType].click()
})
uploadInputs.video.on("change", (e)=>{
inputMedia({
enableTypes: [this.editType ],
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);
}
)
uploadInputs.photo.on("change", (e)=>{
inputMedia({
enableTypes: [this.editType ],
photoDone: (photo)=>{
var plane = this.editPlane.plane
/* $(video).css('width', '100%')
$(video).css('height', '100%') */
plane.material.map = new THREE.Texture();
plane.material.map.image = photo
plane.material.map.needsUpdate = !0
plane.material.map.minFilter = THREE.LinearFilter;
this.editPlane.overlayType = "photo";
$('#overlayUpload .preview video').remove();
//$('#overlayUpload .preview').css('background-image',"").append($(video));
this.useImgRatio()
//自适应比例
this.editPlane.file = photo.file;
plane.material.opacity = 1;
plane.material.color = new THREE.Color(1,1,1)
plane.material.needsUpdate = true;
}
}, "photo", e);
}
)
player.overlayGroup.children.forEach((overlay)=>{
if(overlay.plane.material.map.image)this.getOverlayInfo(overlay)
else overlay._loadDone = ()=>{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;
},
switchEditType : function(type){
this.editType = type;
$('#overlayUpload [name="upload"] button').text(type == 'video' ? "上传视频" : "上传图片")
$('#overlayUpload .preview span').text(type == 'video' ? "支持MP4、MOV等,<20M" : "支持jpg、png等,<20M");
},
beginToAddPlane: function(event) {
this.switchEditType($(event.target).attr("data-type"))
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.posCustom = overlay.position.clone();
overlay.quaCustom = overlay.quaternion.clone();
overlay.widthCustom = overlay.width;
overlay.heightCustom = overlay.height;
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();
overlay.overlayType && this.switchEditType(overlay.overlayType)
if (overlay.overlayType == "video") {
var video = plane.material.map.image
$('#overlayUpload .preview').css({'background-image':"", 'background-size':""}).append(video);
} else if(overlay.overlayType == "photo" || overlay.overlayType == "text"){
$('#overlayUpload .preview').css({
'background-image': src ? ("url(" + src + ")") : "",
'background-size': "contain"
})
}else{
$('#overlayUpload .preview').css({
'background-image': "",
'background-size': ""
})
}
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)
this.updatePano(player.currentPano)
},
//----------------------------
panoPosSwitchOnChange : function(){
var on = this.panoPosSwitch.is(':checked')
if(!on) delete this.editPlane.transformAtPanos[player.currentPano.id]
}
,
getTransformAtPano : function(){
this.editPlane.transformAtPanos[player.currentPano.id] = {
pos : this.editPlane.position.clone(),
qua : this.editPlane.quaternion.clone(),
width : this.editPlane.width,
height : this.editPlane.height,
}
},
updatePosition:function(){
var on = this.panoPosSwitch.is(':checked')
if(on && player.mode == 'panorama'){
this.getTransformAtPano()
}else{
this.editPlane.posCustom.copy(this.editPlane.position)
}
},
updateScale : function(){
var on = this.panoPosSwitch.is(':checked')
var size = this.editPlane.getSizeByScale( )
this.editPlane.width = size.width
this.editPlane.height = size.height
if(on && player.mode == 'panorama'){
this.getTransformAtPano()
}else{
this.editPlane.widthCustom = this.editPlane.width
this.editPlane.heightCustom = this.editPlane.height
}
this.updateOverlayScaleDisplay()
}
,
updateQua : function(){
var on = this.panoPosSwitch.is(':checked')
if(on && player.mode == 'panorama'){
this.getTransformAtPano()
}else{
this.editPlane.quaCustom.copy(this.editPlane.quaternion)
}
}
,
updatePano:function(pano){
if(!EditOverlay.editPlane ) return;
this.panoPosSwitch.prop('checked', !!EditOverlay.editPlane.transformAtPanos[pano.id]);
},
//------------------------------
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.updateScale()
//this.updateOverlayPanel(this.editPlane)
},
getOverlayInfo: function(overlay) {
//2 编辑前, 从当前状态获取info
var plane = overlay.plane;
var transformAtPanos = {}
for(var i in overlay.transformAtPanos){
transformAtPanos[i] = {
width : overlay.transformAtPanos[i].width,
height : overlay.transformAtPanos[i].height,
pos : overlay.transformAtPanos[i].pos.clone(),
qua : overlay.transformAtPanos[i].qua.clone(),
}
}
overlay.info = {
width: overlay.widthCustom,
height: overlay.heightCustom,
depth: settings.overlay.depth * overlay.scale.z,
pos: overlay.posCustom.clone(),
qua: overlay.quaCustom.clone(),
media: plane.material.map.image,
file: overlay.file,
type: overlay.overlayType,
hasBox: overlay.hasBox,
transformAtPanos: transformAtPanos
}
},
getSavingInfo: function(overlay) {
if (!overlay.file && (!overlay.plane.material.map || !overlay.plane.material.map.image)) {
return;
}
var transformAtPanos = {}
for(var i in overlay.transformAtPanos){
transformAtPanos[i] = {
width : toPrecision(overlay.transformAtPanos[i].width, 4),
height : toPrecision(overlay.transformAtPanos[i].height, 4),
pos : toPrecision(overlay.transformAtPanos[i].pos.toArray(), 3),
qua : toPrecision(overlay.transformAtPanos[i].qua.toArray(), 5)
}
}
var info = {
width: toPrecision(overlay.widthCustom, 4),
height: toPrecision(overlay.heightCustom, 4),
depth: toPrecision(settings.overlay.depth * overlay.scale.z, 4),
pos: toPrecision(overlay.posCustom.toArray(), 3),
qua: toPrecision(overlay.quaCustom.toArray(), 5),
sid: overlay.sid,
hasBox: overlay.hasBox ? 1 : 0,
media: [overlay.overlayType],
file: overlay.fileSrc || overlay.plane.material.map.image.src,
transformAtPanos : transformAtPanos
}
return info
},
SaveOverlay: function() {
var overlay = this.editPlane;
if (!overlay.file && (!overlay.plane.material.map || !overlay.plane.material.map.image)) {
this.editType == "video" ? alert("请上传视频") : 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.overlayType == "video" ? "视频 ":"图片 ")+ overlay.sid}
`)
$(".overlayList ul").append(li);
li.on("click", ()=>{
player.clickOverlay(overlay)
}
)
overlay.domLi = li;
},
removeFromList: function(overlay) {
overlay.domLi.remove();
}
}
//----------------漫游可见性---------------------------------
var VisiSet = {
setPanoVisible: false,
setTagVisible: false,
panoVLines: {},
//线条
panoVTemp: {},
//修改后还没保存的临时数据
tagVsetting: null,
//正在设置的热点中心点
tagsVLines: {},
//线条
//tagVTemp //修改后还没保存的临时数据
//热点可见性
$confirmSnap: $("#camera-start"),
colors: {
green: "#00c8ae"
},
init: function() {
this.meshGroup = new THREE.Object3D;
this.meshGroup.name = "setVisible-group"
player.model.add(this.meshGroup)
$("#hotVisible").on("click", ()=>{
VisiSet.enterSet(VisiSet.beginSetTagVisible.bind(VisiSet))
}
)
},
enterSet: function(fun) {
var enter = function() {
if (player.modeTran.split('-')[1] != "floorplan") {
setTimeout(fun, 300)
//提前一点出现
}
player.flyToMode("floorplan", fun);
}
permitTranMode(false)
if (!player.modeTran) {
player.afterCModeFuc = ()=>{
enter()
}
} else
enter()
},
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")
permitTranMode(true)
},
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)) */
let url = cmp ? ('/api/scene/roamViable/' + cmp) : '/manage/scene/roamViable'
$.ajax({
method: 'POST',
url: ceshi + url,
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) {
if (!panos.index[r].isAligned())
continue;
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)
}
})
}
//========热点可见性==============
,
beginSetTagVisible: function() {
if (this.setTagVisible)
return;
$(".toolTop").addClass("unable")
$("#hotVisible").addClass("unable")
this.setTagVisible = true;
this.tagVTemp = {};
this.$confirmSnap.text('完成设置').removeClass("hide")
//objects.tagManager.hideAllTags();
for (let i in player.model.hots) {
player.model.hots[i]._isSprite = player.model.hots[i].isSprite;
player.model.hots[i].isSprite = true;
player.model.hots[i].mesh.material.depthTest = false;
}
this.updateFootIconSize()
//更新一下大小,尤其是上次换了中心点然后退出又进入但是镜头没有变化的话
},
SetOneTagVisible: function(tag) {
//点击某个热点后就对该热点进行设置,或者在热点修改时对其进行设置
if (this.tagVsetting == tag)
return;
if (this.tagVsetting) {
this.saveLastTagVi(this.tagVsetting);
//this.tagVsetting.setElemType(this.tagVsetting.style, this.tagVsetting.styleImageURL);
}
this.tagVsetting = tag;
//记录正在修改的
this.delVisibleLines();
//删除线
this.showFootIcons(player.currentPano);
this.createTagVisiLines(tag);
//创线
this.updateFootIconSize()
//更新一下大小,尤其是上次换了中心点然后退出又进入但是镜头没有变化的话
},
saveLastTagVi: function() {
//保存刚设置过的tag
var change = false;
var newVPs = this.tagVTemp[this.tagVsetting.sid] || this.tagVsetting.visiblePanos.slice(0);
for (var r in this.tagsVLines) {
var line = this.tagsVLines[r];
if (line.name.indexOf("new") > -1 && line.visible) {
//新设置为visible且没有取消
newVPs.push(r)
change = true;
//console.log("add: "+r)
} else if (line.name.indexOf("new") == -1 && !line.visible) {
//旧的且已经取消
var i = newVPs.indexOf(r);
if (i == -1) {
console.log("visiblePanos删除error");
continue;
}
newVPs.splice(i, 1);
change = true;
//console.log("sub: "+r)
}
}
if (change) {
this.tagVTemp[this.tagVsetting.sid] = newVPs;
}
},
pauseSetTagVisible: function() {
//pc保存后删除连线 但还在继续设置 点选热点即开始
if (!this.setTagVisible || !this.tagVsetting)
return;
//this.tagVsetting.setElemType(this.tagVsetting.style, this.tagVsetting.styleImageURL );
this.delVisibleLines();
this.hideFootIcons();
this.tagVTemp = {};
this.tagVsetting = null;
},
finishSetTagVisible: function() {
if (!this.setTagVisible)
return;
$(".toolTop").removeClass("unable")
$("#hotVisible").removeClass("unable")
this.pauseSetTagVisible();
this.setTagVisible = false;
//this.setDisplay(false)
this.$confirmSnap.addClass("hide")
permitTranMode(true)
/* for (var r in objects.tagManager.tags) {
if(objects.tagManager.tags[r].state == "videoPanoFlag")continue;
objects.tagManager.tags[r].disc.visible = false;
objects.tagManager.tags[r].disc.material.depthTest = true;
} */
for (let i in player.model.hots) {
player.model.hots[i].isSprite = player.model.hots[i]._isSprite;
player.model.hots[i].isSprite || player.model.hots[i].mesh.quaternion.copy(player.model.hots[i].quaternion)
player.model.hots[i].mesh.material.depthTest = true;
}
},
/* saveTagVisibles : function () { //保存到服务器
if (this.tagVsetting) this.saveLastTagVi(this.tagVsetting); //获取最后设置的那个热点的改动
//可能出现数据没变但保存的情况。比如先改变了然后切换别的热点但切换回来时又改回来。
var tags = [];
for (var i in this.tagVTemp) {
tags.push({
sid: i,
value: this.tagVTemp[i]//turnToPanoIndex(this.tagVTemp[i])
})
}
if (tags.length == 0) {//没有需要保存的改动
this.finishSetTagVisible()
return;
}
return tags;
} */
//afterSaveTagVisibles : function(){
saveTagVisibles: function() {
if (this.tagVsetting)
this.saveLastTagVi(this.tagVsetting);
for (var i in this.tagVTemp) {
//保持成功于是生效
player.model.hots[i].visiblePanos = this.tagVTemp[i];
}
this.finishSetTagVisible()
//还是保存完直接结束吧,因为现在热点可视不放在单独的设置页面了
},
createTagVisiLines: function(tag) {
// 热点可见性线条
var panos = player.model.panos;
tag.visiblePanos || tag.setVisiblePanos("get")
var visibleList = this.tagVTemp[tag.sid] || tag.visiblePanos;
//如果是刚在设置的要读取设置过的数据
for (var r = 0; r < visibleList.length; r++) {
var pano = panos.index[visibleList[r]];
this.createTagSingleLine(pano, "old", tag)
}
},
createTagSingleLine: function(pano, type, tag) {
var panos = player.model.panos;
var line = LineDraw.createLine([pano.floorPosition.clone()/* .sub(this.position) */
, tag.mesh.position.clone()], {
color: this.colors.green
});
this.meshGroup.add(line);
line.name = "tagVL-" + type + "-" + pano.id;
this.tagsVLines[pano.id] = line;
this.changeFIconState(panos.index[pano.id].footIcon, "linked")
},
dealTagVisible: function(tag, panoName) {
//外部调用
var panos = player.model.panos;
if (this.tagsVLines[panoName]) {
this.tagsVLines[panoName].visible = !this.tagsVLines[panoName].visible;
this.changeFIconState(panos.index[panoName].footIcon, this.tagsVLines[panoName].visible ? "linked" : false)
} else {
this.createTagSingleLine(panos.index[panoName], "new", tag)
}
},
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];
}
}
}
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;
}
function searchParent(searchArea, o, maxTimes) {
//是否是某种元素的下级,并找出该元素
maxTimes = maxTimes || 20;
var count = 0
var f = function(dom) {
if (o.id && o.id == dom.id)
return dom
else if (o.className && dom.classList && dom.classList.contains(o.className))
return dom
else if (o.tagName && o.tagName == dom.tagName)
return dom
}
var find;
while (searchArea && count < maxTimes) {
if (find = f(searchArea))
return find
searchArea = searchArea.parentNode;
count++;
}
}
//})();