diff --git a/CHANGELOG.md b/CHANGELOG.md
index ca3331e3..17b2b919 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,18 +4,23 @@ Minor version by [@jscastro76](https://github.com/jscastro76), some enhancements
#### :sparkles: Enhancements
-- [**#73**](https://github.com/jscastro76/threebox/issues/73) `tb.dispose` must clean `tb.objectsCache`
-- [**#74**](https://github.com/jscastro76/threebox/issues/74) Question: Why is this library not available on npm ?
-- [**#75**](https://github.com/jscastro76/threebox/issues/75) Publish in npm
-- [**#76**](https://github.com/jscastro76/threebox/issues/76) Refactor Objects.prototype._makeGroup
-- [**#78**](https://github.com/jscastro76/threebox/issues/78) refactor var to const and let
-- [**#80**](https://github.com/jscastro76/threebox/issues/80) Update example [15-performance.html](https://github.com/jscastro76/threebox/blob/master/examples/15-performance.html) Add built-in animation to example 15-performance.html windmill.
+- #73 `tb.dispose` must clean `tb.objectsCache`
+- #74 Question: Why is this library not available on npm ?
+- #75 Publish in npm
+- #76 Refactor Objects.prototype._makeGroup
+- #78 refactor var to const and let
+- #80 Update example [15-performance.html](https://github.com/jscastro76/threebox/blob/master/examples/15-performance.html) Add built-in animation to example 15-performance.html windmill.
+- #82 Add a method `tb.getSunTimes`
+- #85 We need an object compare method
+- #87 Change `tb.getSunPosition` to accept lnglat coords instead of two params
+- #88 Add night style change in 12-add3dmodel.html and 13-eiffel.html examples during night hours
#### :beetle: Bug fixes
-- [**#42**](https://github.com/jscastro76/threebox/issues/77) Angular and Threebox. Solved an issue using a `mapboxgl.Point`line
-- [**#77**](https://github.com/jscastro76/threebox/issues/77) example 05-logistics raises an error removing the line
-- [**#79**](https://github.com/jscastro76/threebox/issues/79) Some examples are not using `renderingMode: 3d` in the layer creation
+- #42 Angular and Threebox. Solved an issue using a `mapboxgl.Point`line
+- #77 example 05-logistics raises an error removing the line
+- #79 Some examples are not using `renderingMode: 3d` in the layer creation
+- #86 After #56 the feature that comes in userData is not being updated.
diff --git a/README.md b/README.md
index 8cf65f51..4c6ee391 100755
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ A **[*Three.js*](https://threejs.org/)** plugin for **[*Mapbox GL JS*](https://d
- - -
## Current release
-Current release is [**2.0.7**](https://github.com/jscastro76/threebox/releases/tag/v.2.0.7), please review the [**Change log**](https://github.com/jscastro76/threebox/blob/master/CHANGELOG.md#207) for more details.
+Current release is [**2.0.8**](https://github.com/jscastro76/threebox/releases/tag/v.2.0.8), please review the [**Change log**](https://github.com/jscastro76/threebox/blob/master/CHANGELOG.md#208) for more details.
Threebox is available as an [nmp package](https://www.npmjs.com/package/threebox-plugin)
```js
@@ -43,26 +43,25 @@ Only in this fork, there is a list of new features implemented on top of the ama
- Update to Three.js v117.
- Update to Mapbox-gl-js v1.11.1.
- [15 examples](https://github.com/jscastro76/threebox/tree/master/examples) with new features.
-- Support for multiple format objects (FBX, GLTF/GLB, Collada + OBJ/MTL).
+- Support for multiple 3D format objects (FBX, GLTF/GLB, Collada, OBJ/MTL).
- Support for CSS2D labels supporting rich HTML controls through a new LabelManager.
- Support for CSS2D tooltips/title browser-like and mapbox-like.
-- Support for Objects3D auto-centering, bounding box and floor projection.
- Support for built-in shadows and real Sun light positioning for a given datetime and lnglat coords.
-- Support for built-in Raycaster in loaded Objects3D and fill-extrusions together.
+- Support for built-in Raycaster in loaded Object3D and fill-extrusions together.
- Support for built-in MouseOver/Mouseout, Selected, Drag&Drop, Drag&Rotate, Wireframe in loadedObjects including events.
-- Support for GeoJson standard features format import and export in different layers.
-- Support for Objects3D embedded animations, and combined animations on AnimationManager (i.e. translate + embedded).
+- Support for [GeoJson](https://geojson.org/) standard features format import and export in different layers.
+- Support for Object3D embedded animations, and combined animations on AnimationManager (i.e. translate + embedded).
- Support for multi-floor design of spaces.
-- Support for style change through `setStyle` and keeping 3D models.
- Support for Non-AABB Non Axes Aligned Bounding Box and real model size.
-- Support for wireframing on Objects3D, removing them from the raycast.
+- Support for wireframing on Object3D, removing them from the raycast.
- Support for `setLayerZoomRange` and `setLayoutProperty` on Custom Layers (not available in Mapbox).
-- Support for `removeLayer` considering 3D objects.
+- Support for `removeLayer` considering Object3D.
+- Support for style change through `setStyle` and keeping Object3D.
- Support for partial and full dispose of Mapbox, Three and Threebox resources and memory.
+- Support for Object3D auto-centering, bounding box and floor projection.
- Optimization for loading thousands of objects through cache.
- Optimization of Camera perspective to have Raycast with pixel-precision level.
-- Adjusted positioning for Objects3D to set center and rotation axes by config.
-- Check out [v2.0.7 change log](https://github.com/jscastro76/threebox/blob/master/CHANGELOG.md#207) for more detail.
+- Check out [v2.0.7 change log](https://github.com/jscastro76/threebox/blob/master/CHANGELOG.md#208) for more detail.
diff --git a/dist/threebox.js b/dist/threebox.js
index f1895fbe..8e879301 100755
--- a/dist/threebox.js
+++ b/dist/threebox.js
@@ -723,8 +723,13 @@ Threebox.prototype = {
},
//[jscastro] get the sun position (azimuth, altitude) from a given datetime, lng, lat
- getSunPosition: function (date, lng, lat) {
- return SunCalc.getPosition(date, lat, lng);
+ getSunPosition: function (date, coords) {
+ return SunCalc.getPosition(date, coords[1], coords[0]);
+ },
+
+ //[jscastro] get the sun times for sunrise, sunset, etc.. from a given datetime, lng, lat and alt
+ getSunTimes: function (date, coords) {
+ return SunCalc.getTimes(date, coords[1], coords[0], (coords[2] ? coords[2] : 0));
},
//[jscastro] set shadows for fill-extrusion layers
@@ -761,7 +766,7 @@ Threebox.prototype = {
this.lightDateTime = date;
this.lightLng = this.mapCenter.lng;
this.lightLat = this.mapCenter.lat
- this.sunPosition = this.getSunPosition(date, this.mapCenter.lng, this.mapCenter.lat);
+ this.sunPosition = this.getSunPosition(date, [this.mapCenter.lng, this.mapCenter.lat]);
let altitude = this.sunPosition.altitude;
let azimuth = Math.PI + this.sunPosition.azimuth;
//console.log("Altitude: " + utils.degreeify(altitude) + ", Azimuth: " + (utils.degreeify(azimuth)));
@@ -1915,7 +1920,7 @@ class BuildingShadows {
const buildingsLayer = map.getLayer(this.buildingsLayerId);
const context = this.map.painter.context;
const { lng, lat } = this.map.getCenter();
- const pos = this.tb.getSunPosition(this.tb.lightDateTime, lng, lat);
+ const pos = this.tb.getSunPosition(this.tb.lightDateTime, [lng, lat]);
gl.uniform1f(this.uAltitude, (pos.altitude > this.minAltitude ? pos.altitude : 0));
gl.uniform1f(this.uAzimuth, pos.azimuth + 3 * Math.PI / 2);
//this.opacity = Math.sin(Math.max(pos.altitude, 0)) * 0.6;
@@ -16799,10 +16804,13 @@ Objects.prototype = {
let dupe = obj.clone(true); //clone the whole threebox object
dupe.getObjectByName("model").animations = obj.animations; //we must set this explicitly before addMethods
- if (dupe.userData.feature) dupe.userData.feature.properties.uuid = dupe.uuid;
+ if (dupe.userData.feature) {
+ if (options && options.feature) dupe.userData.feature = options.feature;
+ dupe.userData.feature.properties.uuid = dupe.uuid;
+ }
root._addMethods(dupe); // add methods
- if (!options || options.scale == obj.userData.scale) {
+ if (!options || utils.equal(options.scale, obj.userData.scale)) {
//no options, no changes, just return the same object
dupe.copyAnchor(obj); // copy anchors
//[jscastro] we add by default a tooltip that can be overriden later or hide it with threebox `enableTooltips`
@@ -17006,8 +17014,7 @@ Objects.prototype = {
htmlElement: null,
cssClass: " label3D",
alwaysVisible: false,
- topMargin: -0.5,
- feature: null
+ topMargin: -0.5
},
tooltip: {
@@ -19058,6 +19065,33 @@ var utils = {
}
},
+ equal: function (obj1, obj2) {
+ const keys1 = Object.keys(obj1);
+ const keys2 = Object.keys(obj2);
+
+ if (keys1.length !== keys2.length) {
+ return false;
+ }
+
+ for (const key of keys1) {
+ const val1 = obj1[key];
+ const val2 = obj2[key];
+ const areObjects = this.isObject(val1) && this.isObject(val2);
+ if (
+ areObjects && !deepEqual(val1, val2) ||
+ !areObjects && val1 !== val2
+ ) {
+ return false;
+ }
+ }
+
+ return true;
+ },
+
+ isObject: function (object) {
+ return object != null && typeof object === 'object';
+ },
+
_validate: function (userInputs, defaults) {
userInputs = userInputs || {};
diff --git a/dist/threebox.min.js b/dist/threebox.min.js
index 26505e33..46036e6d 100644
--- a/dist/threebox.min.js
+++ b/dist/threebox.min.js
@@ -2,7 +2,7 @@
window.Threebox=require("./src/Threebox.js"),window.THREE=require("./src/three.js");
},{"./src/Threebox.js":2,"./src/three.js":22}],2:[function(require,module,exports){
-const THREE=require("./three.js"),CameraSync=require("./camera/CameraSync.js"),utils=require("./utils/utils.js"),SunCalc=require("./utils/suncalc.js"),AnimationManager=require("./animation/AnimationManager.js"),ThreeboxConstants=require("./utils/constants.js"),Objects=require("./objects/objects.js"),material=require("./utils/material.js"),sphere=require("./objects/sphere.js"),label=require("./objects/label.js"),tooltip=require("./objects/tooltip.js"),loader=require("./objects/loadObj.js"),Object3D=require("./objects/Object3D.js"),line=require("./objects/line.js"),tube=require("./objects/tube.js"),LabelRenderer=require("./objects/LabelRenderer.js"),BuildingShadows=require("./objects/effects/BuildingShadows.js");function Threebox(e,t,i){this.init(e,t,i)}Threebox.prototype={repaint:function(){this.map.repaint=!0},init:function(e,t,i){this.options=utils._validate(i||{},defaultOptions),this.map=e,this.map.tb=this,this.objects=new Objects,this.renderer=new THREE.WebGLRenderer({alpha:!0,antialias:!0,canvas:e.getCanvas(),context:t}),this.renderer.setPixelRatio(window.devicePixelRatio),this.renderer.setSize(this.map.getCanvas().clientWidth,this.map.getCanvas().clientHeight),this.renderer.outputEncoding=THREE.sRGBEncoding,this.renderer.autoClear=!1,this.labelRenderer=new LabelRenderer(this.map),this.scene=new THREE.Scene,this.camera=new THREE.PerspectiveCamera(ThreeboxConstants.FOV_DEGREES,this.map.getCanvas().clientWidth/this.map.getCanvas().clientHeight,1,1e21),this.camera.layers.enable(0),this.camera.layers.enable(1),this.world=new THREE.Group,this.world.name="world",this.scene.add(this.world),this.objectsCache=new Map,this.cameraSync=new CameraSync(this.map,this.camera,this.world),this.raycaster=new THREE.Raycaster,this.raycaster.layers.set(0),this.mapCenter=this.map.getCenter(),this.mapCenterUnits=utils.projectToWorld([this.mapCenter.lng,this.mapCenter.lat]),this.lightDateTime=new Date,this.lightLng=this.mapCenter.lng,this.lightLat=this.mapCenter.lat,this.sunPosition,this.lights=this.initLights,this.options.defaultLights&&this.defaultLights(),this.options.realSunlight&&this.realSunlight(),this.options.enableSelectingFeatures&&(this.enableSelectingFeatures=this.options.enableSelectingFeatures),this.options.enableSelectingObjects&&(this.enableSelectingObjects=this.options.enableSelectingObjects),this.options.enableDraggingObjects&&(this.enableDraggingObjects=this.options.enableDraggingObjects),this.options.enableRotatingObjects&&(this.enableRotatingObjects=this.options.enableRotatingObjects),this.options.enableTooltips&&(this.enableTooltips=this.options.enableTooltips),this.map.on("load",function(){let t,i,s,n,r,o,a,l=this.getCanvasContainer();this.getCanvasContainer().style.cursor="default";let h,u,c=[];function d(e){var t=l.getBoundingClientRect();return{x:e.originalEvent.clientX-t.left-l.clientLeft,y:e.originalEvent.clientY-t.top-l.clientTop}}function g(e,t){void 0!==e.id&&(t.setFeatureState({source:e.source,sourceLayer:e.sourceLayer,id:e.id},{select:!1}),y(e,t),(e=t.queryRenderedFeatures({layers:[e.layer.id],filter:["==",["id"],e.id]})[0])&&t.fire("SelectedFeatureChange",{detail:e}),o=null)}function p(e,t){o=e,t.setFeatureState({source:o.source,sourceLayer:o.sourceLayer,id:o.id},{select:!0}),f(o=t.queryRenderedFeatures({layers:[o.layer.id],filter:["==",["id"],o.id]})[0],t),t.fire("SelectedFeatureChange",{detail:o})}function b(e,t){r&&void 0!==r&&r.id!=e&&(t.setFeatureState({source:r.source,sourceLayer:r.sourceLayer,id:r.id},{hover:!1}),y(r,t),r=null)}function m(e){e.selected=!1,t=null}function f(e,t){if(!t.tb.enableTooltips)return;let i=t.tb.getFeatureCenter(e),s=t.tb.tooltip({text:e.properties.name||e.id||e.type,mapboxStyle:!0,feature:e});s.setCoords(i),t.tb.add(s),e.tooltip=s,e.tooltip.tooltip.visible=!0}function y(e,t){e.tooltip&&(e.tooltip.visibility=!1,t.tb.remove(e.tooltip),e.tooltip=null)}e.onContextMenu=function(e){alert("contextMenu")},e.onClick=function(i){let s,n=[];if(e.tb.enableSelectingObjects&&(n=this.tb.queryRenderedFeatures(i.point)),s="object"==typeof n[0]){let e=Threebox.prototype.findParent3DObject(n[0]);if(e){if(o&&g(o,this),t){if(t.uuid!=e.uuid)t.selected=!1,e.selected=!0,t=e;else if(t.uuid==e.uuid)return void m(t)}else(t=e).selected=!0;t.dispatchEvent(new CustomEvent("Wireframed",{detail:t,bubbles:!0,cancelable:!0})),t.dispatchEvent(new CustomEvent("IsPlayingChanged",{detail:t,bubbles:!0,cancelable:!0})),this.repaint=!0,i.preventDefault()}}else{let s=[];if(e.tb.enableSelectingFeatures&&(s=this.queryRenderedFeatures(i.point)),s.length>0&&"fill-extrusion"==s[0].layer.type&&void 0!==s[0].id)if(t&&m(t),o){if(o.id!=s[0].id)g(o,this),p(s[0],this);else if(o.id==s[0].id)return void g(o,this)}else p(s[0],this)}},e.onMouseMove=function(l){let c,g=d(l);if(this.getCanvasContainer().style.cursor="default",l.originalEvent.altKey&&i){if(!e.tb.enableRotatingObjects)return;s="rotate",this.getCanvasContainer().style.cursor="move";Math.min(a.x,g.x),Math.max(a.x,g.x),Math.min(a.y,g.y),Math.max(a.y,g.y);let t={x:0,y:0,z:360+~~((g.x-a.x)/10)%360*10%360};return void i.setRotation(t)}if(l.originalEvent.shiftKey&&i){if(!e.tb.enableDraggingObjects)return;s="translate",this.getCanvasContainer().style.cursor="move";let t=l.lngLat,n=[Number((t.lng+h).toFixed(6)),Number((t.lat+u).toFixed(6)),i.modelHeight];return void i.setCoords(n)}let p=[];if(e.tb.enableSelectingObjects&&(p=this.tb.queryRenderedFeatures(l.point)),c="object"==typeof p[0]){let e=Threebox.prototype.findParent3DObject(p[0]);e&&(b(r,this),this.getCanvasContainer().style.cursor="pointer",t&&e.uuid==t.uuid||(n&&(n.over=!1,n=null),e.over=!0,n=e),this.repaint=!0,l.preventDefault())}else{n&&(n.over=!1,n=null);let t=[];e.tb.enableSelectingFeatures&&(t=this.queryRenderedFeatures(l.point)),t.length>0&&(b(t[0],this),"fill-extrusion"==t[0].layer.type&&void 0!==t[0].id&&(o&&o.id==t[0].id||(this.getCanvasContainer().style.cursor="pointer",r=t[0],this.setFeatureState({source:r.source,sourceLayer:r.sourceLayer,id:r.id},{hover:!0}),f(r=e.queryRenderedFeatures({layers:[r.layer.id],filter:["==",["id"],r.id]})[0],this))))}},e.onMouseDown=function(s){(s.originalEvent.shiftKey||s.originalEvent.altKey)&&0===s.originalEvent.button&&t&&(s.preventDefault(),e.getCanvasContainer().style.cursor="move",e.once("mouseup",e.onMouseUp),e.once("mouseout",e.onMouseUp),i=t,a=d(s),c=i.coordinates,h=c[0]-s.lngLat.lng,u=c[1]-s.lngLat.lat)},e.onMouseUp=function(t){this.getCanvasContainer().style.cursor="default",this.off("mouseup",e.onMouseUp),this.off("mouseout",e.onMouseUp),this.dragPan.enable(),i&&(i.dispatchEvent(new CustomEvent("ObjectDragged",{detail:{draggedObject:i,draggedAction:s},bubbles:!0,cancelable:!0})),i=null,s=null)},e.onMouseOut=function(e){if(r){let t=this.queryRenderedFeatures(e.point);t.length>0&&r.id!=t[0].id&&(this.getCanvasContainer().style.cursor="default",b(t[0],this))}},this.on("click",e.onClick),this.on("mousemove",e.onMouseMove),this.on("mouseout",e.onMouseOut),this.on("mousedown",e.onMouseDown)})},sphere:function(e){return this.setDefaultView(e,this.options),sphere(e,this.world)},line:line,label:label,tooltip:tooltip,tube:function(e){return this.setDefaultView(e,this.options),tube(e,this.world)},Object3D:function(e,t){return this.setDefaultView(e,this.options),Object3D(e,t)},loadObj:async function(e,t){this.setDefaultView(e,this.options);let i=this.objectsCache.get(e.obj);i?i.promise.then(i=>{t(i.duplicate(e))}).catch(t=>{this.objectsCache.delete(e.obj),console.error("Could not load model file: "+e.obj)}):this.objectsCache.set(e.obj,{promise:new Promise(function(i,s){loader(e,t,function(e){e.duplicate?i(e.duplicate()):s(e)})})})},material:function(e){return material(e)},initLights:{ambientLight:null,dirLight:null,dirLightBack:null,dirLightHelper:null,hemiLight:null,pointLight:null},utils:utils,SunCalc:SunCalc,Constants:ThreeboxConstants,projectToWorld:function(e){return this.utils.projectToWorld(e)},unprojectFromWorld:function(e){return this.utils.unprojectFromWorld(e)},projectedUnitsPerMeter:function(e){return this.utils.projectedUnitsPerMeter(e)},getFeatureCenter:function(e,t,i){return utils.getFeatureCenter(e,t,i)},getObjectHeightOnFloor:function(e,t,i){return utils.getObjectHeightOnFloor(e,t,i)},queryRenderedFeatures:function(e){let t=new THREE.Vector2;return t.x=e.x/this.map.transform.width*2-1,t.y=1-e.y/this.map.transform.height*2,this.raycaster.setFromCamera(t,this.camera),this.raycaster.intersectObjects(this.world.children,!0)},findParent3DObject:function(e){var t;return e.object.traverseAncestors(function(e){e.parent&&"Group"==e.parent.type&&e.userData.obj&&(t=e)}),t},setLabelZoomRange:function(e,t){this.labelRenderer.setZoomRange(e,t)},setLayoutProperty:function(e,t,i){this.map.setLayoutProperty(e,t,i),null==i||"visibility"!==t||this.world.children.forEach(function(t){t.userData.feature&&t.userData.feature.layer===e&&(t.visibility=i)})},setLayerZoomRange:function(e,t,i){this.map.getLayer(e)&&(this.map.setLayerZoomRange(e,t,i),this.setLabelZoomRange(t,i))},setLayerHeigthProperty:function(e,t){let i=this.map.getLayer(e);if(i)if("fill-extrusion"==i.type){let e=this.map.getStyle().sources[i.source].data;e.features.forEach(function(e){e.properties.level=t}),this.map.getSource(i.source).setData(e)}else"custom"==i.type&&this.world.children.forEach(function(i){let s=i.userData.feature;if(s&&s.layer===e){let e=this.tb.getFeatureCenter(s,i,t);i.setCoords(e)}})},setStyle:function(e,t){this.clear().then(()=>{this.map.setStyle(e,t)})},toggleLayer:function(e,t){this.map.getLayer(e)&&this.setLayoutProperty(e,"visibility",t?"visible":"none")},update:function(){this.map.repaint&&(this.map.repaint=!1);var e=Date.now();this.objects.animationManager.update(e),this.updateLightHelper(),this.renderer.state.reset(),this.renderer.render(this.scene,this.camera),this.labelRenderer.render(this.scene,this.camera),!1===this.options.passiveRendering&&this.map.triggerRepaint()},add:function(e){!this.enableTooltips&&e.tooltip&&(e.tooltip.visibility=!1),this.world.add(e)},remove:function(e){e.dispose&&e.dispose(),this.world.remove(e),e=null},clear:async function(e=null,t=!1){return new Promise((i,s)=>{let n=[];this.world.children.forEach(function(e){n.push(e)});for(let t=0;t{e.promise.then(e=>{e.dispose(),e=null})}),i("clear")})},removeLayer:function(e){this.clear(e,!0).then(()=>{this.map.removeLayer(e)})},getSunPosition:function(e,t,i){return SunCalc.getPosition(e,i,t)},setBuildingShadows:function(e){if(this.map.getLayer(e.buildingsLayerId)){let t=new BuildingShadows(e,this);this.map.addLayer(t,e.buildingsLayerId)}else console.warn("The layer '"+e.buildingsLayerId+"' does not exist in the map.")},setSunlight:function(e=new Date,t){if(!this.lights.dirLight||!this.options.realSunlight)return void console.warn("To use setSunlight it's required to set realSunlight : true in Threebox initial options.");var i=new Date(e.getTime());if(this.mapCenter=t?{lng:t[0],lat:t[1]}:this.map.getCenter(),this.lightDateTime&&this.lightDateTime.getTime()===i.getTime()&&this.lightLng===this.mapCenter.lng&&this.lightLat===this.mapCenter.lat)return;this.lightDateTime=i,this.lightLng=this.mapCenter.lng,this.lightLat=this.mapCenter.lat,this.sunPosition=this.getSunPosition(i,this.mapCenter.lng,this.mapCenter.lat);let s=this.sunPosition.altitude,n=Math.PI+this.sunPosition.azimuth,r=ThreeboxConstants.WORLD_SIZE/2,o=Math.sin(s),a=Math.cos(s),l=Math.cos(n)*a,h=Math.sin(n)*a;this.lights.dirLight.position.set(h,l,o),this.lights.dirLight.position.multiplyScalar(r),this.lights.dirLight.intensity=Math.max(o,-.15),this.lights.dirLight.updateMatrixWorld(),this.updateLightHelper(),this.map.loaded()&&this.map.setLight({anchor:"map",position:[1.5,180+180*this.sunPosition.azimuth/Math.PI,90-180*this.sunPosition.altitude/Math.PI],"position-transition":{duration:0},color:`hsl(40, ${50*Math.cos(this.sunPosition.altitude)}%, ${96*Math.sin(this.sunPosition.altitude)}%)`},{duration:0})},updateLightHelper:function(){this.lights.dirLightHelper&&(this.lights.dirLightHelper.position.setFromMatrixPosition(this.lights.dirLight.matrixWorld),this.lights.dirLightHelper.updateMatrix(),this.lights.dirLightHelper.update())},dispose:async function(){return console.log(this.memory()),new Promise(e=>{e(this.clear(null,!0).then(e=>(this.map.remove(),this.map={},this.scene.remove(this.world),this.scene.dispose(),this.world.children=[],this.world=null,this.objectsCache.clear(),this.labelRenderer.dispose(),console.log(this.memory()),this.renderer.dispose(),e)))})},defaultLights:function(){this.lights.ambientLight=new THREE.AmbientLight(new THREE.Color("hsl(0, 0%, 100%)"),.75),this.scene.add(this.lights.ambientLight),this.lights.dirLightBack=new THREE.DirectionalLight(new THREE.Color("hsl(0, 0%, 100%)"),.25),this.lights.dirLightBack.position.set(30,100,100),this.scene.add(this.lights.dirLightBack),this.lights.dirLight=new THREE.DirectionalLight(new THREE.Color("hsl(0, 0%, 100%)"),.25),this.lights.dirLight.position.set(-30,100,-100),this.scene.add(this.lights.dirLight)},realSunlight:function(){this.renderer.shadowMap.enabled=!0,this.lights.dirLight=new THREE.DirectionalLight(16777215,1),this.scene.add(this.lights.dirLight),this.lights.dirLightHelper=new THREE.DirectionalLightHelper(this.lights.dirLight,5),this.scene.add(this.lights.dirLightHelper);this.lights.dirLight.castShadow=!0,this.lights.dirLight.shadow.radius=2,this.lights.dirLight.shadow.mapSize.width=8192,this.lights.dirLight.shadow.mapSize.height=8192,this.lights.dirLight.shadow.camera.top=this.lights.dirLight.shadow.camera.right=1e3,this.lights.dirLight.shadow.camera.bottom=this.lights.dirLight.shadow.camera.left=-1e3,this.lights.dirLight.shadow.camera.near=1,this.lights.dirLight.shadow.camera.visible=!0,this.lights.dirLight.shadow.camera.far=4e8,this.lights.hemiLight=new THREE.HemisphereLight(new THREE.Color(16777215),new THREE.Color(16777215),.6),this.lights.hemiLight.color.setHSL(.661,.96,.12),this.lights.hemiLight.groundColor.setHSL(.11,.96,.14),this.lights.hemiLight.position.set(0,0,50),this.scene.add(this.lights.hemiLight),this.setSunlight()},setDefaultView:function(e,t){e.bbox=e.bbox||t.enableSelectingObjects,e.tooltip=e.tooltip||t.enableTooltips},memory:function(){return this.renderer.info.memory},programs:function(){return this.renderer.info.programs.length},version:"2.0.8"};var defaultOptions={defaultLights:!1,realSunlight:!1,passiveRendering:!0,enableSelectingFeatures:!1,enableSelectingObjects:!1,enableDraggingObjects:!1,enableRotatingObjects:!1,enableTooltips:!1};module.exports=exports=Threebox;
+const THREE=require("./three.js"),CameraSync=require("./camera/CameraSync.js"),utils=require("./utils/utils.js"),SunCalc=require("./utils/suncalc.js"),AnimationManager=require("./animation/AnimationManager.js"),ThreeboxConstants=require("./utils/constants.js"),Objects=require("./objects/objects.js"),material=require("./utils/material.js"),sphere=require("./objects/sphere.js"),label=require("./objects/label.js"),tooltip=require("./objects/tooltip.js"),loader=require("./objects/loadObj.js"),Object3D=require("./objects/Object3D.js"),line=require("./objects/line.js"),tube=require("./objects/tube.js"),LabelRenderer=require("./objects/LabelRenderer.js"),BuildingShadows=require("./objects/effects/BuildingShadows.js");function Threebox(e,t,i){this.init(e,t,i)}Threebox.prototype={repaint:function(){this.map.repaint=!0},init:function(e,t,i){this.options=utils._validate(i||{},defaultOptions),this.map=e,this.map.tb=this,this.objects=new Objects,this.renderer=new THREE.WebGLRenderer({alpha:!0,antialias:!0,canvas:e.getCanvas(),context:t}),this.renderer.setPixelRatio(window.devicePixelRatio),this.renderer.setSize(this.map.getCanvas().clientWidth,this.map.getCanvas().clientHeight),this.renderer.outputEncoding=THREE.sRGBEncoding,this.renderer.autoClear=!1,this.labelRenderer=new LabelRenderer(this.map),this.scene=new THREE.Scene,this.camera=new THREE.PerspectiveCamera(ThreeboxConstants.FOV_DEGREES,this.map.getCanvas().clientWidth/this.map.getCanvas().clientHeight,1,1e21),this.camera.layers.enable(0),this.camera.layers.enable(1),this.world=new THREE.Group,this.world.name="world",this.scene.add(this.world),this.objectsCache=new Map,this.cameraSync=new CameraSync(this.map,this.camera,this.world),this.raycaster=new THREE.Raycaster,this.raycaster.layers.set(0),this.mapCenter=this.map.getCenter(),this.mapCenterUnits=utils.projectToWorld([this.mapCenter.lng,this.mapCenter.lat]),this.lightDateTime=new Date,this.lightLng=this.mapCenter.lng,this.lightLat=this.mapCenter.lat,this.sunPosition,this.lights=this.initLights,this.options.defaultLights&&this.defaultLights(),this.options.realSunlight&&this.realSunlight(),this.options.enableSelectingFeatures&&(this.enableSelectingFeatures=this.options.enableSelectingFeatures),this.options.enableSelectingObjects&&(this.enableSelectingObjects=this.options.enableSelectingObjects),this.options.enableDraggingObjects&&(this.enableDraggingObjects=this.options.enableDraggingObjects),this.options.enableRotatingObjects&&(this.enableRotatingObjects=this.options.enableRotatingObjects),this.options.enableTooltips&&(this.enableTooltips=this.options.enableTooltips),this.map.on("load",function(){let t,i,s,n,r,o,a,l=this.getCanvasContainer();this.getCanvasContainer().style.cursor="default";let h,u,c=[];function d(e){var t=l.getBoundingClientRect();return{x:e.originalEvent.clientX-t.left-l.clientLeft,y:e.originalEvent.clientY-t.top-l.clientTop}}function g(e,t){void 0!==e.id&&(t.setFeatureState({source:e.source,sourceLayer:e.sourceLayer,id:e.id},{select:!1}),y(e,t),(e=t.queryRenderedFeatures({layers:[e.layer.id],filter:["==",["id"],e.id]})[0])&&t.fire("SelectedFeatureChange",{detail:e}),o=null)}function p(e,t){o=e,t.setFeatureState({source:o.source,sourceLayer:o.sourceLayer,id:o.id},{select:!0}),f(o=t.queryRenderedFeatures({layers:[o.layer.id],filter:["==",["id"],o.id]})[0],t),t.fire("SelectedFeatureChange",{detail:o})}function b(e,t){r&&void 0!==r&&r.id!=e&&(t.setFeatureState({source:r.source,sourceLayer:r.sourceLayer,id:r.id},{hover:!1}),y(r,t),r=null)}function m(e){e.selected=!1,t=null}function f(e,t){if(!t.tb.enableTooltips)return;let i=t.tb.getFeatureCenter(e),s=t.tb.tooltip({text:e.properties.name||e.id||e.type,mapboxStyle:!0,feature:e});s.setCoords(i),t.tb.add(s),e.tooltip=s,e.tooltip.tooltip.visible=!0}function y(e,t){e.tooltip&&(e.tooltip.visibility=!1,t.tb.remove(e.tooltip),e.tooltip=null)}e.onContextMenu=function(e){alert("contextMenu")},e.onClick=function(i){let s,n=[];if(e.tb.enableSelectingObjects&&(n=this.tb.queryRenderedFeatures(i.point)),s="object"==typeof n[0]){let e=Threebox.prototype.findParent3DObject(n[0]);if(e){if(o&&g(o,this),t){if(t.uuid!=e.uuid)t.selected=!1,e.selected=!0,t=e;else if(t.uuid==e.uuid)return void m(t)}else(t=e).selected=!0;t.dispatchEvent(new CustomEvent("Wireframed",{detail:t,bubbles:!0,cancelable:!0})),t.dispatchEvent(new CustomEvent("IsPlayingChanged",{detail:t,bubbles:!0,cancelable:!0})),this.repaint=!0,i.preventDefault()}}else{let s=[];if(e.tb.enableSelectingFeatures&&(s=this.queryRenderedFeatures(i.point)),s.length>0&&"fill-extrusion"==s[0].layer.type&&void 0!==s[0].id)if(t&&m(t),o){if(o.id!=s[0].id)g(o,this),p(s[0],this);else if(o.id==s[0].id)return void g(o,this)}else p(s[0],this)}},e.onMouseMove=function(l){let c,g=d(l);if(this.getCanvasContainer().style.cursor="default",l.originalEvent.altKey&&i){if(!e.tb.enableRotatingObjects)return;s="rotate",this.getCanvasContainer().style.cursor="move";Math.min(a.x,g.x),Math.max(a.x,g.x),Math.min(a.y,g.y),Math.max(a.y,g.y);let t={x:0,y:0,z:360+~~((g.x-a.x)/10)%360*10%360};return void i.setRotation(t)}if(l.originalEvent.shiftKey&&i){if(!e.tb.enableDraggingObjects)return;s="translate",this.getCanvasContainer().style.cursor="move";let t=l.lngLat,n=[Number((t.lng+h).toFixed(6)),Number((t.lat+u).toFixed(6)),i.modelHeight];return void i.setCoords(n)}let p=[];if(e.tb.enableSelectingObjects&&(p=this.tb.queryRenderedFeatures(l.point)),c="object"==typeof p[0]){let e=Threebox.prototype.findParent3DObject(p[0]);e&&(b(r,this),this.getCanvasContainer().style.cursor="pointer",t&&e.uuid==t.uuid||(n&&(n.over=!1,n=null),e.over=!0,n=e),this.repaint=!0,l.preventDefault())}else{n&&(n.over=!1,n=null);let t=[];e.tb.enableSelectingFeatures&&(t=this.queryRenderedFeatures(l.point)),t.length>0&&(b(t[0],this),"fill-extrusion"==t[0].layer.type&&void 0!==t[0].id&&(o&&o.id==t[0].id||(this.getCanvasContainer().style.cursor="pointer",r=t[0],this.setFeatureState({source:r.source,sourceLayer:r.sourceLayer,id:r.id},{hover:!0}),f(r=e.queryRenderedFeatures({layers:[r.layer.id],filter:["==",["id"],r.id]})[0],this))))}},e.onMouseDown=function(s){(s.originalEvent.shiftKey||s.originalEvent.altKey)&&0===s.originalEvent.button&&t&&(s.preventDefault(),e.getCanvasContainer().style.cursor="move",e.once("mouseup",e.onMouseUp),e.once("mouseout",e.onMouseUp),i=t,a=d(s),c=i.coordinates,h=c[0]-s.lngLat.lng,u=c[1]-s.lngLat.lat)},e.onMouseUp=function(t){this.getCanvasContainer().style.cursor="default",this.off("mouseup",e.onMouseUp),this.off("mouseout",e.onMouseUp),this.dragPan.enable(),i&&(i.dispatchEvent(new CustomEvent("ObjectDragged",{detail:{draggedObject:i,draggedAction:s},bubbles:!0,cancelable:!0})),i=null,s=null)},e.onMouseOut=function(e){if(r){let t=this.queryRenderedFeatures(e.point);t.length>0&&r.id!=t[0].id&&(this.getCanvasContainer().style.cursor="default",b(t[0],this))}},this.on("click",e.onClick),this.on("mousemove",e.onMouseMove),this.on("mouseout",e.onMouseOut),this.on("mousedown",e.onMouseDown)})},sphere:function(e){return this.setDefaultView(e,this.options),sphere(e,this.world)},line:line,label:label,tooltip:tooltip,tube:function(e){return this.setDefaultView(e,this.options),tube(e,this.world)},Object3D:function(e,t){return this.setDefaultView(e,this.options),Object3D(e,t)},loadObj:async function(e,t){this.setDefaultView(e,this.options);let i=this.objectsCache.get(e.obj);i?i.promise.then(i=>{t(i.duplicate(e))}).catch(t=>{this.objectsCache.delete(e.obj),console.error("Could not load model file: "+e.obj)}):this.objectsCache.set(e.obj,{promise:new Promise(function(i,s){loader(e,t,function(e){e.duplicate?i(e.duplicate()):s(e)})})})},material:function(e){return material(e)},initLights:{ambientLight:null,dirLight:null,dirLightBack:null,dirLightHelper:null,hemiLight:null,pointLight:null},utils:utils,SunCalc:SunCalc,Constants:ThreeboxConstants,projectToWorld:function(e){return this.utils.projectToWorld(e)},unprojectFromWorld:function(e){return this.utils.unprojectFromWorld(e)},projectedUnitsPerMeter:function(e){return this.utils.projectedUnitsPerMeter(e)},getFeatureCenter:function(e,t,i){return utils.getFeatureCenter(e,t,i)},getObjectHeightOnFloor:function(e,t,i){return utils.getObjectHeightOnFloor(e,t,i)},queryRenderedFeatures:function(e){let t=new THREE.Vector2;return t.x=e.x/this.map.transform.width*2-1,t.y=1-e.y/this.map.transform.height*2,this.raycaster.setFromCamera(t,this.camera),this.raycaster.intersectObjects(this.world.children,!0)},findParent3DObject:function(e){var t;return e.object.traverseAncestors(function(e){e.parent&&"Group"==e.parent.type&&e.userData.obj&&(t=e)}),t},setLabelZoomRange:function(e,t){this.labelRenderer.setZoomRange(e,t)},setLayoutProperty:function(e,t,i){this.map.setLayoutProperty(e,t,i),null==i||"visibility"!==t||this.world.children.forEach(function(t){t.userData.feature&&t.userData.feature.layer===e&&(t.visibility=i)})},setLayerZoomRange:function(e,t,i){this.map.getLayer(e)&&(this.map.setLayerZoomRange(e,t,i),this.setLabelZoomRange(t,i))},setLayerHeigthProperty:function(e,t){let i=this.map.getLayer(e);if(i)if("fill-extrusion"==i.type){let e=this.map.getStyle().sources[i.source].data;e.features.forEach(function(e){e.properties.level=t}),this.map.getSource(i.source).setData(e)}else"custom"==i.type&&this.world.children.forEach(function(i){let s=i.userData.feature;if(s&&s.layer===e){let e=this.tb.getFeatureCenter(s,i,t);i.setCoords(e)}})},setStyle:function(e,t){this.clear().then(()=>{this.map.setStyle(e,t)})},toggleLayer:function(e,t){this.map.getLayer(e)&&this.setLayoutProperty(e,"visibility",t?"visible":"none")},update:function(){this.map.repaint&&(this.map.repaint=!1);var e=Date.now();this.objects.animationManager.update(e),this.updateLightHelper(),this.renderer.state.reset(),this.renderer.render(this.scene,this.camera),this.labelRenderer.render(this.scene,this.camera),!1===this.options.passiveRendering&&this.map.triggerRepaint()},add:function(e){!this.enableTooltips&&e.tooltip&&(e.tooltip.visibility=!1),this.world.add(e)},remove:function(e){e.dispose&&e.dispose(),this.world.remove(e),e=null},clear:async function(e=null,t=!1){return new Promise((i,s)=>{let n=[];this.world.children.forEach(function(e){n.push(e)});for(let t=0;t{e.promise.then(e=>{e.dispose(),e=null})}),i("clear")})},removeLayer:function(e){this.clear(e,!0).then(()=>{this.map.removeLayer(e)})},getSunPosition:function(e,t){return SunCalc.getPosition(e,t[1],t[0])},getSunTimes:function(e,t){return SunCalc.getTimes(e,t[1],t[0],t[2]?t[2]:0)},setBuildingShadows:function(e){if(this.map.getLayer(e.buildingsLayerId)){let t=new BuildingShadows(e,this);this.map.addLayer(t,e.buildingsLayerId)}else console.warn("The layer '"+e.buildingsLayerId+"' does not exist in the map.")},setSunlight:function(e=new Date,t){if(!this.lights.dirLight||!this.options.realSunlight)return void console.warn("To use setSunlight it's required to set realSunlight : true in Threebox initial options.");var i=new Date(e.getTime());if(this.mapCenter=t?{lng:t[0],lat:t[1]}:this.map.getCenter(),this.lightDateTime&&this.lightDateTime.getTime()===i.getTime()&&this.lightLng===this.mapCenter.lng&&this.lightLat===this.mapCenter.lat)return;this.lightDateTime=i,this.lightLng=this.mapCenter.lng,this.lightLat=this.mapCenter.lat,this.sunPosition=this.getSunPosition(i,[this.mapCenter.lng,this.mapCenter.lat]);let s=this.sunPosition.altitude,n=Math.PI+this.sunPosition.azimuth,r=ThreeboxConstants.WORLD_SIZE/2,o=Math.sin(s),a=Math.cos(s),l=Math.cos(n)*a,h=Math.sin(n)*a;this.lights.dirLight.position.set(h,l,o),this.lights.dirLight.position.multiplyScalar(r),this.lights.dirLight.intensity=Math.max(o,-.15),this.lights.dirLight.updateMatrixWorld(),this.updateLightHelper(),this.map.loaded()&&this.map.setLight({anchor:"map",position:[1.5,180+180*this.sunPosition.azimuth/Math.PI,90-180*this.sunPosition.altitude/Math.PI],"position-transition":{duration:0},color:`hsl(40, ${50*Math.cos(this.sunPosition.altitude)}%, ${96*Math.sin(this.sunPosition.altitude)}%)`},{duration:0})},updateLightHelper:function(){this.lights.dirLightHelper&&(this.lights.dirLightHelper.position.setFromMatrixPosition(this.lights.dirLight.matrixWorld),this.lights.dirLightHelper.updateMatrix(),this.lights.dirLightHelper.update())},dispose:async function(){return console.log(this.memory()),new Promise(e=>{e(this.clear(null,!0).then(e=>(this.map.remove(),this.map={},this.scene.remove(this.world),this.scene.dispose(),this.world.children=[],this.world=null,this.objectsCache.clear(),this.labelRenderer.dispose(),console.log(this.memory()),this.renderer.dispose(),e)))})},defaultLights:function(){this.lights.ambientLight=new THREE.AmbientLight(new THREE.Color("hsl(0, 0%, 100%)"),.75),this.scene.add(this.lights.ambientLight),this.lights.dirLightBack=new THREE.DirectionalLight(new THREE.Color("hsl(0, 0%, 100%)"),.25),this.lights.dirLightBack.position.set(30,100,100),this.scene.add(this.lights.dirLightBack),this.lights.dirLight=new THREE.DirectionalLight(new THREE.Color("hsl(0, 0%, 100%)"),.25),this.lights.dirLight.position.set(-30,100,-100),this.scene.add(this.lights.dirLight)},realSunlight:function(){this.renderer.shadowMap.enabled=!0,this.lights.dirLight=new THREE.DirectionalLight(16777215,1),this.scene.add(this.lights.dirLight),this.lights.dirLightHelper=new THREE.DirectionalLightHelper(this.lights.dirLight,5),this.scene.add(this.lights.dirLightHelper);this.lights.dirLight.castShadow=!0,this.lights.dirLight.shadow.radius=2,this.lights.dirLight.shadow.mapSize.width=8192,this.lights.dirLight.shadow.mapSize.height=8192,this.lights.dirLight.shadow.camera.top=this.lights.dirLight.shadow.camera.right=1e3,this.lights.dirLight.shadow.camera.bottom=this.lights.dirLight.shadow.camera.left=-1e3,this.lights.dirLight.shadow.camera.near=1,this.lights.dirLight.shadow.camera.visible=!0,this.lights.dirLight.shadow.camera.far=4e8,this.lights.hemiLight=new THREE.HemisphereLight(new THREE.Color(16777215),new THREE.Color(16777215),.6),this.lights.hemiLight.color.setHSL(.661,.96,.12),this.lights.hemiLight.groundColor.setHSL(.11,.96,.14),this.lights.hemiLight.position.set(0,0,50),this.scene.add(this.lights.hemiLight),this.setSunlight()},setDefaultView:function(e,t){e.bbox=e.bbox||t.enableSelectingObjects,e.tooltip=e.tooltip||t.enableTooltips},memory:function(){return this.renderer.info.memory},programs:function(){return this.renderer.info.programs.length},version:"2.0.8"};var defaultOptions={defaultLights:!1,realSunlight:!1,passiveRendering:!0,enableSelectingFeatures:!1,enableSelectingObjects:!1,enableDraggingObjects:!1,enableRotatingObjects:!1,enableTooltips:!1};module.exports=exports=Threebox;
},{"./animation/AnimationManager.js":3,"./camera/CameraSync.js":4,"./objects/LabelRenderer.js":6,"./objects/Object3D.js":7,"./objects/effects/BuildingShadows.js":9,"./objects/label.js":10,"./objects/line.js":11,"./objects/loadObj.js":12,"./objects/objects.js":18,"./objects/sphere.js":19,"./objects/tooltip.js":20,"./objects/tube.js":21,"./three.js":22,"./utils/constants.js":23,"./utils/material.js":24,"./utils/suncalc.js":25,"./utils/utils.js":26}],3:[function(require,module,exports){
const THREE=require("../three.js"),utils=require("../utils/utils.js");function AnimationManager(t){this.map=t,this.enrolledObjects=[],this.previousFrameTime}AnimationManager.prototype={unenroll:function(t){this.enrolledObjects.splice(this.enrolledObjects.indexOf(t),1)},enroll:function(t){if(t.clock=new THREE.Clock,t.hasDefaultAnimation=!1,t.defaultAction,t.actions=[],t.mixer,t.animations&&t.animations.length>0){t.hasDefaultAnimation=!0;let i=t.userData.defaultAnimation?t.userData.defaultAnimation:0;t.mixer=new THREE.AnimationMixer(t),e(i)}function e(e){for(let i=0;it.animations.length&&console.log("The animation index "+e+" doesn't exist for this object");let a=t.animations[i],n=t.mixer.clipAction(a);t.actions.push(n),e===i?(t.defaultAction=n,n.setEffectiveWeight(1)):n.setEffectiveWeight(0),n.play()}}let i=!1;Object.defineProperty(t,"isPlaying",{get:()=>i,set(e){i!=e&&(i=e,t.dispatchEvent(new CustomEvent("IsPlayingChanged",{detail:t,bubbles:!0,cancelable:!0})))}}),this.enrolledObjects.push(t),t.animationQueue=[],t.set=function(e){if(e.duration>0){let i={start:Date.now(),expiration:Date.now()+e.duration,endState:{}};utils.extend(e,i);let a=e.coords,n=e.rotation,o=e.scale||e.scaleX||e.scaleY||e.scaleZ;if(n){let i=t.rotation;e.startRotation=[i.x,i.y,i.z],e.endState.rotation=utils.types.rotation(e.rotation,e.startRotation),e.rotationPerMs=e.endState.rotation.map(function(t,i){return(t-e.startRotation[i])/e.duration})}if(o){let i=t.scale;e.startScale=[i.x,i.y,i.z],e.endState.scale=utils.types.scale(e.scale,e.startScale),e.scalePerMs=e.endState.scale.map(function(t,i){return(t-e.startScale[i])/e.duration})}a&&(e.pathCurve=new THREE.CatmullRomCurve3(utils.lnglatsToWorld([t.coordinates,e.coords])));let s={type:"set",parameters:e};this.animationQueue.push(s),tb.map.repaint=!0}else this.stop(),e.rotation=utils.radify(e.rotation),this._setObject(e);return this},t.animationMethod=null,t.stop=function(e){return t.mixer&&(t.isPlaying=!1,cancelAnimationFrame(t.animationMethod)),this.animationQueue=[],this},t.followPath=function(t,e){let i={type:"followPath",parameters:utils._validate(t,defaults.followPath)};return utils.extend(i.parameters,{pathCurve:new THREE.CatmullRomCurve3(utils.lnglatsToWorld(t.path)),start:Date.now(),expiration:Date.now()+i.parameters.duration,cb:e}),this.animationQueue.push(i),tb.map.repaint=!0,this},t._setObject=function(t){let e=t.position,i=t.rotation,a=t.scale,n=t.worldCoordinates,o=t.quaternion,s=t.translate;if(e){this.coordinates=e;let t=utils.projectToWorld(e);this.position.copy(t)}if(s){this.coordinates=[this.coordinates[0]+s[0],this.coordinates[1]+s[1],this.coordinates[2]+s[2]];let t=utils.projectToWorld(s);this.translateX(t.x),this.translateY(t.y),this.translateZ(t.z)}i&&this.rotation.set(i[0],i[1],i[2]),a&&this.scale.set(a[0],a[1],a[2]),o&&this.quaternion.setFromAxisAngle(o[0],o[1]),n&&this.position.copy(n),this.updateMatrixWorld(),tb.map.repaint=!0},t.playDefault=function(e){if(t.mixer&&t.hasDefaultAnimation){let t={start:Date.now(),expiration:Date.now()+e.duration,endState:{}};utils.extend(e,t);let i={type:"playDefault",parameters:e};return this.animationQueue.push(i),tb.map.repaint=!0,this}},t.playAnimation=function(i){t.mixer&&(i.animation&&e(i.animation),t.playDefault(i))},t.pauseAllActions=function(){t.mixer&&t.actions.forEach(function(t){t.paused=!0})},t.unPauseAllActions=function(){t.mixer&&t.actions.forEach(function(t){t.paused=!1})},t.deactivateAllActions=function(){t.mixer&&t.actions.forEach(function(t){t.stop()})},t.activateAllActions=function(){t.mixer&&t.actions.forEach(function(t){t.play()})},t.idle=function(){return t.mixer&&t.mixer.update(.01),tb.map.repaint=!0,this}},update:function(t){void 0===this.previousFrameTime&&(this.previousFrameTime=t);if(!this.enrolledObjects)return!1;for(let e=this.enrolledObjects.length-1;e>=0;e--){let i=this.enrolledObjects[e];if(i.animationQueue&&0!==i.animationQueue.length)for(let e=i.animationQueue.length-1;e>=0;e--){let a=i.animationQueue[e];if(!a)continue;let n=a.parameters;if(!n.expiration)return i.animationQueue.splice(e,1),void(i.animationQueue[e]&&(i.animationQueue[e].parameters.start=t));if(t>=n.expiration)n.expiration=!1,"playDefault"===a.type?i.stop():(n.endState&&i._setObject(n.endState),void 0!==n.cb&&n.cb());else{let e=(t-n.start)/n.duration;if("set"===a.type){let t={};n.pathCurve&&(t.worldCoordinates=n.pathCurve.getPoint(e)),n.rotationPerMs&&(t.rotation=n.startRotation.map(function(t,i){return t+n.rotationPerMs[i]*e*n.duration})),n.scalePerMs&&(t.scale=n.startScale.map(function(t,i){return t+n.scalePerMs[i]*e*n.duration})),i._setObject(t)}if("followPath"===a.type){let t=n.pathCurve.getPointAt(e);if(objectState={worldCoordinates:t},n.trackHeading){let t=n.pathCurve.getTangentAt(e).normalize(),i=new THREE.Vector3(0,0,0),a=new THREE.Vector3(0,1,0);i.crossVectors(a,t).normalize();let o=Math.acos(a.dot(t));objectState.quaternion=[i,o]}i._setObject(objectState)}"playDefault"===a.type&&(i.activateAllActions(),i.isPlaying=!0,i.animationMethod=requestAnimationFrame(this.update),i.mixer.update(i.clock.getDelta()),tb.map.repaint=!0)}}}this.previousFrameTime=t}};const defaults={followPath:{path:null,duration:1e3,trackHeading:!0}};module.exports=exports=AnimationManager;
@@ -23,7 +23,7 @@ const Objects=require("./objects.js"),utils=require("../utils/utils.js");functio
var mod={},l=void 0,aa=mod;function r(t,r){var i,e=t.split("."),h=aa;!(e[0]in h)&&h.execScript&&h.execScript("var "+e[0]);for(;e.length&&(i=e.shift());)e.length||r===l?h=h[i]?h[i]:h[i]={}:h[i]=r}var t="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array&&"undefined"!=typeof DataView;function v(r){var i,e,h,s,a,n,f,o,l,u,c=r.length,b=0,y=Number.POSITIVE_INFINITY;for(o=0;ob&&(b=r[o]),r[o]>=1;for(u=h<<16|o,l=n;l>>=1){case 0:var i=this.input,e=this.a,h=this.c,s=this.b,a=i.length,n=l,f=h.length,o=l;if(this.d=this.f=0,e+1>=a)throw Error("invalid uncompressed block header: LEN");if(n=i[e++]|i[e++]<<8,e+1>=a)throw Error("invalid uncompressed block header: NLEN");if(n===~(i[e++]|i[e++]<<8))throw Error("invalid uncompressed block header: length verify");if(e+n>i.length)throw Error("input buffer is broken");switch(this.i){case A:for(;s+n>h.length;){if(n-=o=f-s,t)h.set(i.subarray(e,e+o),s),s+=o,e+=o;else for(;o--;)h[s++]=i[e++];this.b=s,h=this.e(),s=this.b}break;case y:for(;s+n>h.length;)h=this.e({p:2});break;default:throw Error("invalid inflate mode")}if(t)h.set(i.subarray(e,e+n),s),s+=n,e+=n;else for(;n--;)h[s++]=i[e++];this.a=e,this.b=s,this.c=h;break;case 1:this.j(ba,ca);break;case 2:var u,c,b,d,p=C(this,5)+257,w=C(this,5)+1,g=C(this,4)+4,k=new(t?Uint8Array:Array)(D.length),m=l,U=l,I=l,N=l,P=l;for(P=0;P=P?8:255>=P?9:279>=P?7:8;var R,ga,ba=v(O),Q=new(t?Uint8Array:Array)(30);for(R=0,ga=Q.length;R=n)throw Error("input buffer is broken");e|=s[a++]<>>r,t.d=h-r,t.a=a,i}function E(t,r){for(var i,e,h=t.f,s=t.d,a=t.input,n=t.a,f=a.length,o=r[0],l=r[1];s=f);)h|=a[n++]<>>16)>s)throw Error("invalid code length: "+e);return t.f=h>>e,t.d=s-e,t.a=n,65535&i}function W(t,r){var i,e;switch(this.input=t,this.a=0,!r&&(r={})||(r.index&&(this.a=r.index),r.verify&&(this.A=r.verify)),i=t[this.a++],e=t[this.a++],15&i){case ha:this.method=ha;break;default:throw Error("unsupported compression method")}if(0!=((i<<8)+e)%31)throw Error("invalid fcheck flag:"+((i<<8)+e)%31);if(32&e)throw Error("fdict flag is not supported");this.q=new w(t,{index:this.a,bufferSize:r.bufferSize,bufferType:r.bufferType,resize:r.resize})}w.prototype.j=function(t,r){var i=this.c,e=this.b;this.o=t;for(var h,s,a,n,f=i.length-258;256!==(h=E(this,t));)if(256>h)e>=f&&(this.b=e,i=this.e(),e=this.b),i[e++]=h;else for(n=I[s=h-257],0=f&&(this.b=e,i=this.e(),e=this.b);n--;)i[e]=i[e++-a];for(;8<=this.d;)this.d-=8,this.a--;this.b=e},w.prototype.w=function(t,r){var i=this.c,e=this.b;this.o=t;for(var h,s,a,n,f=i.length;256!==(h=E(this,t));)if(256>h)e>=f&&(f=(i=this.e()).length),i[e++]=h;else for(n=I[s=h-257],0f&&(f=(i=this.e()).length);n--;)i[e]=i[e++-a];for(;8<=this.d;)this.d-=8,this.a--;this.b=e},w.prototype.e=function(){var r,i,e=new(t?Uint8Array:Array)(this.b-32768),h=this.b-32768,s=this.c;if(t)e.set(s.subarray(32768,e.length));else for(r=0,i=e.length;rr;++r)s[r]=s[h+r];return this.b=32768,s},w.prototype.z=function(r){var i,e,h,s=this.input.length/this.a+1|0,a=this.input,n=this.c;return r&&("number"==typeof r.p&&(s=r.p),"number"==typeof r.u&&(s+=r.u)),2>s?e=(h=(a.length-this.a)/this.o[2]/2*258|0)i&&(this.c.length=i),r=this.c),this.buffer=r},W.prototype.k=function(){var t,r,i=this.input;if(t=this.q.k(),this.a=this.q.a,this.A){r=(i[this.a++]<<24|i[this.a++]<<16|i[this.a++]<<8|i[this.a++])>>>0;var e=t;if("string"==typeof e){var h,s,a=e.split("");for(h=0,s=a.length;h>>0;e=a}for(var n,f=1,o=0,l=e.length,u=0;0>>0)throw Error("invalid adler-32 checksum")}return t};var ha=8;r("Zlib.Inflate",W),r("Zlib.Inflate.prototype.decompress",W.prototype.k);var Y,Z,$,ia,X={ADAPTIVE:B.s,BLOCK:B.t};if(Object.keys)Y=Object.keys(X);else for(Z in Y=[],$=0,X)Y[$++]=Z;for($=0,ia=Y.length;$ 0.0 ? height : base, 1);\n\t\t\t\tfloat len = pos.z * u_height_factor / tan(u_altitude);\n\t\t\t\tpos.x += cos(u_azimuth) * len;\n\t\t\t\tpos.y += sin(u_azimuth) * len;\n\t\t\t\tpos.z = 0.0;\n\t\t\t\tgl_Position = u_matrix * pos;\n\t\t\t}\n\t\t\t"),i.compileShader(e);const r=i.createShader(i.FRAGMENT_SHADER);i.shaderSource(r,"\n\t\t\tvoid main() {\n\t\t\t\tgl_FragColor = vec4(0.0, 0.0, 0.0, 0.7);\n\t\t\t}\n\t\t\t"),i.compileShader(r),this.program=i.createProgram(),i.attachShader(this.program,e),i.attachShader(this.program,r),i.linkProgram(this.program),i.validateProgram(this.program),this.uMatrix=i.getUniformLocation(this.program,"u_matrix"),this.uHeightFactor=i.getUniformLocation(this.program,"u_height_factor"),this.uAltitude=i.getUniformLocation(this.program,"u_altitude"),this.uAzimuth=i.getUniformLocation(this.program,"u_azimuth"),this.aPos=i.getAttribLocation(this.program,"a_pos"),this.aNormal=i.getAttribLocation(this.program,"a_normal_ed"),this.aBase=i.getAttribLocation(this.program,"a_base"),this.aHeight=i.getAttribLocation(this.program,"a_height")}render(t,i){t.useProgram(this.program);const e=this.map.style.sourceCaches.composite,r=e.getVisibleCoordinates().reverse(),a=map.getLayer(this.buildingsLayerId),o=this.map.painter.context,{lng:s,lat:n}=this.map.getCenter(),h=this.tb.getSunPosition(this.tb.lightDateTime,s,n);t.uniform1f(this.uAltitude,h.altitude>this.minAltitude?h.altitude:0),t.uniform1f(this.uAzimuth,h.azimuth+3*Math.PI/2),t.enable(t.BLEND),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA);t.getExtension("EXT_blend_minmax");t.disable(t.DEPTH_TEST);for(const i of r){const r=e.getTile(i),s=r.getBucket(a);if(!s)continue;const[n,h]=s.programConfigurations.programConfigurations[this.buildingsLayerId]._buffers;t.uniformMatrix4fv(this.uMatrix,!1,i.posMatrix),t.uniform1f(this.uHeightFactor,Math.pow(2,i.overscaledZ)/r.tileSize/8);for(const i of s.segments.get()){const e=o.currentNumAttributes||0,r=2;for(let i=r;i 0.0 ? height : base, 1);\n\t\t\t\tfloat len = pos.z * u_height_factor / tan(u_altitude);\n\t\t\t\tpos.x += cos(u_azimuth) * len;\n\t\t\t\tpos.y += sin(u_azimuth) * len;\n\t\t\t\tpos.z = 0.0;\n\t\t\t\tgl_Position = u_matrix * pos;\n\t\t\t}\n\t\t\t"),i.compileShader(e);const r=i.createShader(i.FRAGMENT_SHADER);i.shaderSource(r,"\n\t\t\tvoid main() {\n\t\t\t\tgl_FragColor = vec4(0.0, 0.0, 0.0, 0.7);\n\t\t\t}\n\t\t\t"),i.compileShader(r),this.program=i.createProgram(),i.attachShader(this.program,e),i.attachShader(this.program,r),i.linkProgram(this.program),i.validateProgram(this.program),this.uMatrix=i.getUniformLocation(this.program,"u_matrix"),this.uHeightFactor=i.getUniformLocation(this.program,"u_height_factor"),this.uAltitude=i.getUniformLocation(this.program,"u_altitude"),this.uAzimuth=i.getUniformLocation(this.program,"u_azimuth"),this.aPos=i.getAttribLocation(this.program,"a_pos"),this.aNormal=i.getAttribLocation(this.program,"a_normal_ed"),this.aBase=i.getAttribLocation(this.program,"a_base"),this.aHeight=i.getAttribLocation(this.program,"a_height")}render(t,i){t.useProgram(this.program);const e=this.map.style.sourceCaches.composite,r=e.getVisibleCoordinates().reverse(),a=map.getLayer(this.buildingsLayerId),o=this.map.painter.context,{lng:s,lat:n}=this.map.getCenter(),h=this.tb.getSunPosition(this.tb.lightDateTime,[s,n]);t.uniform1f(this.uAltitude,h.altitude>this.minAltitude?h.altitude:0),t.uniform1f(this.uAzimuth,h.azimuth+3*Math.PI/2),t.enable(t.BLEND),t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA);t.getExtension("EXT_blend_minmax");t.disable(t.DEPTH_TEST);for(const i of r){const r=e.getTile(i),s=r.getBucket(a);if(!s)continue;const[n,h]=s.programConfigurations.programConfigurations[this.buildingsLayerId]._buffers;t.uniformMatrix4fv(this.uMatrix,!1,i.posMatrix),t.uniform1f(this.uHeightFactor,Math.pow(2,i.overscaledZ)/r.tileSize/8);for(const i of s.segments.get()){const e=o.currentNumAttributes||0,r=2;for(let i=r;i0?t[t.length-1]:"",smooth:void 0!==r?r.smooth:this.smooth,groupStart:void 0!==r?r.groupEnd:0,groupEnd:-1,groupCount:-1,inherited:!1,clone:function(e){var t={index:"number"==typeof e?e:this.index,name:this.name,mtllib:this.mtllib,smooth:this.smooth,groupStart:0,groupEnd:-1,groupCount:-1,inherited:!1};return t.clone=this.clone.bind(t),t}};return this.materials.push(s),s},currentMaterial:function(){if(this.materials.length>0)return this.materials[this.materials.length-1]},_finalize:function(e){var t=this.currentMaterial();if(t&&-1===t.groupEnd&&(t.groupEnd=this.geometry.vertices.length/3,t.groupCount=t.groupEnd-t.groupStart,t.inherited=!1),e&&this.materials.length>1)for(var r=this.materials.length-1;r>=0;r--)this.materials[r].groupCount<=0&&this.materials.splice(r,1);return e&&0===this.materials.length&&this.materials.push({name:"",smooth:this.smooth}),t}},r&&r.name&&"function"==typeof r.clone){var s=r.clone(0);s.inherited=!0,this.object.materials.push(s)}this.objects.push(this.object)},finalize:function(){this.object&&"function"==typeof this.object._finalize&&this.object._finalize(!0)},parseVertexIndex:function(e,t){var r=parseInt(e,10);return 3*(r>=0?r-1:r+t/3)},parseNormalIndex:function(e,t){var r=parseInt(e,10);return 3*(r>=0?r-1:r+t/3)},parseUVIndex:function(e,t){var r=parseInt(e,10);return 2*(r>=0?r-1:r+t/2)},addVertex:function(e,t,r){var s=this.vertices,i=this.object.geometry.vertices;i.push(s[e+0],s[e+1],s[e+2]),i.push(s[t+0],s[t+1],s[t+2]),i.push(s[r+0],s[r+1],s[r+2])},addVertexPoint:function(e){var t=this.vertices;this.object.geometry.vertices.push(t[e+0],t[e+1],t[e+2])},addVertexLine:function(e){var t=this.vertices;this.object.geometry.vertices.push(t[e+0],t[e+1],t[e+2])},addNormal:function(e,t,r){var s=this.normals,i=this.object.geometry.normals;i.push(s[e+0],s[e+1],s[e+2]),i.push(s[t+0],s[t+1],s[t+2]),i.push(s[r+0],s[r+1],s[r+2])},addFaceNormal:function(e,t,r){var s=this.vertices,h=this.object.geometry.normals;i.fromArray(s,e),a.fromArray(s,t),o.fromArray(s,r),l.subVectors(o,a),n.subVectors(i,a),l.cross(n),l.normalize(),h.push(l.x,l.y,l.z),h.push(l.x,l.y,l.z),h.push(l.x,l.y,l.z)},addColor:function(e,t,r){var s=this.colors,i=this.object.geometry.colors;void 0!==s[e]&&i.push(s[e+0],s[e+1],s[e+2]),void 0!==s[t]&&i.push(s[t+0],s[t+1],s[t+2]),void 0!==s[r]&&i.push(s[r+0],s[r+1],s[r+2])},addUV:function(e,t,r){var s=this.uvs,i=this.object.geometry.uvs;i.push(s[e+0],s[e+1]),i.push(s[t+0],s[t+1]),i.push(s[r+0],s[r+1])},addDefaultUV:function(){var e=this.object.geometry.uvs;e.push(0,0),e.push(0,0),e.push(0,0)},addUVLine:function(e){var t=this.uvs;this.object.geometry.uvs.push(t[e+0],t[e+1])},addFace:function(e,t,r,s,i,a,o,n,l){var h=this.vertices.length,c=this.parseVertexIndex(e,h),u=this.parseVertexIndex(t,h),p=this.parseVertexIndex(r,h);if(this.addVertex(c,u,p),this.addColor(c,u,p),void 0!==o&&""!==o){var m=this.normals.length;c=this.parseNormalIndex(o,m),u=this.parseNormalIndex(n,m),p=this.parseNormalIndex(l,m),this.addNormal(c,u,p),this.object.geometry.hasNormalIndices=!0}else this.addFaceNormal(c,u,p);if(void 0!==s&&""!==s){var d=this.uvs.length;c=this.parseUVIndex(s,d),u=this.parseUVIndex(i,d),p=this.parseUVIndex(a,d),this.addUV(c,u,p),this.object.geometry.hasUVIndices=!0}else this.addDefaultUV()},addPointGeometry:function(e){this.object.geometry.type="Points";for(var t=this.vertices.length,r=0,s=e.length;r=7?a.colors.push(parseFloat(d[4]),parseFloat(d[5]),parseFloat(d[6])):a.colors.push(void 0,void 0,void 0);break;case"vn":a.normals.push(parseFloat(d[1]),parseFloat(d[2]),parseFloat(d[3]));break;case"vt":a.uvs.push(parseFloat(d[1]),parseFloat(d[2]))}}else if("f"===l){for(var f=n.substr(1).trim().split(/\s+/),v=[],g=0,b=f.length;g0){var y=E.split("/");v.push(y)}}var j=v[0];for(g=1,b=v.length-1;g1){var z=c[1].trim().toLowerCase();a.object.smooth="0"!==z&&"off"!==z}else a.object.smooth=!0;(q=a.object.currentMaterial())&&(q.smooth=a.object.smooth)}else{if("\0"===n)continue;console.warn('THREE.OBJLoader: Unexpected line: "'+n+'"')}a.finalize();var A=new THREE.Group;A.materialLibraries=[].concat(a.materialLibraries);for(p=0,m=a.objects.length;p0&&(C=!0,_.setAttribute("color",new THREE.Float32BufferAttribute(P.colors,3))),!0===P.hasUVIndices&&_.setAttribute("uv",new THREE.Float32BufferAttribute(P.uvs,2));for(var G,S=[],D=0,J=B.length;D1){for(D=0,J=B.length;De.getObjectByName("model")}),Object.defineProperty(e,"animations",{get(){const t=e.model;return t?t.animations:null}}),o.animationManager.enroll(e),e.setCoords=function(t){if("meters"===e.userData.units){var o=utils.projectedUnitsPerMeter(t[1]);o||(o=1),"number"==typeof(o=Number(o.toFixed(7)))?e.scale.set(o,o,o):e.scale.set(o.x,o.y,o.z)}return e.userData.topMargin&&e.userData.feature&&(t[2]+=(e.userData.feature.properties.height-(e.userData.feature.properties.base_height||e.userData.feature.properties.min_height||0))*e.userData.topMargin),e.coordinates=t,e.set({position:t}),e.modelHeight=e.coordinates[2],e.boxGroup&&e.setBoundingBoxShadowFloor(),e},e.setTranslate=function(t){return e.set({translate:t}),e},e.setRotation=function(t){"number"==typeof t&&(t={z:t});var o={x:utils.radify(t.x)||e.rotation.x,y:utils.radify(t.y)||e.rotation.y,z:utils.radify(t.z)||e.rotation.z};e._setObject({rotation:[o.x,o.y,o.z]})},e.calculateAdjustedPosition=function(t,o,a){let i=t.slice(),n=utils.unprojectFromWorld(e.modelSize);return a?(i[0]-=0!=o.x?n[0]/o.x:0,i[1]-=0!=o.y?n[1]/o.y:0,i[2]-=0!=o.z?n[2]/o.z:0):(i[0]+=0!=o.x?n[0]/o.x:0,i[1]+=0!=o.y?n[1]/o.y:0,i[2]+=0!=o.z?n[2]/o.z:0),i},e.setRotationAxis=function(t){"number"==typeof t&&(t={z:t});let o=e.modelBox(),i=new THREE.Vector3(o.max.x,o.max.y,o.min.z);0!=t.x&&a(e,i,new THREE.Vector3(0,0,1),t.x),0!=t.y&&a(e,i,new THREE.Vector3(0,0,1),t.y),0!=t.z&&a(e,i,new THREE.Vector3(0,0,1),t.z)},Object.defineProperty(e,"scaleGroup",{get:()=>e.getObjectByName("scaleGroup")}),Object.defineProperty(e,"boxGroup",{get:()=>e.getObjectByName("boxGroup")}),Object.defineProperty(e,"boundingBox",{get:()=>e.getObjectByName("boxModel")}),Object.defineProperty(e,"boundingBoxShadow",{get:()=>e.getObjectByName("boxShadow")}),e.drawBoundingBox=function(){let t=e.box3(),o=new THREE.Group;o.name="boxGroup",o.updateMatrixWorld(!0);let a=new THREE.Box3Helper(t,Objects.prototype._defaults.colors.yellow);a.name="boxModel",o.add(a),a.layers.disable(0);let i=t.clone();i.max.z=i.min.z;let n=new THREE.Box3Helper(i,Objects.prototype._defaults.colors.black);n.name="boxShadow",o.add(n),n.layers.disable(0),o.visible=!1,e.scaleGroup.add(o),e.setBoundingBoxShadowFloor()},e.setBoundingBoxShadowFloor=function(){e.boundingBox&&(e.boundingBoxShadow.box.max.z=-e.modelHeight,e.boundingBoxShadow.box.min.z=-e.modelHeight)},e.setAnchor=function(t){const o=e.box3(),a=(o.getSize(new THREE.Vector3),o.getCenter(new THREE.Vector3));switch(e.none={x:0,y:0,z:0},e.center={x:a.x,y:a.y,z:o.min.z},e.bottom={x:a.x,y:o.max.y,z:o.min.z},e.bottomLeft={x:o.max.x,y:o.max.y,z:o.min.z},e.bottomRight={x:o.min.x,y:o.max.y,z:o.min.z},e.top={x:a.x,y:o.min.y,z:o.min.z},e.topLeft={x:o.max.x,y:o.min.y,z:o.min.z},e.topRight={x:o.min.x,y:o.min.y,z:o.min.z},e.left={x:o.max.x,y:a.y,z:o.min.z},e.right={x:o.min.x,y:a.y,z:o.min.z},t){case"center":e.anchor=e.center;break;case"top":e.anchor=e.top;break;case"top-left":e.anchor=e.topLeft;break;case"top-right":e.anchor=e.topRight;break;case"left":e.anchor=e.left;break;case"right":e.anchor=e.right;break;case"bottom":e.anchor=e.bottom;break;case"bottom-left":default:e.anchor=e.bottomLeft;break;case"bottom-right":e.anchor=e.bottomRight;break;case"auto":case"none":e.anchor=e.none}e.model.position.set(-e.anchor.x,-e.anchor.y,-e.anchor.z)},e.setCenter=function(t){if(t&&(0!=t.x||0!=t.y||0!=t.z)){let o=e.getSize();e.anchor={x:-o.x*t.x,y:-o.y*t.y,z:-o.z*t.z},e.model.position.set(-e.anchor.x,-e.anchor.y,-e.anchor.z)}},Object.defineProperty(e,"label",{get:()=>e.getObjectByName("label")}),Object.defineProperty(e,"tooltip",{get:()=>e.getObjectByName("tooltip")}),Object.defineProperty(e,"visibility",{get:()=>e.visible,set(t){let o=t;if("visible"==t||1==t)o=!0,e.label&&(e.label.visible=o);else{if("none"!=t&&0!=t)return;o=!1,e.label&&e.label.alwaysVisible&&(e.label.visible=o),e.tooltip&&(e.tooltip.visible=o)}e.visible!=o&&(e.visible=o,e.model&&e.model.traverse(function(e){"Mesh"!=e.type&&"SkinnedMesh"!=e.type||(o?e.layers.enable(0):e.layers.disable(0)),"LineSegments"==e.type&&e.layers.disableAll()}))}}),e.addLabel=function(t,o=!1,a=e.anchor){t&&e.scaleGroup.add(e.drawLabelHTML(t,o,a))},e.removeLabel=function(){if(e.label){e.label.dispose();let t=e.scaleGroup.children;t.splice(t.indexOf(e.label),1)}},e.drawLabelHTML=function(t,a=!1,i=e.anchor){let n=o.drawLabelHTML(t,Objects.prototype._defaults.label.cssClass);const l=e.box3(),r=l.getSize(new THREE.Vector3);let s=l.max.x,c=l.max.y;l.min.z;e.removeLabel();let p=new CSS2D.CSS2DObject(n);return p.name="label",p.position.set(.5*-r.x-e.model.position.x-i.x+s,.5*-r.y-e.model.position.y-i.y+c,.5*r.z),p.visible=a,p.alwaysVisible=a,p},e.addTooltip=function(t,a=!1,i=e.anchor,n=!0){if(t){let l=o.drawTooltip(t,a);const r=e.box3(),s=r.getSize(new THREE.Vector3);let c={x:r.max.x,y:r.max.y,z:r.min.z};e.removeTooltip();let p=new CSS2D.CSS2DObject(l);p.name="tooltip",p.position.set(.5*-s.x-e.model.position.x-i.x+c.x,.5*-s.y-e.model.position.y-i.y+c.y,s.z),p.visible=!1,p.custom=n,e.scaleGroup.add(p)}},e.removeTooltip=function(){if(e.tooltip){e.tooltip.dispose();let t=e.scaleGroup.children;t.splice(t.indexOf(e.tooltip),1)}};let t=!1;Object.defineProperty(e,"castShadow",{get:()=>t,set(o){if(t!=o){if(e.model.traverse(function(e){e.isMesh&&(e.castShadow=!0)}),o){const t=e.modelSize,a=[t.x,t.y,t.z],i=10*Math.max(...a),n=new THREE.PlaneBufferGeometry(i,i),l=new THREE.ShadowMaterial;l.opacity=.5;let r=new THREE.Mesh(n,l);r.layers.enable(1),r.layers.disable(0),r.receiveShadow=o,e.add(r)}else e.traverse(function(t){t.isMesh&&t.material instanceof THREE.ShadowMaterial&&e.remove(t)});t=o}}});let i=!1;Object.defineProperty(e,"receiveShadow",{get:()=>i,set(t){i!=t&&(e.model.traverse(function(e){e.isMesh&&(e.receiveShadow=!0)}),i=t)}});let n=!1;Object.defineProperty(e,"wireframe",{get:()=>n,set(t){n!=t&&(e.model.traverse(function(e){if("Mesh"==e.type||"SkinnedMesh"==e.type){let o=[];Array.isArray(e.material)?o=e.material:o.push(e.material),o.forEach(function(e){e.opacity=t?.5:1,e.wireframe=t}),t?(e.layers.disable(0),e.layers.enable(1)):(e.layers.disable(1),e.layers.enable(0))}"LineSegments"==e.type&&e.layers.disableAll()}),n=t,e.dispatchEvent(new CustomEvent("Wireframed",{detail:e,bubbles:!0,cancelable:!0})))}});let l=!1;Object.defineProperty(e,"selected",{get:()=>l,set(t){t?(e.boxGroup&&(e.boundingBox.material=Objects.prototype._defaults.materials.boxSelectedMaterial,e.boundingBox.parent.visible=!0,e.boundingBox.layers.enable(1),e.boundingBoxShadow.layers.enable(1)),e.label&&!e.label.alwaysVisible&&(e.label.visible=!0)):(e.boxGroup&&(e.boundingBox.parent.visible=!1,e.boundingBox.layers.disable(1),e.boundingBoxShadow.layers.disable(1),e.boundingBox.material=Objects.prototype._defaults.materials.boxNormalMaterial,e.remove(e.boxGroup)),e.label&&!e.label.alwaysVisible&&(e.label.visible=!1)),e.tooltip&&(e.tooltip.visible=t),l!=t&&(l=t,e.dispatchEvent(new CustomEvent("SelectedChange",{detail:e,bubbles:!0,cancelable:!0})))}});let r=!1;Object.defineProperty(e,"over",{get:()=>r,set(t){t?(e.selected||(e.userData.bbox&&!e.boundingBox&&e.drawBoundingBox(),e.userData.tooltip&&!e.tooltip&&e.addTooltip(e.uuid,!0,e.anchor,!1),e.boxGroup&&(e.boundingBox.material=Objects.prototype._defaults.materials.boxOverMaterial,e.boundingBox.parent.visible=!0,e.boundingBox.layers.enable(1),e.boundingBoxShadow.layers.enable(1))),e.label&&!e.label.alwaysVisible&&(e.label.visible=!0),e.dispatchEvent(new CustomEvent("ObjectMouseOver",{detail:e,bubbles:!0,cancelable:!0}))):(e.selected||(e.boundingBox&&(e.boundingBox.parent.visible=!1,e.boundingBox.layers.disable(1),e.boundingBoxShadow.layers.disable(1),e.boundingBox.material=Objects.prototype._defaults.materials.boxNormalMaterial,e.remove(e.boxGroup),e.tooltip.custom||e.removeTooltip()),e.label&&!e.label.alwaysVisible&&(e.label.visible=!1)),e.dispatchEvent(new CustomEvent("ObjectMouseOut",{detail:e,bubbles:!0,cancelable:!0}))),e.tooltip&&(e.tooltip.visible=t||e.selected),r=t}}),e.box3=function(){let t;if(e.updateMatrix(),e.updateMatrixWorld(!0,!0),e.model){let o=e.clone(!0),a=e.model.clone();if(t=(new THREE.Box3).setFromObject(a),e.parent){let i=new THREE.Matrix4,n=new THREE.Matrix4;e.matrix.extractRotation(i),i.getInverse(n),o.setRotationFromMatrix(n),t=(new THREE.Box3).setFromObject(a)}}return t},e.modelBox=function(){return e.box3()},e.getSize=function(){return e.box3().getSize(new THREE.Vector3(0,0,0))};let s=!1;Object.defineProperty(e,"modelSize",{get:()=>s=e.getSize(),set(e){s!=e&&(s=e)}}),e.modelHeight=0}e.add=function(t){return e.scaleGroup.add(t),t.position.z=e.coordinates[2]?-e.coordinates[2]:0,t},e.remove=function(t){t&&(t.traverse(e=>{if(e.geometry&&e.geometry.dispose(),e.material)if(e.material.isMaterial)i(e.material);else for(const t of e.material)i(t);e.dispose&&e.dispose()}),e.scaleGroup.remove(t),tb.map.repaint=!0)},e.duplicate=function(t){let a=e.clone(!0);if(a.getObjectByName("model").animations=e.animations,a.userData.feature&&(a.userData.feature.properties.uuid=a.uuid),o._addMethods(a),t&&t.scale!=e.userData.scale){a.userData=t,a.userData.isGeoGroup=!0,a.remove(a.boxGroup);const e=utils.types.rotation(t.rotation,[0,0,0]),o=utils.types.scale(t.scale,[1,1,1]);return a.model.rotation.set(e[0],e[1],e[2]),a.model.scale.set(o[0],o[1],o[2]),a.setAnchor(t.anchor),a.setCenter(t.adjustment),a}return a.copyAnchor(e),a},e.copyAnchor=function(t){e.anchor=t.anchor,e.none={x:0,y:0,z:0},e.center=t.center,e.bottom=t.bottom,e.bottomLeft=t.bottomLeft,e.bottomRight=t.bottomRight,e.top=t.top,e.topLeft=t.topLeft,e.topRight=t.topRight,e.left=t.left,e.right=t.right},e.dispose=function(){Objects.prototype.unenroll(e),e.traverse(e=>{if((!e.parent||"world"!=e.parent.name)&&"threeboxObject"!==e.name){if(e.geometry&&e.geometry.dispose(),e.material)if(e.material.isMaterial)i(e.material);else for(const t of e.material)i(t);e.dispose&&e.dispose()}}),e.children=[]};const i=e=>{e.dispose();for(const t of Object.keys(e)){const o=e[t];o&&"object"==typeof o&&"minFilter"in o&&o.dispose()}let t=e;(t.map||t.alphaMap||t.aoMap||t.bumpMap||t.displacementMap||t.emissiveMap||t.envMap||t.lightMap||t.metalnessMap||t.normalMap||t.roughnessMap)&&(t.map&&t.map.dispose(),t.alphaMap&&t.alphaMap.dispose(),t.aoMap&&t.aoMap.dispose(),t.bumpMap&&t.bumpMap.dispose(),t.displacementMap&&t.displacementMap.dispose(),t.emissiveMap&&t.emissiveMap.dispose(),t.envMap&&t.envMap.dispose(),t.lightMap&&t.lightMap.dispose(),t.metalnessMap&&t.metalnessMap.dispose(),t.normalMap&&t.normalMap.dispose(),t.roughnessMap&&t.roughnessMap.dispose())};return e},_makeGroup:function(e,t){let a=new THREE.Group;a.name="scaleGroup",a.add(e);var i=new THREE.Group;if(i.userData=t||{},i.userData.isGeoGroup=!0,i.userData.feature&&(i.userData.feature.properties.uuid=i.uuid),a.length)for(o of a)i.add(o);else i.add(a);return i.name="threeboxObject",i},animationManager:new AnimationManager,drawTooltip:function(e,t=!1){if(e){let o;if(t){let t=document.createElement("div");t.className="mapboxgl-popup-content";let a=document.createElement("strong");a.innerHTML=e,t.appendChild(a);let i=document.createElement("div");i.className="mapboxgl-popup-tip";let n=document.createElement("div");n.className="marker mapboxgl-popup-anchor-bottom",n.appendChild(i),n.appendChild(t),(o=document.createElement("div")).className+="label3D",o.appendChild(n)}else(o=document.createElement("span")).className=this._defaults.tooltip.cssClass,o.innerHTML=e;return o}},drawLabelHTML:function(e,t){let o=document.createElement("div");return o.className+=t,o.innerHTML="string"==typeof e?e:e.outerHTML,o},_defaults:{colors:{red:new THREE.Color(16711680),yellow:new THREE.Color(16776960),green:new THREE.Color(65280),black:new THREE.Color(0)},materials:{boxNormalMaterial:new THREE.LineBasicMaterial({color:new THREE.Color(16711680)}),boxOverMaterial:new THREE.LineBasicMaterial({color:new THREE.Color(16776960)}),boxSelectedMaterial:new THREE.LineBasicMaterial({color:new THREE.Color(65280)})},line:{geometry:null,color:"black",width:1,opacity:1},sphere:{position:[0,0,0],radius:1,sides:20,units:"scene",material:"MeshBasicMaterial",anchor:"bottom-left",bbox:!1,tooltip:!1},label:{htmlElement:null,cssClass:" label3D",alwaysVisible:!1,topMargin:-.5,feature:null},tooltip:{text:"",cssClass:"toolTip text-xs",mapboxStyle:!1,topMargin:0,feature:null},tube:{geometry:null,radius:1,sides:6,units:"scene",material:"MeshBasicMaterial",anchor:"center",bbox:!1,tooltip:!1},extrusion:{footprint:null,base:0,top:100,color:"black",material:"MeshBasicMaterial",scaleToLatitude:!1},loadObj:{type:null,obj:null,units:"scene",scale:1,rotation:0,defaultAnimation:0,anchor:"bottom-left",bbox:!1,tooltip:!1},Object3D:{obj:null,units:"scene",anchor:"bottom-left",bbox:!1,tooltip:!1}},geometries:{line:["LineString"],tube:["LineString"],sphere:["Point"]}},module.exports=exports=Objects;
+const utils=require("../utils/utils.js"),material=require("../utils/material.js"),THREE=require("../three.js"),AnimationManager=require("../animation/AnimationManager.js"),CSS2D=require("./CSS2DRenderer.js");function Objects(){}Objects.prototype={line:function(e){e=utils._validate(e,this._defaults.line);var t=utils.lnglatsToWorld(e.geometry),o=utils.normalizeVertices(t),a=utils.flattenVectors(o.vertices),i=new Float32Array(a),n=new THREE.BufferGeometry;n.setAttribute("position",new THREE.BufferAttribute(i,3));var l=new THREE.LineBasicMaterial({color:16711680,linewidth:21}),r=new THREE.Line(n,l);return r.options=options||{},r.position.copy(o.position),r},extrusion:function(e){},unenroll:function(e,t){t||this.animationManager.unenroll(e)},_addMethods:function(e,t){var o=this;if(t);else{function a(e,t,o,a){let i=utils.radify(a);e.position.sub(t),e.position.applyAxisAngle(o,i),e.position.add(t),e.rotateOnAxis(o,i),tb.map.repaint=!0}e.coordinates||(e.coordinates=[0,0,0]),Object.defineProperty(e,"model",{get:()=>e.getObjectByName("model")}),Object.defineProperty(e,"animations",{get(){const t=e.model;return t?t.animations:null}}),o.animationManager.enroll(e),e.setCoords=function(t){if("meters"===e.userData.units){var o=utils.projectedUnitsPerMeter(t[1]);o||(o=1),"number"==typeof(o=Number(o.toFixed(7)))?e.scale.set(o,o,o):e.scale.set(o.x,o.y,o.z)}return e.userData.topMargin&&e.userData.feature&&(t[2]+=(e.userData.feature.properties.height-(e.userData.feature.properties.base_height||e.userData.feature.properties.min_height||0))*e.userData.topMargin),e.coordinates=t,e.set({position:t}),e.modelHeight=e.coordinates[2],e.boxGroup&&e.setBoundingBoxShadowFloor(),e},e.setTranslate=function(t){return e.set({translate:t}),e},e.setRotation=function(t){"number"==typeof t&&(t={z:t});var o={x:utils.radify(t.x)||e.rotation.x,y:utils.radify(t.y)||e.rotation.y,z:utils.radify(t.z)||e.rotation.z};e._setObject({rotation:[o.x,o.y,o.z]})},e.calculateAdjustedPosition=function(t,o,a){let i=t.slice(),n=utils.unprojectFromWorld(e.modelSize);return a?(i[0]-=0!=o.x?n[0]/o.x:0,i[1]-=0!=o.y?n[1]/o.y:0,i[2]-=0!=o.z?n[2]/o.z:0):(i[0]+=0!=o.x?n[0]/o.x:0,i[1]+=0!=o.y?n[1]/o.y:0,i[2]+=0!=o.z?n[2]/o.z:0),i},e.setRotationAxis=function(t){"number"==typeof t&&(t={z:t});let o=e.modelBox(),i=new THREE.Vector3(o.max.x,o.max.y,o.min.z);0!=t.x&&a(e,i,new THREE.Vector3(0,0,1),t.x),0!=t.y&&a(e,i,new THREE.Vector3(0,0,1),t.y),0!=t.z&&a(e,i,new THREE.Vector3(0,0,1),t.z)},Object.defineProperty(e,"scaleGroup",{get:()=>e.getObjectByName("scaleGroup")}),Object.defineProperty(e,"boxGroup",{get:()=>e.getObjectByName("boxGroup")}),Object.defineProperty(e,"boundingBox",{get:()=>e.getObjectByName("boxModel")}),Object.defineProperty(e,"boundingBoxShadow",{get:()=>e.getObjectByName("boxShadow")}),e.drawBoundingBox=function(){let t=e.box3(),o=new THREE.Group;o.name="boxGroup",o.updateMatrixWorld(!0);let a=new THREE.Box3Helper(t,Objects.prototype._defaults.colors.yellow);a.name="boxModel",o.add(a),a.layers.disable(0);let i=t.clone();i.max.z=i.min.z;let n=new THREE.Box3Helper(i,Objects.prototype._defaults.colors.black);n.name="boxShadow",o.add(n),n.layers.disable(0),o.visible=!1,e.scaleGroup.add(o),e.setBoundingBoxShadowFloor()},e.setBoundingBoxShadowFloor=function(){e.boundingBox&&(e.boundingBoxShadow.box.max.z=-e.modelHeight,e.boundingBoxShadow.box.min.z=-e.modelHeight)},e.setAnchor=function(t){const o=e.box3(),a=(o.getSize(new THREE.Vector3),o.getCenter(new THREE.Vector3));switch(e.none={x:0,y:0,z:0},e.center={x:a.x,y:a.y,z:o.min.z},e.bottom={x:a.x,y:o.max.y,z:o.min.z},e.bottomLeft={x:o.max.x,y:o.max.y,z:o.min.z},e.bottomRight={x:o.min.x,y:o.max.y,z:o.min.z},e.top={x:a.x,y:o.min.y,z:o.min.z},e.topLeft={x:o.max.x,y:o.min.y,z:o.min.z},e.topRight={x:o.min.x,y:o.min.y,z:o.min.z},e.left={x:o.max.x,y:a.y,z:o.min.z},e.right={x:o.min.x,y:a.y,z:o.min.z},t){case"center":e.anchor=e.center;break;case"top":e.anchor=e.top;break;case"top-left":e.anchor=e.topLeft;break;case"top-right":e.anchor=e.topRight;break;case"left":e.anchor=e.left;break;case"right":e.anchor=e.right;break;case"bottom":e.anchor=e.bottom;break;case"bottom-left":default:e.anchor=e.bottomLeft;break;case"bottom-right":e.anchor=e.bottomRight;break;case"auto":case"none":e.anchor=e.none}e.model.position.set(-e.anchor.x,-e.anchor.y,-e.anchor.z)},e.setCenter=function(t){if(t&&(0!=t.x||0!=t.y||0!=t.z)){let o=e.getSize();e.anchor={x:-o.x*t.x,y:-o.y*t.y,z:-o.z*t.z},e.model.position.set(-e.anchor.x,-e.anchor.y,-e.anchor.z)}},Object.defineProperty(e,"label",{get:()=>e.getObjectByName("label")}),Object.defineProperty(e,"tooltip",{get:()=>e.getObjectByName("tooltip")}),Object.defineProperty(e,"visibility",{get:()=>e.visible,set(t){let o=t;if("visible"==t||1==t)o=!0,e.label&&(e.label.visible=o);else{if("none"!=t&&0!=t)return;o=!1,e.label&&e.label.alwaysVisible&&(e.label.visible=o),e.tooltip&&(e.tooltip.visible=o)}e.visible!=o&&(e.visible=o,e.model&&e.model.traverse(function(e){"Mesh"!=e.type&&"SkinnedMesh"!=e.type||(o?e.layers.enable(0):e.layers.disable(0)),"LineSegments"==e.type&&e.layers.disableAll()}))}}),e.addLabel=function(t,o=!1,a=e.anchor){t&&e.scaleGroup.add(e.drawLabelHTML(t,o,a))},e.removeLabel=function(){if(e.label){e.label.dispose();let t=e.scaleGroup.children;t.splice(t.indexOf(e.label),1)}},e.drawLabelHTML=function(t,a=!1,i=e.anchor){let n=o.drawLabelHTML(t,Objects.prototype._defaults.label.cssClass);const l=e.box3(),r=l.getSize(new THREE.Vector3);let s=l.max.x,c=l.max.y;l.min.z;e.removeLabel();let p=new CSS2D.CSS2DObject(n);return p.name="label",p.position.set(.5*-r.x-e.model.position.x-i.x+s,.5*-r.y-e.model.position.y-i.y+c,.5*r.z),p.visible=a,p.alwaysVisible=a,p},e.addTooltip=function(t,a=!1,i=e.anchor,n=!0){if(t){let l=o.drawTooltip(t,a);const r=e.box3(),s=r.getSize(new THREE.Vector3);let c={x:r.max.x,y:r.max.y,z:r.min.z};e.removeTooltip();let p=new CSS2D.CSS2DObject(l);p.name="tooltip",p.position.set(.5*-s.x-e.model.position.x-i.x+c.x,.5*-s.y-e.model.position.y-i.y+c.y,s.z),p.visible=!1,p.custom=n,e.scaleGroup.add(p)}},e.removeTooltip=function(){if(e.tooltip){e.tooltip.dispose();let t=e.scaleGroup.children;t.splice(t.indexOf(e.tooltip),1)}};let t=!1;Object.defineProperty(e,"castShadow",{get:()=>t,set(o){if(t!=o){if(e.model.traverse(function(e){e.isMesh&&(e.castShadow=!0)}),o){const t=e.modelSize,a=[t.x,t.y,t.z],i=10*Math.max(...a),n=new THREE.PlaneBufferGeometry(i,i),l=new THREE.ShadowMaterial;l.opacity=.5;let r=new THREE.Mesh(n,l);r.layers.enable(1),r.layers.disable(0),r.receiveShadow=o,e.add(r)}else e.traverse(function(t){t.isMesh&&t.material instanceof THREE.ShadowMaterial&&e.remove(t)});t=o}}});let i=!1;Object.defineProperty(e,"receiveShadow",{get:()=>i,set(t){i!=t&&(e.model.traverse(function(e){e.isMesh&&(e.receiveShadow=!0)}),i=t)}});let n=!1;Object.defineProperty(e,"wireframe",{get:()=>n,set(t){n!=t&&(e.model.traverse(function(e){if("Mesh"==e.type||"SkinnedMesh"==e.type){let o=[];Array.isArray(e.material)?o=e.material:o.push(e.material),o.forEach(function(e){e.opacity=t?.5:1,e.wireframe=t}),t?(e.layers.disable(0),e.layers.enable(1)):(e.layers.disable(1),e.layers.enable(0))}"LineSegments"==e.type&&e.layers.disableAll()}),n=t,e.dispatchEvent(new CustomEvent("Wireframed",{detail:e,bubbles:!0,cancelable:!0})))}});let l=!1;Object.defineProperty(e,"selected",{get:()=>l,set(t){t?(e.boxGroup&&(e.boundingBox.material=Objects.prototype._defaults.materials.boxSelectedMaterial,e.boundingBox.parent.visible=!0,e.boundingBox.layers.enable(1),e.boundingBoxShadow.layers.enable(1)),e.label&&!e.label.alwaysVisible&&(e.label.visible=!0)):(e.boxGroup&&(e.boundingBox.parent.visible=!1,e.boundingBox.layers.disable(1),e.boundingBoxShadow.layers.disable(1),e.boundingBox.material=Objects.prototype._defaults.materials.boxNormalMaterial,e.remove(e.boxGroup)),e.label&&!e.label.alwaysVisible&&(e.label.visible=!1)),e.tooltip&&(e.tooltip.visible=t),l!=t&&(l=t,e.dispatchEvent(new CustomEvent("SelectedChange",{detail:e,bubbles:!0,cancelable:!0})))}});let r=!1;Object.defineProperty(e,"over",{get:()=>r,set(t){t?(e.selected||(e.userData.bbox&&!e.boundingBox&&e.drawBoundingBox(),e.userData.tooltip&&!e.tooltip&&e.addTooltip(e.uuid,!0,e.anchor,!1),e.boxGroup&&(e.boundingBox.material=Objects.prototype._defaults.materials.boxOverMaterial,e.boundingBox.parent.visible=!0,e.boundingBox.layers.enable(1),e.boundingBoxShadow.layers.enable(1))),e.label&&!e.label.alwaysVisible&&(e.label.visible=!0),e.dispatchEvent(new CustomEvent("ObjectMouseOver",{detail:e,bubbles:!0,cancelable:!0}))):(e.selected||(e.boundingBox&&(e.boundingBox.parent.visible=!1,e.boundingBox.layers.disable(1),e.boundingBoxShadow.layers.disable(1),e.boundingBox.material=Objects.prototype._defaults.materials.boxNormalMaterial,e.remove(e.boxGroup),e.tooltip.custom||e.removeTooltip()),e.label&&!e.label.alwaysVisible&&(e.label.visible=!1)),e.dispatchEvent(new CustomEvent("ObjectMouseOut",{detail:e,bubbles:!0,cancelable:!0}))),e.tooltip&&(e.tooltip.visible=t||e.selected),r=t}}),e.box3=function(){let t;if(e.updateMatrix(),e.updateMatrixWorld(!0,!0),e.model){let o=e.clone(!0),a=e.model.clone();if(t=(new THREE.Box3).setFromObject(a),e.parent){let i=new THREE.Matrix4,n=new THREE.Matrix4;e.matrix.extractRotation(i),i.getInverse(n),o.setRotationFromMatrix(n),t=(new THREE.Box3).setFromObject(a)}}return t},e.modelBox=function(){return e.box3()},e.getSize=function(){return e.box3().getSize(new THREE.Vector3(0,0,0))};let s=!1;Object.defineProperty(e,"modelSize",{get:()=>s=e.getSize(),set(e){s!=e&&(s=e)}}),e.modelHeight=0}e.add=function(t){return e.scaleGroup.add(t),t.position.z=e.coordinates[2]?-e.coordinates[2]:0,t},e.remove=function(t){t&&(t.traverse(e=>{if(e.geometry&&e.geometry.dispose(),e.material)if(e.material.isMaterial)i(e.material);else for(const t of e.material)i(t);e.dispose&&e.dispose()}),e.scaleGroup.remove(t),tb.map.repaint=!0)},e.duplicate=function(t){let a=e.clone(!0);if(a.getObjectByName("model").animations=e.animations,a.userData.feature&&(t&&t.feature&&(a.userData.feature=t.feature),a.userData.feature.properties.uuid=a.uuid),o._addMethods(a),!t||utils.equal(t.scale,e.userData.scale))return a.copyAnchor(e),a;{a.userData=t,a.userData.isGeoGroup=!0,a.remove(a.boxGroup);const e=utils.types.rotation(t.rotation,[0,0,0]),o=utils.types.scale(t.scale,[1,1,1]);return a.model.rotation.set(e[0],e[1],e[2]),a.model.scale.set(o[0],o[1],o[2]),a.setAnchor(t.anchor),a.setCenter(t.adjustment),a}},e.copyAnchor=function(t){e.anchor=t.anchor,e.none={x:0,y:0,z:0},e.center=t.center,e.bottom=t.bottom,e.bottomLeft=t.bottomLeft,e.bottomRight=t.bottomRight,e.top=t.top,e.topLeft=t.topLeft,e.topRight=t.topRight,e.left=t.left,e.right=t.right},e.dispose=function(){Objects.prototype.unenroll(e),e.traverse(e=>{if((!e.parent||"world"!=e.parent.name)&&"threeboxObject"!==e.name){if(e.geometry&&e.geometry.dispose(),e.material)if(e.material.isMaterial)i(e.material);else for(const t of e.material)i(t);e.dispose&&e.dispose()}}),e.children=[]};const i=e=>{e.dispose();for(const t of Object.keys(e)){const o=e[t];o&&"object"==typeof o&&"minFilter"in o&&o.dispose()}let t=e;(t.map||t.alphaMap||t.aoMap||t.bumpMap||t.displacementMap||t.emissiveMap||t.envMap||t.lightMap||t.metalnessMap||t.normalMap||t.roughnessMap)&&(t.map&&t.map.dispose(),t.alphaMap&&t.alphaMap.dispose(),t.aoMap&&t.aoMap.dispose(),t.bumpMap&&t.bumpMap.dispose(),t.displacementMap&&t.displacementMap.dispose(),t.emissiveMap&&t.emissiveMap.dispose(),t.envMap&&t.envMap.dispose(),t.lightMap&&t.lightMap.dispose(),t.metalnessMap&&t.metalnessMap.dispose(),t.normalMap&&t.normalMap.dispose(),t.roughnessMap&&t.roughnessMap.dispose())};return e},_makeGroup:function(e,t){let a=new THREE.Group;a.name="scaleGroup",a.add(e);var i=new THREE.Group;if(i.userData=t||{},i.userData.isGeoGroup=!0,i.userData.feature&&(i.userData.feature.properties.uuid=i.uuid),a.length)for(o of a)i.add(o);else i.add(a);return i.name="threeboxObject",i},animationManager:new AnimationManager,drawTooltip:function(e,t=!1){if(e){let o;if(t){let t=document.createElement("div");t.className="mapboxgl-popup-content";let a=document.createElement("strong");a.innerHTML=e,t.appendChild(a);let i=document.createElement("div");i.className="mapboxgl-popup-tip";let n=document.createElement("div");n.className="marker mapboxgl-popup-anchor-bottom",n.appendChild(i),n.appendChild(t),(o=document.createElement("div")).className+="label3D",o.appendChild(n)}else(o=document.createElement("span")).className=this._defaults.tooltip.cssClass,o.innerHTML=e;return o}},drawLabelHTML:function(e,t){let o=document.createElement("div");return o.className+=t,o.innerHTML="string"==typeof e?e:e.outerHTML,o},_defaults:{colors:{red:new THREE.Color(16711680),yellow:new THREE.Color(16776960),green:new THREE.Color(65280),black:new THREE.Color(0)},materials:{boxNormalMaterial:new THREE.LineBasicMaterial({color:new THREE.Color(16711680)}),boxOverMaterial:new THREE.LineBasicMaterial({color:new THREE.Color(16776960)}),boxSelectedMaterial:new THREE.LineBasicMaterial({color:new THREE.Color(65280)})},line:{geometry:null,color:"black",width:1,opacity:1},sphere:{position:[0,0,0],radius:1,sides:20,units:"scene",material:"MeshBasicMaterial",anchor:"bottom-left",bbox:!1,tooltip:!1},label:{htmlElement:null,cssClass:" label3D",alwaysVisible:!1,topMargin:-.5},tooltip:{text:"",cssClass:"toolTip text-xs",mapboxStyle:!1,topMargin:0,feature:null},tube:{geometry:null,radius:1,sides:6,units:"scene",material:"MeshBasicMaterial",anchor:"center",bbox:!1,tooltip:!1},extrusion:{footprint:null,base:0,top:100,color:"black",material:"MeshBasicMaterial",scaleToLatitude:!1},loadObj:{type:null,obj:null,units:"scene",scale:1,rotation:0,defaultAnimation:0,anchor:"bottom-left",bbox:!1,tooltip:!1},Object3D:{obj:null,units:"scene",anchor:"bottom-left",bbox:!1,tooltip:!1}},geometries:{line:["LineString"],tube:["LineString"],sphere:["Point"]}},module.exports=exports=Objects;
},{"../animation/AnimationManager.js":3,"../three.js":22,"../utils/material.js":24,"../utils/utils.js":26,"./CSS2DRenderer.js":5}],19:[function(require,module,exports){
const utils=require("../utils/utils.js"),material=require("../utils/material.js"),Objects=require("./objects.js"),Object3D=require("./Object3D.js");function Sphere(e){e=utils._validate(e,Objects.prototype._defaults.sphere);let t=new THREE.SphereBufferGeometry(e.radius,e.sides,e.sides),s=material(e),r=new THREE.Mesh(t,s);return new Object3D({obj:r,units:e.units,anchor:e.anchor,adjustment:e.adjustment,bbox:e.bbox,tooltip:e.tooltip})}module.exports=exports=Sphere;
@@ -74,7 +74,7 @@ var utils=require("../utils/utils.js"),THREE=require("../three.js"),defaults={ma
!function(){"use strict";var n=Math.PI,t=Math.sin,e=Math.cos,r=Math.tan,a=Math.asin,u=Math.atan2,o=Math.acos,i=n/180,c=864e5,s=2440588,d=2451545;function f(n){return new Date((n+.5-s)*c)}function h(n){return function(n){return n.valueOf()/c-.5+s}(n)-d}var l=23.4397*i;function M(n,a){return u(t(n)*e(l)-r(a)*t(l),e(n))}function g(n,r){return a(t(r)*e(l)+e(r)*t(l)*t(n))}function v(n,a,o){return u(t(n),e(n)*t(a)-r(o)*e(a))}function w(n,r,u){return a(t(r)*t(u)+e(r)*e(u)*e(n))}function m(n,t){return i*(280.16+360.9856235*n)-t}function D(n){return i*(357.5291+.98560028*n)}function P(e){return e+i*(1.9148*t(e)+.02*t(2*e)+3e-4*t(3*e))+102.9372*i+n}function p(n){var t=P(D(n));return{dec:g(t,0),ra:M(t,0)}}var H={getPosition:function(n,t,e){var r=i*-e,a=i*t,u=h(n),o=p(u),c=m(u,r)-o.ra;return{azimuth:v(c,a,o.dec),altitude:w(c,a,o.dec)}}},T=H.times=[[-.833,"sunrise","sunset"],[-.3,"sunriseEnd","sunsetStart"],[-6,"dawn","dusk"],[-12,"nauticalDawn","nauticalDusk"],[-18,"nightEnd","night"],[6,"goldenHourEnd","goldenHour"]];H.addTime=function(n,t,e){T.push([n,t,e])};var b=9e-4;function E(t,e,r){return b+(t+e)/(2*n)+r}function I(n,e,r){return d+n+.0053*t(e)-.0069*t(2*r)}function k(n,r,a,u,i,c,s){return I(E(function(n,r,a){return o((t(n)-t(r)*t(a))/(e(r)*e(a)))}(n,a,u),r,i),c,s)}function q(n){var r=i*(134.963+13.064993*n),a=i*(93.272+13.22935*n),u=i*(218.316+13.176396*n)+6.289*i*t(r),o=5.128*i*t(a),c=385001-20905*e(r);return{ra:M(u,o),dec:g(u,o),dist:c}}function x(n,t){return new Date(n.valueOf()+t*c/24)}H.getTimes=function(t,e,r,a){var u,o,c,s,d,l=i*-r,M=i*e,v=function(n){return-2.076*Math.sqrt(n)/60}(a=a||0),w=function(t,e){return Math.round(t-b-e/(2*n))}(h(t),l),m=E(0,l,w),p=D(m),H=P(p),q=g(H,0),x=I(m,p,H),y={solarNoon:f(x),nadir:f(x-.5)};for(u=0,o=T.length;u=0&&(v=h-(m=Math.sqrt(M)/(2*Math.abs(d))),w=h+m,Math.abs(v)<=1&&g++,Math.abs(w)<=1&&g++,v<-1&&(v=w)),1===g?P<0?c=p+v:s=p+v:2===g&&(c=p+(l<0?w:v),s=p+(l<0?v:w)),!c||!s);p+=2)P=o;var T={};return c&&(T.rise=x(a,c)),s&&(T.set=x(a,s)),c||s||(T[l>0?"alwaysUp":"alwaysDown"]=!0),T},module.exports=exports=H}();
},{}],26:[function(require,module,exports){
-var THREE=require("../three.js"),Constants=require("./constants.js"),validate=require("./validate.js"),utils={prettyPrintMatrix:function(t){for(var e=0;e<4;e++){var r=[t[e],t[e+4],t[e+8],t[e+12]];console.log(r.map(function(t){return t.toFixed(4)}))}},makePerspectiveMatrix:function(t,e,r,n){var o=new THREE.Matrix4,i=1/Math.tan(t/2),s=1/(r-n),a=[i/e,0,0,0,0,i,0,0,0,0,(n+r)*s,-1,0,0,2*n*r*s,0];return o.elements=a,o},radify:function(t){function e(t){return t=t||0,2*Math.PI*t/360}return"object"==typeof t?t.length>0?t.map(function(t){return e(t)}):[e(t.x),e(t.y),e(t.z)]:e(t)},degreeify:function(t){function e(t){return 360*(t=t||0)/(2*Math.PI)}return"object"==typeof t?[e(t.x),e(t.y),e(t.z)]:e(t)},projectToWorld:function(t){var e=[-Constants.MERCATOR_A*Constants.DEG2RAD*t[0]*Constants.PROJECTION_WORLD_SIZE,-Constants.MERCATOR_A*Math.log(Math.tan(.25*Math.PI+.5*Constants.DEG2RAD*t[1]))*Constants.PROJECTION_WORLD_SIZE];if(t[2]){var r=this.projectedUnitsPerMeter(t[1]);e.push(t[2]*r)}else e.push(0);return new THREE.Vector3(e[0],e[1],e[2])},projectedUnitsPerMeter:function(t){return Math.abs(Constants.WORLD_SIZE/Math.cos(Constants.DEG2RAD*t)/Constants.EARTH_CIRCUMFERENCE)},_scaleVerticesToMeters:function(t,e){for(var r=this.projectedUnitsPerMeter(t[1]),n=(this.projectToWorld(t),0);n0?t.map(function(t){return e(t)}):[e(t.x),e(t.y),e(t.z)]:e(t)},degreeify:function(t){function e(t){return 360*(t=t||0)/(2*Math.PI)}return"object"==typeof t?[e(t.x),e(t.y),e(t.z)]:e(t)},projectToWorld:function(t){var e=[-Constants.MERCATOR_A*Constants.DEG2RAD*t[0]*Constants.PROJECTION_WORLD_SIZE,-Constants.MERCATOR_A*Math.log(Math.tan(.25*Math.PI+.5*Constants.DEG2RAD*t[1]))*Constants.PROJECTION_WORLD_SIZE];if(t[2]){var n=this.projectedUnitsPerMeter(t[1]);e.push(t[2]*n)}else e.push(0);return new THREE.Vector3(e[0],e[1],e[2])},projectedUnitsPerMeter:function(t){return Math.abs(Constants.WORLD_SIZE/Math.cos(Constants.DEG2RAD*t)/Constants.EARTH_CIRCUMFERENCE)},_scaleVerticesToMeters:function(t,e){for(var n=this.projectedUnitsPerMeter(t[1]),r=(this.projectToWorld(t),0);r90))return r;console.error("Latitude must be between -90 and 90")}else console.error("Coords must be an array")},Line:function(r){if(r.constructor===Array){for(const o of r)if(!this.Coords(o))return void console.error("Each coordinate in a line must be a valid Coords type");return r}console.error("Line must be an array")},Rotation:function(r){if(r.constructor===Number)r={z:r};else{if(r.constructor!==Object)return void console.error("Rotation must be an object or a number");for(const o of Object.keys(r)){if(!["x","y","z"].includes(o))return void console.error("Rotation parameters must be x, y, or z");if(r[o].constructor!==Number)return void console.error("Individual rotation values must be numbers")}}return r},Scale:function(r){if(r.constructor===Number)r={x:r,y:r,z:r};else{if(r.constructor!==Object)return void console.error("Scale must be an object or a number");for(const o of Object.keys(r)){if(!["x","y","z"].includes(o))return void console.error("Scale parameters must be x, y, or z");if(r[o].constructor!==Number)return void console.error("Individual scale values must be numbers")}}return r}},module.exports=exports=Validate;
diff --git a/docs/Threebox.md b/docs/Threebox.md
index 6cb6f94e..9df0b088 100755
--- a/docs/Threebox.md
+++ b/docs/Threebox.md
@@ -269,6 +269,21 @@ This method can be used for both a Poligon feature for a Fill Extrusion or a Poi
+#### getSunPosition
+```js
+tb.getSunPosition(date, coords)
+```
+This method gets Sun light position (azimuth, altitude) based on `suncalc.js.` module which calculates the sun position for a given date, time, lng, lat combination.
+
+
+
+#### getSunTimes
+```js
+tb.getSunTimes(date, coords)
+```
+This method gets Sun times based on `suncalc.js.` module which calculates the times for the different light phases (sunrise, sunset, etc..) from a given datetime, lng, lat and alt. This is used to change the map style based on day/night hour.
+
+
#### loadObj
```js
@@ -453,8 +468,6 @@ model/gltf-binary glb
application/octet-stream fbx
```
-
-
#### memory
diff --git a/examples/12-add3dmodel.html b/examples/12-add3dmodel.html
index 97160f8d..c1392a6f 100644
--- a/examples/12-add3dmodel.html
+++ b/examples/12-add3dmodel.html
@@ -55,9 +55,15 @@
mapboxgl.accessToken = config.accessToken;
+ let styles = {
+ day: 'light-v10',
+ night: 'dark-v10'
+ }
+ let selectedStyle = styles.day;
+
var map = (window.map = new mapboxgl.Map({
container: 'map',
- style: 'mapbox://styles/mapbox/outdoors-v11',
+ style: 'mapbox://styles/mapbox/' + selectedStyle,
zoom: 18,
center: [148.9819, -35.3981],
pitch: 60,
@@ -78,7 +84,7 @@
// parameters to ensure the model is georeferenced correctly on the map
var modelOrigin = [148.9819, -35.39847];
- let date = new Date(2020, 7, 14, 0, 39); // change this UTC date time to show the shadow view
+ let date = new Date();//new Date(2020, 7, 14, 0, 39); // change this UTC date time to show the shadow view
let time = date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds();
let timeInput = document.getElementById('time');
timeInput.value = time;
@@ -122,6 +128,7 @@
let dupDate = new Date(date.getTime()); // dup the date to avoid modify the original instance
let dateTZ = new Date(dupDate.toLocaleString("en-US", { timeZone: 'Australia/Sydney' }));
hour.innerHTML = "Sunlight on date/time: " + dateTZ.toLocaleString();
+ changeStyleWithDaylight(date, origin);
tb.update();
}
};
@@ -133,5 +140,20 @@
map.addLayer(createCustomLayer('3d-model', modelOrigin), 'waterway-label');
});
+ function changeStyleWithDaylight(date, origin) {
+ let sunTimes = tb.getSunTimes(date, origin);
+ if (date >= sunTimes.sunriseEnd && date <= sunTimes.sunsetStart) {
+ if (selectedStyle != styles.day) {
+ tb.setStyle("mapbox://styles/mapbox/" + styles.day);
+ selectedStyle = styles.day;
+ }
+ } else {
+ if (selectedStyle != styles.night) {
+ tb.setStyle("mapbox://styles/mapbox/" + styles.night);
+ selectedStyle = styles.night;
+ }
+ }
+ }
+