黄陂项目
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

530 lines
17 KiB

// 从这里开始
var h1 = null
var h2 = null
var h3 = null
var oldtransformNodex = null
var oldMeshOther = null
var drag = null
var isRotating = true // 控制整体旋转状态:true=自动旋转,false=停止
var clickParentRotate = false // 仅标记「手动暂停」状态,不干扰鼠标划出逻辑
// 新增:标记鼠标是否悬停在模型上(核心控制旋转恢复的开关)
var isPointerOverModel = false
var targetAngles = {
default: { // 初始视角
alpha: 2.5809,
beta: 0.9804,
radius: 3
},
alarm: { // 报警视角(示例)
alpha: 3.1213,
beta: 0.5855,
radius: 3
}
}
var camera
BABYLON.DefaultLoadingScreen.prototype.displayLoadingUI = function() {
if (document.getElementById('customLoadingScreenDiv')) {
document.getElementById('customLoadingScreenDiv').style.display = 'initial'
return
}
this._loadingDiv = document.createElement('div')
this._loadingDiv.id = 'customLoadingScreenDiv'
thecss = 'lohingifpc'
thecss2 = 'zcpc'
this._loadingDiv.innerHTML = "<div class='oka'><div class='" + thecss + "'><image src='./logok.gif' class='jiazaiimg'/></div></div>"
this._resizeLoadingUI()
window.addEventListener('resize', this._resizeLoadingUI)
document.body.appendChild(this._loadingDiv)
}
// 重构通用的模型交互绑定函数(核心优化鼠标划入/划出逻辑)
function bindModelPointerEvents(transformNodex, clickCallback, highlightColor) {
var mesheses = null
if (transformNodex.getClassName() === 'TransformNode') {
mesheses = transformNodex.getChildMeshes(false)
} else {
mesheses = [transformNodex]
}
for (var i = 0; i < mesheses.length; i++) {
const mesh = mesheses[i]
mesh.actionManager = new BABYLON.ActionManager(scene)
// 鼠标划入:停止旋转(无论之前是否在旋转)
mesh.actionManager.registerAction(
new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPointerOverTrigger, function() {
isPointerOverModel = true
isRotating = false // 标记为停止状态
camera.useAutoRotationBehavior = false // 立即停止旋转
// 高亮逻辑(如果需要)
if (highlightColor && h2) {
h2.addMesh(mesh, highlightColor)
}
})
)
// 鼠标划出:无条件恢复旋转(核心修改!只要移出,就恢复,除非手动暂停)
mesh.actionManager.registerAction(
new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPointerOutTrigger, function() {
isPointerOverModel = false
// 关键:只要不是「手动暂停」,就恢复旋转(没有其他额外条件)
if (!clickParentRotate) {
isRotating = true
camera.useAutoRotationBehavior = true // 立即恢复旋转
}
// 移除高亮(如果需要)
if (highlightColor && h2) {
h2.removeMesh(mesh)
}
})
)
// 点击事件(不影响旋转逻辑)
mesh.actionManager.registerAction(
new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger, function() {
try {
clickCallback && clickCallback(transformNodex)
} catch (error) {
console.warn('点击回调执行失败:', error)
}
})
)
}
}
// 原prepareGroupButton2改为调用通用函数
function prepareGroupButton2(transformNodex, color, qu) {
bindModelPointerEvents(transformNodex, cameraClick, color || new BABYLON.Color3(0, 0, 1))
}
// 原prepareGroupButton3改为调用通用函数
function prepareGroupButton3(transformNodex, color, qu) {
bindModelPointerEvents(transformNodex, archCabinetsClick, color || new BABYLON.Color3(0, 1, 0))
}
BABYLON.DefaultLoadingScreen.prototype.hideLoadingUI = function() {
show = 50
document.getElementById('customLoadingScreenDiv').style.display = 'none'
document.getElementById('customLoadingScreenDiv_first').style.display = 'none'
document.title = '档案室'
var prepareGroupButton2ByMesh = function(transformNodex, color, qu) {
var mesheses = null
if (transformNodex.getClassName() === 'Mesh') {
mesheses = [transformNodex]
}
for (var i = 0; i < mesheses.length; i++) {
const mesh = mesheses[i]
mesh.actionManager = new BABYLON.ActionManager(scene)
mesh.actionManager.registerAction(
new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPointerOverTrigger, function() {
isPointerOverModel = true
isRotating = false
camera.useAutoRotationBehavior = false
if (oldMeshOther != null) {
oldMeshOther.removeBehavior(drag)
var mesheses2 = oldMeshOther.getClassName() === 'Mesh' ? [oldMeshOther] : []
mesheses2.forEach(m => {
try { h2.removeMesh(m) } catch (e) {}
})
}
oldMeshOther = transformNodex
var mesheses3 = transformNodex.getClassName() === 'Mesh' ? [transformNodex] : []
mesheses3.forEach(m => {
try { h2.addMesh(m, color) } catch (e) {}
})
})
)
// 同样优化这个函数里的鼠标划出逻辑
mesh.actionManager.registerAction(
new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPointerOutTrigger, function() {
isPointerOverModel = false
if (!clickParentRotate) { // 仅排除「手动暂停」的情况
isRotating = true
camera.useAutoRotationBehavior = true
}
var mesheses4 = transformNodex.getClassName() === 'Mesh' ? [transformNodex] : []
mesheses4.forEach(m => {
try { h2.removeMesh(m) } catch (e) {}
})
})
)
mesh.actionManager.registerAction(
new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger, function() {
try {
cameraClick(transformNodex)
} catch (error) {
console.warn('点击回调执行失败:', error)
}
})
)
}
}
// 绑功能点(烟感)
var smokeAlarms = []
scene.transformNodes.forEach(function(node) {
if (node.name.startsWith('smokealarm')) {
smokeAlarms.push(node)
}
})
var length = smokeAlarms.length
console.log('以 smokealarm 开头的对象数量:', length)
smokeAlarms.forEach(function(jk01, index) {
console.log('smokeAlarms', jk01)
var parts = jk01.name.split('smokealarm')
jk01.nameID = parts.length > 1 ? `S${String(index + 1).padStart(3, '0')}` : 'S000'
jk01.baojing = false
prepareGroupButton2(jk01)
})
// 绑监控设备
const cameraMeshes = []
scene.transformNodes.forEach(function(node) {
if (node.name.startsWith('有害生物去除器')) {
cameraMeshes.push(node)
}
})
const cameraCount = cameraMeshes.length
console.log('以 有害生物去除器 开头的 Mesh 数量:', cameraCount)
const colorBlue = new BABYLON.Color3(0, 0, 1)
cameraMeshes.forEach((cam, index) => {
cam.nameID = `cam_${String(index + 1).padStart(3, '0')}`
prepareGroupButton2(cam, colorBlue)
})
// 绑档案柜
const archivesCabinets = [];
scene.transformNodes.forEach(function(node) {
if (node.name.startsWith('档案柜')) {
archivesCabinets.push(node);
}
});
const archivesCabinetsCount = archivesCabinets.length;
console.log('档案柜数量:', archivesCabinetsCount);
if (archivesCabinets.length > 0) {
const children = archivesCabinets[0]._children;
const filteredChildren = children.filter(cam => cam.name !== "克隆_1");
for (let i = filteredChildren.length - 1; i >= 0; i--) {
const cam = filteredChildren[i];
const paddedIndex = String(filteredChildren.length - i);
cam.nameID = `cabinet-${paddedIndex}`;
prepareGroupButton3(cam);
}
}
var light = new BABYLON.HemisphericLight('HemiLight', new BABYLON.Vector3(0, 1, 0), scene)
light.intensity = 2
light.diffuse = new BABYLON.Color3(0.92, 0.92, 0.92)
// 给vue页面传值,加载完成之后
parent.getIframeLoading('false')
}
BABYLON.DracoCompression.Configuration.decoder.wasmUrl = './js/draco_wasm_wrapper_gltf.js'
BABYLON.DracoCompression.Configuration.decoder.wasmBinaryUrl = './js/draco_decoder_gltf.wasm'
BABYLON.DracoCompression.Configuration.decoder.fallbackUrl = './js/draco_decoder_gltf.js'
// 3D模型页面(web3D/index.html)的createScene函数后添加适配逻辑
var canvas = document.getElementById('renderCanvas')
var engine = new BABYLON.Engine(canvas, true, { stencil: true })
// ========== 新增:画布自适应iframe尺寸 ==========
function resizeCanvas() {
// 获取iframe的容器尺寸(如果iframe有父容器,也可以取父容器尺寸)
const iframeWidth = window.innerWidth || document.documentElement.clientWidth
const iframeHeight = window.innerHeight || document.documentElement.clientHeight
// 设置canvas尺寸为iframe的100%(保证填满iframe,且跟随iframe缩放)
canvas.width = iframeWidth
canvas.height = iframeHeight
// 通知引擎更新尺寸
engine.resize()
}
// 初始化时执行一次
resizeCanvas()
// 监听窗口大小变化(iframe缩放时触发)
window.addEventListener('resize', resizeCanvas)
// createScene function that creates and return the scene
var createScene = function() {
engine.displayLoadingUI()
var scene = new BABYLON.Scene(engine)
camera = new BABYLON.ArcRotateCamera(
'Camera', 4.02, 0.98, 2.6,
new BABYLON.Vector3(1.2, 0.08, 0.03),
scene
)
camera.setTarget(new BABYLON.Vector3(0, 0, 0))
camera.attachControl(canvas, true)
// 相机参数(保持原优化)
camera.lowerRadiusLimit = 0.1
camera.upperRadiusLimit = 500
camera.inertia = 0.1
camera.minZ = 0.01
camera.maxZ = 1000
camera.fov = 1.0
camera.useAutoRotationBehavior = isRotating // 初始启用自动旋转
// 透明背景
scene.clearColor = new BABYLON.Color4(0, 0, 0, 0)
scene.activeCamera = camera
scene.activeCamera.useInputToRestoreState = true
var assetsManager = new BABYLON.AssetsManager(scene)
// 加载GLB模型
BABYLON.SceneLoader.LoadAssetContainerAsync('asset/', 'F5.glb', scene).then((container) => {
container.addAllToScene()
}).catch((error) => {
console.error('加载模型时出错:', error)
})
var hdrTexture = new BABYLON.CubeTexture.CreateFromPrefilteredData('textures/environmentSpecular.env', scene)
scene.environmentTexture = hdrTexture
var spriteManagerPlayer = new BABYLON.SpriteManager('playerManager', './img/bl9.png', 10, {
width: 100,
height: 100
}, scene)
spriteManagerPlayer.isPickable = true
scene.onPointerDown = function(evt) {
var pickResult = scene.pickSprite(this.pointerX, this.pointerY)
var pick = scene.pick(scene.pointerX, scene.pointerY)
console.log('pick', pick.pickedPoint)
if (pickResult.pickedSprite != null && pickResult.hit) {
alert(pickResult.pickedSprite.name)
}
}
assetsManager.load()
drag = new BABYLON.PointerDragBehavior({
dragPlaneNormal: new BABYLON.Vector3(0, 0, 1)
})
drag.validateDrag = (targetPosition) => {
if (targetPosition.x > 10.5 || targetPosition.x < -10.5) return false
if (targetPosition.z > 10.5 || targetPosition.z < -10.5) return false
return oldtransformNodex != null
}
// GUI高亮层
h1 = new BABYLON.HighlightLayer('hl1', scene)
h2 = new BABYLON.HighlightLayer('hl2', scene)
h3 = new BABYLON.HighlightLayer('hl3', scene)
var step = 0.1
var currentx = 1
h1.blurHorizontalSize = 0.1
scene.registerAfterRender(() => {
h1.blurHorizontalSize = h1.blurVerticalSize + currentx
// 报警高亮逻辑
var nodealert = scene.getTransformNodeByName('yan')
if (nodealert != null) {
var mesheses3 = nodealert.getClassName() === 'TransformNode'
? nodealert.getChildMeshes(false)
: [nodealert]
mesheses3.forEach(mesh => {
try {
if (nodealert.baojing === true) {
h3.addMesh(mesh, new BABYLON.Color3(1, 0, 0))
} else {
h3.removeMesh(mesh)
}
} catch (error) {}
})
}
// 修复高亮动画速度控制
if (currentx > 0.5) step *= -1
if (currentx < 0) step *= -1
currentx += step
})
return scene
}
var canvas = document.getElementById('renderCanvas')
var engine = new BABYLON.Engine(canvas, true, { stencil: true })
var scene = createScene()
scene.autoClear = true
scene.imageProcessingConfiguration.exposure = 1
scene.imageProcessingConfiguration.contrast = 1
scene.environmentIntensity = 0.4
engine.runRenderLoop(function() {
scene.render()
})
window.addEventListener('resize', function() {
engine.resize()
})
// 设备点击回调
function cameraClick(TheCamera) {
window.parent.postMessage({
type: 'cameraClick',
data: TheCamera.nameID
}, '*')
}
function archCabinetsClick(TheCamera) {
window.parent.postMessage({
type: 'archCabinetsClick',
data: TheCamera.nameID
}, '*')
}
// 报警状态处理
function handleAlarm(deviceId, isAlarm) {
var cl = new BABYLON.Color3(0, 0, 1)
var c2 = new BABYLON.Color3(1, 0, 0)
const targetDevice = scene.transformNodes.find(node => node.nameID === deviceId)
if (targetDevice) {
targetDevice.baojing = isAlarm
var mesheses = targetDevice.getClassName() === 'TransformNode'
? targetDevice.getChildMeshes(false)
: [targetDevice]
mesheses.forEach(mesh => {
if (isAlarm) {
h2.addMesh(mesh, c2)
} else {
h2.removeMesh(mesh)
h2.addMesh(mesh, cl)
}
})
} else {
console.log(`未找到设备 ID 为 ${deviceId} 的设备`)
}
}
// 接收父页面消息(手动控制旋转)
window.addEventListener('message', function(e) {
if (e.data.type === 'deviceState') {
console.log('ddd', e.data.data)
const deviceData = e.data.data
if (Array.isArray(deviceData)) {
deviceData.forEach((device) => {
handleAlarm(device.deviceId, device.isAlarm)
})
} else {
handleAlarm(deviceData.deviceId, deviceData.isAlarm)
}
} else if (e.data.type === 'isGetRotate') {
const isGetRotate = e.data.value
console.log('isGetRotate:', isGetRotate)
toggleAutoRotation(isGetRotate)
}
}, false)
// 手动控制旋转开关(仅影响「手动暂停」状态)
function toggleAutoRotation(isAutoRotating) {
clickParentRotate = isAutoRotating // 标记:true=手动暂停,false=手动启用
if (isAutoRotating) {
// 手动暂停:无论鼠标是否在模型上,都停止旋转
isRotating = false
camera.useAutoRotationBehavior = false
camera.angularSpeed = 0
} else {
// 手动启用:如果鼠标不在模型上,立即恢复旋转
if (!isPointerOverModel) {
isRotating = true
camera.useAutoRotationBehavior = true
}
}
}
// 相机动画跳转
function moveCameraTo(targetPreset) {
var target = targetAngles[targetPreset]
if (!target) return console.error('无效的视角预设')
var camera = scene.activeCamera
camera.panningInertia = 0
var animationAlpha = new BABYLON.Animation(
'cameraAlphaAnimation',
'alpha',
60,
BABYLON.Animation.ANIMATIONTYPE_FLOAT,
BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT
)
var animationBeta = new BABYLON.Animation(
'cameraBetaAnimation',
'beta',
60,
BABYLON.Animation.ANIMATIONTYPE_FLOAT,
BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT
)
var animationRadius = new BABYLON.Animation(
'cameraRadiusAnimation',
'radius',
60,
BABYLON.Animation.ANIMATIONTYPE_FLOAT,
BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT
)
var keysAlpha = [
{ frame: 0, value: camera.alpha },
{ frame: 120, value: target.alpha }
]
var keysBeta = [
{ frame: 0, value: camera.beta },
{ frame: 120, value: target.beta }
]
var keysRadius = [
{ frame: 0, value: camera.radius },
{ frame: 120, value: target.radius }
]
animationAlpha.setKeys(keysAlpha)
animationBeta.setKeys(keysBeta)
animationRadius.setKeys(keysRadius)
var easingFunction = new BABYLON.CubicEase()
easingFunction.setEasingMode(BABYLON.EasingFunction.EASINGMODE_EASEINOUT)
animationAlpha.setEasingFunction(easingFunction)
animationBeta.setEasingFunction(easingFunction)
animationRadius.setEasingFunction(easingFunction)
scene.beginDirectAnimation(camera, [animationAlpha, animationBeta, animationRadius], 0, 120, false, 1, function() {
camera.panningInertia = 0.1
toggleAutoRotation(false) // 动画结束后,恢复自动旋转(除非手动暂停)
window.parent.postMessage({ type: 'autoRotationStatus', value: true }, '*')
})
}