123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419 |
- /* Copyright© 2000 - 2021 SuperMap Software Co.Ltd. All rights reserved.*/
- var ThreeApplication = {
- data: null,
- buildingMesh: null,
- buildingRoofMesh: null,
- terrainMesh: null,
- rooms: [],
- buildingView: null,
- modelOpacity: 0.4,
- register: function (renderer, scene, camera) {
- this.renderer = renderer;
- this.scene = scene;
- this.camera = camera;
- return this;
- },
- //threeLayer主要用来设置模型在地图上位置
- setTargetLayer: function (threeLayer) {
- this.threeLayer = threeLayer;
- return this;
- },
- setPosition: function (position) {
- this.position = position;
- return this;
- },
- start: function () {
- //程序入口开始
- SceneBuilder.preLoader(ThreeApplication).load();
- }
- };
- var SceneBuilder = {
- //预加载模型数据
- preLoader: function (app) {
- var manager, slowLoopIntervalId, is3DDataLoaded = false;
- function loadData(onComplete) {
- var url = '../data/ThreeBuildingData.json';
- $.ajax({
- dataType: 'json',
- url: url,
- success: function (result) {
- app.data = new DataProcessor(result);
- onComplete();
- },
- error: function (jqXHR, status, errorThrown) {
- console.log(status, errorThrown);
- }
- });
- }
- function loadResources() {
- manager = new THREE.LoadingManager();
- manager.onProgress = function (item, loaded, total) {
- };
- manager.onLoad = function () {
- is3DDataLoaded = true;
- };
- loadBuildingModel();
- loadRooms();
- }
- function loadBuildingModel() {
- var loader = new THREE.LegacyJSONLoader(manager);
- // loader.setResourcePath()('./js/obj/building/maps/');
- loader.load('./js/obj/building/building.js', function (geometry, materials) {
- var material = new THREE.MultiMaterial(materials);
- for (var i = 0; i < materials.length; i++) {
- materials[i].transparent = true;
- materials[i].vertexColors = THREE.FaceColors;
- }
- scaleGeometry(geometry);
- for (var i = 0; i < geometry.faces.length; i++) {
- geometry.faces[i].color = new THREE.Color(0x08acff);
- geometry.colorsNeedUpdate = true;
- }
- app.buildingMesh = new THREE.Mesh(geometry, material);
- app.buildingMesh.geometry.computeBoundingSphere();
- }
- );
- var loader = new THREE.LegacyJSONLoader(manager);
- loader.load('./js/obj/building/building-roof.js', function (geometry, materials) {
- var material = new THREE.MultiMaterial(materials);
- for (var i = 0; i < materials.length; i++) {
- materials[i] = new THREE.MeshPhongMaterial({
- color: 0xffffff,
- transparent: true,
- polygonOffset: true,
- polygonOffsetFactor: 1,
- polygonOffsetUnits: 1
- });
- }
- scaleGeometry(geometry);
- app.buildingRoofMesh = new THREE.Mesh(geometry, material);
- });
- }
- function loadRooms() {
- var roomData = app.data.locations;
- for (var i = 0; i < roomData.length; i++) {
- loadRoom(roomData[i]);
- }
- function loadRoom(data) {
- var name = data.name,
- slug = data.slug,
- loader = new THREE.LegacyJSONLoader(manager);
- loader.load("./js/" + data.objRoom, function (geometry, materials) {
- var material = new THREE.MeshPhongMaterial({
- color: 0xffffff
- });
- scaleGeometry(geometry);
- var mesh = new THREE.Mesh(geometry, material);
- var room = new InteractiveModel(mesh, name, slug);
- room.setEmissiveDefault(0x333333);
- room.unmark();
- app.rooms.push(room);
- });
- }
- }
- function scaleGeometry(geometry) {
- var transform = new THREE.Matrix4(),
- scale = new THREE.Matrix4(),
- translate = new THREE.Matrix4();
- scale.makeScale(0.2, 0.2, 0.2);
- translate.makeTranslation(32.57, 0, 30);
- transform.multiplyMatrices(scale, translate);
- geometry.applyMatrix(transform);
- }
- function waitForLoading() {
- slowLoopIntervalId = setInterval(function () {
- if (is3DDataLoaded) {
- is3DDataLoaded = false;
- SceneBuilder.viewBuilder(app).build();
- clearInterval(slowLoopIntervalId);
- }
- }, 500);
- }
- this.load = function () {
- loadData(function () {
- loadResources();
- });
- waitForLoading();
- };
- return this;
- },
- //构建模型场景
- viewBuilder: function (app) {
- this.build = function () {
- app.buildingView = app.buildingView || new BuildingView(app);
- var buildingView = app.buildingView;
- buildingView.setOpacity(app.modelOpacity);
- };
- return this;
- }
- };
- //数据处理器
- function DataProcessor(data) {
- var locationBySlug = {},
- witnessBySlug = {},
- locations = data.locations,
- witnesses = data.witnesses,
- location,
- witness,
- i;
- for (i = 0; i < locations.length; i++) {
- location = locations[i];
- locationBySlug[location.slug] = location;
- }
- for (i = 0; i < witnesses.length; i++) {
- witness = witnesses[i];
- witnessBySlug[witness.slug] = witness;
- }
- return {
- locations: locations,
- witnesses: witnesses,
- locationBySlug: locationBySlug,
- witnessBySlug: witnessBySlug
- }
- }
- //可交互对象(建筑和房间)
- function InteractiveModel(mesh, name, slug, labelOffset) {
- var object3D = null,
- center = null;
- var scale = 1;
- var emissiveDefault = 0x000000,
- emissiveHighlight = 0xff0000,
- isDoubleSide = true,
- opacityDefault = 1.0,
- opacityHighLight = 1.0;
- build3D();
- calculateCenter();
- function build3D() {
- object3D = mesh;
- object3D.name = slug;
- opacityDefault = object3D.material.opacity;
- opacityHighLight = object3D.material.opacity;
- if (object3D.material.length > 1) {
- for (var i = 0; i < object3D.material.length; i++) {
- setMaterial(object3D.material[i]);
- }
- } else {
- setMaterial(object3D.material);
- }
- function setMaterial(material) {
- material.side = THREE.DoubleSide;
- material.emissive.setHex(emissiveDefault);
- material.polygonOffset = true;
- material.polygonOffsetFactor = -2;
- material.polygonOffsetUnits = 1;
- material.needsUpdate = true;
- }
- }
- function calculateCenter() {
- mesh.geometry.computeBoundingBox();
- center = new THREE.Vector3();
- center.addVectors(
- mesh.geometry.boundingBox.min,
- mesh.geometry.boundingBox.max
- );
- center.divideScalar(2);
- }
- function getName() {
- return name;
- }
- function getSlug() {
- return slug;
- }
- function getCenter() {
- calculateCenter();
- return center;
- }
- function mark() {
- object3D.material.emissive.setHex(emissiveHighlight);
- object3D.material.opacity = opacityHighLight;
- object3D.material.needsUpdate = true;
- }
- function unmark() {
- object3D.material.emissive.setHex(emissiveDefault);
- object3D.material.opacity = opacityDefault;
- object3D.material.needsUpdate = true;
- }
- function setEmissiveDefault(hex) {
- emissiveDefault = hex;
- }
- function setDoubleSide(bool) {
- isDoubleSide = bool;
- object3D.material.side = (bool) ? THREE.DoubleSide : THREE.FrontSide;
- object3D.material.needsUpdate = true;
- }
- function setHighlightOpacity(val) {
- opacityHighLight = val;
- }
- return {
- object3D: object3D,
- getCenter: getCenter,
- getName: getName,
- mark: mark,
- unmark: unmark,
- scale: scale,
- setEmissiveDefault: setEmissiveDefault,
- setDoubleSide: setDoubleSide,
- setHighlightOpacity: setHighlightOpacity
- }
- }
- //添加three场景,添加模型
- function BuildingView(app) {
- var renderer, camera, scene,
- buildingMesh,
- roofMesh,
- roofEdgeHelper,
- rooms, roomsGroup,
- raycaster;
- init();
- function init() {
- renderer = app.renderer;
- camera = app.camera;
- scene = app.scene;
- buildingMesh = app.buildingMesh;
- roofMesh = app.buildingRoofMesh;
- rooms = app.rooms;
- initScene();
- addObjects();
- }
- function initScene() {
- raycaster = app.raycaster = new THREE.Raycaster();
- }
- function addObjects() {
- // building
- correctionObject3D(buildingMesh);
- scene.add(buildingMesh);
- // line helper (building)
- var edgeHelper = new THREE.EdgesHelper(buildingMesh, 0x02f7f8, 1);
- edgeHelper.material.linewidth = 10;
- correctionObject3D(edgeHelper);
- scene.add(edgeHelper);
- // roof
- var materials = roofMesh.material.materials;
- for (var i = 0; i < materials.length; i++) {
- materials[i].transparent = true;
- }
- roofMesh.renderOrder = 1;
- correctionObject3D(roofMesh);
- scene.add(roofMesh);
- // line helper (roof)
- roofEdgeHelper = new THREE.EdgesHelper(roofMesh, 0x02f7f8, 20);
- roofEdgeHelper.material.transparent = true;
- roofEdgeHelper.material.opacity = 0.2;
- roofEdgeHelper.material.linewidth = 1;
- roofEdgeHelper.renderOrder = 1;
- correctionObject3D(roofEdgeHelper);
- scene.add(roofEdgeHelper);
- // rooms
- roomsGroup = new THREE.Object3D();
- for (var i = 0; i < rooms.length; i++) {
- roomsGroup.add(rooms[i].object3D);
- }
- correctionObject3D(roomsGroup);
- scene.add(roomsGroup);
- }
- function correctionObject3D(obj3D) {
- obj3D.rotation.x = -Math.PI / 2;
- obj3D.rotation.y = Math.PI / 7;
- obj3D.scale.set(16, 16, 16);
- app.threeLayer.setPosition(obj3D, app.position);
- }
- this.setOpacity = function (val) {
- var materials = buildingMesh.material.materials;
- for (var i = 0; i < materials.length; i++) {
- materials[i].opacity = 0.1 + val * (1 - 0.15);
- materials[i].needsUpdate = true;
- }
- // roof
- materials = roofMesh.material.materials;
- for (var i = 0; i < materials.length; i++) {
- materials[i].opacity = val * val * 1.1;
- materials[i].needsUpdate = true;
- }
- roofEdgeHelper.material.opacity = val * val * 0.2;
- roofEdgeHelper.material.needsUpdate = true;
- };
- }
|