/** * Created by gaimeng on 15/3/9. */ IndoorMap3d = function(mapdiv){ var _this = this; var _theme = null; var _mapDiv = mapdiv, _canvasWidth = _mapDiv.clientWidth, _canvasWidthHalf = _canvasWidth / 2, _canvasHeight = _mapDiv.clientHeight, _canvasHeightHalf = _canvasHeight / 2; var _scene, _controls, _projector, _rayCaster; var _canvasDiv; var _selected; var _showNames = true, _showPubPoints = true; var _curFloorId = 0; var _selectionListener = null; var _sceneOrtho, _cameraOrtho;//for 2d var _spriteMaterials = [], _pubPointSprites=null, _nameSprites = null; this.camera = null; this.renderer = null; this.mall = null; this.is3d = true; this.init = function(){ // perspective scene for normal 3d rendering _scene = new THREE.Scene(); _this.camera = new THREE.PerspectiveCamera(20, _canvasWidth / _canvasHeight, 0.1, 2000); //orthogonal scene for sprites 2d rendering _sceneOrtho = new THREE.Scene(); _cameraOrtho = new THREE.OrthographicCamera(- _canvasWidthHalf, _canvasWidthHalf, _canvasHeightHalf, -_canvasHeightHalf, 1, 10); _cameraOrtho.position.z = 10; //controls _controls = new THREE.OrbitControls(_this.camera); //renderer _this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); _this.renderer.autoClear = false; _this.renderer.setClearAlpha(0); //set up the lights var light = new THREE.DirectionalLight(0xffffff); light.position.set(-500, 500, -500); _scene.add(light); var light = new THREE.DirectionalLight(0xffffff); light.position.set(500, 500, 500); _scene.add(light); //canvas div _this.renderer.setSize(_mapDiv.clientWidth, _mapDiv.clientHeight); _canvasDiv = _this.renderer.domElement _mapDiv.appendChild(_canvasDiv); _mapDiv.style.overflow = "hidden"; _canvasDiv.style.width = "100%"; _canvasDiv.style.height = "100%"; } this.setTheme = function(theme){ if(_theme == null){ _theme = theme } else if(_theme != theme) { _theme = theme; _this.parse(_this.mall.jsonData); //parse } return _this; } this.theme = function(){ return _theme; } //load the map by the json file name this.load = function (fileName, callback) { var loader = new IndoorMapLoader(true); _theme = default3dTheme; loader.load(fileName, function(mall){ _this.mall = mall; _scene.add(_this.mall.root); _scene.mall = mall; if(callback) { callback(); } // FixMe: 2020年7月7日00:41:14 透明色配置 // _this.renderer.setClearColor(_theme.background); if(_curFloorId == 0){ _this.showAllFloors(); }else{ _this.showFloor(_curFloorId); } }); return _this; } //parse the json file this.parse = function(json){ if(_theme == null) { _theme = default3dTheme; } _this.mall = ParseModel(json, _this.is3d, _theme); _scene.mall = _this.mall; _this.showFloor(_this.mall.getDefaultFloorId()); _this.renderer.setClearColor(_theme.background); _scene.add(_this.mall.root); _mapDiv.style.background = _theme.background; return _this; } //reset the camera to default configuration this.setDefaultView = function () { // var camAngle = _this.mall.FrontAngle + Math.PI/2; var camAngle = 0; var camDir = [Math.cos(camAngle), Math.sin(camAngle)]; var camLen = 230; var tiltAngle = 75.0 * Math.PI/180.0; _this.camera.position.set(camDir[1]*camLen, Math.sin(tiltAngle) * camLen, camDir[0]*camLen);//TODO: adjust the position automatically _this.camera.lookAt(_scene.position); _controls.reset(); _controls.viewChanged = true; return _this; } //set top view this.setTopView = function(){ _this.camera.position.set(0, 500, 0); return _this; } //TODO:adjust camera to fit the building this.adjustCamera = function() { _this.setDefaultView(); } this.zoomIn = function(zoomScale){ _controls.zoomOut(zoomScale); redraw(); } this.zoomOut = function(zoomScale){ _controls.zoomIn(zoomScale); redraw(); } //show floor by id this.showFloor = function(floorid) { _curFloorId = floorid; if(_scene.mall == null){ return; } _scene.mall.showFloor(floorid); _this.adjustCamera(); if(_showPubPoints) { createPubPointSprites(floorid); } if(_showNames) { createNameSprites(floorid); } redraw(); return _this; } //show all floors this.showAllFloors = function(){ _curFloorId = 0; //0 for showing all if(_this.mall == null){ return; } _this.mall.showAllFloors(); _this.adjustCamera(); clearPubPointSprites(); clearNameSprites(); return _this; } //set if the objects are selectable this.setSelectable = function (selectable) { if(selectable){ _projector = new THREE.Projector(); _rayCaster = new THREE.Raycaster(); _mapDiv.addEventListener('mousedown', onSelectObject, false); _mapDiv.addEventListener('touchstart', onSelectObject, false); }else{ _mapDiv.removeEventListener('mousedown', onSelectObject, false); _mapDiv.removeEventListener('touchstart', onSelectObject, false); } return _this; } //set if the user can pan the camera this.setMovable = function(movable){ _controls.enable = movable; return _this; } //show the labels this.showAreaNames = function(show) { _showNames = show == undefined ? true : show; return _this; } //show pubPoints(entries, ATM, escalator...) this.showPubPoints = function(show){ _showPubPoints = show == undefined ? true: show; return _this; } //get the selected object this.getSelectedId = function(){ return _selected.id; } //the callback function when sth is selected this.setSelectionListener = function(callback){ _selectionListener = callback; return _this; } //select object by id this.selectById = function(id){ var floor = _this.mall.getCurFloor(); for(var i = 0; i < floor.children.length; i++){ if(floor.children[i].id && floor.children[i].id == id) { if (_selected) { _selected.material.color.setHex(_selected.currentHex); } select(floor.children[i]); } } } //select object(just hight light it) function select(obj){ obj.currentHex = _selected.material.color.getHex(); obj.material.color = new THREE.Color(_theme.selected); obj.scale = new THREE.Vector3(2,2,2); } function onSelectObject(event) { // find intersections event.preventDefault(); var mouse = new THREE.Vector2(); if(event.type == "touchstart"){ mouse.x = ( event.touches[0].clientX / _canvasDiv.clientWidth ) * 2 - 1; mouse.y = -( event.touches[0].clientY / _canvasDiv.clientHeight ) * 2 + 1; }else { mouse.x = ( event.clientX / _canvasDiv.clientWidth ) * 2 - 1; mouse.y = -( event.clientY / _canvasDiv.clientHeight ) * 2 + 1; } var vector = new THREE.Vector3( mouse.x, mouse.y, 1 ); vector.unproject( _this.camera); _rayCaster.set( _this.camera.position, vector.sub( _this.camera.position ).normalize() ); var intersects = _rayCaster.intersectObjects( _this.mall.root.children[0].children ); if ( intersects.length > 0 ) { if ( _selected != intersects[ 0 ].object ) { if ( _selected ) { _selected.material.color.setHex( _selected.currentHex ); } for(var i=0; i