=-1&&o.z<=1?"":"none";var u={distanceToCameraSquared:m(s,e)};c.objects.set(e,u),c.list.set(e,e),d.parentNode!==l&&l.appendChild(d),e.onAfterRender(i,t,s)}else e.remove();for(var E=0,p=e.children.length;Ethis.maxzoom?this.toggleLabels(!1):this.toggleLabels(!0)},this.toggleLabels=function(e){i!=e&&(this.setVisibility(e,this.scene,this.camera,this.renderer),i=e)},this.setVisibility=function(e,t,i,s){this.renderer.cacheList.forEach(function(n){n.visible!=e&&(e&&n.alwaysVisible||!e)&&(n.visible=e,s.renderObject(n,t,i))})}}module.exports=exports=LabelRenderer;
},{"./CSS2DRenderer.js":5}],7:[function(require,module,exports){
-var Objects=require("./objects.js"),utils=require("../utils/utils.js");function Object3D(t){var e=(t=utils._validate(t,Objects.prototype._defaults.Object3D)).obj,o=new THREE.Group;o.add(e);var r=Objects.prototype._makeGroup(o,t);r.model=t.obj,Objects.prototype._addMethods(r),r.setAnchor(t.anchor),r.setCenter(t.adjustment);let s=r.drawBoundingBox();return o.add(s),r.addTooltip(r.uuid,!0,r.anchor),r.visibility=!0,r}module.exports=exports=Object3D;
+var Objects=require("./objects.js"),utils=require("../utils/utils.js");function Object3D(t){var e=(t=utils._validate(t,Objects.prototype._defaults.Object3D)).obj,o=new THREE.Group;o.add(e);var r=Objects.prototype._makeGroup(o,t);t.obj.name="model",Objects.prototype._addMethods(r),r.setAnchor(t.anchor),r.setCenter(t.adjustment);let s=r.drawBoundingBox();return o.add(s),r.addTooltip(r.uuid,!0,r.anchor),r.visibility=!0,r}module.exports=exports=Object3D;
},{"../utils/utils.js":26,"./objects.js":18}],8:[function(require,module,exports){
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\n\t\t#include \n\t\t#include \n\t\t#include \n\t\t#include \n\n\t\tuniform float linewidth;\n\t\tuniform vec2 resolution;\n\n\t\tattribute vec3 instanceStart;\n\t\tattribute vec3 instanceEnd;\n\n\t\tattribute vec3 instanceColorStart;\n\t\tattribute vec3 instanceColorEnd;\n\n\t\tvarying vec2 vUv;\n\n\t\t#ifdef USE_DASH\n\n\t\t\tuniform float dashScale;\n\t\t\tattribute float instanceDistanceStart;\n\t\t\tattribute float instanceDistanceEnd;\n\t\t\tvarying float vLineDistance;\n\n\t\t#endif\n\n\t\tvoid trimSegment( const in vec4 start, inout vec4 end ) {\n\n\t\t\t// trim end segment so it terminates between the camera plane and the near plane\n\n\t\t\t// conservative estimate of the near plane\n\t\t\tfloat a = projectionMatrix[ 2 ][ 2 ]; // 3nd entry in 3th column\n\t\t\tfloat b = projectionMatrix[ 3 ][ 2 ]; // 3nd entry in 4th column\n\t\t\tfloat nearEstimate = - 0.5 * b / a;\n\n\t\t\tfloat alpha = ( nearEstimate - start.z ) / ( end.z - start.z );\n\n\t\t\tend.xyz = mix( start.xyz, end.xyz, alpha );\n\n\t\t}\n\n\t\tvoid main() {\n\n\t\t\t#ifdef USE_COLOR\n\n\t\t\t\tvColor.xyz = ( position.y < 0.5 ) ? instanceColorStart : instanceColorEnd;\n\n\t\t\t#endif\n\n\t\t\t#ifdef USE_DASH\n\n\t\t\t\tvLineDistance = ( position.y < 0.5 ) ? dashScale * instanceDistanceStart : dashScale * instanceDistanceEnd;\n\n\t\t\t#endif\n\n\t\t\tfloat aspect = resolution.x / resolution.y;\n\n\t\t\tvUv = uv;\n\n\t\t\t// camera space\n\t\t\tvec4 start = modelViewMatrix * vec4( instanceStart, 1.0 );\n\t\t\tvec4 end = modelViewMatrix * vec4( instanceEnd, 1.0 );\n\n\t\t\t// special case for perspective projection, and segments that terminate either in, or behind, the camera plane\n\t\t\t// clearly the gpu firmware has a way of addressing this issue when projecting into ndc space\n\t\t\t// but we need to perform ndc-space calculations in the shader, so we must address this issue directly\n\t\t\t// perhaps there is a more elegant solution -- WestLangley\n\n\t\t\tbool perspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 ); // 4th entry in the 3rd column\n\n\t\t\tif ( perspective ) {\n\n\t\t\t\tif ( start.z < 0.0 && end.z >= 0.0 ) {\n\n\t\t\t\t\ttrimSegment( start, end );\n\n\t\t\t\t} else if ( end.z < 0.0 && start.z >= 0.0 ) {\n\n\t\t\t\t\ttrimSegment( end, start );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// clip space\n\t\t\tvec4 clipStart = projectionMatrix * start;\n\t\t\tvec4 clipEnd = projectionMatrix * end;\n\n\t\t\t// ndc space\n\t\t\tvec2 ndcStart = clipStart.xy / clipStart.w;\n\t\t\tvec2 ndcEnd = clipEnd.xy / clipEnd.w;\n\n\t\t\t// direction\n\t\t\tvec2 dir = ndcEnd - ndcStart;\n\n\t\t\t// account for clip-space aspect ratio\n\t\t\tdir.x *= aspect;\n\t\t\tdir = normalize( dir );\n\n\t\t\t// perpendicular to dir\n\t\t\tvec2 offset = vec2( dir.y, - dir.x );\n\n\t\t\t// undo aspect ratio adjustment\n\t\t\tdir.x /= aspect;\n\t\t\toffset.x /= aspect;\n\n\t\t\t// sign flip\n\t\t\tif ( position.x < 0.0 ) offset *= - 1.0;\n\n\t\t\t// endcaps\n\t\t\tif ( position.y < 0.0 ) {\n\n\t\t\t\toffset += - dir;\n\n\t\t\t} else if ( position.y > 1.0 ) {\n\n\t\t\t\toffset += dir;\n\n\t\t\t}\n\n\t\t\t// adjust for linewidth\n\t\t\toffset *= linewidth;\n\n\t\t\t// adjust for clip-space to screen-space conversion // maybe resolution should be based on viewport ...\n\t\t\toffset /= resolution.y;\n\n\t\t\t// select end\n\t\t\tvec4 clip = ( position.y < 0.5 ) ? clipStart : clipEnd;\n\n\t\t\t// back to clip space\n\t\t\toffset *= clip.w;\n\n\t\t\tclip.xy += offset;\n\n\t\t\tgl_Position = clip;\n\n\t\t\t#include \n\n\t\t\t#include \n\t\t\t#include \n\t\t\t#include \n\n\t\t}\n\t\t",fragmentShader:"\n\t\tuniform vec3 diffuse;\n\t\tuniform float opacity;\n\n\t\t#ifdef USE_DASH\n\n\t\t\tuniform float dashSize;\n\t\t\tuniform float gapSize;\n\n\t\t#endif\n\n\t\tvarying float vLineDistance;\n\n\t\t#include \n\t\t#include \n\t\t#include \n\t\t#include \n\t\t#include \n\n\t\tvarying vec2 vUv;\n\n\t\tvoid main() {\n\n\t\t\t#include \n\n\t\t\t#ifdef USE_DASH\n\n\t\t\t\tif ( vUv.y < 0.5 || vUv.y > 0.5 ) discard; // discard endcaps\n\n\t\t\t\tif ( mod( vLineDistance, dashSize + gapSize ) > dashSize ) discard; // todo - FIX\n\n\t\t\t#endif\n\n\t\t\tif ( vUv.y < 0.5 || vUv.y > 0.5 ) {\n\n\t\t\t\tfloat a = vUv.x - 0.5;\n\t\t\t\tfloat b = vUv.y - 0.5;\n\t\t\t\tfloat len2 = a * a + b * b;\n\n\t\t\t\tif ( len2 > 0.25 ) discard;\n\n\t\t\t}\n\n\t\t\tvec4 diffuseColor = vec4( diffuse, opacity );\n\n\t\t\t#include \n\t\t\t#include \n\n\t\t\tgl_FragColor = vec4( diffuseColor.rgb, opacity );\n\n\t\t\t#include \n\t\t\t#include \n\t\t\t#include \n\t\t\t#include \n\n\t\t}\n\t\t"},THREE.LineMaterial=function(t){var e=THREE.UniformsUtils.clone(THREE.ShaderLib.line.uniforms);e.opacity.value=t.opacity,THREE.ShaderMaterial.call(this,{type:"LineMaterial",uniforms:e,vertexShader:THREE.ShaderLib.line.vertexShader,fragmentShader:THREE.ShaderLib.line.fragmentShader}),this.dashed=!1,Object.defineProperties(this,{color:{enumerable:!0,get:function(){return this.uniforms.diffuse.value},set:function(t){this.uniforms.diffuse.value=t}},linewidth:{enumerable:!0,get:function(){return this.uniforms.linewidth.value},set:function(t){this.uniforms.linewidth.value=t}},dashScale:{enumerable:!0,get:function(){return this.uniforms.dashScale.value},set:function(t){this.uniforms.dashScale.value=t}},dashSize:{enumerable:!0,get:function(){return this.uniforms.dashSize.value},set:function(t){this.uniforms.dashSize.value=t}},gapSize:{enumerable:!0,get:function(){return this.uniforms.gapSize.value},set:function(t){this.uniforms.gapSize.value=t}},resolution:{enumerable:!0,get:function(){return this.uniforms.resolution.value},set:function(t){this.uniforms.resolution.value.copy(t)}}}),this.setValues(t)},THREE.LineMaterial.prototype=Object.create(THREE.ShaderMaterial.prototype),THREE.LineMaterial.prototype.constructor=THREE.LineMaterial,THREE.LineMaterial.prototype.isLineMaterial=!0,THREE.LineMaterial.prototype.copy=function(t){return THREE.ShaderMaterial.prototype.copy.call(this,t),this.color.copy(t.color),this.linewidth=t.linewidth,this.resolution=t.resolution,this},THREE.LineSegments2=function(t,e){THREE.Mesh.call(this),this.type="LineSegments2",this.geometry=void 0!==t?t:new THREE.LineSegmentsGeometry,this.material=void 0!==e?e:new THREE.LineMaterial({color:16777215*Math.random()})},THREE.LineSegments2.prototype=Object.assign(Object.create(THREE.Mesh.prototype),{constructor:THREE.LineSegments2,isLineSegments2:!0,computeLineDistances:function(){var t=new THREE.Vector3,e=new THREE.Vector3;return function(){for(var n=this.geometry,i=n.attributes.instanceStart,r=n.attributes.instanceEnd,o=new Float32Array(2*i.data.count),a=0,s=0,c=i.data.count;a{let t;switch(e.type){case"mtl":r=r.children[0];break;case"gltf":case"dae":t=r.animations,r=r.scene;break;case"fbx":t=r.animations}var l=utils.types.rotation(e.rotation,[0,0,0]),s=utils.types.scale(e.scale,[1,1,1]);r.rotation.set(l[0],l[1],l[2]),r.scale.set(s[0],s[1],s[2]),e.normalize&&function(e){e.traverse(function(e){if(e.isMesh){let a;"MeshStandardMaterial"==e.material.type?(e.material.metalness&&(e.material.metalness*=.1),e.material.glossiness&&(e.material.glossiness*=.25),a=new THREE.Color(12,12,12)):"MeshPhongMaterial"==e.material.type&&(e.material.shininess=.1,a=new THREE.Color(20,20,20)),e.material.specular&&e.material.specular.isColor&&(e.material.specular=a)}})}(r);var d=new THREE.Group;d.add(r);var i=Objects.prototype._makeGroup(d,e);i.model=r,i.animations=t,Objects.prototype._addMethods(i),i.setAnchor(e.anchor),i.setCenter(e.adjustment);let n=i.drawBoundingBox();d.add(n),i.addTooltip(i.uuid,!0,i.anchor),a(i),o(i),i.idle()},()=>null,a=>{console.error("Could not load model file: "+e.obj+" \n "+a.stack),o("Error loading the model")})},()=>null,e=>{console.warn("No material file found for SymbolLayer3D model "+m)})}module.exports=exports=loadObj;
+var utils=require("../utils/utils.js"),Objects=require("./objects.js");const OBJLoader=require("./loaders/OBJLoader.js"),MTLLoader=require("./loaders/MTLLoader.js"),FBXLoader=require("./loaders/FBXLoader.js"),GLTFLoader=require("./loaders/GLTFLoader.js"),ColladaLoader=require("./loaders/ColladaLoader.js"),objLoader=new OBJLoader,materialLoader=new MTLLoader,gltfLoader=new GLTFLoader,fbxLoader=new FBXLoader,daeLoader=new ColladaLoader;function loadObj(e,a,o){if(void 0===e)return console.error("Invalid options provided to loadObj()");e=utils._validate(e,Objects.prototype._defaults.loadObj),this.loaded=!1;var r;switch(e.type||(e.type="mtl"),e.type){case"mtl":r=objLoader;break;case"gltf":r=gltfLoader;break;case"fbx":r=fbxLoader;break;case"dae":r=daeLoader}materialLoader.load(e.mtl,function(t){t&&"mtl"==e.type&&(t.preload(),r.setMaterials(t));r.load(e.obj,r=>{let t=[];switch(e.type){case"mtl":r=r.children[0];break;case"gltf":case"dae":t=r.animations,r=r.scene;break;case"fbx":t=r.animations}r.animations=t;var l=utils.types.rotation(e.rotation,[0,0,0]),s=utils.types.scale(e.scale,[1,1,1]);r.rotation.set(l[0],l[1],l[2]),r.scale.set(s[0],s[1],s[2]),e.normalize&&function(e){e.traverse(function(e){if(e.isMesh){let a;"MeshStandardMaterial"==e.material.type?(e.material.metalness&&(e.material.metalness*=.1),e.material.glossiness&&(e.material.glossiness*=.25),a=new THREE.Color(12,12,12)):"MeshPhongMaterial"==e.material.type&&(e.material.shininess=.1,a=new THREE.Color(20,20,20)),e.material.specular&&e.material.specular.isColor&&(e.material.specular=a)}})}(r),r.name="model";var d=new THREE.Group;d.name="group",d.add(r);var i=Objects.prototype._makeGroup(d,e);i.name="object",i.animations=t,Objects.prototype._addMethods(i),i.setAnchor(e.anchor),i.setCenter(e.adjustment);i.animations;let n=i.drawBoundingBox();d.add(n),i.addTooltip(i.uuid,!0,i.anchor),a(i),o(i),i.idle()},()=>null,a=>{console.error("Could not load model file: "+e.obj+" \n "+a.stack),o("Error loading the model")})},()=>null,e=>{console.warn("No material file found for SymbolLayer3D model "+m)})}module.exports=exports=loadObj;
},{"../utils/utils.js":26,"./loaders/ColladaLoader.js":13,"./loaders/FBXLoader.js":14,"./loaders/GLTFLoader.js":15,"./loaders/MTLLoader.js":16,"./loaders/OBJLoader.js":17,"./objects.js":18}],13:[function(require,module,exports){
const THREE=require("../../three.js");THREE.ColladaLoader=function(e){THREE.Loader.call(this,e)},THREE.ColladaLoader.prototype=Object.assign(Object.create(THREE.Loader.prototype),{constructor:THREE.ColladaLoader,load:function(e,t,r,a){var n=this,i=""===n.path?THREE.LoaderUtils.extractUrlBase(e):n.path,s=new THREE.FileLoader(n.manager);s.setPath(n.path),s.load(e,function(r){try{t(n.parse(r,i))}catch(t){a?a(t):console.error(t),n.manager.itemError(e)}},r,a)},options:{set convertUpAxis(e){console.warn("THREE.ColladaLoader: options.convertUpAxis() has been removed. Up axis is converted automatically.")}},parse:function(e,t){function r(e,t){for(var r=[],a=e.childNodes,n=0,i=a.length;n0&&t.push(new THREE.VectorKeyframeTrack(a+".position",n,i)),s.length>0&&t.push(new THREE.QuaternionKeyframeTrack(a+".quaternion",n,s)),o.length>0&&t.push(new THREE.VectorKeyframeTrack(a+".scale",n,o)),t}function T(e,t,r){var a,n,i,s=!0;for(n=0,i=e.length;n=0;){var a=e[t];if(null!==a.value[r])return a;t--}return null}function x(e,t,r){for(;t>>0));switch(r=r.toLowerCase()){case"tga":t=De;break;default:t=We}return t}(r);if(void 0!==n){var i=n.load(r),s=e.extra;if(void 0!==s&&void 0!==s.technique&&!1===o(s.technique)){var c=s.technique;i.wrapS=c.wrapU?THREE.RepeatWrapping:THREE.ClampToEdgeWrapping,i.wrapT=c.wrapV?THREE.RepeatWrapping:THREE.ClampToEdgeWrapping,i.offset.set(c.offsetU||0,c.offsetV||0),i.repeat.set(c.repeatU||1,c.repeatV||1)}else i.wrapS=THREE.RepeatWrapping,i.wrapT=THREE.RepeatWrapping;return i}return console.warn("THREE.ColladaLoader: Loader for texture %s not found.",r),null}return console.warn("THREE.ColladaLoader: Couldn't create texture with ID:",e.id),null}r.name=e.name||"";var c=n.parameters;for(var l in c){var d=c[l];switch(l){case"diffuse":d.color&&r.color.fromArray(d.color),d.texture&&(r.map=s(d.texture));break;case"specular":d.color&&r.specular&&r.specular.fromArray(d.color),d.texture&&(r.specularMap=s(d.texture));break;case"bump":d.texture&&(r.normalMap=s(d.texture));break;case"ambient":d.texture&&(r.lightMap=s(d.texture));break;case"shininess":d.float&&r.shininess&&(r.shininess=d.float);break;case"emission":d.color&&r.emissive&&r.emissive.fromArray(d.color),d.texture&&(r.emissiveMap=s(d.texture))}}var u=c.transparent,h=c.transparency;if(void 0===h&&u&&(h={float:1}),void 0===u&&h&&(u={opaque:"A_ONE",data:{color:[1,1,1,1]}}),u&&h)if(u.data.texture)r.transparent=!0;else{var m=u.data.color;switch(u.opaque){case"A_ONE":r.opacity=m[3]*h.float;break;case"RGB_ZERO":r.opacity=1-m[0]*h.float;break;case"A_ZERO":r.opacity=1-m[3]*h.float;break;case"RGB_ONE":r.opacity=m[0]*h.float;break;default:console.warn('THREE.ColladaLoader: Invalid opaque type "%s" of transparent tag.',u.opaque)}r.opacity<1&&(r.transparent=!0)}return void 0!==i&&void 0!==i.technique&&1===i.technique.double_sided&&(r.side=THREE.DoubleSide),r}function X(e){return f(Ke.materials[e],J)}function K(e){for(var t=0;t0?c+d:c;t.inputs[u]={id:o,offset:l},t.stride=Math.max(t.stride,l+1),"TEXCOORD"===c&&(t.hasUV=!0);break;case"vcount":t.vcount=i(n.textContent);break;case"p":t.p=i(n.textContent)}}return t}function oe(e){for(var t=0,r=0,a=e.length;r0&&t0&&h.setAttribute("position",new THREE.Float32BufferAttribute(n.array,n.stride)),i.array.length>0&&h.setAttribute("normal",new THREE.Float32BufferAttribute(i.array,i.stride)),c.array.length>0&&h.setAttribute("color",new THREE.Float32BufferAttribute(c.array,c.stride)),s.array.length>0&&h.setAttribute("uv",new THREE.Float32BufferAttribute(s.array,s.stride)),o.array.length>0&&h.setAttribute("uv2",new THREE.Float32BufferAttribute(o.array,o.stride)),l.length>0&&h.setAttribute("skinIndex",new THREE.Float32BufferAttribute(l,d)),u.length>0&&h.setAttribute("skinWeight",new THREE.Float32BufferAttribute(u,f)),a.data=h,a.type=e[0].type,a.materialKeys=m,a}function de(e,t,r,a){var n=e.p,i=e.stride,s=e.vcount;function o(e){for(var t=n[e+r]*l,i=t+l;t4)for(var g=1,b=h-2;g<=b;g++){m=d+i*g,p=d+i*(g+1);o(d+0*i),o(m),o(p)}d+=i*h}else for(u=0,f=n.length;u=t.limits.max&&(t.static=!0),t.middlePosition=(t.limits.min+t.limits.max)/2,t}function ve(e){for(var t={sid:e.getAttribute("sid"),name:e.getAttribute("name")||"",attachments:[],transforms:[]},r=0;ra.limits.max||t0?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;Dt,set(e){t=e}}),Object.defineProperty(e,"boundingBoxShadow",{get:()=>i,set(e){i=e}}),e.drawBoundingBox=function(){let t=e.box3(),o=new THREE.Group;o.name="BoxGrid",o.updateMatrixWorld(!0);let a=new THREE.Box3Helper(t,Objects.prototype._defaults.colors.yellow);a.name="BoxModel",o.add(a),a.layers.disable(0),e.boundingBox=a;let i=t.clone();i.max.z=i.min.z;let n=new THREE.Box3Helper(i,Objects.prototype._defaults.colors.black);return n.name="BoxShadow",o.add(n),n.layers.disable(0),e.boundingBoxShadow=n,o.visible=!1,o},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:()=>n,set(e){n=e}}),Object.defineProperty(e,"tooltip",{get:()=>l,set(e){l=e}}),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.children[0].add(e.drawLabelHTML(t,o,a))},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,d=l.max.y;l.min.z;return e.label&&(e.label.remove,e.label=null),e.label=new CSS2D.CSS2DObject(n),e.label.position.set(.5*-r.x-e.model.position.x-i.x+s,.5*-r.y-e.model.position.y-i.y+d,.5*r.z),e.label.visible=a,e.label.alwaysVisible=a,e.label},e.addTooltip=function(t,a=!1,i=e.anchor){if(t){let n=o.drawTooltip(t,a);const l=e.box3(),r=l.getSize(new THREE.Vector3);let s={x:l.max.x,y:l.max.y,z:l.min.z};e.tooltip&&(e.tooltip.remove,e.tooltip=null),e.tooltip=new CSS2D.CSS2DObject(n),e.tooltip.position.set(.5*-r.x-e.model.position.x-i.x+s.x,.5*-r.y-e.model.position.y-i.y+s.y,r.z),e.tooltip.visible=!1,e.children[0].add(e.tooltip)}};let r=!1;Object.defineProperty(e,"castShadow",{get:()=>r,set(t){if(r!=t){if(e.model.traverse(function(e){e.isMesh&&(e.castShadow=!0)}),t){const o=e.modelSize,a=[o.x,o.y,o.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=t,e.add(r)}else e.traverse(function(t){t.isMesh&&t.material instanceof THREE.ShadowMaterial&&e.remove(t)});r=t}}});let s=!1;Object.defineProperty(e,"receiveShadow",{get:()=>s,set(t){s!=t&&(e.model.traverse(function(e){e.isMesh&&(e.receiveShadow=!0)}),s=t)}});let d=!1;Object.defineProperty(e,"wireframe",{get:()=>d,set(t){d!=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()}),d=t,e.dispatchEvent(new CustomEvent("Wireframed",{detail:e,bubbles:!0,cancelable:!0})))}});let c=!1;Object.defineProperty(e,"selected",{get:()=>c,set(t){t?(e.boundingBox&&(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.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.label&&!e.label.alwaysVisible&&(e.label.visible=!1)),e.tooltip&&(e.tooltip.visible=t),c!=t&&(c=t,e.dispatchEvent(new CustomEvent("SelectedChange",{detail:e,bubbles:!0,cancelable:!0})))}});let p=!1;Object.defineProperty(e,"over",{get:()=>p,set(t){t?(e.selected||e.boundingBox&&(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.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),p=t}}),e.box3=function(){let t;if(e.updateMatrix(),e.updateMatrixWorld(!0,!0),e.model){let o=e.clone(!0);if(o.model=e.model.clone(),t=(new THREE.Box3).setFromObject(o.model),e.parent){let a=new THREE.Matrix4,i=new THREE.Matrix4;e.matrix.extractRotation(a),a.getInverse(i),o.setRotationFromMatrix(i),t=(new THREE.Box3).setFromObject(o.model)}}return t},e.modelBox=function(){return e.box3()},e.getSize=function(){return e.box3().getSize(new THREE.Vector3(0,0,0))};let b=!1;Object.defineProperty(e,"modelSize",{get:()=>b=e.getSize(),set(e){b!=e&&(b=e)}}),e.modelHeight=0}e.add=function(t){return e.children[0].add(t),t.position.z=e.coordinates[2]?-e.coordinates[2]:0,t},e.remove=function(t){e.children[0].remove(t),tb.map.repaint=!0},e.duplicate=function(){var t=e.clone(!0);return t.userData=e.userData,t.model=t.children[0].children[0],t.animations=t.model.animations,o._addMethods(t),t.deepCopy(e),t},e.deepCopy=function(t){return e.anchor=t.anchor,e.bottom=t.bottom,e.bottomLeft=t.bottomLeft,e.bottomRight=t.bottomRight,e.center=t.center,e.left=t.left,e.right=t.right,e.top=t.top,e.topLeft=t.topLeft,e.topRight=t.topRight,e.boundingBox=e.children[0].children[1].children[0],e.boundingBoxShadow=e.children[0].children[1].children[1],e.tooltip=e.children[0].children[2],e},e.dispose=function(){e.traverse(e=>{if(e.isMesh)if(e.geometry.dispose(),e.material.isMaterial)i(e.material);else for(const t of e.material)i(t)}),e.label&&e.label.dispose(),e.tooltip&&e.tooltip.dispose(),e.model&&(e.model={})};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){var a=new THREE.Group;if(a.userData=t||{},a.userData.isGeoGroup=!0,a.userData.feature&&(a.userData.feature.properties.uuid=a.uuid),e.length)for(o of e)a.add(o);else a.add(e);return utils._flipMaterialSides(e),a},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"},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"},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"},Object3D:{obj:null,units:"scene",anchor:"bottom-left"}},geometries:{line:["LineString"],tube:["LineString"],sphere:["Point"]}},module.exports=exports=Objects;
+var utils=require("../utils/utils.js"),material=require("../utils/material.js");const 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}let t;e.coordinates||(e.coordinates=[0,0,0]),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.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,"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="BoxGrid",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);return n.name="BoxShadow",o.add(n),n.layers.disable(0),o.visible=!1,o},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,"model",{get:()=>e.getObjectByName("model")}),Object.defineProperty(e,"animations",{get:()=>t,set(e){t=e}}),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.children[0].add(e.drawLabelHTML(t,o,a))},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,d=l.max.y;l.min.z;e.label&&e.label.remove;let c=new CSS2D.CSS2DObject(n);return c.name="label",c.position.set(.5*-r.x-e.model.position.x-i.x+s,.5*-r.y-e.model.position.y-i.y+d,.5*r.z),c.visible=a,c.alwaysVisible=a,c},e.addTooltip=function(t,a=!1,i=e.anchor){if(t){let n=o.drawTooltip(t,a);const l=e.box3(),r=l.getSize(new THREE.Vector3);let s={x:l.max.x,y:l.max.y,z:l.min.z};e.tooltip&&e.tooltip.remove;let d=new CSS2D.CSS2DObject(n);d.name="tooltip",d.position.set(.5*-r.x-e.model.position.x-i.x+s.x,.5*-r.y-e.model.position.y-i.y+s.y,r.z),d.visible=!1,e.children[0].add(d)}};let i=!1;Object.defineProperty(e,"castShadow",{get:()=>i,set(t){if(i!=t){if(e.model.traverse(function(e){e.isMesh&&(e.castShadow=!0)}),t){const o=e.modelSize,a=[o.x,o.y,o.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=t,e.add(r)}else e.traverse(function(t){t.isMesh&&t.material instanceof THREE.ShadowMaterial&&e.remove(t)});i=t}}});let n=!1;Object.defineProperty(e,"receiveShadow",{get:()=>n,set(t){n!=t&&(e.model.traverse(function(e){e.isMesh&&(e.receiveShadow=!0)}),n=t)}});let l=!1;Object.defineProperty(e,"wireframe",{get:()=>l,set(t){l!=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()}),l=t,e.dispatchEvent(new CustomEvent("Wireframed",{detail:e,bubbles:!0,cancelable:!0})))}});let r=!1;Object.defineProperty(e,"selected",{get:()=>r,set(t){t?(e.boundingBox&&(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.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.label&&!e.label.alwaysVisible&&(e.label.visible=!1)),e.tooltip&&(e.tooltip.visible=t),r!=t&&(r=t,e.dispatchEvent(new CustomEvent("SelectedChange",{detail:e,bubbles:!0,cancelable:!0})))}});let s=!1;Object.defineProperty(e,"over",{get:()=>s,set(t){t?(e.selected||e.boundingBox&&(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.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),s=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 d=!1;Object.defineProperty(e,"modelSize",{get:()=>d=e.getSize(),set(e){d!=e&&(d=e)}}),e.modelHeight=0}e.add=function(t){return e.children[0].add(t),t.position.z=e.coordinates[2]?-e.coordinates[2]:0,t},e.remove=function(t){e.children[0].remove(t),tb.map.repaint=!0},e.duplicate=function(t){let a=e.clone(!0);return a.userData=t||e.userData,o._addMethods(a),a.deepCopy(e),a},e.deepCopy=function(t){return 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},e.dispose=function(){Objects.prototype.unenroll(e),e.traverse(e=>{if(!e.parent||"world"!=e.parent.name){if(e.isMesh)if(e.geometry.dispose(),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){var a=new THREE.Group;if(a.userData=t||{},a.userData.isGeoGroup=!0,a.userData.feature&&(a.userData.feature.properties.uuid=a.uuid),e.length)for(o of e)a.add(o);else a.add(e);return utils._flipMaterialSides(e),a},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"},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"},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"},Object3D:{obj:null,units:"scene",anchor:"bottom-left"}},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){
var 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);var t=new THREE.SphereBufferGeometry(e.radius,e.sides,e.sides),r=material(e),s=new THREE.Mesh(t,r);return new Object3D({obj:s,units:e.units,anchor:e.anchor,adjustment:e.adjustment})}module.exports=exports=Sphere;
},{"../utils/material.js":24,"../utils/utils.js":26,"./Object3D.js":7,"./objects.js":18}],20:[function(require,module,exports){
-const utils=require("../utils/utils.js"),Objects=require("./objects.js"),CSS2D=require("./CSS2DRenderer.js");function Tooltip(t){if((t=utils._validate(t,Objects.prototype._defaults.tooltip)).text){let o=Objects.prototype.drawTooltip(t.text,t.mapboxStyle),r=new CSS2D.CSS2DObject(o);r.visible=!1;var e=Objects.prototype._makeGroup(r,t);return Objects.prototype._addMethods(e),e.tooltip=r,e}}module.exports=exports=Tooltip;
+const utils=require("../utils/utils.js"),Objects=require("./objects.js"),CSS2D=require("./CSS2DRenderer.js");function Tooltip(t){if((t=utils._validate(t,Objects.prototype._defaults.tooltip)).text){let o=Objects.prototype.drawTooltip(t.text,t.mapboxStyle),r=new CSS2D.CSS2DObject(o);r.visible=!1,r.name="tooltip";var e=Objects.prototype._makeGroup(r,t);return Objects.prototype._addMethods(e),e}}module.exports=exports=Tooltip;
},{"../utils/utils.js":26,"./CSS2DRenderer.js":5,"./objects.js":18}],21:[function(require,module,exports){
var utils=require("../utils/utils.js"),material=require("../utils/material.js"),Objects=require("./objects.js"),THREE=require("../three.js"),Object3D=require("./Object3D.js");function tube(e,t){e=utils._validate(e,Objects.prototype._defaults.tube);var r=utils.lnglatsToWorld(e.geometry),i=utils.normalizeVertices(r),s=tube.prototype.defineCrossSection(e),o=tube.prototype.buildVertices(s,i.vertices,t),a=tube.prototype.buildFaces(o,i.vertices,e),n=material(e),u=new THREE.Mesh(a,n);return new Object3D({obj:u,units:e.units,anchor:e.anchor,adjustment:e.adjustment})}tube.prototype={buildVertices:function(e,t,r){var s=new THREE.PlaneBufferGeometry(99999999999,9999999999),o=new THREE.MeshBasicMaterial({color:16777215,side:THREE.DoubleSide});o.opacity=0;var a=new THREE.Mesh(s,o),n=new THREE.Geometry,u=!1,c=[t[0].clone().normalize()];for(i in t){var l;i=parseFloat(i),t[i+1]&&(l=(new THREE.Vector3).subVectors(t[i+1],t[i]).normalize()),c.push(l)}for(i in c.push(new THREE.Vector3),t){i=parseFloat(i);var E=t[i],d=c[i],p=c[i+1],f=d.clone().add(p).normalize();if(0===i?f=p:i===t.length-1&&(f=d),u){v=[];a.position.copy(E),a.lookAt(f.clone().add(E)),a.updateMatrixWorld(),u.forEach(function(e){var t=new THREE.Raycaster(e,d).intersectObject(a)[0];t?(n.vertices.push(t.point),v.push(t.point)):console.error("Tube geometry failed at vertex "+i+". Consider reducing tube radius, or smoothening out the sharp angle at this vertex")}),u=v}else{var v;(v=e.clone()).lookAt(f),v.vertices.forEach(function(e){n.vertices.push(e.add(E))}),u=v.vertices}}return r.remove(a),n},defineCrossSection:function(e){for(var t=new THREE.Geometry,r=e.sides,i=0;i
+
Threebox performance test
@@ -64,7 +64,7 @@
}
);
-
+
import Stats from 'https://threejs.org/examples/jsm/libs/stats.module.js';
map.on('style.load', function () {
@@ -106,6 +106,8 @@
count: 100
};
+ var model = { obj: 'models/windmill_a/windmill_a.json', type: 'gltf', scale: 0.1 };
+
function initMesh() {
let diff = api.count - tb.world.children.length;
@@ -116,7 +118,6 @@
console.time("(clear)");
for (let j = tb.world.children.length - 1; j >= api.count; j--) {
var obj = tb.world.children[j];
- if (obj.dispose) obj.dispose();
tb.remove(obj);
}
getGeometryTotalLength();
@@ -126,22 +127,23 @@
} else {
var options = {
- obj: 'models/windmill_a/windmill_a.json',
- type: 'gltf',
- scale: 0.1,
+ obj: model.obj,
+ type: model.type,
+ scale: model.scale,
units: 'meters',
rotation: { x: 90, y: 90, z: 0 },
anchor: 'center'
}
- makeNaive(options, diff);
+ if (!processing) makeNaive(options, diff);
}
}
+ let processing = false;
function makeNaive(options, diff) {
-
+ processing = true;
let j = 0;
for (var i = 0; i < diff; i++) {
@@ -158,14 +160,16 @@
let lng = origin[0] + Math.random() * 0.4 - 0.2;
let lat = origin[1] + Math.random() * 0.4 - 0.2;
let alt = origin[2] + Math.random() * 0.4 - 0.2;
- let pdu = model.setCoords([lng, lat, alt]);
- tb.add(pdu);
+ let obj = model.setCoords([lng, lat, alt]);
+ tb.add(obj);
getGeometryTotalLength();
- if (j == diff)
+ if (j == diff) {
console.timeEnd(api.method + ' (build)');
-
+ console.log("Items: " + tb.world.children.length);
+ processing = false;
+ }
})
}
@@ -178,7 +182,7 @@
gui = new GUI();
gui.add(api, 'method', Method).onChange(initMesh);
- gui.add(api, 'count', 1, 1000).step(10).onChange(initMesh);
+ gui.add(api, 'count', 0, 1000).step(10).onChange(initMesh);
var perfFolder = gui.addFolder('Performance');
diff --git a/src/Animation/AnimationManager.js b/src/Animation/AnimationManager.js
index 8351b0de..356f2c3a 100755
--- a/src/Animation/AnimationManager.js
+++ b/src/Animation/AnimationManager.js
@@ -13,6 +13,10 @@ function AnimationManager(map) {
AnimationManager.prototype = {
+ unenroll: function (obj) {
+ this.enrolledObjects.splice(this.enrolledObjects.indexOf(obj), 1);
+ },
+
enroll: function (obj) {
//[jscastro] add the object default animations
@@ -71,7 +75,6 @@ AnimationManager.prototype = {
})
/* Extend the provided object with animation-specific properties and track in the animation manager */
-
this.enrolledObjects.push(obj);
// Give this object its own internal animation queue
@@ -128,7 +131,7 @@ AnimationManager.prototype = {
this.animationQueue
.push(entry);
- map.repaint = true;
+ tb.map.repaint = true;
}
//if no duration set, stop object's existing animations and go to that state immediately
@@ -178,7 +181,7 @@ AnimationManager.prototype = {
this.animationQueue
.push(entry);
- map.repaint = true;
+ tb.map.repaint = true;
return this;
};
@@ -215,7 +218,7 @@ AnimationManager.prototype = {
if (w) this.position.copy(w);
this.updateMatrixWorld();
- map.repaint = true
+ tb.map.repaint = true
};
//[jscastro] play default animation
@@ -238,7 +241,7 @@ AnimationManager.prototype = {
this.animationQueue
.push(entry);
- map.repaint = true
+ tb.map.repaint = true
return this;
}
}
@@ -298,7 +301,7 @@ AnimationManager.prototype = {
// Update the animation mixer and render this frame
obj.mixer.update(0.01);
}
- map.repaint = true;
+ tb.map.repaint = true;
return this;
}
@@ -413,7 +416,7 @@ AnimationManager.prototype = {
object.isPlaying = true;
object.animationMethod = requestAnimationFrame(this.update);
object.mixer.update(object.clock.getDelta());
- map.repaint = true;
+ tb.map.repaint = true;
}
}
diff --git a/src/Threebox.js b/src/Threebox.js
index 781115ca..f601eb0b 100644
--- a/src/Threebox.js
+++ b/src/Threebox.js
@@ -48,7 +48,7 @@ Threebox.prototype = {
this.map = map;
this.map.tb = this; //[jscastro] needed if we want to queryRenderedFeatures from map.onload
- this.objects = new Objects(this.map);
+ this.objects = new Objects();
// Set up a THREE.js scene
this.renderer = new THREE.WebGLRenderer({
@@ -81,7 +81,7 @@ Threebox.prototype = {
this.scene.add(this.world);
this.objectsCache = new Map();
-
+
this.cameraSync = new CameraSync(this.map, this.camera, this.world);
//raycaster for mouse events
@@ -485,7 +485,7 @@ Threebox.prototype = {
cache.promise
.then(obj => {
//console.log("Cloning " + options.obj);
- cb(obj.duplicate());
+ cb(obj.duplicate(options));
})
.catch(err => {
this.objectsCache.delete(options.obj);
@@ -498,7 +498,7 @@ Threebox.prototype = {
loader(options, cb, function (obj) {
//console.log("Loading " + options.obj);
if (obj.duplicate) {
- resolve(obj);
+ resolve(obj.duplicate());
} else {
reject(obj);
}
@@ -675,43 +675,9 @@ Threebox.prototype = {
},
remove: function (obj) {
- //[jscastro] remove also the label if exists dispatching the event removed to fire CSS2DRenderer "removed" listener
- if (obj.label) { obj.label.remove() };
- if (obj.tooltip) { obj.tooltip.remove() };
- obj.traverse(function (o) {
- if (o.isMesh) {
- o.geometry.dispose();
- if (o.material) {
- if (o.material instanceof THREE.MeshFaceMaterial) {
- o.material.materials.forEach(function (m) {
- m.dispose();
- if (m.map) {
- m.map.dispose();
- }
- });
- } else {
- o.material.dispose();
- }
- let m = o.material;
- let md = (m.map || m.alphaMap || m.aoMap || m.bumpMap || m.displacementMap || m.emissiveMap || m.envMap || m.lightMap || m.metalnessMap || m.normalMap || m.roughnessMap)
- if (md) {
- if (m.map) m.map.dispose();
- if (m.alphaMap) m.alphaMap.dispose();
- if (m.aoMap) m.aoMap.dispose();
- if (m.bumpMap) m.bumpMap.dispose();
- if (m.displacementMap) m.displacementMap.dispose();
- if (m.emissiveMap) m.emissiveMap.dispose();
- if (m.envMap) m.envMap.dispose();
- if (m.lightMap) m.lightMap.dispose();
- if (m.metalnessMap) m.metalnessMap.dispose();
- if (m.normalMap) m.normalMap.dispose();
- if (m.roughnessMap) m.roughnessMap.dispose();
- }
- }
- }
- if (o.dispose) o.dispose();
- })
+ obj.dispose()
this.world.remove(obj);
+ obj = null;
},
//[jscastro] this clears tb.world in order to dispose properly the resources
@@ -725,7 +691,6 @@ Threebox.prototype = {
let obj = objects[i];
//if layerId, check the layer to remove, otherwise always remove
if ((layerId && obj.userData.feature.layer === layerId) || !layerId) {
- if (dispose) obj.dispose();
this.remove(obj);
}
}
@@ -888,7 +853,7 @@ Threebox.prototype = {
programs: function () { return this.renderer.info.programs.length },
- version: '2.0.6',
+ version: '2.0.7',
}
diff --git a/src/objects/CSS2DRenderer.js b/src/objects/CSS2DRenderer.js
index f81bddb2..25e8ce13 100644
--- a/src/objects/CSS2DRenderer.js
+++ b/src/objects/CSS2DRenderer.js
@@ -16,6 +16,8 @@ THREE.CSS2DObject = function (element) {
this.dispose = function () {
this.remove();
+ this.element = null;
+ if (this.parent) this.parent.remove(this);
}
this.remove = function () {
diff --git a/src/objects/Object3D.js b/src/objects/Object3D.js
index 3610076d..06dfc104 100644
--- a/src/objects/Object3D.js
+++ b/src/objects/Object3D.js
@@ -9,8 +9,8 @@ function Object3D(options) {
var projScaleGroup = new THREE.Group();
projScaleGroup.add(obj);
var userScaleGroup = Objects.prototype._makeGroup(projScaleGroup, options);
-
- userScaleGroup.model = options.obj;
+ options.obj.name = "model";
+ //userScaleGroup.model = options.obj;
Objects.prototype._addMethods(userScaleGroup);
//[jscastro] calculate automatically the pivotal center of the object
diff --git a/src/objects/label.js b/src/objects/label.js
index e2e269e3..19416f94 100644
--- a/src/objects/label.js
+++ b/src/objects/label.js
@@ -9,12 +9,12 @@ function Label(obj) {
let div = Objects.prototype.drawLabelHTML(obj.htmlElement, obj.cssClass);
let label = new THREE.CSS2DObject(div);
+ label.name = "label";
label.visible = obj.alwaysVisible;
label.alwaysVisible = obj.alwaysVisible;
var userScaleGroup = Objects.prototype._makeGroup(label, obj);
Objects.prototype._addMethods(userScaleGroup);
- userScaleGroup.label = label;
userScaleGroup.visibility = obj.alwaysVisible;
return userScaleGroup;
diff --git a/src/objects/loadObj.js b/src/objects/loadObj.js
index 02f8fa41..2814fa6c 100644
--- a/src/objects/loadObj.js
+++ b/src/objects/loadObj.js
@@ -59,7 +59,7 @@ function loadObj(options, cb, promise) {
loader.load(options.obj, obj => {
//[jscastro] MTL/GLTF/FBX models have a different structure
- let animations;
+ let animations = [];
switch (options.type) {
case "mtl":
obj = obj.children[0];
@@ -73,7 +73,7 @@ function loadObj(options, cb, promise) {
animations = obj.animations;
break;
}
-
+ obj.animations = animations;
// [jscastro] options.rotation was wrongly used
var r = utils.types.rotation(options.rotation, [0, 0, 0]);
var s = utils.types.scale(options.scale, [1, 1, 1]);
@@ -81,11 +81,12 @@ function loadObj(options, cb, promise) {
obj.scale.set(s[0], s[1], s[2]);
// [jscastro] normalize specular/metalness/shininess from meshes in FBX and GLB model as it would need 5 lights to illuminate them properly
if (options.normalize) { normalizeSpecular(obj); }
-
+ obj.name = "model";
var projScaleGroup = new THREE.Group();
+ projScaleGroup.name = "group";
projScaleGroup.add(obj)
var userScaleGroup = Objects.prototype._makeGroup(projScaleGroup, options);
- userScaleGroup.model = obj;
+ userScaleGroup.name = "object";
//[jscastro] assign the animations to the userScaleGroup before enrolling it in AnimationsManager through _addMethods
userScaleGroup.animations = animations;
@@ -95,6 +96,8 @@ function loadObj(options, cb, promise) {
//[jscastro] override the center calculated if the object has adjustments
userScaleGroup.setCenter(options.adjustment);
+ let anim = userScaleGroup.animations;
+
// [jscastro] after adding methods create the bounding box at userScaleGroup but add it to its children for positioning
let boxGrid = userScaleGroup.drawBoundingBox();
projScaleGroup.add(boxGrid);
diff --git a/src/objects/objects.js b/src/objects/objects.js
index ac0794f1..488b4bda 100644
--- a/src/objects/objects.js
+++ b/src/objects/objects.js
@@ -47,6 +47,21 @@ Objects.prototype = {
},
+ unenroll: function (obj, isStatic) {
+ var root = this;
+
+ if (isStatic) {
+
+ }
+
+ else {
+ // Bestow this mesh with animation superpowers and keeps track of its movements in the global animation queue
+ root.animationManager.unenroll(obj);
+
+ }
+
+ },
+
_addMethods: function (obj, isStatic) {
var root = this;
@@ -157,24 +172,22 @@ Objects.prototype = {
model.position.add(point); // re-add the offset
model.rotateOnAxis(axis, theta)
- map.repaint = true;
+ tb.map.repaint = true;
}
let _boundingBox;
//[jscastro] added property for boundingBox helper
Object.defineProperty(obj, 'boundingBox', {
- get() { return _boundingBox; },
- set(value) {
- _boundingBox = value;
+ get() {
+ return obj.getObjectByName("BoxModel");
}
})
let _boundingBoxShadow;
//[jscastro] added property for boundingBox helper
Object.defineProperty(obj, 'boundingBoxShadow', {
- get() { return _boundingBoxShadow; },
- set(value) {
- _boundingBoxShadow = value;
+ get() {
+ return obj.getObjectByName("BoxShadow");
}
})
@@ -190,7 +203,7 @@ Objects.prototype = {
boxModel.name = "BoxModel";
boxGrid.add(boxModel);
boxModel.layers.disable(0); // it makes the object invisible for the raycaster
- obj.boundingBox = boxModel;
+ //obj.boundingBox = boxModel;
//it needs to clone, to avoid changing the object by reference
let bb2 = bb.clone();
@@ -201,7 +214,7 @@ Objects.prototype = {
boxGrid.add(boxShadow);
boxShadow.layers.disable(0); // it makes the object invisible for the raycaster
- obj.boundingBoxShadow = boxShadow;
+ //obj.boundingBoxShadow = boxShadow;
boxGrid.visible = false; // visibility is managed from the parent
return boxGrid;
@@ -280,21 +293,27 @@ Objects.prototype = {
}
let _label;
- //[jscastro] added property for wireframes state
+ //[jscastro] added property for simulated label
Object.defineProperty(obj, 'label', {
- get() { return _label; },
- set(value) {
- _label = value;
- }
+ get() { return obj.getObjectByName("label"); }
});
let _tooltip;
//[jscastro] added property for simulated tooltip
Object.defineProperty(obj, 'tooltip', {
- get() { return _tooltip; },
- set(value) {
- _tooltip = value;
- }
+ get() { return obj.getObjectByName("tooltip"); }
+ });
+
+ //[jscastro] added property for the internal 3D model
+ Object.defineProperty(obj, 'model', {
+ get() { return obj.getObjectByName("model"); }
+ });
+
+ let _animations;
+ //[jscastro] added property for the internal 3D model
+ Object.defineProperty(obj, 'animations', {
+ get() { return _animations},
+ set(value) { _animations = value}
});
//[jscastro] added property to redefine visible, including the label and tooltip
@@ -348,13 +367,14 @@ Objects.prototype = {
const box = obj.box3();
const size = box.getSize(new THREE.Vector3());
let bottomLeft = { x: box.max.x, y: box.max.y, z: box.min.z };
- if (obj.label) { obj.label.remove; obj.label = null; }
- obj.label = new CSS2D.CSS2DObject(div);
- obj.label.position.set(((-size.x * 0.5) - obj.model.position.x - center.x + bottomLeft.x), ((-size.y * 0.5) - obj.model.position.y - center.y + bottomLeft.y), size.z * 0.5); //middle-centered
- obj.label.visible = visible;
- obj.label.alwaysVisible = visible;
-
- return obj.label;
+ if (obj.label) { obj.label.remove; }
+ let label = new CSS2D.CSS2DObject(div);
+ label.name = "label";
+ label.position.set(((-size.x * 0.5) - obj.model.position.x - center.x + bottomLeft.x), ((-size.y * 0.5) - obj.model.position.y - center.y + bottomLeft.y), size.z * 0.5); //middle-centered
+ label.visible = visible;
+ label.alwaysVisible = visible;
+
+ return label;
}
//[jscastro] add tooltip method
@@ -364,12 +384,13 @@ Objects.prototype = {
const box = obj.box3();
const size = box.getSize(new THREE.Vector3());
let bottomLeft = { x: box.max.x, y: box.max.y, z: box.min.z };
- if (obj.tooltip) { obj.tooltip.remove; obj.tooltip = null; }
- obj.tooltip = new CSS2D.CSS2DObject(divToolTip);
- obj.tooltip.position.set(((-size.x * 0.5) - obj.model.position.x - center.x + bottomLeft.x), ((-size.y * 0.5) - obj.model.position.y - center.y + bottomLeft.y), size.z); //top-centered
- obj.tooltip.visible = false; //only visible on mouseover or selected
+ if (obj.tooltip) { obj.tooltip.remove; }
+ let tooltip = new CSS2D.CSS2DObject(divToolTip);
+ tooltip.name = "tooltip";
+ tooltip.position.set(((-size.x * 0.5) - obj.model.position.x - center.x + bottomLeft.x), ((-size.y * 0.5) - obj.model.position.y - center.y + bottomLeft.y), size.z); //top-centered
+ tooltip.visible = false; //only visible on mouseover or selected
//we add it to the first children to get same boxing and position
- obj.children[0].add(obj.tooltip);
+ obj.children[0].add(tooltip);
}
}
@@ -535,9 +556,9 @@ Objects.prototype = {
if (obj.model) {
//let's clone the object before manipulate it
let dup = obj.clone(true);
- dup.model = obj.model.clone();
+ let model = obj.model.clone();
//get the size of the model because the object is translated and has boundingBoxShadow
- bounds = new THREE.Box3().setFromObject(dup.model);
+ bounds = new THREE.Box3().setFromObject(model);
//if the object has parent it's already in the added to world so it's scaled and it could be rotated
if (obj.parent) {
//first, we return the object to it's original position of rotation, extract rotation and apply inversed
@@ -547,7 +568,7 @@ Objects.prototype = {
rm.getInverse(rmi);
dup.setRotationFromMatrix(rmi);
//now the object inside will give us a NAABB Non-Axes Aligned Bounding Box
- bounds = new THREE.Box3().setFromObject(dup.model);
+ bounds = new THREE.Box3().setFromObject(model);
}
}
return bounds;
@@ -595,11 +616,9 @@ Objects.prototype = {
}
//[jscastro] clone + assigning all the attributes
- obj.duplicate = function () {
- var dupe = obj.clone(true);
- dupe.userData = obj.userData;
- dupe.model = dupe.children[0].children[0];
- dupe.animations = dupe.model.animations;
+ obj.duplicate = function (options) {
+ let dupe = obj.clone(true);
+ dupe.userData = options || obj.userData;
root._addMethods(dupe);
dupe.deepCopy(obj);
@@ -609,40 +628,44 @@ Objects.prototype = {
obj.deepCopy = function (o) {
obj.anchor = o.anchor;
+ obj.none = { x: 0, y: 0, z: 0 };
+ obj.center = o.center;
obj.bottom = o.bottom;
obj.bottomLeft = o.bottomLeft;
obj.bottomRight = o.bottomRight;
- obj.center = o.center;
- obj.left = o.left;
- obj.right = o.right;
obj.top = o.top;
obj.topLeft = o.topLeft;
obj.topRight = o.topRight;
- obj.boundingBox = obj.children[0].children[1].children[0];
- obj.boundingBoxShadow = obj.children[0].children[1].children[1];
- obj.tooltip = obj.children[0].children[2];
+ obj.left = o.left;
+ obj.right = o.right;
return obj;
}
obj.dispose = function () {
- obj.traverse(object => {
- if (!object.isMesh) return
- //console.log('dispose geometry!')
- object.geometry.dispose()
+ Objects.prototype.unenroll(obj);
- if (object.material.isMaterial) {
- cleanMaterial(object.material)
- } else {
- // an array of materials
- for (const material of object.material) cleanMaterial(material)
+ obj.traverse(o => {
+ //don't dispose th object itself as it will be recursive
+ if (o.parent && o.parent.name == "world") return;
+ if (o.isMesh) {
+ //console.log('dispose geometry!')
+ o.geometry.dispose();
+
+ if (o.material.isMaterial) {
+ cleanMaterial(o.material)
+ } else {
+ // an array of materials
+ for (const material of o.material) cleanMaterial(material)
+ }
}
+ if (o.dispose) o.dispose();
+
})
- if (obj.label) { obj.label.dispose() };
- if (obj.tooltip) { obj.tooltip.dispose() };
- if (obj.model) { obj.model = {} };
+ obj.children = [];
+
}
const cleanMaterial = material => {
diff --git a/src/objects/tooltip.js b/src/objects/tooltip.js
index e14c4094..4d0b3c02 100644
--- a/src/objects/tooltip.js
+++ b/src/objects/tooltip.js
@@ -12,10 +12,9 @@ function Tooltip(obj) {
let tooltip = new CSS2D.CSS2DObject(divToolTip);
tooltip.visible = false;
+ tooltip.name = "tooltip";
var userScaleGroup = Objects.prototype._makeGroup(tooltip, obj);
Objects.prototype._addMethods(userScaleGroup);
- userScaleGroup.tooltip = tooltip;
-
return userScaleGroup;
}
diff --git a/tests/threebox-tests-bundle.js b/tests/threebox-tests-bundle.js
index c5ffd7b0..f116e104 100644
--- a/tests/threebox-tests-bundle.js
+++ b/tests/threebox-tests-bundle.js
@@ -8992,7 +8992,7 @@ Threebox.prototype = {
this.map = map;
this.map.tb = this; //[jscastro] needed if we want to queryRenderedFeatures from map.onload
- this.objects = new Objects(this.map);
+ this.objects = new Objects();
// Set up a THREE.js scene
this.renderer = new THREE.WebGLRenderer({
@@ -9025,8 +9025,7 @@ Threebox.prototype = {
this.scene.add(this.world);
this.objectsCache = new Map();
- this.primises = new Map();
-
+
this.cameraSync = new CameraSync(this.map, this.camera, this.world);
//raycaster for mouse events
@@ -9430,7 +9429,7 @@ Threebox.prototype = {
cache.promise
.then(obj => {
//console.log("Cloning " + options.obj);
- cb(obj.duplicate());
+ cb(obj.duplicate(options));
})
.catch(err => {
this.objectsCache.delete(options.obj);
@@ -9443,7 +9442,7 @@ Threebox.prototype = {
loader(options, cb, function (obj) {
//console.log("Loading " + options.obj);
if (obj.duplicate) {
- resolve(obj);
+ resolve(obj.duplicate());
} else {
reject(obj);
}
@@ -9620,43 +9619,9 @@ Threebox.prototype = {
},
remove: function (obj) {
- //[jscastro] remove also the label if exists dispatching the event removed to fire CSS2DRenderer "removed" listener
- if (obj.label) { obj.label.remove() };
- if (obj.tooltip) { obj.tooltip.remove() };
- obj.traverse(function (o) {
- if (o.isMesh) {
- o.geometry.dispose();
- if (o.material) {
- if (o.material instanceof THREE.MeshFaceMaterial) {
- o.material.materials.forEach(function (m) {
- m.dispose();
- if (m.map) {
- m.map.dispose();
- }
- });
- } else {
- o.material.dispose();
- }
- let m = o.material;
- let md = (m.map || m.alphaMap || m.aoMap || m.bumpMap || m.displacementMap || m.emissiveMap || m.envMap || m.lightMap || m.metalnessMap || m.normalMap || m.roughnessMap)
- if (md) {
- if (m.map) m.map.dispose();
- if (m.alphaMap) m.alphaMap.dispose();
- if (m.aoMap) m.aoMap.dispose();
- if (m.bumpMap) m.bumpMap.dispose();
- if (m.displacementMap) m.displacementMap.dispose();
- if (m.emissiveMap) m.emissiveMap.dispose();
- if (m.envMap) m.envMap.dispose();
- if (m.lightMap) m.lightMap.dispose();
- if (m.metalnessMap) m.metalnessMap.dispose();
- if (m.normalMap) m.normalMap.dispose();
- if (m.roughnessMap) m.roughnessMap.dispose();
- }
- }
- }
- if (o.dispose) o.dispose();
- })
+ obj.dispose()
this.world.remove(obj);
+ obj = null;
},
//[jscastro] this clears tb.world in order to dispose properly the resources
@@ -9670,7 +9635,6 @@ Threebox.prototype = {
let obj = objects[i];
//if layerId, check the layer to remove, otherwise always remove
if ((layerId && obj.userData.feature.layer === layerId) || !layerId) {
- if (dispose) obj.dispose();
this.remove(obj);
}
}
@@ -9833,7 +9797,7 @@ Threebox.prototype = {
programs: function () { return this.renderer.info.programs.length },
- version: '2.0.6',
+ version: '2.0.7',
}
@@ -9866,6 +9830,10 @@ function AnimationManager(map) {
AnimationManager.prototype = {
+ unenroll: function (obj) {
+ this.enrolledObjects.splice(this.enrolledObjects.indexOf(obj), 1);
+ },
+
enroll: function (obj) {
//[jscastro] add the object default animations
@@ -9924,7 +9892,6 @@ AnimationManager.prototype = {
})
/* Extend the provided object with animation-specific properties and track in the animation manager */
-
this.enrolledObjects.push(obj);
// Give this object its own internal animation queue
@@ -9981,7 +9948,7 @@ AnimationManager.prototype = {
this.animationQueue
.push(entry);
- map.repaint = true;
+ tb.map.repaint = true;
}
//if no duration set, stop object's existing animations and go to that state immediately
@@ -10031,7 +9998,7 @@ AnimationManager.prototype = {
this.animationQueue
.push(entry);
- map.repaint = true;
+ tb.map.repaint = true;
return this;
};
@@ -10068,7 +10035,7 @@ AnimationManager.prototype = {
if (w) this.position.copy(w);
this.updateMatrixWorld();
- map.repaint = true
+ tb.map.repaint = true
};
//[jscastro] play default animation
@@ -10091,7 +10058,7 @@ AnimationManager.prototype = {
this.animationQueue
.push(entry);
- map.repaint = true
+ tb.map.repaint = true
return this;
}
}
@@ -10151,7 +10118,7 @@ AnimationManager.prototype = {
// Update the animation mixer and render this frame
obj.mixer.update(0.01);
}
- map.repaint = true;
+ tb.map.repaint = true;
return this;
}
@@ -10266,7 +10233,7 @@ AnimationManager.prototype = {
object.isPlaying = true;
object.animationMethod = requestAnimationFrame(this.update);
object.mixer.update(object.clock.getDelta());
- map.repaint = true;
+ tb.map.repaint = true;
}
}
@@ -10430,6 +10397,8 @@ THREE.CSS2DObject = function (element) {
this.dispose = function () {
this.remove();
+ this.element = null;
+ if (this.parent) this.parent.remove(this);
}
this.remove = function () {
@@ -10750,8 +10719,8 @@ function Object3D(options) {
var projScaleGroup = new THREE.Group();
projScaleGroup.add(obj);
var userScaleGroup = Objects.prototype._makeGroup(projScaleGroup, options);
-
- userScaleGroup.model = options.obj;
+ options.obj.name = "model";
+ //userScaleGroup.model = options.obj;
Objects.prototype._addMethods(userScaleGroup);
//[jscastro] calculate automatically the pivotal center of the object
@@ -10929,12 +10898,12 @@ function Label(obj) {
let div = Objects.prototype.drawLabelHTML(obj.htmlElement, obj.cssClass);
let label = new THREE.CSS2DObject(div);
+ label.name = "label";
label.visible = obj.alwaysVisible;
label.alwaysVisible = obj.alwaysVisible;
var userScaleGroup = Objects.prototype._makeGroup(label, obj);
Objects.prototype._addMethods(userScaleGroup);
- userScaleGroup.label = label;
userScaleGroup.visibility = obj.alwaysVisible;
return userScaleGroup;
@@ -11999,7 +11968,7 @@ function loadObj(options, cb, promise) {
loader.load(options.obj, obj => {
//[jscastro] MTL/GLTF/FBX models have a different structure
- let animations;
+ let animations = [];
switch (options.type) {
case "mtl":
obj = obj.children[0];
@@ -12013,7 +11982,7 @@ function loadObj(options, cb, promise) {
animations = obj.animations;
break;
}
-
+ obj.animations = animations;
// [jscastro] options.rotation was wrongly used
var r = utils.types.rotation(options.rotation, [0, 0, 0]);
var s = utils.types.scale(options.scale, [1, 1, 1]);
@@ -12021,11 +11990,12 @@ function loadObj(options, cb, promise) {
obj.scale.set(s[0], s[1], s[2]);
// [jscastro] normalize specular/metalness/shininess from meshes in FBX and GLB model as it would need 5 lights to illuminate them properly
if (options.normalize) { normalizeSpecular(obj); }
-
+ obj.name = "model";
var projScaleGroup = new THREE.Group();
+ projScaleGroup.name = "group";
projScaleGroup.add(obj)
var userScaleGroup = Objects.prototype._makeGroup(projScaleGroup, options);
- userScaleGroup.model = obj;
+ userScaleGroup.name = "object";
//[jscastro] assign the animations to the userScaleGroup before enrolling it in AnimationsManager through _addMethods
userScaleGroup.animations = animations;
@@ -12035,6 +12005,8 @@ function loadObj(options, cb, promise) {
//[jscastro] override the center calculated if the object has adjustments
userScaleGroup.setCenter(options.adjustment);
+ let anim = userScaleGroup.animations;
+
// [jscastro] after adding methods create the bounding box at userScaleGroup but add it to its children for positioning
let boxGrid = userScaleGroup.drawBoundingBox();
projScaleGroup.add(boxGrid);
@@ -25138,6 +25110,21 @@ Objects.prototype = {
},
+ unenroll: function (obj, isStatic) {
+ var root = this;
+
+ if (isStatic) {
+
+ }
+
+ else {
+ // Bestow this mesh with animation superpowers and keeps track of its movements in the global animation queue
+ root.animationManager.unenroll(obj);
+
+ }
+
+ },
+
_addMethods: function (obj, isStatic) {
var root = this;
@@ -25248,24 +25235,22 @@ Objects.prototype = {
model.position.add(point); // re-add the offset
model.rotateOnAxis(axis, theta)
- map.repaint = true;
+ tb.map.repaint = true;
}
let _boundingBox;
//[jscastro] added property for boundingBox helper
Object.defineProperty(obj, 'boundingBox', {
- get() { return _boundingBox; },
- set(value) {
- _boundingBox = value;
+ get() {
+ return obj.getObjectByName("BoxModel");
}
})
let _boundingBoxShadow;
//[jscastro] added property for boundingBox helper
Object.defineProperty(obj, 'boundingBoxShadow', {
- get() { return _boundingBoxShadow; },
- set(value) {
- _boundingBoxShadow = value;
+ get() {
+ return obj.getObjectByName("BoxShadow");
}
})
@@ -25281,7 +25266,7 @@ Objects.prototype = {
boxModel.name = "BoxModel";
boxGrid.add(boxModel);
boxModel.layers.disable(0); // it makes the object invisible for the raycaster
- obj.boundingBox = boxModel;
+ //obj.boundingBox = boxModel;
//it needs to clone, to avoid changing the object by reference
let bb2 = bb.clone();
@@ -25292,7 +25277,7 @@ Objects.prototype = {
boxGrid.add(boxShadow);
boxShadow.layers.disable(0); // it makes the object invisible for the raycaster
- obj.boundingBoxShadow = boxShadow;
+ //obj.boundingBoxShadow = boxShadow;
boxGrid.visible = false; // visibility is managed from the parent
return boxGrid;
@@ -25371,21 +25356,27 @@ Objects.prototype = {
}
let _label;
- //[jscastro] added property for wireframes state
+ //[jscastro] added property for simulated label
Object.defineProperty(obj, 'label', {
- get() { return _label; },
- set(value) {
- _label = value;
- }
+ get() { return obj.getObjectByName("label"); }
});
let _tooltip;
//[jscastro] added property for simulated tooltip
Object.defineProperty(obj, 'tooltip', {
- get() { return _tooltip; },
- set(value) {
- _tooltip = value;
- }
+ get() { return obj.getObjectByName("tooltip"); }
+ });
+
+ //[jscastro] added property for the internal 3D model
+ Object.defineProperty(obj, 'model', {
+ get() { return obj.getObjectByName("model"); }
+ });
+
+ let _animations;
+ //[jscastro] added property for the internal 3D model
+ Object.defineProperty(obj, 'animations', {
+ get() { return _animations},
+ set(value) { _animations = value}
});
//[jscastro] added property to redefine visible, including the label and tooltip
@@ -25439,13 +25430,14 @@ Objects.prototype = {
const box = obj.box3();
const size = box.getSize(new THREE.Vector3());
let bottomLeft = { x: box.max.x, y: box.max.y, z: box.min.z };
- if (obj.label) { obj.label.remove; obj.label = null; }
- obj.label = new CSS2D.CSS2DObject(div);
- obj.label.position.set(((-size.x * 0.5) - obj.model.position.x - center.x + bottomLeft.x), ((-size.y * 0.5) - obj.model.position.y - center.y + bottomLeft.y), size.z * 0.5); //middle-centered
- obj.label.visible = visible;
- obj.label.alwaysVisible = visible;
+ if (obj.label) { obj.label.remove; }
+ let label = new CSS2D.CSS2DObject(div);
+ label.name = "label";
+ label.position.set(((-size.x * 0.5) - obj.model.position.x - center.x + bottomLeft.x), ((-size.y * 0.5) - obj.model.position.y - center.y + bottomLeft.y), size.z * 0.5); //middle-centered
+ label.visible = visible;
+ label.alwaysVisible = visible;
- return obj.label;
+ return label;
}
//[jscastro] add tooltip method
@@ -25455,12 +25447,13 @@ Objects.prototype = {
const box = obj.box3();
const size = box.getSize(new THREE.Vector3());
let bottomLeft = { x: box.max.x, y: box.max.y, z: box.min.z };
- if (obj.tooltip) { obj.tooltip.remove; obj.tooltip = null; }
- obj.tooltip = new CSS2D.CSS2DObject(divToolTip);
- obj.tooltip.position.set(((-size.x * 0.5) - obj.model.position.x - center.x + bottomLeft.x), ((-size.y * 0.5) - obj.model.position.y - center.y + bottomLeft.y), size.z); //top-centered
- obj.tooltip.visible = false; //only visible on mouseover or selected
+ if (obj.tooltip) { obj.tooltip.remove; }
+ let tooltip = new CSS2D.CSS2DObject(divToolTip);
+ tooltip.name = "tooltip";
+ tooltip.position.set(((-size.x * 0.5) - obj.model.position.x - center.x + bottomLeft.x), ((-size.y * 0.5) - obj.model.position.y - center.y + bottomLeft.y), size.z); //top-centered
+ tooltip.visible = false; //only visible on mouseover or selected
//we add it to the first children to get same boxing and position
- obj.children[0].add(obj.tooltip);
+ obj.children[0].add(tooltip);
}
}
@@ -25626,9 +25619,9 @@ Objects.prototype = {
if (obj.model) {
//let's clone the object before manipulate it
let dup = obj.clone(true);
- dup.model = obj.model.clone();
+ let model = obj.model.clone();
//get the size of the model because the object is translated and has boundingBoxShadow
- bounds = new THREE.Box3().setFromObject(dup.model);
+ bounds = new THREE.Box3().setFromObject(model);
//if the object has parent it's already in the added to world so it's scaled and it could be rotated
if (obj.parent) {
//first, we return the object to it's original position of rotation, extract rotation and apply inversed
@@ -25638,7 +25631,7 @@ Objects.prototype = {
rm.getInverse(rmi);
dup.setRotationFromMatrix(rmi);
//now the object inside will give us a NAABB Non-Axes Aligned Bounding Box
- bounds = new THREE.Box3().setFromObject(dup.model);
+ bounds = new THREE.Box3().setFromObject(model);
}
}
return bounds;
@@ -25686,11 +25679,9 @@ Objects.prototype = {
}
//[jscastro] clone + assigning all the attributes
- obj.duplicate = function () {
- var dupe = obj.clone(true);
- dupe.userData = obj.userData;
- dupe.model = dupe.children[0].children[0];
- dupe.animations = dupe.model.animations;
+ obj.duplicate = function (options) {
+ let dupe = obj.clone(true);
+ dupe.userData = options || obj.userData;
root._addMethods(dupe);
dupe.deepCopy(obj);
@@ -25700,40 +25691,44 @@ Objects.prototype = {
obj.deepCopy = function (o) {
obj.anchor = o.anchor;
+ obj.none = { x: 0, y: 0, z: 0 };
+ obj.center = o.center;
obj.bottom = o.bottom;
obj.bottomLeft = o.bottomLeft;
obj.bottomRight = o.bottomRight;
- obj.center = o.center;
- obj.left = o.left;
- obj.right = o.right;
obj.top = o.top;
obj.topLeft = o.topLeft;
obj.topRight = o.topRight;
- obj.boundingBox = obj.children[0].children[1].children[0];
- obj.boundingBoxShadow = obj.children[0].children[1].children[1];
- obj.tooltip = obj.children[0].children[2];
+ obj.left = o.left;
+ obj.right = o.right;
return obj;
}
obj.dispose = function () {
- obj.traverse(object => {
- if (!object.isMesh) return
- //console.log('dispose geometry!')
- object.geometry.dispose()
+ Objects.prototype.unenroll(obj);
- if (object.material.isMaterial) {
- cleanMaterial(object.material)
- } else {
- // an array of materials
- for (const material of object.material) cleanMaterial(material)
+ obj.traverse(o => {
+ //don't dispose th object itself as it will be recursive
+ if (o.parent && o.parent.name == "world") return;
+ if (o.isMesh) {
+ //console.log('dispose geometry!')
+ o.geometry.dispose();
+
+ if (o.material.isMaterial) {
+ cleanMaterial(o.material)
+ } else {
+ // an array of materials
+ for (const material of o.material) cleanMaterial(material)
+ }
}
+ if (o.dispose) o.dispose();
+
})
- if (obj.label) { obj.label.dispose() };
- if (obj.tooltip) { obj.tooltip.dispose() };
- if (obj.model) { obj.model = {} };
+ obj.children = [];
+
}
const cleanMaterial = material => {
@@ -25956,10 +25951,9 @@ function Tooltip(obj) {
let tooltip = new CSS2D.CSS2DObject(divToolTip);
tooltip.visible = false;
+ tooltip.name = "tooltip";
var userScaleGroup = Objects.prototype._makeGroup(tooltip, obj);
Objects.prototype._addMethods(userScaleGroup);
- userScaleGroup.tooltip = tooltip;
-
return userScaleGroup;
}