var MDC = { create: function(id, option) { var mdc = {}; mdc.id = id; mdc.domId = "#" + id; mdc.parts = []; mdc.event = { onMouseClick: null }; mdc.options = option; mdc.mouse = new THREE.Vector2(); function getViewSize() { var style = window.getComputedStyle(document.getElementById(mdc.id), null); var SCREEN_WIDTH = parseInt(style.getPropertyValue("width")); //window.innerWidth; var SCREEN_HEIGHT = parseInt(style.getPropertyValue("height")); //window.innerHeight; return { width: SCREEN_WIDTH, height: SCREEN_HEIGHT }; }; mdc.initScene = function initScene() { mdc.raycaster = new THREE.Raycaster(); mdc.scene = new THREE.Scene(); var urls = [ '/img/3d/rb_2.png', '/img/3d/rb_4.png', '/img/3d/rb_5.png', '/img/3d/rb_6.png', '/img/3d/rb_1.png', '/img/3d/rb_3.png' ]; window.reflectionCube = new THREE.CubeTextureLoader().load(urls); reflectionCube.format = THREE.RGBFormat; mdc.scene.background = reflectionCube; mdc.clock = new THREE.Clock(true); mdc.tick = 0; }; mdc.initRender = function() { if (Detector.webgl) { mdc.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); if (mdc.enableShadow) { mdc.renderer.shadowMap.enabled = true; mdc.renderer.shadowMapSoft = true; mdc.renderer.shadowMap.type = THREE.PCFSoftShadowMap; } console.info("webGL render is working."); } else { mdc.renderer = new THREE.CanvasRenderer(); //WebGLRenderer console.info("canvas render is working. restart brower remote to enable WebGL"); } mdc.renderer.sortObjects = false; mdc.renderer.setClearColor(0x467676, 0.4); //0x232335 mdc.renderer.setPixelRatio(window.devicePixelRatio); mdc.renderer.setSize(getViewSize().width, getViewSize().height); }; mdc.initCamera = function() { // camera attributes var VIEW_ANGLE = 45, ASPECT = getViewSize().width / getViewSize().height, NEAR = 10, FAR = 50000; mdc.camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR); mdc.camera.position.set(550, 550, 550); mdc.camera.lookAt(mdc.scene.position); mdc.scene.add(mdc.camera); //mdc.scene.fog = new THREE.Fog( 0xffffff, 1, 5000 ); //mdc.scene.fog.color.setHSL( 0.6, 0, 1 ); }; mdc.initResize = function() { //window.addEventListener('resize', onWindowResize, false); $(window).resize(function (){ var x = getViewSize().width; var y = getViewSize().height; mdc.camera.aspect = x / y; mdc.camera.updateProjectionMatrix(); mdc.renderer.setSize(x, y); }); }; mdc.initControl = function() { mdc.controls = new THREE.OrbitControls(mdc.camera); mdc.controls.addEventListener('change', mdc.render); mdc.controls.minDistance = 200; mdc.controls.maxDistance = 5000; mdc.controls.maxPolarAngle = Math.PI * 0.5; }; mdc.initDebugParts = function() { // axes var axes = new THREE.AxisHelper(1000); mdc.scene.add(axes); // displays current and past frames per second attained by scene mdc.stats = new Stats(); mdc.stats.domElement.style.position = 'absolute'; mdc.stats.domElement.style.bottom = '0px'; mdc.stats.domElement.style.zIndex = 100; mdc.container.appendChild(mdc.stats.domElement); // Grid var size = 800, step = 80; var geometry = new THREE.Geometry(); for (var i = -size; i <= size; i += step) { geometry.vertices.push(new THREE.Vector3(-size, 0, i)); geometry.vertices.push(new THREE.Vector3(size, 0, i)); geometry.vertices.push(new THREE.Vector3(i, 0, -size)); geometry.vertices.push(new THREE.Vector3(i, 0, size)); } var material = new THREE.LineBasicMaterial({ color: 0xeeeeee, opacity: 0.7 }); var line = new THREE.Line(geometry, material, THREE.LinePieces); mdc.scene.add(line); // //ArrowHelper // var directionV3 = new THREE.Vector3(1, 0, 1); // var originV3 = new THREE.Vector3(0, 200, 0); // // 100 is length, 20 and 10 are head length and width // var arrowHelper = new THREE.ArrowHelper(directionV3, originV3, 100, 0xff0000, 20, 10); // mdc.scene.add(arrowHelper); // 3. BoundingBoxHelper //bboxHelper = new THREE.BoundingBoxHelper(group, 0x999999); //ar.scene.add(bboxHelper); }; mdc.defineMouseBehavior = function() { mdc.container.addEventListener('mousemove', onDocumentMouseMove, false); mdc.container.addEventListener('dblclick', onDocumentMouseDown, false); //mdc.container.addEventListener('click',onDocumentMouseDown,false) function onDocumentMouseMove(event) { mdc.mouse.x = ((event.clientX - $(mdc.domId).position().left) / $(mdc.domId).width()) * 2 - 1; mdc.mouse.y = -((event.clientY - $(mdc.domId).position().top) / $(mdc.domId).height()) * 2 + 1; event.preventDefault(); } function onDocumentMouseDown(e) { e.preventDefault(); var part = null; if (mdc.INTERSECTED) { for (var i = 0; i < mdc.parts.length; i++) { var partexist = mdc.util.getObjectByMesh(mdc.parts[i].currentShape, mdc.INTERSECTED); if (partexist) { part = mdc.parts[i]; break; } } if (!part) return; if (part.category == "door") return; if (part.category == "base") return; if (part.category == "ceiling") return; if (part.category == "waterLeakage") return; if (part.category == "thermalMap") return; if (mdc.event.onMouseClick) { mdc.event.onMouseClick(part); } } } }; mdc.attachToDom = function() { mdc.container = document.getElementById(mdc.id); mdc.container.appendChild(mdc.renderer.domElement); }; mdc.initLight = function() { //泛光可调整整个房间的明暗度 var ambient = new THREE.AmbientLight(0xaaaaaa); mdc.scene.add(ambient); mdc.ambientLight = ambient; //var light = new THREE.DirectionalLight( 0xffffff ); //light.position.set( 0, 1, 1 ).normalize(); //mdc.scene.add(light); //半球面环境光,模拟天空到大地的光线,可作为主环境光 var envlight = new THREE.HemisphereLight(0xffffff, 0xA2C9ED, 0.8); //var envlight = new THREE.HemisphereLight( 0x888888, 0x111111, 0.8); envlight.position.set(0, 1500, 0); //envlight.shadowCameraFov = 60; mdc.scene.add(envlight); // // 5000 is sphere size, 3000 is arrow length // //var hlightHelper = new THREE.HemisphereLightHelper(envlight, 10000, 1000); // //ar.scene.add(hlightHelper); // //平行光,用于产生阴影 // var light = new THREE.DirectionalLight(0xffffff); // light.position.set(0, 1000, 1000); // light.target.position.set(0, 0, 0); // light.castShadow = true; // light.shadowDarkness = 0.7; // //light.shadowCameraNear = 2; // //light.shadowCameraFar = 5000; // light.shadowCameraLeft = -3000; // light.shadowCameraRight = 3000; // light.shadowCameraTop = 3000; // light.shadowCameraBottom = -3000; // //light.shadowCameraFov = 60000; // light.shadowMapWidth = light.shadowMapHeight = 1024; // mdc.scene.add(light); // mdc.light = light; // var light = new THREE.PointLight( 0xff0000, 1, 100 ); // light.position.set( 50, 50, 50 ); // mdc.scene.add( light ); // mdc.light = light; mdc.angle = 0.1; var spotLight1 = new THREE.SpotLight(0xffffff); spotLight1.position.set(1000, 1000, 1000); spotLight1.castShadow = true; spotLight1.shadowCameraVisible = true; spotLight1.shadowDarkness = 0.7; spotLight1.shadowMapWidth = 1024; spotLight1.shadowMapHeight = 1024; spotLight1.shadowCameraNear = 500; spotLight1.shadowCameraFar = 4000; spotLight1.shadowCameraFov = 30; mdc.scene.add(spotLight1); mdc.light1 = spotLight1; var spotLight2 = new THREE.SpotLight(0xffffff); spotLight2.position.set(-1000, 1000, -1000); spotLight2.castShadow = true; spotLight2.shadowCameraVisible = true; spotLight2.shadowDarkness = 0.7; spotLight2.shadowMapWidth = 1024; spotLight2.shadowMapHeight = 1024; spotLight2.shadowCameraNear = 500; spotLight2.shadowCameraFar = 4000; spotLight2.shadowCameraFov = 30; mdc.scene.add(spotLight2); mdc.light2 = spotLight2; //ar.camera.updateMatrix(); //var cameraHelper = new THREE.CameraHelper( light.shadow ); //this.scene.add(cameraHelper); //// 50 is helper size //dlightHelper = new THREE.DirectionalLightHelper(light, 500); //ar.scene.add(dlightHelper); }; mdc.init = function(id, option) { this.initScene(); this.initRender(); this.initCamera(); this.attachToDom(); this.initResize(); this.initControl(); this.initDebugParts(); this.defineMouseBehavior(); this.initParts(option); this.initLight(); }; mdc.animate = function(time) { mdc.aniframeId = requestAnimationFrame(mdc.animate); TWEEN.update(); mdc.controls.update(); mdc.render(time); }; mdc.render = function(time) { if (!mdc) return; mdc.update(time); mdc.renderer.render(mdc.scene, mdc.camera); }; mdc.update = function(time) { if (mdc.effect.smoke) { mdc.effect.smoke.group.tick(mdc.clock.getDelta()); }; if (mdc.effect.invade) { mdc.light1.color.setHex(0xff0000); mdc.light2.color.setHex(0xff0000); mdc.ambientLight.color.setHex(0xff6666); }; if (!mdc.effect.invade) { mdc.light1.color.setHex(0xffffff); mdc.light2.color.setHex(0xffffff); mdc.ambientLight.color.setHex(0xaaaaaa); }; if (mdc.effect.cruise) { mdc.parts.forEach(function(part) { if (part.category !== "waterLeakage") part.currentShape.rotation.y -= 0.002; }); } var wls = _.where(mdc.parts, { category: "waterLeakage" }); if (wls.length > 0) { wls.forEach(function(part){ if(part.shape.children.length == 0) return; part.shape.children[0].material.uniforms.visibility.value = (time / 3000) % 1.0; //part.shape.children[0].rotation.copy(mdc.parts[0].currentShape.rotation); }); } // high light mouse indicator mdc.raycaster.setFromCamera(mdc.mouse, mdc.camera); var intersects = mdc.raycaster.intersectObjects(mdc.scene.children, true); if (intersects.length > 0) { if (mdc.INTERSECTED != intersects[0].object) { if (mdc.INTERSECTED) mdc.util.maskColor(mdc.INTERSECTED, mdc.INTERSECTED.currentHex); mdc.INTERSECTED = intersects[0].object; mdc.INTERSECTED.currentHex = mdc.util.getMaskColor(mdc.INTERSECTED); mdc.util.maskColor(mdc.INTERSECTED, 0x223366); } } else { if (mdc.INTERSECTED) mdc.util.maskColor(mdc.INTERSECTED, mdc.INTERSECTED.currentHex); mdc.INTERSECTED = null; } if (Date.now() % 2 == 0) { mdc.angle -= 0.1; mdc.light1.position.x = 800 + 300 * Math.sin(mdc.angle); mdc.light1.position.y = 800 + 300 * Math.cos(mdc.angle); mdc.light1.position.z = 800 + 300 * Math.cos(mdc.angle); mdc.light2.position.x = -800 + 300 * Math.sin(mdc.angle); mdc.light2.position.y = 800 + 300 * Math.cos(mdc.angle); mdc.light2.position.z = -800 + 300 * Math.sin(mdc.angle); } }; mdc.initParts = function(option) { if(option == undefined || option.number == undefined){ if(option == undefined) option = {}; option.number = 24; } var rowNumber = parseInt(parseInt(option.number)/2); this.parts.push(PartManager.createBase(rowNumber)); PartManager.createCameras(rowNumber).forEach(function(c) { mdc.parts.push(c); }); this.parts.push(PartManager.createCeiling(rowNumber)); PartManager.createCabinets(option).forEach(function(cab) { mdc.parts.push(cab); }); PartManager.createThermalMaps(rowNumber).forEach(function(map) { mdc.parts.push(map); }); PartManager.createDoors(rowNumber).forEach(function(door) { mdc.parts.push(door); }); this.parts.forEach(function(part) { mdc.scene.add(part.shape); part.init(); }); mdc.scene.updateMatrixWorld(true); }; mdc.util = {}; mdc.util.getObjectByMesh = function(parent, mesh) { if (parent === mesh) return true; if (!parent) return; for (var i = 0; i < parent.children.length; i++) { if (mdc.util.getObjectByMesh(parent.children[i], mesh)) return true; } return false; }; mdc.util.maskColor = function(mesh, color) { if (!mesh) return; for (var i = 0; i < mdc.parts.length; i++) { var partexist = mdc.util.getObjectByMesh(mdc.parts[i].currentShape, mesh); if (partexist) { if (mdc.parts[i].category !== "rack") return; } } try { if (mesh.material instanceof THREE.MeshPhongMaterial) { mesh.material.emissive.setHex(color); //mesh.material.color.setHex( color ); } if (mesh.material instanceof THREE.MultiMaterial) { mesh.material.materials.forEach(function(m) { //m.color.setHex( color ); m.emissive.setHex(color); }); } } catch (err) { } }; mdc.util.getMaskColor = function(mesh) { if (!mesh) return; if (mesh.material instanceof THREE.MeshPhongMaterial) { return mesh.material.emissive.getHex(); } if (mesh.material instanceof THREE.MultiMaterial) { return mesh.material.materials[0].emissive.getHex(); } }; mdc.stage = {}; mdc.stage.current = null; mdc.stage.switch = function(newStage) { if (mdc.stage.current === newStage) return; mdc.effect.cruise = null; // var expanded = _.every(mdc.parts, function(part) { // return part.states.expanded; // }); // if (expanded) mdc.effect.collapseAll(); // var collapsed = _.every(mdc.parts, function(part) { // return !part.states.expanded; // }); // var tick = 100; // if (!expanded && !collapsed) { // return; // } if (mdc.stage.current) { if (mdc.stage.current === "monitor") mdc.stage.exitMonitor(); if (mdc.stage.current === "thermal") mdc.stage.exitThermal(); if (mdc.stage.current === "space") mdc.stage.exitSpace(); if (mdc.stage.current === "power") mdc.stage.exitPower(); } if (newStage === "monitor") mdc.stage.enterMonitor(); if (newStage === "thermal") mdc.stage.enterThermal(); if (newStage === "space") mdc.stage.enterSpace(); if (newStage === "power") mdc.stage.enterPower(); mdc.stage.current = newStage; }; mdc.stage.enterMonitor = function() { }; mdc.stage.exitMonitor = function() { }; mdc.stage.enterThermal = function() { mdc.updateThermalMaps(); mdc.parts.forEach(function(part) { part.stageDefault(mdc); if (part.category === "thermalMap"){ part.shape.visible = true; //part.states.expanded = false; //part.expand(); } }); }; mdc.stage.exitThermal = function() { mdc.parts.forEach(function(part) { part.stageDefault(mdc); if (part.category === "thermalMap"){ part.shape.visible = false; } }); }; mdc.stage.enterSpace = function() { mdc.parts.forEach(function(part) { part.stageSpace(mdc); }); }; mdc.stage.exitSpace = function() { mdc.parts.forEach(function(part) { part.stageDefault(mdc); }); }; mdc.stage.enterPower = function() { mdc.parts.forEach(function(part) { part.stagePower(mdc); }); }; mdc.stage.exitPower = function() { mdc.parts.forEach(function(part) { part.stageDefault(mdc); }); }; mdc.effect = {}; mdc.effect.tweenCamera = function(position, target) { new TWEEN.Tween(mdc.camera.position).to({ x: position.x, y: position.y, z: position.z }, 3000).easing(TWEEN.Easing.Linear.None).onUpdate(function() { mdc.camera.lookAt(target); }).onComplete(function() {}).start(); }; mdc.effect.partmount = function() { var expanded = _.every(mdc.parts, function(part) { return part.states.expanded; }); if (expanded) mdc.effect.collapseAll(); var collapsed = _.every(mdc.parts, function(part) { return !part.states.expanded; }); if (collapsed) mdc.effect.expandAll(); if (!collapsed && !expanded) mdc.effect.collapseAll(); }; mdc.effect.expandAll = function() { mdc.effect.cruise = null; new TWEEN.Tween(mdc.camera.position) .to({ x: 700, y: 700, z: 700 }, 2000) // relative animation .start(); mdc.parts.forEach(function(part) { part.expand(); }); if (!mdc.lastData && mdc.stage == "monitor") return; var wls = _.where(mdc.parts, { category: "waterLeakage" }); wls.forEach(function(wd){ wd.shape.visible = true; wd.shape.rotation.copy(mdc.parts[0].currentShape.rotation); }); }; mdc.effect.collapseAll = function() { mdc.effect.cruise = null; new TWEEN.Tween(mdc.camera.position) .to({ x: 530, y: 530, z: 530 }, 2000) // relative animation .start(); mdc.parts.forEach(function(part) { if (part.category === "thermalMap"){ console.log('aa'); } part.collapse(); }); if (!mdc.lastData && mdc.stage == "monitor") return; var wls = _.where(mdc.parts, { category: "waterLeakage" }); wls.forEach(function(wd){ wd.shape.visible = false; }); }; mdc.effect.skyLightfalling = function(status) { var angle = "-" + Math.PI / 2 ; if (status) { mdc.effect.skyfall = {}; angle = "-" + Math.PI / 2 ; } else { mdc.effect.skyfall = undefined; angle = 0 ; } var ceiling = _.find(mdc.parts, function(part) { return part.id === "ceiling"; }); var oldceiling = _.find(ceiling.shape.children, function(mesh) { return mesh.isWindow === true; }); oldceiling.children.forEach(function(win) { new TWEEN.Tween(win.rotation) .to({ x: angle }, 1000) // relative animation .start(); }); }; mdc.effect.closeSmoking = function(){ if (!mdc.effect.smoke) return; mdc.scene.remove(mdc.effect.smoke.group.mesh); PartManager.disposeShape(mdc.effect.smoke.group.mesh); mdc.effect.smoke = undefined; }; mdc.effect.smoking = function(rowNumber) { function initParticles(rowNumber) { var zV = - (rowNumber - 12)*30; var loader = new THREE.TextureLoader(); var url = 'img/3d/cloudSml.png'; var texture = loader.load(url); var particleGroupCrash = new SPE.Group({ texture: { value: texture }, blending: THREE.NormalBlending }); var crashemitter = new SPE.Emitter({ maxAge: { value: 3 }, position: { value: new THREE.Vector3(0, 0, zV), spread: new THREE.Vector3(200, 0, 260) }, wiggle: { value: 4000 }, size: { value: [64, 256, 512], spread: [0, 32, 64, 128, 192, 256, 512], randomise: true }, acceleration: { value: new THREE.Vector3(0, 40, 0), spread: new THREE.Vector3(40, 10, 40) }, rotation: { axis: new THREE.Vector3(0, 1, 0), spread: new THREE.Vector3(10, 20, 0), angle: 100 * Math.PI / 180 }, velocity: { value: new THREE.Vector3(0, 1, -0.5), spread: new THREE.Vector3(0.25, 0.1, 0.25) }, opacity: { value: [0.2, 0.3, 0] }, color: { value: [new THREE.Color(0x333333), new THREE.Color(0x111111)], spread: [new THREE.Vector3(0.2, 0.1, 0.1), new THREE.Vector3(0, 0, 0)] }, particleCount: 4000, maxParticleCount: 300000 }); particleGroupCrash.addEmitter(crashemitter); mdc.scene.add(particleGroupCrash.mesh); return particleGroupCrash; }; mdc.effect.smoke = {}; mdc.effect.smoke.group = initParticles(rowNumber); }; mdc.effect.invading = function() { mdc.effect.invade = {}; }; mdc.effect.openDoor = function(index){ if (index === 0){ mdc.effect.doorA = {}; } if (index === 1){ mdc.effect.doorB = {}; } var doors = _.where(mdc.parts, { category: "door" }); if(doors.length == 0) return; new TWEEN.Tween(doors[index].shape.children[0].position) .to({ x: -100 }, 1000) .start(); new TWEEN.Tween(doors[index].shape.children[1].position) .to({ x: 100 }, 1000) .start(); }; mdc.effect.closeDoor = function(index){ if (index === 0){ mdc.effect.doorA = undefined; } if (index === 1){ mdc.effect.doorB = undefined; } var doors = _.where(mdc.parts, { category: "door" }); if(doors.length == 0) return; new TWEEN.Tween(doors[index].shape.children[0].position) .to({ x: -44 }, 1000) .start(); new TWEEN.Tween(doors[index].shape.children[1].position) .to({ x: 44 }, 1000) .start(); }; mdc.effect.dooropening = function() { mdc.effect.dooropen = {}; var doors = _.where(mdc.parts, { category: "door" }); new TWEEN.Tween(doors[0].shape.children[0].position) .to({ x: -100 }, 1000) .start(); new TWEEN.Tween(doors[0].shape.children[1].position) .to({ x: 100 }, 1000) .start(); }; mdc.effect.cruising = function() { var expanded = _.every(mdc.parts, function(part) { return part.states.expanded; }); var collapsed = _.every(mdc.parts, function(part) { return !part.states.expanded; }); if (!expanded && !collapsed) return; if (!mdc.effect.cruise) { mdc.effect.collapseAll(); mdc.effect.cruise = {}; } else { delete mdc.effect.cruise; } }; mdc.effect.rackAlarming = function(rackId, alarmLevel){ var resetColor = function(rack){ var mesh = rack.currentShape.children[0].children[0]; if (mesh.material instanceof THREE.MultiMaterial) { var i=0; mesh.material.materials.forEach( function(m) { m.color = {r:1,g:1,b:1}; }); } }; var showAlarm = function(rack, alarmLevel) { var tweens =[]; var mesh = rack.currentShape.children[0].children[0]; var color = 0xffffff; switch (alarmLevel) { case 1: color = 0x00FF33; break; case 2: color = 0x66ccff; break; case 3: color = 0xffff66; break; case 4: color = 0xff6666; break; default: } if (mesh.material instanceof THREE.MultiMaterial) { //var kso = {id:that.id,twarray:[]}; mesh.material.materials.forEach(function(m) { var c = new THREE.Color(color); var t1 = new TWEEN.Tween(m.color) .to(c, 3000) .easing(TWEEN.Easing.Quartic.InOut) .repeat(Infinity) .start(); var t2 = new TWEEN.Tween(m.shininess) .to(400, 3000) .easing(TWEEN.Easing.Quartic.InOut) .repeat(Infinity) .start(); tweens.push(t1); tweens.push(t2); //kso.twarray.push(tw); }); //that.tws.push(kso); } return tweens; }; var rack = _.find(mdc.parts, function(part) { return part.id === rackId; }); if (!rack) return; if (!alarmLevel) return; // if no his & no new alarm, return if (alarmLevel <= 0 && !rack.states.alarm) return; if (rack.states.alarm){ //if new alarm is same to old, not need update. if (rack.states.alarm.alarmLevel == alarmLevel) return; } //stop old alarm if (rack.states.alarm){ rack.states.alarm.tws.forEach(function(tw){ tw.stop(); }); resetColor(rack); rack.states.alarm = null; if (alarmLevel <= 0) return; } //start new alarm rack.states.alarm = {alarmLevel:alarmLevel, tws:[] }; var twarray = showAlarm(rack, alarmLevel); twarray.forEach(function(tw){ rack.states.alarm.tws.push(tw); }); }; mdc.effect.shining = function() { var showAlarm = function(rack, alarmLevel) { var mesh = rack.currentShape.children[0].children[0]; var color = 0xffffff; switch (alarmLevel) { case 1: color = 0x00FF33; break; case 2: color = 0x66ccff; break; case 3: color = 0xffff66; break; case 4: color = 0xff6666; break; default: } if (mesh.material instanceof THREE.MultiMaterial) { //var kso = {id:that.id,twarray:[]}; mesh.material.materials.forEach(function(m) { var c = new THREE.Color(color); new TWEEN.Tween(m.color) .to(c, 3000) .easing(TWEEN.Easing.Quartic.InOut) .repeat(Infinity) .start(); new TWEEN.Tween(m.shininess) .to(400, 3000) .easing(TWEEN.Easing.Quartic.InOut) .repeat(Infinity) .start(); //kso.twarray.push(tw); }); //that.tws.push(kso); } }; var r1 = _.find(mdc.parts, function(part) { return part.id === "rack1"; }); var r2 = _.find(mdc.parts, function(part) { return part.id === "rack8"; }); var r3 = _.find(mdc.parts, function(part) { return part.id === "rack10"; }); var r4 = _.find(mdc.parts, function(part) { return part.id === "rack17"; }); showAlarm(r1, 1); showAlarm(r2, 2); showAlarm(r3, 3); showAlarm(r4, 4); }; mdc.effect.closeWaterLeakingA = function(){ var wl = _.find(mdc.parts, function(part) { return part.id === "waterLeakageA"; }); if (!wl) return; mdc.scene.remove(wl.shape); PartManager.disposeShape(wl.shape); mdc.parts = _.without(mdc.parts, wl); mdc.effect.waterDetectorA = undefined; delete mdc.effect.waterDetectorA; }; mdc.effect.closeWaterLeakingB = function(){ var wl = _.find(mdc.parts, function(part) { return part.id === "waterLeakageB"; }); if (!wl) return; mdc.scene.remove(wl.shape); PartManager.disposeShape(wl.shape); mdc.parts = _.without(mdc.parts, wl); mdc.effect.waterDetectorB = undefined; delete mdc.effect.waterDetectorA; }; mdc.effect.waterLeakingA = function(rowNumber) { mdc.effect.waterDetectorA = {}; var wl = _.find(mdc.parts, function(part) { return part.id === "waterLeakageA"; }); if (wl) return; var part= PartManager.createWaterLeakageA(rowNumber); mdc.parts.push(part); part.init(); mdc.scene.add(part.shape); part.shape.rotation.copy(mdc.parts[0].currentShape.rotation); mdc.effect.expandAll(); }; mdc.effect.waterLeakingB = function(rowNumber) { mdc.effect.waterDetectorB = {}; var wl = _.find(mdc.parts, function(part) { return part.id === "waterLeakageB"; }); if (wl) return; var part= PartManager.createWaterLeakageB(rowNumber); mdc.parts.push(part); part.init(); mdc.scene.add(part.shape); part.shape.rotation.copy(mdc.parts[0].currentShape.rotation); mdc.effect.expandAll(); }; mdc.updateThermalMaps = function(){ var maps = []; if (mdc.stage.current !== "thermal") { mdc.parts.forEach(function(part) { if (part.category === "thermalMap"){ part.shape.visible = false; } }); return; } mdc.parts.forEach(function(part) { if (part.category === "thermalMap") { maps.push(part); } }); maps.forEach(function(map) { mdc.parts = _.without(mdc.parts, map); map.dispose(mdc); }); maps=[]; var cfgA = {side:'A',points:[]}; var cfgB = {side:'B',points:[]}; mdc.parts.forEach(function(part) { if (part.info) { if (part.info.tempSensors){ part.info.tempSensors.forEach(function(sensor){ if (part.info.side === "A"){ cfgA.points.push(sensor); } if (part.info.side === "B"){ cfgB.points.push(sensor); } }); } } }); var mapA,mapB; if (cfgA.points.length > 0){ mapA = PartManager.createThermalMap(cfgA.side,cfgA.points, mdc.options); //setTimeout(function(){ mdc.parts.push(mapA); mdc.scene.add(mapA.shape); mapA.shape.rotation.copy(mdc.parts[0].currentShape.rotation); mapA.init(); if (mdc.parts[0].states.expanded) mapA.expand(); //}, 5000); } if (cfgB.points.length > 0){ mapB = PartManager.createThermalMap(cfgB.side,cfgB.points, mdc.options); //setTimeout(function(){ mdc.parts.push(mapB); mdc.scene.add(mapB.shape); mapB.shape.rotation.copy(mdc.parts[0].currentShape.rotation); mapB.init(); if (mdc.parts[0].states.expanded) mapB.expand(); //}, 5000); } }; mdc.dispose = function () { var disposeObject = function (obj) { for (var b in obj) { if (typeof (obj[b]) === "function" && obj[b].name === "event") { obj[b] = undefined; } else if (typeof (obj[b]) === "function" && obj[b].length > 0) { disposeObject(obj[b]); } else if (typeof (obj[b]) === "object" && b === "dispatch") { disposeObject(obj[b]); } } }; var disposeNode = function (node) { if (node instanceof THREE.Camera) { node = undefined; } else if (node instanceof THREE.Light) { if (!node.dispose) { disposeObject(node); } else node.dispose(); node = undefined; } else if (node instanceof THREE.Mesh) { if (node.geometry) { node.geometry.dispose(); node.geometry = undefined; delete node.geometry; } if (node.material) { if (node.material instanceof THREE.MeshFaceMaterial) { $.each(node.material.materials, function (idx, mtrl) { if (!mtrl) return; mtrl.dispose(); if (mtrl.map) { mtrl.map.dispose(); mtrl.map = undefined; delete mtrl.map; } if (mtrl.lightMap) mtrl.lightMap.dispose(); if (mtrl.bumpMap) mtrl.bumpMap.dispose(); if (mtrl.normalMap) mtrl.normalMap.dispose(); if (mtrl.specularMap) mtrl.specularMap.dispose(); if (mtrl.envMap) mtrl.envMap.dispose(); mtrl.dispose(); // disposes any programs associated with the material mtrl = undefined; delete mtrl; }); } else { if (node.material.map) { node.material.map.dispose(); node.material.map = undefined; delete node.material.map; } if (node.material.lightMap) node.material.lightMap.dispose(); if (node.material.bumpMap) node.material.bumpMap.dispose(); if (node.material.normalMap) node.material.normalMap.dispose(); if (node.material.specularMap) node.material.specularMap.dispose(); if (node.material.envMap) node.material.envMap.dispose(); node.material.dispose(); // disposes any programs associated with the material node.material = undefined; delete node.material; } } node = undefined; } else if (node instanceof THREE.Object3D) { node = undefined; delete node; } }; var disposeHierarchy = function (node, callback) { for (var i = node.children.length - 1; i >= 0; i--) { var child = node.children[i]; disposeHierarchy(child, callback); callback(child); } }; mdc.effect.closeSmoking(); mdc.effect.closeWaterLeakingA(); mdc.effect.closeWaterLeakingB(); //remove event for controller $(window).off(); $(window).unbind(); $(document).off(); $(document).unbind(); $(mdc.domId).off(); $(mdc.domId).unbind(); if (mdc.renderer) $(mdc.renderer.domElement).off(); //stop animation TWEEN.removeAll(); if (mdc.aniframeId) window.cancelAnimationFrame(mdc.aniframeId); //remove shapes //remove scene if (mdc.controls) mdc.controls.dispose(); if (mdc.raycaster) disposeObject(mdc.raycaster); if (mdc.camera) disposeObject(mdc.camera); if (mdc.container) disposeObject(mdc.container); if (mdc.renderer) { mdc.renderer.forceContextLoss(); mdc.renderer.context = null; mdc.renderer.domElement = null; disposeObject(mdc.renderer); mdc.renderer = null; } doDispose(mdc.scene); function doDispose(obj) { if (obj !== null) { for (var i = 0; i < obj.children.length; i++) { doDispose(obj.children[i]); } if (obj.geometry) { obj.geometry.dispose(); obj.geometry = undefined; } if (obj.material) { if (obj.material instanceof THREE.MeshFaceMaterial) { $.each(obj.material.materials, function (idx, o) { if (!o) return; if (o.map) { o.map.dispose(); o.map = undefined; delete o.map; } o.dispose(); }); } else { obj.material.dispose(); } } if (obj.dispose) { obj.dispose(); } } obj = undefined; } mdc.scene = null; disposeObject(mdc); mdc = undefined; }; mdc.updateData = function (response) { if (!response) return; if (!response.mdc) return; if (!response.cabinets) return; mdc.lastData = response; var rowNumber = parseInt(parseInt(mdc.options.number)/2); //update smoke status if (mdc.stage.current === "monitor"){ if (response.mdc.smokeDetector){ if (!mdc.effect.smoke && response.mdc.smokeDetector.alarming){ mdc.effect.smoking(rowNumber); } if (mdc.effect.smoke && !response.mdc.smokeDetector.alarming){ mdc.effect.closeSmoking(); } } if (response.mdc.infraredDetector){ if (!mdc.effect.invade && response.mdc.infraredDetector.alarming){ mdc.effect.invade = {}; } if (mdc.effect.invade && !response.mdc.infraredDetector.alarming){ mdc.effect.invade = undefined; } } if (response.mdc.ceilingWindow){ if (!mdc.effect.skyfall && response.mdc.ceilingWindow.opened){ mdc.effect.skyLightfalling(true); } if (mdc.effect.skyfall && !response.mdc.ceilingWindow.opened){ mdc.effect.skyLightfalling(false); } } if (response.mdc.doorA){ if (!mdc.effect.doorA && response.mdc.doorA.opened){ mdc.effect.openDoor(0); } if (mdc.effect.doorA && !response.mdc.doorA.opened){ mdc.effect.closeDoor(0) } } if (response.mdc.doorB){ if (!mdc.effect.doorB && response.mdc.doorB.opened){ mdc.effect.openDoor(1); } if (mdc.effect.doorB && !response.mdc.doorB.opened){ mdc.effect.closeDoor(1) } } if (response.mdc.waterDetectorA){ if (!mdc.effect.waterDetectorA && response.mdc.waterDetectorA.alarming){ mdc.effect.waterLeakingA(rowNumber); } if (mdc.effect.waterDetectorA && !response.mdc.waterDetectorA.alarming){ mdc.effect.closeWaterLeakingA(); } } if (response.mdc.waterDetectorB){ if (!mdc.effect.waterDetectorB && response.mdc.waterDetectorB.alarming){ mdc.effect.waterLeakingB(rowNumber); } if (mdc.effect.waterDetectorB && !response.mdc.waterDetectorB.alarming){ mdc.effect.closeWaterLeakingB(); } } if (response.cabinets){ response.cabinets.forEach(function(cab){ mdc.effect.rackAlarming(cab.id,cab.alarmLevel); }); } } if (response.cabinets){ response.cabinets.forEach(function(cab){ var rack = _.find(mdc.parts, function(part) { return part.id === cab.id; }); if (rack) rack.info = cab; }); mdc.updateThermalMaps(); } }; mdc.init(id, option); //mdc.stage.switch('space'); mdc.animate(); return mdc; } };