diff --git a/dist/mago3d.js b/dist/mago3d.js index 91b50b09..97a43115 100644 --- a/dist/mago3d.js +++ b/dist/mago3d.js @@ -1,31915 +1,29579 @@ +/* eslint-env jquery */ 'use strict'; /** - * 하늘에 구름을 관리하는 매니저 - * - * @class Atmosphere + * An API that interacts with the on-screen UI. Class name to be modified by APIGateWay or API class + * @class MagoFacade */ -var Atmosphere = function() +/** + * mago3d 활성화/비활성화 + * @param {ManagerFactory} managerFactoryInstance + * @param {Boolean} isShow true = show, false = hide + */ +function changeMagoStateAPI(managerFactoryInstance, isShow) { - if (!(this instanceof Atmosphere)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - this.cloudsManager = new CloudsManager(); - this.shadowBlendingCube = new ShadowBlendingCube(); + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("changeMagoState"); + api.setMagoEnable(isShow); + managerFactoryInstance.callAPI(api); }; /** - * 구름이 땅에 그림자를 그릴때 사용함 - * - * @class ShadowBlendingCube + * Label show/hide + * @param {ManagerFactory} managerFactoryInstance + * @param {Boolean} isShow true = show, false = hide */ -var ShadowBlendingCube = function() +function changeLabelAPI(managerFactoryInstance, isShow) { - if (!(this instanceof ShadowBlendingCube)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - this.vertexMatrix = new VertexMatrix(); - this.tTrianglesMatrix = new TTrianglesMatrix(); - this.init(this.vertexMatrix, this.tTrianglesMatrix); - - this.vboVertexCacheKey; - this.vboIndexCacheKey; - this.indicesCount = 0; -}; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("changeLabel"); + api.setShowLabelInfo(isShow); + managerFactoryInstance.callAPI(api); +} /** - * 구름이 땅에 그림자를 그릴때 초기화 - * - * @param vtxMat 변수 - * @param tTriMat 변수 + * Origin show/hide + * @param {ManagerFactory} managerFactoryInstance + * @param {Boolean} isShow true = show, false = hide */ -ShadowBlendingCube.prototype.init = function(vtxMat, tTriMat) +function changeOriginAPI(managerFactoryInstance, isShow) { - // create a blending cube, with faces inverted.*** - var cubeSideSemiLength = 150.5; - - var r = 0.1; - var g = 0.1; - var b = 0.1; - var alpha = 0.6; - - // Center Bottom of the cube.*** - var vertexList = vtxMat.newVertexList(); - var vertex = vertexList.newVertex(); - vertex.setPosition(0.0, 0.0, -cubeSideSemiLength); - vertex.setColorRGBA(r, g, b, alpha); - - vertex = vertexList.newVertex(); - vertex.setPosition(0.0, 0.0, -cubeSideSemiLength); - vertex.setColorRGBA(r, g, b, alpha); - - vertex = vertexList.newVertex(); - vertex.setPosition(0.0, 0.0, -cubeSideSemiLength); - vertex.setColorRGBA(r, g, b, alpha); - - vertex = vertexList.newVertex(); - vertex.setPosition(0.0, 0.0, -cubeSideSemiLength); - vertex.setColorRGBA(r, g, b, alpha); - - // Bottom of the cube.*** - vertexList = vtxMat.newVertexList(); - vertex = vertexList.newVertex(); - vertex.setPosition(-cubeSideSemiLength, -cubeSideSemiLength, - -cubeSideSemiLength); - vertex.setColorRGBA(r, g, b, alpha); - - vertex = vertexList.newVertex(); - vertex.setPosition(cubeSideSemiLength, -cubeSideSemiLength, - -cubeSideSemiLength); - vertex.setColorRGBA(r, g, b, alpha); - - vertex = vertexList.newVertex(); - vertex.setPosition(cubeSideSemiLength, cubeSideSemiLength, - -cubeSideSemiLength); - vertex.setColorRGBA(r, g, b, alpha); - - vertex = vertexList.newVertex(); - vertex.setPosition(-cubeSideSemiLength, cubeSideSemiLength, - -cubeSideSemiLength); - vertex.setColorRGBA(r, g, b, alpha); - - // Top of the cube.*** - vertexList = vtxMat.newVertexList(); - vertex = vertexList.newVertex(); - vertex.setPosition(-cubeSideSemiLength, -cubeSideSemiLength, - cubeSideSemiLength); - vertex.setColorRGBA(r, g, b, alpha); - - vertex = vertexList.newVertex(); - vertex.setPosition(cubeSideSemiLength, -cubeSideSemiLength, - cubeSideSemiLength); - vertex.setColorRGBA(r, g, b, alpha); - - vertex = vertexList.newVertex(); - vertex.setPosition(cubeSideSemiLength, cubeSideSemiLength, - cubeSideSemiLength); - vertex.setColorRGBA(r, g, b, alpha); - - vertex = vertexList.newVertex(); - vertex.setPosition(-cubeSideSemiLength, cubeSideSemiLength, - cubeSideSemiLength); - vertex.setColorRGBA(r, g, b, alpha); - - // Center Top of the cube.*** - vertexList = vtxMat.newVertexList(); - vertex = vertexList.newVertex(); - vertex.setPosition(0.0, 0.0, cubeSideSemiLength); - vertex.setColorRGBA(r, g, b, alpha); - - vertex = vertexList.newVertex(); - vertex.setPosition(0.0, 0.0, cubeSideSemiLength); - vertex.setColorRGBA(r, g, b, alpha); + if (managerFactoryInstance === null) { return; } - vertex = vertexList.newVertex(); - vertex.setPosition(0.0, 0.0, cubeSideSemiLength); - vertex.setColorRGBA(r, g, b, alpha); + var api = new Mago3D.API("changeOrigin"); + api.setShowOrigin(isShow); + managerFactoryInstance.callAPI(api); +} - vertex = vertexList.newVertex(); - vertex.setPosition(0.0, 0.0, cubeSideSemiLength); - vertex.setColorRGBA(r, g, b, alpha); +/** + * boundingBox show/hide + * @param {ManagerFactory} managerFactoryInstance + * @param {Boolean} isShow true = show, false = hide + */ +function changeBoundingBoxAPI(managerFactoryInstance, isShow) +{ + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("changeBoundingBox"); + api.setShowBoundingBox(isShow); + managerFactoryInstance.callAPI(api); +} - // Now, make the tTrianglesMatrix.*** - vtxMat.makeTTrianglesLateralSidesLOOP(tTriMat); - // tTriMat.invert_trianglesSense(); -}; +/** + * 속성값에 의한 가시화 유무설정 + * 삭제 예정 + * @param {ManagerFactory} managerFactoryInstance + * @param {Boolean} isShow true = 표시, false = 비표시 + */ +function changePropertyRenderingAPI(managerFactoryInstance, isShow, projectId, property) +{ + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("changePropertyRendering"); + api.setShowShadow(isShow); + api.setProjectId(projectId); + api.setProperty(property); + managerFactoryInstance.callAPI(api); +} /** - * 그래픽 카드에 데이터를 올릴때 요청 - * - * @returns floatArray + * 그림자 표시/비표시 + * @param {ManagerFactory} managerFactoryInstance + * @param {Boolean} isShow true = 활성화, false = 비활성화 */ -ShadowBlendingCube.prototype.getVBOVertexColorRGBAFloatArray = function() +function changeShadowAPI(managerFactoryInstance, isShow) { - var floatArray = this.vertexMatrix.getVBOVertexColorRGBAFloatArray(); - return floatArray; -}; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("changeShadow"); + api.setShowShadow(isShow); + managerFactoryInstance.callAPI(api); +} /** - * 그래픽 카드에 데이터를 올릴때 사용(삼각형을 이루어 주는 순서) - * - * @returns shortArray + * color 변경 + * @param {ManagerFactory} managerFactoryInstance + * @param {string} projectId 프로젝트 아이디 + * @param {string} dataKey data key + * @param {string} objectIds object id. 복수개의 경우 , 로 입력 + * @param {string} property 속성값 예)isMain=true + * @param {string} color R, G, B 색깔을 ',' 로 연결한 string 값을 받음. */ -ShadowBlendingCube.prototype.getVBOIndicesShortArray = function() +function changeColorAPI(managerFactoryInstance, projectId, dataKey, objectIds, property, color) { - this.vertexMatrix.setVertexIdxInList(); - var shortArray = this.tTrianglesMatrix.getVBOIndicesShortArray(); - this.indicesCount = shortArray.length; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("changeColor"); + api.setProjectId(projectId); + api.setDataKey(dataKey); + api.setObjectIds(objectIds); + api.setProperty(property); + api.setColor(color); + managerFactoryInstance.callAPI(api); +} - return shortArray; -}; +/** + * Object literal with change Location And Rotation animation option. + * @typedef {Object} animationOption + * @property {string} dutaion optional. + * @property {Boolean} autoChangeRotation optional. If this option is true, your heading, pitch will be ignore, Heading and pitch changes according to the direction. + */ /** - * 구름 매니저 - * - * @class CloudsManager + * location and rotation 변경 + * @param {ManagerFactory} managerFactoryInstance + * @param {string} projectId + * @param {string} dataKey + * @param {string} latitude 위도 + * @param {string} longitude 경도 + * @param {string} height 높이 + * @param {string} heading 좌, 우 + * @param {string} pitch 위, 아래 + * @param {string} roll 좌, 우 기울기 + * @param {animationOption} animationOption animation option */ -var CloudsManager = function() +function changeLocationAndRotationAPI(managerFactoryInstance, projectId, dataKey, latitude, longitude, height, heading, pitch, roll, animationOption) { - if (!(this instanceof CloudsManager)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - this.circularCloudsArray = []; -}; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("changeLocationAndRotation"); + api.setProjectId(projectId); + api.setDataKey(dataKey); + api.setLatitude(latitude); + api.setLongitude(longitude); + api.setElevation(height); + api.setHeading(heading); + api.setPitch(pitch); + api.setRoll(roll); + api.setAnimationOption(animationOption); + managerFactoryInstance.callAPI(api); +} /** - * 원형 구름 생성 - * - * @returns circularCloud + * 마우스 클릭 객체 이동 대상 변경 + * @param {ManagerFactory} managerFactoryInstance + * @param {string} objectMoveMode 0 = All, 1 = object, 2 = None */ -CloudsManager.prototype.newCircularCloud = function() +function changeObjectMoveAPI(managerFactoryInstance, objectMoveMode) { - var circularCloud = new CircularCloud(); - this.circularCloudsArray.push(circularCloud); - return circularCloud; -}; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("changeObjectMove"); + api.setObjectMoveMode(objectMoveMode); + managerFactoryInstance.callAPI(api); +} /** - * 원형 구름 - * - * @class CircularCloud + * 마우스로 이동한 객체 정보를 브라우저내 저장 + * @param {ManagerFactory} managerFactoryInstance + * @param {string} objectMoveMode 0 = All, 1 = object, 2 = None */ -var CircularCloud = function() +function saveObjectMoveAPI(managerFactoryInstance, objectMoveMode) { - if (!(this instanceof CircularCloud)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - this.radius = 200.0; - this.depth = 150.0; - this.numPointsForCicle = 8; - - this.vertexMatrix = new VertexMatrix(); - this.tTrianglesMatrix = new TTrianglesMatrix(); - this.shadowVertexMatrix = new VertexMatrix(); - this.shadowTTrianglesMatrix = new TTrianglesMatrix(); - - this.sunLightDirection = new Point3D(); - this.sunLightDirection.set(1, 1, -5); - this.sunLightDirection.unitary(); - - this.longitude; - this.latitude; - this.altitude; - this.position; - this.positionHIGH; - this.positionLOW; - - this.bbox = new BoundingBox(); - this.cullingPosition; - this.cullingRadius; - - this.vboVertexCacheKey; - this.vboIndexCacheKey; - this.vboShadowVertexCacheKey; - this.vboShadowIndexCacheKey; - this.indicesCount = 0; - - this.rendered = false; // Test.*** - - // SCRATCH.*** SCRATCH.*** SCRATCH.*** SCRATCH.*** SCRATCH.*** SCRATCH.*** - // SCRATCH.*** SCRATCH.*** - this.point3dSC = new Point3D(); - this.vertexSC = new Vertex(); -}; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("saveObjectMove"); + api.setObjectMoveMode(objectMoveMode); + managerFactoryInstance.callAPI(api); +} /** - * 그래픽 카드에 올릴 데이터를 요청 - * - * @returns floatArray + * 브라우저내 모든 마우스 이동 정보를 삭제 + * @param {ManagerFactory} managerFactoryInstance + * @param {string} objectMoveMode 0 = All, 1 = object, 2 = None */ -CircularCloud.prototype.getVBOVertexColorFloatArray = function() +function deleteAllObjectMoveAPI(managerFactoryInstance, objectMoveMode) { - var floatArray; - floatArray = this.vertexMatrix.getVBOVertexColorFloatArray(floatArray); - return floatArray; -}; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("deleteAllObjectMove"); + api.setObjectMoveMode(objectMoveMode); + managerFactoryInstance.callAPI(api); +} /** - * 그래픽 카드에 올릴 데이터를 요청(삼각형) - * - * @returns floatArray + * 브라우저내 모든 색깔 변경 이력을 삭제 + * @param {ManagerFactory} managerFactoryInstance */ -CircularCloud.prototype.getVBOIndicesShortArray = function() +function deleteAllChangeColorAPI(managerFactoryInstance) { - this.vertexMatrix.setVertexIdxInList(); - var shortArray = this.tTrianglesMatrix.getVBOIndicesShortArray(); - this.indicesCount = shortArray.length; - - return shortArray; -}; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("deleteAllChangeColor"); + managerFactoryInstance.callAPI(api); +} /** - * 그래픽 카드에 올릴 데이터를 요청(Vertex) - * - * @returns floatArray + * 이슈 등록 활성화 유무 + * @param {ManagerFactory} managerFactoryInstance + * @param {Boolean} flag true = 활성화, false = 비활성화 */ -CircularCloud.prototype.getVBOShadowVertexFloatArray = function() +function changeInsertIssueModeAPI(managerFactoryInstance, flag) { - var floatArray; - floatArray = this.shadowVertexMatrix.getVBOVertexFloatArray(floatArray); - return floatArray; -}; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("changeInsertIssueMode"); + api.setIssueInsertEnable(flag); + managerFactoryInstance.callAPI(api); +} /** - * 그래픽 카드에 올릴 데이터를 요청(삼삭형 순서) - * - * @returns shortArray + * object 정보 표시 활성화 유무 + * @param {ManagerFactory} managerFactoryInstance + * @param {Boolean} flag true = 활성화, false = 비활성화 */ -CircularCloud.prototype.getVBOShadowIndicesShortArray = function() +function changeObjectInfoViewModeAPI(managerFactoryInstance, flag) { - this.shadowVertexMatrix.setVertexIdxInList(); - var shortArray = this.shadowTTrianglesMatrix.getVBOIndicesShortArray(); - this.indicesCount = shortArray.length; - - return shortArray; -}; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("changeObjectInfoViewMode"); + api.setObjectInfoViewEnable(flag); + managerFactoryInstance.callAPI(api); +} /** - * 로케이션을 따라서 회전 - * - * @param vtxMat - * 변수 + * Object Occlusion culling + * @param {ManagerFactory} managerFactoryInstance + * @param {Boolean} flag true = 활성화, false = 비활성화 + * @param {string} dataKey */ -CircularCloud.prototype.rotateMeshByLocation = function(vtxMat) +function changeOcclusionCullingAPI(managerFactoryInstance, flag, dataKey) { - // we rotate the cloud mesh by longitude, latitude.*** - var matrix = new Matrix4(); - - // 1) Rotation Z. Longitude.*** - matrix.rotationAxisAngDeg(-this.longitude, 0.0, 0.0, 1.0); - vtxMat.transformPointsByMatrix4(matrix); - - // 2) Rotation X'. Latitude.*** - var longitudeRad = this.longitude * Math.PI / 180.0; - - var cloudEquatorialPos = new Point3D(); - var zAxis = new Point3D(); - var pitchAxis; - cloudEquatorialPos.set(Math.cos(longitudeRad), Math.sin(longitudeRad), 0.0); - zAxis.set(0.0, 0.0, 1.0); - pitchAxis = cloudEquatorialPos.crossProduct(zAxis, pitchAxis); - pitchAxis.unitary(); - - // matrix.rotationAxisAngDeg(90.0-this.latitude, Math.cos(longitudeRad-90), - // -Math.sin(longitudeRad-90), 0.0); - matrix.rotationAxisAngDeg(90.0 - this.latitude, pitchAxis.x, pitchAxis.y, - 0.0); - vtxMat.transformPointsByMatrix4(matrix); -}; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("changeOcclusionCulling"); + api.setOcclusionCullingEnable(flag); + api.setDataKey(dataKey); + managerFactoryInstance.callAPI(api); +} /** - * 햇빛 방향으로 시작 + * 1인칭, 3인칭 모드 개발중... + * @param {ManagerFactory} managerFactoryInstance + * @param {Boolean} flag true = 활성화, false = 비활성화 */ -CircularCloud.prototype.doShadowMeshWithSunDirection = function() +function changeFPVModeAPI(managerFactoryInstance, flag) { - var distance = 3000.0; - var vertexList = this.shadowVertexMatrix.getVertexList(5); // Bottom radius - // zero ring.*** - vertexList.translateVertices(this.sunLightDirection.x, - this.sunLightDirection.y, this.sunLightDirection.z, distance); - - vertexList = this.shadowVertexMatrix.getVertexList(4); // Bottom minor - // ring.*** - vertexList.translateVertices(this.sunLightDirection.x, - this.sunLightDirection.y, this.sunLightDirection.z, distance); - - vertexList = this.shadowVertexMatrix.getVertexList(3); // Bottom major - // ring.*** - vertexList.translateVertices(this.sunLightDirection.x, - this.sunLightDirection.y, this.sunLightDirection.z, distance); -}; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("changeFPVMode"); + api.setFPVMode(flag); + managerFactoryInstance.callAPI(api); +} /** - * 구름 생성 - * - * @param logitude - * 경도 - * @param latitude - * 위도 - * @param radius - * 반지름 - * @param depth - * 깊이 - * @param numPointsForCircle - * 동그라미 하나당 점의 갯수 + * 1인칭, 3인칭 모드 개발중... + * @param {ManagerFactory} managerFactoryInstance + * @param {Boolean} flag true = 활성화, false = 비활성화 */ -CircularCloud.prototype.createCloud = function(longitude, latitude, altitude, - radius, depth, numPointsForCircle) +function changeMagoModeAPI(managerFactoryInstance, flag) { - this.longitude = longitude; - this.latitude = latitude; - this.altitude = altitude; - this.radius = radius; - this.depth = depth; - this.numPointsForCicle = numPointsForCircle; - - this.makeMesh(this.vertexMatrix, this.tTrianglesMatrix, - this.shadowVertexMatrix, this.shadowTTrianglesMatrix); - // this.makeMesh(this.shadowVertexMatrix, this.shadowTTrianglesMatrix, - // true); - // this.shadowTTrianglesMatrix.invertTrianglesSense();// TEST!!!!!! - this.doShadowMeshWithSunDirection(); - - this.rotateMeshByLocation(this.vertexMatrix); - this.rotateMeshByLocation(this.shadowVertexMatrix); - - var position = Cesium.Cartesian3.fromDegrees(this.longitude, this.latitude, - this.altitude); - this.position = position; - - // var splitValue = Cesium.EncodedCartesian3.encode(position); - var splitVelueX = Cesium.EncodedCartesian3.encode(position.x); - var splitVelueY = Cesium.EncodedCartesian3.encode(position.y); - var splitVelueZ = Cesium.EncodedCartesian3.encode(position.z); - - this.positionHIGH = new Float32Array([ splitVelueX.high, splitVelueY.high, - splitVelueZ.high ]); - this.positionLOW = new Float32Array([ splitVelueX.low, splitVelueY.low, - splitVelueZ.low ]); - - this.bbox = this.shadowVertexMatrix.getBoundingBox(this.bbox); - var cloudPoint3d; - cloudPoint3d = this.bbox.getCenterPoint(cloudPoint3d); - this.cullingPosition = new Cesium.Cartesian3(cloudPoint3d.x - + this.position.x, cloudPoint3d.y + this.position.y, cloudPoint3d.z - + this.position.z); - this.cullingRadius = this.bbox.getMaxLength() / 2; -}; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("changeMagoMode"); + api.setMagoMode(flag); + managerFactoryInstance.callAPI(api); +} /** - * mesh 생성 - * - * @param vtxMat - * 변수 - * @param tTriMat - * 변수 - * @param shadowVtxMat - * 변수 - * @param shadowTTriMat - * 변수 + * 현재 위치 근처 issue list. false인 경우 clear + * 삭제 예정 + * @param {ManagerFactory} managerFactoryInstance + * @param {Boolean} flag true = 활성화, false = 비활성화 */ -CircularCloud.prototype.makeMesh = function(vtxMat, tTriMat, shadowVtxMat, - shadowTTriMat) +function changeNearGeoIssueListViewModeAPI(managerFactoryInstance, flag) { - // use vertex_matrix.*** - // our cloud has 6 rings. Top ring and the bottom ring has radius zero.*** - var numPointsForRing = 16; - var increAngRad = (2.0 * Math.PI) / numPointsForRing; - var angRad = 0.0; - var vertex; - var shadowVertex; - var semiDepth = this.depth / 2.0; - var x = 0.0; - var y = 0.0; - var randomValue = 0; - // var cloudWhite = 0.98; - - // 1) Top ring. radius zero.*** - var vertexList = vtxMat.newVertexList(); - var shadowVertexList = shadowVtxMat.newVertexList(); - randomValue = 0.9 + 0.3 * Math.random(); - for (var i = 0; i < numPointsForRing; i++) - { - vertex = vertexList.newVertex(); - vertex.setPosition(x, y, semiDepth); - shadowVertex = shadowVertexList.newVertex(); - shadowVertex.setPosition(x, y, -semiDepth * 1.2); - vertex.setColorRGB(randomValue, randomValue, randomValue); - } - - // 2) Top menor_ring.*** - angRad = 0.0; - var menorRingRadius = this.radius * 0.7; - vertexList = vtxMat.newVertexList(); - shadowVertexList = shadowVtxMat.newVertexList(); - for (var i = 0; i < numPointsForRing; i++) - { - // Math.random(); // returns from 0.0 to 1.0.*** - randomValue = (2 + Math.random()) / 2; - vertex = vertexList.newVertex(); - shadowVertex = shadowVertexList.newVertex(); - x = menorRingRadius * Math.cos(angRad) * randomValue; - y = menorRingRadius * Math.sin(angRad) * randomValue; - shadowVertex.setPosition(x, y, -semiDepth * 2); - vertex.setPosition(x, y, semiDepth * 0.8); - randomValue = 0.9 + 0.3 * Math.random(); - vertex.setColorRGB(randomValue, randomValue, randomValue); - angRad += increAngRad; - } - - // 3) Top major_ring.*** - angRad = 0.0; - vertexList = vtxMat.newVertexList(); - shadowVertexList = shadowVtxMat.newVertexList(); - for (var i = 0; i < numPointsForRing; i++) - { - randomValue = (2 + Math.random()) / 2; - vertex = vertexList.newVertex(); - shadowVertex = shadowVertexList.newVertex(); - x = this.radius * Math.cos(angRad) * randomValue; - y = this.radius * Math.sin(angRad) * randomValue; - shadowVertex.setPosition(x, y, -semiDepth * 2); - vertex.setPosition(x, y, semiDepth * 0.4); - - randomValue = 0.9 + 0.3 * Math.random(); - vertex.setColorRGB(randomValue, randomValue, randomValue); - angRad += increAngRad; - } - - // 4) Bottom major_ring.*** - angRad = 0.0; - vertexList = vtxMat.newVertexList(); - shadowVertexList = shadowVtxMat.newVertexList(); - for ( var i = 0; i < numPointsForRing; i++ ) - { - randomValue = (2 + Math.random()) / 2; - vertex = vertexList.newVertex(); - shadowVertex = shadowVertexList.newVertex(); - x = this.radius * Math.cos(angRad) * randomValue; - y = this.radius * Math.sin(angRad) * randomValue; - shadowVertex.setPosition(x, y, -semiDepth * 2); - vertex.setPosition(x, y, -semiDepth * 0.4); - randomValue = 0.8 + 0.3 * Math.random(); - vertex.setColorRGB(randomValue, randomValue, randomValue); - angRad += increAngRad; - } - - // 5) Bottom menor_ring.*** - angRad = 0.0; - menorRingRadius = this.radius * 0.7; - vertexList = vtxMat.newVertexList(); - shadowVertexList = shadowVtxMat.newVertexList(); - for (var i = 0; i < numPointsForRing; i++ ) - { - randomValue = (2 + Math.random()) / 2; - vertex = vertexList.newVertex(); - shadowVertex = shadowVertexList.newVertex(); - x = menorRingRadius * Math.cos(angRad) * randomValue; - y = menorRingRadius * Math.sin(angRad) * randomValue; - vertex.setPosition(x, y, -semiDepth * 0.8); - shadowVertex.setPosition(x, y, -semiDepth * 1.2); - - randomValue = 0.6 + 0.3 * Math.random(); - vertex.setColorRGB(randomValue, randomValue, randomValue); - // vertex.setColorRGB(0.58, 0.58, 0.58); - angRad += increAngRad; - } - - // 6) Bottom ring. radius zero.*** - vertexList = vtxMat.newVertexList(); - shadowVertexList = shadowVtxMat.newVertexList(); - randomValue = 0.6 + 0.3 * Math.random(); - for ( var i = 0; i < numPointsForRing; i++ ) - { - // randomValue = (2+Math.random())/2; - vertex = vertexList.newVertex(); - shadowVertex = shadowVertexList.newVertex(); - vertex.setPosition(0.0, 0.0, -semiDepth); - shadowVertex.setPosition(0.0, 0.0, -semiDepth); - - vertex.setColorRGB(randomValue, randomValue, randomValue); - // vertex.setColorRGB(0.58, 0.58, 0.58); - } - - // Now, make the tTrianglesMatrix.*** - vtxMat.makeTTrianglesLateralSidesLOOP(tTriMat); - shadowVtxMat.makeTTrianglesLateralSidesLOOP(shadowTTriMat); - // tTriMat.invertTrianglesSense(); // No.*** - - // Now, calculate the culling bbox.*** -}; - -'use strict'; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("changeNearGeoIssueListViewMode"); + api.setNearGeoIssueListEnable(flag); + managerFactoryInstance.callAPI(api); +} /** - * 영역 박스 - * @class AuxiliarSegment + * TODO 이건 위에 이슈 등록 활성화, 비활성화 api로 통합이 가능할거 같음 + * issue 등록 geo 정보 관련 상태 변경 + * 확인 필요 + * @param {ManagerFactory} managerFactoryInstance + * @param {string} insertIssueState 이슈 등록 좌표 상태 */ -var AuxiliarSegment = function() -{ - if (!(this instanceof AuxiliarSegment)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - this.point1; //auxSegment.point1 = new WorldWind.Vec3(); - this.point2; //auxSegment.point2 = new WorldWind.Vec3(); -}; - -AuxiliarSegment.prototype.setPoints = function(point1X, point1Y, point1Z, point2X, point2Y, point2Z) +function changeInsertIssueStateAPI(managerFactoryInstance, insertIssueState) { - this.point1[0] = point1X; - this.point1[1] = point1Y; - this.point1[2] = point1Z; + if (managerFactoryInstance === null) { return; } - this.point2[0] = point2X; - this.point2[1] = point2Y; - this.point2[2] = point2Z; -}; -'use strict'; + var api = new Mago3D.API("changeInsertIssueState"); + api.setInsertIssueState(insertIssueState); + managerFactoryInstance.callAPI(api); +} /** - * 영역박스 - * - * @alias BoundingBox - * @class BoundingBox + * LOD 설정을 변경 + * @param {ManagerFactory} managerFactoryInstance + * @param {string} lod0DistInMeters + * @param {string} lod1DistInMeters + * @param {string} lod2DistInMeters + * @param {string} lod3DistInMeters + * @param {string} lod4DistInMeters + * @param {string} lod5DistInMeters */ -var BoundingBox = function() +function changeLodAPI(managerFactoryInstance, lod0DistInMeters, lod1DistInMeters, lod2DistInMeters, lod3DistInMeters, lod4DistInMeters, lod5DistInMeters) { - if (!(this instanceof BoundingBox)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - this.minX = 1000000.0; - this.minY = 1000000.0; - this.minZ = 1000000.0; - - this.maxX = -1000000.0; - this.maxY = -1000000.0; - this.maxZ = -1000000.0; -}; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("changeLod"); + api.setLod0DistInMeters(lod0DistInMeters); + api.setLod1DistInMeters(lod1DistInMeters); + api.setLod2DistInMeters(lod2DistInMeters); + api.setLod3DistInMeters(lod3DistInMeters); + api.setLod4DistInMeters(lod4DistInMeters); + api.setLod5DistInMeters(lod5DistInMeters); + managerFactoryInstance.callAPI(api); +} /** - * 영역박스 초기화 - * - * @param {Point3D} point 3차원 점 + * Lighting 설정 + * @param {ManagerFactory} managerFactoryInstance + * @param {string} ambientReflectionCoef + * @param {string} diffuseReflectionCoef + * @param {string} specularReflectionCoef + * @param {string} ambientColor + * @param {string} specularColor */ -BoundingBox.prototype.init = function(point) +function changeLightingAPI(managerFactoryInstance, ambientReflectionCoef, diffuseReflectionCoef, specularReflectionCoef, ambientColor, specularColor) { - point = point || new Point3D(); - - this.minX = point.x; - this.minY = point.y; - this.minZ = point.z; - - this.maxX = point.x; - this.maxY = point.y; - this.maxZ = point.z; -}; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("changeLighting"); + api.setAmbientReflectionCoef(ambientReflectionCoef); + api.setDiffuseReflectionCoef(diffuseReflectionCoef); + api.setSpecularReflectionCoef(specularReflectionCoef); + api.setAmbientColor(ambientColor); + api.setSpecularColor(specularColor); + managerFactoryInstance.callAPI(api); +} /** - * 영역박스 삭제 - * + * SSAO Radius 설정 + * @param {ManagerFactory} managerFactoryInstance + * @param {string} ssaoRadius */ -BoundingBox.prototype.deleteObjects = function() +function changeSsaoRadiusAPI(managerFactoryInstance, ssaoRadius) { - this.minX = undefined; - this.minY = undefined; - this.minZ = undefined; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("changeSsaoRadius"); + api.setSsaoRadius(ssaoRadius); + managerFactoryInstance.callAPI(api); +} - this.maxX = undefined; - this.maxY = undefined; - this.maxZ = undefined; -}; +/** + * 모든 f4d 데이터를 삭제, 비표시 + * @param {ManagerFactory} managerFactoryInstance + */ +function clearAllDataAPI(managerFactoryInstance) +{ + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("clearAllData"); + Mago3D.MagoConfig.clearAllData(); + managerFactoryInstance.callAPI(api); +} /** - * 영역박스 확대 - * - * @param {Number} distance + * pin image를 그림 + * @param {ManagerFactory} managerFactoryInstance + * @param {string} drawType 이미지를 그리는 유형 0 : DB, 1 : 이슈등록 + * @param {string} issue_id 이슈 고유키 + * @param {string} issue_type 이슈 고유키 + * @param {string} data_key 데이터 고유키 + * @param {string} latitude 데이터 고유키 + * @param {string} longitude 데이터 고유키 + * @param {string} height 데이터 고유키 */ -BoundingBox.prototype.copyFrom = function(bbox) +function drawInsertIssueImageAPI(managerFactoryInstance, drawType, issue_id, issue_type, data_key, latitude, longitude, height) { - this.minX = bbox.minX; - this.minY = bbox.minY; - this.minZ = bbox.minZ; - - this.maxX = bbox.maxX; - this.maxY = bbox.maxY; - this.maxZ = bbox.maxZ; -}; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("drawInsertIssueImage"); + api.setDrawType(drawType); + api.setIssueId(issue_id); + api.setIssueId(issue_type); + api.setDataKey(data_key); + api.setLatitude(latitude); + api.setLongitude(longitude); + api.setElevation(height); + managerFactoryInstance.callAPI(api); +} /** - * 영역박스 확대 - * + * 해당 프로젝트를 로딩하고 이동하기 + * @param {ManagerFactory} managerFactoryInstance + * @param {string} projectId project id + * @param {string} latitude 데이터 고유키 + * @param {string} longitude 데이터 고유키 + * @param {string} height 데이터 고유키 + * @param {string} duration 이동하는 시간 */ -BoundingBox.prototype.translateToOrigin = function() +function gotoProjectAPI(managerFactoryInstance, projectId, projectData, projectDataFolder, longitude, latitude, height, duration) { - var semiXLength = this.getXLength() /2; - var semiYLength = this.getYLength() /2; - var semiZLength = this.getZLength() /2; + if (managerFactoryInstance === null) { return; } - this.minX = -semiXLength; - this.minY = -semiYLength; - this.minZ = -semiZLength; - - this.maxX = semiXLength; - this.maxY = semiYLength; - this.maxZ = semiZLength; -}; + Mago3D.MagoConfig.setData(Mago3D.CODE.PROJECT_ID_PREFIX + projectId, projectData); + Mago3D.MagoConfig.setProjectDataFolder(Mago3D.CODE.PROJECT_DATA_FOLDER_PREFIX + projectDataFolder, projectDataFolder); + + var api = new Mago3D.API("gotoProject"); + api.setProjectId(projectId); + api.setProjectDataFolder(projectDataFolder); + api.setLatitude(latitude); + api.setLongitude(longitude); + api.setElevation(height); + api.setDuration(duration); + managerFactoryInstance.callAPI(api); +} /** - * 영역박스 확대 - * - * @param {Number} distance + * 해당 프로젝트를 로딩하고 Issue 등록 지점으로 이동하기 + * @param {ManagerFactory} managerFactoryInstance + * @param {string} projectId project id + * @param {string} issueId issue id + * @param {string} issueType issue type + * @param {string} latitude 데이터 고유키 + * @param {string} longitude 데이터 고유키 + * @param {string} height 데이터 고유키 + * @param {string} duration 이동하는 시간 */ -BoundingBox.prototype.expand = function(distance) +function gotoIssueAPI(managerFactoryInstance, projectId, projectData, projectDataFolder, issueId, issueType, longitude, latitude, height, duration) { - distance = distance || 0.0; - distance = Math.abs(distance); - - this.minX -= distance; - this.minY -= distance; - this.minZ -= distance; - - this.maxX += distance; - this.maxY += distance; - this.maxZ += distance; -}; + if (managerFactoryInstance === null) { return; } + + Mago3D.MagoConfig.setData(Mago3D.CODE.PROJECT_ID_PREFIX + projectId, projectData); + Mago3D.MagoConfig.setProjectDataFolder(Mago3D.CODE.PROJECT_DATA_FOLDER_PREFIX + projectDataFolder, projectDataFolder); + + var api = new Mago3D.API("gotoIssue"); + api.setProjectId(projectId); + api.setProjectDataFolder(projectDataFolder); + api.setIssueId(issueId); + api.setIssueType(issueType); + api.setLatitude(latitude); + api.setLongitude(longitude); + api.setElevation(height); + api.setDuration(duration); + managerFactoryInstance.callAPI(api); +} /** - * 주어진 3차원 점을 포함하는 영역으로 영역박스 크기를 변경 - * - * @param {Point3D} point 3차원 점 + * 고려 소프트웨어: 바로가기 */ -BoundingBox.prototype.addPoint = function(point) +function gotoFlyAPI(managerFactoryInstance, longitude, latitude, height, duration) { - if (point === undefined) { return; } - - if (point.x < this.minX) { this.minX = point.x; } - else if (point.x > this.maxX) { this.maxX = point.x; } - - if (point.y < this.minY) { this.minY = point.y; } - else if (point.y > this.maxY) { this.maxY = point.y; } - - if (point.z < this.minZ) { this.minZ = point.z; } - else if (point.z > this.maxZ) { this.maxZ = point.z; } -}; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("gotoFly"); + api.setLongitude(longitude); + api.setLatitude(latitude); + api.setElevation(height); + api.setDuration(duration); + managerFactoryInstance.callAPI(api); +} /** - * 주어진 영역박스를 포함하는 영역으로 영역박스 크기를 변경 - * - * @param {BoundingBox} box 영역박스 + * 마우스를 사용할 수 없는 환경에서 버튼 이벤트로 대체 + * 삭제 예정 + * @param {ManagerFactory} managerFactoryInstance + * @param {string} eventType 어떤 마우스 동작을 원하는지를 구분 */ -BoundingBox.prototype.addBox = function(box) +function mouseMoveAPI(managerFactoryInstance, eventType) { - if (box === undefined) { return; } - - if (box.minX < this.minX) { this.minX = box.minX; } - if (box.maxX > this.maxX) { this.maxX = box.maxX; } - - if (box.minY < this.minY) { this.minY = box.minY; } - if (box.maxY > this.maxY) { this.maxY = box.maxY; } - - if (box.minZ < this.minZ) { this.minZ = box.minZ; } - if (box.maxZ > this.maxZ) { this.maxZ = box.maxZ; } -}; + if (managerFactoryInstance === null) { return; } + + managerFactoryInstance.mouseMove(eventType); +} /** - * 영역박스의 가로, 세로, 높이 중에서 최소값 - * - * @returns {Number} 최소값 + * 데이터 검색 + * @param {ManagerFactory} managerFactoryInstance + * @param {string} projectId 데이터 고유키 + * @param {string} dataKey 데이터 고유키 */ -BoundingBox.prototype.getMinLength = function() +function searchDataAPI(managerFactoryInstance, projectId, dataKey) { - return Math.min(this.maxX - this.minX, this.maxY - this.minY, this.maxZ - this.minZ); -}; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("searchData"); + api.setProjectId(projectId); + api.setDataKey(dataKey); + managerFactoryInstance.callAPI(api); +} /** - * 영역박스의 가로, 세로, 높이 중에서 최대값 - * - * @returns {Number} 최대값 + * 환경 설정 data Object에 key 값의 존재 유무를 판별 + * @param {string} key 검색 키 + * @param */ -BoundingBox.prototype.getMaxLength = function() +function isDataExistAPI(key) { - return Math.max(this.maxX - this.minX, this.maxY - this.minY, this.maxZ - this.minZ); -}; + if (Mago3D.MagoConfig.isDataExist(key)) { return true; } + else { return false; } +} /** - * 영역박스의 X축 방향의 길이 - * - * @returns {Number} 길이값 + * 환경 설정 data map에서 key 값을 취득 + * @param {string} key 검색 키 + * @param */ -BoundingBox.prototype.getXLength = function() +function getDataAPI(key) { - return this.maxX - this.minX; -}; + return Mago3D.MagoConfig.getData(key); +} /** - * 영역박스의 Y축 방향의 길이 - * - * @returns {Number} 길이값 + * Data Key 를 이용하여 Geo Spatial Info를 취득 + * @param {ManagerFactory} managerFactoryInstance + * @param {String} projectId 고유키 + * @param {String} dataKey Data 고유키 + * @param */ -BoundingBox.prototype.getYLength = function() +function getDataInfoByDataKeyAPI(managerFactoryInstance, projectId, dataKey) { - return this.maxY - this.minY; -}; + if (managerFactoryInstance === null) { return; } + + var api = new Mago3D.API("getDataInfoByDataKey"); + api.setProjectId(projectId); + api.setDataKey(dataKey); + managerFactoryInstance.callAPI(api); +} /** - * 영역박스의 Z축 방향의 길이 - * - * @returns {Number} 길이값 + * 데이터를 Rendering + * @param {ManagerFactory} managerFactoryInstance + * @param {Object[]} projectIdArray 프로젝트 이름들 + * @param {Object[]} projectDataArray 프로젝트 데이터들 + * @param {Object[]} projectDataFolderArray 프로젝트 f4d 파일 경로 + * @param */ -BoundingBox.prototype.getZLength = function() +function drawAppendDataAPI(managerFactoryInstance, projectIdArray, projectDataArray, projectDataFolderArray) { - return this.maxZ - this.minZ; -}; + if (managerFactoryInstance === null) { return; } + + if (projectIdArray.length <= 0) { return; } + + var api = new Mago3D.API("drawAppendData"); + projectIdArray.forEach(function(dataName, index) + { + + Mago3D.MagoConfig.setData(Mago3D.CODE.PROJECT_ID_PREFIX + dataName, projectDataArray[index]); + Mago3D.MagoConfig.setProjectDataFolder(Mago3D.CODE.PROJECT_DATA_FOLDER_PREFIX + projectDataFolderArray[index], projectDataFolderArray[index]); + + api.setProjectId(dataName); + api.setProjectDataFolder(projectDataFolderArray[index]); + managerFactoryInstance.callAPI(api); + }); +} /** - * 영역박스의 중심점을 구한다. - * - * @param {Point3D} result 영역박스의 중심점 - * - * @returns {Point3D} 영역박스의 중심점 + * get coodinate relative to building + * @param {ManagerFactory} managerFactoryInstance + * @param {string} projectId project primary key + * @param {string} dataKey data key + * @param {string} inputPoint input x, y, z + * @param {string} resultPoint return point */ -BoundingBox.prototype.getCenterPoint = function(result) +function getCoordinateRelativeToBuildingAPI(managerFactoryInstance, projectId, dataKey, inputPoint, resultPoint) { - if ( result === undefined ) { result = new Point3D(); } + if (managerFactoryInstance === null) { return; } - result.set((this.maxX + this.minX)/2, (this.maxY + this.minY)/2, (this.maxZ + this.minZ)/2); + var api = new Mago3D.API("getCoordinateRelativeToBuilding"); + api.setReturnable(true); + api.setProjectId(projectId); + api.setDataKey(dataKey); + api.setInputPoint(inputPoint); + api.setResultPoint(resultPoint); - return result; -}; + return managerFactoryInstance.callAPI(api); +} /** - * 영역박스의 중심점을 구한다. - * - * @returns {float} apriximately radius. + * get absolte coodinate of building point + * @param {ManagerFactory} managerFactoryInstance + * @param {string} projectId project primary key + * @param {string} dataKey data key + * @param {string} inputPoint input x, y, z + * @param {string} resultPoint return point */ -BoundingBox.prototype.getRadiusAprox = function() +function getAbsoluteCoodinateOfBuildingPointAPI(managerFactoryInstance, projectId, dataKey, inputPoint, resultPoint) { - var maxLength = this.getMaxLength(); - return maxLength/1.5; -}; + if (managerFactoryInstance === null) { return; } + var api = new Mago3D.API("getAbsoluteCoodinateOfBuildingPoint"); + api.setReturnable(true); + api.setProjectId(projectId); + api.setDataKey(dataKey); + api.setInputPoint(inputPoint); + api.setResultPoint(resultPoint); -/** - * 영역박스와 점과의 교차 여부를 판단 - * - * @param {Point3D} point 3차원 점 - * @returns {Boolean} 교차 여부 - */ -BoundingBox.prototype.intersectWithPoint = function(point) -{ - if (point === undefined) { return false; } - - if (point.x < this.minX || point.x > this.maxX || - point.y < this.minY || point.y > this.maxY || - point.z < this.minZ || point.z > this.maxZ) - { - return false; - } - - //return this.isPoint3dInside(point.x, point.y, point.z); - return true; -}; + return managerFactoryInstance.callAPI(api); +} /** - * 영역박스와 점과의 교차 여부를 판단 - * - * @param {Number} x x성분 - * @param {Number} y y성분 - * @param {Number} z z성분 - * @returns {Boolean} 교차 여부 + * get current camera position + * @param {ManagerFactory} managerFactoryInstance + * @param {Number} unit position unit. if not define, default value is Mago3D.CODE.units.DEGREE. 0 : Mago3D.CODE.units.METRE, 1 : Mago3D.CODE.units.DEGREE, 2 : Mago3D.CODE.units.RADIAN + * @returns {Object|Cartesian3|Cartographic} */ -BoundingBox.prototype.isPoint3dInside = function(x, y, z) +function getCameraCurrentPositionAPI(managerFactoryInstance, unit) { - if (x < this.minX || x > this.maxX) - { - return false; - } - else if (y < this.minY || y > this.maxY) - { - return false; - } - else if (z < this.minZ || z > this.maxZ) - { - return false; - } - - return true; -}; + var api = new Mago3D.API("getCameraCurrentPosition"); + + api.setReturnable(true); + api.setUnit(unit); + + return managerFactoryInstance.callAPI(api); +} /** - * 영역박스와 주어진 영역박스와의 교차 여부를 판단 - * - * @param {BoundingBox} box 영역박스 - * @returns {Boolean} 교차 여부 + * get current camera orientaion + * @param {ManagerFactory} managerFactoryInstance + * @returns {Object} */ -BoundingBox.prototype.intersectWithBox = function(box) +function getCameraCurrentOrientaionAPI(managerFactoryInstance) { - if (box === undefined) { return false; } - - if (box.minX > this.maxX || box.maxX < this.minX || - box.minY > this.maxY || box.maxY < this.minY || - box.minZ > this.maxZ || box.maxZ < this.minZ) - { - return false; - } - - return true; -}; + var api = new Mago3D.API("getCameraCurrentOrientaion"); + + api.setReturnable(true); + return managerFactoryInstance.callAPI(api); +} /** - * 영역박스와 주어진 영역박스와의 교차 여부를 판단 - * - * @param {BoundingBox} box 영역박스 - * @returns {Boolean} 교차 여부 + * change camera orientation + * @param {ManagerFactory} managerFactoryInstance + * @param {string|undefined|null} heading 좌, 우. needs degree. default value is current camera's heading value. + * @param {string|undefined|null} pitch 위, 아래. needs degree. default value is current camera's pitch value. + * @param {string|undefined|null} roll 좌, 우 기울기. needs degree. default value is current camera's roll value. + * @param {string|undefined|null} duration 이동하는 시간. default value is 0. */ -BoundingBox.prototype.intersectsWithBBox = function(box) +function changeCameraOrientationAPI(managerFactoryInstance, heading, pitch, roll, duration) { - var intersection = true; + var api = new Mago3D.API("changeCameraOrientation"); - if (this.maxX < box.minX) - { - intersection = false; - } - else if (this.minX > box.maxX) - { - intersection = false; - } - else if (this.maxY < box.minY) - { - intersection = false; - } - else if (this.minY > box.maxY) - { - intersection = false; - } - else if (this.maxZ < box.minZ) - { - intersection = false; - } - else if (this.minZ > box.maxZ) - { - intersection = false; - } + api.setHeading(heading); + api.setPitch(pitch); + api.setRoll(roll); + api.setDuration(duration); - return intersection; -}; + managerFactoryInstance.callAPI(api); +} -'use strict'; /** - * 영역 박스 - * @class BoundingSphere + * Object literal with config options for instantiate static model. + * @typedef {Object} instantiateOption + * @property {string} projectId Required. projectId. static model key. + * @property {string} instanceId Required. instance Id. + * @property {number} longitude Required. initial longitude. + * @property {number} latitude Required. initial latitude. + * @property {number} height Optional. Default value is 0. + * @property {number} heading Optional. Default value is 0. + * @property {number} pitch Optional. Default value is 0. + * @property {number} roll Optional. Default value is 0. */ -var BoundingSphere = function() -{ - if (!(this instanceof BoundingSphere)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - this.center = new Point3D(); - this.radius = 0.0; -}; -'use strict'; /** - * 영역 박스 - * @class Box + * instantiate static model + * @param {ManagerFactory} managerFactoryInstance + * @param {instantiateOption} attributes */ -var Box = function() +function instantiateStaticModelAPI(managerFactoryInstance, attributes) { - if (!(this instanceof Box)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } + var api = new Mago3D.API("instantiateStaticModel"); - this.vbo_vicks_container = new VBOVertexIdxCacheKeysContainer(); - this.vbo_vicks_containerEdges; - this.centerPoint; - this.width; - this.length; - this.height; + api.setInstantiateObj(attributes); + managerFactoryInstance.callAPI(api); +} -}; +/** + * Object literal with config options for add static model. + * @typedef {Object} staticModelOption + * @property {string} projectId Required. projectId. Static model key. + * @property {string} projectFolderName Required. Static Model Folder Name. + * @property {string} buildingFolderName Required. Static Model data Folder Name. + */ /** - * box + * add static model + * @param {ManagerFactory} managerFactoryInstance + * @param {staticModelOption} attributes */ -Box.prototype.getVboKeysContainer = function() +function addStaticModelAPI(managerFactoryInstance, attributes) { - return this.vbo_vicks_container; -}; + var api = new Mago3D.API("addStaticModel"); + + api.setStaticModelAttributeObj(attributes); + managerFactoryInstance.callAPI(api); +} /** - * box + * set track target node. + * @param {ManagerFactory} managerFactoryInstance + * @param {string} projectId project primary key + * @param {string} dataKey data key */ -Box.prototype.makeMesh = function(width, length, height) +function setTrackNodeAPI(managerFactoryInstance, projectId, dataKey) { - // check dimensions of the box.*** - if (width !== undefined) - { this.width = width; } - - if (length !== undefined) - { this.length = length; } - - if (height !== undefined) - { this.height = height; } - - if (this.width === undefined) - { this.width = 1; } - - if (this.length === undefined) - { this.length = 1; } - - if (this.height === undefined) - { this.height = 1; } - - if (this.centerPoint === undefined) - { this.centerPoint = new Point3D(0, 0, 0); } - - if (this.vbo_vicks_container === undefined) - { this.vbo_vicks_container = new VBOVertexIdxCacheKeysContainer(); } - - if (this.vbo_vicks_containerEdges === undefined) - { this.vbo_vicks_containerEdges = new VBOVertexIdxCacheKeysContainer(); } - - // Create a parametric mesh.*** - var pMesh = new ParametricMesh(); - - // Create a Profile2d.*** - pMesh.profile = new Profile(); - var profileAux = pMesh.profile; - - // Create a outer ring in the Profile2d.*** - var outerRing = profileAux.newOuterRing(); - var rect = outerRing.newElement("RECTANGLE"); - rect.setCenterPosition(this.centerPoint.x, this.centerPoint.y); - rect.setDimensions(this.width, this.length); - - // Extrude the Profile.*** - var extrudeSegmentsCount = 1; - var extrusionVector = undefined; - pMesh.extrude(profileAux, this.height, extrudeSegmentsCount, extrusionVector); - - var bIncludeBottomCap = true; - var bIncludeTopCap = true; - var mesh = pMesh.getSurfaceIndependentMesh(undefined, bIncludeBottomCap, bIncludeTopCap); + var api = new Mago3D.API("setTrackNode"); - // translate the box bcos center the origen to the center of the box.*** - mesh.translate(0, 0, -this.height/2); - - return mesh; -}; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + api.setProjectId(projectId); + api.setDataKey(dataKey); + managerFactoryInstance.callAPI(api); +} +/** + * set track target node. + * @param {ManagerFactory} managerFactoryInstance + */ +function stopTrackAPI(managerFactoryInstance) +{ + var api = new Mago3D.API("stopTrack"); + + managerFactoryInstance.callAPI(api); +} +/** + * check static model is exist + * @param {ManagerFactory} managerFactoryInstance + * @param {string} projectId + * @returns {Boolean} isExist + */ +function isExistStaticModelAPI(managerFactoryInstance, projectId) +{ + var api = new Mago3D.API("isExistStaticModel"); + api.setReturnable(true); + api.setProjectId(projectId); + return managerFactoryInstance.callAPI(api); +} +/** + * check data is exist + * @param {ManagerFactory} managerFactoryInstance + * @param {string} projectId project primary key + * @param {string} dataKey data key + * @returns {Boolean} isExist + */ +function isExistDataAPI(managerFactoryInstance, projectId, dataKey) +{ + var api = new Mago3D.API("isExistData"); + api.setReturnable(true); + api.setProjectId(projectId); + api.setDataKey(dataKey); + return managerFactoryInstance.callAPI(api); +} 'use strict'; /** - * buildings seed - * @class BuildingSeed + * api 처리 결과를 담당하는 callback function + * @param functionName policy json의 geo_callback_apiresult 속성값 + * @param apiName 호출한 api 이름 + * @param result 결과값 */ -var BuildingSeed = function() +function apiResultCallback(functionName, apiName, result) { - if (!(this instanceof BuildingSeed)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - this.fisrtName; - this.name = ""; - this.buildingId; - this.buildingFileName; - this.geographicCoord; // class : GeographicCoord. - this.rotationsDegree; // class : Point3D. (heading, pitch, roll). - this.bBox; // class : BoundingBox. - this.geographicCoordOfBBox; // class : GeographicCoord. -}; + window[functionName](apiName, result); +} /** - * 어떤 일을 하고 있습니까? + * 선택한 object 정보를 화면에 표시 + * @param functionName callback + * @param projectId + * @param data_key + * @param objectId + * @param latitude + * @param longitude + * @param elevation + * @param heading + * @param pitch + * @param roll + * @param */ -BuildingSeed.prototype.deleteObjects = function() +function selectedObjectCallback(functionName, projectId, dataKey, objectId, latitude, longitude, elevation, heading, pitch, roll) { - this.fisrtName = undefined; - this.name = undefined; - this.buildingId = undefined; - this.buildingFileName = undefined; - - this.geographicCoord.deleteObjects(); - this.rotationsDegree.deleteObjects(); - this.bBox.deleteObjects(); - this.geographicCoordOfBBox.deleteObjects(); - - this.geographicCoord = undefined; - this.rotationsDegree = undefined; - this.bBox = undefined; - this.geographicCoordOfBBox = undefined; -}; + window[functionName](projectId, dataKey, objectId, latitude, longitude, elevation, heading, pitch, roll); +} /** - * buildings seed list - * @class BuildingSeedList + * 이동한 data 정보를 화면에 표시 + * @param functionName callback + * @param projectId + * @param data_key + * @param objectId + * @param latitude + * @param longitude + * @param elevation + * @param heading + * @param pitch + * @param roll + * @param */ -var BuildingSeedList = function() +function movedDataCallback(functionName, projectId, dataKey, objectId, latitude, longitude, elevation, heading, pitch, roll) { - if (!(this instanceof BuildingSeedList)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - this.buildingSeedArray = []; - this.minGeographicCoord; // longitude, latitude, altitude. - this.maxGeographicCoord; // longitude, latitude, altitude. - - this.dataArrayBuffer; // binary data. -}; + window[functionName](projectId, dataKey, objectId, latitude, longitude, elevation, heading, pitch, roll); +} /** - * 어떤 일을 하고 있습니까? + * Data Key 를 이용하여 Geo Spatial Info를 획득하여 화면에 표시 + * @param functionName callback + * @param projectId + * @param data_key + * @param dataName + * @param latitude + * @param longitude + * @param elevation + * @param heading + * @param pitch + * @param roll + * @param */ -BuildingSeedList.prototype.deleteObjects = function() +function dataInfoCallback(functionName, projectId, dataKey, dataName, latitude, longitude, elevation, heading, pitch, roll) { - this.minGeographicCoord.deleteObjects(); - this.maxGeographicCoord.deleteObjects(); - - this.minGeographicCoord = undefined; - this.maxGeographicCoord = undefined; - - if (this.buildingSeedArray) - { - var buildingSeedsCount = this.buildingSeedArray.length; - for (var i=0; i this._byteLength) { + this._byteLength = req; + } + return; + } + if (blen < 1) { + blen = 1; + } + while (req > blen) { + blen *= 2; + } + var buf = new ArrayBuffer(blen); + var src = new Uint8Array(this._buffer); + var dst = new Uint8Array(buf, 0, src.length); + dst.set(src); + this.buffer = buf; + this._byteLength = req; +}; +/** + Internal function to trim the DataStream buffer when required. + Used for stripping out the extra bytes from the backing buffer when + the virtual byteLength is smaller than the buffer byteLength (happens after + growing the buffer with writes and not filling the extra space completely). + @return {null} + */ +DataStream.prototype._trimAlloc = function() { + if (this._byteLength == this._buffer.byteLength) { + return; + } + var buf = new ArrayBuffer(this._byteLength); + var dst = new Uint8Array(buf); + var src = new Uint8Array(this._buffer, 0, dst.length); + dst.set(src); + this.buffer = buf; +}; +/** + Sets the DataStream read/write position to given position. + Clamps between 0 and DataStream length. + @param {number} pos Position to seek to. + @return {null} + */ +DataStream.prototype.seek = function(pos) { + var npos = Math.max(0, Math.min(this.byteLength, pos)); + this.position = (isNaN(npos) || !isFinite(npos)) ? 0 : npos; +}; +/** + Returns true if the DataStream seek pointer is at the end of buffer and + there's no more data to read. + @return {boolean} True if the seek pointer is at the end of the buffer. + */ +DataStream.prototype.isEof = function() { + return (this.position >= this.byteLength); +}; +/** + Maps an Int32Array into the DataStream buffer, swizzling it to native + endianness in-place. The current offset from the start of the buffer needs to + be a multiple of element size, just like with typed array views. + Nice for quickly reading in data. Warning: potentially modifies the buffer + contents. + @param {number} length Number of elements to map. + @param {?boolean} e Endianness of the data to read. + @return {Object} Int32Array to the DataStream backing buffer. + */ +DataStream.prototype.mapInt32Array = function(length, e) { + this._realloc(length * 4); + var arr = new Int32Array(this._buffer, this.byteOffset+this.position, length); + DataStream.arrayToNative(arr, e == null ? this.endianness : e); + this.position += length * 4; + return arr; +}; +/** + Maps an Int16Array into the DataStream buffer, swizzling it to native + endianness in-place. The current offset from the start of the buffer needs to + be a multiple of element size, just like with typed array views. + Nice for quickly reading in data. Warning: potentially modifies the buffer + contents. + @param {number} length Number of elements to map. + @param {?boolean} e Endianness of the data to read. + @return {Object} Int16Array to the DataStream backing buffer. + */ +DataStream.prototype.mapInt16Array = function(length, e) { + this._realloc(length * 2); + var arr = new Int16Array(this._buffer, this.byteOffset+this.position, length); + DataStream.arrayToNative(arr, e == null ? this.endianness : e); + this.position += length * 2; + return arr; +}; +/** + Maps an Int8Array into the DataStream buffer. + Nice for quickly reading in data. + @param {number} length Number of elements to map. + @param {?boolean} e Endianness of the data to read. + @return {Object} Int8Array to the DataStream backing buffer. + */ +DataStream.prototype.mapInt8Array = function(length) { + this._realloc(length * 1); + var arr = new Int8Array(this._buffer, this.byteOffset+this.position, length); + this.position += length * 1; + return arr; +}; +/** + Maps a Uint32Array into the DataStream buffer, swizzling it to native + endianness in-place. The current offset from the start of the buffer needs to + be a multiple of element size, just like with typed array views. + Nice for quickly reading in data. Warning: potentially modifies the buffer + contents. - -'use strict'; + @param {number} length Number of elements to map. + @param {?boolean} e Endianness of the data to read. + @return {Object} Uint32Array to the DataStream backing buffer. + */ +DataStream.prototype.mapUint32Array = function(length, e) { + this._realloc(length * 4); + var arr = new Uint32Array(this._buffer, this.byteOffset+this.position, length); + DataStream.arrayToNative(arr, e == null ? this.endianness : e); + this.position += length * 4; + return arr; +}; /** - * 카메라 - * @class Camera - */ -var Camera = function() -{ - if (!(this instanceof Camera)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } + Maps a Uint16Array into the DataStream buffer, swizzling it to native + endianness in-place. The current offset from the start of the buffer needs to + be a multiple of element size, just like with typed array views. - this.position = new Point3D(); - this.direction = new Point3D(); - this.up = new Point3D(); - this.right = new Point3D(); - this.frustum = new Frustum(); // current frustum.*** - this.bigFrustum = new Frustum(); // sum of all frustums.*** - this.dirty = true; - this.frustumsArray = []; - this.frustumsArray.push(this.frustum); - - // auxiliar vars. - // points. - this.nearCenterPoint = new Point3D(); - this.farCenterPoint = new Point3D(); - - this.farLeftBottomPoint = new Point3D(); - this.farRightTopPoint = new Point3D(); - - // directions. - this.leftBottomDir = new Point3D(); - this.rightTopDir = new Point3D(); - - // normals. - this.leftNormal = new Point3D(); - this.rightNormal = new Point3D(); - this.bottomNormal = new Point3D(); - this.topNormal = new Point3D(); + Nice for quickly reading in data. Warning: potentially modifies the buffer + contents. + + @param {number} length Number of elements to map. + @param {?boolean} e Endianness of the data to read. + @return {Object} Uint16Array to the DataStream backing buffer. + */ +DataStream.prototype.mapUint16Array = function(length, e) { + this._realloc(length * 2); + var arr = new Uint16Array(this._buffer, this.byteOffset+this.position, length); + DataStream.arrayToNative(arr, e == null ? this.endianness : e); + this.position += length * 2; + return arr; }; /** - * 카메라 - * @class Camera - */ -Camera.prototype.copyPosDirUpFrom = function(camera) -{ - this.position.copyFrom(camera.position); - this.direction.copyFrom(camera.direction); - this.up.copyFrom(camera.up); + Maps a Uint8Array into the DataStream buffer. + + Nice for quickly reading in data. + + @param {number} length Number of elements to map. + @param {?boolean} e Endianness of the data to read. + @return {Object} Uint8Array to the DataStream backing buffer. + */ +DataStream.prototype.mapUint8Array = function(length) { + this._realloc(length * 1); + var arr = new Uint8Array(this._buffer, this.byteOffset+this.position, length); + this.position += length * 1; + return arr; }; /** - * 카메라 - * @class Camera - */ -Camera.prototype.transformByMatrix4 = function(mat) -{ - // transform position, direction and up.*** - /* - var camePosHIGH = new Float32Array(3); - var camPosLOW = new Float32Array(3); - var pos = vec3.clone([this.position.x, this.position.y, this.position.z]); - ManagerUtils.calculateSplited3fv(pos, camePosHIGH, camPosLOW); - - camePosHIGH = vec3.transformMat4(camePosHIGH, camePosHIGH, mat); - camPosLOW = vec3.transformMat4(camPosLOW, camPosLOW, mat); - this.position.set(camePosHIGH[0] + camPosLOW[0], camePosHIGH[1] + camPosLOW[1], camePosHIGH[2] + camPosLOW[2]); - */ - this.position = this.transformPoint3DByMatrix4(this.position, mat); - - if (this.rotMat === undefined) - { this.rotMat = mat3.create(); } - - this.rotMat = mat3.fromMat4(this.rotMat, mat); + Maps a Float64Array into the DataStream buffer, swizzling it to native + endianness in-place. The current offset from the start of the buffer needs to + be a multiple of element size, just like with typed array views. - this.direction = this.rotatePoint3DByMatrix3(this.direction, this.rotMat); - this.up = this.rotatePoint3DByMatrix3(this.up, this.rotMat); + Nice for quickly reading in data. Warning: potentially modifies the buffer + contents. + + @param {number} length Number of elements to map. + @param {?boolean} e Endianness of the data to read. + @return {Object} Float64Array to the DataStream backing buffer. + */ +DataStream.prototype.mapFloat64Array = function(length, e) { + this._realloc(length * 8); + var arr = new Float64Array(this._buffer, this.byteOffset+this.position, length); + DataStream.arrayToNative(arr, e == null ? this.endianness : e); + this.position += length * 8; + return arr; }; /** - * 카메라 - * @class Camera - */ -Camera.prototype.getCameraDirectionLine = function(resultLine) -{ - if (resultLine === undefined) - { resultLine = new Line(); } - - resultLine.point.set(this.position.x, this.position.y, this.position.z); - resultLine.direction.set(this.direction.x, this.direction.y, this.direction.z); - - return resultLine; + Maps a Float32Array into the DataStream buffer, swizzling it to native + endianness in-place. The current offset from the start of the buffer needs to + be a multiple of element size, just like with typed array views. + + Nice for quickly reading in data. Warning: potentially modifies the buffer + contents. + + @param {number} length Number of elements to map. + @param {?boolean} e Endianness of the data to read. + @return {Object} Float32Array to the DataStream backing buffer. + */ +DataStream.prototype.mapFloat32Array = function(length, e) { + this._realloc(length * 4); + var arr = new Float32Array(this._buffer, this.byteOffset+this.position, length); + DataStream.arrayToNative(arr, e == null ? this.endianness : e); + this.position += length * 4; + return arr; }; /** - * 카메라 - * @class Camera + Reads an Int32Array of desired length and endianness from the DataStream. + + @param {number} length Number of elements to map. + @param {?boolean} e Endianness of the data to read. + @return {Object} The read Int32Array. */ -Camera.prototype.getCameraElevation = function() -{ - // determine camHeight.*** - var camModul = this.position.getModul(); - // this.equatorialRadius = 6378137.0; - //this.polarRadius = 6356752.3142; - return camModul - 6356752.3142; +DataStream.prototype.readInt32Array = function(length, e) { + length = length == null ? (this.byteLength-this.position / 4) : length; + var arr = new Int32Array(length); + DataStream.memcpy(arr.buffer, 0, + this.buffer, this.byteOffset+this.position, + length*arr.BYTES_PER_ELEMENT); + DataStream.arrayToNative(arr, e == null ? this.endianness : e); + this.position += arr.byteLength; + return arr; }; /** - * 카메라 - * @class Camera + Reads an Int16Array of desired length and endianness from the DataStream. + + @param {number} length Number of elements to map. + @param {?boolean} e Endianness of the data to read. + @return {Object} The read Int16Array. */ -Camera.prototype.getCameraRight = function() -{ - if (this.right === undefined) - { this.right = new Point3D(); } - - this.right = this.direction.crossProduct(this.up, this.right); - return this.right; +DataStream.prototype.readInt16Array = function(length, e) { + length = length == null ? (this.byteLength-this.position / 2) : length; + var arr = new Int16Array(length); + DataStream.memcpy(arr.buffer, 0, + this.buffer, this.byteOffset+this.position, + length*arr.BYTES_PER_ELEMENT); + DataStream.arrayToNative(arr, e == null ? this.endianness : e); + this.position += arr.byteLength; + return arr; }; /** - * 카메라 - * @class Camera + Reads an Int8Array of desired length from the DataStream. + + @param {number} length Number of elements to map. + @param {?boolean} e Endianness of the data to read. + @return {Object} The read Int8Array. */ -Camera.prototype.transformPoint3DByMatrix4 = function(point, mat) -{ - var pos = vec3.clone([point.x, point.y, point.z]); - var tPos = vec3.create(); - tPos = vec3.transformMat4(tPos, pos, mat); - point.set(tPos[0], tPos[1], tPos[2]); - - return point; +DataStream.prototype.readInt8Array = function(length) { + length = length == null ? (this.byteLength-this.position) : length; + var arr = new Int8Array(length); + DataStream.memcpy(arr.buffer, 0, + this.buffer, this.byteOffset+this.position, + length*arr.BYTES_PER_ELEMENT); + this.position += arr.byteLength; + return arr; }; /** - * 카메라 - * @class Camera + Reads a Uint32Array of desired length and endianness from the DataStream. + + @param {number} length Number of elements to map. + @param {?boolean} e Endianness of the data to read. + @return {Object} The read Uint32Array. */ -Camera.prototype.rotatePoint3DByMatrix3 = function(point, mat) -{ - var pos = vec3.clone([point.x, point.y, point.z]); - var tPos = vec3.create(); - tPos = vec3.transformMat3(tPos, pos, mat); - point.set(tPos[0], tPos[1], tPos[2]); - - return point; +DataStream.prototype.readUint32Array = function(length, e) { + length = length == null ? (this.byteLength-this.position / 4) : length; + var arr = new Uint32Array(length); + DataStream.memcpy(arr.buffer, 0, + this.buffer, this.byteOffset+this.position, + length*arr.BYTES_PER_ELEMENT); + DataStream.arrayToNative(arr, e == null ? this.endianness : e); + this.position += arr.byteLength; + return arr; }; /** - * 카메라 - * @class Camera + Reads a Uint16Array of desired length and endianness from the DataStream. + + @param {number} length Number of elements to map. + @param {?boolean} e Endianness of the data to read. + @return {Object} The read Uint16Array. */ -Camera.prototype.setDirty = function(cameraIsDirty) -{ - this.dirty = cameraIsDirty; +DataStream.prototype.readUint16Array = function(length, e) { + length = length == null ? (this.byteLength-this.position / 2) : length; + var arr = new Uint16Array(length); + DataStream.memcpy(arr.buffer, 0, + this.buffer, this.byteOffset+this.position, + length*arr.BYTES_PER_ELEMENT); + DataStream.arrayToNative(arr, e == null ? this.endianness : e); + this.position += arr.byteLength; + return arr; }; /** - * 카메라 - * @class Camera + Reads a Uint8Array of desired length from the DataStream. + + @param {number} length Number of elements to map. + @param {?boolean} e Endianness of the data to read. + @return {Object} The read Uint8Array. */ -Camera.prototype.getDirty = function() -{ - return this.dirty; +DataStream.prototype.readUint8Array = function(length) { + length = length == null ? (this.byteLength-this.position) : length; + var arr = new Uint8Array(length); + DataStream.memcpy(arr.buffer, 0, + this.buffer, this.byteOffset+this.position, + length*arr.BYTES_PER_ELEMENT); + this.position += arr.byteLength; + return arr; }; /** - * 카메라 - * @class Camera + Reads a Float64Array of desired length and endianness from the DataStream. + + @param {number} length Number of elements to map. + @param {?boolean} e Endianness of the data to read. + @return {Object} The read Float64Array. */ -Camera.prototype.isCameraMoved = function(newPosX, newPosY, newPosZ, newDirX, newDirY, newDirZ, newUpX, newUpY, newUpZ ) -{ - if (this.position.x === newPosX && this.position.y === newPosY && this.position.z === newPosZ && - this.direction.x === newDirX && this.direction.y === newDirY && this.direction.z === newDirZ && - this.up.x === newUpX && this.up.y === newUpY && this.up.z === newUpZ) - { return false; } - else - { return true; } +DataStream.prototype.readFloat64Array = function(length, e) { + length = length == null ? (this.byteLength-this.position / 8) : length; + var arr = new Float64Array(length); + DataStream.memcpy(arr.buffer, 0, + this.buffer, this.byteOffset+this.position, + length*arr.BYTES_PER_ELEMENT); + DataStream.arrayToNative(arr, e == null ? this.endianness : e); + this.position += arr.byteLength; + return arr; }; /** - * 카메라 - * @class Camera + Reads a Float32Array of desired length and endianness from the DataStream. + + @param {number} length Number of elements to map. + @param {?boolean} e Endianness of the data to read. + @return {Object} The read Float32Array. */ -Camera.prototype.getFrustum = function(idx) -{ - if (this.frustumsArray[idx] === undefined) - { - this.frustumsArray[idx] = new Frustum(); - this.frustumsArray[idx].fovRad[0] = this.frustumsArray[0].fovRad[0]; - this.frustumsArray[idx].fovyRad[0]= this.frustumsArray[0].fovyRad[0]; - this.frustumsArray[idx].aspectRatio[0] = this.frustumsArray[0].aspectRatio[0]; - this.frustumsArray[idx].tangentOfHalfFovy[0] = this.frustumsArray[0].tangentOfHalfFovy[0]; - } - - return this.frustumsArray[idx]; +DataStream.prototype.readFloat32Array = function(length, e) { + length = length == null ? (this.byteLength-this.position / 4) : length; + var arr = new Float32Array(length); + DataStream.memcpy(arr.buffer, 0, + this.buffer, this.byteOffset+this.position, + length*arr.BYTES_PER_ELEMENT); + DataStream.arrayToNative(arr, e == null ? this.endianness : e); + this.position += arr.byteLength; + return arr; }; /** - * 카메라 - * @class Camera - */ -Camera.prototype.getLastFrustum = function() -{ - return this.getFrustum(this.frustumsArray.length - 1); + Writes an Int32Array of specified endianness to the DataStream. + + @param {Object} arr The array to write. + @param {?boolean} e Endianness of the data to write. + */ +DataStream.prototype.writeInt32Array = function(arr, e) { + this._realloc(arr.length * 4); + if (arr instanceof Int32Array && + (this.byteOffset+this.position) % arr.BYTES_PER_ELEMENT == 0) { + DataStream.memcpy(this._buffer, this.byteOffset+this.position, + arr.buffer, arr.byteOffset, + arr.byteLength); + this.mapInt32Array(arr.length, e); + } else { + for (var i=0; i 20000.0) - { this.bigFrustum.far[0] = 20000.0; } +DataStream.prototype.writeInt16Array = function(arr, e) { + this._realloc(arr.length * 2); + if (arr instanceof Int16Array && + (this.byteOffset+this.position) % arr.BYTES_PER_ELEMENT == 0) { + DataStream.memcpy(this._buffer, this.byteOffset+this.position, + arr.buffer, arr.byteOffset, + arr.byteLength); + this.mapInt16Array(arr.length, e); + } else { + for (var i=0; i this.maxHeading) - { - this.heading = this.maxHeading; - this.headingAngularSpeed *= -1.0; - } - else if (this.heading < this.minHeading) - { - this.heading = this.minHeading; - this.headingAngularSpeed *= -1.0; - } - - this.lastTime = currTime; - this.calculateRotationMatrix(); - - // change color.*** - if (this.greenFactor === undefined) - { this.greenFactor = 1.0; } - - if (this.blueFactor === undefined) - { this.blueFactor = 1.0; } - - if (this.alphaFactor === undefined) - { this.alphaFactor = 1.0; } - - this.greenFactor += this.greenFactorSpeed * timeAmount; - this.blueFactor += this.blueFactorSpeed * timeAmount; - - if (this.greenFactor > 0.5 ) - { - this.greenFactor = 0.5; - this.greenFactorSpeed *= -1; - } - - if (this.greenFactor < 0.0 ) - { - this.greenFactor = 0.0; - this.greenFactorSpeed *= -1; - } - - if (this.blueFactor > 0.9 ) - { - this.blueFactor = 0.9; - this.blueFactorSpeed *= -1; - } - - if (this.blueFactor < 0.0 ) - { - this.blueFactor = 0.0; - this.blueFactorSpeed *= -1; - } - - - if (this.alphaFactor > 0.6 ) - { - this.alphaFactor = 0.6; - this.alphaFactorSpeed *= -1; - } - - if (this.alphaFactor < 0.0 ) - { - this.alphaFactor = 0.0; - this.alphaFactorSpeed *= -1; - } - - this.color.setRGBA(0.0, this.greenFactor, this.blueFactor, this.alphaFactor); + @param {number} v Number to write. + */ +DataStream.prototype.writeInt8 = function(v) { + this._realloc(1); + this._dataView.setInt8(this.position, v); + this.position += 1; }; /** - */ -CCTV.prototype.calculateRotationMatrix = function() -{ - var rotMatAux; - rotMatAux = Matrix4.getRotationDegZXYMatrix(this.heading, this.pitch, this.roll, rotMatAux); - this.rotMat = rotMatAux.getMultipliedByMatrix(this.geoLocationData.rotMatrix, this.rotMat); -}; + Writes a 32-bit unsigned int to the DataStream with the desired endianness. -/** + @param {number} v Number to write. + @param {?boolean} e Endianness of the number. */ -CCTV.prototype.getVbo = function(resultVboContainer, resultVboContainerEdges) -{ - if (resultVboContainer === undefined) - { resultVboContainer = new VBOVertexIdxCacheKeysContainer(); } - - if (this.vboKeyContainerEdges === undefined) - { this.vboKeyContainerEdges = new VBOVertexIdxCacheKeysContainer(); } - - var frustumMesh; - - /* - frustumMesh = this.makeFrustumGeometry(frustumMesh); - - var surfaceIndepMesh; - surfaceIndepMesh = frustumMesh.getCopySurfaceIndependentMesh(surfaceIndepMesh); - resultVboContainer = surfaceIndepMesh.getVbo(resultVboContainer); - return resultVboContainer; - */ - - // make vbo.*** - frustumMesh = this.makeFrustumGeometry_2(frustumMesh); - var bIncludeBottomCap = true; - var bIncludeTopCap = true; - - // now rotate in X axis.*** - var rotMatAux = new Matrix4(); - var frustum = this.camera.bigFrustum; - var halfFovyRad = frustum.fovyRad / 2.0; - rotMatAux.rotationAxisAngDeg(-90.0 - (halfFovyRad/2) * 180.0 / Math.PI, 1.0, 0.0, 0.0); - - var surfIndepMesh = frustumMesh.getSurfaceIndependentMesh(undefined, bIncludeBottomCap, bIncludeTopCap); - surfIndepMesh.transformByMatrix4(rotMatAux); - surfIndepMesh.setColor(0.0, 0.5, 0.9, 0.3); - - surfIndepMesh.getVbo(resultVboContainer); - surfIndepMesh.getVboEdges(this.vboKeyContainerEdges); - - return resultVboContainer; +DataStream.prototype.writeUint32 = function(v, e) { + this._realloc(4); + this._dataView.setUint32(this.position, v, e == null ? this.endianness : e); + this.position += 4; }; /** + Writes a 16-bit unsigned int to the DataStream with the desired endianness. + + @param {number} v Number to write. + @param {?boolean} e Endianness of the number. */ -CCTV.prototype.render = function(gl, magoManager, shader) -{ - if (this.vboKeyContainer === undefined) - { return; } - - var cacheKeys_count = this.vboKeyContainer.vboCacheKeysArray.length; - - //gl.uniform1i(shader.bApplySpecularLighting_loc, false); - - // Must applicate the transformMatrix.*** - gl.uniformMatrix4fv(shader.buildingRotMatrix_loc, false, this.geoLocationData.rotMatrix._floatArrays); - gl.uniform3fv(shader.buildingPosHIGH_loc, this.geoLocationData.positionHIGH); - gl.uniform3fv(shader.buildingPosLOW_loc, this.geoLocationData.positionLOW); - - gl.uniform1i(shader.hasTexture_loc, false); //.*** - - gl.enable(gl.POLYGON_OFFSET_FILL); - gl.polygonOffset(1, 3); - - var renderWireframe; - - var refMatrixType = 2; - gl.uniform1i(shader.refMatrixType_loc, refMatrixType); - gl.uniformMatrix4fv(shader.refMatrix_loc, false, this.rotMat._floatArrays); - - var renderer = magoManager.renderer; - - // render wireframe.*** - renderWireframe = true; - renderer.renderNormals = false; - gl.uniform4fv(shader.oneColor4_loc, [0.0, 0.0, 0.0, 1.0]); - renderer.renderVboContainer(gl, this.vboKeyContainerEdges, magoManager, shader, renderWireframe); - - // now render fill.*** - gl.enable(gl.BLEND); - renderWireframe = false; - renderer.renderNormals = true; - //gl.uniform4fv(shader.oneColor4_loc, [this.blueFactor, this.greenFactor, 0.0, this.alphaFactor]); - gl.uniform4fv(shader.oneColor4_loc, [this.blueFactor, 0.0, 0.0, this.alphaFactor]); - renderer.renderVboContainer(gl, this.vboKeyContainer, magoManager, shader, renderWireframe); - gl.disable(gl.BLEND); - - gl.disable(gl.POLYGON_OFFSET_FILL); +DataStream.prototype.writeUint16 = function(v, e) { + this._realloc(2); + this._dataView.setUint16(this.position, v, e == null ? this.endianness : e); + this.position += 2; }; /** - */ -CCTV.prototype.makeFrustumGeometry_2 = function(resultMesh) -{ - // 1rst, make the profile: icecream shape.*** - if (resultMesh === undefined) - { resultMesh = new ParametricMesh(); } + Writes an 8-bit unsigned int to the DataStream. - resultMesh.profile = new Profile(); - var profileAux = resultMesh.profile; - - // camera geometry values.*** - var frustum = this.camera.bigFrustum; - var far = frustum.far; - var halfFovyRad = frustum.fovyRad / 2.0; - var halfFovxRad = frustum.fovRad / 2.0; - - var left = -far * Math.tan(halfFovxRad); - var right = -left; - var top = far * Math.tan(halfFovyRad); - var bottom = -top; - - // Outer ring.************************************** - var outerRing = profileAux.newOuterRing(); - var polyLine, point3d, arc; - - polyLine = outerRing.newElement("POLYLINE"); - point3d = polyLine.newPoint2d(-far * Math.sin(halfFovxRad), far * Math.cos(halfFovxRad)); // 0 - point3d = polyLine.newPoint2d(0.0, 0.0); // 1 - point3d = polyLine.newPoint2d(far * Math.sin(halfFovxRad), far * Math.cos(halfFovxRad)); // 2 - - var startAngDeg = 90.0 - halfFovxRad * 180.0 / Math.PI; - var endAngDeg = 90.0 + halfFovxRad * 180.0 / Math.PI; - arc = outerRing.newElement("ARC"); - this.sweepSense = 1; - arc.setCenterPosition(0.0, 0.0); - arc.setRadius(far); - //arc.setStartPoint(far * Math.sin(halfFovxRad), far * Math.cos(halfFovxRad)); - //arc.setEndPoint(-far * Math.sin(halfFovxRad), far * Math.cos(halfFovxRad)); - arc.setStartAngleDegree(startAngDeg); - arc.setSweepAngleDegree(endAngDeg - startAngDeg); - arc.numPointsFor360Deg = 36; - - // now revolve.*** - var revolveAngDeg, revolveSegmentsCount, revolveSegment2d; - revolveAngDeg = (halfFovyRad * 2) * 180.0 / Math.PI; - revolveSegment2d = new Segment2D(); - var strPoint2d = new Point2D(-1, 0); - var endPoint2d = new Point2D(1, 0); - revolveSegment2d.setPoints(strPoint2d, endPoint2d); - revolveSegmentsCount = 6; - resultMesh.revolve(profileAux, revolveAngDeg, revolveSegmentsCount, revolveSegment2d); - - return resultMesh; - - + @param {number} v Number to write. + */ +DataStream.prototype.writeUint8 = function(v) { + this._realloc(1); + this._dataView.setUint8(this.position, v); + this.position += 1; }; /** - */ -CCTV.prototype.makeFrustumGeometry = function(resultMesh) -{ - // make a frustum mesh.*** - if (resultMesh === undefined) - { resultMesh = new Mesh(); } - - if (resultMesh.hedgesList === undefined) - { resultMesh.hedgesList = new HalfEdgesList(); } - - // 1rst, calculate the positions of 5 vertices.*** - var focusPosition = new Point3D(0.0, 0.0, 0.0); - - var frustum = this.camera.bigFrustum; - var far = frustum.far; - var halfFovyRad = frustum.fovyRad / 2.0; - var halfFovxRad = frustum.fovRad / 2.0; - - var left = -far * Math.tan(halfFovxRad); - var right = -left; - var top = far * Math.tan(halfFovyRad); - var bottom = -top; - - var farLeftDown = new Point3D(left, bottom, -far); - var farRightDown = new Point3D(right, bottom, -far); - var farRightTop = new Point3D(right, top, -far); - var farLeftTop = new Point3D(left, top, -far); - - // now make vertices. 5 vertices in total.*** - var focusVertex = new Vertex(focusPosition); - var farLeftDownVertex = new Vertex(farLeftDown); - var farRightDownVertex = new Vertex(farRightDown); - var farRightTopVertex = new Vertex(farRightTop); - var farLeftTopVertex = new Vertex(farLeftTop); - - // provisionally make wireframe here.*** - if (this.vboKeyContainerEdges === undefined) - { this.vboKeyContainerEdges = new VBOVertexIdxCacheKeysContainer(); } - - var face; - - // there are no near polygon.*** - // 1- far polygon.*** - var farSurface = resultMesh.newSurface(); - face = farSurface.newFace(); - // ad vertices in ccw order.*** - face.addVertex(farLeftDownVertex); - face.addVertex(farLeftTopVertex); - face.addVertex(farRightTopVertex); - face.addVertex(farRightDownVertex); - - // make wireframe vbo.************************************************ - var vertex_1, vertex_2, pos_1, pos_2; - var next_idx; - var curr_edge_idx = 0; - var posDataArray = []; - var indicesDataArray = []; - - var vertexCount = face.vertexArray.length; - for (var i=0; i 0; /** + Copies byteLength bytes from the src buffer at srcOffset to the + dst buffer at dstOffset. + + @param {Object} dst Destination ArrayBuffer to write to. + @param {number} dstOffset Offset to the destination ArrayBuffer. + @param {Object} src Source ArrayBuffer to read from. + @param {number} srcOffset Offset to the source ArrayBuffer. + @param {number} byteLength Number of bytes to copy. */ -CCTVList.prototype.getCCTV = function(idx) -{ - return this.camerasList[idx]; +DataStream.memcpy = function(dst, dstOffset, src, srcOffset, byteLength) { + var dstU8 = new Uint8Array(dst, dstOffset, byteLength); + var srcU8 = new Uint8Array(src, srcOffset, byteLength); + dstU8.set(srcU8); }; /** + Converts array to native endianness in-place. + + @param {Object} array Typed array to convert. + @param {boolean} arrayIsLittleEndian True if the data in the array is + little-endian. Set false for big-endian. + @return {Object} The converted typed array. */ -CCTVList.prototype.getCCTVCount = function() -{ - return this.camerasList.length; +DataStream.arrayToNative = function(array, arrayIsLittleEndian) { + if (arrayIsLittleEndian == this.endianness) { + return array; + } else { + return this.flipArrayEndianness(array); + } }; +/** + Converts native endianness array to desired endianness in-place. + @param {Object} array Typed array to convert. + @param {boolean} littleEndian True if the converted array should be + little-endian. Set false for big-endian. + @return {Object} The converted typed array. + */ +DataStream.nativeToEndian = function(array, littleEndian) { + if (this.endianness == littleEndian) { + return array; + } else { + return this.flipArrayEndianness(array); + } +}; +/** + Flips typed array endianness in-place. + @param {Object} array Typed array to flip. + @return {Object} The converted typed array. + */ +DataStream.flipArrayEndianness = function(array) { + var u8 = new Uint8Array(array.buffer, array.byteOffset, array.byteLength); + for (var i=0; ik; j--, k++) { + var tmp = u8[k]; + u8[k] = u8[j]; + u8[j] = tmp; + } + } + return array; +}; +/** + Creates an array from an array of character codes. + Uses String.fromCharCode in chunks for memory efficiency and then concatenates + the resulting string chunks. + @param {array} array Array of character codes. + @return {string} String created from the character codes. +**/ +DataStream.createStringFromArray = function(array) { + var chunk_size = 0x8000; + var chunks = []; + for (var i=0; i < array.length; i += chunk_size) { + chunks.push(String.fromCharCode.apply(null, array.subarray(i, i + chunk_size))); + } + return chunks.join(""); +}; +/** + Seek position where DataStream#readStruct ran into a problem. + Useful for debugging struct parsing. + @type {number} + */ +DataStream.prototype.failurePosition = 0; +/** + Reads a struct of data from the DataStream. The struct is defined as + a flat array of [name, type]-pairs. See the example below: + ds.readStruct([ + 'headerTag', 'uint32', // Uint32 in DataStream endianness. + 'headerTag2', 'uint32be', // Big-endian Uint32. + 'headerTag3', 'uint32le', // Little-endian Uint32. + 'array', ['[]', 'uint32', 16], // Uint32Array of length 16. + 'array2Length', 'uint32', + 'array2', ['[]', 'uint32', 'array2Length'] // Uint32Array of length array2Length + ]); + The possible values for the type are as follows: + // Number types + // Unsuffixed number types use DataStream endianness. + // To explicitly specify endianness, suffix the type with + // 'le' for little-endian or 'be' for big-endian, + // e.g. 'int32be' for big-endian int32. + 'uint8' -- 8-bit unsigned int + 'uint16' -- 16-bit unsigned int + 'uint32' -- 32-bit unsigned int + 'int8' -- 8-bit int + 'int16' -- 16-bit int + 'int32' -- 32-bit int + 'float32' -- 32-bit float + 'float64' -- 64-bit float + // String types + 'cstring' -- ASCII string terminated by a zero byte. + 'string:N' -- ASCII string of length N, where N is a literal integer. + 'string:variableName' -- ASCII string of length $variableName, + where 'variableName' is a previously parsed number in the current struct. + 'string,CHARSET:N' -- String of byteLength N encoded with given CHARSET. + 'u16string:N' -- UCS-2 string of length N in DataStream endianness. + 'u16stringle:N' -- UCS-2 string of length N in little-endian. + 'u16stringbe:N' -- UCS-2 string of length N in big-endian. + // Complex types + [name, type, name_2, type_2, ..., name_N, type_N] -- Struct + function(dataStream, struct) {} -- Callback function to read and return data. + {get: function(dataStream, struct) {}, + set: function(dataStream, struct) {}} + -- Getter/setter functions to read and return data, handy for using the same + struct definition for reading and writing structs. + ['[]', type, length] -- Array of given type and length. The length can be either + a number, a string that references a previously-read + field, or a callback function(struct, dataStream, type){}. + If length is '*', reads in as many elements as it can. - - - - - - - - - - - - - - - - - -'use strict'; - - - -/** - * 어떤 일을 하고 있습니까? - * @class Color + @param {Object} structDefinition Struct definition object. + @return {Object} The read struct. Null if failed to read struct. */ -var Color = function() -{ - if (!(this instanceof Color)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - //this[0] = 0.0; - //this[1] = 0.0; - //this[2] = 0.0; - //this[3] = 1.0; - - this.r = 0; - this.g = 0; - this.b = 0; - this.a = 1; +DataStream.prototype.readStruct = function(structDefinition) { + var struct = {}, t, v, n; + var p = this.position; + for (var i=0; i= 254) - { - this.color.b = 0; - this.color.g += 1; - if (this.color.g >= 254) - { - this.color.g = 0; - this.color.r += 1; - if (this.color.r >= 254) - { - this.color.r = 0; - this.cycle += 1; - } - } - } - - return resultColor; +DataStream.prototype.readString = function(length, encoding) { + if (encoding == null || encoding == "ASCII") { + return DataStream.createStringFromArray(this.mapUint8Array(length == null ? this.byteLength-this.position : length)); + } else { + return (new TextDecoder(encoding)).decode(this.mapUint8Array(length)); + } }; /** - * 어떤 일을 하고 있습니까? + Writes a string of desired length and encoding to the DataStream. + + @param {string} s The string to write. + @param {?string} encoding The encoding for the written string data. + Defaults to ASCII. + @param {?number} length The number of characters to write. */ -SelectionColor.prototype.decodeColor3 = function(r, g, b) -{ - return 64516*r + 254*g + b; +DataStream.prototype.writeString = function(s, encoding, length) { + if (encoding == null || encoding == "ASCII") { + if (length != null) { + var i = 0; + var len = Math.min(s.length, length); + for (i=0; i= this.maxFilesRequestedCount; -}; + var det = a0 * a3 - a2 * a1; -FileRequestControler.prototype.isFullHeaders = function () -{ - return this.headerFilesRequestedCount >= 1; -}; + if (!det) { + return null; + } -FileRequestControler.prototype.isFullPlus = function (extraCount) -{ - if (extraCount === undefined) - { extraCount = 0; } - - return this.filesRequestedCount >= (this.maxFilesRequestedCount + extraCount); -}; + det = 1.0 / det; + out[0] = a3 * det; + out[1] = -a1 * det; + out[2] = -a2 * det; + out[3] = a0 * det; + return out; + } + /** + * Calculates the adjugate of a mat2 + * + * @param {mat2} out the receiving matrix + * @param {mat2} a the source matrix + * @returns {mat2} out + */ -FileRequestControler.prototype.isFullPlusModelReferences = function (extraCount) -{ - if (extraCount === undefined) - { extraCount = 0; } - - return this.modelRefFilesRequestedCount >= (this.maxFilesRequestedCount + extraCount); -}; + function adjoint(out, a) { + // Caching this value is nessecary if out == a + var a0 = a[0]; + out[0] = a[3]; + out[1] = -a[1]; + out[2] = -a[2]; + out[3] = a0; + return out; + } + /** + * Calculates the determinant of a mat2 + * + * @param {mat2} a the source matrix + * @returns {Number} determinant of a + */ -FileRequestControler.prototype.isFullPlusLowLodData = function (extraCount) -{ - if (extraCount === undefined) - { extraCount = 0; } - - return this.lowLodDataRequestedCount >= (this.maxFilesRequestedCount + extraCount); -}; + function determinant(a) { + return a[0] * a[3] - a[2] * a[1]; + } + /** + * Multiplies two mat2's + * + * @param {mat2} out the receiving matrix + * @param {mat2} a the first operand + * @param {mat2} b the second operand + * @returns {mat2} out + */ -FileRequestControler.prototype.isFullPlusLowLodImages = function (extraCount) -{ - if (extraCount === undefined) - { extraCount = 0; } - - return this.lowLodImagesRequestedCount >= (this.maxFilesRequestedCount + extraCount); -}; + function multiply(out, a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + out[0] = a0 * b0 + a2 * b1; + out[1] = a1 * b0 + a3 * b1; + out[2] = a0 * b2 + a2 * b3; + out[3] = a1 * b2 + a3 * b3; + return out; + } + /** + * Rotates a mat2 by the given angle + * + * @param {mat2} out the receiving matrix + * @param {mat2} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat2} out + */ -'use strict'; + function rotate(out, a, rad) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var s = Math.sin(rad); + var c = Math.cos(rad); + out[0] = a0 * c + a2 * s; + out[1] = a1 * c + a3 * s; + out[2] = a0 * -s + a2 * c; + out[3] = a1 * -s + a3 * c; + return out; + } + /** + * Scales the mat2 by the dimensions in the given vec2 + * + * @param {mat2} out the receiving matrix + * @param {mat2} a the matrix to rotate + * @param {vec2} v the vec2 to scale the matrix by + * @returns {mat2} out + **/ + + function scale(out, a, v) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var v0 = v[0], + v1 = v[1]; + out[0] = a0 * v0; + out[1] = a1 * v0; + out[2] = a2 * v1; + out[3] = a3 * v1; + return out; + } + /** + * Creates a matrix from a given angle + * This is equivalent to (but much faster than): + * + * mat2.identity(dest); + * mat2.rotate(dest, dest, rad); + * + * @param {mat2} out mat2 receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat2} out + */ -var keyFlags = { - moveForward : false, - moveBackward : false, - moveLeft : false, - moveRight : false -}; + function fromRotation(out, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); + out[0] = c; + out[1] = s; + out[2] = -s; + out[3] = c; + return out; + } + /** + * Creates a matrix from a vector scaling + * This is equivalent to (but much faster than): + * + * mat2.identity(dest); + * mat2.scale(dest, dest, vec); + * + * @param {mat2} out mat2 receiving operation result + * @param {vec2} v Scaling vector + * @returns {mat2} out + */ -function getFlagFromKeyCode(code) -{ - switch (code) - { - case 37 : // Arrow-Left - { - //console.log("KeyDown Left"); - return 'moveLeft'; - } - case 38 : // Arrow-Up - { - //console.log("KeyDown Up"); - return 'moveForward'; - } - case 39 : // Arrow-Right - { - //console.log("KeyDown Right"); - return 'moveRight'; - } - case 40 : // Arrow-Down - { - //console.log("KeyDown Down"); - return 'moveBackward'; - } - default : - { - return undefined; - } - } -}; + function fromScaling(out, v) { + out[0] = v[0]; + out[1] = 0; + out[2] = 0; + out[3] = v[1]; + return out; + } + /** + * Returns a string representation of a mat2 + * + * @param {mat2} a matrix to represent as a string + * @returns {String} string representation of the matrix + */ -function onKeyDown(event) -{ - var flag = getFlagFromKeyCode(event.keyCode); - if ( typeof flag !== 'undefined') - { - keyFlags[flag] = true; - } -}; + function str(a) { + return 'mat2(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')'; + } + /** + * Returns Frobenius norm of a mat2 + * + * @param {mat2} a the matrix to calculate Frobenius norm of + * @returns {Number} Frobenius norm + */ -function onKeyUp(event) -{ - var flag = getFlagFromKeyCode(event.keyCode); - if ( typeof flag !== 'undefined') - { - keyFlags[flag] = false; - } -}; + function frob(a) { + return Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2)); + } + /** + * Returns L, D and U matrices (Lower triangular, Diagonal and Upper triangular) by factorizing the input matrix + * @param {mat2} L the lower triangular matrix + * @param {mat2} D the diagonal matrix + * @param {mat2} U the upper triangular matrix + * @param {mat2} a the input matrix to factorize + */ -/** - * 카메라 1인칭 시점 모드 - * - */ -function FirstPersonView () -{ - this._camera = undefined; - this._cameraBAK = undefined; - this._position = new Point3D(); - this._rotation = new Point3D(); - this._positionSpeed = 1.0; - this._ratationSpeed = 1.0; -} + function LDU(L, D, U, a) { + L[2] = a[2] / a[0]; + U[0] = a[0]; + U[1] = a[1]; + U[3] = a[3] - L[2] * U[1]; + return [L, D, U]; + } + /** + * Adds two mat2's + * + * @param {mat2} out the receiving matrix + * @param {mat2} a the first operand + * @param {mat2} b the second operand + * @returns {mat2} out + */ -Object.defineProperties(FirstPersonView.prototype, { - "camera": { - get : function () { return this._camera; }, - set : function (value) { this._camera = value; } - }, - "position": { - get : function () { return this._position; }, - set : function (value) { this._position = value; } - }, - "rotation": { - get : function () { return this._rotation; }, - set : function (value) { this._rotation = value; } - }, - "positionSpeed": { - get : function () { return this._positionSpeed; }, - set : function (value) { this._positionSpeed = value; } - }, - "rotationSpeed": { - get : function () { return this._ratationSpeed; }, - set : function (value) { this._ratationSpeed = value; } - } -}); + function add(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + return out; + } + /** + * Subtracts matrix b from matrix a + * + * @param {mat2} out the receiving matrix + * @param {mat2} a the first operand + * @param {mat2} b the second operand + * @returns {mat2} out + */ -FirstPersonView.prototype.init = function () -{ - this._position.set(0.0, 0.0, 0.0); - this._rotation.set(0.0, 0.0, 0.0); + function subtract(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + out[3] = a[3] - b[3]; + return out; + } + /** + * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) + * + * @param {mat2} a The first matrix. + * @param {mat2} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ - document.addEventListener('keydown', onKeyDown, false); - document.addEventListener('keyup', onKeyUp, false); -}; + function exactEquals(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]; + } + /** + * Returns whether or not the matrices have approximately the same elements in the same position. + * + * @param {mat2} a The first matrix. + * @param {mat2} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ -FirstPersonView.prototype.release = function () -{ - this._camera = undefined; - this._cameraBAK = undefined; - document.removeEventListener('keydown', onKeyDown, false); - document.removeEventListener('keyup', onKeyUp, false); -}; + function equals$1(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)); + } + /** + * Multiply each element of the matrix by a scalar. + * + * @param {mat2} out the receiving matrix + * @param {mat2} a the matrix to scale + * @param {Number} b amount to scale the matrix's elements by + * @returns {mat2} out + */ -FirstPersonView.prototype.move = function (vector) -{ - var position = vec3.fromValues(this._position.x, this._position.y, this.position.z); - var matrix = mat4.create(); - mat4.rotateY(matrix, matrix, this._rotation.y); - vec3.transformMat4(vector, vector, matrix); - vec3.add(position, position, vector); - this._position.set(position[0], position[1], position[2]); -}; -FirstPersonView.prototype.update = function(manager) -{ - if (this._camera === undefined) { return; } - /* - var scratchLookAtMatrix4 = new Cesium.Matrix4(); - var scratchFlyToBoundingSphereCart4 = new Cesium.Cartesian4(); - var transform = Cesium.Transforms.eastNorthUpToFixedFrame(this._camera.position, Cesium.Ellipsoid.WGS84, scratchLookAtMatrix4); - Cesium.Cartesian3.fromCartesian4(Cesium.Matrix4.getColumn(transform, 1, scratchFlyToBoundingSphereCart4), this._camera.direction); - Cesium.Cartesian3.fromCartesian4(Cesium.Matrix4.getColumn(transform, 2, scratchFlyToBoundingSphereCart4), this._camera.up); - - var pos1 = Cesium.Cartesian3.fromDegrees(126.60795289318042, 37.58281268636716, 28.0); - var pos2 = Cesium.Cartesian3.fromDegrees(126.60795243349536, 37.58283027052396, 28.0); - console.log(Cesium.Cartesian3.distance(pos1, pos2)); - */ - if (keyFlags.moveForward) - { - //var isBlocked = manager.checkCollision(this._camera.position, this._camera.direction); - //if (isBlocked) { return; } - this._camera.moveForward(0.5); - this.move(vec3.fromValues(0.0, 1.0, 0.0)); - } - if (keyFlags.moveBackward) - { - this._camera.moveBackward(0.5); - this.move(vec3.fromValues(0.0, -1.0, 0.0)); - } - if (keyFlags.moveLeft) - { - this._camera.lookLeft(0.1); - this.move(vec3.fromValues(-1.0, 0.0, 0.0)); - } - if (keyFlags.moveRight) - { - this._camera.lookRight(0.1); - this.move(vec3.fromValues(1.0, 0.0, 0.0)); - } -}; + function multiplyScalar(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + out[3] = a[3] * b; + return out; + } + /** + * Adds two mat2's after multiplying each element of the second operand by a scalar value. + * + * @param {mat2} out the receiving vector + * @param {mat2} a the first operand + * @param {mat2} b the second operand + * @param {Number} scale the amount to scale b's elements by before adding + * @returns {mat2} out + */ -'use strict'; + function multiplyScalarAndAdd(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + out[2] = a[2] + b[2] * scale; + out[3] = a[3] + b[3] * scale; + return out; + } + /** + * Alias for {@link mat2.multiply} + * @function + */ -/** - * 카메라 - * @class Frustum - */ -var Frustum = function() -{ - if (!(this instanceof Frustum)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - this.near = new Float32Array([0.1]); - this.far = new Float32Array([1000.0]); - this.fovyRad = new Float32Array([0.8037]); - this.tangentOfHalfFovy = new Float32Array([0.0]); - this.fovRad = new Float32Array([1.047]); - this.aspectRatio = new Float32Array([1.3584]); - this.planesArray = []; - this.dirty = true; - - // plane[0] = near, plane[1] = far.*** - for (var i=0; i<6; i++) - { - var plane = new Plane(); - this.planesArray.push(plane); - } -}; - -/** - * 포인트값 삭제 - * 어떤 일을 하고 있습니까? - */ -Frustum.prototype.copyParametersFrom = function(frustum) -{ - this.near[0] = frustum.near[0]; - this.far[0] = frustum.far[0]; - this.fovyRad[0] = frustum.fovyRad[0]; - this.tangentOfHalfFovy[0] = frustum.tangentOfHalfFovy[0]; - this.fovRad[0] = frustum.fovRad[0]; - this.aspectRatio[0] = frustum.aspectRatio[0]; -}; + var mul = multiply; + /** + * Alias for {@link mat2.subtract} + * @function + */ -/** - * 포인트값 삭제 - * 어떤 일을 하고 있습니까? - */ -Frustum.prototype.setNear = function(near) -{ - this.near[0] = near; -}; + var sub = subtract; + + var mat2 = /*#__PURE__*/Object.freeze({ + create: create, + clone: clone, + copy: copy, + identity: identity, + fromValues: fromValues, + set: set, + transpose: transpose, + invert: invert, + adjoint: adjoint, + determinant: determinant, + multiply: multiply, + rotate: rotate, + scale: scale, + fromRotation: fromRotation, + fromScaling: fromScaling, + str: str, + frob: frob, + LDU: LDU, + add: add, + subtract: subtract, + exactEquals: exactEquals, + equals: equals$1, + multiplyScalar: multiplyScalar, + multiplyScalarAndAdd: multiplyScalarAndAdd, + mul: mul, + sub: sub + }); -/** - * 포인트값 삭제 - * 어떤 일을 하고 있습니까? - */ -Frustum.prototype.setFar = function(far) -{ - this.far[0] = far; -}; + /** + * 2x3 Matrix + * @module mat2d + * + * @description + * A mat2d contains six elements defined as: + *
+   * [a, c, tx,
+   *  b, d, ty]
+   * 
+ * This is a short form for the 3x3 matrix: + *
+   * [a, c, tx,
+   *  b, d, ty,
+   *  0, 0, 1]
+   * 
+ * The last row is ignored so the array is shorter and operations are faster. + */ -/** - * 포인트값 삭제 - * 어떤 일을 하고 있습니까? - */ -Frustum.prototype.intersectionNearFarSphere = function(sphere) -{ - var intersects = false; - for (var i=0; i<2; i++) - { - var intersectionType = this.planesArray[i].intersectionSphere(sphere); - if (intersectionType === Constant.INTERSECTION_OUTSIDE) - { return Constant.INTERSECTION_OUTSIDE; } - else if (intersectionType === Constant.INTERSECTION_INTERSECT) - { intersects = true; } - } - - if (intersects) - { return Constant.INTERSECTION_INTERSECT; } - else - { return Constant.INTERSECTION_INSIDE; } -}; + /** + * Creates a new identity mat2d + * + * @returns {mat2d} a new 2x3 matrix + */ -/** - * 포인트값 삭제 - * 어떤 일을 하고 있습니까? - */ -Frustum.prototype.intersectionSphere = function(sphere) -{ - var intersects = false; - for (var i=0; i<6; i++) - { - var intersectionType = this.planesArray[i].intersectionSphere(sphere); - if (intersectionType === Constant.INTERSECTION_OUTSIDE) - { return Constant.INTERSECTION_OUTSIDE; } - else if (intersectionType === Constant.INTERSECTION_INTERSECT) - { intersects = true; } - } - - if (intersects) - { return Constant.INTERSECTION_INTERSECT; } - else - { return Constant.INTERSECTION_INSIDE; } -}; + function create$1() { + var out = new ARRAY_TYPE(6); + if (ARRAY_TYPE != Float32Array) { + out[1] = 0; + out[2] = 0; + out[4] = 0; + out[5] = 0; + } + out[0] = 1; + out[3] = 1; + return out; + } + /** + * Creates a new mat2d initialized with values from an existing matrix + * + * @param {mat2d} a matrix to clone + * @returns {mat2d} a new 2x3 matrix + */ + function clone$1(a) { + var out = new ARRAY_TYPE(6); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + return out; + } + /** + * Copy the values from one mat2d to another + * + * @param {mat2d} out the receiving matrix + * @param {mat2d} a the source matrix + * @returns {mat2d} out + */ + function copy$1(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + return out; + } + /** + * Set a mat2d to the identity matrix + * + * @param {mat2d} out the receiving matrix + * @returns {mat2d} out + */ + function identity$1(out) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 1; + out[4] = 0; + out[5] = 0; + return out; + } + /** + * Create a new mat2d with the given values + * + * @param {Number} a Component A (index 0) + * @param {Number} b Component B (index 1) + * @param {Number} c Component C (index 2) + * @param {Number} d Component D (index 3) + * @param {Number} tx Component TX (index 4) + * @param {Number} ty Component TY (index 5) + * @returns {mat2d} A new mat2d + */ + function fromValues$1(a, b, c, d, tx, ty) { + var out = new ARRAY_TYPE(6); + out[0] = a; + out[1] = b; + out[2] = c; + out[3] = d; + out[4] = tx; + out[5] = ty; + return out; + } + /** + * Set the components of a mat2d to the given values + * + * @param {mat2d} out the receiving matrix + * @param {Number} a Component A (index 0) + * @param {Number} b Component B (index 1) + * @param {Number} c Component C (index 2) + * @param {Number} d Component D (index 3) + * @param {Number} tx Component TX (index 4) + * @param {Number} ty Component TY (index 5) + * @returns {mat2d} out + */ + function set$1(out, a, b, c, d, tx, ty) { + out[0] = a; + out[1] = b; + out[2] = c; + out[3] = d; + out[4] = tx; + out[5] = ty; + return out; + } + /** + * Inverts a mat2d + * + * @param {mat2d} out the receiving matrix + * @param {mat2d} a the source matrix + * @returns {mat2d} out + */ + function invert$1(out, a) { + var aa = a[0], + ab = a[1], + ac = a[2], + ad = a[3]; + var atx = a[4], + aty = a[5]; + var det = aa * ad - ab * ac; + if (!det) { + return null; + } + det = 1.0 / det; + out[0] = ad * det; + out[1] = -ab * det; + out[2] = -ac * det; + out[3] = aa * det; + out[4] = (ac * aty - ad * atx) * det; + out[5] = (ab * atx - aa * aty) * det; + return out; + } + /** + * Calculates the determinant of a mat2d + * + * @param {mat2d} a the source matrix + * @returns {Number} determinant of a + */ + function determinant$1(a) { + return a[0] * a[3] - a[1] * a[2]; + } + /** + * Multiplies two mat2d's + * + * @param {mat2d} out the receiving matrix + * @param {mat2d} a the first operand + * @param {mat2d} b the second operand + * @returns {mat2d} out + */ + function multiply$1(out, a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3], + b4 = b[4], + b5 = b[5]; + out[0] = a0 * b0 + a2 * b1; + out[1] = a1 * b0 + a3 * b1; + out[2] = a0 * b2 + a2 * b3; + out[3] = a1 * b2 + a3 * b3; + out[4] = a0 * b4 + a2 * b5 + a4; + out[5] = a1 * b4 + a3 * b5 + a5; + return out; + } + /** + * Rotates a mat2d by the given angle + * + * @param {mat2d} out the receiving matrix + * @param {mat2d} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat2d} out + */ + function rotate$1(out, a, rad) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5]; + var s = Math.sin(rad); + var c = Math.cos(rad); + out[0] = a0 * c + a2 * s; + out[1] = a1 * c + a3 * s; + out[2] = a0 * -s + a2 * c; + out[3] = a1 * -s + a3 * c; + out[4] = a4; + out[5] = a5; + return out; + } + /** + * Scales the mat2d by the dimensions in the given vec2 + * + * @param {mat2d} out the receiving matrix + * @param {mat2d} a the matrix to translate + * @param {vec2} v the vec2 to scale the matrix by + * @returns {mat2d} out + **/ + + function scale$1(out, a, v) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5]; + var v0 = v[0], + v1 = v[1]; + out[0] = a0 * v0; + out[1] = a1 * v0; + out[2] = a2 * v1; + out[3] = a3 * v1; + out[4] = a4; + out[5] = a5; + return out; + } + /** + * Translates the mat2d by the dimensions in the given vec2 + * + * @param {mat2d} out the receiving matrix + * @param {mat2d} a the matrix to translate + * @param {vec2} v the vec2 to translate the matrix by + * @returns {mat2d} out + **/ + + function translate(out, a, v) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5]; + var v0 = v[0], + v1 = v[1]; + out[0] = a0; + out[1] = a1; + out[2] = a2; + out[3] = a3; + out[4] = a0 * v0 + a2 * v1 + a4; + out[5] = a1 * v0 + a3 * v1 + a5; + return out; + } + /** + * Creates a matrix from a given angle + * This is equivalent to (but much faster than): + * + * mat2d.identity(dest); + * mat2d.rotate(dest, dest, rad); + * + * @param {mat2d} out mat2d receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat2d} out + */ + function fromRotation$1(out, rad) { + var s = Math.sin(rad), + c = Math.cos(rad); + out[0] = c; + out[1] = s; + out[2] = -s; + out[3] = c; + out[4] = 0; + out[5] = 0; + return out; + } + /** + * Creates a matrix from a vector scaling + * This is equivalent to (but much faster than): + * + * mat2d.identity(dest); + * mat2d.scale(dest, dest, vec); + * + * @param {mat2d} out mat2d receiving operation result + * @param {vec2} v Scaling vector + * @returns {mat2d} out + */ + function fromScaling$1(out, v) { + out[0] = v[0]; + out[1] = 0; + out[2] = 0; + out[3] = v[1]; + out[4] = 0; + out[5] = 0; + return out; + } + /** + * Creates a matrix from a vector translation + * This is equivalent to (but much faster than): + * + * mat2d.identity(dest); + * mat2d.translate(dest, dest, vec); + * + * @param {mat2d} out mat2d receiving operation result + * @param {vec2} v Translation vector + * @returns {mat2d} out + */ + function fromTranslation(out, v) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 1; + out[4] = v[0]; + out[5] = v[1]; + return out; + } + /** + * Returns a string representation of a mat2d + * + * @param {mat2d} a matrix to represent as a string + * @returns {String} string representation of the matrix + */ + function str$1(a) { + return 'mat2d(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + a[4] + ', ' + a[5] + ')'; + } + /** + * Returns Frobenius norm of a mat2d + * + * @param {mat2d} a the matrix to calculate Frobenius norm of + * @returns {Number} Frobenius norm + */ + function frob$1(a) { + return Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + 1); + } + /** + * Adds two mat2d's + * + * @param {mat2d} out the receiving matrix + * @param {mat2d} a the first operand + * @param {mat2d} b the second operand + * @returns {mat2d} out + */ + function add$1(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + out[4] = a[4] + b[4]; + out[5] = a[5] + b[5]; + return out; + } + /** + * Subtracts matrix b from matrix a + * + * @param {mat2d} out the receiving matrix + * @param {mat2d} a the first operand + * @param {mat2d} b the second operand + * @returns {mat2d} out + */ + function subtract$1(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + out[3] = a[3] - b[3]; + out[4] = a[4] - b[4]; + out[5] = a[5] - b[5]; + return out; + } + /** + * Multiply each element of the matrix by a scalar. + * + * @param {mat2d} out the receiving matrix + * @param {mat2d} a the matrix to scale + * @param {Number} b amount to scale the matrix's elements by + * @returns {mat2d} out + */ + function multiplyScalar$1(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + out[3] = a[3] * b; + out[4] = a[4] * b; + out[5] = a[5] * b; + return out; + } + /** + * Adds two mat2d's after multiplying each element of the second operand by a scalar value. + * + * @param {mat2d} out the receiving vector + * @param {mat2d} a the first operand + * @param {mat2d} b the second operand + * @param {Number} scale the amount to scale b's elements by before adding + * @returns {mat2d} out + */ + function multiplyScalarAndAdd$1(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + out[2] = a[2] + b[2] * scale; + out[3] = a[3] + b[3] * scale; + out[4] = a[4] + b[4] * scale; + out[5] = a[5] + b[5] * scale; + return out; + } + /** + * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) + * + * @param {mat2d} a The first matrix. + * @param {mat2d} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + function exactEquals$1(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5]; + } + /** + * Returns whether or not the matrices have approximately the same elements in the same position. + * + * @param {mat2d} a The first matrix. + * @param {mat2d} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + function equals$2(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3], + b4 = b[4], + b5 = b[5]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)); + } + /** + * Alias for {@link mat2d.multiply} + * @function + */ + var mul$1 = multiply$1; + /** + * Alias for {@link mat2d.subtract} + * @function + */ + var sub$1 = subtract$1; + + var mat2d = /*#__PURE__*/Object.freeze({ + create: create$1, + clone: clone$1, + copy: copy$1, + identity: identity$1, + fromValues: fromValues$1, + set: set$1, + invert: invert$1, + determinant: determinant$1, + multiply: multiply$1, + rotate: rotate$1, + scale: scale$1, + translate: translate, + fromRotation: fromRotation$1, + fromScaling: fromScaling$1, + fromTranslation: fromTranslation, + str: str$1, + frob: frob$1, + add: add$1, + subtract: subtract$1, + multiplyScalar: multiplyScalar$1, + multiplyScalarAndAdd: multiplyScalarAndAdd$1, + exactEquals: exactEquals$1, + equals: equals$2, + mul: mul$1, + sub: sub$1 + }); + /** + * 3x3 Matrix + * @module mat3 + */ + /** + * Creates a new identity mat3 + * + * @returns {mat3} a new 3x3 matrix + */ + function create$2() { + var out = new ARRAY_TYPE(9); -'use strict'; + if (ARRAY_TYPE != Float32Array) { + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[5] = 0; + out[6] = 0; + out[7] = 0; + } -/** - * 카메라 - * @class FrustumVolumeControl - */ -var FrustumVolumeControl = function() -{ - if (!(this instanceof FrustumVolumeControl)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - this.frustumVolumensMap = {}; -}; + out[0] = 1; + out[4] = 1; + out[8] = 1; + return out; + } + /** + * Copies the upper-left 3x3 values into the given mat3. + * + * @param {mat3} out the receiving 3x3 matrix + * @param {mat4} a the source 4x4 matrix + * @returns {mat3} out + */ -FrustumVolumeControl.prototype.getFrustumVolumeCulling = function(key) -{ - // 1rst, check if exist. If no exist create it.*** - if (!this.frustumVolumensMap.hasOwnProperty(key)) - { - this.frustumVolumensMap[key] = {}; - this.frustumVolumensMap[key].fullyIntersectedLowestTilesArray = []; - this.frustumVolumensMap[key].partiallyIntersectedLowestTilesArray = []; - this.frustumVolumensMap[key].visibleNodes = new VisibleObjectsController(); - } - - return this.frustumVolumensMap[key]; -}; + function fromMat4(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[4]; + out[4] = a[5]; + out[5] = a[6]; + out[6] = a[8]; + out[7] = a[9]; + out[8] = a[10]; + return out; + } + /** + * Creates a new mat3 initialized with values from an existing matrix + * + * @param {mat3} a matrix to clone + * @returns {mat3} a new 3x3 matrix + */ -FrustumVolumeControl.prototype.initArrays = function() -{ - var frustumVolumeObject; - for (var key in this.frustumVolumensMap) - { - frustumVolumeObject = this.frustumVolumensMap[key]; - frustumVolumeObject.fullyIntersectedLowestTilesArray.length = 0; - frustumVolumeObject.partiallyIntersectedLowestTilesArray.length = 0; - frustumVolumeObject.visibleNodes.initArrays(); - } -}; -'use strict'; + function clone$2(a) { + var out = new ARRAY_TYPE(9); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[8] = a[8]; + return out; + } + /** + * Copy the values from one mat3 to another + * + * @param {mat3} out the receiving matrix + * @param {mat3} a the source matrix + * @returns {mat3} out + */ -/** - * 어떤 일을 하고 있습니까? - * @class GeographicCoord - */ -var GeographicCoord = function(lon, lat, alt) -{ - if (!(this instanceof GeographicCoord)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - this.longitude; - this.latitude; - this.altitude; - - if (lon !== undefined) - { this.longitude = lon; } - - if (lat !== undefined) - { this.latitude = lat; } - - if (alt !== undefined) - { this.altitude = alt; } -}; + function copy$2(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[8] = a[8]; + return out; + } + /** + * Create a new mat3 with the given values + * + * @param {Number} m00 Component in column 0, row 0 position (index 0) + * @param {Number} m01 Component in column 0, row 1 position (index 1) + * @param {Number} m02 Component in column 0, row 2 position (index 2) + * @param {Number} m10 Component in column 1, row 0 position (index 3) + * @param {Number} m11 Component in column 1, row 1 position (index 4) + * @param {Number} m12 Component in column 1, row 2 position (index 5) + * @param {Number} m20 Component in column 2, row 0 position (index 6) + * @param {Number} m21 Component in column 2, row 1 position (index 7) + * @param {Number} m22 Component in column 2, row 2 position (index 8) + * @returns {mat3} A new mat3 + */ -/** - * 어떤 일을 하고 있습니까? - * @param longitude 경도 - * @param latitude 위도 - * @param altitude 고도 - */ -GeographicCoord.prototype.deleteObjects = function() -{ - this.longitude = undefined; - this.latitude = undefined; - this.altitude = undefined; -}; + function fromValues$2(m00, m01, m02, m10, m11, m12, m20, m21, m22) { + var out = new ARRAY_TYPE(9); + out[0] = m00; + out[1] = m01; + out[2] = m02; + out[3] = m10; + out[4] = m11; + out[5] = m12; + out[6] = m20; + out[7] = m21; + out[8] = m22; + return out; + } + /** + * Set the components of a mat3 to the given values + * + * @param {mat3} out the receiving matrix + * @param {Number} m00 Component in column 0, row 0 position (index 0) + * @param {Number} m01 Component in column 0, row 1 position (index 1) + * @param {Number} m02 Component in column 0, row 2 position (index 2) + * @param {Number} m10 Component in column 1, row 0 position (index 3) + * @param {Number} m11 Component in column 1, row 1 position (index 4) + * @param {Number} m12 Component in column 1, row 2 position (index 5) + * @param {Number} m20 Component in column 2, row 0 position (index 6) + * @param {Number} m21 Component in column 2, row 1 position (index 7) + * @param {Number} m22 Component in column 2, row 2 position (index 8) + * @returns {mat3} out + */ -/** - * 어떤 일을 하고 있습니까? - * @param longitude 경도 - * @param latitude 위도 - * @param altitude 고도 - */ -GeographicCoord.prototype.copyFrom = function(geographicCoord) -{ - this.longitude = geographicCoord.longitude; - this.latitude = geographicCoord.latitude; - this.altitude = geographicCoord.altitude; -}; + function set$2(out, m00, m01, m02, m10, m11, m12, m20, m21, m22) { + out[0] = m00; + out[1] = m01; + out[2] = m02; + out[3] = m10; + out[4] = m11; + out[5] = m12; + out[6] = m20; + out[7] = m21; + out[8] = m22; + return out; + } + /** + * Set a mat3 to the identity matrix + * + * @param {mat3} out the receiving matrix + * @returns {mat3} out + */ -/** - * 어떤 일을 하고 있습니까? - * @param longitude 경도 - * @param latitude 위도 - * @param altitude 고도 - */ -GeographicCoord.prototype.setLonLatAlt = function(longitude, latitude, altitude) -{ - this.longitude = longitude; - this.latitude = latitude; - this.altitude = altitude; -}; + function identity$2(out) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 1; + out[5] = 0; + out[6] = 0; + out[7] = 0; + out[8] = 1; + return out; + } + /** + * Transpose the values of a mat3 + * + * @param {mat3} out the receiving matrix + * @param {mat3} a the source matrix + * @returns {mat3} out + */ -/** - * 어떤 일을 하고 있습니까? - */ -GeographicCoord.getMidPoint = function(geographicCoordA, geographicCoordB, resultGeographicCoord) -{ - var midLat = ( geographicCoordA.latitude + geographicCoordB.latitude) / 2.0; - var midLon = ( geographicCoordA.longitude + geographicCoordB.longitude) / 2.0; - var midAlt = ( geographicCoordA.altitude + geographicCoordB.altitude) / 2.0; - - if (resultGeographicCoord === undefined) - { resultGeographicCoord = new GeographicCoord(midLon, midLat, midAlt); } - else - { - resultGeographicCoord.setLonLatAlt(midLon, midLat, midAlt); - } - - return resultGeographicCoord; -}; + function transpose$1(out, a) { + // If we are transposing ourselves we can skip a few steps but have to cache some values + if (out === a) { + var a01 = a[1], + a02 = a[2], + a12 = a[5]; + out[1] = a[3]; + out[2] = a[6]; + out[3] = a01; + out[5] = a[7]; + out[6] = a02; + out[7] = a12; + } else { + out[0] = a[0]; + out[1] = a[3]; + out[2] = a[6]; + out[3] = a[1]; + out[4] = a[4]; + out[5] = a[7]; + out[6] = a[2]; + out[7] = a[5]; + out[8] = a[8]; + } + return out; + } + /** + * Inverts a mat3 + * + * @param {mat3} out the receiving matrix + * @param {mat3} a the source matrix + * @returns {mat3} out + */ + function invert$2(out, a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2]; + var a10 = a[3], + a11 = a[4], + a12 = a[5]; + var a20 = a[6], + a21 = a[7], + a22 = a[8]; + var b01 = a22 * a11 - a12 * a21; + var b11 = -a22 * a10 + a12 * a20; + var b21 = a21 * a10 - a11 * a20; // Calculate the determinant + var det = a00 * b01 + a01 * b11 + a02 * b21; + if (!det) { + return null; + } + det = 1.0 / det; + out[0] = b01 * det; + out[1] = (-a22 * a01 + a02 * a21) * det; + out[2] = (a12 * a01 - a02 * a11) * det; + out[3] = b11 * det; + out[4] = (a22 * a00 - a02 * a20) * det; + out[5] = (-a12 * a00 + a02 * a10) * det; + out[6] = b21 * det; + out[7] = (-a21 * a00 + a01 * a20) * det; + out[8] = (a11 * a00 - a01 * a10) * det; + return out; + } + /** + * Calculates the adjugate of a mat3 + * + * @param {mat3} out the receiving matrix + * @param {mat3} a the source matrix + * @returns {mat3} out + */ + function adjoint$1(out, a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2]; + var a10 = a[3], + a11 = a[4], + a12 = a[5]; + var a20 = a[6], + a21 = a[7], + a22 = a[8]; + out[0] = a11 * a22 - a12 * a21; + out[1] = a02 * a21 - a01 * a22; + out[2] = a01 * a12 - a02 * a11; + out[3] = a12 * a20 - a10 * a22; + out[4] = a00 * a22 - a02 * a20; + out[5] = a02 * a10 - a00 * a12; + out[6] = a10 * a21 - a11 * a20; + out[7] = a01 * a20 - a00 * a21; + out[8] = a00 * a11 - a01 * a10; + return out; + } + /** + * Calculates the determinant of a mat3 + * + * @param {mat3} a the source matrix + * @returns {Number} determinant of a + */ + function determinant$2(a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2]; + var a10 = a[3], + a11 = a[4], + a12 = a[5]; + var a20 = a[6], + a21 = a[7], + a22 = a[8]; + return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20); + } + /** + * Multiplies two mat3's + * + * @param {mat3} out the receiving matrix + * @param {mat3} a the first operand + * @param {mat3} b the second operand + * @returns {mat3} out + */ + function multiply$2(out, a, b) { + var a00 = a[0], + a01 = a[1], + a02 = a[2]; + var a10 = a[3], + a11 = a[4], + a12 = a[5]; + var a20 = a[6], + a21 = a[7], + a22 = a[8]; + var b00 = b[0], + b01 = b[1], + b02 = b[2]; + var b10 = b[3], + b11 = b[4], + b12 = b[5]; + var b20 = b[6], + b21 = b[7], + b22 = b[8]; + out[0] = b00 * a00 + b01 * a10 + b02 * a20; + out[1] = b00 * a01 + b01 * a11 + b02 * a21; + out[2] = b00 * a02 + b01 * a12 + b02 * a22; + out[3] = b10 * a00 + b11 * a10 + b12 * a20; + out[4] = b10 * a01 + b11 * a11 + b12 * a21; + out[5] = b10 * a02 + b11 * a12 + b12 * a22; + out[6] = b20 * a00 + b21 * a10 + b22 * a20; + out[7] = b20 * a01 + b21 * a11 + b22 * a21; + out[8] = b20 * a02 + b21 * a12 + b22 * a22; + return out; + } + /** + * Translate a mat3 by the given vector + * + * @param {mat3} out the receiving matrix + * @param {mat3} a the matrix to translate + * @param {vec2} v vector to translate by + * @returns {mat3} out + */ + function translate$1(out, a, v) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a10 = a[3], + a11 = a[4], + a12 = a[5], + a20 = a[6], + a21 = a[7], + a22 = a[8], + x = v[0], + y = v[1]; + out[0] = a00; + out[1] = a01; + out[2] = a02; + out[3] = a10; + out[4] = a11; + out[5] = a12; + out[6] = x * a00 + y * a10 + a20; + out[7] = x * a01 + y * a11 + a21; + out[8] = x * a02 + y * a12 + a22; + return out; + } + /** + * Rotates a mat3 by the given angle + * + * @param {mat3} out the receiving matrix + * @param {mat3} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat3} out + */ + function rotate$2(out, a, rad) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a10 = a[3], + a11 = a[4], + a12 = a[5], + a20 = a[6], + a21 = a[7], + a22 = a[8], + s = Math.sin(rad), + c = Math.cos(rad); + out[0] = c * a00 + s * a10; + out[1] = c * a01 + s * a11; + out[2] = c * a02 + s * a12; + out[3] = c * a10 - s * a00; + out[4] = c * a11 - s * a01; + out[5] = c * a12 - s * a02; + out[6] = a20; + out[7] = a21; + out[8] = a22; + return out; + } + /** + * Scales the mat3 by the dimensions in the given vec2 + * + * @param {mat3} out the receiving matrix + * @param {mat3} a the matrix to rotate + * @param {vec2} v the vec2 to scale the matrix by + * @returns {mat3} out + **/ + + function scale$2(out, a, v) { + var x = v[0], + y = v[1]; + out[0] = x * a[0]; + out[1] = x * a[1]; + out[2] = x * a[2]; + out[3] = y * a[3]; + out[4] = y * a[4]; + out[5] = y * a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[8] = a[8]; + return out; + } + /** + * Creates a matrix from a vector translation + * This is equivalent to (but much faster than): + * + * mat3.identity(dest); + * mat3.translate(dest, dest, vec); + * + * @param {mat3} out mat3 receiving operation result + * @param {vec2} v Translation vector + * @returns {mat3} out + */ + function fromTranslation$1(out, v) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 1; + out[5] = 0; + out[6] = v[0]; + out[7] = v[1]; + out[8] = 1; + return out; + } + /** + * Creates a matrix from a given angle + * This is equivalent to (but much faster than): + * + * mat3.identity(dest); + * mat3.rotate(dest, dest, rad); + * + * @param {mat3} out mat3 receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat3} out + */ + function fromRotation$2(out, rad) { + var s = Math.sin(rad), + c = Math.cos(rad); + out[0] = c; + out[1] = s; + out[2] = 0; + out[3] = -s; + out[4] = c; + out[5] = 0; + out[6] = 0; + out[7] = 0; + out[8] = 1; + return out; + } + /** + * Creates a matrix from a vector scaling + * This is equivalent to (but much faster than): + * + * mat3.identity(dest); + * mat3.scale(dest, dest, vec); + * + * @param {mat3} out mat3 receiving operation result + * @param {vec2} v Scaling vector + * @returns {mat3} out + */ + function fromScaling$2(out, v) { + out[0] = v[0]; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = v[1]; + out[5] = 0; + out[6] = 0; + out[7] = 0; + out[8] = 1; + return out; + } + /** + * Copies the values from a mat2d into a mat3 + * + * @param {mat3} out the receiving matrix + * @param {mat2d} a the matrix to copy + * @returns {mat3} out + **/ + function fromMat2d(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = 0; + out[3] = a[2]; + out[4] = a[3]; + out[5] = 0; + out[6] = a[4]; + out[7] = a[5]; + out[8] = 1; + return out; + } + /** + * Calculates a 3x3 matrix from the given quaternion + * + * @param {mat3} out mat3 receiving operation result + * @param {quat} q Quaternion to create matrix from + * + * @returns {mat3} out + */ + function fromQuat(out, q) { + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var yx = y * x2; + var yy = y * y2; + var zx = z * x2; + var zy = z * y2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + out[0] = 1 - yy - zz; + out[3] = yx - wz; + out[6] = zx + wy; + out[1] = yx + wz; + out[4] = 1 - xx - zz; + out[7] = zy - wx; + out[2] = zx - wy; + out[5] = zy + wx; + out[8] = 1 - xx - yy; + return out; + } + /** + * Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix + * + * @param {mat3} out mat3 receiving operation result + * @param {mat4} a Mat4 to derive the normal matrix from + * + * @returns {mat3} out + */ + function normalFromMat4(out, a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a10 = a[4], + a11 = a[5], + a12 = a[6], + a13 = a[7]; + var a20 = a[8], + a21 = a[9], + a22 = a[10], + a23 = a[11]; + var a30 = a[12], + a31 = a[13], + a32 = a[14], + a33 = a[15]; + var b00 = a00 * a11 - a01 * a10; + var b01 = a00 * a12 - a02 * a10; + var b02 = a00 * a13 - a03 * a10; + var b03 = a01 * a12 - a02 * a11; + var b04 = a01 * a13 - a03 * a11; + var b05 = a02 * a13 - a03 * a12; + var b06 = a20 * a31 - a21 * a30; + var b07 = a20 * a32 - a22 * a30; + var b08 = a20 * a33 - a23 * a30; + var b09 = a21 * a32 - a22 * a31; + var b10 = a21 * a33 - a23 * a31; + var b11 = a22 * a33 - a23 * a32; // Calculate the determinant + + var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; + + if (!det) { + return null; + } + det = 1.0 / det; + out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; + out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det; + out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det; + out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det; + out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det; + out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det; + out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det; + out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det; + out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det; + return out; + } + /** + * Generates a 2D projection matrix with the given bounds + * + * @param {mat3} out mat3 frustum matrix will be written into + * @param {number} width Width of your gl context + * @param {number} height Height of gl context + * @returns {mat3} out + */ + function projection(out, width, height) { + out[0] = 2 / width; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = -2 / height; + out[5] = 0; + out[6] = -1; + out[7] = 1; + out[8] = 1; + return out; + } + /** + * Returns a string representation of a mat3 + * + * @param {mat3} a matrix to represent as a string + * @returns {String} string representation of the matrix + */ + function str$2(a) { + return 'mat3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' + a[8] + ')'; + } + /** + * Returns Frobenius norm of a mat3 + * + * @param {mat3} a the matrix to calculate Frobenius norm of + * @returns {Number} Frobenius norm + */ + function frob$2(a) { + return Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2)); + } + /** + * Adds two mat3's + * + * @param {mat3} out the receiving matrix + * @param {mat3} a the first operand + * @param {mat3} b the second operand + * @returns {mat3} out + */ + function add$2(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + out[4] = a[4] + b[4]; + out[5] = a[5] + b[5]; + out[6] = a[6] + b[6]; + out[7] = a[7] + b[7]; + out[8] = a[8] + b[8]; + return out; + } + /** + * Subtracts matrix b from matrix a + * + * @param {mat3} out the receiving matrix + * @param {mat3} a the first operand + * @param {mat3} b the second operand + * @returns {mat3} out + */ + function subtract$2(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + out[3] = a[3] - b[3]; + out[4] = a[4] - b[4]; + out[5] = a[5] - b[5]; + out[6] = a[6] - b[6]; + out[7] = a[7] - b[7]; + out[8] = a[8] - b[8]; + return out; + } + /** + * Multiply each element of the matrix by a scalar. + * + * @param {mat3} out the receiving matrix + * @param {mat3} a the matrix to scale + * @param {Number} b amount to scale the matrix's elements by + * @returns {mat3} out + */ + function multiplyScalar$2(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + out[3] = a[3] * b; + out[4] = a[4] * b; + out[5] = a[5] * b; + out[6] = a[6] * b; + out[7] = a[7] * b; + out[8] = a[8] * b; + return out; + } + /** + * Adds two mat3's after multiplying each element of the second operand by a scalar value. + * + * @param {mat3} out the receiving vector + * @param {mat3} a the first operand + * @param {mat3} b the second operand + * @param {Number} scale the amount to scale b's elements by before adding + * @returns {mat3} out + */ + function multiplyScalarAndAdd$2(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + out[2] = a[2] + b[2] * scale; + out[3] = a[3] + b[3] * scale; + out[4] = a[4] + b[4] * scale; + out[5] = a[5] + b[5] * scale; + out[6] = a[6] + b[6] * scale; + out[7] = a[7] + b[7] * scale; + out[8] = a[8] + b[8] * scale; + return out; + } + /** + * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) + * + * @param {mat3} a The first matrix. + * @param {mat3} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + function exactEquals$2(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8]; + } + /** + * Returns whether or not the matrices have approximately the same elements in the same position. + * + * @param {mat3} a The first matrix. + * @param {mat3} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + function equals$3(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3], + a4 = a[4], + a5 = a[5], + a6 = a[6], + a7 = a[7], + a8 = a[8]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3], + b4 = b[4], + b5 = b[5], + b6 = b[6], + b7 = b[7], + b8 = b[8]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8)); + } + /** + * Alias for {@link mat3.multiply} + * @function + */ + var mul$2 = multiply$2; + /** + * Alias for {@link mat3.subtract} + * @function + */ + var sub$2 = subtract$2; + + var mat3 = /*#__PURE__*/Object.freeze({ + create: create$2, + fromMat4: fromMat4, + clone: clone$2, + copy: copy$2, + fromValues: fromValues$2, + set: set$2, + identity: identity$2, + transpose: transpose$1, + invert: invert$2, + adjoint: adjoint$1, + determinant: determinant$2, + multiply: multiply$2, + translate: translate$1, + rotate: rotate$2, + scale: scale$2, + fromTranslation: fromTranslation$1, + fromRotation: fromRotation$2, + fromScaling: fromScaling$2, + fromMat2d: fromMat2d, + fromQuat: fromQuat, + normalFromMat4: normalFromMat4, + projection: projection, + str: str$2, + frob: frob$2, + add: add$2, + subtract: subtract$2, + multiplyScalar: multiplyScalar$2, + multiplyScalarAndAdd: multiplyScalarAndAdd$2, + exactEquals: exactEquals$2, + equals: equals$3, + mul: mul$2, + sub: sub$2 + }); + /** + * 4x4 Matrix
Format: column-major, when typed out it looks like row-major
The matrices are being post multiplied. + * @module mat4 + */ + /** + * Creates a new identity mat4 + * + * @returns {mat4} a new 4x4 matrix + */ + function create$3() { + var out = new ARRAY_TYPE(16); + if (ARRAY_TYPE != Float32Array) { + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + } + out[0] = 1; + out[5] = 1; + out[10] = 1; + out[15] = 1; + return out; + } + /** + * Creates a new mat4 initialized with values from an existing matrix + * + * @param {mat4} a matrix to clone + * @returns {mat4} a new 4x4 matrix + */ + function clone$3(a) { + var out = new ARRAY_TYPE(16); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[8] = a[8]; + out[9] = a[9]; + out[10] = a[10]; + out[11] = a[11]; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + return out; + } + /** + * Copy the values from one mat4 to another + * + * @param {mat4} out the receiving matrix + * @param {mat4} a the source matrix + * @returns {mat4} out + */ + function copy$3(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[8] = a[8]; + out[9] = a[9]; + out[10] = a[10]; + out[11] = a[11]; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + return out; + } + /** + * Create a new mat4 with the given values + * + * @param {Number} m00 Component in column 0, row 0 position (index 0) + * @param {Number} m01 Component in column 0, row 1 position (index 1) + * @param {Number} m02 Component in column 0, row 2 position (index 2) + * @param {Number} m03 Component in column 0, row 3 position (index 3) + * @param {Number} m10 Component in column 1, row 0 position (index 4) + * @param {Number} m11 Component in column 1, row 1 position (index 5) + * @param {Number} m12 Component in column 1, row 2 position (index 6) + * @param {Number} m13 Component in column 1, row 3 position (index 7) + * @param {Number} m20 Component in column 2, row 0 position (index 8) + * @param {Number} m21 Component in column 2, row 1 position (index 9) + * @param {Number} m22 Component in column 2, row 2 position (index 10) + * @param {Number} m23 Component in column 2, row 3 position (index 11) + * @param {Number} m30 Component in column 3, row 0 position (index 12) + * @param {Number} m31 Component in column 3, row 1 position (index 13) + * @param {Number} m32 Component in column 3, row 2 position (index 14) + * @param {Number} m33 Component in column 3, row 3 position (index 15) + * @returns {mat4} A new mat4 + */ + function fromValues$3(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) { + var out = new ARRAY_TYPE(16); + out[0] = m00; + out[1] = m01; + out[2] = m02; + out[3] = m03; + out[4] = m10; + out[5] = m11; + out[6] = m12; + out[7] = m13; + out[8] = m20; + out[9] = m21; + out[10] = m22; + out[11] = m23; + out[12] = m30; + out[13] = m31; + out[14] = m32; + out[15] = m33; + return out; + } + /** + * Set the components of a mat4 to the given values + * + * @param {mat4} out the receiving matrix + * @param {Number} m00 Component in column 0, row 0 position (index 0) + * @param {Number} m01 Component in column 0, row 1 position (index 1) + * @param {Number} m02 Component in column 0, row 2 position (index 2) + * @param {Number} m03 Component in column 0, row 3 position (index 3) + * @param {Number} m10 Component in column 1, row 0 position (index 4) + * @param {Number} m11 Component in column 1, row 1 position (index 5) + * @param {Number} m12 Component in column 1, row 2 position (index 6) + * @param {Number} m13 Component in column 1, row 3 position (index 7) + * @param {Number} m20 Component in column 2, row 0 position (index 8) + * @param {Number} m21 Component in column 2, row 1 position (index 9) + * @param {Number} m22 Component in column 2, row 2 position (index 10) + * @param {Number} m23 Component in column 2, row 3 position (index 11) + * @param {Number} m30 Component in column 3, row 0 position (index 12) + * @param {Number} m31 Component in column 3, row 1 position (index 13) + * @param {Number} m32 Component in column 3, row 2 position (index 14) + * @param {Number} m33 Component in column 3, row 3 position (index 15) + * @returns {mat4} out + */ + function set$3(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) { + out[0] = m00; + out[1] = m01; + out[2] = m02; + out[3] = m03; + out[4] = m10; + out[5] = m11; + out[6] = m12; + out[7] = m13; + out[8] = m20; + out[9] = m21; + out[10] = m22; + out[11] = m23; + out[12] = m30; + out[13] = m31; + out[14] = m32; + out[15] = m33; + return out; + } + /** + * Set a mat4 to the identity matrix + * + * @param {mat4} out the receiving matrix + * @returns {mat4} out + */ + function identity$3(out) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = 1; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 1; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Transpose the values of a mat4 + * + * @param {mat4} out the receiving matrix + * @param {mat4} a the source matrix + * @returns {mat4} out + */ + function transpose$2(out, a) { + // If we are transposing ourselves we can skip a few steps but have to cache some values + if (out === a) { + var a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a12 = a[6], + a13 = a[7]; + var a23 = a[11]; + out[1] = a[4]; + out[2] = a[8]; + out[3] = a[12]; + out[4] = a01; + out[6] = a[9]; + out[7] = a[13]; + out[8] = a02; + out[9] = a12; + out[11] = a[14]; + out[12] = a03; + out[13] = a13; + out[14] = a23; + } else { + out[0] = a[0]; + out[1] = a[4]; + out[2] = a[8]; + out[3] = a[12]; + out[4] = a[1]; + out[5] = a[5]; + out[6] = a[9]; + out[7] = a[13]; + out[8] = a[2]; + out[9] = a[6]; + out[10] = a[10]; + out[11] = a[14]; + out[12] = a[3]; + out[13] = a[7]; + out[14] = a[11]; + out[15] = a[15]; + } + return out; + } + /** + * Inverts a mat4 + * + * @param {mat4} out the receiving matrix + * @param {mat4} a the source matrix + * @returns {mat4} out + */ + function invert$3(out, a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a10 = a[4], + a11 = a[5], + a12 = a[6], + a13 = a[7]; + var a20 = a[8], + a21 = a[9], + a22 = a[10], + a23 = a[11]; + var a30 = a[12], + a31 = a[13], + a32 = a[14], + a33 = a[15]; + var b00 = a00 * a11 - a01 * a10; + var b01 = a00 * a12 - a02 * a10; + var b02 = a00 * a13 - a03 * a10; + var b03 = a01 * a12 - a02 * a11; + var b04 = a01 * a13 - a03 * a11; + var b05 = a02 * a13 - a03 * a12; + var b06 = a20 * a31 - a21 * a30; + var b07 = a20 * a32 - a22 * a30; + var b08 = a20 * a33 - a23 * a30; + var b09 = a21 * a32 - a22 * a31; + var b10 = a21 * a33 - a23 * a31; + var b11 = a22 * a33 - a23 * a32; // Calculate the determinant + + var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; + + if (!det) { + return null; + } + det = 1.0 / det; + out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; + out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det; + out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det; + out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det; + out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det; + out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det; + out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det; + out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det; + out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det; + out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det; + out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det; + out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det; + out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det; + out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det; + out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det; + out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det; + return out; + } + /** + * Calculates the adjugate of a mat4 + * + * @param {mat4} out the receiving matrix + * @param {mat4} a the source matrix + * @returns {mat4} out + */ + function adjoint$2(out, a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a10 = a[4], + a11 = a[5], + a12 = a[6], + a13 = a[7]; + var a20 = a[8], + a21 = a[9], + a22 = a[10], + a23 = a[11]; + var a30 = a[12], + a31 = a[13], + a32 = a[14], + a33 = a[15]; + out[0] = a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22); + out[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22)); + out[2] = a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12); + out[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12)); + out[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22)); + out[5] = a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22); + out[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12)); + out[7] = a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12); + out[8] = a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21); + out[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21)); + out[10] = a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11); + out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11)); + out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21)); + out[13] = a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21); + out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11)); + out[15] = a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11); + return out; + } + /** + * Calculates the determinant of a mat4 + * + * @param {mat4} a the source matrix + * @returns {Number} determinant of a + */ + function determinant$3(a) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a10 = a[4], + a11 = a[5], + a12 = a[6], + a13 = a[7]; + var a20 = a[8], + a21 = a[9], + a22 = a[10], + a23 = a[11]; + var a30 = a[12], + a31 = a[13], + a32 = a[14], + a33 = a[15]; + var b00 = a00 * a11 - a01 * a10; + var b01 = a00 * a12 - a02 * a10; + var b02 = a00 * a13 - a03 * a10; + var b03 = a01 * a12 - a02 * a11; + var b04 = a01 * a13 - a03 * a11; + var b05 = a02 * a13 - a03 * a12; + var b06 = a20 * a31 - a21 * a30; + var b07 = a20 * a32 - a22 * a30; + var b08 = a20 * a33 - a23 * a30; + var b09 = a21 * a32 - a22 * a31; + var b10 = a21 * a33 - a23 * a31; + var b11 = a22 * a33 - a23 * a32; // Calculate the determinant + + return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; + } + /** + * Multiplies two mat4s + * + * @param {mat4} out the receiving matrix + * @param {mat4} a the first operand + * @param {mat4} b the second operand + * @returns {mat4} out + */ + function multiply$3(out, a, b) { + var a00 = a[0], + a01 = a[1], + a02 = a[2], + a03 = a[3]; + var a10 = a[4], + a11 = a[5], + a12 = a[6], + a13 = a[7]; + var a20 = a[8], + a21 = a[9], + a22 = a[10], + a23 = a[11]; + var a30 = a[12], + a31 = a[13], + a32 = a[14], + a33 = a[15]; // Cache only the current line of the second matrix + + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + b0 = b[4]; + b1 = b[5]; + b2 = b[6]; + b3 = b[7]; + out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + b0 = b[8]; + b1 = b[9]; + b2 = b[10]; + b3 = b[11]; + out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + b0 = b[12]; + b1 = b[13]; + b2 = b[14]; + b3 = b[15]; + out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; + out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; + out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; + out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; + return out; + } + /** + * Translate a mat4 by the given vector + * + * @param {mat4} out the receiving matrix + * @param {mat4} a the matrix to translate + * @param {vec3} v vector to translate by + * @returns {mat4} out + */ + function translate$2(out, a, v) { + var x = v[0], + y = v[1], + z = v[2]; + var a00, a01, a02, a03; + var a10, a11, a12, a13; + var a20, a21, a22, a23; + + if (a === out) { + out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; + out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; + out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; + out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; + } else { + a00 = a[0]; + a01 = a[1]; + a02 = a[2]; + a03 = a[3]; + a10 = a[4]; + a11 = a[5]; + a12 = a[6]; + a13 = a[7]; + a20 = a[8]; + a21 = a[9]; + a22 = a[10]; + a23 = a[11]; + out[0] = a00; + out[1] = a01; + out[2] = a02; + out[3] = a03; + out[4] = a10; + out[5] = a11; + out[6] = a12; + out[7] = a13; + out[8] = a20; + out[9] = a21; + out[10] = a22; + out[11] = a23; + out[12] = a00 * x + a10 * y + a20 * z + a[12]; + out[13] = a01 * x + a11 * y + a21 * z + a[13]; + out[14] = a02 * x + a12 * y + a22 * z + a[14]; + out[15] = a03 * x + a13 * y + a23 * z + a[15]; + } + return out; + } + /** + * Scales the mat4 by the dimensions in the given vec3 not using vectorization + * + * @param {mat4} out the receiving matrix + * @param {mat4} a the matrix to scale + * @param {vec3} v the vec3 to scale the matrix by + * @returns {mat4} out + **/ + + function scale$3(out, a, v) { + var x = v[0], + y = v[1], + z = v[2]; + out[0] = a[0] * x; + out[1] = a[1] * x; + out[2] = a[2] * x; + out[3] = a[3] * x; + out[4] = a[4] * y; + out[5] = a[5] * y; + out[6] = a[6] * y; + out[7] = a[7] * y; + out[8] = a[8] * z; + out[9] = a[9] * z; + out[10] = a[10] * z; + out[11] = a[11] * z; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + return out; + } + /** + * Rotates a mat4 by the given angle around the given axis + * + * @param {mat4} out the receiving matrix + * @param {mat4} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @param {vec3} axis the axis to rotate around + * @returns {mat4} out + */ + function rotate$3(out, a, rad, axis) { + var x = axis[0], + y = axis[1], + z = axis[2]; + var len = Math.sqrt(x * x + y * y + z * z); + var s, c, t; + var a00, a01, a02, a03; + var a10, a11, a12, a13; + var a20, a21, a22, a23; + var b00, b01, b02; + var b10, b11, b12; + var b20, b21, b22; + + if (len < EPSILON) { + return null; + } -'use strict'; + len = 1 / len; + x *= len; + y *= len; + z *= len; + s = Math.sin(rad); + c = Math.cos(rad); + t = 1 - c; + a00 = a[0]; + a01 = a[1]; + a02 = a[2]; + a03 = a[3]; + a10 = a[4]; + a11 = a[5]; + a12 = a[6]; + a13 = a[7]; + a20 = a[8]; + a21 = a[9]; + a22 = a[10]; + a23 = a[11]; // Construct the elements of the rotation matrix + + b00 = x * x * t + c; + b01 = y * x * t + z * s; + b02 = z * x * t - y * s; + b10 = x * y * t - z * s; + b11 = y * y * t + c; + b12 = z * y * t + x * s; + b20 = x * z * t + y * s; + b21 = y * z * t - x * s; + b22 = z * z * t + c; // Perform rotation-specific matrix multiplication + + out[0] = a00 * b00 + a10 * b01 + a20 * b02; + out[1] = a01 * b00 + a11 * b01 + a21 * b02; + out[2] = a02 * b00 + a12 * b01 + a22 * b02; + out[3] = a03 * b00 + a13 * b01 + a23 * b02; + out[4] = a00 * b10 + a10 * b11 + a20 * b12; + out[5] = a01 * b10 + a11 * b11 + a21 * b12; + out[6] = a02 * b10 + a12 * b11 + a22 * b12; + out[7] = a03 * b10 + a13 * b11 + a23 * b12; + out[8] = a00 * b20 + a10 * b21 + a20 * b22; + out[9] = a01 * b20 + a11 * b21 + a21 * b22; + out[10] = a02 * b20 + a12 * b21 + a22 * b22; + out[11] = a03 * b20 + a13 * b21 + a23 * b22; + + if (a !== out) { + // If the source and destination differ, copy the unchanged last row + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + } -/** - * GeographicExtent - * @class GeographicExtent - */ -var GeographicExtent = function() -{ - if (!(this instanceof GeographicExtent)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - this.minGeographicCoord; - this.maxGeographicCoord; -}; -'use strict'; + return out; + } + /** + * Rotates a matrix by the given angle around the X axis + * + * @param {mat4} out the receiving matrix + * @param {mat4} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ -/** - * 어떤 일을 하고 있습니까? - * @class GeoLocationData - * @param geoLocationDataName 변수 - */ -var GeoLocationData = function(geoLocationDataName) -{ - if (!(this instanceof GeoLocationData)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - this.name; - - if (geoLocationDataName === undefined) { this.name = "noName"; } - else { this.name = geoLocationDataName; } - - this.geographicCoord; // longitude, latitude, altitude.*** - - this.heading; - this.pitch; - this.roll; - - this.date; // year - month - day - hour - min - seg - miliseg.*** - - this.position; // Point3D().*** - this.positionHIGH; // Float32Array[3].*** - this.positionLOW; // Float32Array[3].*** - this.pivotPoint; // Point3D().*** // Actually position = pivotPoint. - - // F4D Matrix4.**** - this.geoLocMatrix; // this is just the cartographic transformation matrix determined by (lon, lat, elev).*** - this.geoLocMatrixInv; // this is just the cartographic transformation matrixInv determined by (lon, lat, elev).*** - this.tMatrix; // this contains translation & rotations.*** - this.tMatrixInv; // this contains translation & rotations.*** - this.rotMatrix; // this contains only rotation.*** - this.rotMatrixInv; // this contains only rotation.*** - - // Aditional.*** - this.pivotPointTraslation; // made when translate the pivot point.*** -}; + function rotateX(out, a, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); + var a10 = a[4]; + var a11 = a[5]; + var a12 = a[6]; + var a13 = a[7]; + var a20 = a[8]; + var a21 = a[9]; + var a22 = a[10]; + var a23 = a[11]; -/** - * 어떤 일을 하고 있습니까? - * @class GeoLocationData - * @param geoLocData 변수 - */ -GeoLocationData.prototype.deleteObjects = function() -{ - this.name = undefined; - if (this.geographicCoord) - { this.geographicCoord.deleteObjects(); } - this.geographicCoord = undefined; - - this.heading = undefined; - this.pitch = undefined; - this.roll = undefined; - - this.date = undefined; - - if (this.position) - { this.position.deleteObjects(); } - this.position = undefined; - this.positionHIGH = undefined; - this.positionLOW = undefined; - if (this.pivotPoint) - { this.pivotPoint.deleteObjects(); } - this.pivotPoint = undefined; - - // F4D Matrix4.**** - if (this.geoLocMatrix) - { this.geoLocMatrix.deleteObjects(); } - if (this.geoLocMatrixInv) - { this.geoLocMatrixInv.deleteObjects(); } - if (this.tMatrix) - { this.tMatrix.deleteObjects(); } - if (this.tMatrixInv) - { this.tMatrixInv.deleteObjects(); } - if (this.rotMatrix) - { this.rotMatrix.deleteObjects(); } - if (this.rotMatrixInv) - { this.rotMatrixInv.deleteObjects(); } - - this.geoLocMatrix = undefined; - this.geoLocMatrixInv = undefined; - this.tMatrix = undefined; - this.tMatrixInv = undefined; - this.rotMatrix = undefined; - this.rotMatrixInv = undefined; - - // Aditional.*** - if (this.pivotPointTraslation) - { this.pivotPointTraslation.deleteObjects(); } - this.pivotPointTraslation = undefined; -}; + if (a !== out) { + // If the source and destination differ, copy the unchanged rows + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + } // Perform axis-specific matrix multiplication + + + out[4] = a10 * c + a20 * s; + out[5] = a11 * c + a21 * s; + out[6] = a12 * c + a22 * s; + out[7] = a13 * c + a23 * s; + out[8] = a20 * c - a10 * s; + out[9] = a21 * c - a11 * s; + out[10] = a22 * c - a12 * s; + out[11] = a23 * c - a13 * s; + return out; + } + /** + * Rotates a matrix by the given angle around the Y axis + * + * @param {mat4} out the receiving matrix + * @param {mat4} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ -/** - * 어떤 일을 하고 있습니까? - * @class GeoLocationData - * @param geoLocData 변수 - */ -GeoLocationData.prototype.doEffectivePivotPointTranslation = function() -{ - // this function adds the "pivotPointTraslation" to the positions. - // this function is not for move the building on the globe. This function is only for translate the pivot point of the building. - if (this.pivotPointTraslation === undefined) - { return; } - - var traslationVector; - traslationVector = this.tMatrix.rotatePoint3D(this.pivotPointTraslation, traslationVector ); - - this.position.x += traslationVector.x; - this.position.y += traslationVector.y; - this.position.z += traslationVector.z; + function rotateY(out, a, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a03 = a[3]; + var a20 = a[8]; + var a21 = a[9]; + var a22 = a[10]; + var a23 = a[11]; - this.positionLOW[0] += traslationVector.x; - this.positionLOW[1] += traslationVector.y; - this.positionLOW[2] += traslationVector.z; + if (a !== out) { + // If the source and destination differ, copy the unchanged rows + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + } // Perform axis-specific matrix multiplication + + + out[0] = a00 * c - a20 * s; + out[1] = a01 * c - a21 * s; + out[2] = a02 * c - a22 * s; + out[3] = a03 * c - a23 * s; + out[8] = a00 * s + a20 * c; + out[9] = a01 * s + a21 * c; + out[10] = a02 * s + a22 * c; + out[11] = a03 * s + a23 * c; + return out; + } + /** + * Rotates a matrix by the given angle around the Z axis + * + * @param {mat4} out the receiving matrix + * @param {mat4} a the matrix to rotate + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ - if (this.pivotPoint === undefined) - { this.pivotPoint = new Point3D(); } + function rotateZ(out, a, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a03 = a[3]; + var a10 = a[4]; + var a11 = a[5]; + var a12 = a[6]; + var a13 = a[7]; + + if (a !== out) { + // If the source and destination differ, copy the unchanged last row + out[8] = a[8]; + out[9] = a[9]; + out[10] = a[10]; + out[11] = a[11]; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + } // Perform axis-specific matrix multiplication + + + out[0] = a00 * c + a10 * s; + out[1] = a01 * c + a11 * s; + out[2] = a02 * c + a12 * s; + out[3] = a03 * c + a13 * s; + out[4] = a10 * c - a00 * s; + out[5] = a11 * c - a01 * s; + out[6] = a12 * c - a02 * s; + out[7] = a13 * c - a03 * s; + return out; + } + /** + * Creates a matrix from a vector translation + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.translate(dest, dest, vec); + * + * @param {mat4} out mat4 receiving operation result + * @param {vec3} v Translation vector + * @returns {mat4} out + */ - this.pivotPoint.set(this.position.x, this.position.y, this.position.z); -}; + function fromTranslation$2(out, v) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = 1; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 1; + out[11] = 0; + out[12] = v[0]; + out[13] = v[1]; + out[14] = v[2]; + out[15] = 1; + return out; + } + /** + * Creates a matrix from a vector scaling + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.scale(dest, dest, vec); + * + * @param {mat4} out mat4 receiving operation result + * @param {vec3} v Scaling vector + * @returns {mat4} out + */ + function fromScaling$3(out, v) { + out[0] = v[0]; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = v[1]; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = v[2]; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Creates a matrix from a given angle around a given axis + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.rotate(dest, dest, rad, axis); + * + * @param {mat4} out mat4 receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @param {vec3} axis the axis to rotate around + * @returns {mat4} out + */ -/** - * 어떤 일을 하고 있습니까? - * @class GeoLocationData - * @param geoLocData 변수 - */ -GeoLocationData.prototype.copyFrom = function(geoLocData) -{ - if (geoLocData === undefined) - { return; } - - this.name = geoLocData.name; - if (geoLocData.geographicCoord) - { - if (this.geographicCoord === undefined) - { this.geographicCoord = new GeographicCoord(); } - - this.geographicCoord.copyFrom(geoLocData.geographicCoord); // longitude, latitude, altitude.*** - } - - this.heading = geoLocData.heading; - this.pitch = geoLocData.pitch; - this.roll = geoLocData.roll; - - this.date = geoLocData.date; // year - month - day - hour - min - seg - miliseg.*** - - if (geoLocData.position) - { - if (this.position === undefined) - { this.position = new Point3D(); } - this.position.copyFrom(geoLocData.position); - } - if (geoLocData.positionHIGH) - { - if (this.positionHIGH === undefined) - { this.positionHIGH = new Float32Array(3); } - - this.positionHIGH[0]= geoLocData.positionHIGH[0]; - this.positionHIGH[1]= geoLocData.positionHIGH[1]; - this.positionHIGH[2]= geoLocData.positionHIGH[2]; - } - if (geoLocData.positionLOW) - { - if (this.positionLOW === undefined) - { this.positionLOW = new Float32Array(3); } - - this.positionLOW[0]= geoLocData.positionLOW[0]; - this.positionLOW[1]= geoLocData.positionLOW[1]; - this.positionLOW[2]= geoLocData.positionLOW[2]; - } - if (geoLocData.pivotPoint) - { - if (this.pivotPoint === undefined) - { this.pivotPoint = new Point3D(); } - - this.pivotPoint.copyFrom(geoLocData.pivotPoint); - } - - // F4D Matrix4.**** - if (geoLocData.geoLocMatrix) - { - if (this.geoLocMatrix === undefined) - { this.geoLocMatrix = new Matrix4(); } - - this.geoLocMatrix.copyFromMatrix4(geoLocData.geoLocMatrix); - } - if (geoLocData.geoLocMatrixInv) - { - if (this.geoLocMatrixInv === undefined) - { this.geoLocMatrixInv = new Matrix4(); } - - this.geoLocMatrixInv.copyFromMatrix4(geoLocData.geoLocMatrixInv); - } - if (geoLocData.tMatrix) - { - if (this.tMatrix === undefined) - { this.tMatrix = new Matrix4(); } - - this.tMatrix.copyFromMatrix4(geoLocData.tMatrix); - } - if (geoLocData.tMatrixInv) - { - if (this.tMatrixInv === undefined) - { this.tMatrixInv = new Matrix4(); } - - this.tMatrixInv.copyFromMatrix4(geoLocData.tMatrixInv); - } - if (geoLocData.rotMatrix) - { - if (this.rotMatrix === undefined) - { this.rotMatrix = new Matrix4(); } - - this.rotMatrix.copyFromMatrix4(geoLocData.rotMatrix); - } - if (geoLocData.rotMatrixInv) - { - if (this.rotMatrixInv === undefined) - { this.rotMatrixInv = new Matrix4(); } - - this.rotMatrixInv.copyFromMatrix4(geoLocData.rotMatrixInv); - } - - if (geoLocData.aditionalTraslation) - { - if (this.aditionalTraslation === undefined) - { this.aditionalTraslation = new Point3D(); } - - this.aditionalTraslation.copyFrom(geoLocData.aditionalTraslation); - } - -}; + function fromRotation$3(out, rad, axis) { + var x = axis[0], + y = axis[1], + z = axis[2]; + var len = Math.sqrt(x * x + y * y + z * z); + var s, c, t; -/** - * This function transforms a local position of this geoLocation to world position. - * @param localCoord instance of Point3D. - * @param resultWorldCoord. instance of Point3D. - * @returns resultWorldCoord. instance of Point3D. - */ -GeoLocationData.prototype.localCoordToWorldCoord = function(localCoord, resultWorldCoord) -{ - if (localCoord === undefined || this.tMatrix === undefined) - { return undefined; } - - if (resultWorldCoord === undefined) - { resultWorldCoord = new Point3D(); } - - resultWorldCoord = this.tMatrix.transformPoint3D(localCoord, resultWorldCoord); - return resultWorldCoord; -}; + if (len < EPSILON) { + return null; + } -/** - * This function transforms an absolute position to local position for this geoLocation. - * @param worldCoord instance of Point3D. - * @param resultLocalCoord. instance of Point3D. - * @returns resultLocalCoord. instance of Point3D. - */ -GeoLocationData.prototype.worldCoordToLocalCoord = function(worldCoord, resultLocalCoord) -{ - if (worldCoord === undefined || this.tMatrixInv === undefined) - { return undefined; } - - if (resultLocalCoord === undefined) - { resultLocalCoord = new Point3D(); } - - resultLocalCoord = this.tMatrixInv.transformPoint3D(worldCoord, resultLocalCoord); - return resultLocalCoord; -}; + len = 1 / len; + x *= len; + y *= len; + z *= len; + s = Math.sin(rad); + c = Math.cos(rad); + t = 1 - c; // Perform rotation-specific matrix multiplication + + out[0] = x * x * t + c; + out[1] = y * x * t + z * s; + out[2] = z * x * t - y * s; + out[3] = 0; + out[4] = x * y * t - z * s; + out[5] = y * y * t + c; + out[6] = z * y * t + x * s; + out[7] = 0; + out[8] = x * z * t + y * s; + out[9] = y * z * t - x * s; + out[10] = z * z * t + c; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Creates a matrix from the given angle around the X axis + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.rotateX(dest, dest, rad); + * + * @param {mat4} out mat4 receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ -/** - * This function transforms an absolute camera (world coord) into a relative camera (local coord) for this geoLocation. - * @param absoluteCamera instance of Camera. - * @param resultCamera instance of Camera. This is the transformed camera. - * @returns resultCamera - */ -GeoLocationData.prototype.getTransformedRelativeCamera = function(absoluteCamera, resultCamera) -{ - var pointAux = new Point3D(); - - pointAux.set(absoluteCamera.position.x - this.position.x, - absoluteCamera.position.y - this.position.y, - absoluteCamera.position.z - this.position.z); - - resultCamera.position = this.rotMatrixInv.transformPoint3D(pointAux, resultCamera.position); - - pointAux.set(absoluteCamera.direction.x, absoluteCamera.direction.y, absoluteCamera.direction.z); - resultCamera.direction = this.rotMatrixInv.transformPoint3D(pointAux, resultCamera.direction); - - pointAux.set(absoluteCamera.up.x, absoluteCamera.up.y, absoluteCamera.up.z); - resultCamera.up = this.rotMatrixInv.transformPoint3D(pointAux, resultCamera.up); - - pointAux.x = undefined; - pointAux.y = undefined; - pointAux.z = undefined; - pointAux = undefined; - - return resultCamera; -}; + function fromXRotation(out, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); // Perform axis-specific matrix multiplication + + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = c; + out[6] = s; + out[7] = 0; + out[8] = 0; + out[9] = -s; + out[10] = c; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Creates a matrix from the given angle around the Y axis + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.rotateY(dest, dest, rad); + * + * @param {mat4} out mat4 receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ -/** - * 어떤 일을 하고 있습니까? - * @class GeoLocationDataManager - */ -var GeoLocationDataManager = function() -{ - if (!(this instanceof GeoLocationDataManager)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - this.geoLocationDataArray = []; - //this.geoLocationDataCache = {}; // use this.*** -}; + function fromYRotation(out, rad) { + var s = Math.sin(rad); + var c = Math.cos(rad); // Perform axis-specific matrix multiplication + + out[0] = c; + out[1] = 0; + out[2] = -s; + out[3] = 0; + out[4] = 0; + out[5] = 1; + out[6] = 0; + out[7] = 0; + out[8] = s; + out[9] = 0; + out[10] = c; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Creates a matrix from the given angle around the Z axis + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.rotateZ(dest, dest, rad); + * + * @param {mat4} out mat4 receiving operation result + * @param {Number} rad the angle to rotate the matrix by + * @returns {mat4} out + */ -/** - * 어떤 일을 하고 있습니까? - * @class GeoLocationData - * @param geoLocationName 변수 - * @returns geoLocationData - */ -GeoLocationDataManager.prototype.deleteObjects = function() -{ - if (this.geoLocationDataArray) - { - for (var i=0; i this.geoLocationDataArray.length - 1) - { return undefined; } - return this.geoLocationDataArray[idx]; -}; + function fromRotationTranslation(out, q, v) { + // Quaternion math + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var xy = x * y2; + var xz = x * z2; + var yy = y * y2; + var yz = y * z2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + out[0] = 1 - (yy + zz); + out[1] = xy + wz; + out[2] = xz - wy; + out[3] = 0; + out[4] = xy - wz; + out[5] = 1 - (xx + zz); + out[6] = yz + wx; + out[7] = 0; + out[8] = xz + wy; + out[9] = yz - wx; + out[10] = 1 - (xx + yy); + out[11] = 0; + out[12] = v[0]; + out[13] = v[1]; + out[14] = v[2]; + out[15] = 1; + return out; + } + /** + * Creates a new mat4 from a dual quat. + * + * @param {mat4} out Matrix + * @param {quat2} a Dual Quaternion + * @returns {mat4} mat4 receiving operation result + */ -/** - * 어떤 일을 하고 있습니까? - * @class GeoLocationData - * @param idx - * @returns this.geoLoactionDataArray[idx] - */ -GeoLocationDataManager.prototype.getCurrentGeoLocationData = function() -{ - if (this.geoLocationDataArray.length === 0) - { - return undefined; - } - return this.geoLocationDataArray[0]; // provisionally return the 1rst. -}; + function fromQuat2(out, a) { + var translation = new ARRAY_TYPE(3); + var bx = -a[0], + by = -a[1], + bz = -a[2], + bw = a[3], + ax = a[4], + ay = a[5], + az = a[6], + aw = a[7]; + var magnitude = bx * bx + by * by + bz * bz + bw * bw; //Only scale if it makes sense + + if (magnitude > 0) { + translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2 / magnitude; + translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2 / magnitude; + translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2 / magnitude; + } else { + translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2; + translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2; + translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2; + } + fromRotationTranslation(out, a, translation); + return out; + } + /** + * Returns the translation vector component of a transformation + * matrix. If a matrix is built with fromRotationTranslation, + * the returned vector will be the same as the translation vector + * originally supplied. + * @param {vec3} out Vector to receive translation component + * @param {mat4} mat Matrix to be decomposed (input) + * @return {vec3} out + */ + function getTranslation(out, mat) { + out[0] = mat[12]; + out[1] = mat[13]; + out[2] = mat[14]; + return out; + } + /** + * Returns the scaling factor component of a transformation + * matrix. If a matrix is built with fromRotationTranslationScale + * with a normalized Quaternion paramter, the returned vector will be + * the same as the scaling vector + * originally supplied. + * @param {vec3} out Vector to receive scaling factor component + * @param {mat4} mat Matrix to be decomposed (input) + * @return {vec3} out + */ + function getScaling(out, mat) { + var m11 = mat[0]; + var m12 = mat[1]; + var m13 = mat[2]; + var m21 = mat[4]; + var m22 = mat[5]; + var m23 = mat[6]; + var m31 = mat[8]; + var m32 = mat[9]; + var m33 = mat[10]; + out[0] = Math.sqrt(m11 * m11 + m12 * m12 + m13 * m13); + out[1] = Math.sqrt(m21 * m21 + m22 * m22 + m23 * m23); + out[2] = Math.sqrt(m31 * m31 + m32 * m32 + m33 * m33); + return out; + } + /** + * Returns a quaternion representing the rotational component + * of a transformation matrix. If a matrix is built with + * fromRotationTranslation, the returned quaternion will be the + * same as the quaternion originally supplied. + * @param {quat} out Quaternion to receive the rotation component + * @param {mat4} mat Matrix to be decomposed (input) + * @return {quat} out + */ + function getRotation(out, mat) { + // Algorithm taken from http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm + var trace = mat[0] + mat[5] + mat[10]; + var S = 0; + + if (trace > 0) { + S = Math.sqrt(trace + 1.0) * 2; + out[3] = 0.25 * S; + out[0] = (mat[6] - mat[9]) / S; + out[1] = (mat[8] - mat[2]) / S; + out[2] = (mat[1] - mat[4]) / S; + } else if (mat[0] > mat[5] && mat[0] > mat[10]) { + S = Math.sqrt(1.0 + mat[0] - mat[5] - mat[10]) * 2; + out[3] = (mat[6] - mat[9]) / S; + out[0] = 0.25 * S; + out[1] = (mat[1] + mat[4]) / S; + out[2] = (mat[8] + mat[2]) / S; + } else if (mat[5] > mat[10]) { + S = Math.sqrt(1.0 + mat[5] - mat[0] - mat[10]) * 2; + out[3] = (mat[8] - mat[2]) / S; + out[0] = (mat[1] + mat[4]) / S; + out[1] = 0.25 * S; + out[2] = (mat[6] + mat[9]) / S; + } else { + S = Math.sqrt(1.0 + mat[10] - mat[0] - mat[5]) * 2; + out[3] = (mat[1] - mat[4]) / S; + out[0] = (mat[8] + mat[2]) / S; + out[1] = (mat[6] + mat[9]) / S; + out[2] = 0.25 * S; + } + return out; + } + /** + * Creates a matrix from a quaternion rotation, vector translation and vector scale + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.translate(dest, vec); + * let quatMat = mat4.create(); + * quat4.toMat4(quat, quatMat); + * mat4.multiply(dest, quatMat); + * mat4.scale(dest, scale) + * + * @param {mat4} out mat4 receiving operation result + * @param {quat4} q Rotation quaternion + * @param {vec3} v Translation vector + * @param {vec3} s Scaling vector + * @returns {mat4} out + */ + function fromRotationTranslationScale(out, q, v, s) { + // Quaternion math + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var xy = x * y2; + var xz = x * z2; + var yy = y * y2; + var yz = y * z2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + var sx = s[0]; + var sy = s[1]; + var sz = s[2]; + out[0] = (1 - (yy + zz)) * sx; + out[1] = (xy + wz) * sx; + out[2] = (xz - wy) * sx; + out[3] = 0; + out[4] = (xy - wz) * sy; + out[5] = (1 - (xx + zz)) * sy; + out[6] = (yz + wx) * sy; + out[7] = 0; + out[8] = (xz + wy) * sz; + out[9] = (yz - wx) * sz; + out[10] = (1 - (xx + yy)) * sz; + out[11] = 0; + out[12] = v[0]; + out[13] = v[1]; + out[14] = v[2]; + out[15] = 1; + return out; + } + /** + * Creates a matrix from a quaternion rotation, vector translation and vector scale, rotating and scaling around the given origin + * This is equivalent to (but much faster than): + * + * mat4.identity(dest); + * mat4.translate(dest, vec); + * mat4.translate(dest, origin); + * let quatMat = mat4.create(); + * quat4.toMat4(quat, quatMat); + * mat4.multiply(dest, quatMat); + * mat4.scale(dest, scale) + * mat4.translate(dest, negativeOrigin); + * + * @param {mat4} out mat4 receiving operation result + * @param {quat4} q Rotation quaternion + * @param {vec3} v Translation vector + * @param {vec3} s Scaling vector + * @param {vec3} o The origin vector around which to scale and rotate + * @returns {mat4} out + */ + function fromRotationTranslationScaleOrigin(out, q, v, s, o) { + // Quaternion math + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var xy = x * y2; + var xz = x * z2; + var yy = y * y2; + var yz = y * z2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + var sx = s[0]; + var sy = s[1]; + var sz = s[2]; + var ox = o[0]; + var oy = o[1]; + var oz = o[2]; + var out0 = (1 - (yy + zz)) * sx; + var out1 = (xy + wz) * sx; + var out2 = (xz - wy) * sx; + var out4 = (xy - wz) * sy; + var out5 = (1 - (xx + zz)) * sy; + var out6 = (yz + wx) * sy; + var out8 = (xz + wy) * sz; + var out9 = (yz - wx) * sz; + var out10 = (1 - (xx + yy)) * sz; + out[0] = out0; + out[1] = out1; + out[2] = out2; + out[3] = 0; + out[4] = out4; + out[5] = out5; + out[6] = out6; + out[7] = 0; + out[8] = out8; + out[9] = out9; + out[10] = out10; + out[11] = 0; + out[12] = v[0] + ox - (out0 * ox + out4 * oy + out8 * oz); + out[13] = v[1] + oy - (out1 * ox + out5 * oy + out9 * oz); + out[14] = v[2] + oz - (out2 * ox + out6 * oy + out10 * oz); + out[15] = 1; + return out; + } + /** + * Calculates a 4x4 matrix from the given quaternion + * + * @param {mat4} out mat4 receiving operation result + * @param {quat} q Quaternion to create matrix from + * + * @returns {mat4} out + */ + function fromQuat$1(out, q) { + var x = q[0], + y = q[1], + z = q[2], + w = q[3]; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var yx = y * x2; + var yy = y * y2; + var zx = z * x2; + var zy = z * y2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + out[0] = 1 - yy - zz; + out[1] = yx + wz; + out[2] = zx - wy; + out[3] = 0; + out[4] = yx - wz; + out[5] = 1 - xx - zz; + out[6] = zy + wx; + out[7] = 0; + out[8] = zx + wy; + out[9] = zy - wx; + out[10] = 1 - xx - yy; + out[11] = 0; + out[12] = 0; + out[13] = 0; + out[14] = 0; + out[15] = 1; + return out; + } + /** + * Generates a frustum matrix with the given bounds + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {Number} left Left bound of the frustum + * @param {Number} right Right bound of the frustum + * @param {Number} bottom Bottom bound of the frustum + * @param {Number} top Top bound of the frustum + * @param {Number} near Near bound of the frustum + * @param {Number} far Far bound of the frustum + * @returns {mat4} out + */ + function frustum(out, left, right, bottom, top, near, far) { + var rl = 1 / (right - left); + var tb = 1 / (top - bottom); + var nf = 1 / (near - far); + out[0] = near * 2 * rl; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = near * 2 * tb; + out[6] = 0; + out[7] = 0; + out[8] = (right + left) * rl; + out[9] = (top + bottom) * tb; + out[10] = (far + near) * nf; + out[11] = -1; + out[12] = 0; + out[13] = 0; + out[14] = far * near * 2 * nf; + out[15] = 0; + return out; + } + /** + * Generates a perspective projection matrix with the given bounds. + * Passing null/undefined/no value for far will generate infinite projection matrix. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {number} fovy Vertical field of view in radians + * @param {number} aspect Aspect ratio. typically viewport width/height + * @param {number} near Near bound of the frustum + * @param {number} far Far bound of the frustum, can be null or Infinity + * @returns {mat4} out + */ + function perspective(out, fovy, aspect, near, far) { + var f = 1.0 / Math.tan(fovy / 2), + nf; + out[0] = f / aspect; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = f; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[11] = -1; + out[12] = 0; + out[13] = 0; + out[15] = 0; + + if (far != null && far !== Infinity) { + nf = 1 / (near - far); + out[10] = (far + near) * nf; + out[14] = 2 * far * near * nf; + } else { + out[10] = -1; + out[14] = -2 * near; + } + return out; + } + /** + * Generates a perspective projection matrix with the given field of view. + * This is primarily useful for generating projection matrices to be used + * with the still experiemental WebVR API. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {Object} fov Object containing the following values: upDegrees, downDegrees, leftDegrees, rightDegrees + * @param {number} near Near bound of the frustum + * @param {number} far Far bound of the frustum + * @returns {mat4} out + */ + function perspectiveFromFieldOfView(out, fov, near, far) { + var upTan = Math.tan(fov.upDegrees * Math.PI / 180.0); + var downTan = Math.tan(fov.downDegrees * Math.PI / 180.0); + var leftTan = Math.tan(fov.leftDegrees * Math.PI / 180.0); + var rightTan = Math.tan(fov.rightDegrees * Math.PI / 180.0); + var xScale = 2.0 / (leftTan + rightTan); + var yScale = 2.0 / (upTan + downTan); + out[0] = xScale; + out[1] = 0.0; + out[2] = 0.0; + out[3] = 0.0; + out[4] = 0.0; + out[5] = yScale; + out[6] = 0.0; + out[7] = 0.0; + out[8] = -((leftTan - rightTan) * xScale * 0.5); + out[9] = (upTan - downTan) * yScale * 0.5; + out[10] = far / (near - far); + out[11] = -1.0; + out[12] = 0.0; + out[13] = 0.0; + out[14] = far * near / (near - far); + out[15] = 0.0; + return out; + } + /** + * Generates a orthogonal projection matrix with the given bounds + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {number} left Left bound of the frustum + * @param {number} right Right bound of the frustum + * @param {number} bottom Bottom bound of the frustum + * @param {number} top Top bound of the frustum + * @param {number} near Near bound of the frustum + * @param {number} far Far bound of the frustum + * @returns {mat4} out + */ + function ortho(out, left, right, bottom, top, near, far) { + var lr = 1 / (left - right); + var bt = 1 / (bottom - top); + var nf = 1 / (near - far); + out[0] = -2 * lr; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = -2 * bt; + out[6] = 0; + out[7] = 0; + out[8] = 0; + out[9] = 0; + out[10] = 2 * nf; + out[11] = 0; + out[12] = (left + right) * lr; + out[13] = (top + bottom) * bt; + out[14] = (far + near) * nf; + out[15] = 1; + return out; + } + /** + * Generates a look-at matrix with the given eye position, focal point, and up axis. + * If you want a matrix that actually makes an object look at another object, you should use targetTo instead. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {vec3} eye Position of the viewer + * @param {vec3} center Point the viewer is looking at + * @param {vec3} up vec3 pointing up + * @returns {mat4} out + */ + function lookAt(out, eye, center, up) { + var x0, x1, x2, y0, y1, y2, z0, z1, z2, len; + var eyex = eye[0]; + var eyey = eye[1]; + var eyez = eye[2]; + var upx = up[0]; + var upy = up[1]; + var upz = up[2]; + var centerx = center[0]; + var centery = center[1]; + var centerz = center[2]; + + if (Math.abs(eyex - centerx) < EPSILON && Math.abs(eyey - centery) < EPSILON && Math.abs(eyez - centerz) < EPSILON) { + return identity$3(out); + } + z0 = eyex - centerx; + z1 = eyey - centery; + z2 = eyez - centerz; + len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2); + z0 *= len; + z1 *= len; + z2 *= len; + x0 = upy * z2 - upz * z1; + x1 = upz * z0 - upx * z2; + x2 = upx * z1 - upy * z0; + len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2); + + if (!len) { + x0 = 0; + x1 = 0; + x2 = 0; + } else { + len = 1 / len; + x0 *= len; + x1 *= len; + x2 *= len; + } + y0 = z1 * x2 - z2 * x1; + y1 = z2 * x0 - z0 * x2; + y2 = z0 * x1 - z1 * x0; + len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2); + if (!len) { + y0 = 0; + y1 = 0; + y2 = 0; + } else { + len = 1 / len; + y0 *= len; + y1 *= len; + y2 *= len; + } + out[0] = x0; + out[1] = y0; + out[2] = z0; + out[3] = 0; + out[4] = x1; + out[5] = y1; + out[6] = z1; + out[7] = 0; + out[8] = x2; + out[9] = y2; + out[10] = z2; + out[11] = 0; + out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez); + out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez); + out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez); + out[15] = 1; + return out; + } + /** + * Generates a matrix that makes something look at something else. + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {vec3} eye Position of the viewer + * @param {vec3} center Point the viewer is looking at + * @param {vec3} up vec3 pointing up + * @returns {mat4} out + */ + function targetTo(out, eye, target, up) { + var eyex = eye[0], + eyey = eye[1], + eyez = eye[2], + upx = up[0], + upy = up[1], + upz = up[2]; + var z0 = eyex - target[0], + z1 = eyey - target[1], + z2 = eyez - target[2]; + var len = z0 * z0 + z1 * z1 + z2 * z2; + + if (len > 0) { + len = 1 / Math.sqrt(len); + z0 *= len; + z1 *= len; + z2 *= len; + } + var x0 = upy * z2 - upz * z1, + x1 = upz * z0 - upx * z2, + x2 = upx * z1 - upy * z0; + len = x0 * x0 + x1 * x1 + x2 * x2; + if (len > 0) { + len = 1 / Math.sqrt(len); + x0 *= len; + x1 *= len; + x2 *= len; + } + out[0] = x0; + out[1] = x1; + out[2] = x2; + out[3] = 0; + out[4] = z1 * x2 - z2 * x1; + out[5] = z2 * x0 - z0 * x2; + out[6] = z0 * x1 - z1 * x0; + out[7] = 0; + out[8] = z0; + out[9] = z1; + out[10] = z2; + out[11] = 0; + out[12] = eyex; + out[13] = eyey; + out[14] = eyez; + out[15] = 1; + return out; + } + /** + * Returns a string representation of a mat4 + * + * @param {mat4} a matrix to represent as a string + * @returns {String} string representation of the matrix + */ + function str$3(a) { + return 'mat4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' + a[8] + ', ' + a[9] + ', ' + a[10] + ', ' + a[11] + ', ' + a[12] + ', ' + a[13] + ', ' + a[14] + ', ' + a[15] + ')'; + } + /** + * Returns Frobenius norm of a mat4 + * + * @param {mat4} a the matrix to calculate Frobenius norm of + * @returns {Number} Frobenius norm + */ + function frob$3(a) { + return Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2) + Math.pow(a[9], 2) + Math.pow(a[10], 2) + Math.pow(a[11], 2) + Math.pow(a[12], 2) + Math.pow(a[13], 2) + Math.pow(a[14], 2) + Math.pow(a[15], 2)); + } + /** + * Adds two mat4's + * + * @param {mat4} out the receiving matrix + * @param {mat4} a the first operand + * @param {mat4} b the second operand + * @returns {mat4} out + */ + function add$3(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + out[4] = a[4] + b[4]; + out[5] = a[5] + b[5]; + out[6] = a[6] + b[6]; + out[7] = a[7] + b[7]; + out[8] = a[8] + b[8]; + out[9] = a[9] + b[9]; + out[10] = a[10] + b[10]; + out[11] = a[11] + b[11]; + out[12] = a[12] + b[12]; + out[13] = a[13] + b[13]; + out[14] = a[14] + b[14]; + out[15] = a[15] + b[15]; + return out; + } + /** + * Subtracts matrix b from matrix a + * + * @param {mat4} out the receiving matrix + * @param {mat4} a the first operand + * @param {mat4} b the second operand + * @returns {mat4} out + */ + function subtract$3(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + out[3] = a[3] - b[3]; + out[4] = a[4] - b[4]; + out[5] = a[5] - b[5]; + out[6] = a[6] - b[6]; + out[7] = a[7] - b[7]; + out[8] = a[8] - b[8]; + out[9] = a[9] - b[9]; + out[10] = a[10] - b[10]; + out[11] = a[11] - b[11]; + out[12] = a[12] - b[12]; + out[13] = a[13] - b[13]; + out[14] = a[14] - b[14]; + out[15] = a[15] - b[15]; + return out; + } + /** + * Multiply each element of the matrix by a scalar. + * + * @param {mat4} out the receiving matrix + * @param {mat4} a the matrix to scale + * @param {Number} b amount to scale the matrix's elements by + * @returns {mat4} out + */ + function multiplyScalar$3(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + out[3] = a[3] * b; + out[4] = a[4] * b; + out[5] = a[5] * b; + out[6] = a[6] * b; + out[7] = a[7] * b; + out[8] = a[8] * b; + out[9] = a[9] * b; + out[10] = a[10] * b; + out[11] = a[11] * b; + out[12] = a[12] * b; + out[13] = a[13] * b; + out[14] = a[14] * b; + out[15] = a[15] * b; + return out; + } + /** + * Adds two mat4's after multiplying each element of the second operand by a scalar value. + * + * @param {mat4} out the receiving vector + * @param {mat4} a the first operand + * @param {mat4} b the second operand + * @param {Number} scale the amount to scale b's elements by before adding + * @returns {mat4} out + */ + function multiplyScalarAndAdd$3(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + out[2] = a[2] + b[2] * scale; + out[3] = a[3] + b[3] * scale; + out[4] = a[4] + b[4] * scale; + out[5] = a[5] + b[5] * scale; + out[6] = a[6] + b[6] * scale; + out[7] = a[7] + b[7] * scale; + out[8] = a[8] + b[8] * scale; + out[9] = a[9] + b[9] * scale; + out[10] = a[10] + b[10] * scale; + out[11] = a[11] + b[11] * scale; + out[12] = a[12] + b[12] * scale; + out[13] = a[13] + b[13] * scale; + out[14] = a[14] + b[14] * scale; + out[15] = a[15] + b[15] * scale; + return out; + } + /** + * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) + * + * @param {mat4} a The first matrix. + * @param {mat4} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ + function exactEquals$3(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8] && a[9] === b[9] && a[10] === b[10] && a[11] === b[11] && a[12] === b[12] && a[13] === b[13] && a[14] === b[14] && a[15] === b[15]; + } + /** + * Returns whether or not the matrices have approximately the same elements in the same position. + * + * @param {mat4} a The first matrix. + * @param {mat4} b The second matrix. + * @returns {Boolean} True if the matrices are equal, false otherwise. + */ -'use strict'; + function equals$4(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var a4 = a[4], + a5 = a[5], + a6 = a[6], + a7 = a[7]; + var a8 = a[8], + a9 = a[9], + a10 = a[10], + a11 = a[11]; + var a12 = a[12], + a13 = a[13], + a14 = a[14], + a15 = a[15]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + var b4 = b[4], + b5 = b[5], + b6 = b[6], + b7 = b[7]; + var b8 = b[8], + b9 = b[9], + b10 = b[10], + b11 = b[11]; + var b12 = b[12], + b13 = b[13], + b14 = b[14], + b15 = b[15]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8)) && Math.abs(a9 - b9) <= EPSILON * Math.max(1.0, Math.abs(a9), Math.abs(b9)) && Math.abs(a10 - b10) <= EPSILON * Math.max(1.0, Math.abs(a10), Math.abs(b10)) && Math.abs(a11 - b11) <= EPSILON * Math.max(1.0, Math.abs(a11), Math.abs(b11)) && Math.abs(a12 - b12) <= EPSILON * Math.max(1.0, Math.abs(a12), Math.abs(b12)) && Math.abs(a13 - b13) <= EPSILON * Math.max(1.0, Math.abs(a13), Math.abs(b13)) && Math.abs(a14 - b14) <= EPSILON * Math.max(1.0, Math.abs(a14), Math.abs(b14)) && Math.abs(a15 - b15) <= EPSILON * Math.max(1.0, Math.abs(a15), Math.abs(b15)); + } + /** + * Alias for {@link mat4.multiply} + * @function + */ -/** - * 어떤 일을 하고 있습니까? - * @class GeometryModifier - */ -var GeometryModifier = function() -{ - if (!(this instanceof GeometryModifier)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } -}; + var mul$3 = multiply$3; + /** + * Alias for {@link mat4.subtract} + * @function + */ -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param f4dPoint3d 변수 - * @param px 변수 - * @param py 변수 - * @param pz 변수 - */ -GeometryModifier.prototype.setPoint3d = function(f4dPoint3d, px, py, pz) -{ - f4dPoint3d.x = px; - f4dPoint3d.y = py; - f4dPoint3d.z = pz; -}; + var sub$3 = subtract$3; + + var mat4 = /*#__PURE__*/Object.freeze({ + create: create$3, + clone: clone$3, + copy: copy$3, + fromValues: fromValues$3, + set: set$3, + identity: identity$3, + transpose: transpose$2, + invert: invert$3, + adjoint: adjoint$2, + determinant: determinant$3, + multiply: multiply$3, + translate: translate$2, + scale: scale$3, + rotate: rotate$3, + rotateX: rotateX, + rotateY: rotateY, + rotateZ: rotateZ, + fromTranslation: fromTranslation$2, + fromScaling: fromScaling$3, + fromRotation: fromRotation$3, + fromXRotation: fromXRotation, + fromYRotation: fromYRotation, + fromZRotation: fromZRotation, + fromRotationTranslation: fromRotationTranslation, + fromQuat2: fromQuat2, + getTranslation: getTranslation, + getScaling: getScaling, + getRotation: getRotation, + fromRotationTranslationScale: fromRotationTranslationScale, + fromRotationTranslationScaleOrigin: fromRotationTranslationScaleOrigin, + fromQuat: fromQuat$1, + frustum: frustum, + perspective: perspective, + perspectiveFromFieldOfView: perspectiveFromFieldOfView, + ortho: ortho, + lookAt: lookAt, + targetTo: targetTo, + str: str$3, + frob: frob$3, + add: add$3, + subtract: subtract$3, + multiplyScalar: multiplyScalar$3, + multiplyScalarAndAdd: multiplyScalarAndAdd$3, + exactEquals: exactEquals$3, + equals: equals$4, + mul: mul$3, + sub: sub$3 + }); -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * @param f4dPoint3d 변수 - * @param px 변수 - * @param py 변수 - * @param pz 변수 - * @retuns dx*dx + dy*dy + dz*dz - */ -GeometryModifier.prototype.point3dSquareDistTo = function(f4dPoint3d, px, py, pz) -{ - var dx = f4dPoint3d.x - px; - var dy = f4dPoint3d.y - py; - var dz = f4dPoint3d.z - pz; + /** + * 3 Dimensional Vector + * @module vec3 + */ - return dx*dx + dy*dy + dz*dz; -}; + /** + * Creates a new, empty vec3 + * + * @returns {vec3} a new 3D vector + */ -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param matrix4 변수 - * @param float32array 변수 - */ -GeometryModifier.prototype.Matrix4SetByFloat32Array = function(matrix4, float32array) -{ - for (var i = 0; i < 16; i++) - { - matrix4._floatArrays[i] = float32array[i]; - } -}; + function create$4() { + var out = new ARRAY_TYPE(3); -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param matrix4 변수 - * @param point3d 변수 - * @returns transformedPoint3d - */ -GeometryModifier.prototype.Matrix4TransformPoint3D = function(matrix4, point3d) -{ - var transformedPoint3d = new Point3D(); - // t.x= q.x*m[0][0] + q.y*m[1][0] + q.z*m[2][0] + m[3][0]; - // t.y= q.x*m[0][1] + q.y*m[1][1] + q.z*m[2][1] + m[3][1]; - // t.z= q.x*m[0][2] + q.y*m[1][2] + q.z*m[2][2] + m[3][2]; + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + } - // Note: idx = 4*col+row;.*** - //_floatArrays + return out; + } + /** + * Creates a new vec3 initialized with values from an existing vector + * + * @param {vec3} a vector to clone + * @returns {vec3} a new 3D vector + */ - // Old version.************************************************************************************************************************* - //transformedPoint3d.x = point3d.x*matrix4.get(0,0) + point3d.y*matrix4.get(1,0) + point3d.z*matrix4.get(2,0) + matrix4.get(3,0); - //transformedPoint3d.y = point3d.x*matrix4.get(0,1) + point3d.y*matrix4.get(1,1) + point3d.z*matrix4.get(2,1) + matrix4.get(3,1); - //transformedPoint3d.z = point3d.x*matrix4.get(0,2) + point3d.y*matrix4.get(1,2) + point3d.z*matrix4.get(2,2) + matrix4.get(3,2); - //-------------------------------------------------------------------------------------------------------------------------------------- + function clone$4(a) { + var out = new ARRAY_TYPE(3); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + return out; + } + /** + * Calculates the length of a vec3 + * + * @param {vec3} a vector to calculate length of + * @returns {Number} length of a + */ - // New version. Acces directly to the array.********************************************************************************************************************** - transformedPoint3d.x = point3d.x*matrix4._floatArrays[0] + point3d.y*matrix4._floatArrays[4] + point3d.z*matrix4._floatArrays[8] + matrix4._floatArrays[12]; - transformedPoint3d.y = point3d.x*matrix4._floatArrays[1] + point3d.y*matrix4._floatArrays[5] + point3d.z*matrix4._floatArrays[9] + matrix4._floatArrays[13]; - transformedPoint3d.z = point3d.x*matrix4._floatArrays[2] + point3d.y*matrix4._floatArrays[6] + point3d.z*matrix4._floatArrays[10] + matrix4._floatArrays[14]; - //---------------------------------------------------------------------------------------------------------------------------------------------------------------- + function length(a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + return Math.sqrt(x * x + y * y + z * z); + } + /** + * Creates a new vec3 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @returns {vec3} a new 3D vector + */ - return transformedPoint3d; -}; + function fromValues$4(x, y, z) { + var out = new ARRAY_TYPE(3); + out[0] = x; + out[1] = y; + out[2] = z; + return out; + } + /** + * Copy the values from one vec3 to another + * + * @param {vec3} out the receiving vector + * @param {vec3} a the source vector + * @returns {vec3} out + */ -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param matrixA 변수 - * @param matrixB 변수 - * @retuns resultMat - */ -GeometryModifier.prototype.Matrix4GetMultipliedByMatrix = function(matrixA, matrixB) -{ - //CKK_Matrix4 operator*(const CKK_Matrix4 &A) - //{ - // // Copied From Carve.*** - // CKK_Matrix4 c; - // for (int i = 0; i < 4; i++) { - // for (int j = 0; j < 4; j++) { - // c.m[i][j] = 0.0; - // for (int k = 0; k < 4; k++) { - // c.m[i][j] += A.m[k][j] * m[i][k]; - // } - // } - // } - // return c; - //} + function copy$4(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + return out; + } + /** + * Set the components of a vec3 to the given values + * + * @param {vec3} out the receiving vector + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @returns {vec3} out + */ - var resultMat = new Matrix4(); - for (var i = 0; i < 4; i++) - { - for (var j = 0; j < 4; j++) - { - // Note: idx = 4*col+row;.*** - //var idx = matrixA.getIndexOfArray(i, j); // Old.*** - var idx = 4*i + j; - resultMat._floatArrays[idx] = 0.0; - for (var k = 0; k < 4; k++) - { - resultMat._floatArrays[idx] += matrixB._floatArrays[4*k + j] * matrixA._floatArrays[4*i + k]; - } - } - } - return resultMat; -}; + function set$4(out, x, y, z) { + out[0] = x; + out[1] = y; + out[2] = z; + return out; + } + /** + * Adds two vec3's + * + * @param {vec3} out the receiving vector + * @param {vec3} a the first operand + * @param {vec3} b the second operand + * @returns {vec3} out + */ -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param reference 변수 - * @param matrix 변수 - */ -GeometryModifier.prototype.referenceMultiplyTransformMatrix = function(reference, matrix) -{ - //var multipliedMat = reference._matrix4.getMultipliedByMatrix(matrix); // Original.*** - var multipliedMat = this.Matrix4GetMultipliedByMatrix(reference._matrix4, matrix); // Original.*** - reference._matrix4 = multipliedMat; -}; + function add$4(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + return out; + } + /** + * Subtracts vector b from vector a + * + * @param {vec3} out the receiving vector + * @param {vec3} a the first operand + * @param {vec3} b the second operand + * @returns {vec3} out + */ -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param compRefList 변수 - * @param matrix 변수 - */ -GeometryModifier.prototype.compoundReferencesListMultiplyReferencesMatrices = function(compRefList, matrix) -{ - var compRefsCount = compRefList._compoundRefsArray.length; - for (var i = 0; i < compRefsCount; i++) - { - var compRef = compRefList._compoundRefsArray[i]; - var refsCount = compRef._referencesList.length; - for (var j = 0; j < refsCount; j++) - { - var reference = compRef._referencesList[j]; - //reference.multiplyTransformMatrix(matrix);// Old.*** - this.referenceMultiplyTransformMatrix(reference, matrix); - } - } -}; + function subtract$4(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + return out; + } + /** + * Multiplies two vec3's + * + * @param {vec3} out the receiving vector + * @param {vec3} a the first operand + * @param {vec3} b the second operand + * @returns {vec3} out + */ -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param compRefList 변수 - * @param eyeX 변수 - * @param eyeY 변수 - * @param eyeZ 변수 - * @returns visibleCompRefObjectsArray - */ -GeometryModifier.prototype.compoundReferencesListGetVisibleCompRefObjectsList = function(compRefList, eyeX, eyeY, eyeZ) -{ - /* - // https://gist.github.com/72lions/4528834 - var _appendBuffer = function(buffer1, buffer2) { - var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength); - tmp.set(new Uint8Array(buffer1), 0); - tmp.set(new Uint8Array(buffer2), buffer1.byteLength); - return tmp.buffer; -}; -*/ + function multiply$4(out, a, b) { + out[0] = a[0] * b[0]; + out[1] = a[1] * b[1]; + out[2] = a[2] * b[2]; + return out; + } + /** + * Divides two vec3's + * + * @param {vec3} out the receiving vector + * @param {vec3} a the first operand + * @param {vec3} b the second operand + * @returns {vec3} out + */ - var visibleCompRefObjectsArray = new CompoundReferencesList(); - visibleCompRefObjectsArray._myBlocksList = compRefList._myBlocksList; + function divide(out, a, b) { + out[0] = a[0] / b[0]; + out[1] = a[1] / b[1]; + out[2] = a[2] / b[2]; + return out; + } + /** + * Math.ceil the components of a vec3 + * + * @param {vec3} out the receiving vector + * @param {vec3} a vector to ceil + * @returns {vec3} out + */ - var ocCullingBox = compRefList._ocCulling._ocCulling_box; - var indicesVisiblesArrayInterior = this.occlusionCullingOctreeCellGetIndicesVisiblesForEye(ocCullingBox, eyeX, eyeY, eyeZ); - if (indicesVisiblesArrayInterior) - { - var indicesCount = indicesVisiblesArrayInterior.length; - for (var i = 0; i < indicesCount; i++) - { - visibleCompRefObjectsArray._compoundRefsArray.push(compRefList._compoundRefsArray[indicesVisiblesArrayInterior[i]]); - } + function ceil(out, a) { + out[0] = Math.ceil(a[0]); + out[1] = Math.ceil(a[1]); + out[2] = Math.ceil(a[2]); + return out; + } + /** + * Math.floor the components of a vec3 + * + * @param {vec3} out the receiving vector + * @param {vec3} a vector to floor + * @returns {vec3} out + */ - } + function floor(out, a) { + out[0] = Math.floor(a[0]); + out[1] = Math.floor(a[1]); + out[2] = Math.floor(a[2]); + return out; + } + /** + * Returns the minimum of two vec3's + * + * @param {vec3} out the receiving vector + * @param {vec3} a the first operand + * @param {vec3} b the second operand + * @returns {vec3} out + */ - var infiniteOcCullingBox = compRefList._ocCulling._infinite_ocCulling_box; - var indicesVisiblesArrayExterior = this.occlusionCullingOctreeCellGetIndicesVisiblesForEye(infiniteOcCullingBox, eye_x, eye_y, eye_z); - if (indicesVisiblesArrayExterior) - { - var indicesCount = indicesVisiblesArrayExterior.length; - for (var i = 0; i < indicesCount; i++) - { - visibleCompRefObjectsArray._compoundRefsArray.push(compRefList._compoundRefsArray[indicesVisiblesArrayExterior[i]]); - } - } + function min(out, a, b) { + out[0] = Math.min(a[0], b[0]); + out[1] = Math.min(a[1], b[1]); + out[2] = Math.min(a[2], b[2]); + return out; + } + /** + * Returns the maximum of two vec3's + * + * @param {vec3} out the receiving vector + * @param {vec3} a the first operand + * @param {vec3} b the second operand + * @returns {vec3} out + */ - if (visibleCompRefObjectsArray && visibleCompRefObjectsArray.length === 0) { return null; } + function max(out, a, b) { + out[0] = Math.max(a[0], b[0]); + out[1] = Math.max(a[1], b[1]); + out[2] = Math.max(a[2], b[2]); + return out; + } + /** + * Math.round the components of a vec3 + * + * @param {vec3} out the receiving vector + * @param {vec3} a vector to round + * @returns {vec3} out + */ - return visibleCompRefObjectsArray; -}; + function round(out, a) { + out[0] = Math.round(a[0]); + out[1] = Math.round(a[1]); + out[2] = Math.round(a[2]); + return out; + } + /** + * Scales a vec3 by a scalar number + * + * @param {vec3} out the receiving vector + * @param {vec3} a the vector to scale + * @param {Number} b amount to scale the vector by + * @returns {vec3} out + */ -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param compRefListContainer 변수 - * @param eyeX 변수 - * @param eyeY 변수 - * @param eyeZ 변수 - * @returns visibleCompRefObjectsArrayTotal - */ -GeometryModifier.prototype.compoundReferencesListContainerGetVisibleCompRefObjectsList = function(compRefListContainer, eyeX, eyeY, eyeZ) -{ - var visibleCompRefObjectsArrayTotal = []; - var compRefList = undefined; - var compRefListsCount = compRefListContainer.compRefsListArray.length; - for (var i = 0; i < compRefListsCount; i++) - { - compRefList = compRefListContainer.compRefsListArray[i]; - var visibleCompRefObjectsArray = this.compoundReferencesListGetVisibleCompRefObjectsList(compRefList, eyeX, eyeY, eyeZ); - if (visibleCompRefObjectsArray !== null) - { visibleCompRefObjectsArrayTotal.push(visibleCompRefObjectsArray); } - } - return visibleCompRefObjectsArrayTotal; -}; + function scale$4(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + out[2] = a[2] * b; + return out; + } + /** + * Adds two vec3's after scaling the second operand by a scalar value + * + * @param {vec3} out the receiving vector + * @param {vec3} a the first operand + * @param {vec3} b the second operand + * @param {Number} scale the amount to scale b by before adding + * @returns {vec3} out + */ -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param buildingProject 변수 - * @param eyeX 변수 - * @param eyeY 변수 - * @param eyeZ 변수 - * @returns totalVisibleCompRefLists - */ -GeometryModifier.prototype.bRbuildingProjectGetVisibleCompRefLists = function(buildingProject, eyeX, eyeY, eyeZ) -{ - // 1rst, check if the eye is in the building.*** - var InteriorCompRefListContainer = buildingProject._interiorCompRefList_Container; - var interior_visibleCompRefLists = this.compoundReferencesListContainerGetVisibleCompRefObjectsList(InteriorCompRefListContainer, eye_x, eye_y, eye_z); + function scaleAndAdd(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + out[2] = a[2] + b[2] * scale; + return out; + } + /** + * Calculates the euclidian distance between two vec3's + * + * @param {vec3} a the first operand + * @param {vec3} b the second operand + * @returns {Number} distance between a and b + */ - var compRefListContainer = buildingProject._compRefList_Container; - var visibleCompRefLists = this.compoundReferencesListContainerGetVisibleCompRefObjectsList(compRefListContainer, eyeX, eyeY, eyeZ); + function distance(a, b) { + var x = b[0] - a[0]; + var y = b[1] - a[1]; + var z = b[2] - a[2]; + return Math.sqrt(x * x + y * y + z * z); + } + /** + * Calculates the squared euclidian distance between two vec3's + * + * @param {vec3} a the first operand + * @param {vec3} b the second operand + * @returns {Number} squared distance between a and b + */ - var totalVisibleCompRefLists = visibleCompRefLists.concat(interior_visibleCompRefLists); + function squaredDistance(a, b) { + var x = b[0] - a[0]; + var y = b[1] - a[1]; + var z = b[2] - a[2]; + return x * x + y * y + z * z; + } + /** + * Calculates the squared length of a vec3 + * + * @param {vec3} a vector to calculate squared length of + * @returns {Number} squared length of a + */ - return totalVisibleCompRefLists; -}; + function squaredLength(a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + return x * x + y * y + z * z; + } + /** + * Negates the components of a vec3 + * + * @param {vec3} out the receiving vector + * @param {vec3} a vector to negate + * @returns {vec3} out + */ -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param ocCullOctreeCell 변수 - * @param minX 변수 - * @param maxX 변수 - * @param minY 변수 - * @param maxY 변수 - * @param minZ 변수 - * @param maxZ 변수 - */ -GeometryModifier.prototype.occlusionCullingOctreeCellSetDimensions = function(ocCullOctreeCell, minX, maxX, minY, maxY, minZ, maxZ) -{ - ocCullOctreeCell.minX = minX; - ocCullOctreeCell.maxX = maxX; - ocCullOctreeCell.minY = minY; - ocCullOctreeCell.maxY = maxY; - ocCullOctreeCell.minZ = minZ; - ocCullOctreeCell.maxZ = maxZ; -}; + function negate(out, a) { + out[0] = -a[0]; + out[1] = -a[1]; + out[2] = -a[2]; + return out; + } + /** + * Returns the inverse of the components of a vec3 + * + * @param {vec3} out the receiving vector + * @param {vec3} a vector to invert + * @returns {vec3} out + */ -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param ocCullOctreeCell 변수 - */ -GeometryModifier.prototype.occlusionCullingOctreeCellSetSizesSubBoxes = function(ocCullOctreeCell) -{ - // Bottom Top - // |----------|----------| |----------|----------| - // | | | | | | Y - // | 3 | 2 | | 7 | 6 | ^ - // | | | | | | | - // |----------|----------| |----------|----------| | - // | | | | | | | - // | 0 | 1 | | 4 | 5 | | - // | | | | | | -----------------> X - // |----------|----------| |----------|----------| + function inverse(out, a) { + out[0] = 1.0 / a[0]; + out[1] = 1.0 / a[1]; + out[2] = 1.0 / a[2]; + return out; + } + /** + * Normalize a vec3 + * + * @param {vec3} out the receiving vector + * @param {vec3} a vector to normalize + * @returns {vec3} out + */ - if (ocCullOctreeCell._subBoxesArray.length > 0) - { - var halfX = (ocCullOctreeCell.maxX + ocCullOctreeCell.minX)/2.0; - var halfY = (ocCullOctreeCell.maxY + ocCullOctreeCell.minY)/2.0; - var halfZ = (ocCullOctreeCell.maxZ + ocCullOctreeCell.minZ)/2.0; + function normalize(out, a) { + var x = a[0]; + var y = a[1]; + var z = a[2]; + var len = x * x + y * y + z * z; - // Old.*************************************************************************************************************************************************** - //ocCullOctreeCell._subBoxesArray[0].setDimensions(ocCullOctreeCell.minX, halfX, ocCullOctreeCell.minY, halfY, ocCullOctreeCell.minZ, halfZ); - //ocCullOctreeCell._subBoxesArray[1].setDimensions(halfX, ocCullOctreeCell.maxX, ocCullOctreeCell.minY, halfY, ocCullOctreeCell.minZ, halfZ); - //ocCullOctreeCell._subBoxesArray[2].setDimensions(halfX, ocCullOctreeCell.maxX, halfY, ocCullOctreeCell.maxY, ocCullOctreeCell.minZ, halfZ); - //ocCullOctreeCell._subBoxesArray[3].setDimensions(ocCullOctreeCell.minX, halfX, halfY, ocCullOctreeCell.maxY, ocCullOctreeCell.minZ, halfZ); + if (len > 0) { + //TODO: evaluate use of glm_invsqrt here? + len = 1 / Math.sqrt(len); + } - //ocCullOctreeCell._subBoxesArray[4].setDimensions(ocCullOctreeCell.minX, halfX, ocCullOctreeCell.minY, halfY, halfZ, ocCullOctreeCell.maxZ); - //ocCullOctreeCell._subBoxesArray[5].setDimensions(halfX, ocCullOctreeCell.maxX, ocCullOctreeCell.minY, halfY, halfZ, ocCullOctreeCell.maxZ); - //ocCullOctreeCell._subBoxesArray[6].setDimensions(halfX, ocCullOctreeCell.maxX, halfY, ocCullOctreeCell.maxY, halfZ, ocCullOctreeCell.maxZ); - //ocCullOctreeCell._subBoxesArray[7].setDimensions(ocCullOctreeCell.minX, halfX, halfY, ocCullOctreeCell.maxY, halfZ, ocCullOctreeCell.maxZ); + out[0] = a[0] * len; + out[1] = a[1] * len; + out[2] = a[2] * len; + return out; + } + /** + * Calculates the dot product of two vec3's + * + * @param {vec3} a the first operand + * @param {vec3} b the second operand + * @returns {Number} dot product of a and b + */ - // New version.********************************************************************************************************************************************* - this.occlusionCullingOctreeCellSetDimensions(ocCullOctreeCell._subBoxesArray[0], ocCullOctreeCell.minX, halfX, ocCullOctreeCell.minY, halfY, ocCullOctreeCell.minZ, halfZ); - this.occlusionCullingOctreeCellSetDimensions(ocCullOctreeCell._subBoxesArray[1], halfX, ocCullOctreeCell.maxX, ocCullOctreeCell.minY, halfY, ocCullOctreeCell.minZ, halfZ); - this.occlusionCullingOctreeCellSetDimensions(ocCullOctreeCell._subBoxesArray[2], halfX, ocCullOctreeCell.maxX, halfY, ocCullOctreeCell.maxY, ocCullOctreeCell.minZ, halfZ); - this.occlusionCullingOctreeCellSetDimensions(ocCullOctreeCell._subBoxesArray[3], ocCullOctreeCell.minX, halfX, halfY, ocCullOctreeCell.maxY, ocCullOctreeCell.minZ, half_z); + function dot(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; + } + /** + * Computes the cross product of two vec3's + * + * @param {vec3} out the receiving vector + * @param {vec3} a the first operand + * @param {vec3} b the second operand + * @returns {vec3} out + */ - this.occlusionCullingOctreeCellSetDimensions(ocCullOctreeCell._subBoxesArray[4], ocCullOctreeCell.minX, halfX, ocCullOctreeCell.minY, halfY, halfZ, ocCullOctreeCell.maxZ); - this.occlusionCullingOctreeCellSetDimensions(ocCullOctreeCell._subBoxesArray[5], halfX, ocCullOctreeCell.maxX, ocCullOctreeCell.minY, halfY, halfZ, ocCullOctreeCell.maxZ); - this.occlusionCullingOctreeCellSetDimensions(ocCullOctreeCell._subBoxesArray[6], halfX, ocCullOctreeCell.maxX, halfY, ocCullOctreeCell.maxY, halfZ, ocCullOctreeCell.maxZ); - this.occlusionCullingOctreeCellSetDimensions(ocCullOctreeCell._subBoxesArray[7], ocCullOctreeCell.minX, halfX, halfY, ocCullOctreeCell.maxY, halfZ, ocCullOctreeCell.maxZ); - //------------------------------------------------------------------------------------------------------------------------------------------------------------- + function cross(out, a, b) { + var ax = a[0], + ay = a[1], + az = a[2]; + var bx = b[0], + by = b[1], + bz = b[2]; + out[0] = ay * bz - az * by; + out[1] = az * bx - ax * bz; + out[2] = ax * by - ay * bx; + return out; + } + /** + * Performs a linear interpolation between two vec3's + * + * @param {vec3} out the receiving vector + * @param {vec3} a the first operand + * @param {vec3} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {vec3} out + */ - for (var i = 0; i < ocCullOctreeCell._subBoxesArray.length; i++) - { - //ocCullOctreeCell._subBoxesArray[i].setSizesSubBoxes(); // Old.*** - this.occlusionCullingOctreeCellSetSizesSubBoxes(ocCullOctreeCell._subBoxesArray[i]); - } - } -}; + function lerp(out, a, b, t) { + var ax = a[0]; + var ay = a[1]; + var az = a[2]; + out[0] = ax + t * (b[0] - ax); + out[1] = ay + t * (b[1] - ay); + out[2] = az + t * (b[2] - az); + return out; + } + /** + * Performs a hermite interpolation with two control points + * + * @param {vec3} out the receiving vector + * @param {vec3} a the first operand + * @param {vec3} b the second operand + * @param {vec3} c the third operand + * @param {vec3} d the fourth operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {vec3} out + */ -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param ocCullOctreeCell 변수 - * @param x 변수 - * @param y 변수 - * @param z 변수 - * @returns intersects - */ -GeometryModifier.prototype.occlusionCullingOctreeCellIntersectsWithPoint3D = function(ocCullOctreeCell, x, y, z) -{ - var intersects = false; + function hermite(out, a, b, c, d, t) { + var factorTimes2 = t * t; + var factor1 = factorTimes2 * (2 * t - 3) + 1; + var factor2 = factorTimes2 * (t - 2) + t; + var factor3 = factorTimes2 * (t - 1); + var factor4 = factorTimes2 * (3 - 2 * t); + out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4; + out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4; + out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4; + return out; + } + /** + * Performs a bezier interpolation with two control points + * + * @param {vec3} out the receiving vector + * @param {vec3} a the first operand + * @param {vec3} b the second operand + * @param {vec3} c the third operand + * @param {vec3} d the fourth operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {vec3} out + */ - if (x > ocCullOctreeCell.minX && x < ocCullOctreeCell.maxX) - { - if (y > ocCullOctreeCell.minY && y < ocCullOctreeCell.maxY) - { - if (z > ocCullOctreeCell.minZ && z < ocCullOctreeCell.maxZ) - { - intersects = true; - } - } - } + function bezier(out, a, b, c, d, t) { + var inverseFactor = 1 - t; + var inverseFactorTimesTwo = inverseFactor * inverseFactor; + var factorTimes2 = t * t; + var factor1 = inverseFactorTimesTwo * inverseFactor; + var factor2 = 3 * t * inverseFactorTimesTwo; + var factor3 = 3 * factorTimes2 * inverseFactor; + var factor4 = factorTimes2 * t; + out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4; + out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4; + out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4; + return out; + } + /** + * Generates a random vector with the given scale + * + * @param {vec3} out the receiving vector + * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned + * @returns {vec3} out + */ - return intersects; -}; + function random(out, scale) { + scale = scale || 1.0; + var r = RANDOM() * 2.0 * Math.PI; + var z = RANDOM() * 2.0 - 1.0; + var zScale = Math.sqrt(1.0 - z * z) * scale; + out[0] = Math.cos(r) * zScale; + out[1] = Math.sin(r) * zScale; + out[2] = z * scale; + return out; + } + /** + * Transforms the vec3 with a mat4. + * 4th vector component is implicitly '1' + * + * @param {vec3} out the receiving vector + * @param {vec3} a the vector to transform + * @param {mat4} m matrix to transform with + * @returns {vec3} out + */ -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param ocCullOctreeCell 변수 - * @param x 변수 - * @param y 변수 - * @param z 변수 - * @returns intersectedSubBox - */ -GeometryModifier.prototype.occlusionCullingOctreeCellGetIntersectedSubBoxByPoint3D = function(ocCullOctreeCell, x, y, z) -{ - var intersectedSubBox = null; + function transformMat4(out, a, m) { + var x = a[0], + y = a[1], + z = a[2]; + var w = m[3] * x + m[7] * y + m[11] * z + m[15]; + w = w || 1.0; + out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w; + out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w; + out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w; + return out; + } + /** + * Transforms the vec3 with a mat3. + * + * @param {vec3} out the receiving vector + * @param {vec3} a the vector to transform + * @param {mat3} m the 3x3 matrix to transform with + * @returns {vec3} out + */ - if (ocCullOctreeCell._ocCulling_Cell_owner === null) - { - // This is the mother_cell.*** - if (!this.occlusionCullingOctreeCellIntersectsWithPoint3D(ocCullOctreeCell, x, y, z)) - { - return null; - } - } + function transformMat3(out, a, m) { + var x = a[0], + y = a[1], + z = a[2]; + out[0] = x * m[0] + y * m[3] + z * m[6]; + out[1] = x * m[1] + y * m[4] + z * m[7]; + out[2] = x * m[2] + y * m[5] + z * m[8]; + return out; + } + /** + * Transforms the vec3 with a quat + * Can also be used for dual quaternions. (Multiply it with the real part) + * + * @param {vec3} out the receiving vector + * @param {vec3} a the vector to transform + * @param {quat} q quaternion to transform with + * @returns {vec3} out + */ - var subBoxesCount = ocCullOctreeCell._subBoxesArray.length; - if (subBoxesCount > 0) - { - var centerX = (ocCullOctreeCell.minX + ocCullOctreeCell.maxX)/2.0; - var centerY = (ocCullOctreeCell.minY + ocCullOctreeCell.maxY)/2.0; - var centerZ = (ocCullOctreeCell.minZ + ocCullOctreeCell.maxZ)/2.0; + function transformQuat(out, a, q) { + // benchmarks: https://jsperf.com/quaternion-transform-vec3-implementations-fixed + var qx = q[0], + qy = q[1], + qz = q[2], + qw = q[3]; + var x = a[0], + y = a[1], + z = a[2]; // var qvec = [qx, qy, qz]; + // var uv = vec3.cross([], qvec, a); + + var uvx = qy * z - qz * y, + uvy = qz * x - qx * z, + uvz = qx * y - qy * x; // var uuv = vec3.cross([], qvec, uv); + + var uuvx = qy * uvz - qz * uvy, + uuvy = qz * uvx - qx * uvz, + uuvz = qx * uvy - qy * uvx; // vec3.scale(uv, uv, 2 * w); + + var w2 = qw * 2; + uvx *= w2; + uvy *= w2; + uvz *= w2; // vec3.scale(uuv, uuv, 2); + + uuvx *= 2; + uuvy *= 2; + uuvz *= 2; // return vec3.add(out, a, vec3.add(out, uv, uuv)); + + out[0] = x + uvx + uuvx; + out[1] = y + uvy + uuvy; + out[2] = z + uvz + uuvz; + return out; + } + /** + * Rotate a 3D vector around the x-axis + * @param {vec3} out The receiving vec3 + * @param {vec3} a The vec3 point to rotate + * @param {vec3} b The origin of the rotation + * @param {Number} c The angle of rotation + * @returns {vec3} out + */ - var intersectedSubBoxAux = null; - var intersectedSubBoxIdx = undefined; + function rotateX$1(out, a, b, c) { + var p = [], + r = []; //Translate point to the origin - if (x < centerX) - { - // Here are the boxes number 0, 3, 4, 7.*** - if (y < centerY) - { - // Here are 0, 4.*** - if (z < centerZ) { intersectedSubBoxIdx = 0; } - else { intersectedSubBoxIdx = 4; } - } - else - { - // Here are 3, 7.*** - if (z < centerZ) { intersectedSubBoxIdx = 3; } - else { intersectedSubBoxIdx = 7; } - } - } - else - { - // Here are the boxes number 1, 2, 5, 6.*** - if (y 0) - { - indicesVisiblesArray = intersectedSubBox._indicesArray; - } + r[0] = p[2] * Math.sin(c) + p[0] * Math.cos(c); + r[1] = p[1]; + r[2] = p[2] * Math.cos(c) - p[0] * Math.sin(c); //translate to correct position - return indicesVisiblesArray; -}; + out[0] = r[0] + b[0]; + out[1] = r[1] + b[1]; + out[2] = r[2] + b[2]; + return out; + } + /** + * Rotate a 3D vector around the z-axis + * @param {vec3} out The receiving vec3 + * @param {vec3} a The vec3 point to rotate + * @param {vec3} b The origin of the rotation + * @param {Number} c The angle of rotation + * @returns {vec3} out + */ -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param ocCullOctreeCell 변수 - * @param expansionDist 변수 - */ -GeometryModifier.prototype.occlusionCullingOctreeCellExpandBox = function(ocCullOctreeCell, expansionDist) -{ - ocCullOctreeCell.minX -= expansionDist; - ocCullOctreeCell.maxX += expansionDist; - ocCullOctreeCell.minY -= expansionDist; - ocCullOctreeCell.maxY += expansionDist; - ocCullOctreeCell.minZ -= expansionDist; - ocCullOctreeCell.maxZ += expansionDist; -}; + function rotateZ$1(out, a, b, c) { + var p = [], + r = []; //Translate point to the origin -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param vtArraysCacheKeys_container 변수 - * @returns vtCacheKey - */ -GeometryModifier.prototype.vertexTexcoordsArraysCacheKeysContainerNewVertexTexcoordsArraysCacheKey = function(vtArraysCacheKeys_container) -{ - var vtCacheKey = new VertexTexcoordsArraysCacheKeys(); - vtArraysCacheKeys_container._vtArrays_cacheKeys_array.push(vtCacheKey); - return vtCacheKey; -}; + p[0] = a[0] - b[0]; + p[1] = a[1] - b[1]; + p[2] = a[2] - b[2]; //perform rotation -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param blockList 변수 - * @param idx 변수 - * @returns block - */ -GeometryModifier.prototype.blocksListGetBlock = function(blockList, idx) -{ - var block = null; + r[0] = p[0] * Math.cos(c) - p[1] * Math.sin(c); + r[1] = p[0] * Math.sin(c) + p[1] * Math.cos(c); + r[2] = p[2]; //translate to correct position - if (idx >= 0 && idx < blockList.blocksArray.length) - { - block = blockList.blocksArray[idx]; - } - return block; -}; + out[0] = r[0] + b[0]; + out[1] = r[1] + b[1]; + out[2] = r[2] + b[2]; + return out; + } + /** + * Get the angle between two 3D vectors + * @param {vec3} a The first operand + * @param {vec3} b The second operand + * @returns {Number} The angle in radians + */ -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param blockListContainer 변수 - * @param blocksListName 변수 - * @returns blocksList - */ -GeometryModifier.prototype.blocksListsContainerNewBlocksList = function(blockListContainer, blocksListName) -{ - var blocksList = new BlocksList(); - blocksList.name = blocksListName; - blockListContainer.blocksListsArray.push(blocksList); - return blocksList; -}; + function angle(a, b) { + var tempA = fromValues$4(a[0], a[1], a[2]); + var tempB = fromValues$4(b[0], b[1], b[2]); + normalize(tempA, tempA); + normalize(tempB, tempB); + var cosine = dot(tempA, tempB); + + if (cosine > 1.0) { + return 0; + } else if (cosine < -1.0) { + return Math.PI; + } else { + return Math.acos(cosine); + } + } + /** + * Set the components of a vec3 to zero + * + * @param {vec3} out the receiving vector + * @returns {vec3} out + */ -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param blockListContainer 변수 - * @param blocksListName 변수 - * @returns blocksList - */ -GeometryModifier.prototype.blocksListsContainerGetBlockList = function(blockListContainer, blocksListName) -{ - var blocksListsCount = blockListContainer.blocksListsArray.length; - var found = false; - var i = 0; - var blocksList = null; - while (!found && i < blocksListsCount) - { - var currentBlocksList = blockListContainer.blocksListsArray[i]; - if (currentBlocksList.name === blocksListName) - { - found = true; - blocksList = currentBlocksList; - } - i++; - } - return blocksList; -}; + function zero(out) { + out[0] = 0.0; + out[1] = 0.0; + out[2] = 0.0; + return out; + } + /** + * Returns a string representation of a vector + * + * @param {vec3} a vector to represent as a string + * @returns {String} string representation of the vector + */ -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param buildingProject 변수 - */ -GeometryModifier.prototype.bRbuildingProjectCreateDefaultBlockReferencesLists = function(buildingProject) -{ - // Create 5 BlocksLists: "Blocks1", "Blocks2", "Blocks3", Blocks4" and "BlocksBone".*** + function str$4(a) { + return 'vec3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ')'; + } + /** + * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===) + * + * @param {vec3} a The first vector. + * @param {vec3} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ - // Old.********************************************************* - //this._blocksList_Container.newBlocksList("Blocks1"); - //this._blocksList_Container.newBlocksList("Blocks2"); - //this._blocksList_Container.newBlocksList("Blocks3"); - //this._blocksList_Container.newBlocksList("Blocks4"); - //this._blocksList_Container.newBlocksList("BlocksBone"); - //---------------------------------------------------------------- + function exactEquals$4(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2]; + } + /** + * Returns whether or not the vectors have approximately the same elements in the same position. + * + * @param {vec3} a The first vector. + * @param {vec3} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ - this.f4dBlocksListsContainerNewBlocksList(buildingProject._blocksList_Container, "Blocks1"); - this.f4dBlocksListsContainerNewBlocksList(buildingProject._blocksList_Container, "Blocks2"); - this.f4dBlocksListsContainerNewBlocksList(buildingProject._blocksList_Container, "Blocks3"); - this.f4dBlocksListsContainerNewBlocksList(buildingProject._blocksList_Container, "Blocks4"); - this.f4dBlocksListsContainerNewBlocksList(buildingProject._blocksList_Container, "BlocksBone"); -}; + function equals$5(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2]; + var b0 = b[0], + b1 = b[1], + b2 = b[2]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)); + } + /** + * Alias for {@link vec3.subtract} + * @function + */ -/** - * 어떤 일을 하고 있습니까? - * @memberof GeometryModifier - * - * @param buildingProjectsList 변수 - * @returns brBuildingProject - */ -GeometryModifier.prototype.bRbuildingProjectsListNewBRProject = function(buildingProjectsList) -{ - //var titol = "holes a tothom" - //var brBuildingProject = new BRBuildingProject({Titol : titol}); - var brBuildingProject = new BRBuildingProject(); + var sub$4 = subtract$4; + /** + * Alias for {@link vec3.multiply} + * @function + */ - // Create the blocks lists default.*** - this.bRbuildingProjectCreateDefaultBlockReferencesLists(brBuildingProject); + var mul$4 = multiply$4; + /** + * Alias for {@link vec3.divide} + * @function + */ - buildingProjectsList._BR_buildingsArray.push(brBuildingProject); - return brBuildingProject; -}; + var div = divide; + /** + * Alias for {@link vec3.distance} + * @function + */ -'use strict'; + var dist = distance; + /** + * Alias for {@link vec3.squaredDistance} + * @function + */ -/** - * 어떤 일을 하고 있습니까? - * @class Globe - */ -var Globe = function() -{ - if (!(this instanceof Globe)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - //WGS 84.*************************************************** - // Extracted from WikiPedia "Geodetic datum". - // WGS 84 Defining Parameters - // semi-major axis a 6378137.0 m - // Reciprocal of flattening 1/f 298.257223563 - - // WGS 84 derived geometric constants - // Semi-minor axis b = a(1 − f) 6356752.3142 m - // First eccentricity squared e2 = (1 − b2/a2 = 2f − f2) = 6.69437999014 x 10−3 - // Second eccentricity squared e′2 = (a2/b2 − 1 = f(2 − f)/(1 − f)2) = 6.73949674228 x 10−3 - //---------------------------------------------------------- - - this.equatorialRadius = 6378137.0; // meters. - this.polarRadius = 6356752.3142; // meters. - this.firstEccentricitySquared = 6.69437999014E-3; - this.secondEccentricitySquared = 6.73949674228E-3; - this.degToRadFactor = Math.PI/180.0; -}; + var sqrDist = squaredDistance; + /** + * Alias for {@link vec3.length} + * @function + */ -Globe.equatorialRadius = function() -{ - return 6378137.0;; -}; + var len = length; + /** + * Alias for {@link vec3.squaredLength} + * @function + */ -Globe.prototype.normalizeCartesian = function(cartesian) -{ - if (cartesian === undefined) - { return; } + var sqrLen = squaredLength; + /** + * Perform some operation over an array of vec3s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ - var modul = Math.sqrt(cartesian[0]*cartesian[0] + cartesian[1]*cartesian[1] + cartesian[2]*cartesian[2] ); - cartesian[0] /= modul; - cartesian[1] /= modul; - cartesian[2] /= modul; - - return cartesian; -}; + var forEach = function () { + var vec = create$4(); + return function (a, stride, offset, count, fn, arg) { + var i, l; -Globe.prototype.transformMatrixAtCartesianPointWgs84 = function(x, y, z, float32Array) -{ - var xAxis, yAxis, zAxis; - - zAxis = this.normalAtCartesianPointWgs84(x, y, z, zAxis); - - // Check if zAxis is vertical vector. PENDENT.*** - - // now, calculate the east direction. - // project zAxis to plane XY and calculate the left perpendicular.*** - xAxis = new Float32Array(3); - xAxis[0] = -y; - xAxis[1] = x; - xAxis[2] = 0.0; - xAxis = this.normalizeCartesian(xAxis); - - // finally calculate the north direction.*** - var xAxisVector = new Point3D(xAxis[0], xAxis[1], xAxis[2]); - var yAxisVector = new Point3D(); - var zAxisVector = new Point3D(zAxis[0], zAxis[1], zAxis[2]); - - yAxisVector = zAxisVector.crossProduct(xAxisVector, yAxisVector); - - if (float32Array === undefined) - { float32Array = new Float32Array(16); } - - float32Array[0] = xAxisVector.x; - float32Array[1] = xAxisVector.y; - float32Array[2] = xAxisVector.z; - float32Array[3] = 0.0; - - float32Array[4] = yAxisVector.x; - float32Array[5] = yAxisVector.y; - float32Array[6] = yAxisVector.z; - float32Array[7] = 0.0; - - float32Array[8] = zAxisVector.x; - float32Array[9] = zAxisVector.y; - float32Array[10] = zAxisVector.z; - float32Array[11] = 0.0; - - float32Array[12] = x; - float32Array[13] = y; - float32Array[14] = z; - float32Array[15] = 1.0; - - return float32Array; -}; + if (!stride) { + stride = 3; + } -Globe.prototype.intersectionLineWgs84 = function(line, resultCartesian, radius) -{ - // line: (x, y, z) = x1 + t(x2 - x1), y1 + t(y2 - y1), z1 + t(z2 - z1) - // sphere: (x - x3)^2 + (y - y3)^2 + (z - z3)^2 = r^2, where x3, y3, z3 is the center of the sphere. - - // line: - var p1 = line.point; - var lineDir = line.direction; - var dist = 1000.0;// any value is ok.*** - var p2 = new Point3D(p1.x + lineDir.x * dist, p1.y + lineDir.y * dist, p1.z + lineDir.z * dist); - var x1 = p1.x; - var y1 = p1.y; - var z1 = p1.z; - var x2 = p2.x; - var y2 = p2.y; - var z2 = p2.z; + if (!offset) { + offset = 0; + } - // sphere: - var x3 = 0; - var y3 = 0; - var z3 = 0; - var r = this.equatorialRadius; // provisionally.*** - if (radius !== undefined) - { r = radius; } - - // resolve: - var x21 = (x2-x1); - var y21 = (y2-y1); - var z21 = (z2-z1); - - var a = x21*x21 + y21*y21 + z21*z21; - - var x13 = (x1-x3); - var y13 = (y1-y3); - var z13 = (z1-z3); - - var b = 2*(x21 * x13 + y21 * y13 + z21 * z13); - - var c = x3*x3 + y3*y3 + z3*z3 + x1*x1 + y1*y1 + z1*z1 - 2*(x3*x1 + y3*y1+ z3*z1) - r*r; - - var discriminant = b*b - 4*a*c; - - if (discriminant < 0) - { - // no intersection.*** - return undefined; - } - else if (discriminant === 0) - { - // this is tangent.*** - if (resultCartesian === undefined) - { resultCartesian = new Float32Array(3); } - - var t1 = (-b)/(2*a); - var intersectPoint1 = new Point3D(x1 + (x2 - x1)*t1, y1 + (y2 - y1)*t1, z1 + (z2 - z1)*t1); - resultCartesian[0] = intersectPoint1.x; - resultCartesian[1] = intersectPoint1.y; - resultCartesian[2] = intersectPoint1.z; - - } - else - { - // find the nearest to p1.*** - var t1 = (-b + Math.sqrt(discriminant))/(2*a); - var t2 = (-b - Math.sqrt(discriminant))/(2*a); - - // solution 1.*** - var intersectPoint1 = new Point3D(x1 + (x2 - x1)*t1, y1 + (y2 - y1)*t1, z1 + (z2 - z1)*t1); - var intersectPoint2 = new Point3D(x1 + (x2 - x1)*t2, y1 + (y2 - y1)*t2, z1 + (z2 - z1)*t2); - - var dist1 = p1.squareDistToPoint(intersectPoint1); - var dist2 = p1.squareDistToPoint(intersectPoint2); - - if (resultCartesian === undefined) - { resultCartesian = new Float32Array(3); } - - if (dist1 < dist2) - { - resultCartesian[0] = intersectPoint1.x; - resultCartesian[1] = intersectPoint1.y; - resultCartesian[2] = intersectPoint1.z; - } - else - { - resultCartesian[0] = intersectPoint2.x; - resultCartesian[1] = intersectPoint2.y; - resultCartesian[2] = intersectPoint2.z; - } - } - - return resultCartesian; - -}; + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } -Globe.prototype.normalAtCartesianPointWgs84 = function(x, y, z, resultNormal) -{ - if (resultNormal === undefined) - { resultNormal = new Float32Array(3); } + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + vec[2] = a[i + 2]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + a[i + 2] = vec[2]; + } - var equatorialRadiusSquared = this.equatorialRadius * this.equatorialRadius; - var polarRadiusSquared = this.polarRadius * this.polarRadius; + return a; + }; + }(); + + var vec3 = /*#__PURE__*/Object.freeze({ + create: create$4, + clone: clone$4, + length: length, + fromValues: fromValues$4, + copy: copy$4, + set: set$4, + add: add$4, + subtract: subtract$4, + multiply: multiply$4, + divide: divide, + ceil: ceil, + floor: floor, + min: min, + max: max, + round: round, + scale: scale$4, + scaleAndAdd: scaleAndAdd, + distance: distance, + squaredDistance: squaredDistance, + squaredLength: squaredLength, + negate: negate, + inverse: inverse, + normalize: normalize, + dot: dot, + cross: cross, + lerp: lerp, + hermite: hermite, + bezier: bezier, + random: random, + transformMat4: transformMat4, + transformMat3: transformMat3, + transformQuat: transformQuat, + rotateX: rotateX$1, + rotateY: rotateY$1, + rotateZ: rotateZ$1, + angle: angle, + zero: zero, + str: str$4, + exactEquals: exactEquals$4, + equals: equals$5, + sub: sub$4, + mul: mul$4, + div: div, + dist: dist, + sqrDist: sqrDist, + len: len, + sqrLen: sqrLen, + forEach: forEach + }); - resultNormal[0] = x / equatorialRadiusSquared; - resultNormal[1] = y / equatorialRadiusSquared; - resultNormal[2] = z / polarRadiusSquared; - - // Normalize cartesian.*** - resultNormal = this.normalizeCartesian(resultNormal); - - return resultNormal; -}; + /** + * 4 Dimensional Vector + * @module vec4 + */ -Globe.CartesianToGeographicWgs84 = function (x, y, z, result) -{ - // Copied from WebWorldWind.*** - // According to H. Vermeille, "An analytical method to transform geocentric into geodetic coordinates" - // http://www.springerlink.com/content/3t6837t27t351227/fulltext.pdf - // Journal of Geodesy, accepted 10/2010, not yet published - - /* - this.equatorialRadius = 6378137.0; // meters. - this.polarRadius = 6356752.3142; // meters. - this.firstEccentricitySquared = 6.69437999014E-3; - this.secondEccentricitySquared = 6.73949674228E-3; - this.degToRadFactor = Math.PI/180.0; - */ - var firstEccentricitySquared = 6.69437999014E-3; - var equatorialRadius = 6378137.0; - /* - var X = z, - Y = x, - Z = y, - */ - var X = x, - Y = y, - Z = z, - XXpYY = X * X + Y * Y, - sqrtXXpYY = Math.sqrt(XXpYY), - a = equatorialRadius, - ra2 = 1 / (a * a), - e2 = firstEccentricitySquared, - e4 = e2 * e2, - p = XXpYY * ra2, - q = Z * Z * (1 - e2) * ra2, - r = (p + q - e4) / 6, - h, - phi, - u, - evoluteBorderTest = 8 * r * r * r + e4 * p * q, - rad1, - rad2, - rad3, - atan, - v, - w, - k, - D, - sqrtDDpZZ, - e, - lambda, - s2; + /** + * Creates a new, empty vec4 + * + * @returns {vec4} a new 4D vector + */ - if (evoluteBorderTest > 0 || q != 0) - { - if (evoluteBorderTest > 0) - { - // Step 2: general case - rad1 = Math.sqrt(evoluteBorderTest); - rad2 = Math.sqrt(e4 * p * q); + function create$5() { + var out = new ARRAY_TYPE(4); - // 10*e2 is my arbitrary decision of what Vermeille means by "near... the cusps of the evolute". - if (evoluteBorderTest > 10 * e2) - { - rad3 = Math.cbrt((rad1 + rad2) * (rad1 + rad2)); - u = r + 0.5 * rad3 + 2 * r * r / rad3; - } - else - { - u = r + 0.5 * Math.cbrt((rad1 + rad2) * (rad1 + rad2)) - + 0.5 * Math.cbrt((rad1 - rad2) * (rad1 - rad2)); - } - } - else - { - // Step 3: near evolute - rad1 = Math.sqrt(-evoluteBorderTest); - rad2 = Math.sqrt(-8 * r * r * r); - rad3 = Math.sqrt(e4 * p * q); - atan = 2 * Math.atan2(rad3, rad1 + rad2) / 3; + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 0; + } - u = -4 * r * Math.sin(atan) * Math.cos(Math.PI / 6 + atan); - } + return out; + } + /** + * Creates a new vec4 initialized with values from an existing vector + * + * @param {vec4} a vector to clone + * @returns {vec4} a new 4D vector + */ - v = Math.sqrt(u * u + e4 * q); - w = e2 * (u + v - q) / (2 * v); - k = (u + v) / (Math.sqrt(w * w + u + v) + w); - D = k * sqrtXXpYY / (k + e2); - sqrtDDpZZ = Math.sqrt(D * D + Z * Z); + function clone$5(a) { + var out = new ARRAY_TYPE(4); + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + /** + * Creates a new vec4 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {vec4} a new 4D vector + */ - h = (k + e2 - 1) * sqrtDDpZZ / k; - phi = 2 * Math.atan2(Z, sqrtDDpZZ + D); - } - else - { - // Step 4: singular disk - rad1 = Math.sqrt(1 - e2); - rad2 = Math.sqrt(e2 - p); - e = Math.sqrt(e2); + function fromValues$5(x, y, z, w) { + var out = new ARRAY_TYPE(4); + out[0] = x; + out[1] = y; + out[2] = z; + out[3] = w; + return out; + } + /** + * Copy the values from one vec4 to another + * + * @param {vec4} out the receiving vector + * @param {vec4} a the source vector + * @returns {vec4} out + */ - h = -a * rad1 * rad2 / e; - phi = rad2 / (e * rad2 + rad1 * Math.sqrt(p)); - } + function copy$5(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + /** + * Set the components of a vec4 to the given values + * + * @param {vec4} out the receiving vector + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {vec4} out + */ - // Compute lambda - s2 = Math.sqrt(2); - if ((s2 - 1) * Y < sqrtXXpYY + X) - { - // case 1 - -135deg < lambda < 135deg - lambda = 2 * Math.atan2(Y, sqrtXXpYY + X); - } - else if (sqrtXXpYY + Y < (s2 + 1) * X) - { - // case 2 - -225deg < lambda < 45deg - lambda = -Math.PI * 0.5 + 2 * Math.atan2(X, sqrtXXpYY - Y); - } - else - { - // if (sqrtXXpYY-Y<(s2=1)*X) { // is the test, if needed, but it's not - // case 3: - -45deg < lambda < 225deg - lambda = Math.PI * 0.5 - 2 * Math.atan2(X, sqrtXXpYY + Y); - } + function set$5(out, x, y, z, w) { + out[0] = x; + out[1] = y; + out[2] = z; + out[3] = w; + return out; + } + /** + * Adds two vec4's + * + * @param {vec4} out the receiving vector + * @param {vec4} a the first operand + * @param {vec4} b the second operand + * @returns {vec4} out + */ - if (result === undefined) - { result = new GeographicCoord(); } + function add$5(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + out[2] = a[2] + b[2]; + out[3] = a[3] + b[3]; + return out; + } + /** + * Subtracts vector b from vector a + * + * @param {vec4} out the receiving vector + * @param {vec4} a the first operand + * @param {vec4} b the second operand + * @returns {vec4} out + */ - var factor = 180.0 / Math.PI; - result.latitude = factor * phi; - result.longitude = factor * lambda; - result.altitude = h; + function subtract$5(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + out[2] = a[2] - b[2]; + out[3] = a[3] - b[3]; + return out; + } + /** + * Multiplies two vec4's + * + * @param {vec4} out the receiving vector + * @param {vec4} a the first operand + * @param {vec4} b the second operand + * @returns {vec4} out + */ - return result; -}; -/* -Globe.CartesianToGeographicWgs84 = function(x, y, z, resultGeographic) -{ - // defined in the LINZ standard LINZS25000 (Standard for New Zealand Geodetic Datum 2000) - // https://www.linz.govt.nz/data/geodetic-system/coordinate-conversion/geodetic-datum-conversions/equations-used-datum - var a = 6378137.0; - var f = 1.0 / 298.257223563; - var f2 = f*f; - var e2 = 2*f - f2; - var p = Math.sqrt(x*x + y*y); - var r = Math.sqrt(p*p + z*z); - - var nu = Math.atan(z/2 *((1-f) + (e2*a/r))); - var lambda = Math.atan(y/x); - - var sin_nu = Math.sin(nu); - var cos_nu = Math.cos(nu); - var sin3_nu = sin_nu * sin_nu * sin_nu; - var cos3_nu = cos_nu * cos_nu * cos_nu; - - var numerator = z*(1-f)+e2*a*sin3_nu; - var denominator = (1-f)*(p-e2*a*cos3_nu); - var fita = Math.atan(numerator/denominator); - var sin_fita = Math.sin(fita); - var h = p*Math.cos(fita) + z*sin_fita - a*Math.sqrt(1-e2*sin_fita*sin_fita); - - var radToDegFactor = 180.0/Math.PI; - if (resultGeographic === undefined) - { resultGeographic = new GeographicCoord(); } - - resultGeographic.setLonLatAlt(lambda * radToDegFactor, fita * radToDegFactor, h); - return resultGeographic; -}; -*/ + function multiply$5(out, a, b) { + out[0] = a[0] * b[0]; + out[1] = a[1] * b[1]; + out[2] = a[2] * b[2]; + out[3] = a[3] * b[3]; + return out; + } + /** + * Divides two vec4's + * + * @param {vec4} out the receiving vector + * @param {vec4} a the first operand + * @param {vec4} b the second operand + * @returns {vec4} out + */ -Globe.geographicToCartesianWgs84 = function(longitude, latitude, altitude, resultCartesian) -{ - // defined in the LINZ standard LINZS25000 (Standard for New Zealand Geodetic Datum 2000) - // https://www.linz.govt.nz/data/geodetic-system/coordinate-conversion/geodetic-datum-conversions/equations-used-datum - // a = semi-major axis. - // e2 = firstEccentricitySquared. - // v = a / sqrt(1 - e2 * sin2(lat)). - // x = (v+h)*cos(lat)*cos(lon). - // y = (v+h)*cos(lat)*sin(lon). - // z = [v*(1-e2)+h]*sin(lat). - var degToRadFactor = Math.PI/180.0; - var equatorialRadius = 6378137.0; // meters. - var firstEccentricitySquared = 6.69437999014E-3; - var lonRad = longitude * degToRadFactor; - var latRad = latitude * degToRadFactor; - var cosLon = Math.cos(lonRad); - var cosLat = Math.cos(latRad); - var sinLon = Math.sin(lonRad); - var sinLat = Math.sin(latRad); - var a = equatorialRadius; - var e2 = firstEccentricitySquared; - var v = a/Math.sqrt(1.0 - e2 * sinLat * sinLat); - var h = altitude; - - if (resultCartesian === undefined) - { resultCartesian = new Float32Array(3); } - - resultCartesian[0]=(v+h)*cosLat*cosLon; - resultCartesian[1]=(v+h)*cosLat*sinLon; - resultCartesian[2]=(v*(1.0-e2)+h)*sinLat; - - return resultCartesian; -}; + function divide$1(out, a, b) { + out[0] = a[0] / b[0]; + out[1] = a[1] / b[1]; + out[2] = a[2] / b[2]; + out[3] = a[3] / b[3]; + return out; + } + /** + * Math.ceil the components of a vec4 + * + * @param {vec4} out the receiving vector + * @param {vec4} a vector to ceil + * @returns {vec4} out + */ -Globe.geographicRadianArrayToFloat32ArrayWgs84 = function(lonArray, latArray, altArray, resultCartesianArray) -{ - // defined in the LINZ standard LINZS25000 (Standard for New Zealand Geodetic Datum 2000) - // https://www.linz.govt.nz/data/geodetic-system/coordinate-conversion/geodetic-datum-conversions/equations-used-datum - // a = semi-major axis. - // e2 = firstEccentricitySquared. - // v = a / sqrt(1 - e2 * sin2(lat)). - // x = (v+h)*cos(lat)*cos(lon). - // y = (v+h)*cos(lat)*sin(lon). - // z = [v*(1-e2)+h]*sin(lat). - var equatorialRadius = 6378137.0; // meters. - var firstEccentricitySquared = 6.69437999014E-3; - - var lonRad; - var latRad; - var cosLon; - var cosLat; - var sinLon; - var sinLat; - var a = equatorialRadius; - var e2 = firstEccentricitySquared; - var e2a = 1.0 - e2; - var v; - var h; - var resultCartesian; - - var coordsCount = lonArray.length; - resultCartesianArray = new Float32Array(coordsCount*3); - for (var i=0; i 0) { + len = 1 / Math.sqrt(len); + } - // Original for hemisphere.*** - /* - for(var i=0; i= 1); + + do { + v3 = RANDOM() * 2 - 1; + v4 = RANDOM() * 2 - 1; + s2 = v3 * v3 + v4 * v4; + } while (s2 >= 1); + + var d = Math.sqrt((1 - s1) / s2); + out[0] = scale * v1; + out[1] = scale * v2; + out[2] = scale * v3 * d; + out[3] = scale * v4 * d; + return out; + } + /** + * Transforms the vec4 with a mat4. + * + * @param {vec4} out the receiving vector + * @param {vec4} a the vector to transform + * @param {mat4} m matrix to transform with + * @returns {vec4} out + */ - this.lastCamPos = new Point3D(); - this.squareDistUmbral = 22.0; + function transformMat4$1(out, a, m) { + var x = a[0], + y = a[1], + z = a[2], + w = a[3]; + out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w; + out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w; + out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w; + out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w; + return out; + } + /** + * Transforms the vec4 with a quat + * + * @param {vec4} out the receiving vector + * @param {vec4} a the vector to transform + * @param {quat} q quaternion to transform with + * @returns {vec4} out + */ - this.lowestOctreeArray = []; + function transformQuat$1(out, a, q) { + var x = a[0], + y = a[1], + z = a[2]; + var qx = q[0], + qy = q[1], + qz = q[2], + qw = q[3]; // calculate quat * vec + + var ix = qw * x + qy * z - qz * y; + var iy = qw * y + qz * x - qx * z; + var iz = qw * z + qx * y - qy * x; + var iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat + + out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy; + out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz; + out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx; + out[3] = a[3]; + return out; + } + /** + * Set the components of a vec4 to zero + * + * @param {vec4} out the receiving vector + * @returns {vec4} out + */ - this.backGround_fileReadings_count = 0; // this can be as max = 9.*** - this.backGround_imageReadings_count = 0; - this.isCameraMoving = false; - this.isCameraInsideNeoBuilding = false; - this.renderingFase = 0; + function zero$1(out) { + out[0] = 0.0; + out[1] = 0.0; + out[2] = 0.0; + out[3] = 0.0; + return out; + } + /** + * Returns a string representation of a vector + * + * @param {vec4} a vector to represent as a string + * @returns {String} string representation of the vector + */ - this.bPicking = false; - this.scene; + function str$5(a) { + return 'vec4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')'; + } + /** + * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===) + * + * @param {vec4} a The first vector. + * @param {vec4} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ - this.numFrustums; - this.isLastFrustum = false; - this.currentFrustumIdx = 0; - this.highLightColor4 = new Float32Array([0.2, 1.0, 0.2, 1.0]); - this.thereAreUrgentOctrees = false; - - this.hierarchyManager = new HierarchyManager(); - - // small object size. - this.smallObjectSize = 0.153; - - // sqrtTable. - - this.sqrtTable = new Float32Array(11); - // make 100 values. - var increValue = 0.1; - for (var i=0; i<11; i++) - { - this.sqrtTable[i] = Math.sqrt(1+(increValue*i)*(increValue*i)); - } - - this.managerUtil = new ManagerUtils(); + function exactEquals$5(a, b) { + return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]; + } + /** + * Returns whether or not the vectors have approximately the same elements in the same position. + * + * @param {vec4} a The first vector. + * @param {vec4} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ - // CURRENTS.******************************************************************** - this.currentSelectedObj_idx = -1; - this.currentByteColorPicked = new Uint8Array(4); - this.currentShader; + function equals$6(a, b) { + var a0 = a[0], + a1 = a[1], + a2 = a[2], + a3 = a[3]; + var b0 = b[0], + b1 = b[1], + b2 = b[2], + b3 = b[3]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)); + } + /** + * Alias for {@link vec4.subtract} + * @function + */ - // SCRATCH.*** SCRATCH.*** SCRATCH.*** SCRATCH.*** SCRATCH.*** SCRATCH.*** SCRATCH.*** SCRATCH.*** SCRATCH.*** - this.pointSC= new Point3D(); - this.pointSC_2= new Point3D(); - this.arrayAuxSC = []; + var sub$5 = subtract$5; + /** + * Alias for {@link vec4.multiply} + * @function + */ - this.currentTimeSC; - this.dateSC; - this.startTimeSC; - this.maxMilisecondsForRender = 10; + var mul$5 = multiply$5; + /** + * Alias for {@link vec4.divide} + * @function + */ - this.terranTileSC; + var div$1 = divide$1; + /** + * Alias for {@link vec4.distance} + * @function + */ - this.textureAux_1x1; - this.resultRaySC = new Float32Array(3); - this.matrix4SC = new Matrix4(); + var dist$1 = distance$1; + /** + * Alias for {@link vec4.squaredDistance} + * @function + */ - this.unitaryBoxSC = new BoxAux(); - this.unitaryBoxSC.makeAABB(1.0, 1.0, 1.0); // make a unitary box.*** - this.unitaryBoxSC.vBOVertexIdxCacheKey = this.unitaryBoxSC.triPolyhedron.getVBOArrayModePosNorCol(this.unitaryBoxSC.vBOVertexIdxCacheKey); - - this.axisXYZ = new AxisXYZ(); - - this.invertedBox = new Box(); - var mesh = this.invertedBox.makeMesh(1.5, 1.5, 1.5); - mesh.reverseSense(); - //mesh.setColor(0.5, 0.5, 0.5, 0.5); - mesh.getVbo(this.invertedBox.vbo_vicks_container); - mesh.getVboEdges(this.invertedBox.vbo_vicks_containerEdges); + var sqrDist$1 = squaredDistance$1; + /** + * Alias for {@link vec4.length} + * @function + */ - this.demoBlocksLoaded = false; + var len$1 = length$1; + /** + * Alias for {@link vec4.squaredLength} + * @function + */ - this.objMarkerManager = new ObjectMarkerManager(); - this.pin = new Pin(); -}; + var sqrLen$1 = squaredLength$1; + /** + * Perform some operation over an array of vec4s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ -/** - * noise texture를 생성 - * @param gl 변수 - * @param w 변수 - * @param h 변수 - * @param pixels 변수 - * @returns texture - */ -function genNoiseTextureRGBA(gl, w, h, pixels) -{ - var texture = gl.createTexture(); - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture); - // var b = new ArrayBuffer(w*h*4); - //var pixels = new Uint8Array(b); + var forEach$1 = function () { + var vec = create$5(); + return function (a, stride, offset, count, fn, arg) { + var i, l; - if (w === 4 && h === 4) - { - /* - pixels[0] = 149; pixels[1] = 16; pixels[2] = 2; pixels[3] = 197; - pixels[4] = 79; pixels[5] = 76; pixels[6] = 11; pixels[7] = 53; - pixels[8] = 83; pixels[9] = 74; pixels[10] = 155; pixels[11] = 159; - pixels[12] = 19; pixels[13] = 232; pixels[14] = 183; pixels[15] = 27; - - pixels[16] = 200; pixels[17] = 248; pixels[18] = 98; pixels[19] = 10; - pixels[20] = 63; pixels[21] = 75; pixels[22] = 229; pixels[23] = 231; - pixels[24] = 162; pixels[25] = 85; pixels[26] = 114; pixels[27] = 243; - pixels[28] = 149; pixels[29] = 136; pixels[30] = 210; pixels[31] = 59; - - pixels[32] = 210; pixels[33] = 233; pixels[34] = 117; pixels[35] = 103; - pixels[36] = 83; pixels[37] = 214; pixels[38] = 42; pixels[39] = 175; - pixels[40] = 117; pixels[41] = 223; pixels[42] = 87; pixels[43] = 197; - pixels[44] = 99; pixels[45] = 254; pixels[46] = 128; pixels[47] = 9; - - pixels[48] = 137; pixels[49] = 99; pixels[50] = 146; pixels[51] = 38; - pixels[52] = 145; pixels[53] = 76; pixels[54] = 178; pixels[55] = 133; - pixels[56] = 202; pixels[57] = 11; pixels[58] = 220; pixels[59] = 34; - pixels[60] = 61; pixels[61] = 216; pixels[62] = 95; pixels[63] = 249; - */ - var i = 0; - pixels[i] = 50; i++; - pixels[i] = 58; i++; - pixels[i] = 229; i++; - pixels[i] = 120; i++; - pixels[i] = 212; i++; - pixels[i] = 236; i++; - pixels[i] = 251; i++; - pixels[i] = 148; i++; - pixels[i] = 75; i++; - pixels[i] = 92; i++; - pixels[i] = 246; i++; - pixels[i] = 59; i++; - pixels[i] = 197; i++; - pixels[i] = 95; i++; - pixels[i] = 235; i++; - pixels[i] = 216; i++; - pixels[i] = 130; i++; - pixels[i] = 124; i++; - pixels[i] = 215; i++; - pixels[i] = 154; i++; - pixels[i] = 25; i++; - pixels[i] = 41; i++; - pixels[i] = 221; i++; - pixels[i] = 146; i++; - pixels[i] = 187; i++; - pixels[i] = 217; i++; - pixels[i] = 130; i++; - pixels[i] = 199; i++; - pixels[i] = 142; i++; - pixels[i] = 112; i++; - pixels[i] = 61; i++; - pixels[i] = 135; i++; - pixels[i] = 67; i++; - pixels[i] = 125; i++; - pixels[i] = 159; i++; - pixels[i] = 153; i++; - pixels[i] = 215; i++; - pixels[i] = 49; i++; - pixels[i] = 49; i++; - pixels[i] = 69; i++; - pixels[i] = 126; i++; - pixels[i] = 168; i++; - pixels[i] = 61; i++; - pixels[i] = 215; i++; - pixels[i] = 21; i++; - pixels[i] = 93; i++; - pixels[i] = 183; i++; - pixels[i] = 1; i++; - pixels[i] = 125; i++; - pixels[i] = 44; i++; - pixels[i] = 22; i++; - pixels[i] = 130; i++; - pixels[i] = 197; i++; - pixels[i] = 118; i++; - pixels[i] = 109; i++; - pixels[i] = 23; i++; - pixels[i] = 195; i++; - pixels[i] = 4; i++; - pixels[i] = 148; i++; - pixels[i] = 245; i++; - pixels[i] = 124; i++; - pixels[i] = 125; i++; - pixels[i] = 185; i++; - pixels[i] = 28; i++; - } - else - { - for (var y=0; y EPSILON) { + out_axis[0] = q[0] / s; + out_axis[1] = q[1] / s; + out_axis[2] = q[2] / s; + } else { + // If s is zero, return any axis (no rotation - axis does not matter) + out_axis[0] = 1; + out_axis[1] = 0; + out_axis[2] = 0; + } -/** - * 기상 데이터를 그림 - * @param gl 변수 - * @param cameraPosition 변수 - * @param cullingVolume 변수 - * @param _modelViewProjectionRelativeToEye 변수 - * @param scene 변수 - * @param isLastFrustum 변수 - */ -MagoManager.prototype.renderAtmosphere = function(gl, cameraPosition, cullingVolume, _modelViewProjectionRelativeToEye) -{ - var clouds_count = this.atmosphere.cloudsManager.circularCloudsArray.length; - if (clouds_count === 0) { return; } + return rad; + } + /** + * Multiplies two quat's + * + * @param {quat} out the receiving quaternion + * @param {quat} a the first operand + * @param {quat} b the second operand + * @returns {quat} out + */ - var camSplitVelue_X = Cesium.EncodedCartesian3.encode(cameraPosition.x); - var camSplitVelue_Y = Cesium.EncodedCartesian3.encode(cameraPosition.y); - var camSplitVelue_Z = Cesium.EncodedCartesian3.encode(cameraPosition.z); + function multiply$6(out, a, b) { + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bx = b[0], + by = b[1], + bz = b[2], + bw = b[3]; + out[0] = ax * bw + aw * bx + ay * bz - az * by; + out[1] = ay * bw + aw * by + az * bx - ax * bz; + out[2] = az * bw + aw * bz + ax * by - ay * bx; + out[3] = aw * bw - ax * bx - ay * by - az * bz; + return out; + } + /** + * Rotates a quaternion by the given angle about the X axis + * + * @param {quat} out quat receiving operation result + * @param {quat} a quat to rotate + * @param {number} rad angle (in radians) to rotate + * @returns {quat} out + */ - this.encodedCamPosMC_High[0] = camSplitVelue_X.high; - this.encodedCamPosMC_High[1] = camSplitVelue_Y.high; - this.encodedCamPosMC_High[2] = camSplitVelue_Z.high; + function rotateX$2(out, a, rad) { + rad *= 0.5; + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bx = Math.sin(rad), + bw = Math.cos(rad); + out[0] = ax * bw + aw * bx; + out[1] = ay * bw + az * bx; + out[2] = az * bw - ay * bx; + out[3] = aw * bw - ax * bx; + return out; + } + /** + * Rotates a quaternion by the given angle about the Y axis + * + * @param {quat} out quat receiving operation result + * @param {quat} a quat to rotate + * @param {number} rad angle (in radians) to rotate + * @returns {quat} out + */ - this.encodedCamPosMC_Low[0] = camSplitVelue_X.low; - this.encodedCamPosMC_Low[1] = camSplitVelue_Y.low; - this.encodedCamPosMC_Low[2] = camSplitVelue_Z.low; - // Test using f4d_shaderManager.************************ - var shadersManager = this.shadersManager; - var standardShader = shadersManager.getMagoShader(4); // 4 = cloud-shader.*** - var shaderProgram = standardShader.SHADER_PROGRAM; + function rotateY$2(out, a, rad) { + rad *= 0.5; + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var by = Math.sin(rad), + bw = Math.cos(rad); + out[0] = ax * bw - az * by; + out[1] = ay * bw + aw * by; + out[2] = az * bw + ax * by; + out[3] = aw * bw - ay * by; + return out; + } + /** + * Rotates a quaternion by the given angle about the Z axis + * + * @param {quat} out quat receiving operation result + * @param {quat} a quat to rotate + * @param {number} rad angle (in radians) to rotate + * @returns {quat} out + */ - gl.useProgram(shaderProgram); - gl.enableVertexAttribArray(standardShader._color); - gl.enableVertexAttribArray(standardShader._position); + function rotateZ$2(out, a, rad) { + rad *= 0.5; + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bz = Math.sin(rad), + bw = Math.cos(rad); + out[0] = ax * bw + ay * bz; + out[1] = ay * bw - ax * bz; + out[2] = az * bw + aw * bz; + out[3] = aw * bw - az * bz; + return out; + } + /** + * Calculates the W component of a quat from the X, Y, and Z components. + * Assumes that quaternion is 1 unit in length. + * Any existing W component will be ignored. + * + * @param {quat} out the receiving quaternion + * @param {quat} a quat to calculate W component of + * @returns {quat} out + */ - // Calculate "modelViewProjectionRelativeToEye".********************************************************* - Cesium.Matrix4.toArray(_modelViewProjectionRelativeToEye, this.modelViewProjRelToEye_matrix); - //End Calculate "modelViewProjectionRelativeToEye".------------------------------------------------------ + function calculateW(out, a) { + var x = a[0], + y = a[1], + z = a[2]; + out[0] = x; + out[1] = y; + out[2] = z; + out[3] = Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z)); + return out; + } + /** + * Performs a spherical linear interpolation between two quat + * + * @param {quat} out the receiving quaternion + * @param {quat} a the first operand + * @param {quat} b the second operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {quat} out + */ - gl.uniformMatrix4fv(standardShader._ModelViewProjectionMatrixRelToEye, false, this.modelViewProjRelToEye_matrix); - gl.uniform3fv(standardShader._encodedCamPosHIGH, this.encodedCamPosMC_High); - gl.uniform3fv(standardShader._encodedCamPosLOW, this.encodedCamPosMC_Low); + function slerp(out, a, b, t) { + // benchmarks: + // http://jsperf.com/quaternion-slerp-implementations + var ax = a[0], + ay = a[1], + az = a[2], + aw = a[3]; + var bx = b[0], + by = b[1], + bz = b[2], + bw = b[3]; + var omega, cosom, sinom, scale0, scale1; // calc cosine + + cosom = ax * bx + ay * by + az * bz + aw * bw; // adjust signs (if necessary) + + if (cosom < 0.0) { + cosom = -cosom; + bx = -bx; + by = -by; + bz = -bz; + bw = -bw; + } // calculate coefficients + + + if (1.0 - cosom > EPSILON) { + // standard case (slerp) + omega = Math.acos(cosom); + sinom = Math.sin(omega); + scale0 = Math.sin((1.0 - t) * omega) / sinom; + scale1 = Math.sin(t * omega) / sinom; + } else { + // "from" and "to" quaternions are very close + // ... so we can do a linear interpolation + scale0 = 1.0 - t; + scale1 = t; + } // calculate final values - gl.enable(gl.DEPTH_TEST); - gl.depthFunc(gl.LEQUAL); - gl.depthRange(0, 1); - // Clouds.*************************************************** - var cloud; - for (var i=0; i 0.0) { + // |w| > 1/2, may as well choose w > 1/2 + fRoot = Math.sqrt(fTrace + 1.0); // 2w - gl.bindBuffer(gl.ARRAY_BUFFER, null); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); -}; + out[3] = 0.5 * fRoot; + fRoot = 0.5 / fRoot; // 1/(4w) -/** - * 구름 그림자를 그림 - * @param gl 변수 - * @param cameraPosition 변수 - * @param cullingVolume 변수 - * @param _modelViewProjectionRelativeToEye 변수 - * @param scene 변수 - * @param isLastFrustum 변수 - */ -MagoManager.prototype.renderCloudShadows = function(gl, cameraPosition, cullingVolume, _modelViewProjectionRelativeToEye) -{ - //if(!isLastFrustum) - // return; - //this.doFrustumCullingClouds(cullingVolume, this.atmosphere.cloudsManager.circularCloudsArray, cameraPosition); + out[0] = (m[5] - m[7]) * fRoot; + out[1] = (m[6] - m[2]) * fRoot; + out[2] = (m[1] - m[3]) * fRoot; + } else { + // |w| <= 1/2 + var i = 0; + if (m[4] > m[0]) i = 1; + if (m[8] > m[i * 3 + i]) i = 2; + var j = (i + 1) % 3; + var k = (i + 2) % 3; + fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1.0); + out[i] = 0.5 * fRoot; + fRoot = 0.5 / fRoot; + out[3] = (m[j * 3 + k] - m[k * 3 + j]) * fRoot; + out[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot; + out[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot; + } - var clouds_count = this.atmosphere.cloudsManager.circularCloudsArray.length; - if (clouds_count === 0) { return; } + return out; + } + /** + * Creates a quaternion from the given euler angle x, y, z. + * + * @param {quat} out the receiving quaternion + * @param {x} Angle to rotate around X axis in degrees. + * @param {y} Angle to rotate around Y axis in degrees. + * @param {z} Angle to rotate around Z axis in degrees. + * @returns {quat} out + * @function + */ - var camSplitVelue_X = Cesium.EncodedCartesian3.encode(cameraPosition.x); - var camSplitVelue_Y = Cesium.EncodedCartesian3.encode(cameraPosition.y); - var camSplitVelue_Z = Cesium.EncodedCartesian3.encode(cameraPosition.z); + function fromEuler(out, x, y, z) { + var halfToRad = 0.5 * Math.PI / 180.0; + x *= halfToRad; + y *= halfToRad; + z *= halfToRad; + var sx = Math.sin(x); + var cx = Math.cos(x); + var sy = Math.sin(y); + var cy = Math.cos(y); + var sz = Math.sin(z); + var cz = Math.cos(z); + out[0] = sx * cy * cz - cx * sy * sz; + out[1] = cx * sy * cz + sx * cy * sz; + out[2] = cx * cy * sz - sx * sy * cz; + out[3] = cx * cy * cz + sx * sy * sz; + return out; + } + /** + * Returns a string representation of a quatenion + * + * @param {quat} a vector to represent as a string + * @returns {String} string representation of the vector + */ - this.encodedCamPosMC_High[0] = camSplitVelue_X.high; - this.encodedCamPosMC_High[1] = camSplitVelue_Y.high; - this.encodedCamPosMC_High[2] = camSplitVelue_Z.high; + function str$6(a) { + return 'quat(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')'; + } + /** + * Creates a new quat initialized with values from an existing quaternion + * + * @param {quat} a quaternion to clone + * @returns {quat} a new quaternion + * @function + */ - this.encodedCamPosMC_Low[0] = camSplitVelue_X.low; - this.encodedCamPosMC_Low[1] = camSplitVelue_Y.low; - this.encodedCamPosMC_Low[2] = camSplitVelue_Z.low; - // Test using f4d_shaderManager.************************ - var shadersManager = this.shadersManager; - var standardShader = shadersManager.getMagoShader(4); // 4 = cloud-shader.*** - var shaderProgram = standardShader.SHADER_PROGRAM; + var clone$6 = clone$5; + /** + * Creates a new quat initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {quat} a new quaternion + * @function + */ - gl.useProgram(shaderProgram); - //gl.enableVertexAttribArray(standardShader._color); - //gl.disableVertexAttribArray(standardShader._color); - gl.enableVertexAttribArray(standardShader._position); + var fromValues$6 = fromValues$5; + /** + * Copy the values from one quat to another + * + * @param {quat} out the receiving quaternion + * @param {quat} a the source quaternion + * @returns {quat} out + * @function + */ - // Calculate "modelViewProjectionRelativeToEye".********************************************************* - Cesium.Matrix4.toArray(_modelViewProjectionRelativeToEye, this.modelViewProjRelToEye_matrix); - //End Calculate "modelViewProjectionRelativeToEye".------------------------------------------------------ + var copy$6 = copy$5; + /** + * Set the components of a quat to the given values + * + * @param {quat} out the receiving quaternion + * @param {Number} x X component + * @param {Number} y Y component + * @param {Number} z Z component + * @param {Number} w W component + * @returns {quat} out + * @function + */ - gl.uniformMatrix4fv(standardShader._ModelViewProjectionMatrixRelToEye, false, this.modelViewProjRelToEye_matrix); - gl.uniform3fv(standardShader._encodedCamPosHIGH, this.encodedCamPosMC_High); - gl.uniform3fv(standardShader._encodedCamPosLOW, this.encodedCamPosMC_Low); + var set$6 = set$5; + /** + * Adds two quat's + * + * @param {quat} out the receiving quaternion + * @param {quat} a the first operand + * @param {quat} b the second operand + * @returns {quat} out + * @function + */ - gl.enable(gl.DEPTH_TEST); - gl.depthFunc(gl.LEQUAL); - gl.depthRange(0, 1); + var add$6 = add$5; + /** + * Alias for {@link quat.multiply} + * @function + */ - // SHADOW SETTINGS.********************************************************************************** - gl.colorMask(false, false, false, false); - gl.depthMask(false); - gl.enable(gl.CULL_FACE); - gl.enable(gl.STENCIL_TEST); - gl.enable(gl.POLYGON_OFFSET_FILL); - gl.polygonOffset(1.0, 2.0); // Original.*** - //gl.polygonOffset(1.0, 1.0); + var mul$6 = multiply$6; + /** + * Scales a quat by a scalar number + * + * @param {quat} out the receiving vector + * @param {quat} a the vector to scale + * @param {Number} b amount to scale the vector by + * @returns {quat} out + * @function + */ - // First pas.**************************************************************************************************** - gl.cullFace(gl.FRONT); - gl.stencilFunc(gl.ALWAYS, 0x0, 0xff); - gl.stencilOp(gl.KEEP, gl.INCR, gl.KEEP); - gl.clearStencil(0); - //gl.clear(gl.STENCIL_BUFFER_BIT); + var scale$6 = scale$5; + /** + * Calculates the dot product of two quat's + * + * @param {quat} a the first operand + * @param {quat} b the second operand + * @returns {Number} dot product of a and b + * @function + */ - // Clouds.*** - //clouds_count = this.currentVisibleClouds_array.length; - var cloud; - for (var i=0; i 0.999999) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 1; + return out; + } else { + cross(tmpvec3, a, b); + out[0] = tmpvec3[0]; + out[1] = tmpvec3[1]; + out[2] = tmpvec3[2]; + out[3] = 1 + dot$$1; + return normalize$2(out, out); + } + }; + }(); + /** + * Performs a spherical linear interpolation with two control points + * + * @param {quat} out the receiving quaternion + * @param {quat} a the first operand + * @param {quat} b the second operand + * @param {quat} c the third operand + * @param {quat} d the fourth operand + * @param {Number} t interpolation amount, in the range [0-1], between the two inputs + * @returns {quat} out + */ - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cloud.vbo_shadowIndexCacheKey); - gl.drawElements(gl.TRIANGLES, cloud.indicesCount, gl.UNSIGNED_SHORT, 0); // Fill.*** - //gl.drawElements(gl.LINE_LOOP, cloud.indicesCount, gl.UNSIGNED_SHORT, 0); // Wireframe.*** - } - //gl.disableVertexAttribArray(standardShader._color); - gl.disableVertexAttribArray(standardShader._position); + var sqlerp = function () { + var temp1 = create$6(); + var temp2 = create$6(); + return function (out, a, b, c, d, t) { + slerp(temp1, a, d, t); + slerp(temp2, b, c, t); + slerp(out, temp1, temp2, 2 * t * (1 - t)); + return out; + }; + }(); + /** + * Sets the specified quaternion with values corresponding to the given + * axes. Each axis is a vec3 and is expected to be unit length and + * perpendicular to all other specified axes. + * + * @param {vec3} view the vector representing the viewing direction + * @param {vec3} right the vector representing the local "right" direction + * @param {vec3} up the vector representing the local "up" direction + * @returns {quat} out + */ - // Render the shadow.********************************************************************************************* - gl.disable(gl.POLYGON_OFFSET_FILL); - gl.disable(gl.CULL_FACE); - gl.colorMask(true, true, true, true); - gl.depthMask(false); - gl.stencilMask(0x00); + var setAxes = function () { + var matr = create$2(); + return function (out, view, right, up) { + matr[0] = right[0]; + matr[3] = right[1]; + matr[6] = right[2]; + matr[1] = up[0]; + matr[4] = up[1]; + matr[7] = up[2]; + matr[2] = -view[0]; + matr[5] = -view[1]; + matr[8] = -view[2]; + return normalize$2(out, fromMat3(out, matr)); + }; + }(); + + var quat = /*#__PURE__*/Object.freeze({ + create: create$6, + identity: identity$4, + setAxisAngle: setAxisAngle, + getAxisAngle: getAxisAngle, + multiply: multiply$6, + rotateX: rotateX$2, + rotateY: rotateY$2, + rotateZ: rotateZ$2, + calculateW: calculateW, + slerp: slerp, + random: random$2, + invert: invert$4, + conjugate: conjugate, + fromMat3: fromMat3, + fromEuler: fromEuler, + str: str$6, + clone: clone$6, + fromValues: fromValues$6, + copy: copy$6, + set: set$6, + add: add$6, + mul: mul$6, + scale: scale$6, + dot: dot$2, + lerp: lerp$2, + length: length$2, + len: len$2, + squaredLength: squaredLength$2, + sqrLen: sqrLen$2, + normalize: normalize$2, + exactEquals: exactEquals$6, + equals: equals$7, + rotationTo: rotationTo, + sqlerp: sqlerp, + setAxes: setAxes + }); - gl.stencilFunc(gl.NOTEQUAL, 1, 0xff); - gl.stencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE); + /** + * Dual Quaternion
+ * Format: [real, dual]
+ * Quaternion format: XYZW
+ * Make sure to have normalized dual quaternions, otherwise the functions may not work as intended.
+ * @module quat2 + */ - gl.disable(gl.DEPTH_TEST); - gl.enable(gl.BLEND); - gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); // Original.*** - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); - // must draw a rectangle for blending.*** - gl.cullFace(gl.FRONT); + /** + * Creates a new identity dual quat + * + * @returns {quat2} a new dual quaternion [real -> rotation, dual -> translation] + */ - // render the shadowBlendingCube.*** - standardShader = shadersManager.getMagoShader(5); // 5 = blendingCube-shader.*** - gl.useProgram(standardShader.SHADER_PROGRAM); + function create$7() { + var dq = new ARRAY_TYPE(8); + + if (ARRAY_TYPE != Float32Array) { + dq[0] = 0; + dq[1] = 0; + dq[2] = 0; + dq[4] = 0; + dq[5] = 0; + dq[6] = 0; + dq[7] = 0; + } - gl.enableVertexAttribArray(standardShader._color); - gl.enableVertexAttribArray(standardShader._position); + dq[3] = 1; + return dq; + } + /** + * Creates a new quat initialized with values from an existing quaternion + * + * @param {quat2} a dual quaternion to clone + * @returns {quat2} new dual quaternion + * @function + */ - gl.uniformMatrix4fv(standardShader._ModelViewProjectionMatrixRelToEye, false, this.modelViewProjRelToEye_matrix); - gl.uniform3fv(standardShader._encodedCamPosHIGH, this.encodedCamPosMC_High); - gl.uniform3fv(standardShader._encodedCamPosLOW, this.encodedCamPosMC_Low); + function clone$7(a) { + var dq = new ARRAY_TYPE(8); + dq[0] = a[0]; + dq[1] = a[1]; + dq[2] = a[2]; + dq[3] = a[3]; + dq[4] = a[4]; + dq[5] = a[5]; + dq[6] = a[6]; + dq[7] = a[7]; + return dq; + } + /** + * Creates a new dual quat initialized with the given values + * + * @param {Number} x1 X component + * @param {Number} y1 Y component + * @param {Number} z1 Z component + * @param {Number} w1 W component + * @param {Number} x2 X component + * @param {Number} y2 Y component + * @param {Number} z2 Z component + * @param {Number} w2 W component + * @returns {quat2} new dual quaternion + * @function + */ - var shadowBC = this.atmosphere.shadowBlendingCube; - if (shadowBC.vbo_vertexCacheKey === undefined) - { - shadowBC.vbo_vertexCacheKey = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, shadowBC.vbo_vertexCacheKey); - gl.bufferData(gl.ARRAY_BUFFER, shadowBC.getVBOVertexColorRGBAFloatArray(), gl.STATIC_DRAW); - } - if (shadowBC.vbo_indexCacheKey === undefined) - { - shadowBC.vbo_indexCacheKey = gl.createBuffer(); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, shadowBC.vbo_indexCacheKey); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, shadowBC.getVBOIndicesShortArray(), gl.STATIC_DRAW); - } + function fromValues$7(x1, y1, z1, w1, x2, y2, z2, w2) { + var dq = new ARRAY_TYPE(8); + dq[0] = x1; + dq[1] = y1; + dq[2] = z1; + dq[3] = w1; + dq[4] = x2; + dq[5] = y2; + dq[6] = z2; + dq[7] = w2; + return dq; + } + /** + * Creates a new dual quat from the given values (quat and translation) + * + * @param {Number} x1 X component + * @param {Number} y1 Y component + * @param {Number} z1 Z component + * @param {Number} w1 W component + * @param {Number} x2 X component (translation) + * @param {Number} y2 Y component (translation) + * @param {Number} z2 Z component (translation) + * @returns {quat2} new dual quaternion + * @function + */ - // Interleaved mode.*** - gl.bindBuffer(gl.ARRAY_BUFFER, shadowBC.vbo_vertexCacheKey); - gl.vertexAttribPointer(standardShader._position, 3, gl.FLOAT, false, 28, 0); - gl.vertexAttribPointer(standardShader._color, 4, gl.FLOAT, false, 28, 12); + function fromRotationTranslationValues(x1, y1, z1, w1, x2, y2, z2) { + var dq = new ARRAY_TYPE(8); + dq[0] = x1; + dq[1] = y1; + dq[2] = z1; + dq[3] = w1; + var ax = x2 * 0.5, + ay = y2 * 0.5, + az = z2 * 0.5; + dq[4] = ax * w1 + ay * z1 - az * y1; + dq[5] = ay * w1 + az * x1 - ax * z1; + dq[6] = az * w1 + ax * y1 - ay * x1; + dq[7] = -ax * x1 - ay * y1 - az * z1; + return dq; + } + /** + * Creates a dual quat from a quaternion and a translation + * + * @param {quat2} dual quaternion receiving operation result + * @param {quat} q quaternion + * @param {vec3} t tranlation vector + * @returns {quat2} dual quaternion receiving operation result + * @function + */ - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, shadowBC.vbo_indexCacheKey); - gl.drawElements(gl.TRIANGLES, shadowBC.indicesCount, gl.UNSIGNED_SHORT, 0); // Fill.*** + function fromRotationTranslation$1(out, q, t) { + var ax = t[0] * 0.5, + ay = t[1] * 0.5, + az = t[2] * 0.5, + bx = q[0], + by = q[1], + bz = q[2], + bw = q[3]; + out[0] = bx; + out[1] = by; + out[2] = bz; + out[3] = bw; + out[4] = ax * bw + ay * bz - az * by; + out[5] = ay * bw + az * bx - ax * bz; + out[6] = az * bw + ax * by - ay * bx; + out[7] = -ax * bx - ay * by - az * bz; + return out; + } + /** + * Creates a dual quat from a translation + * + * @param {quat2} dual quaternion receiving operation result + * @param {vec3} t translation vector + * @returns {quat2} dual quaternion receiving operation result + * @function + */ - gl.disableVertexAttribArray(standardShader._position); - gl.disableVertexAttribArray(standardShader._color); + function fromTranslation$3(out, t) { + out[0] = 0; + out[1] = 0; + out[2] = 0; + out[3] = 1; + out[4] = t[0] * 0.5; + out[5] = t[1] * 0.5; + out[6] = t[2] * 0.5; + out[7] = 0; + return out; + } + /** + * Creates a dual quat from a quaternion + * + * @param {quat2} dual quaternion receiving operation result + * @param {quat} q the quaternion + * @returns {quat2} dual quaternion receiving operation result + * @function + */ - gl.enable(gl.DEPTH_TEST); - gl.disable(gl.BLEND); - gl.disable(gl.STENCIL_TEST); -}; + function fromRotation$4(out, q) { + out[0] = q[0]; + out[1] = q[1]; + out[2] = q[2]; + out[3] = q[3]; + out[4] = 0; + out[5] = 0; + out[6] = 0; + out[7] = 0; + return out; + } + /** + * Creates a new dual quat from a matrix (4x4) + * + * @param {quat2} out the dual quaternion + * @param {mat4} a the matrix + * @returns {quat2} dual quat receiving operation result + * @function + */ -/** - * 텍스처를 읽어서 그래픽 카드에 올림 - * Loading Texture - * - * @param {any} gl - * @param {any} image - * @param {any} texture - */ -function handleTextureLoaded(gl, image, texture) -{ - // https://developer.mozilla.org/en-US/docs/Web/API/Webgl_API/Tutorial/Using_textures_in_Webgl - gl.bindTexture(gl.TEXTURE_2D, texture); - //gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBgl,true); // if need vertical mirror of the image.*** - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); // Original.*** - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST); - gl.generateMipmap(gl.TEXTURE_2D); - gl.bindTexture(gl.TEXTURE_2D, null); -}; + function fromMat4$1(out, a) { + //TODO Optimize this + var outer = create$6(); + getRotation(outer, a); + var t = new ARRAY_TYPE(3); + getTranslation(t, a); + fromRotationTranslation$1(out, outer, t); + return out; + } + /** + * Copy the values from one dual quat to another + * + * @param {quat2} out the receiving dual quaternion + * @param {quat2} a the source dual quaternion + * @returns {quat2} out + * @function + */ -/** - * 빌딩을 준비(새버전) - * @param {gl} gl - */ -MagoManager.prototype.prepareNeoBuildingsAsimetricVersion = function(gl, visibleObjControlerNodes) -{ - // for all renderables, prepare data.*** - var neoBuilding; - var node, rootNode; - var projectFolderName; - - //var geometryDataPath = this.readerWriter.getCurrentDataPath(); - var geometryDataPath = this.readerWriter.geometryDataPath; - if (this.headersRequestedCounter === undefined) - { this.headersRequestedCounter = 0; } + function copy$7(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4]; + out[5] = a[5]; + out[6] = a[6]; + out[7] = a[7]; + return out; + } + /** + * Set a dual quat to the identity dual quaternion + * + * @param {quat2} out the receiving quaternion + * @returns {quat2} out + */ - var currentVisibleNodes = [].concat(visibleObjControlerNodes.currentVisibles0, visibleObjControlerNodes.currentVisibles2, visibleObjControlerNodes.currentVisibles3); - for (var i=0, length = currentVisibleNodes.length; i 0) { + magnitude = Math.sqrt(magnitude); + var a0 = a[0] / magnitude; + var a1 = a[1] / magnitude; + var a2 = a[2] / magnitude; + var a3 = a[3] / magnitude; + var b0 = a[4]; + var b1 = a[5]; + var b2 = a[6]; + var b3 = a[7]; + var a_dot_b = a0 * b0 + a1 * b1 + a2 * b2 + a3 * b3; + out[0] = a0; + out[1] = a1; + out[2] = a2; + out[3] = a3; + out[4] = (b0 - a0 * a_dot_b) / magnitude; + out[5] = (b1 - a1 * a_dot_b) / magnitude; + out[6] = (b2 - a2 * a_dot_b) / magnitude; + out[7] = (b3 - a3 * a_dot_b) / magnitude; + } - this.prepareVisibleOctreesSortedByDistanceLOD2(gl, this.visibleObjControlerOctrees.currentVisibles0, fileRequestExtraCount); - this.prepareVisibleOctreesSortedByDistanceLOD2(gl, this.visibleObjControlerOctrees.currentVisibles1, fileRequestExtraCount); - this.prepareVisibleOctreesSortedByDistanceLOD2(gl, this.visibleObjControlerOctrees.currentVisibles2, fileRequestExtraCount); - - //fileRequestExtraCount = 2; - fileRequestExtraCount = this.visibleObjControlerOctrees.currentVisibles0.length; - if (fileRequestExtraCount > 2) - { fileRequestExtraCount = 2; } - - // lod 2. - nodesCount = this.visibleObjControlerNodes.currentVisibles2.length; - for (var i=0; i=0; i--) - { - // inversed "for" because delete 1rst farest.*** - node = this.visibleObjControlerNodes.currentVisibles2[i]; - this.processQueue.putNodeToDeleteModelReferences(node, 0); - } - - // in this point, put nodes to delete lod LOWER THAN lod3 (delete lod0, lod1, lod2).*** - /* - //if(this.currentFrustumIdx === 0) - { - nodesCount = this.visibleObjControlerNodes.currentVisibles3.length; - var nodesPutted = 0; - for (var i=nodesCount-1; i>=0; i--) - { - // inverse "for" because delete 1rst farest.*** - node = this.visibleObjControlerNodes.currentVisibles3[i]; - neoBuilding = node.data.neoBuilding; - if (neoBuilding === undefined) - { continue; } - - var key = neoBuilding.buildingId; - - if(neoBuilding.currentLod === 3) - { - this.processQueue.eraseNodeToDeleteLessThanLod4(node); - if (!this.processQueue.nodesToDeleteLessThanLod3Map.hasOwnProperty(key)) - { - this.processQueue.putNodeToDeleteLessThanLod3(node, 0); - nodesPutted++; - } - } - else if(neoBuilding.currentLod === 4) - { - this.processQueue.eraseNodeToDeleteLessThanLod5(node); - if (!this.processQueue.nodesToDeleteLessThanLod4Map.hasOwnProperty(key)) - { - this.processQueue.putNodeToDeleteLessThanLod4(node, 0); - nodesPutted++; - } - } - else{ - if (!this.processQueue.nodesToDeleteLessThanLod5Map.hasOwnProperty(key)) - { - this.processQueue.putNodeToDeleteLessThanLod5(node, 0); - nodesPutted++; - } - } - - - if (nodesPutted > 5) - { break; } - } - } - */ - // lod3, lod4, lod5.*** - this.prepareVisibleLowLodNodes(this.visibleObjControlerNodes.currentVisibles3); - - // provisionally prepare pointsCloud datas.****************************************************** - if (this.visibleObjControlerOctreesAux === undefined) - { this.visibleObjControlerOctreesAux = new VisibleObjectsController(); } - - this.visibleObjControlerOctreesAux.initArrays(); // init.****** - var nodesCount = this.visibleObjControlerNodes.currentVisiblesAux.length; - for (var i=0; i maxIterations) - // break; - } - - // 2) 2nd, for all terrains that exist, if there are not in the visiblesMap, then delete its.*** - for (var key in terrName_tinTerrain_map) - { - tinTerrain = terrName_geoCoords_map[key]; - if (tinTerrain === undefined) - { - tinTerrainToDelete = terrName_tinTerrain_map[key]; - this.processQueue.putTinTerrainToDelete(tinTerrainToDelete, 0); - } - } - -}; + /** + * 2 Dimensional Vector + * @module vec2 + */ -/** - * Prepare current visibles low LOD nodes.*** - */ -MagoManager.prototype.prepareVisibleLowLodNodes = function(lowLodNodesArray) -{ - var lowLodDataInQueueCount = Object.keys(this.loadQueue.lowLodSkinDataMap).length; - if (lowLodDataInQueueCount > 1) - { return; } - - var lowLodTexturesInQueueCount = Object.keys(this.loadQueue.lowLodSkinTextureMap).length; - if (lowLodTexturesInQueueCount > 1) - { return; } - - // Prepare lod3, lod4 and lod5 meshes.*** - // check "this.visibleObjControlerNodes.currentVisibles3".*** - var lowLodMesh; - var lod; - var node; - var neoBuilding; - var projectFolderName; - var buildingFolderName; - var extraCount = 5; - var gl = this.sceneState.gl; - var geometryDataPath = this.readerWriter.geometryDataPath; - - var lowLodNodesCount = lowLodNodesArray.length; - for (var i=0; i 1) - { return; } - - if (Object.keys(this.loadQueue.lowLodSkinTextureMap).length > 1) - { return; } + /** + * Creates a new, empty vec2 + * + * @returns {vec2} a new 2D vector + */ - node = lowLodNodesArray[i]; - neoBuilding = node.data.neoBuilding; + function create$8() { + var out = new ARRAY_TYPE(2); - var headerVersion = neoBuilding.getHeaderVersion(); - if (headerVersion === undefined) - { continue; } - - if (headerVersion[0] !== "0") - { - continue; - } - - if (neoBuilding.lodMeshesMap === undefined) - { neoBuilding.lodMeshesMap = {}; } - - projectFolderName = neoBuilding.projectFolderName; - buildingFolderName = neoBuilding.buildingFileName; - - // recalculate the distToCam with octrees.*** - //var cameraPosition = this.sceneState.camera.position; - //neoBuilding.distToCam = neoBuilding.octree.getMinDistToCamera(cameraPosition); - var textureFileName; - var lodString; - var lodIdx = neoBuilding.currentLod; - - // must check if the desirable lodMesh is available.*** - var lodBuildingData = neoBuilding.getLodBuildingData(neoBuilding.currentLod); - if (lodBuildingData === undefined) - { continue; } - - if (lodBuildingData.isModelRef) - { continue; } - - textureFileName = lodBuildingData.textureFileName; - lodString = lodBuildingData.geometryFileName; - - ///lowLodMesh = neoBuilding.lodMeshesMap.get(lodString); // code if "lodMeshesMap" is a map.*** - lowLodMesh = neoBuilding.lodMeshesMap[lodString]; - if (lowLodMesh === undefined) - { - lowLodMesh = new Lego(); - lowLodMesh.fileLoadState = CODE.fileLoadState.READY; - lowLodMesh.textureName = textureFileName; - lowLodMesh.legoKey = neoBuilding.buildingId + "_" + lodString; - neoBuilding.lodMeshesMap[lodString] = lowLodMesh; - } - - if (lowLodMesh.fileLoadState === -1) - { - // if a lodObject has "fileLoadState" = -1 means that there are no file in server.*** - continue; - } - - if (lowLodMesh.fileLoadState === CODE.fileLoadState.READY) - { - // put it into fileLoadQueue.*** - var lodMeshFilePath = geometryDataPath + "/" + projectFolderName + "/" + buildingFolderName + "/" + lodString; - this.loadQueue.putLowLodSkinData(lowLodMesh, lodMeshFilePath, 0); - - if (lowLodMesh.vbo_vicks_container.vboCacheKeysArray === undefined) - { lowLodMesh.vbo_vicks_container.vboCacheKeysArray = []; } - - } - - if (lowLodMesh.vbo_vicks_container.vboCacheKeysArray[0] && lowLodMesh.vbo_vicks_container.vboCacheKeysArray[0].meshTexcoordsCacheKey) - { - // this is the new version.*** - if (lowLodMesh.texture === undefined) - { - lowLodMesh.texture = new Texture(); - var filePath_inServer = geometryDataPath + "/" + projectFolderName + "/" + buildingFolderName + "/" + textureFileName; - //this.readerWriter.readLegoSimpleBuildingTexture(gl, filePath_inServer, lowLodMesh.texture, this); // old.*** - this.loadQueue.putLowLodSkinTexture(filePath_inServer, lowLodMesh.texture, 0); - } - } + if (ARRAY_TYPE != Float32Array) { + out[0] = 0; + out[1] = 0; + } - if (this.fileRequestControler.isFullPlusLowLodData(extraCount)) - { return; } - } -}; + return out; + } + /** + * Creates a new vec2 initialized with values from an existing vector + * + * @param {vec2} a vector to clone + * @returns {vec2} a new 2D vector + */ -/** - * Mago geometries generation test.*** - */ -MagoManager.prototype.renderMagoGeometries = function(ssao_idx) -{ - // 1rst, make the test object if no exist.*** - //return; - - if (this.nativeProjectsArray === undefined) - { - this.nativeProjectsArray = []; - var natProject = new MagoNativeProject(); - this.nativeProjectsArray.push(natProject); - - var pMesh = natProject.newParametricMesh(); - - pMesh.profile = new Profile(); // provisional.*** - var profileAux = pMesh.profile; // provisional.*** - - profileAux.TEST__setFigureHole_2(); - //profileAux.TEST__setFigure_1(); - - if (pMesh.vboKeyContainer === undefined) - { pMesh.vboKeyContainer = new VBOVertexIdxCacheKeysContainer(); } - - if (pMesh.vboKeyContainerEdges === undefined) - { pMesh.vboKeyContainerEdges = new VBOVertexIdxCacheKeysContainer(); } - - var bIncludeBottomCap, bIncludeTopCap; - var extrusionVector, extrusionDist, extrudeSegmentsCount; - /* - extrudeSegmentsCount = 120; - extrusionDist = 15.0; - pMesh.extrude(profileAux, extrusionDist, extrudeSegmentsCount, extrusionVector); - */ - - var revolveAngDeg, revolveSegmentsCount, revolveSegment2d; - revolveAngDeg = 90.0; - revolveSegment2d = new Segment2D(); - var strPoint2d = new Point2D(20, -10); - var endPoint2d = new Point2D(20, 10); - revolveSegment2d.setPoints(strPoint2d, endPoint2d); - revolveSegmentsCount = 24; - pMesh.revolve(profileAux, revolveAngDeg, revolveSegmentsCount, revolveSegment2d); - - bIncludeBottomCap = true; - bIncludeTopCap = true; - var mesh = pMesh.getSurfaceIndependentMesh(undefined, bIncludeBottomCap, bIncludeTopCap); - mesh.setColor(0.1, 0.5, 0.5, 1.0); + function clone$8(a) { + var out = new ARRAY_TYPE(2); + out[0] = a[0]; + out[1] = a[1]; + return out; + } + /** + * Creates a new vec2 initialized with the given values + * + * @param {Number} x X component + * @param {Number} y Y component + * @returns {vec2} a new 2D vector + */ - mesh.getVbo(pMesh.vboKeyContainer); - mesh.getVboEdges(pMesh.vboKeyContainerEdges); - - // Now, provisionally make a geoLocationData for the nativeProject.************************************* - if (natProject.geoLocDataManager === undefined) - { - natProject.geoLocDataManager = new GeoLocationDataManager(); - var geoLoc = natProject.geoLocDataManager.newGeoLocationData("deploymentLoc"); - - var longitude = 126.61120237344926; - var latitude = 37.577213509597016; - var altitude = 50; - var heading = 0.0; - var pitch = 0.0; - var roll = 0.0; + function fromValues$8(x, y) { + var out = new ARRAY_TYPE(2); + out[0] = x; + out[1] = y; + return out; + } + /** + * Copy the values from one vec2 to another + * + * @param {vec2} out the receiving vector + * @param {vec2} a the source vector + * @returns {vec2} out + */ - ManagerUtils.calculateGeoLocationData(longitude, latitude, altitude, heading, pitch, roll, geoLoc, this); - } - - } - //--------------------------------------------------------------------------------------------------------------- - - var gl = this.sceneState.gl; - var color; - var node; - var currentShader; - if (ssao_idx === 0) - { - currentShader = this.postFxShadersManager.getTriPolyhedronDepthShader(); // triPolyhedron ssao.*** - gl.disable(gl.BLEND); - } - if (ssao_idx === 1) - { - currentShader = this.postFxShadersManager.getTriPolyhedronShader(); // triPolyhedron ssao.*** - gl.enable(gl.BLEND); - } - - var shaderProgram = currentShader.program; - - gl.frontFace(gl.CCW); - gl.useProgram(shaderProgram); - gl.enableVertexAttribArray(currentShader.position3_loc); - - gl.uniformMatrix4fv(currentShader.modelViewProjectionMatrix4RelToEye_loc, false, this.sceneState.modelViewProjRelToEyeMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.modelViewMatrix4RelToEye_loc, false, this.sceneState.modelViewRelToEyeMatrix._floatArrays); // original.*** - - - gl.uniform3fv(currentShader.cameraPosHIGH_loc, this.sceneState.encodedCamPosHigh); - gl.uniform3fv(currentShader.cameraPosLOW_loc, this.sceneState.encodedCamPosLow); + function copy$8(out, a) { + out[0] = a[0]; + out[1] = a[1]; + return out; + } + /** + * Set the components of a vec2 to the given values + * + * @param {vec2} out the receiving vector + * @param {Number} x X component + * @param {Number} y Y component + * @returns {vec2} out + */ - gl.uniform1f(currentShader.near_loc, this.sceneState.camera.frustum.near); - gl.uniform1f(currentShader.far_loc, this.sceneState.camera.frustum.far); - - gl.uniform1i(currentShader.bApplySsao_loc, false); + function set$8(out, x, y) { + out[0] = x; + out[1] = y; + return out; + } + /** + * Adds two vec2's + * + * @param {vec2} out the receiving vector + * @param {vec2} a the first operand + * @param {vec2} b the second operand + * @returns {vec2} out + */ - gl.uniformMatrix4fv(currentShader.normalMatrix4_loc, false, this.sceneState.normalMatrix4._floatArrays); - //----------------------------------------------------------------------------------------------------------- - - if (ssao_idx === 1) - { - // provisionally render all native projects.*** - gl.enableVertexAttribArray(currentShader.normal3_loc); - gl.enableVertexAttribArray(currentShader.color4_loc); + function add$8(out, a, b) { + out[0] = a[0] + b[0]; + out[1] = a[1] + b[1]; + return out; + } + /** + * Subtracts vector b from vector a + * + * @param {vec2} out the receiving vector + * @param {vec2} a the first operand + * @param {vec2} b the second operand + * @returns {vec2} out + */ - gl.uniform1i(currentShader.bUse1Color_loc, false); - if (color) - { - gl.uniform4fv(currentShader.oneColor4_loc, [color.r, color.g, color.b, 1.0]); //.*** - } - else - { - gl.uniform4fv(currentShader.oneColor4_loc, [1.0, 0.1, 0.1, 1.0]); //.*** - } - - gl.uniform1i(currentShader.bUseNormal_loc, true); - - gl.uniformMatrix4fv(currentShader.modelViewMatrix4_loc, false, this.sceneState.modelViewMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.projectionMatrix4_loc, false, this.sceneState.projectionMatrix._floatArrays); + function subtract$6(out, a, b) { + out[0] = a[0] - b[0]; + out[1] = a[1] - b[1]; + return out; + } + /** + * Multiplies two vec2's + * + * @param {vec2} out the receiving vector + * @param {vec2} a the first operand + * @param {vec2} b the second operand + * @returns {vec2} out + */ - gl.uniform1i(currentShader.depthTex_loc, 0); - gl.uniform1i(currentShader.noiseTex_loc, 1); - gl.uniform1i(currentShader.diffuseTex_loc, 2); // no used.*** - gl.uniform1f(currentShader.fov_loc, this.sceneState.camera.frustum.fovyRad); // "frustum._fov" is in radians.*** - gl.uniform1f(currentShader.aspectRatio_loc, this.sceneState.camera.frustum.aspectRatio); - gl.uniform1f(currentShader.screenWidth_loc, this.sceneState.drawingBufferWidth); - gl.uniform1f(currentShader.screenHeight_loc, this.sceneState.drawingBufferHeight); + function multiply$8(out, a, b) { + out[0] = a[0] * b[0]; + out[1] = a[1] * b[1]; + return out; + } + /** + * Divides two vec2's + * + * @param {vec2} out the receiving vector + * @param {vec2} a the first operand + * @param {vec2} b the second operand + * @returns {vec2} out + */ + function divide$2(out, a, b) { + out[0] = a[0] / b[0]; + out[1] = a[1] / b[1]; + return out; + } + /** + * Math.ceil the components of a vec2 + * + * @param {vec2} out the receiving vector + * @param {vec2} a vector to ceil + * @returns {vec2} out + */ - gl.uniform2fv(currentShader.noiseScale2_loc, [this.depthFboNeo.width/this.noiseTexture.width, this.depthFboNeo.height/this.noiseTexture.height]); - gl.uniform3fv(currentShader.kernel16_loc, this.kernel); - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, this.depthFboNeo.colorBuffer); // original.*** - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, this.noiseTexture); - } - - var neoBuilding; - var natProject, mesh; - var geoLocDataManager; - var buildingGeoLocation; - var nativeProjectsCount = this.nativeProjectsArray.length; - for (var i=0; i= 0 && screenCoord.y >= 0) - { - ctx.font = "13px Arial"; - //ctx.strokeText(nodeRoot.data.nodeId, screenCoord.x, screenCoord.y); - //ctx.fillText(nodeRoot.data.nodeId, screenCoord.x, screenCoord.y); - ctx.strokeText(nodeRoot.data.data_name, screenCoord.x, screenCoord.y); - ctx.fillText(nodeRoot.data.data_name, screenCoord.x, screenCoord.y); - } - } - } - - rootNodesMap = {}; + function max$2(out, a, b) { + out[0] = Math.max(a[0], b[0]); + out[1] = Math.max(a[1], b[1]); + return out; + } + /** + * Math.round the components of a vec2 + * + * @param {vec2} out the receiving vector + * @param {vec2} a vector to round + * @returns {vec2} out + */ - ctx.restore(); -}; + function round$2(out, a) { + out[0] = Math.round(a[0]); + out[1] = Math.round(a[1]); + return out; + } + /** + * Scales a vec2 by a scalar number + * + * @param {vec2} out the receiving vector + * @param {vec2} a the vector to scale + * @param {Number} b amount to scale the vector by + * @returns {vec2} out + */ -/** - * The camera was moved. - */ -MagoManager.prototype.cameraMoved = function() -{ - this.sceneState.camera.setDirty(true); - - if (this.selectionFbo === undefined) - { this.selectionFbo = new FBO(this.sceneState.gl, this.sceneState.drawingBufferWidth, this.sceneState.drawingBufferHeight); } + function scale$8(out, a, b) { + out[0] = a[0] * b; + out[1] = a[1] * b; + return out; + } + /** + * Adds two vec2's after scaling the second operand by a scalar value + * + * @param {vec2} out the receiving vector + * @param {vec2} a the first operand + * @param {vec2} b the second operand + * @param {Number} scale the amount to scale b by before adding + * @returns {vec2} out + */ - this.selectionFbo.dirty = true; -}; + function scaleAndAdd$2(out, a, b, scale) { + out[0] = a[0] + b[0] * scale; + out[1] = a[1] + b[1] * scale; + return out; + } + /** + * Calculates the euclidian distance between two vec2's + * + * @param {vec2} a the first operand + * @param {vec2} b the second operand + * @returns {Number} distance between a and b + */ -/** - * @param {Object} node - * @returns {Object} - */ -MagoManager.prototype.getNodeGeoLocDataManager = function(node) -{ - if (node === undefined) - { return undefined; } - - // provisionally take the geoLocDatamanager from the rootNode. - //var rootNode = node.getRoot(); - - var closestRootNode = node.getClosestParentWithData("geoLocDataManager"); - - if (closestRootNode === undefined) - { return undefined; } + function distance$2(a, b) { + var x = b[0] - a[0], + y = b[1] - a[1]; + return Math.sqrt(x * x + y * y); + } + /** + * Calculates the squared euclidian distance between two vec2's + * + * @param {vec2} a the first operand + * @param {vec2} b the second operand + * @returns {Number} squared distance between a and b + */ - if (closestRootNode.data === undefined) - { return undefined; } - - var rootNodeGeoLocDataManager = closestRootNode.data.geoLocDataManager; - return rootNodeGeoLocDataManager; -}; + function squaredDistance$2(a, b) { + var x = b[0] - a[0], + y = b[1] - a[1]; + return x * x + y * y; + } + /** + * Calculates the length of a vec2 + * + * @param {vec2} a vector to calculate length of + * @returns {Number} length of a + */ -/** - * Renders the current frustumVolumen with colorCoding for selection. - * @param {GL} gl. - * @param {VisibleObjectsControler} visibleObjControlerBuildings Contains the current visible objects clasified by LOD. - * @returns {Array} resultSelectedArray - */ -MagoManager.prototype.renderGeometryColorCoding = function(gl, visibleObjControlerNodes) -{ - //if (this.selectionFbo.dirty) // todo. - { - // set byteColor codes for references objects.*** - var node; - var rootNode; - var neoBuilding; - var currentVisibleOctreesControler; - var currentVisibleLowestOctCount; - var lowestOctree; - - var isInterior = false; - var ssao_idx = -1; - var minSize = 0.0; - var refTMatrixIdxKey = 0; - var glPrimitive = gl.TRIANGLES; + function length$4(a) { + var x = a[0], + y = a[1]; + return Math.sqrt(x * x + y * y); + } + /** + * Calculates the squared length of a vec2 + * + * @param {vec2} a vector to calculate squared length of + * @returns {Number} squared length of a + */ - // Set uniforms.*************** - var currentShader = this.postFxShadersManager.pFx_shaders_array[5]; // color selection shader.*** - + function squaredLength$4(a) { + var x = a[0], + y = a[1]; + return x * x + y * y; + } + /** + * Negates the components of a vec2 + * + * @param {vec2} out the receiving vector + * @param {vec2} a vector to negate + * @returns {vec2} out + */ - var shaderProgram = currentShader.program; - gl.useProgram(shaderProgram); - gl.enableVertexAttribArray(currentShader.position3_loc); + function negate$2(out, a) { + out[0] = -a[0]; + out[1] = -a[1]; + return out; + } + /** + * Returns the inverse of the components of a vec2 + * + * @param {vec2} out the receiving vector + * @param {vec2} a vector to invert + * @returns {vec2} out + */ - gl.uniformMatrix4fv(currentShader.modelViewProjectionMatrix4RelToEye_loc, false, this.sceneState.modelViewProjRelToEyeMatrix._floatArrays); - gl.uniform3fv(currentShader.cameraPosHIGH_loc, this.sceneState.encodedCamPosHigh); - gl.uniform3fv(currentShader.cameraPosLOW_loc, this.sceneState.encodedCamPosLow); - - // do the colorCoding render.*** - var idxKey; - var nodesLOD0Count = visibleObjControlerNodes.currentVisibles0.length; - for (var i=0; i 0) { + //TODO: evaluate use of glm_invsqrt here? + len = 1 / Math.sqrt(len); + } - gl.uniform1i(currentShader.hasAditionalMov_loc, false); - gl.uniform3fv(currentShader.aditionalMov_loc, [0.0, 0.0, 0.0]); //.*** + out[0] = a[0] * len; + out[1] = a[1] * len; + return out; + } + /** + * Calculates the dot product of two vec2's + * + * @param {vec2} a the first operand + * @param {vec2} b the second operand + * @returns {Number} dot product of a and b + */ - this.renderer.renderLodBuildingColorSelection(gl, lowestOctree.lego, this, currentShader); - } - } - - var nodesLOD2Count = visibleObjControlerNodes.currentVisibles2.length; - for (var i=0; i 0) { + //TODO: evaluate use of glm_invsqrt here? + len1 = 1 / Math.sqrt(len1); + } - // now, select the object.*** - var idx = 64516*pixels[0] + 254*pixels[1] + pixels[2]; - this.selectionCandidates.selectObjects(idx); - - var selectedObject = this.selectionCandidates.currentReferenceSelected; + var len2 = x2 * x2 + y2 * y2; - resultSelectedArray[0] = this.selectionCandidates.currentBuildingSelected; - resultSelectedArray[1] = this.selectionCandidates.currentOctreeSelected; - resultSelectedArray[2] = this.selectionCandidates.currentReferenceSelected; - resultSelectedArray[3] = this.selectionCandidates.currentNodeSelected; - - return selectedObject; -}; + if (len2 > 0) { + //TODO: evaluate use of glm_invsqrt here? + len2 = 1 / Math.sqrt(len2); + } + var cosine = (x1 * x2 + y1 * y2) * len1 * len2; -/** - * Calculates the direction vector of a ray that starts in the camera position and - * continues to the pixel position in world space. - * @param {GL} gl 변수 - * @param {int} pixelX Screen x position of the pixel. - * @param {int} pixelY Screen y position of the pixel. - * @returns {Line} resultRay - */ -MagoManager.prototype.getRayWorldSpace = function(gl, pixelX, pixelY, resultRay) -{ - // in this function the "ray" is a line.*** - if (resultRay === undefined) - { resultRay = new Line(); } - - // world ray = camPos + lambda*camDir. - var camPos = this.sceneState.camera.position; - var rayCamSpace = new Float32Array(3); - rayCamSpace = this.getRayCamSpace(pixelX, pixelY, rayCamSpace); - - if (this.pointSC === undefined) - { this.pointSC = new Point3D(); } - - this.pointSC.set(rayCamSpace[0], rayCamSpace[1], rayCamSpace[2]); + if (cosine > 1.0) { + return 0; + } else if (cosine < -1.0) { + return Math.PI; + } else { + return Math.acos(cosine); + } + } + /** + * Set the components of a vec2 to zero + * + * @param {vec2} out the receiving vector + * @returns {vec2} out + */ - // now, must transform this posCamCoord to world coord.*** - this.pointSC2 = this.sceneState.modelViewMatrixInv.rotatePoint3D(this.pointSC, this.pointSC2); // rayWorldSpace.*** - this.pointSC2.unitary(); // rayWorldSpace.*** - resultRay.setPointAndDir(camPos.x, camPos.y, camPos.z, this.pointSC2.x, this.pointSC2.y, this.pointSC2.z);// original.*** + function zero$2(out) { + out[0] = 0.0; + out[1] = 0.0; + return out; + } + /** + * Returns a string representation of a vector + * + * @param {vec2} a vector to represent as a string + * @returns {String} string representation of the vector + */ - return resultRay; -}; + function str$8(a) { + return 'vec2(' + a[0] + ', ' + a[1] + ')'; + } + /** + * Returns whether or not the vectors exactly have the same elements in the same position (when compared with ===) + * + * @param {vec2} a The first vector. + * @param {vec2} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ -/** - * Calculates the direction vector of a ray that starts in the camera position and - * continues to the pixel position in camera space. - * @param {GL} gl 변수 - * @param {int} pixelX Screen x position of the pixel. - * @param {int} pixelY Screen y position of the pixel. - * @returns {Float32Array(3)} resultRay Result of the calculation. - */ -MagoManager.prototype.getRayCamSpace = function(pixelX, pixelY, resultRay) -{ - // in this function "ray" is a vector.*** - var frustum_far = 1.0; // unitary frustum far.*** - var fov = this.sceneState.camera.frustum.fovyRad; - var aspectRatio = this.sceneState.camera.frustum.aspectRatio; + function exactEquals$8(a, b) { + return a[0] === b[0] && a[1] === b[1]; + } + /** + * Returns whether or not the vectors have approximately the same elements in the same position. + * + * @param {vec2} a The first vector. + * @param {vec2} b The second vector. + * @returns {Boolean} True if the vectors are equal, false otherwise. + */ - var hfar = 2.0 * Math.tan(fov/2.0) * frustum_far; - var wfar = hfar * aspectRatio; - var mouseX = pixelX; - var mouseY = this.sceneState.drawingBufferHeight - pixelY; - if (resultRay === undefined) - { resultRay = new Float32Array(3); } - resultRay[0] = wfar*((mouseX/this.sceneState.drawingBufferWidth) - 0.5); - resultRay[1] = hfar*((mouseY/this.sceneState.drawingBufferHeight) - 0.5); - resultRay[2] = - frustum_far; - return resultRay; -}; + function equals$9(a, b) { + var a0 = a[0], + a1 = a[1]; + var b0 = b[0], + b1 = b[1]; + return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)); + } + /** + * Alias for {@link vec2.length} + * @function + */ -/** - * Calculates the plane on move an object. - * @param {GL} gl 변수 - * @param {int} pixelX Screen x position of the pixel. - * @param {int} pixelY Screen y position of the pixel. - * @return {Plane} resultSelObjMovePlane Calculated plane. - */ -MagoManager.prototype.calculateSelObjMovePlaneAsimetricMode = function(gl, pixelX, pixelY, resultSelObjMovePlane) -{ - if (this.pointSC === undefined) - { this.pointSC = new Point3D(); } - - if (this.pointSC2 === undefined) - { this.pointSC2 = new Point3D(); } - - var geoLocDataManager = this.getNodeGeoLocDataManager(this.nodeSelected); - - this.calculatePixelPositionWorldCoord(gl, pixelX, pixelY, this.pointSC2); - var buildingGeoLocation = geoLocDataManager.getCurrentGeoLocationData(); - this.pointSC = buildingGeoLocation.tMatrixInv.transformPoint3D(this.pointSC2, this.pointSC); // buildingSpacePoint.*** + var len$4 = length$4; + /** + * Alias for {@link vec2.subtract} + * @function + */ - if (resultSelObjMovePlane === undefined) - { resultSelObjMovePlane = new Plane(); } - // the plane is in world coord.*** - resultSelObjMovePlane.setPointAndNormal(this.pointSC.x, this.pointSC.y, this.pointSC.z, 0.0, 0.0, 1.0); - return resultSelObjMovePlane; -}; + var sub$6 = subtract$6; + /** + * Alias for {@link vec2.multiply} + * @function + */ -/** - * Calculates the pixel position in camera coordinates. - * @param {GL} gl 변수 - * @param {int} pixelX Screen x position of the pixel. - * @param {int} pixelY Screen y position of the pixel. - * @param {Point3D} resultPixelPos The result of the calculation. - * @return {Point3D} resultPixelPos The result of the calculation. - */ -MagoManager.prototype.calculatePixelPositionCamCoord = function(gl, pixelX, pixelY, resultPixelPos) -{ - // depth render. - gl.enable(gl.DEPTH_TEST); - gl.depthFunc(gl.LEQUAL); - gl.depthRange(0, 1); - gl.frontFace(gl.CCW); + var mul$8 = multiply$8; + /** + * Alias for {@link vec2.divide} + * @function + */ - var current_frustum_far = this.sceneState.camera.frustum.far; - //var frustum = this.myCameraSCX.getFrustum(0); - //var current_frustum_far = frustum.far; - - if (this.depthFboNeo) - { - this.depthFboNeo.bind(); // bind the existent last depthFramebuffer. - } - else - { - // never enter here. - if (this.depthFboNeo === undefined) - { this.depthFboNeo = new FBO(gl, this.sceneState.drawingBufferWidth, this.sceneState.drawingBufferHeight); } - this.depthFboNeo.bind(); + var div$2 = divide$2; + /** + * Alias for {@link vec2.distance} + * @function + */ - gl.clearColor(1, 1, 1, 1); // white background.*** - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // clear buffer.*** - gl.disable(gl.BLEND); - var ssao_idx = 0; - this.depthRenderLowestOctreeAsimetricVersion(gl, ssao_idx, this.visibleObjControlerNodes); - } + var dist$2 = distance$2; + /** + * Alias for {@link vec2.squaredDistance} + * @function + */ - // Now, read the pixel and find the pixel position. - var depthPixels = new Uint8Array(4 * 1 * 1); // 4 x 1x1 pixel.*** - gl.readPixels(pixelX, this.sceneState.drawingBufferHeight - pixelY, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, depthPixels); - var zDepth = depthPixels[0]/(256.0*256.0*256.0) + depthPixels[1]/(256.0*256.0) + depthPixels[2]/256.0 + depthPixels[3]; // 0 to 256 range depth.*** - zDepth /= 256.0; // convert to 0 to 1.0 range depth.*** - var realZDepth = zDepth*current_frustum_far; - - // now, find the 3d position of the pixel in camCoord.**** - this.resultRaySC = this.getRayCamSpace(pixelX, pixelY, this.resultRaySC); - if (resultPixelPos === undefined) - { resultPixelPos = new Point3D(); } + var sqrDist$2 = squaredDistance$2; + /** + * Alias for {@link vec2.squaredLength} + * @function + */ - this.depthFboNeo.unbind(); - - resultPixelPos.set(this.resultRaySC[0] * realZDepth, this.resultRaySC[1] * realZDepth, this.resultRaySC[2] * realZDepth); - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - return resultPixelPos; -}; + var sqrLen$4 = squaredLength$4; + /** + * Perform some operation over an array of vec2s. + * + * @param {Array} a the array of vectors to iterate over + * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed + * @param {Number} offset Number of elements to skip at the beginning of the array + * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array + * @param {Function} fn Function to call for each vector in the array + * @param {Object} [arg] additional argument to pass to fn + * @returns {Array} a + * @function + */ -/** - * Calculates the pixel position in world coordinates. - * @param {GL} gl 변수 - * @param {int} pixelX Screen x position of the pixel. - * @param {int} pixelY Screen y position of the pixel. - * @param {Point3D} resultPixelPos The result of the calculation. - * @return {Point3D} resultPixelPos The result of the calculation. - */ -MagoManager.prototype.calculatePixelPositionWorldCoord = function(gl, pixelX, pixelY, resultPixelPos) -{ - var pixelPosCamCoord = new Point3D(); - pixelPosCamCoord = this.calculatePixelPositionCamCoord(gl, pixelX, pixelY, pixelPosCamCoord); + var forEach$2 = function () { + var vec = create$8(); + return function (a, stride, offset, count, fn, arg) { + var i, l; - if (resultPixelPos === undefined) - { var resultPixelPos = new Point3D(); } + if (!stride) { + stride = 2; + } - resultPixelPos = this.cameraCoordPositionToWorldCoord(pixelPosCamCoord, resultPixelPos); - return resultPixelPos; -}; + if (!offset) { + offset = 0; + } -/** - * Calculates the cameraCoord position in world coordinates. - * @param {Point3D} cameraCoord position. - * @return {Point3D} resultPixelPos The result of the calculation. - */ -MagoManager.prototype.cameraCoordPositionToWorldCoord = function(camCoordPos, resultWorldPos) -{ - // now, must transform this pixelCamCoord to world coord.*** - var mv_inv = this.sceneState.modelViewMatrixInv; - if (resultWorldPos === undefined) - { var resultWorldPos = new Point3D(); } - resultWorldPos = mv_inv.transformPoint3D(camCoordPos, resultWorldPos); - return resultWorldPos; -}; + if (count) { + l = Math.min(count * stride + offset, a.length); + } else { + l = a.length; + } -/** - * Calculates the pixel position in world coordinates. - * @param {GL} gl 변수 - * @param {int} pixelX Screen x position of the pixel. - * @param {int} pixelY Screen y position of the pixel. - * @param {Point3D} resultPixelPos The result of the calculation. - * @return {Point3D} resultPixelPos The result of the calculation. - */ -MagoManager.prototype.calculateWorldPositionToScreenCoord = function(gl, worldCoordX, worldCoordY, worldCoordZ, resultScreenCoord) -{ - if (resultScreenCoord === undefined) - { resultScreenCoord = new Point3D(); } - - if (this.pointSC === undefined) - { this.pointSC = new Point3D(); } - - if (this.pointSC2 === undefined) - { this.pointSC2 = new Point3D(); } - - this.pointSC.set(worldCoordX, worldCoordY, worldCoordZ); - - // calculate the position in camera coords. - this.pointSC2 = this.sceneState.modelViewMatrix.transformPoint3D(this.pointSC, this.pointSC2); - - // now calculate the position in screen coords. - var zDist = this.pointSC2.z; - if (zDist > 0) - { - // the worldPoint is rear the camera. - resultScreenCoord.set(-1, -1, 0); - return resultScreenCoord; - } - - // now calculate the width and height of the plane in zDist. - //var fovyRad = this.sceneState.camera.frustum.fovyRad; - - var planeHeight = this.sceneState.camera.frustum.tangentOfHalfFovy*zDist*2; - var planeWidth = planeHeight * this.sceneState.camera.frustum.aspectRatio; // aspectRatio(w/h). - - var pixelX = -this.pointSC2.x * this.sceneState.drawingBufferWidth / planeWidth; - var pixelY = -(this.pointSC2.y) * this.sceneState.drawingBufferHeight / planeHeight; + for (i = offset; i < l; i += stride) { + vec[0] = a[i]; + vec[1] = a[i + 1]; + fn(vec, vec, arg); + a[i] = vec[0]; + a[i + 1] = vec[1]; + } - pixelX += this.sceneState.drawingBufferWidth / 2; - pixelY += this.sceneState.drawingBufferHeight / 2; - - pixelY = this.sceneState.drawingBufferHeight - pixelY; - - resultScreenCoord.set(pixelX, pixelY, 0); - - return resultScreenCoord; -}; + return a; + }; + }(); + + var vec2 = /*#__PURE__*/Object.freeze({ + create: create$8, + clone: clone$8, + fromValues: fromValues$8, + copy: copy$8, + set: set$8, + add: add$8, + subtract: subtract$6, + multiply: multiply$8, + divide: divide$2, + ceil: ceil$2, + floor: floor$2, + min: min$2, + max: max$2, + round: round$2, + scale: scale$8, + scaleAndAdd: scaleAndAdd$2, + distance: distance$2, + squaredDistance: squaredDistance$2, + length: length$4, + squaredLength: squaredLength$4, + negate: negate$2, + inverse: inverse$2, + normalize: normalize$4, + dot: dot$4, + cross: cross$2, + lerp: lerp$4, + random: random$3, + transformMat2: transformMat2, + transformMat2d: transformMat2d, + transformMat3: transformMat3$1, + transformMat4: transformMat4$2, + rotate: rotate$4, + angle: angle$1, + zero: zero$2, + str: str$8, + exactEquals: exactEquals$8, + equals: equals$9, + len: len$4, + sub: sub$6, + mul: mul$8, + div: div$2, + dist: dist$2, + sqrDist: sqrDist$2, + sqrLen: sqrLen$4, + forEach: forEach$2 + }); + + exports.glMatrix = common; + exports.mat2 = mat2; + exports.mat2d = mat2d; + exports.mat3 = mat3; + exports.mat4 = mat4; + exports.quat = quat; + exports.quat2 = quat2; + exports.vec2 = vec2; + exports.vec3 = vec3; + exports.vec4 = vec4; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = global || self, global.i18next = factory()); +}(this, function () { 'use strict'; + + function _typeof(obj) { + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function (obj) { + return typeof obj; + }; + } else { + _typeof = function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + } -/** - * 드래그 여부 판단 - * - * @returns {Boolean} 드래그 여부 - */ -MagoManager.prototype.isDragging = function() -{ - // test function.*** - var gl = this.sceneState.gl; + return _typeof(obj); + } - if (this.magoPolicy.objectMoveMode === CODE.moveMode.ALL) // Moving all - { - this.arrayAuxSC.length = 0; - this.selectionFbo.bind(); - var current_objectSelected = this.getSelectedObjects(gl, this.mouse_x, this.mouse_y, this.arrayAuxSC); - var currentBuildingSelected = this.arrayAuxSC[0]; - var currentNodeSelected = this.arrayAuxSC[3]; - var currentRootNodeSelected; - if (currentNodeSelected) - { - currentRootNodeSelected = currentNodeSelected.getRoot(); - } - this.arrayAuxSC.length = 0; + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } - if (currentRootNodeSelected === this.rootNodeSelected) - { - return true; - } - else - { - return false; - } - } - else if (this.magoPolicy.objectMoveMode === CODE.moveMode.OBJECT) // Moving object - { - this.arrayAuxSC.length = 0; - this.selectionFbo.bind(); - var current_objectSelected = this.getSelectedObjects(gl, this.mouse_x, this.mouse_y, this.arrayAuxSC); - this.arrayAuxSC.length = 0; + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } - if (current_objectSelected === this.objectSelected) - { - return true; - } - else - { - return false; - } - } - else - { - return false; - } + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } -}; + function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } -/** - * 카메라 motion 활성 또는 비활성 - * - * @param {Boolean} state 카메라 모션 활성화 여부 - */ -MagoManager.prototype.setCameraMotion = function(state) -{ - if (this.configInformation.geo_view_library === Constant.WORLDWIND) - { - this.wwd.navigator.panRecognizer.enabled = state; - this.wwd.navigator.primaryDragRecognizer.enabled = state; - } - else if (this.configInformation.geo_view_library === Constant.CESIUM) - { - this.scene.screenSpaceCameraController.enableRotate = state; - this.scene.screenSpaceCameraController.enableZoom = state; - this.scene.screenSpaceCameraController.enableLook = state; - this.scene.screenSpaceCameraController.enableTilt = state; - this.scene.screenSpaceCameraController.enableTranslate = state; - } -}; + return obj; + } -/** - * 선택 객체를 asimetric mode 로 이동 - * @param gl 변수 - * @param scene 변수 - */ -MagoManager.prototype.mouseActionLeftDown = function(mouseX, mouseY) -{ - this.dateSC = new Date(); - this.startTimeSC = this.dateSC.getTime(); + function _objectSpread(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i] != null ? arguments[i] : {}; + var ownKeys = Object.keys(source); - this.mouse_x = mouseX; - this.mouse_y = mouseY; - this.mouseLeftDown = true; - //this.isCameraMoving = true; -}; + if (typeof Object.getOwnPropertySymbols === 'function') { + ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { + return Object.getOwnPropertyDescriptor(source, sym).enumerable; + })); + } -/** - * 선택 객체를 asimetric mode 로 이동 - * @param gl 변수 - * @param scene 변수 - */ -MagoManager.prototype.saveHistoryObjectMovement = function(refObject, node) -{ - var changeHistory = new ChangeHistory(); - var refMove = changeHistory.getReferenceObjectAditionalMovement(); - var refMoveRelToBuilding = changeHistory.getReferenceObjectAditionalMovementRelToBuilding(); - - if (refObject.moveVector === undefined) - { refObject.moveVector = new Point3D(); } - - if (refObject.moveVectorRelToBuilding === undefined) - { refObject.moveVectorRelToBuilding = new Point3D(); } - - refMove.set(refObject.moveVector.x, refObject.moveVector.y, refObject.moveVector.z); - refMoveRelToBuilding.set(refObject.moveVectorRelToBuilding.x, refObject.moveVectorRelToBuilding.y, refObject.moveVectorRelToBuilding.z); - if (node === undefined) - { return; } + ownKeys.forEach(function (key) { + _defineProperty(target, key, source[key]); + }); + } - var projectId = node.data.projectId; - var dataKey = node.data.nodeId; - var objectIndex = refObject._id; - - changeHistory.setProjectId(projectId); - changeHistory.setDataKey(dataKey); - changeHistory.setObjectIndexOrder(objectIndex); - MagoConfig.saveMovingHistory(projectId, dataKey, objectIndex, changeHistory); -}; + return target; + } -/** - * 선택 객체를 asimetric mode 로 이동 - * @param gl 변수 - * @param scene 변수 - */ -MagoManager.prototype.mouseActionLeftUp = function(mouseX, mouseY) -{ - if (this.objectMoved) - { - this.objectMoved = false; - var nodeSelected = this.selectionCandidates.currentNodeSelected; - if (nodeSelected === undefined) - { return; } - - this.saveHistoryObjectMovement(this.objectSelected, nodeSelected); - } - - this.isCameraMoving = false; - this.mouseLeftDown = false; - this.mouseDragging = false; - this.selObjMovePlane = undefined; - this.mustCheckIfDragging = true; - this.thereAreStartMovePoint = false; + function _inherits(subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function"); + } - this.dateSC = new Date(); - this.currentTimeSC = this.dateSC.getTime(); - var miliSecondsUsed = this.currentTimeSC - this.startTimeSC; - if (miliSecondsUsed < 1500) - { - if (this.mouse_x === mouseX && this.mouse_y === mouseY) - { - this.bPicking = true; - } - } - - this.setCameraMotion(true); -}; + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + writable: true, + configurable: true + } + }); + if (superClass) _setPrototypeOf(subClass, superClass); + } -/** - * 선택 객체를 asimetric mode 로 이동 - * @param gl 변수 - * @param scene 변수 - */ -MagoManager.prototype.mouseActionMiddleDown = function(mouseX, mouseY) -{ - this.dateSC = new Date(); - this.startTimeSC = this.dateSC.getTime(); + function _getPrototypeOf(o) { + _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { + return o.__proto__ || Object.getPrototypeOf(o); + }; + return _getPrototypeOf(o); + } - this.mouse_x = mouseX; - this.mouse_y = mouseY; - this.mouseMiddleDown = true; - this.isCameraMoving = true; -}; + function _setPrototypeOf(o, p) { + _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; -/** - * 선택 객체를 asimetric mode 로 이동 - * @param gl 변수 - * @param scene 변수 - */ -MagoManager.prototype.mouseActionMiddleUp = function(mouseX, mouseY) -{ - this.isCameraMoving = false; - this.mouseMiddleDown = false; - this.mouseDragging = false; - this.selObjMovePlane = undefined; - this.mustCheckIfDragging = true; - this.thereAreStartMovePoint = false; - this.setCameraMotion(false); -}; + return _setPrototypeOf(o, p); + } -/** - * 선택 객체를 asimetric mode 로 이동 - * @param gl 변수 - * @param scene 변수 - */ -MagoManager.prototype.mouseActionRightDown = function(mouseX, mouseY) -{ - /* - this.dateSC = new Date(); - this.startTimeSC = this.dateSC.getTime(); + function _assertThisInitialized(self) { + if (self === void 0) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } - this.mouse_x = mouseX; - this.mouse_y = mouseY; - this.mouseRightDown = true; - this.isCameraMoving = true; - */ -}; + return self; + } -/** - * 선택 객체를 asimetric mode 로 이동 - * @param gl 변수 - * @param scene 변수 - */ -MagoManager.prototype.mouseActionRightUp = function(mouseX, mouseY) -{ - /* - this.isCameraMoving = false; - this.setCameraMotion(false); - */ -}; + function _possibleConstructorReturn(self, call) { + if (call && (typeof call === "object" || typeof call === "function")) { + return call; + } -/** - * 선택 객체를 asimetric mode 로 이동 - * @param gl 변수 - * @param scene 변수 - */ -MagoManager.prototype.mouseActionMove = function(mouseX, mouseY) -{ - if (this.mouseLeftDown) - { - this.manageMouseDragging(mouseX, mouseY); - } - else if (this.mouseMiddleDown) - { - this.sceneState.camera.setDirty(true); - } - else if (this.mouseRightDown) - { - this.sceneState.camera.setDirty(true); - } - else - { - this.mouseDragging = false; - this.setCameraMotion(false); - if (this.mouseMiddleDown) - { - this.isCameraMoving = true; - } - } -}; + return _assertThisInitialized(self); + } + function _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); + } -/** - * 선택 객체를 asimetric mode 로 이동 - * @param gl 변수 - * @param scene 변수 - * @param renderables_neoRefLists_array 변수 - */ -MagoManager.prototype.manageMouseDragging = function(mouseX, mouseY) -{ - this.sceneState.camera.setDirty(true); - - // distinguish 2 modes.****************************************************** - if (this.magoPolicy.objectMoveMode === CODE.moveMode.ALL) // blocks move.*** - { - if (this.buildingSelected !== undefined) - { - // move the selected object.*** - this.mouse_x = mouseX; - this.mouse_y = mouseY; + function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); + } - // 1rst, check if there are objects to move.*** - if (this.mustCheckIfDragging) - { - if (this.isDragging()) - { - this.mouseDragging = true; - this.setCameraMotion(false); - } - this.mustCheckIfDragging = false; - } - // Display geoLocationData while moving building.*** - var nodeOwner = this.buildingSelected.nodeOwner; - if (nodeOwner === undefined) - { return; } + function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; - var geoLocDataManager = nodeOwner.data.geoLocDataManager; - if (geoLocDataManager === undefined) - { return; } + return arr2; + } + } - var geoLocation = geoLocDataManager.getGeoLocationData(0); - if (geoLocation === undefined) - { return; } + function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; + } - var geographicCoords = geoLocation.geographicCoord; - if (geographicCoords === undefined) - { return; } - - movedDataCallback( MagoConfig.getPolicy().geo_callback_moveddata, - nodeOwner.data.projectId, - nodeOwner.data.nodeId, - null, - geographicCoords.latitude, - geographicCoords.longitude, - geographicCoords.altitude, - geoLocation.heading, - geoLocation.pitch, - geoLocation.roll); - - } - else - { - this.isCameraMoving = true; // if no object is selected.*** - } - } - else if (this.magoPolicy.objectMoveMode === CODE.moveMode.OBJECT) // objects move.*** - { - if (this.objectSelected !== undefined) - { - // move the selected object.*** - this.mouse_x = mouseX; - this.mouse_y = mouseY; + function _iterableToArray(iter) { + if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); + } - // 1rst, check if there are objects to move.*** - if (this.mustCheckIfDragging) - { - if (this.isDragging()) - { - this.mouseDragging = true; - this.setCameraMotion(false); - } - this.mustCheckIfDragging = false; - } - } - else - { - this.isCameraMoving = true; // if no object is selected.*** - } - } - //--------------------------------------------------------------------------------- - this.isCameraMoving = true; // test.*** - if (this.mouseDragging) - { - this.moveSelectedObjectAsimetricMode(this.sceneState.gl); - } -}; + function _iterableToArrayLimit(arr, i) { + var _arr = []; + var _n = true; + var _d = false; + var _e = undefined; + try { + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); -/** - * Moves an object. - * @param {GL} gl 변수 - */ -MagoManager.prototype.moveSelectedObjectAsimetricMode = function(gl) -{ - //var cameraPosition = this.sceneState.camera.position; - if (this.magoPolicy.objectMoveMode === CODE.moveMode.ALL) // buildings move.*** - { - if (this.selectionCandidates.currentNodeSelected === undefined) - { return; } - - var geoLocDataManager = this.getNodeGeoLocDataManager(this.selectionCandidates.currentNodeSelected); - var geoLocationData = geoLocDataManager.getCurrentGeoLocationData(); - - // create a XY_plane in the selected_pixel_position.*** - if (this.selObjMovePlane === undefined) - { - this.selObjMovePlane = new Plane(); - // create a local XY plane. - // find the pixel position relative to building. - var pixelPosWorldCoord = new Point3D(); - pixelPosWorldCoord = this.calculatePixelPositionWorldCoord(gl, this.mouse_x, this.mouse_y, pixelPosWorldCoord); - var pixelPosBuildingCoord = geoLocationData.tMatrixInv.transformPoint3D(pixelPosWorldCoord, pixelPosBuildingCoord); - - this.selObjMovePlane.setPointAndNormal(pixelPosBuildingCoord.x, pixelPosBuildingCoord.y, pixelPosBuildingCoord.z, 0.0, 0.0, 1.0); - } + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) _i["return"](); + } finally { + if (_d) throw _e; + } + } - if (this.lineSC === undefined) - { this.lineSC = new Line(); } - - this.lineSC = this.getRayWorldSpace(gl, this.mouse_x, this.mouse_y, this.lineSC); // rayWorldSpace.*** + return _arr; + } - // transform world_ray to building_ray.*** - var camPosBuilding = new Point3D(); - var camDirBuilding = new Point3D(); + function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance"); + } - camPosBuilding = geoLocationData.geoLocMatrixInv.transformPoint3D(this.lineSC.point, camPosBuilding); - this.pointSC = geoLocationData.geoLocMatrixInv.rotatePoint3D(this.lineSC.direction, this.pointSC); - camDirBuilding.x = this.pointSC.x; - camDirBuilding.y = this.pointSC.y; - camDirBuilding.z = this.pointSC.z; + function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); + } - // now, intersect building_ray with the selObjMovePlane.*** - var line = new Line(); - line.setPointAndDir(camPosBuilding.x, camPosBuilding.y, camPosBuilding.z, camDirBuilding.x, camDirBuilding.y, camDirBuilding.z); + var consoleLogger = { + type: 'logger', + log: function log(args) { + this.output('log', args); + }, + warn: function warn(args) { + this.output('warn', args); + }, + error: function error(args) { + this.output('error', args); + }, + output: function output(type, args) { + var _console; - var intersectionPoint = new Point3D(); - intersectionPoint = this.selObjMovePlane.intersectionLine(line, intersectionPoint); - intersectionPoint.set(-intersectionPoint.x, -intersectionPoint.y, -intersectionPoint.z); - - if (this.pointSC === undefined) - { this.pointSC = new Point3D(); } - this.pointSC = geoLocationData.geoLocMatrix.transformPoint3D(intersectionPoint, this.pointSC); - intersectionPoint.set(this.pointSC.x, this.pointSC.y, this.pointSC.z); + /* eslint no-console: 0 */ + if (console && console[type]) (_console = console)[type].apply(_console, _toConsumableArray(args)); + } + }; - // register the movement.*** - if (!this.thereAreStartMovePoint) - { - var cartographic = ManagerUtils.pointToGeographicCoord(intersectionPoint, cartographic, this); - this.startMovPoint.x = cartographic.longitude; - this.startMovPoint.y = cartographic.latitude; - this.thereAreStartMovePoint = true; - } - else - { - var cartographic = ManagerUtils.pointToGeographicCoord(intersectionPoint, cartographic, this); - this.pointSC.x = cartographic.longitude; - this.pointSC.y = cartographic.latitude; - var difX = this.pointSC.x - this.startMovPoint.x; - var difY = this.pointSC.y - this.startMovPoint.y; + var Logger = + /*#__PURE__*/ + function () { + function Logger(concreteLogger) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var newLongitude = geoLocationData.geographicCoord.longitude - difX; - var newlatitude = geoLocationData.geographicCoord.latitude - difY; - //var newHeight = cartographic.altitude; + _classCallCheck(this, Logger); - this.changeLocationAndRotationNode(this.selectionCandidates.currentNodeSelected, newlatitude, newLongitude, undefined, undefined, undefined, undefined); - this.displayLocationAndRotation(this.buildingSelected); - - this.startMovPoint.x -= difX; - this.startMovPoint.y -= difY; - } - - //this.buildingSelected.calculateBBoxCenterPositionWorldCoord(geoLocationData); - } - else if (this.magoPolicy.objectMoveMode === CODE.moveMode.OBJECT) // objects move.*** - { - if (this.objectSelected === undefined) - { return; } + this.init(concreteLogger, options); + } - // create a XY_plane in the selected_pixel_position.*** - if (this.selObjMovePlane === undefined) - { - this.selObjMovePlane = this.calculateSelObjMovePlaneAsimetricMode(gl, this.mouse_x, this.mouse_y, this.selObjMovePlane); - } - - var geoLocDataManager = this.getNodeGeoLocDataManager(this.selectionCandidates.currentNodeSelected); + _createClass(Logger, [{ + key: "init", + value: function init(concreteLogger) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + this.prefix = options.prefix || 'i18next:'; + this.logger = concreteLogger || consoleLogger; + this.options = options; + this.debug = options.debug; + } + }, { + key: "setDebug", + value: function setDebug(bool) { + this.debug = bool; + } + }, { + key: "log", + value: function log() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } - // world ray = camPos + lambda*camDir.*** - if (this.lineSC === undefined) - { this.lineSC = new Line(); } - - this.getRayWorldSpace(gl, this.mouse_x, this.mouse_y, this.lineSC); // rayWorldSpace.*** - var buildingGeoLocation = geoLocDataManager.getCurrentGeoLocationData(); - var camPosBuilding = new Point3D(); - var camDirBuilding = new Point3D(); - camPosBuilding = buildingGeoLocation.tMatrixInv.transformPoint3D(this.lineSC.point, camPosBuilding); - camDirBuilding = buildingGeoLocation.tMatrixInv.rotatePoint3D(this.lineSC.direction, camDirBuilding); - - // now, intersect building_ray with the selObjMovePlane.*** - var line = new Line(); - line.setPointAndDir(camPosBuilding.x, camPosBuilding.y, camPosBuilding.z, camDirBuilding.x, camDirBuilding.y, camDirBuilding.z);// original.*** + return this.forward(args, 'log', '', true); + } + }, { + key: "warn", + value: function warn() { + for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } - var intersectionPoint = new Point3D(); - intersectionPoint = this.selObjMovePlane.intersectionLine(line, intersectionPoint); + return this.forward(args, 'warn', '', true); + } + }, { + key: "error", + value: function error() { + for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args[_key3] = arguments[_key3]; + } - //the movement of an object must multiply by buildingRotMatrix.*** - if (this.objectSelected.moveVectorRelToBuilding === undefined) - { this.objectSelected.moveVectorRelToBuilding = new Point3D(); } - - // move vector rel to building. - if (!this.thereAreStartMovePoint) - { - this.startMovPoint = intersectionPoint; - this.startMovPoint.add(-this.objectSelected.moveVectorRelToBuilding.x, -this.objectSelected.moveVectorRelToBuilding.y, -this.objectSelected.moveVectorRelToBuilding.z); - this.thereAreStartMovePoint = true; - } - else - { - var difX = intersectionPoint.x - this.startMovPoint.x; - var difY = intersectionPoint.y - this.startMovPoint.y; - var difZ = intersectionPoint.z - this.startMovPoint.z; + return this.forward(args, 'error', ''); + } + }, { + key: "deprecate", + value: function deprecate() { + for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + args[_key4] = arguments[_key4]; + } - this.objectSelected.moveVectorRelToBuilding.set(difX, difY, difZ); - this.objectSelected.moveVector = buildingGeoLocation.tMatrix.rotatePoint3D(this.objectSelected.moveVectorRelToBuilding, this.objectSelected.moveVector); - } - - var projectId = this.selectionCandidates.currentNodeSelected.data.projectId; - var data_key = this.selectionCandidates.currentNodeSelected.data.nodeId; - var objectIndexOrder = this.objectSelected._id; - - MagoConfig.deleteMovingHistoryObject(projectId, data_key, objectIndexOrder); - this.objectMoved = true; // this provoques that on leftMouseUp -> saveHistoryObjectMovement - - } -}; + return this.forward(args, 'warn', 'WARNING DEPRECATED: ', true); + } + }, { + key: "forward", + value: function forward(args, lvl, prefix, debugOnly) { + if (debugOnly && !this.debug) return null; + if (typeof args[0] === 'string') args[0] = "".concat(prefix).concat(this.prefix, " ").concat(args[0]); + return this.logger[lvl](args); + } + }, { + key: "create", + value: function create(moduleName) { + return new Logger(this.logger, _objectSpread({}, { + prefix: "".concat(this.prefix, ":").concat(moduleName, ":") + }, this.options)); + } + }]); + return Logger; + }(); -/** - * Frustum 안의 VisibleOctree 를 검색하여 currentVisibleOctreesControler 를 준비 - * - * @param {any} gl - * @param {any} scene - * @param {any} neoBuilding - * @param {VisibleObjectsController} visibleObjControlerOctrees - * @param {any} lod - */ -MagoManager.prototype.getRenderablesDetailedNeoBuildingAsimetricVersion = function(gl, node, visibleObjControlerOctrees, lod) -{ - var neoBuilding = node.data.neoBuilding; - - // chaek if the neoBuilding has availableLod_0.*** - if (neoBuilding === undefined || neoBuilding.octree === undefined) { return; } + var baseLogger = new Logger(); - var rootGeoLocDataManager = this.getNodeGeoLocDataManager(node); - var rootGeoLoc = rootGeoLocDataManager.getCurrentGeoLocationData(); - - //var nodeGeoLocation = geoLocDataManager.getCurrentGeoLocationData(); // original.*** - var nodeGeoLocation = rootGeoLocDataManager.getCurrentGeoLocationData(); - if (nodeGeoLocation === undefined) - { return false; } + var EventEmitter = + /*#__PURE__*/ + function () { + function EventEmitter() { + _classCallCheck(this, EventEmitter); - if (neoBuilding.currentVisibleOctreesControler === undefined) - { neoBuilding.currentVisibleOctreesControler = new VisibleObjectsController(); } + this.observers = {}; + } - var distLod0 = this.magoPolicy.getLod0DistInMeters(); - var distLod1 = this.magoPolicy.getLod1DistInMeters(); - var distLod2 = this.magoPolicy.getLod2DistInMeters(); - var distLod3 = this.magoPolicy.getLod3DistInMeters(); - var distLod4 = this.magoPolicy.getLod4DistInMeters(); - var distLod5 = this.magoPolicy.getLod5DistInMeters(); + _createClass(EventEmitter, [{ + key: "on", + value: function on(events, listener) { + var _this = this; - var find = false; - if (this.myCameraRelative === undefined) - { this.myCameraRelative = new Camera(); } - - this.myCameraRelative.frustum.copyParametersFrom(this.myCameraSCX.bigFrustum); - this.myCameraRelative = nodeGeoLocation.getTransformedRelativeCamera(this.sceneState.camera, this.myCameraRelative); - //var isCameraInsideOfBuilding = neoBuilding.isCameraInsideOfBuilding(this.myCameraRelative.position.x, this.myCameraRelative.position.y, this.myCameraRelative.position.z); // old.*** - - neoBuilding.currentVisibleOctreesControler.clear(); - - if (lod === 2) - { - // in this case is not necessary calculate the frustum planes. - neoBuilding.octree.extractLowestOctreesByLOD(neoBuilding.currentVisibleOctreesControler, visibleObjControlerOctrees, this.boundingSphere_Aux, - this.myCameraRelative.position, distLod0, distLod1, distLod5); - find = true; - } - else - { - // must calculate the frustum planes. - this.myCameraRelative.calculateFrustumsPlanes(); - - // 1rst, check if there are octrees very close. - var frustum0 = this.myCameraRelative.bigFrustum; - find = neoBuilding.octree.getFrustumVisibleLowestOctreesByLOD( frustum0, neoBuilding.currentVisibleOctreesControler, visibleObjControlerOctrees, this.boundingSphere_Aux, - this.myCameraRelative.position, distLod0, distLod1, distLod2*100); - } + events.split(' ').forEach(function (event) { + _this.observers[event] = _this.observers[event] || []; - if (!find) - { - // if the building is far to camera, then delete it. - if (neoBuilding.distToCam > 10) // default: 60.*** - { this.processQueue.putNodeToDeleteModelReferences(node, 1); } - return false; - } - else - { - this.processQueue.eraseNodeToDeleteModelReferences(node); - } - - // LOD0 & LOD1 - // Check if the lod0lowestOctrees, lod1lowestOctrees must load and parse data - var lowestOctree; - var currentVisibleOctrees = [].concat(neoBuilding.currentVisibleOctreesControler.currentVisibles0, neoBuilding.currentVisibleOctreesControler.currentVisibles1); - var applyOcclusionCulling = neoBuilding.getRenderSettingApplyOcclusionCulling(); - - // if there are no lod0 & lod1 then put the neobuilding to delete model-references data. - if (currentVisibleOctrees.length === 0) - { - this.processQueue.putNodeToDeleteModelReferences(node, 0); - } - else - { - this.processQueue.eraseNodeToDeleteModelReferences(node); - } - - var putLowestOctreeToLod2 = false; - for (var i=0, length = currentVisibleOctrees.length; i 6) - { visibleOctreesCount = 6; } - for (var j=0; j maxDeleteBuildingsCount) - // { break; } - //} - - //if(this.isFarestFrustum()) - { - for (var key in this.processQueue.nodesToDeleteMap) - { - if (Object.prototype.hasOwnProperty.call(this.processQueue.nodesToDeleteMap, key)) - { - //node = nodesToDeleteArray[i]; - node = this.processQueue.nodesToDeleteMap[key]; - - if (node === undefined) - { continue; } + if (index > -1) { + _this2.observers[event].splice(index, 1); + } + } + }); + } + }, { + key: "emit", + value: function emit(event) { + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } - neoBuilding = node.data.neoBuilding; - this.processQueue.eraseNodeToDelete(node); - - if (neoBuilding === undefined) - { continue; } - - var deleteMetaData = true; - if (key == 1) - { deleteMetaData = false; } - this.deleteNeoBuilding(gl, neoBuilding, deleteMetaData); - } - } - - // now delete modelReferences of lod2Octrees. - var modelRefsDeletedCount = 0; - for (var key in this.processQueue.nodesToDeleteModelReferencesMap) - { - if (Object.prototype.hasOwnProperty.call(this.processQueue.nodesToDeleteModelReferencesMap, key)) - { - //node = nodesToDeleteModelReferencesArray[i]; - node = this.processQueue.nodesToDeleteModelReferencesMap[key]; - - if (node.data === undefined) - { continue; } - - neoBuilding = node.data.neoBuilding; - this.processQueue.eraseNodeToDeleteModelReferences(neoBuilding); - if (neoBuilding === undefined) - { continue; } + if (this.observers[event]) { + var cloned = [].concat(this.observers[event]); + cloned.forEach(function (observer) { + observer.apply(void 0, args); + }); + } - if (neoBuilding.octree) - { - neoBuilding.octree.deleteObjectsModelReferences(gl, this.vboMemoryManager); - } - if (neoBuilding.motherBlocksArray.length > 0 || neoBuilding.motherNeoReferencesArray.length > 0) - { - modelRefsDeletedCount ++; - } - neoBuilding.deleteObjectsModelReferences(gl, this.vboMemoryManager); - - if (modelRefsDeletedCount > 10) - { break; } - } - } - } - - var deletedCount = 0; - for (var key in this.processQueue.nodesToDeleteLessThanLod3Map) - { - node = this.processQueue.nodesToDeleteLessThanLod3Map[key]; - //node = nodesToDeleteLod2Lod4Lod5Array[i]; - if (node.data === undefined) - { continue; } - - if (this.processQueue.eraseNodeToDeleteLessThanLod3(node)) - { - neoBuilding = node.data.neoBuilding; - if (neoBuilding === undefined) - { continue; } - - if (neoBuilding.octree) - { - neoBuilding.octree.deleteObjectsModelReferences(gl, this.vboMemoryManager); - } - if (neoBuilding.motherBlocksArray.length > 0 || neoBuilding.motherNeoReferencesArray.length > 0) - { - modelRefsDeletedCount ++; - } - - neoBuilding.deleteObjectsModelReferences(gl, this.vboMemoryManager); - neoBuilding.deleteObjectsLod2(gl, this.vboMemoryManager); - deletedCount++; - - if (deletedCount > 10) - { break; } - } - } - - deletedCount = 0; - for (var key in this.processQueue.nodesToDeleteLessThanLod4Map) - { - node = this.processQueue.nodesToDeleteLessThanLod4Map[key]; - if (node.data === undefined) - { continue; } - - if (this.processQueue.eraseNodeToDeleteLessThanLod4(node)) - { - neoBuilding = node.data.neoBuilding; - if (neoBuilding === undefined) - { continue; } - - neoBuilding.deleteObjectsModelReferences(gl, this.vboMemoryManager); - neoBuilding.deleteObjectsLod2(gl, this.vboMemoryManager); - neoBuilding.deleteObjectsLodMesh(gl, this.vboMemoryManager, "lod3"); - deletedCount++; - - if (deletedCount > 10) - { break; } - } - } - - deletedCount = 0; - for (var key in this.processQueue.nodesToDeleteLessThanLod5Map) - { - node = this.processQueue.nodesToDeleteLessThanLod5Map[key]; - if (node.data === undefined) - { continue; } - - if (this.processQueue.eraseNodeToDeleteLessThanLod5(node)) - { - neoBuilding = node.data.neoBuilding; - if (neoBuilding === undefined) - { continue; } - - neoBuilding.deleteObjectsModelReferences(gl, this.vboMemoryManager); - neoBuilding.deleteObjectsLod2(gl, this.vboMemoryManager); - neoBuilding.deleteObjectsLodMesh(gl, this.vboMemoryManager, "lod3"); - neoBuilding.deleteObjectsLodMesh(gl, this.vboMemoryManager, "lod4"); - deletedCount++; - - if (deletedCount > 10) - { break; } - } - } - - - // now, delete lod0, lod1, lod2.*** - var deletedCount = 0; - - // parse pendent data.********************************************************************************** - var maxParsesCount = 1; - - // parse references lod0 & lod 1. - var lowestOctree; - var neoBuilding; - var headerVersion; - var geoLocDataManager; - var octreesParsedCount = 0; - - if (this.matrix4SC === undefined) - { this.matrix4SC = new Matrix4(); } + if (this.observers['*']) { + var _cloned = [].concat(this.observers['*']); - // is desirable to parse octrees references ordered by the current eye distance. - // in the "visibleObjControlerOctrees" there are the octrees sorted by distance, so must use it. - // parse octrees lod1 references. - octreesParsedCount = 0; - maxParsesCount = 1; - - if (this.parseQueue.parseOctreesLod0References(gl, this.visibleObjControlerOctrees, this, maxParsesCount)) - { - if (this.selectionFbo) - { this.selectionFbo.dirty = true; } - } - - // parse octrees lod1 references. - octreesParsedCount = 0; - maxParsesCount = 1; - if (Object.keys(this.parseQueue.octreesLod0ReferencesToParseMap).length > 0) - { - // 1rst parse the currently closest lowestOctrees to camera. - var octreesLod0Count = this.visibleObjControlerOctrees.currentVisibles1.length; - for (var i=0; i maxParsesCount) - { break; } - } - - if (octreesParsedCount === 0) - { - for (var key in this.parseQueue.octreesLod0ReferencesToParseMap) - { - if (Object.prototype.hasOwnProperty.call(this.parseQueue.octreesLod0ReferencesToParseMap, key)) - { - var lowestOctree = this.parseQueue.octreesLod0ReferencesToParseMap[key]; - //lowestOctree = octreesArray[i]; - this.parseQueue.parseOctreesLod0References(gl, lowestOctree, this); - octreesParsedCount++; - if (octreesParsedCount > maxParsesCount) - { break; } - } - } - } - - if (octreesParsedCount > 0) - { - if (this.selectionFbo) - { this.selectionFbo.dirty = true; } - } - } - - // parse octrees lod0 models. - octreesParsedCount = 0; - maxParsesCount = 1; - if (Object.keys(this.parseQueue.octreesLod0ModelsToParseMap).length > 0) - { - // 1rst parse the currently closest lowestOctrees to camera. - var octreesLod0Count = this.visibleObjControlerOctrees.currentVisibles0.length; - for (var i=0; i maxParsesCount) - { break; } - } - - if (octreesParsedCount === 0) - { - //var octreesArray = Array.from(this.parseQueue.octreesLod0ModelsToParseMap.keys()); - //for (var i=0; i maxParsesCount) - { break; } - } - } - } - - - if (octreesParsedCount > 0) - { - if (this.selectionFbo) - { this.selectionFbo.dirty = true; } - } - } - - // parse octrees lod1 models. - octreesParsedCount = 0; - maxParsesCount = 1; - if (Object.keys(this.parseQueue.octreesLod0ModelsToParseMap).length > 0) - { - // 1rst parse the currently closest lowestOctrees to camera. - var octreesLod0Count = this.visibleObjControlerOctrees.currentVisibles1.length; - for (var i=0; i -1 ? key.replace(/###/g, '.') : key; + } - if (this.parseQueue.octreesLod0ModelsToParseMap.hasOwnProperty(lowestOctree.octreeKey)) - { - delete this.parseQueue.octreesLod0ModelsToParseMap[lowestOctree.octreeKey]; - if (lowestOctree.neoReferencesMotherAndIndices === undefined) - { continue; } - - var blocksList = lowestOctree.neoReferencesMotherAndIndices.blocksList; - if (blocksList === undefined) - { continue; } - - if (blocksList.dataArraybuffer === undefined) - { continue; } - - if (blocksList.fileLoadState !== CODE.fileLoadState.LOADING_FINISHED) - { continue; } - - neoBuilding = lowestOctree.neoBuildingOwner; - headerVersion = neoBuilding.getHeaderVersion(); - if (headerVersion[0] === "v") - { - // parse the beta version. - blocksList.parseBlocksList(blocksList.dataArraybuffer, this.readerWriter, neoBuilding.motherBlocksArray, this); - } - else - { - // parse versioned. - blocksList.parseBlocksListVersioned(blocksList.dataArraybuffer, this.readerWriter, neoBuilding.motherBlocksArray, this); - } - blocksList.dataArraybuffer = undefined; - - octreesParsedCount++; - } + function canNotTraverseDeeper() { + return !object || typeof object === 'string'; + } - if (octreesParsedCount > maxParsesCount) - { break; } - } - - - if (octreesParsedCount === 0) - { - for (var key in this.parseQueue.octreesLod0ModelsToParseMap) - { - if (Object.prototype.hasOwnProperty.call(this.parseQueue.octreesLod0ModelsToParseMap, key)) - { - var lowestOctree = this.parseQueue.octreesLod0ModelsToParseMap[key]; - delete this.parseQueue.octreesLod0ModelsToParseMap[key]; - if (lowestOctree.neoReferencesMotherAndIndices === undefined) - { continue; } - - var blocksList = lowestOctree.neoReferencesMotherAndIndices.blocksList; - if (blocksList === undefined) - { continue; } - - if (blocksList.dataArraybuffer === undefined) - { continue; } - - if (blocksList.fileLoadState !== CODE.fileLoadState.LOADING_FINISHED) - { continue; } - - neoBuilding = lowestOctree.neoBuildingOwner; - headerVersion = neoBuilding.getHeaderVersion(); - if (headerVersion[0] === "v") - { - // parse the beta version. - blocksList.parseBlocksList(blocksList.dataArraybuffer, this.readerWriter, neoBuilding.motherBlocksArray, this); - } - else - { - // parse versioned. - blocksList.parseBlocksListVersioned(blocksList.dataArraybuffer, this.readerWriter, neoBuilding.motherBlocksArray, this); - } - blocksList.dataArraybuffer = undefined; - - octreesParsedCount++; - if (octreesParsedCount > maxParsesCount) - { break; } - } - } - } - - - if (octreesParsedCount > 0) - { - if (this.selectionFbo) - { this.selectionFbo.dirty = true; } - } - } + var stack = typeof path !== 'string' ? [].concat(path) : path.split('.'); - - // parse octrees lod2 (lego). - octreesParsedCount = 0; - maxParsesCount = 1; - if (Object.keys(this.parseQueue.octreesLod2LegosToParseMap).length > 0) - { - var octreesLod0Count = this.visibleObjControlerOctrees.currentVisibles2.length; - for (var i=0; i maxParsesCount) - { break; } - } - - if (octreesParsedCount === 0) - { - //var octreesArray = Array.from(this.parseQueue.octreesLod2LegosToParseMap.keys()); - //for (var i=0; i maxParsesCount) - { break; } - } - } - } - - if (octreesParsedCount > 0) - { - if (this.selectionFbo) - { this.selectionFbo.dirty = true; } - } - } - - // PCloud octree.**************************************************************************** - // PCloud octree.**************************************************************************** - octreesParsedCount = 0; - maxParsesCount = 1; - if (Object.keys(this.parseQueue.octreesPCloudToParseMap).length > 0) - { - var octreesLod0Count = this.visibleObjControlerOctrees.currentVisiblesAux.length; - for (var i=0; i maxParsesCount) - { break; } - } - - if (octreesParsedCount === 0) - { - for (var key in this.parseQueue.octreesPCloudToParseMap) - { - //if (Object.prototype.hasOwnProperty.call(this.parseQueue.octreesPCloudToParseMap, key)) - { - var lowestOctree = this.parseQueue.octreesPCloudToParseMap[key]; - if (this.parseQueue.eraseOctreePCloudToParse(lowestOctree)) - { - if (lowestOctree.lego === undefined) - { continue; } - - //lowestOctree.lego.parseArrayBuffer(gl, lowestOctree.lego.dataArrayBuffer, this); - lowestOctree.lego.parsePointsCloudData(lowestOctree.lego.dataArrayBuffer, gl, this); - lowestOctree.lego.dataArrayBuffer = undefined; - - octreesParsedCount++; - } - if (octreesParsedCount > maxParsesCount) - { break; } - } - } - } - - if (octreesParsedCount > 0) - { - if (this.selectionFbo) - { this.selectionFbo.dirty = true; } - } - } - - // skin-lego.******************************************************************************** - // skin-lego.******************************************************************************** - octreesParsedCount = 0; - maxParsesCount = 1; - if (Object.keys(this.parseQueue.skinLegosToParseMap).length > 0) - { - var node; - var skinLego; - var neoBuilding; - var lod3buildingsCount = this.visibleObjControlerNodes.currentVisibles3.length; - for (var i=0; i 1) { + if (canNotTraverseDeeper()) return {}; + var key = cleanKey(stack.shift()); + if (!object[key] && Empty) object[key] = new Empty(); + object = object[key]; + } - if (lodString === undefined) - { continue; } - - ///skinLego = neoBuilding.lodMeshesMap.get(lodString); - skinLego = neoBuilding.lodMeshesMap[lodString]; - - if (skinLego === undefined) - { continue; } - - if (this.parseQueue.skinLegosToParseMap.hasOwnProperty(skinLego.legoKey)) - { - - delete this.parseQueue.skinLegosToParseMap[skinLego.legoKey]; - skinLego.parseArrayBuffer(gl, skinLego.dataArrayBuffer, this); - skinLego.dataArrayBuffer = undefined; - - octreesParsedCount++; - } - if (octreesParsedCount > maxParsesCount) - { break; } - } - - if (octreesParsedCount === 0) - { - for (var key in this.parseQueue.skinLegosToParseMap) - { - if (Object.prototype.hasOwnProperty.call(this.parseQueue.skinLegosToParseMap, key)) - { - var node = this.parseQueue.skinLegosToParseMap[key]; - - if (node.data === undefined) - { continue; } - - neoBuilding = node.data.neoBuilding; - - if (neoBuilding === undefined) - { continue; } - - // check the current lod of the building.*** - var currentBuildingLod = neoBuilding.currentLod; - var lodIdx = currentBuildingLod - 3; - - if (lodIdx < 0) - { continue; } - - skinLego = neoBuilding.lodMeshesArray[lodIdx]; - if (skinLego === undefined) - { continue; } - if (this.parseQueue.skinLegosToParseMap.hasOwnProperty(skinLego.legoKey)) - { - delete this.parseQueue.skinLegosToParseMap[skinLego.legoKey]; - skinLego.parseArrayBuffer(gl, skinLego.dataArrayBuffer, this); - skinLego.dataArrayBuffer = undefined; - - octreesParsedCount++; - } - if (octreesParsedCount > maxParsesCount) - { break; } - } - } - } - - - } - - // TinTerrain.*********************************************************************************************** - // TinTerrain.*********************************************************************************************** - - var tinTerrain; - var terrName_geoCoords_map = this.tinTerrainManager.currentVisibles_terrName_geoCoords_map; - for (var key in terrName_geoCoords_map)// for all current visible tinTerrains: - { - tinTerrain = this.tinTerrainManager.currentTerrainsMap[key]; // check if exist the tinTerrain.*** - if (tinTerrain !== undefined) - { - if (this.parseQueue.eraseTinTerrainToParse(tinTerrain)) // check if is inside of the que to parse.*** - { - tinTerrain.parseData(tinTerrain.dataArrayBuffer); - } - } - } - -}; + if (canNotTraverseDeeper()) return {}; + return { + obj: object, + k: cleanKey(stack.shift()) + }; + } -/** - */ -MagoManager.prototype.prepareVisibleOctreesSortedByDistancePointsCloudType = function(gl, globalVisibleObjControlerOctrees, fileRequestExtraCount) -{ - var lod2DataInQueueCount = Object.keys(this.loadQueue.lod2PCloudDataMap).length; - if (lod2DataInQueueCount > 5) - { return; } - - var extraCount = fileRequestExtraCount; - - var currentVisibles = [].concat(globalVisibleObjControlerOctrees.currentVisibles0, globalVisibleObjControlerOctrees.currentVisibles1, - globalVisibleObjControlerOctrees.currentVisibles2, globalVisibleObjControlerOctrees.currentVisibles3); - //var currentVisibles = globalVisibleObjControlerOctrees.currentVisiblesAux; + function setPath(object, path, newValue) { + var _getLastOfPath = getLastOfPath(object, path, Object), + obj = _getLastOfPath.obj, + k = _getLastOfPath.k; - if (currentVisibles === undefined) - { return; } + obj[k] = newValue; + } + function pushPath(object, path, newValue, concat) { + var _getLastOfPath2 = getLastOfPath(object, path, Object), + obj = _getLastOfPath2.obj, + k = _getLastOfPath2.k; + + obj[k] = obj[k] || []; + if (concat) obj[k] = obj[k].concat(newValue); + if (!concat) obj[k].push(newValue); + } + function getPath(object, path) { + var _getLastOfPath3 = getLastOfPath(object, path), + obj = _getLastOfPath3.obj, + k = _getLastOfPath3.k; - var geometryDataPath = this.readerWriter.geometryDataPath; - var projectFolderName; - var neoBuilding; - var buildingFolderName; + if (!obj) return undefined; + return obj[k]; + } + function deepExtend(target, source, overwrite) { + /* eslint no-restricted-syntax: 0 */ + for (var prop in source) { + if (prop in target) { + // If we reached a leaf string in target or source then replace with source or skip depending on the 'overwrite' switch + if (typeof target[prop] === 'string' || target[prop] instanceof String || typeof source[prop] === 'string' || source[prop] instanceof String) { + if (overwrite) target[prop] = source[prop]; + } else { + deepExtend(target[prop], source[prop], overwrite); + } + } else { + target[prop] = source[prop]; + } + } - // LOD2 - // Check if the lod2lowestOctrees must load and parse data - var lowestOctree; - for (var i=0, length = currentVisibles.length; i': '>', + '"': '"', + "'": ''', + '/': '/' + }; + /* eslint-enable */ - projectFolderName = neoBuilding.projectFolderName; - buildingFolderName = neoBuilding.buildingFileName; + function escape(data) { + if (typeof data === 'string') { + return data.replace(/[&<>"'\/]/g, function (s) { + return _entityMap[s]; + }); + } - if (lowestOctree.lego.fileLoadState === CODE.fileLoadState.READY) - { - var subOctreeNumberName = lowestOctree.octree_number_name.toString(); - var references_folderPath = geometryDataPath + "/" + projectFolderName + "/" + buildingFolderName + "/References"; - var filePathInServer = references_folderPath + "/" + subOctreeNumberName + "_Ref"; - this.loadQueue.putLod2PCloudData(lowestOctree, filePathInServer, undefined, undefined, 0); - /* - // must load the legoStructure of the lowestOctree.*** - var subOctreeNumberName = lowestOctree.octree_number_name.toString(); - var bricks_folderPath = geometryDataPath + "/" + projectFolderName + "/" + buildingFolderName + "/Bricks"; - var filePathInServer = bricks_folderPath + "/" + subOctreeNumberName + "_Brick"; + return data; + } - // finally check if there are legoSimpleBuildingTexture.*** - // this is the new version.*** - if (neoBuilding.simpleBuilding3x3Texture === undefined) - { - neoBuilding.simpleBuilding3x3Texture = new Texture(); - - var imageFilaName = neoBuilding.getImageFileNameForLOD(2); - var texFilePath = geometryDataPath + "/" + projectFolderName + "/" + buildingFolderName + "/" + imageFilaName; + var ResourceStore = + /*#__PURE__*/ + function (_EventEmitter) { + _inherits(ResourceStore, _EventEmitter); - this.loadQueue.putLod2SkinData(lowestOctree, filePathInServer, neoBuilding.simpleBuilding3x3Texture, texFilePath, 0); - //return; - } - else - { - // check texture fileLoadState.*** - - if ( neoBuilding.simpleBuilding3x3Texture.fileLoadState === CODE.fileLoadState.READY) - { - var imageFilaName = neoBuilding.getImageFileNameForLOD(2); - var texFilePath = geometryDataPath + "/" + projectFolderName + "/" + buildingFolderName + "/" + imageFilaName; - this.loadQueue.putLod2SkinData(lowestOctree, filePathInServer, neoBuilding.simpleBuilding3x3Texture, texFilePath, 0); - } - else if (neoBuilding.simpleBuilding3x3Texture.fileLoadState === CODE.fileLoadState.LOADING_FINISHED) - - { this.loadQueue.putLod2SkinData(lowestOctree, filePathInServer, undefined, undefined, 0); } - } - */ - } - - if (Object.keys(this.loadQueue.lod2PCloudDataMap).length > 5) - { return; } - } -}; + function ResourceStore(data) { + var _this; -/** - * LOD0, LOD1 에 대한 F4D ModelData, ReferenceData 를 요청 - * - * @param {any} gl - * @param {any} scene - * @param {any} neoBuilding - */ -MagoManager.prototype.prepareVisibleOctreesSortedByDistance = function(gl, globalVisibleObjControlerOctrees, fileRequestExtraCount) -{ - if (this.fileRequestControler.isFullPlusModelReferences(fileRequestExtraCount)) - { return; } + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { + ns: ['translation'], + defaultNS: 'translation' + }; - var geometryDataPath = this.readerWriter.geometryDataPath; - var buildingFolderName; - var projectFolderName; - var neoBuilding; - var metaData; + _classCallCheck(this, ResourceStore); - // LOD0 & LOD1 - // Check if the lod0lowestOctrees, lod1lowestOctrees must load and parse data - var currentVisibleOctrees = [].concat(globalVisibleObjControlerOctrees.currentVisibles0, globalVisibleObjControlerOctrees.currentVisibles1); - var lowestOctree; - this.thereAreUrgentOctrees = false; + _this = _possibleConstructorReturn(this, _getPrototypeOf(ResourceStore).call(this)); + EventEmitter.call(_assertThisInitialized(_assertThisInitialized(_this))); // <=IE10 fix (unable to call parent constructor) - // now, prepare the ocree normally. - var maxFilesLoad = 2; - var filesLoadCounter = 0; - /* - for (var i=0, length = currentVisibleOctrees.length; i maxFilesLoad) - { return; } - } -}; + return _this; + } -/** - * LOD2 에 대한 F4D LegoData 를 요청 - * - * @param {any} gl - * @param {any} scene - * @param {any} neoBuilding - */ -MagoManager.prototype.prepareVisibleOctreesSortedByDistanceLOD2 = function(gl, currentVisibles, fileRequestExtraCount) -{ - var lod2DataInQueueCount = Object.keys(this.loadQueue.lod2SkinDataMap).length; - if (lod2DataInQueueCount > 5) - { return; } - - var extraCount = fileRequestExtraCount; + _createClass(ResourceStore, [{ + key: "addNamespaces", + value: function addNamespaces(ns) { + if (this.options.ns.indexOf(ns) < 0) { + this.options.ns.push(ns); + } + } + }, { + key: "removeNamespaces", + value: function removeNamespaces(ns) { + var index = this.options.ns.indexOf(ns); - if (currentVisibles === undefined) - { return; } + if (index > -1) { + this.options.ns.splice(index, 1); + } + } + }, { + key: "getResource", + value: function getResource(lng, ns, key) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + var keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator; + var path = [lng, ns]; + if (key && typeof key !== 'string') path = path.concat(key); + if (key && typeof key === 'string') path = path.concat(keySeparator ? key.split(keySeparator) : key); + + if (lng.indexOf('.') > -1) { + path = lng.split('.'); + } - var geometryDataPath = this.readerWriter.geometryDataPath; - var projectFolderName; - var neoBuilding; - var buildingFolderName; + return getPath(this.data, path); + } + }, { + key: "addResource", + value: function addResource(lng, ns, key, value) { + var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : { + silent: false + }; + var keySeparator = this.options.keySeparator; + if (keySeparator === undefined) keySeparator = '.'; + var path = [lng, ns]; + if (key) path = path.concat(keySeparator ? key.split(keySeparator) : key); + + if (lng.indexOf('.') > -1) { + path = lng.split('.'); + value = ns; + ns = path[1]; + } - // LOD2 - // Check if the lod2lowestOctrees must load and parse data - var lowestOctree; - //var counter = 0; - for (var i=0, length = currentVisibles.length; i 3 && arguments[3] !== undefined ? arguments[3] : { + silent: false + }; - projectFolderName = neoBuilding.projectFolderName; - buildingFolderName = neoBuilding.buildingFileName; - - var headerVersion = neoBuilding.getHeaderVersion(); + /* eslint no-restricted-syntax: 0 */ + for (var m in resources) { + if (typeof resources[m] === 'string' || Object.prototype.toString.apply(resources[m]) === '[object Array]') this.addResource(lng, ns, m, resources[m], { + silent: true + }); + } - if (lowestOctree.lego.fileLoadState === CODE.fileLoadState.READY) - { - // must load the legoStructure of the lowestOctree.*** - var subOctreeNumberName = lowestOctree.octree_number_name.toString(); - var bricks_folderPath = geometryDataPath + "/" + projectFolderName + "/" + buildingFolderName + "/Bricks"; - var filePathInServer = bricks_folderPath + "/" + subOctreeNumberName + "_Brick"; + if (!options.silent) this.emit('added', lng, ns, resources); + } + }, { + key: "addResourceBundle", + value: function addResourceBundle(lng, ns, resources, deep, overwrite) { + var options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : { + silent: false + }; + var path = [lng, ns]; - // finally check if there are legoSimpleBuildingTexture.*** - if (headerVersion[0] === "v") - { - if (lowestOctree.lego.vbo_vicks_container.vboCacheKeysArray[0] && lowestOctree.lego.vbo_vicks_container.vboCacheKeysArray[0].meshTexcoordsCacheKey) - { - // this is the old version.*** - if (neoBuilding.simpleBuilding3x3Texture === undefined) - { - neoBuilding.simpleBuilding3x3Texture = new Texture(); - var buildingFolderName = neoBuilding.buildingFileName; - var texFilePath = geometryDataPath + "/" + projectFolderName + "/" + buildingFolderName + "/SimpleBuildingTexture3x3.png"; - this.loadQueue.putLod2SkinData(lowestOctree, filePathInServer, neoBuilding.simpleBuilding3x3Texture, texFilePath, 0); - } - } - else - { - // there are no texture in this project.*** - this.loadQueue.putLod2SkinData(lowestOctree, filePathInServer, undefined, undefined, 0); - } - } - else - { - // this is the new version.*** - if (neoBuilding.simpleBuilding3x3Texture === undefined) - { - neoBuilding.simpleBuilding3x3Texture = new Texture(); - - var imageFilaName = neoBuilding.getImageFileNameForLOD(2); - var texFilePath = geometryDataPath + "/" + projectFolderName + "/" + buildingFolderName + "/" + imageFilaName; + if (lng.indexOf('.') > -1) { + path = lng.split('.'); + deep = resources; + resources = ns; + ns = path[1]; + } - this.loadQueue.putLod2SkinData(lowestOctree, filePathInServer, neoBuilding.simpleBuilding3x3Texture, texFilePath, 0); - //return; - } - else - { - // check texture fileLoadState.*** - - if ( neoBuilding.simpleBuilding3x3Texture.fileLoadState === CODE.fileLoadState.READY) - { - var imageFilaName = neoBuilding.getImageFileNameForLOD(2); - var texFilePath = geometryDataPath + "/" + projectFolderName + "/" + buildingFolderName + "/" + imageFilaName; - this.loadQueue.putLod2SkinData(lowestOctree, filePathInServer, neoBuilding.simpleBuilding3x3Texture, texFilePath, 0); - } - else if (neoBuilding.simpleBuilding3x3Texture.fileLoadState === CODE.fileLoadState.LOADING_FINISHED) - - { this.loadQueue.putLod2SkinData(lowestOctree, filePathInServer, undefined, undefined, 0); } - } - } - } - - if (Object.keys(this.loadQueue.lod2SkinDataMap).length > 5) - { return; } - } -}; + this.addNamespaces(ns); + var pack = getPath(this.data, path) || {}; -/** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param cameraPosition 카메라 입장에서 화면에 그리기 전에 객체를 그릴 필요가 있는지 유무를 판단하는 값 - * @param scene 변수 - * @param shader 변수 - * @param renderTexture 변수 - * @param ssao_idx 변수 - * @param neoRefLists_array 변수 - */ + if (deep) { + deepExtend(pack, resources, overwrite); + } else { + pack = _objectSpread({}, pack, resources); + } -MagoManager.prototype.checkChangesHistoryMovements = function(nodesArray) -{ - var nodesCount = nodesArray.length; - var node; - var rootNode; - var projectId; - var dataKey; - var moveHistoryMap; - var colorChangedHistoryMap; - var objectIndexOrder; - var neoBuilding; - var refObject; - var moveVector; - var moveVectorRelToBuilding; - var geoLocdataManager; - var geoLoc; - - // check movement of objects. - for (var i=0; i 1 && arguments[1] !== undefined ? arguments[1] : {}; - gl.uniform1f(currentShader.fov_loc, this.sceneState.camera.frustum.fovyRad); // "frustum._fov" is in radians.*** - gl.uniform1f(currentShader.aspectRatio_loc, this.sceneState.camera.frustum.aspectRatio); - gl.uniform1f(currentShader.screenWidth_loc, this.sceneState.drawingBufferWidth); - gl.uniform1f(currentShader.screenHeight_loc, this.sceneState.drawingBufferHeight); - gl.uniform1f(currentShader.shininessValue_loc, 40.0); + _classCallCheck(this, Translator); - gl.uniform1i(currentShader.depthTex_loc, 0); - gl.uniform1i(currentShader.noiseTex_loc, 1); - //gl.uniform1i(currentShader.diffuseTex_loc, 2); // no used.*** + _this = _possibleConstructorReturn(this, _getPrototypeOf(Translator).call(this)); + EventEmitter.call(_assertThisInitialized(_assertThisInitialized(_this))); // <=IE10 fix (unable to call parent constructor) - gl.uniform2fv(currentShader.noiseScale2_loc, [this.depthFboNeo.width/this.noiseTexture.width, this.depthFboNeo.height/this.noiseTexture.height]); - gl.uniform3fv(currentShader.kernel16_loc, this.sceneState.ssaoSphereKernel32); - - gl.uniform1i(currentShader.textureFlipYAxis_loc, this.sceneState.textureFlipYAxis); - - // lighting. - //this.magoPolicy.setSpecularColor(api.getSpecularColor()); - gl.uniform3fv(currentShader.specularColor_loc, [0.7, 0.7, 0.7]); - gl.uniform1f(currentShader.ssaoRadius_loc, 1.5); - gl.uniform1i(currentShader.hasTexture_loc, false); - gl.uniform4fv(currentShader.color4Aux_loc, [0.5, 0.5, 0.5, 1.0]); + copy(['resourceStore', 'languageUtils', 'pluralResolver', 'interpolator', 'backendConnector', 'i18nFormat'], services, _assertThisInitialized(_assertThisInitialized(_this))); + _this.options = options; - gl.uniform1f(currentShader.ambientReflectionCoef_loc, this.magoPolicy.getAmbientReflectionCoef()); - gl.uniform1f(currentShader.diffuseReflectionCoef_loc, this.magoPolicy.getDiffuseReflectionCoef()); - gl.uniform1f(currentShader.specularReflectionCoef_loc, this.magoPolicy.getSpecularReflectionCoef()); - - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, this.depthFboNeo.colorBuffer); // original.*** - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, this.noiseTexture); - - // 1) LOD0 & LOD1.********************************************************************************************************************* - - var refTMatrixIdxKey = 0; - var minSize = 0.0; - var renderTexture; - var ssao_idx = 1; - var bRenderLines = false; - var primitiveType = undefined; - - gl.enable(gl.BLEND); - gl.uniform1i(currentShader.bUseNormal_loc, true); - - if (this.isLastFrustum) - { - //this.renderer.renderObject(gl, this.invertedBox, this, currentShader, ssao_idx, bRenderLines, primitiveType); - //var vbo_vicky = this.invertedBox.vbo_vicks_container.vboCacheKeysArray[0]; - var vbo_vicky = this.fakeScreenPlane.vbo_vicks_container.vboCacheKeysArray[0]; - if (!vbo_vicky.isReadyPositions(gl, this.vboMemoryManager)) - { return; } - gl.bindBuffer(gl.ARRAY_BUFFER, vbo_vicky.meshVertexCacheKey); - gl.vertexAttribPointer(currentShader.position3_loc, 3, gl.FLOAT, false, 0, 0); - - //if (!vbo_vicky.isReadyNormals(gl, this.vboMemoryManager)) - // return; - //gl.bindBuffer(gl.ARRAY_BUFFER, vbo_vicky.meshNormalCacheKey); - //gl.vertexAttribPointer(currentShader.normal3_loc, 3, gl.BYTE, true, 0, 0); - - //if (!vbo_vicky.isReadyFaces(gl, this.vboMemoryManager)) - //{ return; } - //gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vbo_vicky.meshFacesCacheKey); - //gl.drawElements(gl.TRIANGLES, vbo_vicky.indicesCount, gl.UNSIGNED_SHORT, 0); // Fill.*** - gl.drawArrays(gl.TRIANGLES, 0, this.fakeScreenPlane.vbo_vicks_container.vboCacheKeysArray[0].vertexCount); - } - - gl.disable(gl.BLEND); - - if (currentShader) - { - if (currentShader.texCoord2_loc !== -1){ gl.disableVertexAttribArray(currentShader.texCoord2_loc); } - if (currentShader.position3_loc !== -1){ gl.disableVertexAttribArray(currentShader.position3_loc); } - if (currentShader.normal3_loc !== -1){ gl.disableVertexAttribArray(currentShader.normal3_loc); } - if (currentShader.color4_loc !== -1){ gl.disableVertexAttribArray(currentShader.color4_loc); } - } - - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, null); // original.*** - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, null); - gl.activeTexture(gl.TEXTURE2); - gl.bindTexture(gl.TEXTURE_2D, null); - - gl.depthFunc(gl.LEQUAL); -}; + if (_this.options.keySeparator === undefined) { + _this.options.keySeparator = '.'; + } -/** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param cameraPosition 카메라 입장에서 화면에 그리기 전에 객체를 그릴 필요가 있는지 유무를 판단하는 값 - * @param scene 변수 - * @param shader 변수 - * @param renderTexture 변수 - * @param ssao_idx 변수 - * @param neoRefLists_array 변수 - */ + _this.logger = baseLogger.create('translator'); + return _this; + } -MagoManager.prototype.renderDirectionalLight = function(gl, cameraPosition, shader, renderTexture, ssao_idx, visibleObjControlerNodes) -{ - //this.myCameraSCX; - -}; + _createClass(Translator, [{ + key: "changeLanguage", + value: function changeLanguage(lng) { + if (lng) this.language = lng; + } + }, { + key: "exists", + value: function exists(key) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { + interpolation: {} + }; + var resolved = this.resolve(key, options); + return resolved && resolved.res !== undefined; + } + }, { + key: "extractFromKey", + value: function extractFromKey(key, options) { + var nsSeparator = options.nsSeparator || this.options.nsSeparator; + if (nsSeparator === undefined) nsSeparator = ':'; + var keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator; + var namespaces = options.ns || this.options.defaultNS; + + if (nsSeparator && key.indexOf(nsSeparator) > -1) { + var parts = key.split(nsSeparator); + if (nsSeparator !== keySeparator || nsSeparator === keySeparator && this.options.ns.indexOf(parts[0]) > -1) namespaces = parts.shift(); + key = parts.join(keySeparator); + } -/** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param cameraPosition 카메라 입장에서 화면에 그리기 전에 객체를 그릴 필요가 있는지 유무를 판단하는 값 - * @param scene 변수 - * @param shader 변수 - * @param renderTexture 변수 - * @param ssao_idx 변수 - * @param neoRefLists_array 변수 - */ + if (typeof namespaces === 'string') namespaces = [namespaces]; + return { + key: key, + namespaces: namespaces + }; + } + }, { + key: "translate", + value: function translate(keys, options) { + var _this2 = this; + + if (_typeof(options) !== 'object' && this.options.overloadTranslationOptionHandler) { + /* eslint prefer-rest-params: 0 */ + options = this.options.overloadTranslationOptionHandler(arguments); + } -MagoManager.prototype.renderGeometry = function(gl, cameraPosition, shader, renderTexture, ssao_idx, visibleObjControlerNodes) -{ - // ssao_idx = -1 -> pickingMode.*** - // ssao_idx = 0 -> depth.*** - // ssao_idx = 1 -> ssao.*** - gl.frontFace(gl.CCW); - var near = 0.20; - var far = 0.25; + if (!options) options = {}; // non valid keys handling - //gl.depthRange(near, far); - gl.enable(gl.DEPTH_TEST); - gl.depthFunc(gl.LEQUAL); - - var currentShader; - var shaderProgram; - var neoBuilding; - var node; - var rootNode; - var geoLocDataManager; + if (keys === undefined || keys === null) return ''; + if (!Array.isArray(keys)) keys = [String(keys)]; // separators - renderTexture = false; - //var lowestOctreeLegosParsingCount = 0; - - + var keySeparator = options.keySeparator !== undefined ? options.keySeparator : this.options.keySeparator; // get namespace(s) - if (ssao_idx === 0) - { - gl.disable(gl.BLEND); - this.depthRenderLowestOctreeAsimetricVersion(gl, ssao_idx, visibleObjControlerNodes); - // draw the axis.*** - if (this.magoPolicy.getShowOrigin() && this.nodeSelected !== undefined) - { - node = this.nodeSelected; - var nodes = [node]; - - this.renderAxisNodes(gl, nodes, true, ssao_idx); - } - } - if (ssao_idx === 1) - { - // ssao render.************************************************************************************************************ - var nodesLOD0Count = visibleObjControlerNodes.currentVisibles0.length; + var _this$extractFromKey = this.extractFromKey(keys[keys.length - 1], options), + key = _this$extractFromKey.key, + namespaces = _this$extractFromKey.namespaces; - if (nodesLOD0Count > 0) - { - // check changesHistory. - this.checkChangesHistoryMovements(visibleObjControlerNodes.currentVisibles0); - this.checkChangesHistoryColors(visibleObjControlerNodes.currentVisibles0); - - if (this.noiseTexture === undefined) - { this.noiseTexture = genNoiseTextureRGBA(gl, 4, 4, this.pixels); } - - currentShader = this.postFxShadersManager.getShader("modelRefSsao"); - shaderProgram = currentShader.program; - - gl.useProgram(shaderProgram); - gl.uniform1i(currentShader.bApplySpecularLighting_loc, true); - gl.enableVertexAttribArray(currentShader.texCoord2_loc); - gl.enableVertexAttribArray(currentShader.position3_loc); - gl.enableVertexAttribArray(currentShader.normal3_loc); - - currentShader.bindUniformGenerals(); - gl.uniform1i(currentShader.textureFlipYAxis_loc, this.sceneState.textureFlipYAxis); + var namespace = namespaces[namespaces.length - 1]; // return key on CIMode - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, this.depthFboNeo.colorBuffer); // original.*** - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, this.noiseTexture); - - // 1) LOD0 & LOD1.********************************************************************************************************************* - var refTMatrixIdxKey = 0; - var minSize = 0.0; - var renderTexture; - //if (this.isLastFrustum) - { - this.renderer.renderNodes(gl, visibleObjControlerNodes.currentVisibles0, this, currentShader, renderTexture, ssao_idx, minSize, refTMatrixIdxKey); - } - - if (currentShader) - { - if (currentShader.texCoord2_loc !== -1){ gl.disableVertexAttribArray(currentShader.texCoord2_loc); } - if (currentShader.position3_loc !== -1){ gl.disableVertexAttribArray(currentShader.position3_loc); } - if (currentShader.normal3_loc !== -1){ gl.disableVertexAttribArray(currentShader.normal3_loc); } - if (currentShader.color4_loc !== -1){ gl.disableVertexAttribArray(currentShader.color4_loc); } - } - - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, null); // original.*** - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, null); - gl.activeTexture(gl.TEXTURE2); - gl.bindTexture(gl.TEXTURE_2D, null); - } - - // 2) LOD 2, 3, 4, 5.************************************************************************************************************************************ - var nodesLOD2Count = visibleObjControlerNodes.currentVisibles2.length; - var nodesLOD3Count = visibleObjControlerNodes.currentVisibles3.length; - if (nodesLOD2Count > 0 || nodesLOD0Count > 0 || nodesLOD3Count>0) - { - this.checkChangesHistoryColors(visibleObjControlerNodes.currentVisibles2); + var lng = options.lng || this.language; + var appendNamespaceToCIMode = options.appendNamespaceToCIMode || this.options.appendNamespaceToCIMode; - // lodBuildingSsaoSimpleCompressed - currentShader = this.postFxShadersManager.getShader("lodBuildingSsao"); + if (lng && lng.toLowerCase() === 'cimode') { + if (appendNamespaceToCIMode) { + var nsSeparator = options.nsSeparator || this.options.nsSeparator; + return namespace + nsSeparator + key; + } - shaderProgram = currentShader.program; - - gl.useProgram(shaderProgram); - gl.uniform1i(currentShader.bApplySpecularLighting_loc, true); - gl.enableVertexAttribArray(currentShader.position3_loc); - gl.enableVertexAttribArray(currentShader.normal3_loc); - gl.enableVertexAttribArray(currentShader.color4_loc); - - currentShader.bindUniformGenerals(); - gl.uniform1i(currentShader.textureFlipYAxis_loc, this.sceneState.textureFlipYAxis); + return key; + } // resolve from store - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, this.depthFboNeo.colorBuffer); // original.*** - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, this.noiseTexture); - gl.activeTexture(gl.TEXTURE2); - gl.bindTexture(gl.TEXTURE_2D, this.textureAux_1x1); - - this.renderer.renderNeoBuildingsLOD2AsimetricVersion(gl, visibleObjControlerNodes.currentVisibles0, this, currentShader, renderTexture, ssao_idx); // lod 0.*** - this.renderer.renderNeoBuildingsLOD2AsimetricVersion(gl, visibleObjControlerNodes.currentVisibles2, this, currentShader, renderTexture, ssao_idx); // lod 2.*** - this.renderer.renderNeoBuildingsLowLOD(gl, visibleObjControlerNodes.currentVisibles3, this, currentShader, renderTexture, ssao_idx); // lod 3, 4, 5.*** - - if (currentShader) - { - if (currentShader.texCoord2_loc !== -1){ gl.disableVertexAttribArray(currentShader.texCoord2_loc); } - if (currentShader.position3_loc !== -1){ gl.disableVertexAttribArray(currentShader.position3_loc); } - if (currentShader.normal3_loc !== -1){ gl.disableVertexAttribArray(currentShader.normal3_loc); } - if (currentShader.color4_loc !== -1){ gl.disableVertexAttribArray(currentShader.color4_loc); } - } - - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, null); // original.*** - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, null); - gl.activeTexture(gl.TEXTURE2); - gl.bindTexture(gl.TEXTURE_2D, null); - } - // If there are an object selected, then there are a stencilBuffer.****************************************** - if (this.nodeSelected) // if there are an object selected then there are a building selected.*** - { - if (this.magoPolicy.getObjectMoveMode() === CODE.moveMode.OBJECT && this.objectSelected) - { - node = this.nodeSelected; - var geoLocDataManager = this.getNodeGeoLocDataManager(node); - neoBuilding = this.buildingSelected; - var buildingGeoLocation = geoLocDataManager.getCurrentGeoLocationData(); - var neoReferencesMotherAndIndices = this.octreeSelected.neoReferencesMotherAndIndices; - var glPrimitive = gl.POINTS; - glPrimitive = gl.TRIANGLES; - var maxSizeToRender = 0.0; - var refMatrixIdxKey = 0; - - // do as the "getSelectedObjectPicking".********************************************************** - currentShader = this.postFxShadersManager.getModelRefSilhouetteShader(); // silhouette shader.*** - var shaderProgram = currentShader.program; - gl.useProgram(shaderProgram); - - gl.enableVertexAttribArray(currentShader.position3_loc); - - gl.uniformMatrix4fv(currentShader.buildingRotMatrix_loc, false, buildingGeoLocation.rotMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.modelViewProjectionMatrix4RelToEye_loc, false, this.sceneState.modelViewProjRelToEyeMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.ModelViewMatrixRelToEye_loc, false, this.sceneState.modelViewRelToEyeMatrix._floatArrays); - gl.uniform3fv(currentShader.cameraPosHIGH_loc, this.sceneState.encodedCamPosHigh); - gl.uniform3fv(currentShader.cameraPosLOW_loc, this.sceneState.encodedCamPosLow); - - // do the colorCoding render.*** - // position uniforms.*** - gl.uniform3fv(currentShader.buildingPosHIGH_loc, buildingGeoLocation.positionHIGH); - gl.uniform3fv(currentShader.buildingPosLOW_loc, buildingGeoLocation.positionLOW); - - gl.uniform4fv(currentShader.color4Aux_loc, [0.0, 1.0, 0.0, 1.0]); - gl.uniform2fv(currentShader.screenSize_loc, [this.sceneState.drawingBufferWidth, this.sceneState.drawingBufferHeight]); - gl.uniformMatrix4fv(currentShader.ProjectionMatrix_loc, false, this.sceneState.projectionMatrix._floatArrays); - - gl.enable(gl.STENCIL_TEST); - gl.disable(gl.POLYGON_OFFSET_FILL); - gl.disable(gl.CULL_FACE); - gl.disable(gl.DEPTH_TEST); - gl.depthRange(0, 0); - - gl.stencilFunc(gl.EQUAL, 0, 1); - gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE); - - //glPrimitive = gl.POINTS; - glPrimitive = gl.TRIANGLES; - //gl.polygonMode( gl.FRONT_AND_BACK, gl.LINE ); - - var offsetSize = 3/1000; - gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [offsetSize, offsetSize]); - this.renderer.renderNeoReferenceAsimetricVersionColorSelection(gl, this.objectSelected, neoReferencesMotherAndIndices, neoBuilding, this, currentShader, maxSizeToRender, refMatrixIdxKey, glPrimitive); - gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [-offsetSize, offsetSize]); - this.renderer.renderNeoReferenceAsimetricVersionColorSelection(gl, this.objectSelected, neoReferencesMotherAndIndices, neoBuilding, this, currentShader, maxSizeToRender, refMatrixIdxKey, glPrimitive); - gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [offsetSize, -offsetSize]); - this.renderer.renderNeoReferenceAsimetricVersionColorSelection(gl, this.objectSelected, neoReferencesMotherAndIndices, neoBuilding, this, currentShader, maxSizeToRender, refMatrixIdxKey, glPrimitive); - gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [-offsetSize, -offsetSize]); - this.renderer.renderNeoReferenceAsimetricVersionColorSelection(gl, this.objectSelected, neoReferencesMotherAndIndices, neoBuilding, this, currentShader, maxSizeToRender, refMatrixIdxKey, glPrimitive); - gl.enable(gl.DEPTH_TEST);// return to the normal state.*** - gl.disable(gl.STENCIL_TEST); - gl.depthRange(0, 1);// return to the normal value.*** - gl.disableVertexAttribArray(currentShader.position3_loc); - - if (currentShader) - { - if (currentShader.texCoord2_loc !== -1){ gl.disableVertexAttribArray(currentShader.texCoord2_loc); } - if (currentShader.position3_loc !== -1){ gl.disableVertexAttribArray(currentShader.position3_loc); } - if (currentShader.normal3_loc !== -1){ gl.disableVertexAttribArray(currentShader.normal3_loc); } - if (currentShader.color4_loc !== -1){ gl.disableVertexAttribArray(currentShader.color4_loc); } - } - } - - // render bbox for neoBuildingSelected. // old.*** - /* - var selectedNodesArray = []; - selectedNodesArray.push(this.nodeSelected); - if (this.colorSC === undefined) - { this.colorSC = new Color(); } - this.colorSC.setRGB(0.8, 1.0, 1.0); - this.renderBoundingBoxesNodes(gl, selectedNodesArray, this.colorSC); // old. - */ - - // new. Render the silhouette by lod3 or lod4 or lod5 mesh*** - if (this.magoPolicy.getObjectMoveMode() === CODE.moveMode.ALL && this.buildingSelected) - { - node = this.nodeSelected; - var geoLocDataManager = this.getNodeGeoLocDataManager(node); - neoBuilding = this.buildingSelected; - var buildingGeoLocation = geoLocDataManager.getCurrentGeoLocationData(); - //var neoReferencesMotherAndIndices = this.octreeSelected.neoReferencesMotherAndIndices; - var glPrimitive = gl.POINTS; - glPrimitive = gl.TRIANGLES; - var maxSizeToRender = 0.0; - var refMatrixIdxKey = 0; - var skinLego = neoBuilding.getCurrentSkin(); - if (skinLego !== undefined) - { - // do as the "getSelectedObjectPicking".********************************************************** - currentShader = this.postFxShadersManager.getModelRefSilhouetteShader(); // silhouette shader.*** - var shaderProgram = currentShader.program; - gl.useProgram(shaderProgram); - - gl.enableVertexAttribArray(currentShader.position3_loc); - - gl.uniformMatrix4fv(currentShader.buildingRotMatrix_loc, false, buildingGeoLocation.rotMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.modelViewProjectionMatrix4RelToEye_loc, false, this.sceneState.modelViewProjRelToEyeMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.ModelViewMatrixRelToEye_loc, false, this.sceneState.modelViewRelToEyeMatrix._floatArrays); - gl.uniform3fv(currentShader.cameraPosHIGH_loc, this.sceneState.encodedCamPosHigh); - gl.uniform3fv(currentShader.cameraPosLOW_loc, this.sceneState.encodedCamPosLow); - - // do the colorCoding render.*** - // position uniforms.*** - gl.uniform3fv(currentShader.buildingPosHIGH_loc, buildingGeoLocation.positionHIGH); - gl.uniform3fv(currentShader.buildingPosLOW_loc, buildingGeoLocation.positionLOW); - - gl.uniform4fv(currentShader.color4Aux_loc, [0.0, 1.0, 0.0, 1.0]); - gl.uniform2fv(currentShader.screenSize_loc, [this.sceneState.drawingBufferWidth, this.sceneState.drawingBufferHeight]); - gl.uniformMatrix4fv(currentShader.ProjectionMatrix_loc, false, this.sceneState.projectionMatrix._floatArrays); - - gl.uniform3fv(currentShader.aditionalMov_loc, [0.0, 0.0, 0.0]); //.*** - - gl.enable(gl.STENCIL_TEST); - gl.disable(gl.POLYGON_OFFSET_FILL); - gl.disable(gl.CULL_FACE); - gl.disable(gl.DEPTH_TEST); - gl.depthRange(0, 0); - - gl.stencilFunc(gl.EQUAL, 0, 1); - //gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE); - gl.stencilOp(gl.KEEP, gl.REPLACE, gl.REPLACE); - - //glPrimitive = gl.POINTS; - glPrimitive = gl.TRIANGLES; - gl.uniform1i(currentShader.refMatrixType_loc, 0); // 0 = identity matrix.*** - //gl.polygonMode( gl.FRONT_AND_BACK, gl.LINE ); + var resolved = this.resolve(keys, options); + var res = resolved && resolved.res; + var resUsedKey = resolved && resolved.usedKey || key; + var resExactUsedKey = resolved && resolved.exactUsedKey || key; + var resType = Object.prototype.toString.apply(res); + var noObject = ['[object Number]', '[object Function]', '[object RegExp]']; + var joinArrays = options.joinArrays !== undefined ? options.joinArrays : this.options.joinArrays; // object - - var offsetSize = 4/1000; - gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [offsetSize, offsetSize]); - this.renderer.renderLodBuildingColorSelection(gl, skinLego, this, currentShader); - gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [-offsetSize, offsetSize]); - this.renderer.renderLodBuildingColorSelection(gl, skinLego, this, currentShader); - gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [offsetSize, -offsetSize]); - this.renderer.renderLodBuildingColorSelection(gl, skinLego, this, currentShader); - gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [-offsetSize, -offsetSize]); - this.renderer.renderLodBuildingColorSelection(gl, skinLego, this, currentShader); - gl.enable(gl.DEPTH_TEST);// return to the normal state.*** - gl.disable(gl.STENCIL_TEST); - gl.depthRange(0, 1);// return to the normal value.*** - gl.disableVertexAttribArray(currentShader.position3_loc); - - if (currentShader) - { - if (currentShader.texCoord2_loc !== -1){ gl.disableVertexAttribArray(currentShader.texCoord2_loc); } - if (currentShader.position3_loc !== -1){ gl.disableVertexAttribArray(currentShader.position3_loc); } - if (currentShader.normal3_loc !== -1){ gl.disableVertexAttribArray(currentShader.normal3_loc); } - if (currentShader.color4_loc !== -1){ gl.disableVertexAttribArray(currentShader.color4_loc); } - } - } - - } - - // draw the axis.*** - if (this.magoPolicy.getShowOrigin()) - { - node = this.nodeSelected; - //var geoLocDataManager = this.getNodeGeoLocDataManager(node); - var nodes = [node]; - - this.renderAxisNodes(gl, nodes, true, ssao_idx); - } - } - - // 3) now render bboxes.******************************************************************************************************************* - if (this.magoPolicy.getShowBoundingBox()) - { - var bRenderLines = true; - this.renderBoundingBoxesNodes(gl, this.visibleObjControlerNodes.currentVisibles0, undefined, bRenderLines); - this.renderBoundingBoxesNodes(gl, this.visibleObjControlerNodes.currentVisibles2, undefined, bRenderLines); - this.renderBoundingBoxesNodes(gl, this.visibleObjControlerNodes.currentVisibles3, undefined, bRenderLines); - } - - // 4) Render ObjectMarkers.******************************************************************************************************** - // 4) Render ObjectMarkers.******************************************************************************************************** - // 4) Render ObjectMarkers.******************************************************************************************************** - var objectsMarkersCount = this.objMarkerManager.objectMarkerArray.length; - if (objectsMarkersCount > 0) - { - // now repeat the objects markers for png images.*** - // Png for pin image 128x128.******************************************************************** - if (this.pin.positionBuffer === undefined) - { this.pin.createPinCenterBottom(gl); } - - currentShader = this.postFxShadersManager.pFx_shaders_array[13]; // png image shader.*** - - shaderProgram = currentShader.program; - - gl.useProgram(shaderProgram); - gl.uniformMatrix4fv(currentShader.modelViewProjectionMatrix4RelToEye_loc, false, this.sceneState.modelViewProjRelToEyeMatrix._floatArrays); - gl.uniform3fv(currentShader.cameraPosHIGH_loc, this.sceneState.encodedCamPosHigh); - gl.uniform3fv(currentShader.cameraPosLOW_loc, this.sceneState.encodedCamPosLow); - gl.uniformMatrix4fv(currentShader.buildingRotMatrix_loc, false, this.sceneState.modelViewRelToEyeMatrixInv._floatArrays); - - gl.uniform1i(currentShader.textureFlipYAxis_loc, this.sceneState.textureFlipYAxis); - // Tell the shader to get the texture from texture unit 0 - gl.uniform1i(currentShader.texture_loc, 0); - gl.enableVertexAttribArray(currentShader.texCoord2_loc); - gl.enableVertexAttribArray(currentShader.position3_loc); - gl.activeTexture(gl.TEXTURE0); - - gl.depthRange(0, 0); - //var context = document.getElementById('canvas2').getContext("2d"); - //var canvas = document.getElementById("magoContainer"); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.pin.positionBuffer); - gl.vertexAttribPointer(currentShader.position3_loc, 3, gl.FLOAT, false, 0, 0); - gl.bindBuffer(gl.ARRAY_BUFFER, this.pin.texcoordBuffer); - gl.vertexAttribPointer(currentShader.texCoord2_loc, 2, gl.FLOAT, false, 0, 0); - var j=0; - for (var i=0; i= this.pin.texturesArray.length) - { j=0; } - - var currentTexture = this.pin.texturesArray[j]; - var objMarker = this.objMarkerManager.objectMarkerArray[i]; - var objMarkerGeoLocation = objMarker.geoLocationData; - gl.bindTexture(gl.TEXTURE_2D, currentTexture.texId); - gl.uniform3fv(currentShader.buildingPosHIGH_loc, objMarkerGeoLocation.positionHIGH); - gl.uniform3fv(currentShader.buildingPosLOW_loc, objMarkerGeoLocation.positionLOW); + var handleAsObjectInI18nFormat = !this.i18nFormat || this.i18nFormat.handleAsObject; + var handleAsObject = typeof res !== 'string' && typeof res !== 'boolean' && typeof res !== 'number'; - gl.drawArrays(gl.TRIANGLES, 0, 6); - - j++; - } - gl.depthRange(0, 1); - gl.useProgram(null); - gl.bindTexture(gl.TEXTURE_2D, null); - gl.disableVertexAttribArray(currentShader.texCoord2_loc); - gl.disableVertexAttribArray(currentShader.position3_loc); - - } - - // Test TinTerrain.************************************************************************** - // Test TinTerrain.************************************************************************** - // render tiles, rendertiles.*** - - if (this.tinTerrainManager !== undefined) - { - currentShader = this.postFxShadersManager.getShader("tinTerrain"); - shaderProgram = currentShader.program; - - gl.useProgram(shaderProgram); - gl.enableVertexAttribArray(currentShader.position3_loc); - gl.enableVertexAttribArray(currentShader.texCoord2_loc); - //gl.disableVertexAttribArray(currentShader.normal3_loc); - //gl.disableVertexAttribArray(currentShader.color4_loc); - - currentShader.bindUniformGenerals(); + if (handleAsObjectInI18nFormat && res && handleAsObject && noObject.indexOf(resType) < 0 && !(typeof joinArrays === 'string' && resType === '[object Array]')) { + if (!options.returnObjects && !this.options.returnObjects) { + this.logger.warn('accessing an object - but returnObjects options is not enabled!'); + return this.options.returnedObjectHandler ? this.options.returnedObjectHandler(resUsedKey, res, options) : "key '".concat(key, " (").concat(this.language, ")' returned an object instead of string."); + } // if we got a separator we loop over children - else we just return object as is + // as having it set to false means no hierarchy so no lookup for nested values - var tex = this.pin.texturesArray[4]; - gl.activeTexture(gl.TEXTURE2); - gl.bindTexture(gl.TEXTURE_2D, tex.texId); - - gl.uniform1i(currentShader.bIsMakingDepth_loc, false); //.*** - gl.uniform1i(currentShader.hasTexture_loc, true); //.*** - gl.uniform4fv(currentShader.oneColor4_loc, [0.5, 0.5, 0.5, 1.0]); - - //gl.enable(gl.POLYGON_OFFSET_FILL); - //gl.polygonOffset(1, 3); - - var renderWireframe = false; - var tinTerrain; - var currentTerrainsMap = this.tinTerrainManager.currentTerrainsMap; - var currentVisiblesTerrainsMap = this.tinTerrainManager.currentVisibles_terrName_geoCoords_map; - for (var key in currentVisiblesTerrainsMap) - { - //currentVisiblesTerrainsMap - tinTerrain = currentTerrainsMap[key]; - if (tinTerrain === undefined) - { continue; } - - if (tinTerrain.vboKeyContainer === undefined || tinTerrain.vboKeyContainer.vboCacheKeysArray.length === 0) - { continue; } - - // check the texture of the terrain.*** - if (tinTerrain.texture === undefined) - { - tinTerrain.texture = new Texture(); - var imagesDataPath = "\\images\\ko"; - var textureFilePath = imagesDataPath + "\\funny_" + tinTerrain.depth + ".jpg"; - this.readerWriter.readLegoSimpleBuildingTexture(gl, textureFilePath, tinTerrain.texture, this); - continue; - } - - gl.bindTexture(gl.TEXTURE_2D, tinTerrain.texture.texId); - - gl.uniform3fv(currentShader.buildingPosHIGH_loc, tinTerrain.terrainPositionHIGH); - gl.uniform3fv(currentShader.buildingPosLOW_loc, tinTerrain.terrainPositionLOW); - - //this.renderer.renderNeoBuildingsLOD2AsimetricVersion(gl, visibleObjControlerNodes.currentVisibles0, this, currentShader, renderTexture, ssao_idx); // lod 0.*** - var vboKey = tinTerrain.vboKeyContainer.vboCacheKeysArray[0]; - if (vboKey.isReadyPositions(gl, this.vboMemoryManager) && vboKey.isReadyTexCoords(gl, this.vboMemoryManager) && vboKey.isReadyFaces(gl, this.vboMemoryManager)) - { - // Positions.*** - gl.bindBuffer(gl.ARRAY_BUFFER, vboKey.meshVertexCacheKey); - gl.vertexAttribPointer(currentShader.position3_loc, 3, gl.FLOAT, false, 0, 0); - - // TexCoords.*** - gl.bindBuffer(gl.ARRAY_BUFFER, vboKey.meshTexcoordsCacheKey); - gl.vertexAttribPointer(currentShader.texCoord2_loc, 2, gl.FLOAT, false, 0, 0); - - var indicesCount = vboKey.indicesCount; - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vboKey.meshFacesCacheKey); - - if (renderWireframe) - { - var trianglesCount = indicesCount; - for (var i=0; i 0) - { - currentShader = this.postFxShadersManager.getShader("modelRefSsao"); - shaderProgram = currentShader.program; - - gl.useProgram(shaderProgram); - gl.uniform1i(currentShader.bApplySpecularLighting_loc, false); - gl.disableVertexAttribArray(currentShader.texCoord2_loc); - gl.enableVertexAttribArray(currentShader.position3_loc); - gl.enableVertexAttribArray(currentShader.normal3_loc); - - currentShader.bindUniformGenerals(); - gl.uniform1i(currentShader.textureFlipYAxis_loc, this.sceneState.textureFlipYAxis); + if (keySeparator) { + var resTypeIsArray = resType === '[object Array]'; + var copy$$1 = resTypeIsArray ? [] : {}; // apply child translation on a copy - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, this.depthFboNeo.colorBuffer); // original.*** - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, this.noiseTexture); - gl.activeTexture(gl.TEXTURE2); - gl.bindTexture(gl.TEXTURE_2D, this.textureAux_1x1); - - this.renderer.renderTexture = false; - var currTime = new Date().getTime(); - - - for (var i=0; i 0) - { - currentShader = this.postFxShadersManager.getShader("pointsCloud"); + /* eslint no-restricted-syntax: 0 */ - shaderProgram = currentShader.program; - - gl.useProgram(shaderProgram); + var newKeyToUse = resTypeIsArray ? resExactUsedKey : resUsedKey; - gl.enableVertexAttribArray(currentShader.position3_loc); - //gl.disableVertexAttribArray(currentShader.normal3_loc); // provisionally has no normals.*** - gl.enableVertexAttribArray(currentShader.color4_loc); - - currentShader.bindUniformGenerals(); - /* - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, this.depthFboNeo.colorBuffer); // original.*** - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, this.noiseTexture); - gl.activeTexture(gl.TEXTURE2); - gl.bindTexture(gl.TEXTURE_2D, this.textureAux_1x1); - */ + for (var m in res) { + if (Object.prototype.hasOwnProperty.call(res, m)) { + var deepKey = "".concat(newKeyToUse).concat(keySeparator).concat(m); + copy$$1[m] = this.translate(deepKey, _objectSpread({}, options, { + joinArrays: false, + ns: namespaces + })); + if (copy$$1[m] === deepKey) copy$$1[m] = res[m]; // if nothing found use orginal value as fallback + } + } - this.renderer.renderNeoBuildingsPCloud(gl, this.visibleObjControlerNodes.currentVisiblesAux, this, currentShader, renderTexture, ssao_idx); // lod0.*** - - if (currentShader) - { - if (currentShader.texCoord2_loc !== -1){ gl.disableVertexAttribArray(currentShader.texCoord2_loc); } - if (currentShader.position3_loc !== -1){ gl.disableVertexAttribArray(currentShader.position3_loc); } - if (currentShader.normal3_loc !== -1){ gl.disableVertexAttribArray(currentShader.normal3_loc); } - if (currentShader.color4_loc !== -1){ gl.disableVertexAttribArray(currentShader.color4_loc); } - } - /* - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, null); // original.*** - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, null); - gl.activeTexture(gl.TEXTURE2); - gl.bindTexture(gl.TEXTURE_2D, null); - */ - } - - - } - - - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - if (currentShader) - { - if (currentShader.texCoord2_loc !== -1){ gl.disableVertexAttribArray(currentShader.texCoord2_loc); } - if (currentShader.position3_loc !== -1){ gl.disableVertexAttribArray(currentShader.position3_loc); } - if (currentShader.normal3_loc !== -1){ gl.disableVertexAttribArray(currentShader.normal3_loc); } - if (currentShader.color4_loc !== -1){ gl.disableVertexAttribArray(currentShader.color4_loc); } - } + res = copy$$1; + } + } else if (handleAsObjectInI18nFormat && typeof joinArrays === 'string' && resType === '[object Array]') { + // array special treatment + res = res.join(joinArrays); + if (res) res = this.extendTranslation(res, keys, options); + } else { + // string, empty or null + var usedDefault = false; + var usedKey = false; // fallback value - gl.depthRange(0.0, 1.0); -}; + if (!this.isValidLookup(res) && options.defaultValue !== undefined) { + usedDefault = true; -/** - * Draw building names on scene. - */ -MagoManager.prototype.drawCCTVNames = function(cctvArray) -{ - var canvas = document.getElementById("objectLabel"); - if (canvas === undefined) - { return; } - - canvas.style.opacity = 1.0; - canvas.width = this.sceneState.drawingBufferWidth; - canvas.height = this.sceneState.drawingBufferHeight; - var ctx = canvas.getContext("2d"); - //ctx.strokeStyle = 'SlateGrey'; - //ctx.strokeStyle = 'MidnightBlue'; - ctx.strokeStyle = 'DarkSlateGray'; - //ctx.fillStyle= "white"; - ctx.fillStyle= "PapayaWhip"; - ctx.lineWidth = 4; - ctx.font = "20px Arial"; - ctx.textAlign = 'center'; - //ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); - ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); - ctx.save(); - ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + if (options.count !== undefined) { + var suffix = this.pluralResolver.getSuffix(lng, options.count); + res = options["defaultValue".concat(suffix)]; + } - var lineHeight = ctx.measureText("M").width * 1.1; + if (!res) res = options.defaultValue; + } - // lod2. - var gl = this.sceneState.gl; - var node; - var nodeRoot; - var geoLocDataManager; - var geoLoc; - var neoBuilding; - var worldPosition; - var screenCoord; - var cctv; - - var cctvCount = cctvArray.length; - for (var i=0; i= 0 && screenCoord.y >= 0) - { - ctx.font = "13px Arial"; - ctx.strokeText(cctv.name, screenCoord.x, screenCoord.y); - ctx.fillText(cctv.name, screenCoord.x, screenCoord.y); - } - - } + if (!this.isValidLookup(res)) { + usedKey = true; + res = key; + } // save missing - ctx.restore(); -}; -/** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param cameraPosition 카메라 입장에서 화면에 그리기 전에 객체를 그릴 필요가 있는지 유무를 판단하는 값 - * @param scene 변수 - * @param shader 변수 - * @param renderTexture 변수 - * @param ssao_idx 변수 - * @param neoRefLists_array 변수 - */ + var updateMissing = options.defaultValue && options.defaultValue !== res && this.options.updateMissing; -MagoManager.prototype.renderRenderables = function(gl, cameraPosition, shader, renderTexture, ssao_idx, visibleObjControlerNodes) -{ - // ssao_idx = -1 -> pickingMode.*** - // ssao_idx = 0 -> depth.*** - // ssao_idx = 1 -> ssao.*** - gl.frontFace(gl.CCW); - gl.depthRange(0.0, 1.0); - gl.enable(gl.DEPTH_TEST); - - var currentShader; - var shaderProgram; - var neoBuilding; - var node; - var rootNode; - var geoLocDataManager; + if (usedKey || usedDefault || updateMissing) { + this.logger.log(updateMissing ? 'updateKey' : 'missingKey', lng, namespace, key, updateMissing ? options.defaultValue : res); + var lngs = []; + var fallbackLngs = this.languageUtils.getFallbackCodes(this.options.fallbackLng, options.lng || this.language); - renderTexture = false; - //var lowestOctreeLegosParsingCount = 0; + if (this.options.saveMissingTo === 'fallback' && fallbackLngs && fallbackLngs[0]) { + for (var i = 0; i < fallbackLngs.length; i++) { + lngs.push(fallbackLngs[i]); + } + } else if (this.options.saveMissingTo === 'all') { + lngs = this.languageUtils.toResolveHierarchy(options.lng || this.language); + } else { + lngs.push(options.lng || this.language); + } - if (ssao_idx === 0) - { - gl.disable(gl.BLEND); - this.depthRenderLowestOctreeAsimetricVersion(gl, ssao_idx, visibleObjControlerNodes); - // draw the axis.*** - if (this.magoPolicy.getShowOrigin() && this.nodeSelected !== undefined) - { - node = this.nodeSelected; - var nodes = [node]; - - this.renderAxisNodes(gl, nodes, true, ssao_idx); - } - } - if (ssao_idx === 1) - { - // ssao render.************************************************************************************************************ - var nodesLOD0Count = visibleObjControlerNodes.currentVisibles0.length; + var send = function send(l, k) { + if (_this2.options.missingKeyHandler) { + _this2.options.missingKeyHandler(l, namespace, k, updateMissing ? options.defaultValue : res, updateMissing, options); + } else if (_this2.backendConnector && _this2.backendConnector.saveMissing) { + _this2.backendConnector.saveMissing(l, namespace, k, updateMissing ? options.defaultValue : res, updateMissing, options); + } - if (nodesLOD0Count > 0) - { - // check changesHistory. - this.checkChangesHistoryMovements(visibleObjControlerNodes.currentVisibles0); - this.checkChangesHistoryColors(visibleObjControlerNodes.currentVisibles0); - - if (this.noiseTexture === undefined) - { this.noiseTexture = genNoiseTextureRGBA(gl, 4, 4, this.pixels); } - - currentShader = this.postFxShadersManager.getShader("modelRefSsao"); - shaderProgram = currentShader.program; - - gl.useProgram(shaderProgram); - gl.uniform1i(currentShader.bApplySpecularLighting_loc, false); - gl.enableVertexAttribArray(currentShader.texCoord2_loc); - gl.enableVertexAttribArray(currentShader.position3_loc); - gl.enableVertexAttribArray(currentShader.normal3_loc); - - currentShader.bindUniformGenerals(); - gl.uniform1i(currentShader.textureFlipYAxis_loc, this.sceneState.textureFlipYAxis); + _this2.emit('missingKey', l, namespace, k, res); + }; - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, this.depthFboNeo.colorBuffer); // original.*** - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, this.noiseTexture); - - // 1) LOD0 & LOD1.********************************************************************************************************************* - var refTMatrixIdxKey = 0; - var minSize = 0.0; - var renderTexture; - //if (this.isLastFrustum) - { - this.renderer.renderNodes(gl, visibleObjControlerNodes.currentVisibles0, this, currentShader, renderTexture, ssao_idx, minSize, refTMatrixIdxKey); - } - - if (currentShader) - { - if (currentShader.texCoord2_loc !== -1){ gl.disableVertexAttribArray(currentShader.texCoord2_loc); } - if (currentShader.position3_loc !== -1){ gl.disableVertexAttribArray(currentShader.position3_loc); } - if (currentShader.normal3_loc !== -1){ gl.disableVertexAttribArray(currentShader.normal3_loc); } - if (currentShader.color4_loc !== -1){ gl.disableVertexAttribArray(currentShader.color4_loc); } - } - - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, null); // original.*** - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, null); - gl.activeTexture(gl.TEXTURE2); - gl.bindTexture(gl.TEXTURE_2D, null); - } - - // 2) LOD 2, 3, 4, 5.************************************************************************************************************************************ - var nodesLOD2Count = visibleObjControlerNodes.currentVisibles2.length; - var nodesLOD3Count = visibleObjControlerNodes.currentVisibles3.length; - if (nodesLOD2Count > 0 || nodesLOD0Count > 0 || nodesLOD3Count>0) - { - this.checkChangesHistoryColors(visibleObjControlerNodes.currentVisibles2); + if (this.options.saveMissing) { + var needsPluralHandling = options.count !== undefined && typeof options.count !== 'string'; - // lodBuildingSsaoSimpleCompressed - currentShader = this.postFxShadersManager.getShader("lodBuildingSsao"); + if (this.options.saveMissingPlurals && needsPluralHandling) { + lngs.forEach(function (l) { + var plurals = _this2.pluralResolver.getPluralFormsOfKey(l, key); - shaderProgram = currentShader.program; - - gl.useProgram(shaderProgram); - gl.uniform1i(currentShader.bApplySpecularLighting_loc, false); - gl.enableVertexAttribArray(currentShader.position3_loc); - gl.enableVertexAttribArray(currentShader.normal3_loc); - gl.enableVertexAttribArray(currentShader.color4_loc); - - currentShader.bindUniformGenerals(); - gl.uniform1i(currentShader.textureFlipYAxis_loc, this.sceneState.textureFlipYAxis); + plurals.forEach(function (p) { + return send([l], p); + }); + }); + } else { + send(lngs, key); + } + } + } // extend - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, this.depthFboNeo.colorBuffer); // original.*** - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, this.noiseTexture); - gl.activeTexture(gl.TEXTURE2); - gl.bindTexture(gl.TEXTURE_2D, this.textureAux_1x1); - - this.renderer.renderNeoBuildingsLOD2AsimetricVersion(gl, visibleObjControlerNodes.currentVisibles0, this, currentShader, renderTexture, ssao_idx); // lod 0.*** - this.renderer.renderNeoBuildingsLOD2AsimetricVersion(gl, visibleObjControlerNodes.currentVisibles2, this, currentShader, renderTexture, ssao_idx); // lod 2.*** - this.renderer.renderNeoBuildingsLowLOD(gl, visibleObjControlerNodes.currentVisibles3, this, currentShader, renderTexture, ssao_idx); // lod 3, 4, 5.*** - - if (currentShader) - { - if (currentShader.texCoord2_loc !== -1){ gl.disableVertexAttribArray(currentShader.texCoord2_loc); } - if (currentShader.position3_loc !== -1){ gl.disableVertexAttribArray(currentShader.position3_loc); } - if (currentShader.normal3_loc !== -1){ gl.disableVertexAttribArray(currentShader.normal3_loc); } - if (currentShader.color4_loc !== -1){ gl.disableVertexAttribArray(currentShader.color4_loc); } - } - - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, null); // original.*** - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, null); - gl.activeTexture(gl.TEXTURE2); - gl.bindTexture(gl.TEXTURE_2D, null); - } - // If there are an object selected, then there are a stencilBuffer.****************************************** - if (this.nodeSelected) // if there are an object selected then there are a building selected.*** - { - if (this.magoPolicy.getObjectMoveMode() === CODE.moveMode.OBJECT && this.objectSelected) - { - node = this.nodeSelected; - var geoLocDataManager = this.getNodeGeoLocDataManager(node); - neoBuilding = this.buildingSelected; - var buildingGeoLocation = geoLocDataManager.getCurrentGeoLocationData(); - var neoReferencesMotherAndIndices = this.octreeSelected.neoReferencesMotherAndIndices; - var glPrimitive = gl.POINTS; - glPrimitive = gl.TRIANGLES; - var maxSizeToRender = 0.0; - var refMatrixIdxKey = 0; - - // do as the "getSelectedObjectPicking".********************************************************** - currentShader = this.postFxShadersManager.getModelRefSilhouetteShader(); // silhouette shader.*** - var shaderProgram = currentShader.program; - gl.useProgram(shaderProgram); - - gl.enableVertexAttribArray(currentShader.position3_loc); - - gl.uniformMatrix4fv(currentShader.buildingRotMatrix_loc, false, buildingGeoLocation.rotMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.modelViewProjectionMatrix4RelToEye_loc, false, this.sceneState.modelViewProjRelToEyeMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.ModelViewMatrixRelToEye_loc, false, this.sceneState.modelViewRelToEyeMatrix._floatArrays); - gl.uniform3fv(currentShader.cameraPosHIGH_loc, this.sceneState.encodedCamPosHigh); - gl.uniform3fv(currentShader.cameraPosLOW_loc, this.sceneState.encodedCamPosLow); - - // do the colorCoding render.*** - // position uniforms.*** - gl.uniform3fv(currentShader.buildingPosHIGH_loc, buildingGeoLocation.positionHIGH); - gl.uniform3fv(currentShader.buildingPosLOW_loc, buildingGeoLocation.positionLOW); - - gl.uniform4fv(currentShader.color4Aux_loc, [0.0, 1.0, 0.0, 1.0]); - gl.uniform2fv(currentShader.screenSize_loc, [this.sceneState.drawingBufferWidth, this.sceneState.drawingBufferHeight]); - gl.uniformMatrix4fv(currentShader.ProjectionMatrix_loc, false, this.sceneState.projectionMatrix._floatArrays); - - gl.enable(gl.STENCIL_TEST); - gl.disable(gl.POLYGON_OFFSET_FILL); - gl.disable(gl.CULL_FACE); - gl.disable(gl.DEPTH_TEST); - gl.depthRange(0, 0); - - gl.stencilFunc(gl.EQUAL, 0, 1); - gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE); - - //glPrimitive = gl.POINTS; - glPrimitive = gl.TRIANGLES; - //gl.polygonMode( gl.FRONT_AND_BACK, gl.LINE ); - - var offsetSize = 3/1000; - gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [offsetSize, offsetSize]); - this.renderer.renderNeoReferenceAsimetricVersionColorSelection(gl, this.objectSelected, neoReferencesMotherAndIndices, neoBuilding, this, currentShader, maxSizeToRender, refMatrixIdxKey, glPrimitive); - gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [-offsetSize, offsetSize]); - this.renderer.renderNeoReferenceAsimetricVersionColorSelection(gl, this.objectSelected, neoReferencesMotherAndIndices, neoBuilding, this, currentShader, maxSizeToRender, refMatrixIdxKey, glPrimitive); - gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [offsetSize, -offsetSize]); - this.renderer.renderNeoReferenceAsimetricVersionColorSelection(gl, this.objectSelected, neoReferencesMotherAndIndices, neoBuilding, this, currentShader, maxSizeToRender, refMatrixIdxKey, glPrimitive); - gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [-offsetSize, -offsetSize]); - this.renderer.renderNeoReferenceAsimetricVersionColorSelection(gl, this.objectSelected, neoReferencesMotherAndIndices, neoBuilding, this, currentShader, maxSizeToRender, refMatrixIdxKey, glPrimitive); - gl.enable(gl.DEPTH_TEST);// return to the normal state.*** - gl.disable(gl.STENCIL_TEST); - gl.depthRange(0, 1);// return to the normal value.*** - gl.disableVertexAttribArray(currentShader.position3_loc); - - if (currentShader) - { - if (currentShader.texCoord2_loc !== -1){ gl.disableVertexAttribArray(currentShader.texCoord2_loc); } - if (currentShader.position3_loc !== -1){ gl.disableVertexAttribArray(currentShader.position3_loc); } - if (currentShader.normal3_loc !== -1){ gl.disableVertexAttribArray(currentShader.normal3_loc); } - if (currentShader.color4_loc !== -1){ gl.disableVertexAttribArray(currentShader.color4_loc); } - } - } - - // render bbox for neoBuildingSelected. // old.*** - /* - var selectedNodesArray = []; - selectedNodesArray.push(this.nodeSelected); - if (this.colorSC === undefined) - { this.colorSC = new Color(); } - this.colorSC.setRGB(0.8, 1.0, 1.0); - this.renderBoundingBoxesNodes(gl, selectedNodesArray, this.colorSC); // old. - */ - - // new. Render the silhouette by lod3 or lod4 or lod5 mesh*** - if (this.magoPolicy.getObjectMoveMode() === CODE.moveMode.ALL && this.buildingSelected) - { - node = this.nodeSelected; - var geoLocDataManager = this.getNodeGeoLocDataManager(node); - neoBuilding = this.buildingSelected; - var buildingGeoLocation = geoLocDataManager.getCurrentGeoLocationData(); - //var neoReferencesMotherAndIndices = this.octreeSelected.neoReferencesMotherAndIndices; - var glPrimitive = gl.POINTS; - glPrimitive = gl.TRIANGLES; - var maxSizeToRender = 0.0; - var refMatrixIdxKey = 0; - var skinLego = neoBuilding.getCurrentSkin(); - if (skinLego !== undefined) - { - // do as the "getSelectedObjectPicking".********************************************************** - currentShader = this.postFxShadersManager.getModelRefSilhouetteShader(); // silhouette shader.*** - var shaderProgram = currentShader.program; - gl.useProgram(shaderProgram); - - gl.enableVertexAttribArray(currentShader.position3_loc); - - gl.uniformMatrix4fv(currentShader.buildingRotMatrix_loc, false, buildingGeoLocation.rotMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.modelViewProjectionMatrix4RelToEye_loc, false, this.sceneState.modelViewProjRelToEyeMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.ModelViewMatrixRelToEye_loc, false, this.sceneState.modelViewRelToEyeMatrix._floatArrays); - gl.uniform3fv(currentShader.cameraPosHIGH_loc, this.sceneState.encodedCamPosHigh); - gl.uniform3fv(currentShader.cameraPosLOW_loc, this.sceneState.encodedCamPosLow); - - // do the colorCoding render.*** - // position uniforms.*** - gl.uniform3fv(currentShader.buildingPosHIGH_loc, buildingGeoLocation.positionHIGH); - gl.uniform3fv(currentShader.buildingPosLOW_loc, buildingGeoLocation.positionLOW); - - gl.uniform4fv(currentShader.color4Aux_loc, [0.0, 1.0, 0.0, 1.0]); - gl.uniform2fv(currentShader.screenSize_loc, [this.sceneState.drawingBufferWidth, this.sceneState.drawingBufferHeight]); - gl.uniformMatrix4fv(currentShader.ProjectionMatrix_loc, false, this.sceneState.projectionMatrix._floatArrays); - - gl.uniform3fv(currentShader.aditionalMov_loc, [0.0, 0.0, 0.0]); //.*** - - gl.enable(gl.STENCIL_TEST); - gl.disable(gl.POLYGON_OFFSET_FILL); - gl.disable(gl.CULL_FACE); - gl.disable(gl.DEPTH_TEST); - gl.depthRange(0, 0); - - gl.stencilFunc(gl.EQUAL, 0, 1); - //gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE); - gl.stencilOp(gl.KEEP, gl.REPLACE, gl.REPLACE); - - //glPrimitive = gl.POINTS; - glPrimitive = gl.TRIANGLES; - gl.uniform1i(currentShader.refMatrixType_loc, 0); // 0 = identity matrix.*** - //gl.polygonMode( gl.FRONT_AND_BACK, gl.LINE ); + res = this.extendTranslation(res, keys, options, resolved); // append namespace if still key - - var offsetSize = 4/1000; - gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [offsetSize, offsetSize]); - this.renderer.renderLodBuildingColorSelection(gl, skinLego, this, currentShader); - gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [-offsetSize, offsetSize]); - this.renderer.renderLodBuildingColorSelection(gl, skinLego, this, currentShader); - gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [offsetSize, -offsetSize]); - this.renderer.renderLodBuildingColorSelection(gl, skinLego, this, currentShader); - gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [-offsetSize, -offsetSize]); - this.renderer.renderLodBuildingColorSelection(gl, skinLego, this, currentShader); - gl.enable(gl.DEPTH_TEST);// return to the normal state.*** - gl.disable(gl.STENCIL_TEST); - gl.depthRange(0, 1);// return to the normal value.*** - gl.disableVertexAttribArray(currentShader.position3_loc); - - if (currentShader) - { - if (currentShader.texCoord2_loc !== -1){ gl.disableVertexAttribArray(currentShader.texCoord2_loc); } - if (currentShader.position3_loc !== -1){ gl.disableVertexAttribArray(currentShader.position3_loc); } - if (currentShader.normal3_loc !== -1){ gl.disableVertexAttribArray(currentShader.normal3_loc); } - if (currentShader.color4_loc !== -1){ gl.disableVertexAttribArray(currentShader.color4_loc); } - } - } - - } - - // draw the axis.*** - if (this.magoPolicy.getShowOrigin()) - { - node = this.nodeSelected; - //var geoLocDataManager = this.getNodeGeoLocDataManager(node); - var nodes = [node]; - - this.renderAxisNodes(gl, nodes, true, ssao_idx); - } - } - - // 3) now render bboxes.******************************************************************************************************************* - if (this.magoPolicy.getShowBoundingBox()) - { - var bRenderLines = true; - this.renderBoundingBoxesNodes(gl, this.visibleObjControlerNodes.currentVisibles0, undefined, bRenderLines); - this.renderBoundingBoxesNodes(gl, this.visibleObjControlerNodes.currentVisibles2, undefined, bRenderLines); - } - - // 4) Render ObjectMarkers.******************************************************************************************************** - // 4) Render ObjectMarkers.******************************************************************************************************** - // 4) Render ObjectMarkers.******************************************************************************************************** - var objectsMarkersCount = this.objMarkerManager.objectMarkerArray.length; - if (objectsMarkersCount > 0) - { - // now repeat the objects markers for png images.*** - // Png for pin image 128x128.******************************************************************** - if (this.pin.positionBuffer === undefined) - { this.pin.createPinCenterBottom(gl); } - - currentShader = this.postFxShadersManager.pFx_shaders_array[13]; // png image shader.*** - - shaderProgram = currentShader.program; - - gl.useProgram(shaderProgram); - gl.uniformMatrix4fv(currentShader.modelViewProjectionMatrix4RelToEye_loc, false, this.sceneState.modelViewProjRelToEyeMatrix._floatArrays); - gl.uniform3fv(currentShader.cameraPosHIGH_loc, this.sceneState.encodedCamPosHigh); - gl.uniform3fv(currentShader.cameraPosLOW_loc, this.sceneState.encodedCamPosLow); - gl.uniformMatrix4fv(currentShader.buildingRotMatrix_loc, false, this.sceneState.modelViewRelToEyeMatrixInv._floatArrays); - - gl.uniform1i(currentShader.textureFlipYAxis_loc, this.sceneState.textureFlipYAxis); - // Tell the shader to get the texture from texture unit 0 - gl.uniform1i(currentShader.texture_loc, 0); - gl.enableVertexAttribArray(currentShader.texCoord2_loc); - gl.enableVertexAttribArray(currentShader.position3_loc); - gl.activeTexture(gl.TEXTURE0); - - gl.depthRange(0, 0); - //var context = document.getElementById('canvas2').getContext("2d"); - //var canvas = document.getElementById("magoContainer"); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.pin.positionBuffer); - gl.vertexAttribPointer(currentShader.position3_loc, 3, gl.FLOAT, false, 0, 0); - gl.bindBuffer(gl.ARRAY_BUFFER, this.pin.texcoordBuffer); - gl.vertexAttribPointer(currentShader.texCoord2_loc, 2, gl.FLOAT, false, 0, 0); - var j=0; - for (var i=0; i= this.pin.texturesArray.length) - { j=0; } - - var currentTexture = this.pin.texturesArray[j]; - var objMarker = this.objMarkerManager.objectMarkerArray[i]; - var objMarkerGeoLocation = objMarker.geoLocationData; - gl.bindTexture(gl.TEXTURE_2D, currentTexture.texId); - gl.uniform3fv(currentShader.buildingPosHIGH_loc, objMarkerGeoLocation.positionHIGH); - gl.uniform3fv(currentShader.buildingPosLOW_loc, objMarkerGeoLocation.positionLOW); + if (usedKey && res === key && this.options.appendNamespaceToMissingKey) res = "".concat(namespace, ":").concat(key); // parseMissingKeyHandler - gl.drawArrays(gl.TRIANGLES, 0, 6); - - j++; - } - gl.depthRange(0, 1); - gl.useProgram(null); - gl.bindTexture(gl.TEXTURE_2D, null); - gl.disableVertexAttribArray(currentShader.texCoord2_loc); - gl.disableVertexAttribArray(currentShader.position3_loc); - - } - - // Test TinTerrain.************************************************************************** - // Test TinTerrain.************************************************************************** - //this.tinTerrainManager - - if (this.tinTerrainManager !== undefined) - { - - currentShader = this.postFxShadersManager.getShader("tinTerrain"); - shaderProgram = currentShader.program; - - gl.useProgram(shaderProgram); - gl.enableVertexAttribArray(currentShader.position3_loc); - gl.enableVertexAttribArray(currentShader.texCoord2_loc); - //gl.disableVertexAttribArray(currentShader.normal3_loc); - //gl.disableVertexAttribArray(currentShader.color4_loc); - - currentShader.bindUniformGenerals(); + if (usedKey && this.options.parseMissingKeyHandler) res = this.options.parseMissingKeyHandler(res); + } // return - var tex = this.pin.texturesArray[4]; - gl.activeTexture(gl.TEXTURE2); - gl.bindTexture(gl.TEXTURE_2D, tex.texId); - - gl.uniform1i(currentShader.hasTexture_loc, true); //.*** - gl.uniform4fv(currentShader.oneColor4_loc, [0.5, 0.5, 0.5, 1.0]); - - var renderWireframe = false; - var tinTerrain; - var currentTerrainsMap = this.tinTerrainManager.currentTerrainsMap; - var currentVisiblesTerrainsMap = this.tinTerrainManager.currentVisibles_terrName_geoCoords_map; - for (var key in currentVisiblesTerrainsMap) - { - //currentVisiblesTerrainsMap - tinTerrain = currentTerrainsMap[key]; - if (tinTerrain === undefined) - { continue; } - - if (tinTerrain.vboKeyContainer === undefined || tinTerrain.vboKeyContainer.vboCacheKeysArray.length === 0) - { continue; } - - // check the texture of the terrain.*** - if (tinTerrain.texture === undefined) - { - tinTerrain.texture = new Texture(); - var imagesDataPath = "\\images\\ko"; - var textureFilePath = imagesDataPath + "\\funny_" + tinTerrain.depth + ".jpg"; - this.readerWriter.readLegoSimpleBuildingTexture(gl, textureFilePath, tinTerrain.texture, this); - continue; - } - - gl.bindTexture(gl.TEXTURE_2D, tinTerrain.texture.texId); - - gl.uniform3fv(currentShader.buildingPosHIGH_loc, tinTerrain.terrainPositionHIGH); - gl.uniform3fv(currentShader.buildingPosLOW_loc, tinTerrain.terrainPositionLOW); - - //this.renderer.renderNeoBuildingsLOD2AsimetricVersion(gl, visibleObjControlerNodes.currentVisibles0, this, currentShader, renderTexture, ssao_idx); // lod 0.*** - var vboKey = tinTerrain.vboKeyContainer.vboCacheKeysArray[0]; - if (vboKey.isReadyPositions(gl, this.vboMemoryManager) && vboKey.isReadyTexCoords(gl, this.vboMemoryManager) && vboKey.isReadyFaces(gl, this.vboMemoryManager)) - { - // Positions.*** - gl.bindBuffer(gl.ARRAY_BUFFER, vboKey.meshVertexCacheKey); - gl.vertexAttribPointer(currentShader.position3_loc, 3, gl.FLOAT, false, 0, 0); - - // TexCoords.*** - gl.bindBuffer(gl.ARRAY_BUFFER, vboKey.meshTexcoordsCacheKey); - gl.vertexAttribPointer(currentShader.texCoord2_loc, 2, gl.FLOAT, false, 0, 0); - - var indicesCount = vboKey.indicesCount; - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vboKey.meshFacesCacheKey); - - if (renderWireframe) - { - var trianglesCount = indicesCount; - for (var i=0; i 1 && arguments[1] !== undefined ? arguments[1] : {}; + var found; + var usedKey; // plain key + + var exactUsedKey; // key with context / plural + + var usedLng; + var usedNS; + if (typeof keys === 'string') keys = [keys]; // forEach possible key + + keys.forEach(function (k) { + if (_this4.isValidLookup(found)) return; + + var extracted = _this4.extractFromKey(k, options); + + var key = extracted.key; + usedKey = key; + var namespaces = extracted.namespaces; + if (_this4.options.fallbackNS) namespaces = namespaces.concat(_this4.options.fallbackNS); + var needsPluralHandling = options.count !== undefined && typeof options.count !== 'string'; + var needsContextHandling = options.context !== undefined && typeof options.context === 'string' && options.context !== ''; + var codes = options.lngs ? options.lngs : _this4.languageUtils.toResolveHierarchy(options.lng || _this4.language, options.fallbackLng); + namespaces.forEach(function (ns) { + if (_this4.isValidLookup(found)) return; + usedNS = ns; + codes.forEach(function (code) { + if (_this4.isValidLookup(found)) return; + usedLng = code; + var finalKey = key; + var finalKeys = [finalKey]; + + if (_this4.i18nFormat && _this4.i18nFormat.addLookupKeys) { + _this4.i18nFormat.addLookupKeys(finalKeys, key, code, ns, options); + } else { + var pluralSuffix; + if (needsPluralHandling) pluralSuffix = _this4.pluralResolver.getSuffix(code, options.count); // fallback for plural if context not found -/** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param cameraPosition 카메라 입장에서 화면에 그리기 전에 객체를 그릴 필요가 있는지 유무를 판단하는 값 - * @param scene 변수 - * @param shader 변수 - * @param renderTexture 변수 - * @param ssao_idx 변수 - * @param neoRefLists_array 변수 - */ + if (needsPluralHandling && needsContextHandling) finalKeys.push(finalKey + pluralSuffix); // get key for context if needed -MagoManager.prototype.renderBoundingBoxesNodes = function(gl, nodesArray, color, bRenderLines) -{ - var node; - var currentShader = this.postFxShadersManager.getTriPolyhedronShader(); // box ssao.*** - var shaderProgram = currentShader.program; - gl.enable(gl.BLEND); - gl.frontFace(gl.CCW); - gl.useProgram(shaderProgram); - gl.enableVertexAttribArray(currentShader.position3_loc); - gl.enableVertexAttribArray(currentShader.normal3_loc); - gl.disableVertexAttribArray(currentShader.color4_loc); + if (needsContextHandling) finalKeys.push(finalKey += "".concat(_this4.options.contextSeparator).concat(options.context)); // get key for plural if needed - gl.uniformMatrix4fv(currentShader.modelViewProjectionMatrix4RelToEye_loc, false, this.sceneState.modelViewProjRelToEyeMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.modelViewMatrix4RelToEye_loc, false, this.sceneState.modelViewRelToEyeMatrix._floatArrays); // original.*** - gl.uniformMatrix4fv(currentShader.modelViewMatrix4_loc, false, this.sceneState.modelViewMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.projectionMatrix4_loc, false, this.sceneState.projectionMatrix._floatArrays); - gl.uniform3fv(currentShader.cameraPosHIGH_loc, this.sceneState.encodedCamPosHigh); - gl.uniform3fv(currentShader.cameraPosLOW_loc, this.sceneState.encodedCamPosLow); + if (needsPluralHandling) finalKeys.push(finalKey += pluralSuffix); + } // iterate over finalKeys starting with most specific pluralkey (-> contextkey only) -> singularkey only - gl.uniform1f(currentShader.near_loc, this.sceneState.camera.frustum.near); - gl.uniform1f(currentShader.far_loc, this.sceneState.camera.frustum.far); - - gl.uniform1i(currentShader.bApplySsao_loc, false); - gl.uniformMatrix4fv(currentShader.normalMatrix4_loc, false, this.sceneState.normalMatrix4._floatArrays); - //----------------------------------------------------------------------------------------------------------- + var possibleKey; + /* eslint no-cond-assign: 0 */ - gl.uniform1i(currentShader.hasAditionalMov_loc, true); - gl.uniform3fv(currentShader.aditionalMov_loc, [0.0, 0.0, 0.0]); //.*** - gl.uniform1i(currentShader.bScale_loc, true); - var alfa = 1.0; - gl.uniform1i(currentShader.bUse1Color_loc, true); - if (color) - { - gl.uniform4fv(currentShader.oneColor4_loc, [color.r, color.g, color.b, alfa]); //.*** - } - else - { - gl.uniform4fv(currentShader.oneColor4_loc, [1.0, 0.0, 1.0, alfa]); //.*** - } + while (possibleKey = finalKeys.pop()) { + if (!_this4.isValidLookup(found)) { + exactUsedKey = possibleKey; + found = _this4.getResource(code, ns, possibleKey, options); + } + } + }); + }); + }); + return { + res: found, + usedKey: usedKey, + exactUsedKey: exactUsedKey, + usedLng: usedLng, + usedNS: usedNS + }; + } + }, { + key: "isValidLookup", + value: function isValidLookup(res) { + return res !== undefined && !(!this.options.returnNull && res === null) && !(!this.options.returnEmptyString && res === ''); + } + }, { + key: "getResource", + value: function getResource(code, ns, key) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + if (this.i18nFormat && this.i18nFormat.getResource) return this.i18nFormat.getResource(code, ns, key, options); + return this.resourceStore.getResource(code, ns, key, options); + } + }]); - gl.uniform1i(currentShader.depthTex_loc, 0); - gl.uniform1i(currentShader.noiseTex_loc, 1); - gl.uniform1i(currentShader.diffuseTex_loc, 2); // no used.*** - gl.uniform1f(currentShader.fov_loc, this.sceneState.camera.frustum.fovyRad); // "frustum._fov" is in radians.*** - gl.uniform1f(currentShader.aspectRatio_loc, this.sceneState.camera.frustum.aspectRatio); - gl.uniform1f(currentShader.screenWidth_loc, this.sceneState.drawingBufferWidth); - gl.uniform1f(currentShader.screenHeight_loc, this.sceneState.drawingBufferHeight); + return Translator; + }(EventEmitter); + function capitalize(string) { + return string.charAt(0).toUpperCase() + string.slice(1); + } - gl.uniform2fv(currentShader.noiseScale2_loc, [this.depthFboNeo.width/this.noiseTexture.width, this.depthFboNeo.height/this.noiseTexture.height]); - gl.uniform3fv(currentShader.kernel16_loc, this.kernel); - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, this.depthFboNeo.colorBuffer); // original.*** - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, this.noiseTexture); + var LanguageUtil = + /*#__PURE__*/ + function () { + function LanguageUtil(options) { + _classCallCheck(this, LanguageUtil); - var neoBuilding; - var ssao_idx = 1; - var nodesCount = nodesArray.length; - for (var b=0; b -1) { + var specialCases = ['hans', 'hant', 'latn', 'cyrl', 'cans', 'mong', 'arab']; + var p = code.split('-'); + + if (this.options.lowerCaseLng) { + p = p.map(function (part) { + return part.toLowerCase(); + }); + } else if (p.length === 2) { + p[0] = p[0].toLowerCase(); + p[1] = p[1].toUpperCase(); + if (specialCases.indexOf(p[1].toLowerCase()) > -1) p[1] = capitalize(p[1].toLowerCase()); + } else if (p.length === 3) { + p[0] = p[0].toLowerCase(); // if lenght 2 guess it's a country + + if (p[1].length === 2) p[1] = p[1].toUpperCase(); + if (p[0] !== 'sgn' && p[2].length === 2) p[2] = p[2].toUpperCase(); + if (specialCases.indexOf(p[1].toLowerCase()) > -1) p[1] = capitalize(p[1].toLowerCase()); + if (specialCases.indexOf(p[2].toLowerCase()) > -1) p[2] = capitalize(p[2].toLowerCase()); + } - this.pointSC = neoBuilding.bbox.getCenterPoint(this.pointSC); - gl.uniform3fv(currentShader.aditionalMov_loc, [this.pointSC.x, this.pointSC.y, this.pointSC.z]); //.*** - //gl.uniform3fv(currentShader.aditionalMov_loc, [0.0, 0.0, 0.0]); //.*** - this.renderer.renderObject(gl, this.unitaryBoxSC, this, currentShader, ssao_idx, bRenderLines); - } - - if (currentShader) - { - if (currentShader.texCoord2_loc !== -1){ gl.disableVertexAttribArray(currentShader.texCoord2_loc); } - if (currentShader.position3_loc !== -1){ gl.disableVertexAttribArray(currentShader.position3_loc); } - if (currentShader.normal3_loc !== -1){ gl.disableVertexAttribArray(currentShader.normal3_loc); } - if (currentShader.color4_loc !== -1){ gl.disableVertexAttribArray(currentShader.color4_loc); } - } - - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, null); // original.*** - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, null); - gl.activeTexture(gl.TEXTURE2); - gl.bindTexture(gl.TEXTURE_2D, null); - - gl.disable(gl.BLEND); -}; + return p.join('-'); + } -/** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param cameraPosition 카메라 입장에서 화면에 그리기 전에 객체를 그릴 필요가 있는지 유무를 판단하는 값 - * @param scene 변수 - * @param shader 변수 - * @param renderTexture 변수 - * @param ssao_idx 변수 - * @param neoRefLists_array 변수 - */ + return this.options.cleanCode || this.options.lowerCaseLng ? code.toLowerCase() : code; + } + }, { + key: "isWhitelisted", + value: function isWhitelisted(code) { + if (this.options.load === 'languageOnly' || this.options.nonExplicitWhitelist) { + code = this.getLanguagePartFromCode(code); + } -MagoManager.prototype.renderAxisNodes = function(gl, nodesArray, bRenderLines, ssao_idx) -{ - if (this.axisXYZ.vbo_vicks_container.vboCacheKeysArray.length === 0) - { - var mesh = this.axisXYZ.makeMesh(30); - mesh.getVbo(this.axisXYZ.vbo_vicks_container); - } - - var gl = this.sceneState.gl; - var color; - var node; - var currentShader; - if (ssao_idx === 0) - { - currentShader = this.postFxShadersManager.getTriPolyhedronDepthShader(); // triPolyhedron ssao.*** - gl.disable(gl.BLEND); - } - if (ssao_idx === 1) - { - currentShader = this.postFxShadersManager.getTriPolyhedronShader(); // triPolyhedron ssao.*** - gl.enable(gl.BLEND); - } - - var shaderProgram = currentShader.program; - - gl.frontFace(gl.CCW); - gl.useProgram(shaderProgram); - gl.enableVertexAttribArray(currentShader.position3_loc); - - gl.uniformMatrix4fv(currentShader.modelViewProjectionMatrix4RelToEye_loc, false, this.sceneState.modelViewProjRelToEyeMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.modelViewMatrix4RelToEye_loc, false, this.sceneState.modelViewRelToEyeMatrix._floatArrays); // original.*** - - gl.uniform3fv(currentShader.cameraPosHIGH_loc, this.sceneState.encodedCamPosHigh); - gl.uniform3fv(currentShader.cameraPosLOW_loc, this.sceneState.encodedCamPosLow); + return !this.whitelist || !this.whitelist.length || this.whitelist.indexOf(code) > -1; + } + }, { + key: "getFallbackCodes", + value: function getFallbackCodes(fallbacks, code) { + if (!fallbacks) return []; + if (typeof fallbacks === 'string') fallbacks = [fallbacks]; + if (Object.prototype.toString.apply(fallbacks) === '[object Array]') return fallbacks; + if (!code) return fallbacks.default || []; // asume we have an object defining fallbacks + + var found = fallbacks[code]; + if (!found) found = fallbacks[this.getScriptPartFromCode(code)]; + if (!found) found = fallbacks[this.formatLanguageCode(code)]; + if (!found) found = fallbacks.default; + return found || []; + } + }, { + key: "toResolveHierarchy", + value: function toResolveHierarchy(code, fallbackCode) { + var _this = this; - gl.uniform1f(currentShader.near_loc, this.sceneState.camera.frustum.near); - gl.uniform1f(currentShader.far_loc, this.sceneState.camera.frustum.far); - - gl.uniform1i(currentShader.bApplySsao_loc, true); + var fallbackCodes = this.getFallbackCodes(fallbackCode || this.options.fallbackLng || [], code); + var codes = []; - gl.uniformMatrix4fv(currentShader.normalMatrix4_loc, false, this.sceneState.normalMatrix4._floatArrays); - //----------------------------------------------------------------------------------------------------------- - - if (ssao_idx === 1) - { - // provisionally render all native projects.*** - gl.enableVertexAttribArray(currentShader.normal3_loc); - gl.enableVertexAttribArray(currentShader.color4_loc); + var addCode = function addCode(c) { + if (!c) return; - gl.uniform1i(currentShader.bUse1Color_loc, false); - if (color) - { - gl.uniform4fv(currentShader.oneColor4_loc, [color.r, color.g, color.b, 1.0]); //.*** - } - else - { - gl.uniform4fv(currentShader.oneColor4_loc, [1.0, 0.1, 0.1, 1.0]); //.*** - } - - gl.uniformMatrix4fv(currentShader.modelViewMatrix4_loc, false, this.sceneState.modelViewMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.projectionMatrix4_loc, false, this.sceneState.projectionMatrix._floatArrays); + if (_this.isWhitelisted(c)) { + codes.push(c); + } else { + _this.logger.warn("rejecting non-whitelisted language code: ".concat(c)); + } + }; - gl.uniform1i(currentShader.depthTex_loc, 0); - gl.uniform1i(currentShader.noiseTex_loc, 1); - gl.uniform1i(currentShader.diffuseTex_loc, 2); // no used.*** - gl.uniform1f(currentShader.fov_loc, this.sceneState.camera.frustum.fovyRad); // "frustum._fov" is in radians.*** - gl.uniform1f(currentShader.aspectRatio_loc, this.sceneState.camera.frustum.aspectRatio); - gl.uniform1f(currentShader.screenWidth_loc, this.sceneState.drawingBufferWidth); - gl.uniform1f(currentShader.screenHeight_loc, this.sceneState.drawingBufferHeight); + if (typeof code === 'string' && code.indexOf('-') > -1) { + if (this.options.load !== 'languageOnly') addCode(this.formatLanguageCode(code)); + if (this.options.load !== 'languageOnly' && this.options.load !== 'currentOnly') addCode(this.getScriptPartFromCode(code)); + if (this.options.load !== 'currentOnly') addCode(this.getLanguagePartFromCode(code)); + } else if (typeof code === 'string') { + addCode(this.formatLanguageCode(code)); + } + fallbackCodes.forEach(function (fc) { + if (codes.indexOf(fc) < 0) addCode(_this.formatLanguageCode(fc)); + }); + return codes; + } + }]); + + return LanguageUtil; + }(); + + /* eslint-disable */ + + var sets = [{ + lngs: ['ach', 'ak', 'am', 'arn', 'br', 'fil', 'gun', 'ln', 'mfe', 'mg', 'mi', 'oc', 'pt', 'pt-BR', 'tg', 'ti', 'tr', 'uz', 'wa'], + nr: [1, 2], + fc: 1 + }, { + lngs: ['af', 'an', 'ast', 'az', 'bg', 'bn', 'ca', 'da', 'de', 'dev', 'el', 'en', 'eo', 'es', 'et', 'eu', 'fi', 'fo', 'fur', 'fy', 'gl', 'gu', 'ha', 'hi', 'hu', 'hy', 'ia', 'it', 'kn', 'ku', 'lb', 'mai', 'ml', 'mn', 'mr', 'nah', 'nap', 'nb', 'ne', 'nl', 'nn', 'no', 'nso', 'pa', 'pap', 'pms', 'ps', 'pt-PT', 'rm', 'sco', 'se', 'si', 'so', 'son', 'sq', 'sv', 'sw', 'ta', 'te', 'tk', 'ur', 'yo'], + nr: [1, 2], + fc: 2 + }, { + lngs: ['ay', 'bo', 'cgg', 'fa', 'id', 'ja', 'jbo', 'ka', 'kk', 'km', 'ko', 'ky', 'lo', 'ms', 'sah', 'su', 'th', 'tt', 'ug', 'vi', 'wo', 'zh'], + nr: [1], + fc: 3 + }, { + lngs: ['be', 'bs', 'dz', 'hr', 'ru', 'sr', 'uk'], + nr: [1, 2, 5], + fc: 4 + }, { + lngs: ['ar'], + nr: [0, 1, 2, 3, 11, 100], + fc: 5 + }, { + lngs: ['cs', 'sk'], + nr: [1, 2, 5], + fc: 6 + }, { + lngs: ['csb', 'pl'], + nr: [1, 2, 5], + fc: 7 + }, { + lngs: ['cy'], + nr: [1, 2, 3, 8], + fc: 8 + }, { + lngs: ['fr'], + nr: [1, 2], + fc: 9 + }, { + lngs: ['ga'], + nr: [1, 2, 3, 7, 11], + fc: 10 + }, { + lngs: ['gd'], + nr: [1, 2, 3, 20], + fc: 11 + }, { + lngs: ['is'], + nr: [1, 2], + fc: 12 + }, { + lngs: ['jv'], + nr: [0, 1], + fc: 13 + }, { + lngs: ['kw'], + nr: [1, 2, 3, 4], + fc: 14 + }, { + lngs: ['lt'], + nr: [1, 2, 10], + fc: 15 + }, { + lngs: ['lv'], + nr: [1, 2, 0], + fc: 16 + }, { + lngs: ['mk'], + nr: [1, 2], + fc: 17 + }, { + lngs: ['mnk'], + nr: [0, 1, 2], + fc: 18 + }, { + lngs: ['mt'], + nr: [1, 2, 11, 20], + fc: 19 + }, { + lngs: ['or'], + nr: [2, 1], + fc: 2 + }, { + lngs: ['ro'], + nr: [1, 2, 20], + fc: 20 + }, { + lngs: ['sl'], + nr: [5, 1, 2, 3], + fc: 21 + }, { + lngs: ['he'], + nr: [1, 2, 20, 21], + fc: 22 + }]; + var _rulesPluralsTypes = { + 1: function _(n) { + return Number(n > 1); + }, + 2: function _(n) { + return Number(n != 1); + }, + 3: function _(n) { + return 0; + }, + 4: function _(n) { + return Number(n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2); + }, + 5: function _(n) { + return Number(n === 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5); + }, + 6: function _(n) { + return Number(n == 1 ? 0 : n >= 2 && n <= 4 ? 1 : 2); + }, + 7: function _(n) { + return Number(n == 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2); + }, + 8: function _(n) { + return Number(n == 1 ? 0 : n == 2 ? 1 : n != 8 && n != 11 ? 2 : 3); + }, + 9: function _(n) { + return Number(n >= 2); + }, + 10: function _(n) { + return Number(n == 1 ? 0 : n == 2 ? 1 : n < 7 ? 2 : n < 11 ? 3 : 4); + }, + 11: function _(n) { + return Number(n == 1 || n == 11 ? 0 : n == 2 || n == 12 ? 1 : n > 2 && n < 20 ? 2 : 3); + }, + 12: function _(n) { + return Number(n % 10 != 1 || n % 100 == 11); + }, + 13: function _(n) { + return Number(n !== 0); + }, + 14: function _(n) { + return Number(n == 1 ? 0 : n == 2 ? 1 : n == 3 ? 2 : 3); + }, + 15: function _(n) { + return Number(n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2); + }, + 16: function _(n) { + return Number(n % 10 == 1 && n % 100 != 11 ? 0 : n !== 0 ? 1 : 2); + }, + 17: function _(n) { + return Number(n == 1 || n % 10 == 1 ? 0 : 1); + }, + 18: function _(n) { + return Number(n == 0 ? 0 : n == 1 ? 1 : 2); + }, + 19: function _(n) { + return Number(n == 1 ? 0 : n === 0 || n % 100 > 1 && n % 100 < 11 ? 1 : n % 100 > 10 && n % 100 < 20 ? 2 : 3); + }, + 20: function _(n) { + return Number(n == 1 ? 0 : n === 0 || n % 100 > 0 && n % 100 < 20 ? 1 : 2); + }, + 21: function _(n) { + return Number(n % 100 == 1 ? 1 : n % 100 == 2 ? 2 : n % 100 == 3 || n % 100 == 4 ? 3 : 0); + }, + 22: function _(n) { + return Number(n === 1 ? 0 : n === 2 ? 1 : (n < 0 || n > 10) && n % 10 == 0 ? 2 : 3); + } + }; + /* eslint-enable */ + + function createRules() { + var rules = {}; + sets.forEach(function (set) { + set.lngs.forEach(function (l) { + rules[l] = { + numbers: set.nr, + plurals: _rulesPluralsTypes[set.fc] + }; + }); + }); + return rules; + } - gl.uniform2fv(currentShader.noiseScale2_loc, [this.depthFboNeo.width/this.noiseTexture.width, this.depthFboNeo.height/this.noiseTexture.height]); - gl.uniform3fv(currentShader.kernel16_loc, this.kernel); - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, this.depthFboNeo.colorBuffer); // original.*** - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, this.noiseTexture); - } - - var neoBuilding; - var natProject, mesh; - var geoLocDataManager; - var buildingGeoLocation; - var nodesCount = nodesArray.length; - for (var b=0; b 1 && arguments[1] !== undefined ? arguments[1] : {}; - gl.uniform3fv(currentShader.scale_loc, [1, 1, 1]); //.*** - var buildingGeoLocation = this.getNodeGeoLocDataManager(node).getCurrentGeoLocationData(); - //buildingGeoLocation = geoLocDataManager.getCurrentGeoLocationData(); - - gl.uniformMatrix4fv(currentShader.buildingRotMatrix_loc, false, buildingGeoLocation.rotMatrix._floatArrays); - gl.uniform3fv(currentShader.buildingPosHIGH_loc, buildingGeoLocation.positionHIGH); - gl.uniform3fv(currentShader.buildingPosLOW_loc, buildingGeoLocation.positionLOW); - gl.uniform3fv(currentShader.aditionalMov_loc, [0.0, 0.0, 0.0]); //.*** - - this.renderer.renderObject(gl, this.axisXYZ, this, currentShader, ssao_idx); - } - - if (currentShader) - { - if (currentShader.texCoord2_loc !== -1){ gl.disableVertexAttribArray(currentShader.texCoord2_loc); } - if (currentShader.position3_loc !== -1){ gl.disableVertexAttribArray(currentShader.position3_loc); } - if (currentShader.normal3_loc !== -1){ gl.disableVertexAttribArray(currentShader.normal3_loc); } - if (currentShader.color4_loc !== -1){ gl.disableVertexAttribArray(currentShader.color4_loc); } - } - - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, null); // original.*** - gl.activeTexture(gl.TEXTURE1); - gl.bindTexture(gl.TEXTURE_2D, null); - gl.activeTexture(gl.TEXTURE2); - gl.bindTexture(gl.TEXTURE_2D, null); - - gl.disable(gl.BLEND); -}; + _classCallCheck(this, PluralResolver); -/** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param cameraPosition 카메라 입장에서 화면에 그리기 전에 객체를 그릴 필요가 있는지 유무를 판단하는 값 - * @param scene 변수 - * @param shader 변수 - * @param renderTexture 변수 - * @param ssao_idx 변수 - * @param neoRefLists_array 변수 - */ + this.languageUtils = languageUtils; + this.options = options; + this.logger = baseLogger.create('pluralResolver'); + this.rules = createRules(); + } -MagoManager.prototype.depthRenderLowestOctreeAsimetricVersion = function(gl, ssao_idx, visibleObjControlerNodes) -{ - // ssao_idx = -1 -> pickingMode.*** - // ssao_idx = 0 -> depth.*** - // ssao_idx = 1 -> ssao.*** - var currentShader; - var shaderProgram; - var renderTexture = false; - - var nodesLOD0Count = visibleObjControlerNodes.currentVisibles0.length; - if (nodesLOD0Count > 0) - { - // LOD 0. Render detailed.*** - currentShader = this.postFxShadersManager.pFx_shaders_array[3]; // neo depth.*** - shaderProgram = currentShader.program; + _createClass(PluralResolver, [{ + key: "addRule", + value: function addRule(lng, obj) { + this.rules[lng] = obj; + } + }, { + key: "getRule", + value: function getRule(code) { + return this.rules[code] || this.rules[this.languageUtils.getLanguagePartFromCode(code)]; + } + }, { + key: "needsPlural", + value: function needsPlural(code) { + var rule = this.getRule(code); + return rule && rule.numbers.length > 1; + } + }, { + key: "getPluralFormsOfKey", + value: function getPluralFormsOfKey(code, key) { + var _this = this; + + var ret = []; + var rule = this.getRule(code); + if (!rule) return ret; + rule.numbers.forEach(function (n) { + var suffix = _this.getSuffix(code, n); + + ret.push("".concat(key).concat(suffix)); + }); + return ret; + } + }, { + key: "getSuffix", + value: function getSuffix(code, count) { + var _this2 = this; + + var rule = this.getRule(code); + + if (rule) { + // if (rule.numbers.length === 1) return ''; // only singular + var idx = rule.noAbs ? rule.plurals(count) : rule.plurals(Math.abs(count)); + var suffix = rule.numbers[idx]; // special treatment for lngs only having singular and plural + + if (this.options.simplifyPluralSuffix && rule.numbers.length === 2 && rule.numbers[0] === 1) { + if (suffix === 2) { + suffix = 'plural'; + } else if (suffix === 1) { + suffix = ''; + } + } - gl.useProgram(shaderProgram); - gl.enableVertexAttribArray(currentShader.position3_loc); + var returnSuffix = function returnSuffix() { + return _this2.options.prepend && suffix.toString() ? _this2.options.prepend + suffix.toString() : suffix.toString(); + }; // COMPATIBILITY JSON + // v1 + + + if (this.options.compatibilityJSON === 'v1') { + if (suffix === 1) return ''; + if (typeof suffix === 'number') return "_plural_".concat(suffix.toString()); + return returnSuffix(); + } else if ( + /* v2 */ + this.options.compatibilityJSON === 'v2') { + return returnSuffix(); + } else if ( + /* v3 - gettext index */ + this.options.simplifyPluralSuffix && rule.numbers.length === 2 && rule.numbers[0] === 1) { + return returnSuffix(); + } - gl.uniformMatrix4fv(currentShader.modelViewProjectionMatrix4RelToEye_loc, false, this.sceneState.modelViewProjRelToEyeMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.modelViewMatrix4RelToEye_loc, false, this.sceneState.modelViewRelToEyeMatrix._floatArrays); // original.*** - gl.uniformMatrix4fv(currentShader.modelViewMatrix4_loc, false, this.sceneState.modelViewMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.projectionMatrix4_loc, false, this.sceneState.projectionMatrix._floatArrays); - gl.uniform3fv(currentShader.cameraPosHIGH_loc, this.sceneState.encodedCamPosHigh); - gl.uniform3fv(currentShader.cameraPosLOW_loc, this.sceneState.encodedCamPosLow); + return this.options.prepend && idx.toString() ? this.options.prepend + idx.toString() : idx.toString(); + } - gl.uniform1f(currentShader.near_loc, this.sceneState.camera.frustum.near); - gl.uniform1f(currentShader.far_loc, this.sceneState.camera.frustum.far); + this.logger.warn("no plural rule found for: ".concat(code)); + return ''; + } + }]); - // renderDepth for all buildings.*** - // 1) LOD 0 & LOD1.********************************************************************************************************************* - var refTMatrixIdxKey = 0; - var minSize = 0.0; - //if (this.isLastFrustum) - { - this.renderer.renderNodes(gl, visibleObjControlerNodes.currentVisibles0, this, currentShader, renderTexture, ssao_idx, minSize, 0, refTMatrixIdxKey); - } - - if (currentShader.position3_loc !== -1) - { gl.disableVertexAttribArray(currentShader.position3_loc); } - } - - // 2) LOD 2 .************************************************************************************************************************************ - var nodesLOD2Count = visibleObjControlerNodes.currentVisibles2.length; - if (nodesLOD2Count > 0 || nodesLOD0Count > 0) - { - currentShader = this.postFxShadersManager.pFx_shaders_array[7]; // lodBuilding depth.*** - shaderProgram = currentShader.program; - gl.useProgram(shaderProgram); - gl.enableVertexAttribArray(currentShader.position3_loc); + return PluralResolver; + }(); - gl.uniformMatrix4fv(currentShader.modelViewProjectionMatrix4RelToEye_loc, false, this.sceneState.modelViewProjRelToEyeMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.modelViewMatrix4RelToEye_loc, false, this.sceneState.modelViewRelToEyeMatrix._floatArrays); // original.*** - gl.uniformMatrix4fv(currentShader.modelViewMatrix4_loc, false, this.sceneState.modelViewMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.projectionMatrix4_loc, false, this.sceneState.projectionMatrix._floatArrays); - gl.uniform3fv(currentShader.cameraPosHIGH_loc, this.sceneState.encodedCamPosHigh); - gl.uniform3fv(currentShader.cameraPosLOW_loc, this.sceneState.encodedCamPosLow); + var Interpolator = + /*#__PURE__*/ + function () { + function Interpolator() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - gl.uniform1f(currentShader.near_loc, this.sceneState.camera.frustum.near); - gl.uniform1f(currentShader.far_loc, this.sceneState.camera.frustum.far); + _classCallCheck(this, Interpolator); - gl.uniform1i(currentShader.hasAditionalMov_loc, true); - gl.uniform3fv(currentShader.aditionalMov_loc, [0.0, 0.0, 0.0]); //.*** - - this.renderer.renderNeoBuildingsLOD2AsimetricVersion(gl, visibleObjControlerNodes.currentVisibles0, this, currentShader, renderTexture, ssao_idx); - this.renderer.renderNeoBuildingsLOD2AsimetricVersion(gl, visibleObjControlerNodes.currentVisibles2, this, currentShader, renderTexture, ssao_idx); + this.logger = baseLogger.create('interpolator'); + this.init(options, true); + } + /* eslint no-param-reassign: 0 */ - if (currentShader.position3_loc !== -1) - { gl.disableVertexAttribArray(currentShader.position3_loc); } - } - - // 3) LOD3, LOD4, LOD5.************************************************************************************************************************* - var nodesLOD3Count = visibleObjControlerNodes.currentVisibles3.length; - if (nodesLOD3Count > 0) - { - currentShader = this.postFxShadersManager.pFx_shaders_array[7]; // lodBuilding depth.*** - shaderProgram = currentShader.program; - gl.useProgram(shaderProgram); - gl.enableVertexAttribArray(currentShader.position3_loc); - gl.uniformMatrix4fv(currentShader.modelViewProjectionMatrix4RelToEye_loc, false, this.sceneState.modelViewProjRelToEyeMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.modelViewMatrix4RelToEye_loc, false, this.sceneState.modelViewRelToEyeMatrix._floatArrays); // original.*** - gl.uniformMatrix4fv(currentShader.modelViewMatrix4_loc, false, this.sceneState.modelViewMatrix._floatArrays); - gl.uniformMatrix4fv(currentShader.projectionMatrix4_loc, false, this.sceneState.projectionMatrix._floatArrays); - gl.uniform3fv(currentShader.cameraPosHIGH_loc, this.sceneState.encodedCamPosHigh); - gl.uniform3fv(currentShader.cameraPosLOW_loc, this.sceneState.encodedCamPosLow); + _createClass(Interpolator, [{ + key: "init", + value: function init() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var reset = arguments.length > 1 ? arguments[1] : undefined; - gl.uniform1f(currentShader.near_loc, this.sceneState.camera.frustum.near); - gl.uniform1f(currentShader.far_loc, this.sceneState.camera.frustum.far); + if (reset) { + this.options = options; - gl.uniform1i(currentShader.hasAditionalMov_loc, true); - gl.uniform3fv(currentShader.aditionalMov_loc, [0.0, 0.0, 0.0]); //.*** - - this.renderer.renderNeoBuildingsLowLOD(gl, visibleObjControlerNodes.currentVisibles3, this, currentShader, renderTexture, ssao_idx); + this.format = options.interpolation && options.interpolation.format || function (value) { + return value; + }; + } - if (currentShader.position3_loc !== -1) - { gl.disableVertexAttribArray(currentShader.position3_loc); } - } - - // tin terrain.*** - if (this.tinTerrainManager !== undefined) - { - currentShader = this.postFxShadersManager.getShader("tinTerrain"); - shaderProgram = currentShader.program; - - gl.useProgram(shaderProgram); - gl.enableVertexAttribArray(currentShader.position3_loc); - gl.disableVertexAttribArray(currentShader.texCoord2_loc); - //gl.disableVertexAttribArray(currentShader.normal3_loc); - //gl.disableVertexAttribArray(currentShader.color4_loc); - - currentShader.bindUniformGenerals(); + if (!options.interpolation) options.interpolation = { + escapeValue: true + }; + var iOpts = options.interpolation; + this.escape = iOpts.escape !== undefined ? iOpts.escape : escape; + this.escapeValue = iOpts.escapeValue !== undefined ? iOpts.escapeValue : true; + this.useRawValueToEscape = iOpts.useRawValueToEscape !== undefined ? iOpts.useRawValueToEscape : false; + this.prefix = iOpts.prefix ? regexEscape(iOpts.prefix) : iOpts.prefixEscaped || '{{'; + this.suffix = iOpts.suffix ? regexEscape(iOpts.suffix) : iOpts.suffixEscaped || '}}'; + this.formatSeparator = iOpts.formatSeparator ? iOpts.formatSeparator : iOpts.formatSeparator || ','; + this.unescapePrefix = iOpts.unescapeSuffix ? '' : iOpts.unescapePrefix || '-'; + this.unescapeSuffix = this.unescapePrefix ? '' : iOpts.unescapeSuffix || ''; + this.nestingPrefix = iOpts.nestingPrefix ? regexEscape(iOpts.nestingPrefix) : iOpts.nestingPrefixEscaped || regexEscape('$t('); + this.nestingSuffix = iOpts.nestingSuffix ? regexEscape(iOpts.nestingSuffix) : iOpts.nestingSuffixEscaped || regexEscape(')'); + this.maxReplaces = iOpts.maxReplaces ? iOpts.maxReplaces : 1000; // the regexp + + this.resetRegExp(); + } + }, { + key: "reset", + value: function reset() { + if (this.options) this.init(this.options); + } + }, { + key: "resetRegExp", + value: function resetRegExp() { + // the regexp + var regexpStr = "".concat(this.prefix, "(.+?)").concat(this.suffix); + this.regexp = new RegExp(regexpStr, 'g'); + var regexpUnescapeStr = "".concat(this.prefix).concat(this.unescapePrefix, "(.+?)").concat(this.unescapeSuffix).concat(this.suffix); + this.regexpUnescape = new RegExp(regexpUnescapeStr, 'g'); + var nestingRegexpStr = "".concat(this.nestingPrefix, "(.+?)").concat(this.nestingSuffix); + this.nestingRegexp = new RegExp(nestingRegexpStr, 'g'); + } + }, { + key: "interpolate", + value: function interpolate(str, data, lng, options) { + var _this = this; - var tex = this.pin.texturesArray[4]; - gl.activeTexture(gl.TEXTURE2); - gl.bindTexture(gl.TEXTURE_2D, tex.texId); - - gl.uniform1i(currentShader.bIsMakingDepth_loc, true); //.*** - gl.uniform1i(currentShader.hasTexture_loc, true); //.*** - gl.uniform4fv(currentShader.oneColor4_loc, [0.5, 0.5, 0.5, 1.0]); - - //gl.enable(gl.POLYGON_OFFSET_FILL); - //gl.polygonOffset(1, 3); - - var renderWireframe = false; - var tinTerrain; - var currentTerrainsMap = this.tinTerrainManager.currentTerrainsMap; - var currentVisiblesTerrainsMap = this.tinTerrainManager.currentVisibles_terrName_geoCoords_map; - for (var key in currentVisiblesTerrainsMap) - { - //currentVisiblesTerrainsMap - tinTerrain = currentTerrainsMap[key]; - if (tinTerrain === undefined) - { continue; } - - if (tinTerrain.vboKeyContainer === undefined || tinTerrain.vboKeyContainer.vboCacheKeysArray.length === 0) - { continue; } + var match; + var value; + var replaces; - // check the texture of the terrain.*** - //if (tinTerrain.texture === undefined) - //{ - // tinTerrain.texture = new Texture(); - // var imagesDataPath = "\\images\\ko"; - // var textureFilePath = imagesDataPath + "\\funny_" + tinTerrain.depth + ".jpg"; - // this.readerWriter.readLegoSimpleBuildingTexture(gl, textureFilePath, tinTerrain.texture, this); - // continue; - //} - - gl.uniform3fv(currentShader.buildingPosHIGH_loc, tinTerrain.terrainPositionHIGH); - gl.uniform3fv(currentShader.buildingPosLOW_loc, tinTerrain.terrainPositionLOW); - - //this.renderer.renderNeoBuildingsLOD2AsimetricVersion(gl, visibleObjControlerNodes.currentVisibles0, this, currentShader, renderTexture, ssao_idx); // lod 0.*** - var vboKey = tinTerrain.vboKeyContainer.vboCacheKeysArray[0]; - if (vboKey.isReadyPositions(gl, this.vboMemoryManager) && vboKey.isReadyTexCoords(gl, this.vboMemoryManager) && vboKey.isReadyFaces(gl, this.vboMemoryManager)) - { - // Positions.*** - gl.bindBuffer(gl.ARRAY_BUFFER, vboKey.meshVertexCacheKey); - gl.vertexAttribPointer(currentShader.position3_loc, 3, gl.FLOAT, false, 0, 0); - - var indicesCount = vboKey.indicesCount; + function regexSafe(val) { + return val.replace(/\$/g, '$$$$'); + } - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vboKey.meshFacesCacheKey); - - if (renderWireframe) - { - var trianglesCount = indicesCount; - for (var i=0; i= this.maxReplaces) { + break; + } + } - gl.attachShader(shader.program, shader.shader_vertex); - gl.attachShader(shader.program, shader.shader_fragment); - gl.linkProgram(shader.program); - - shader.createUniformGenerals(gl, shader, this.sceneState); - shader.createUniformLocals(gl, shader, this.sceneState); - - // 3) TinTerrain shader.**************************************************************************************** - shaderName = "tinTerrain"; - shader = this.postFxShadersManager.newShader(shaderName); - ssao_vs_source = ShaderSource.TinTerrainVS; - ssao_fs_source = ShaderSource.TinTerrainFS; - - shader.program = gl.createProgram(); - shader.shader_vertex = this.postFxShadersManager.createShader(gl, ssao_vs_source, gl.VERTEX_SHADER, "VERTEX"); - shader.shader_fragment = this.postFxShadersManager.createShader(gl, ssao_fs_source, gl.FRAGMENT_SHADER, "FRAGMENT"); + replaces = 0; // regular escape on demand - gl.attachShader(shader.program, shader.shader_vertex); - gl.attachShader(shader.program, shader.shader_fragment); - gl.linkProgram(shader.program); - - shader.createUniformGenerals(gl, shader, this.sceneState); - shader.createUniformLocals(gl, shader, this.sceneState); - shader.bIsMakingDepth_loc = gl.getUniformLocation(shader.program, "bIsMakingDepth"); - - // 4) PointsCloud shader.**************************************************************************************** - shaderName = "pointsCloud"; - shader = this.postFxShadersManager.newShader(shaderName); - ssao_vs_source = ShaderSource.PointCloudVS; - ssao_fs_source = ShaderSource.PointCloudFS; - - shader.program = gl.createProgram(); - shader.shader_vertex = this.postFxShadersManager.createShader(gl, ssao_vs_source, gl.VERTEX_SHADER, "VERTEX"); - shader.shader_fragment = this.postFxShadersManager.createShader(gl, ssao_fs_source, gl.FRAGMENT_SHADER, "FRAGMENT"); + while (match = this.regexp.exec(str)) { + value = handleFormat(match[1].trim()); - gl.attachShader(shader.program, shader.shader_vertex); - gl.attachShader(shader.program, shader.shader_fragment); - gl.linkProgram(shader.program); - - shader.createUniformGenerals(gl, shader, this.sceneState); - shader.createUniformLocals(gl, shader, this.sceneState); - - // pointsCloud shader locals.*** - shader.bPositionCompressed_loc = gl.getUniformLocation(shader.program, "bPositionCompressed"); - shader.minPosition_loc = gl.getUniformLocation(shader.program, "minPosition"); - shader.bboxSize_loc = gl.getUniformLocation(shader.program, "bboxSize"); - - /* - // 4) ModelReferences SimpleSsaoShader.****************************************************************************** - var shaderName = "modelRefSsaoSimple"; - var shader = this.postFxShadersManager.newShader(shaderName); - var ssao_vs_source = ShaderSource.ModelRefSsaoSimpleVS; - var ssao_fs_source = ShaderSource.ModelRefSsaoSimpleFS; + if (value === undefined) { + if (typeof missingInterpolationHandler === 'function') { + var temp = missingInterpolationHandler(str, match, options); + value = typeof temp === 'string' ? temp : ''; + } else { + this.logger.warn("missed to pass in variable ".concat(match[1], " for interpolating ").concat(str)); + value = ''; + } + } else if (typeof value !== 'string' && !this.useRawValueToEscape) { + value = makeString(value); + } - shader.program = gl.createProgram(); - shader.shader_vertex = this.postFxShadersManager.createShader(gl, ssao_vs_source, gl.VERTEX_SHADER, "VERTEX"); - shader.shader_fragment = this.postFxShadersManager.createShader(gl, ssao_fs_source, gl.FRAGMENT_SHADER, "FRAGMENT"); + value = this.escapeValue ? regexSafe(this.escape(value)) : regexSafe(value); + str = str.replace(match[0], value); + this.regexp.lastIndex = 0; + replaces++; - gl.attachShader(shader.program, shader.shader_vertex); - gl.attachShader(shader.program, shader.shader_fragment); - gl.linkProgram(shader.program); - - shader.createUniformGenerals(gl, shader, this.sceneState); - shader.createUniformLocals(gl, shader, this.sceneState); - - // 5) LodBuilding SimpleSsaoShader.*********************************************************************************** - shaderName = "lodBuildingSsaoSimple"; - shader = this.postFxShadersManager.newShader(shaderName); - ssao_vs_source = ShaderSource.LodBuildingSsaoVS; - ssao_fs_source = ShaderSource.LodBuildingSsaoSimpleFS; - - shader.program = gl.createProgram(); - shader.shader_vertex = this.postFxShadersManager.createShader(gl, ssao_vs_source, gl.VERTEX_SHADER, "VERTEX"); - shader.shader_fragment = this.postFxShadersManager.createShader(gl, ssao_fs_source, gl.FRAGMENT_SHADER, "FRAGMENT"); + if (replaces >= this.maxReplaces) { + break; + } + } - gl.attachShader(shader.program, shader.shader_vertex); - gl.attachShader(shader.program, shader.shader_fragment); - gl.linkProgram(shader.program); - - shader.createUniformGenerals(gl, shader, this.sceneState); - shader.createUniformLocals(gl, shader, this.sceneState); - - // 6) LodBuilding SimpleSsaoShader.*********************************************************************************** - shaderName = "lodBuildingSsaoSimpleCompressed"; - shader = this.postFxShadersManager.newShader(shaderName); - ssao_vs_source = ShaderSource.LodBuildingSsaoSimpleCompressVS; - ssao_fs_source = ShaderSource.LodBuildingSsaoSimpleCompressFS; - - shader.program = gl.createProgram(); - shader.shader_vertex = this.postFxShadersManager.createShader(gl, ssao_vs_source, gl.VERTEX_SHADER, "VERTEX"); - shader.shader_fragment = this.postFxShadersManager.createShader(gl, ssao_fs_source, gl.FRAGMENT_SHADER, "FRAGMENT"); + return str; + } + }, { + key: "nest", + value: function nest(str, fc) { + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var match; + var value; + + var clonedOptions = _objectSpread({}, options); + + clonedOptions.applyPostProcessor = false; // avoid post processing on nested lookup + // if value is something like "myKey": "lorem $(anotherKey, { "count": {{aValueInOptions}} })" + + function handleHasOptions(key, inheritedOptions) { + if (key.indexOf(',') < 0) return key; + var p = key.split(','); + key = p.shift(); + var optionsString = p.join(','); + optionsString = this.interpolate(optionsString, clonedOptions); + optionsString = optionsString.replace(/'/g, '"'); + + try { + clonedOptions = JSON.parse(optionsString); + if (inheritedOptions) clonedOptions = _objectSpread({}, inheritedOptions, clonedOptions); + } catch (e) { + this.logger.error("failed parsing options string in nesting for key ".concat(key), e); + } - gl.attachShader(shader.program, shader.shader_vertex); - gl.attachShader(shader.program, shader.shader_fragment); - gl.linkProgram(shader.program); - - shader.createUniformGenerals(gl, shader, this.sceneState); - shader.createUniformLocals(gl, shader, this.sceneState); - */ -}; + return key; + } // regular escape on demand -/** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param cameraPosition 카메라 입장에서 화면에 그리기 전에 객체를 그릴 필요가 있는지 유무를 판단하는 값 - * @param scene 변수 - * @param shader 변수 - * @param renderTexture 변수 - * @param ssao_idx 변수 - * @param neoRefLists_array 변수 - */ -MagoManager.prototype.renderLodBuilding = function(gl, cameraPosition, scene, shader, renderTexture, ssao_idx, lodBuilding) -{ - // file loaded but not parsed.*** - if (lodBuilding.fileLoadState === CODE.fileLoadState.LOADING_FINISHED) - { - lodBuilding.parseArrayBuffer(gl, this.readerWriter); - } - this.renderer.renderLodBuilding(gl, lodBuilding, this, shader, ssao_idx); -}; + while (match = this.nestingRegexp.exec(str)) { + value = fc(handleHasOptions.call(this, match[1].trim(), clonedOptions), clonedOptions); // is only the nesting key (key1 = '$(key2)') return the value without stringify -/** - * 어떤 일을 하고 있습니까? - * @param scene 변수 - */ -MagoManager.prototype.reCalculateModelViewProjectionRelToEyeMatrix = function(scene) -{ - for (var i=0; i<16; i++) - { - if (scene.context._us._modelView[i] === 0) { return; } - } + if (value && match[0] === str && typeof value !== 'string') return value; // no string to include or empty - var modelViewRelToEye = new Cesium.Matrix4(); - modelViewRelToEye = Cesium.Matrix4.clone(scene.context._us._modelView); - modelViewRelToEye[12] = 0.0; - modelViewRelToEye[13] = 0.0; - modelViewRelToEye[14] = 0.0; - var modelViewProjectionRelToEye = new Cesium.Matrix4(); - Cesium.Matrix4.multiply(scene.context._us._projection, modelViewRelToEye, modelViewProjectionRelToEye); - Cesium.Matrix4.toArray(modelViewProjectionRelToEye, this.modelViewProjRelToEye_matrix); -}; + if (typeof value !== 'string') value = makeString(value); -/** - * 어떤 일을 하고 있습니까? - * @param frustumVolume 변수 - * @param neoVisibleBuildingsArray 변수 - * @param cameraPosition 변수 - * @returns neoVisibleBuildingsArray - */ -MagoManager.prototype.deleteNeoBuilding = function(gl, neoBuilding) -{ - // check if the neoBuilding id the selected building.*** - var vboMemoryManager = this.vboMemoryManager; - if (neoBuilding === this.buildingSelected) - { - this.buildingSelected = undefined; - this.octreeSelected = undefined; - this.objectSelected = undefined; - } - - neoBuilding.deleteObjects(gl, vboMemoryManager); - -}; + if (!value) { + this.logger.warn("missed to resolve ".concat(match[1], " for nesting ").concat(str)); + value = ''; + } // Nested keys should not be escaped by default #854 + // value = this.escapeValue ? regexSafe(utils.escape(value)) : regexSafe(value); -/** - * 카메라 영역에 벗어난 오브젝트의 렌더링은 비 활성화 - * - * @param frustumVolume 변수 - * @param cameraPosition 변수 - */ -MagoManager.prototype.isFarestFrustum = function() -{ - if (this.numFrustums - this.currentFrustumIdx - 1 === 0) - { return true; } - else - { return false; } -}; -/** - * 카메라 영역에 벗어난 오브젝트의 렌더링은 비 활성화 - * - * @param frustumVolume 변수 - * @param cameraPosition 변수 - */ -MagoManager.prototype.doMultiFrustumCullingSmartTiles = function(camera) -{ - // Here uses a frustum that is the sum of all frustums.*** - var frustumVolume = this.myCameraSCX.bigFrustum; - - // This makes the visible buildings array. - var smartTile1 = this.smartTileManager.tilesArray[0]; // America side tile. - var smartTile2 = this.smartTileManager.tilesArray[1]; // Asia side tile. - - if (this.frustumVolumeControl === undefined) - { this.frustumVolumeControl = new FrustumVolumeControl(); } - - if (this.fullyIntersectedLowestTilesArray === undefined) - { this.fullyIntersectedLowestTilesArray = []; } + str = str.replace(match[0], value); + this.regexp.lastIndex = 0; + } - if (this.partiallyIntersectedLowestTilesArray === undefined) - { this.partiallyIntersectedLowestTilesArray = []; } - - if (this.lastIntersectedLowestTilesArray === undefined) - { this.lastIntersectedLowestTilesArray = []; } - - // save the last frustumCulled lowestTiles to delete if necessary. - this.lastIntersectedLowestTilesArray.push.apply(this.lastIntersectedLowestTilesArray, this.fullyIntersectedLowestTilesArray); - this.lastIntersectedLowestTilesArray.push.apply(this.lastIntersectedLowestTilesArray, this.partiallyIntersectedLowestTilesArray); - - // mark all last_tiles as "no visible". - var lastLowestTilesCount = this.lastIntersectedLowestTilesArray.length; - var lowestTile; - for (var i=0; i= 0 ; j--) - { - frustum = this.myCameraSCX.frustumsArray[j]; - if (frustum.intersectionNearFarSphere(lowestTile.sphereExtent) !== Constant.INTERSECTION_OUTSIDE) - { - var frustumVolumeControlObject = this.frustumVolumeControl.getFrustumVolumeCulling(j); - frustumVolumeControlObject.fullyIntersectedLowestTilesArray.push(lowestTile); - //break; - } - } - } - - currentLowestTilesCount = this.partiallyIntersectedLowestTilesArray.length; - for (var i=0; i= 0 ; j--) - { - frustum = this.myCameraSCX.frustumsArray[j]; - if (frustum.intersectionNearFarSphere(lowestTile.sphereExtent) !== Constant.INTERSECTION_OUTSIDE) - { - var frustumVolumeControlObject = this.frustumVolumeControl.getFrustumVolumeCulling(j); - frustumVolumeControlObject.partiallyIntersectedLowestTilesArray.push(lowestTile); - //break; - } - } - } - - // Now, delete all tiles that is no visible in the all frustumVolumes.*** - // Put to deleting queue.*** - var lastLowestTilesCount = this.lastIntersectedLowestTilesArray.length; - var lowestTile; - for (var i=0; i Number(lod5_minDist)) - { continue; } + while (found !== -1) { + arr.splice(found, 1); + found = arr.indexOf(what); + } + } - if (lowestTile.nodesArray && lowestTile.nodesArray.length > 0) - { - // the neoBuildings is made. - var nodesCount = lowestTile.nodesArray.length; - for (var j=0; j frustumFar) - { - // put this node to delete into queue.*** - this.processQueue.putNodeToDelete(node, 0); - continue; - } - - // If necessary do frustum culling.************************************************************************* - if (doFrustumCullingToBuildings) - { - var frustumCull = frustumVolume.intersectionSphere(this.boundingSphere_Aux); // cesium.*** - // intersect with Frustum - if (frustumCull === Constant.INTERSECTION_OUTSIDE) - { - // put this node to delete into queue.*** - //this.processQueue.putNodeToDeleteModelReferences(node, 0); - this.processQueue.putNodeToDeleteLessThanLod3(node, 0); - continue; - } - } - //------------------------------------------------------------------------------------------- - - // provisionally fork versions.*** - var version = neoBuilding.getHeaderVersion(); - if (version === undefined) - { continue; } - - if (version[0] === 'v') - { - if (distToCamera < lod0_minDist) - { - visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles0, node); - } - else if (distToCamera < lod1_minDist) - { - visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles1, node); - } - else if (distToCamera < lod2_minDist) - { - visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles2, node); - } - else if (distToCamera < lod5_minDist) - { - visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles3, node); - } - } - else - { - // provisional test for pointsCloud data.************ - var metaData = neoBuilding.metaData; - var projectsType = metaData.projectDataType; - if (projectsType && projectsType === 4) - { - // Project_data_type (new in version 002).*** - // 1 = 3d model data type (normal 3d with interior & exterior data).*** - // 2 = single building skin data type (as vWorld or googleEarth data).*** - // 3 = multi building skin data type (as Shibuya & Odaiba data).*** - // 4 = pointsCloud data type.*** - visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisiblesAux, node); - } - // end provisional test.----------------------------- - else - { - if (distToCamera < lod0_minDist) - { - // check if the lod0, lod1, lod2 are modelReference type.*** - var lodBuildingData = neoBuilding.getLodBuildingData(0); - if (lodBuildingData && lodBuildingData.isModelRef) - { - visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles0, node); - } - else - { - visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles3, node); - } - } - else if (distToCamera < lod1_minDist) - { - var lodBuildingData = neoBuilding.getLodBuildingData(1); - if (lodBuildingData && lodBuildingData.isModelRef) - { - visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles1, node); - } - else - { - visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles3, node); - } - } - else if (distToCamera < lod2_minDist) - { - var lodBuildingData = neoBuilding.getLodBuildingData(2); - if (lodBuildingData && lodBuildingData.isModelRef) - { - visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles2, node); - } - else - { - visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles3, node); - } - } - else if (distToCamera < lod5_minDist) - { - visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles3, node); - } - } - } - } - - if (lowestTile.nodesArray.length !== lowestTile.nodeSeedsArray.length) - { - // create the buildings by buildingSeeds. - this.createBuildingsByBuildingSeedsOnLowestTile(lowestTile); - } - } - else - { - // create the buildings by buildingSeeds. - this.createBuildingsByBuildingSeedsOnLowestTile(lowestTile); - } - } -}; + var Connector = + /*#__PURE__*/ + function (_EventEmitter) { + _inherits(Connector, _EventEmitter); -/** - * dataKey 이용해서 data 검색 - * @param dataKey - */ -MagoManager.prototype.testAproxDist3D = function() -{ - // test: AproxDistance: - var distCalculationTimeAmount = 0; - var aproxDistCalculationTimeAmount = 0; - var squaredDistCalculationTimeAmount = 0; - - var pointA = new Point3D(); - var pointB = new Point3D(); - - var difX, difY, difZ; - - - - var aproxDist, realDist, squaredDist, startTime, endTime; - startTime = new Date().getTime(); - for (var k=0; k<1000000; k++) - { - pointA.set(Math.random()*1000.0, Math.random()*1000.0, Math.random()*1000.0); - pointB.set(Math.random()*1000.0, Math.random()*1000.0, Math.random()*1000.0); - squaredDist = pointA.squareDistToPoint(pointB); - //difX = pointA.x - pointB.x; - //difY = pointA.y - pointB.y; - //difZ = pointA.z - pointB.z; - //realDist = difX*difX + difY*difY + difZ*difZ; - } - endTime = new Date().getTime(); - squaredDistCalculationTimeAmount += (endTime - startTime)/1000; - - - startTime = new Date().getTime(); - for (var k=0; k<1000000; k++) - { - pointA.set(Math.random()*1000.0, Math.random()*1000.0, Math.random()*1000.0); - pointB.set(Math.random()*1000.0, Math.random()*1000.0, Math.random()*1000.0); - //aproxDist = this.calculateAproxDist3D(pointA, pointB); - aproxDist = pointA.aproxDistTo(pointB, this.sqrtTable); - //aproxDist = this.managerUtil.calculateAproxDist3D(pointA, pointB); - //aproxDist = ManagerUtils.calculateAproxDist3D(pointA, pointB); - } - endTime = new Date().getTime(); - aproxDistCalculationTimeAmount += (endTime - startTime)/1000; - - - startTime = new Date().getTime(); - for (var k=0; k<1000000; k++) - { - pointA.set(Math.random()*1000.0, Math.random()*1000.0, Math.random()*1000.0); - pointB.set(Math.random()*1000.0, Math.random()*1000.0, Math.random()*1000.0); - realDist = pointA.distToPoint(pointB); - //difX = pointA.x - pointB.x; - //difY = pointA.y - pointB.y; - //difZ = pointA.z - pointB.z; - //realDist = Math.sqrt(difX*difX + difY*difY + difZ*difZ ); - } - endTime = new Date().getTime(); - distCalculationTimeAmount += (endTime - startTime)/1000; - - // test. check the calculation time difference. - distCalculationTimeAmount; - aproxDistCalculationTimeAmount; - squaredDistCalculationTimeAmount; - - var ratio = aproxDistCalculationTimeAmount/distCalculationTimeAmount *100; - var error = (aproxDist - realDist)/realDist * 100; - -}; + function Connector(backend, store, services) { + var _this; -/** - * dataKey 이용해서 data 검색 - * @param dataKey - */ -MagoManager.prototype.calculateAproxDist3D = function(pointA, pointB) -{ - // test function. - var difX = Math.abs(pointA.x - pointB.x); - var difY = Math.abs(pointA.y - pointB.y); - var difZ = Math.abs(pointA.z - pointB.z); + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; - - // find the big value. - var maxValue, value1, value2; - var value1Idx, value2Idx; - var aproxDist; - var tableValuesCount = 10; + _classCallCheck(this, Connector); - if (difX > difY) - { - if (difX > difZ) - { - maxValue = difX; - value1 = difY/maxValue; - //value1Idx = Math.floor(value1*100); - value1Idx = ~~(value1*tableValuesCount); - var middleDist = maxValue * this.sqrtTable[value1Idx]; - value2 = difZ/middleDist; - //value2Idx = Math.floor(value2*100); - value2Idx = ~~(value2*tableValuesCount); - return (middleDist * this.sqrtTable[value2Idx]); - } - else - { - maxValue = difZ; - value1 = difX/maxValue; - //value1Idx = Math.floor(value1*100); - value1Idx = ~~(value1*tableValuesCount); - var middleDist = maxValue * this.sqrtTable[value1Idx]; - value2 = difY/middleDist; - //value2Idx = Math.floor(value2*100); - value2Idx = ~~(value2*tableValuesCount); - return (middleDist * this.sqrtTable[value2Idx]); - } - } - else - { - if (difY > difZ) - { - maxValue = difY; - value1 = difX/maxValue; - //value1Idx = Math.floor(value1*100); - value1Idx = ~~(value1*tableValuesCount); - var middleDist = maxValue * this.sqrtTable[value1Idx]; - value2 = difZ/middleDist; - //value2Idx = Math.floor(value2*100); - value2Idx = ~~(value2*tableValuesCount); - return (middleDist * this.sqrtTable[value2Idx]); - } - else - { - maxValue = difZ; - value1 = difX/maxValue; - //value1Idx = Math.floor(value1*100); - value1Idx = ~~(value1*tableValuesCount); - var middleDist = maxValue * this.sqrtTable[value1Idx]; - value2 = difY/middleDist; - //value2Idx = Math.floor(value2*100); - value2Idx = ~~(value2*tableValuesCount); - return (middleDist * this.sqrtTable[value2Idx]); - } - } - -}; + _this = _possibleConstructorReturn(this, _getPrototypeOf(Connector).call(this)); + EventEmitter.call(_assertThisInitialized(_assertThisInitialized(_this))); // <=IE10 fix (unable to call parent constructor) -/** - * dataKey 이용해서 data 검색 - * @param dataKey - */ -MagoManager.prototype.createBuildingsByBuildingSeedsOnLowestTile = function(lowestTile) -{ - // create the buildings by buildingSeeds. - var node; - var neoBuilding; - var nodeBbox; - var buildingSeed; - var startIndex = 0; - - // if exist nodesArray (there are buildings) and add a nodeSeed, we must make nodes of the added nodeSeeds.*** - if (lowestTile.nodesArray) - { startIndex = lowestTile.nodesArray.length; } - - var nodeSeedsCount = lowestTile.nodeSeedsArray.length; - for (var j=startIndex; j this.emit('loaded', q.loaded); + Object.keys(q.loaded).forEach(function (l) { + if (!loaded[l]) loaded[l] = []; - if (realBuildingPos === undefined) - { return; } + if (q.loaded[l].length) { + q.loaded[l].forEach(function (ns) { + if (loaded[l].indexOf(ns) < 0) loaded[l].push(ns); + }); + } + }); + /* eslint no-param-reassign: 0 */ - this.radiusAprox_aux = nodeRoot.data.bbox.getRadiusAprox(); + q.done = true; - if (this.boundingSphere_Aux === undefined) - { this.boundingSphere_Aux = new Sphere(); } - - this.boundingSphere_Aux.radius = this.radiusAprox_aux; + if (q.errors.length) { + q.callback(q.errors); + } else { + q.callback(); + } + } + }); // emit consolidated loaded event - if (this.configInformation.geo_view_library === Constant.CESIUM) - { - this.boundingSphere_Aux.center = Cesium.Cartesian3.clone(realBuildingPos); - var seconds = 3; - this.scene.camera.flyToBoundingSphere(this.boundingSphere_Aux, seconds); - } - else if (this.configInformation.geo_view_library === Constant.WORLDWIND) - { - var geographicCoord = buildingSeed.geographicCoordOfBBox; - this.wwd.goToAnimator.travelTime = 3000; - this.wwd.goTo(new WorldWind.Position(geographicCoord.latitude, geographicCoord.longitude, geographicCoord.altitude + 1000)); - } -}; + this.emit('loaded', loaded); // remove done load requests + this.queue = this.queue.filter(function (q) { + return !q.done; + }); + } + }, { + key: "read", + value: function read(lng, ns, fcName) { + var _this3 = this; + + var tried = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; + var wait = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 250; + var callback = arguments.length > 5 ? arguments[5] : undefined; + if (!lng.length) return callback(null, {}); // noting to load + + return this.backend[fcName](lng, ns, function (err, data) { + if (err && data + /* = retryFlag */ + && tried < 5) { + setTimeout(function () { + _this3.read.call(_this3, lng, ns, fcName, tried + 1, wait * 2, callback); + }, wait); + return; + } -/** - * 어떤 일을 하고 있습니까? - */ -MagoManager.prototype.getNeoBuildingById = function(buildingType, buildingId) -{ - var resultNeoBuilding = this.smartTileManager.getNeoBuildingById(buildingType, buildingId); - return resultNeoBuilding; -}; + callback(err, data); + }); + } + /* eslint consistent-return: 0 */ -/** - * 어떤 일을 하고 있습니까? - */ -MagoManager.prototype.getBuildingSeedById = function(buildingType, buildingId) -{ - var resultNeoBuildingSeed = this.smartTileManager.getBuildingSeedById(buildingType, buildingId); - return resultNeoBuildingSeed; -}; + }, { + key: "prepareLoading", + value: function prepareLoading(languages, namespaces) { + var _this4 = this; -/** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param frustumVolume 변수 - * @param visibleBuildings_array 변수 - * @param cameraPosition 변수 - * @returns visibleBuildings_array - */ -MagoManager.prototype.doFrustumCullingTerranTileServiceFormat = function(gl, frustumVolume, visibleBuildings_array, cameraPosition) -{ - // This makes the visible buildings array.*** - // This has Cesium dependency because uses the frustumVolume and the boundingSphere of cesium.*** - //--------------------------------------------------------------------------------------------------------- - // Note: in this function, we do frustum culling and determine the detailedBuilding in same time.*** + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + var callback = arguments.length > 3 ? arguments[3] : undefined; - // Init the visible buildings array.*************************** - //visibleBuildings_array.length = 0; // Init.*** - //this.currentVisibleBuildings_LOD0_array.length = 0; // Init.*** - //this.detailed_building; + if (!this.backend) { + this.logger.warn('No backend was added via i18next.use. Will not load resources.'); + return callback && callback(); + } - var squaredDistToCamera; - // var squaredDistToCamera_candidate; - var last_squared_dist; - var buildings_count; - // var nearestTile; - // var nearestTile_candidate; + if (typeof languages === 'string') languages = this.languageUtils.toResolveHierarchy(languages); + if (typeof namespaces === 'string') namespaces = [namespaces]; + var toLoad = this.queueLoad(languages, namespaces, options, callback); - this.filteredVisibleTiles_array.length = 0; - this.detailedVisibleTiles_array.length = 0; - this.LOD0VisibleTiles_array.length = 0; + if (!toLoad.toLoad.length) { + if (!toLoad.pending.length) callback(); // nothing to load and no pendings...callback now - var BR_Project; + return null; // pendings will trigger callback + } - var max_tileFilesReading = 10; + toLoad.toLoad.forEach(function (name) { + _this4.loadOne(name); + }); + } + }, { + key: "load", + value: function load(languages, namespaces, callback) { + this.prepareLoading(languages, namespaces, {}, callback); + } + }, { + key: "reload", + value: function reload(languages, namespaces, callback) { + this.prepareLoading(languages, namespaces, { + reload: true + }, callback); + } + }, { + key: "loadOne", + value: function loadOne(name) { + var _this5 = this; - this.currentVisible_terranTiles_array.length = 0;// Init.*** - this.terranTile.getIntersectedSmallestTiles(frustumVolume, this.currentVisible_terranTiles_array, this.boundingSphere_Aux); + var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; - // Find the nearest tile to camera.*** - var visibleTiles_count = this.currentVisible_terranTiles_array.length; - if (visibleTiles_count === 0) { return; } + var _name$split3 = name.split('|'), + _name$split4 = _slicedToArray(_name$split3, 2), + lng = _name$split4[0], + ns = _name$split4[1]; - for (var i=0; i this.min_squaredDist_to_see) { continue; } + _this5.loaded(name, err, data); + }); + } + }, { + key: "saveMissing", + value: function saveMissing(languages, namespace, key, fallbackValue, isUpdate) { + var options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {}; + + if (this.backend && this.backend.create) { + this.backend.create(languages, namespace, key, fallbackValue, null + /* unused callback */ + , _objectSpread({}, options, { + isUpdate: isUpdate + })); + } // write to store to avoid resending + + + if (!languages || !languages[0]) return; + this.store.addResource(languages[0], namespace, key, fallbackValue); + } + }]); - if (squaredDistToCamera < this.min_squaredDist_to_see_detailed * 1.2) - { - this.detailedVisibleTiles_array.push(this.terranTileSC); - } - else if (squaredDistToCamera < this.min_squaredDist_to_see_LOD0 * 1.2) - { - this.LOD0VisibleTiles_array.push(this.terranTileSC); - } - else - { - this.filteredVisibleTiles_array.push(this.terranTileSC); // Original.*** - //this.LOD0VisibleTiles_array.push(this.terranTileSC); // Test.*** - } - } + return Connector; + }(EventEmitter); - // Make the visible buildings list.****************************************************************************** - this.boundingSphere_Aux.radius = 50.0; - var need_frustumCulling = false; - var filePath_scratch; - var tileNumberNameString; + function get() { + return { + debug: false, + initImmediate: true, + ns: ['translation'], + defaultNS: ['translation'], + fallbackLng: ['dev'], + fallbackNS: false, + // string or array of namespaces + whitelist: false, + // array with whitelisted languages + nonExplicitWhitelist: false, + load: 'all', + // | currentOnly | languageOnly + preload: false, + // array with preload languages + simplifyPluralSuffix: true, + keySeparator: '.', + nsSeparator: ':', + pluralSeparator: '_', + contextSeparator: '_', + partialBundledLanguages: false, + // allow bundling certain languages that are not remotely fetched + saveMissing: false, + // enable to send missing values + updateMissing: false, + // enable to update default values if different from translated value (only useful on initial development, or when keeping code as source of truth) + saveMissingTo: 'fallback', + // 'current' || 'all' + saveMissingPlurals: true, + // will save all forms not only singular key + missingKeyHandler: false, + // function(lng, ns, key, fallbackValue) -> override if prefer on handling + missingInterpolationHandler: false, + // function(str, match) + postProcess: false, + // string or array of postProcessor names + returnNull: true, + // allows null value as valid translation + returnEmptyString: true, + // allows empty string value as valid translation + returnObjects: false, + joinArrays: false, + // or string to join array + returnedObjectHandler: function returnedObjectHandler() {}, + // function(key, value, options) triggered if key returns object but returnObjects is set to false + parseMissingKeyHandler: false, + // function(key) parsed a key that was not found in t() before returning + appendNamespaceToMissingKey: false, + appendNamespaceToCIMode: false, + overloadTranslationOptionHandler: function handle(args) { + var ret = {}; + if (_typeof(args[1]) === 'object') ret = args[1]; + if (typeof args[1] === 'string') ret.defaultValue = args[1]; + if (typeof args[2] === 'string') ret.tDescription = args[2]; + + if (_typeof(args[2]) === 'object' || _typeof(args[3]) === 'object') { + var options = args[3] || args[2]; + Object.keys(options).forEach(function (key) { + ret[key] = options[key]; + }); + } - var detailedVisibleTiles_count = this.detailedVisibleTiles_array.length; - for (var i=0; i 0) - { - if (BR_Project._header._f4d_version === 1) - { - if (last_squared_dist) - { - if (squaredDistToCamera < last_squared_dist) - { - last_squared_dist = squaredDistToCamera; - this.currentVisibleBuildings_LOD0_array.push(this.detailed_building); - this.detailed_building = BR_Project; - } - else - { - this.currentVisibleBuildings_LOD0_array.push(BR_Project); - } - } - else - { - last_squared_dist = squaredDistToCamera; - this.detailed_building = BR_Project; - } - } - } - else - { - if (BR_Project._header.isSmall) { visibleBuildings_array.push(BR_Project); } - else { this.currentVisibleBuildings_LOD0_array.push(BR_Project); } - } - } - else if (squaredDistToCamera < this.min_squaredDist_to_see_LOD0) - { - if (need_frustumCulling) - { - this.boundingSphere_Aux.center = Cesium.Cartesian3.clone(BR_Project.buildingPosition); - if (need_frustumCulling && frustumVolume.computeVisibility(this.boundingSphere_Aux) !== Cesium.Intersect.OUTSIDE) - { - this.currentVisibleBuildings_LOD0_array.push(BR_Project); - } - } - else { this.currentVisibleBuildings_LOD0_array.push(BR_Project); } - } - else - { - if (need_frustumCulling) - { - this.boundingSphere_Aux.center = Cesium.Cartesian3.clone(BR_Project.buildingPosition); - if (need_frustumCulling && frustumVolume.computeVisibility(this.boundingSphere_Aux) !== Cesium.Intersect.OUTSIDE) - { - visibleBuildings_array.push(BR_Project); - } - } - else { visibleBuildings_array.push(BR_Project); } - } - } - } + function I18n() { + var _this; - var LOD0VisiblesTiles_count = this.LOD0VisibleTiles_array.length; - for (var i=0; i 0 && arguments[0] !== undefined ? arguments[0] : {}; + var callback = arguments.length > 1 ? arguments[1] : undefined; - if (!this.terranTileSC.fileReading_started) - { - if (this.backGround_fileReadings_count < max_tileFilesReading) - { - tileNumberNameString = this.terranTileSC._numberName.toString(); - filePath_scratch = this.readerWriter.getCurrentDataPath() + Constant.RESULT_XDO2F4D_TERRAINTILES + tileNumberNameString + ".til"; - this.readerWriter.getTileArrayBuffer(gl, filePath_scratch, this.terranTileSC, this.readerWriter, this); - this.backGround_fileReadings_count ++; - } - continue; - } + _classCallCheck(this, I18n); - if (this.terranTileSC.fileReading_finished && !this.terranTileSC.fileParsingFinished) - { - //this.terranTileSC.parseFileOneBuilding(gl, this); - this.terranTileSC.parseFileAllBuildings(this); - //continue; - } + _this = _possibleConstructorReturn(this, _getPrototypeOf(I18n).call(this)); + EventEmitter.call(_assertThisInitialized(_assertThisInitialized(_this))); // <=IE10 fix (unable to call parent constructor) - need_frustumCulling = false; - if (this.terranTileSC.visibilityType === Cesium.Intersect.INTERSECTING) { need_frustumCulling = true; } + _this.options = transformOptions(options); + _this.services = {}; + _this.logger = baseLogger; + _this.modules = { + external: [] + }; - buildings_count = this.terranTileSC._BR_buildingsArray.length; - for (var j=0; j 0 && arguments[0] !== undefined ? arguments[0] : {}; + var callback = arguments.length > 1 ? arguments[1] : undefined; - return visibleBuildings_array; -}; + if (typeof options === 'function') { + callback = options; + options = {}; + } -/** - * 어떤 일을 하고 있습니까? - * @param frustumVolume 변수 - * @param visibleBuildings_array 변수 - * @param cameraPosition 변수 - * @returns visibleBuildings_array - */ -MagoManager.prototype.doFrustumCullingClouds = function(frustumVolume, visibleBuildings_array) -{ - // This makes the visible buildings array.*** - // This has Cesium dependency because uses the frustumVolume and the boundingSphere of cesium.*** - //--------------------------------------------------------------------------------------------------------- - // Note: in this function, we do frustum culling and determine the detailedBuilding in same time.*** + this.options = _objectSpread({}, get(), this.options, transformOptions(options)); + this.format = this.options.interpolation.format; + if (!callback) callback = noop; - // Init the visible buildings array.*** + function createClassOnDemand(ClassOrObject) { + if (!ClassOrObject) return null; + if (typeof ClassOrObject === 'function') return new ClassOrObject(); + return ClassOrObject; + } // init services - this.currentVisibleClouds_array.length = 0; // Init.*** - // var min_squaredDist_to_see_detailed = 40000; // 200m.*** - // var min_squaredDist_to_see_LOD0 = 250000; // 600m.*** - // var min_squaredDist_to_see = 10000000; - // var min_squaredDist_to_see_smallBuildings = 700000; - // - // var squaredDistToCamera; - // var last_squared_dist; + if (!this.options.isClone) { + if (this.modules.logger) { + baseLogger.init(createClassOnDemand(this.modules.logger), this.options); + } else { + baseLogger.init(null, this.options); + } - var clouds_count = this.atmosphere.cloudsManager.circularCloudsArray.length; - for (var p_counter = 0; p_counter 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } - if (cloud.cullingPosition === undefined) - { - continue; - } + _this2.emit.apply(_this2, [event].concat(args)); + }); - /* - squaredDistToCamera = Cesium.Cartesian3.distanceSquared(cameraPosition, cloud.cullingPosition); - if(squaredDistToCamera > min_squaredDist_to_see) - continue; + if (this.modules.languageDetector) { + s.languageDetector = createClassOnDemand(this.modules.languageDetector); + s.languageDetector.init(s, this.options.detection, this.options); + } - if(BR_Project._header.isSmall && squaredDistToCamera>min_squaredDist_to_see_smallBuildings) - continue; - */ + if (this.modules.i18nFormat) { + s.i18nFormat = createClassOnDemand(this.modules.i18nFormat); + if (s.i18nFormat.init) s.i18nFormat.init(this); + } - this.boundingSphere_Aux.center = Cesium.Cartesian3.clone(cloud.cullingPosition); - this.radiusAprox_aux = cloud.cullingRadius; + this.translator = new Translator(this.services, this.options); // pipe events from translator - if (this.radiusAprox_aux) - { - this.boundingSphere_Aux.radius = this.radiusAprox_aux; - } - else - { - this.boundingSphere_Aux.radius = 50.0; // 50m. Provisional.*** - } + this.translator.on('*', function (event) { + for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + args[_key2 - 1] = arguments[_key2]; + } - var frustumCull = frustumVolume.computeVisibility(this.boundingSphere_Aux); - if (frustumCull !== Cesium.Intersect.OUTSIDE) - { - this.currentVisibleClouds_array.push(cloud); - } - } + _this2.emit.apply(_this2, [event].concat(args)); + }); + this.modules.external.forEach(function (m) { + if (m.init) m.init(_this2); + }); + } // append api - return visibleBuildings_array; -}; -/** - * object index 파일을 읽어서 빌딩 개수, 포지션, 크기 정보를 배열에 저장 - */ -MagoManager.prototype.renderModeChanged = function() -{ - if (this.renderModeTemp === 0) - { - ;// - } - else if (this.renderModeTemp === 1) - { - ;// - } - else if (this.renderModeTemp === 2) - { - ;// - } + var storeApi = ['getResource', 'addResource', 'addResources', 'addResourceBundle', 'removeResourceBundle', 'hasResourceBundle', 'getResourceBundle', 'getDataByLanguage']; + storeApi.forEach(function (fcName) { + _this2[fcName] = function () { + var _this2$store; -}; + return (_this2$store = _this2.store)[fcName].apply(_this2$store, arguments); + }; + }); + var deferred = defer(); -MagoManager.prototype.displayLocationAndRotation = function(neoBuilding) -{ - //var node = this.hierarchyManager.getNodeByDataName(projectId, dataName, dataNameValue); // original.*** - var node = neoBuilding.nodeOwner; - var geoLocDatamanager = this.getNodeGeoLocDataManager(node); - if (geoLocDatamanager === undefined) - { return; } - var geoLocationData = geoLocDatamanager.getCurrentGeoLocationData(); - var latitude = geoLocationData.geographicCoord.latitude; - var longitude = geoLocationData.geographicCoord.longitude; - var altitude = geoLocationData.geographicCoord.altitude; - var heading = geoLocationData.heading; - var pitch = geoLocationData.pitch; - var roll = geoLocationData.roll; - var dividedName = neoBuilding.buildingId.split("_"); -}; + var load = function load() { + _this2.changeLanguage(_this2.options.lng, function (err, t) { + _this2.isInitialized = true; -/** - * 변환 행렬 - */ -MagoManager.prototype.selectedObjectNotice = function(neoBuilding) -{ - var node = neoBuilding.nodeOwner; - var geoLocDatamanager = this.getNodeGeoLocDataManager(node); - if (geoLocDatamanager === undefined) - { return; } - var geoLocationData = geoLocDatamanager.getCurrentGeoLocationData(); - var dataKey = node.data.nodeId; - var projectId = node.data.projectId; + _this2.logger.log('initialized', _this2.options); - if (MagoConfig.getPolicy().geo_callback_enable === "true") - { - //if (this.objMarkerSC === undefined) { return; } - var objectId = null; - if (this.objectSelected !== undefined) { objectId = this.objectSelected.objectId; } - - // click object 정보를 표시 - if (this.magoPolicy.getObjectInfoViewEnable()) - { - selectedObjectCallback( MagoConfig.getPolicy().geo_callback_selectedobject, - projectId, - dataKey, - objectId, - geoLocationData.geographicCoord.latitude, - geoLocationData.geographicCoord.longitude, - geoLocationData.geographicCoord.altitude, - geoLocationData.heading, - geoLocationData.pitch, - geoLocationData.roll); - } - - // 이슈 등록 창 오픈 - if (this.magoPolicy.getIssueInsertEnable()) - { - if (this.objMarkerSC === undefined) { return; } - - insertIssueCallback( MagoConfig.getPolicy().geo_callback_insertissue, - projectId, - dataKey, - objectId, - geoLocationData.geographicCoord.latitude, - geoLocationData.geographicCoord.longitude, - (parseFloat(geoLocationData.geographicCoord.altitude))); - } - } - - -}; + _this2.emit('initialized', _this2.options); -/** - * 변환 행렬 - */ -MagoManager.prototype.changeLocationAndRotation = function(projectId, dataKey, latitude, longitude, elevation, heading, pitch, roll) -{ - var nodesMap = this.hierarchyManager.getNodesMap(projectId); - if (nodesMap) - { - var node = nodesMap[dataKey]; - if (node === undefined) - { return; } - this.changeLocationAndRotationNode(node, latitude, longitude, elevation, heading, pitch, roll); - } -}; + deferred.resolve(t); // not rejecting on err (as err is only a loading translation failed warning) -/** - * 변환 행렬 - */ -MagoManager.prototype.changeLocationAndRotationNode = function(node, latitude, longitude, elevation, heading, pitch, roll) -{ - if (node === undefined) - { return; } + callback(err, t); + }); + }; - // 1rst, find the rootNode. - var nodeRoot; - //nodeRoot = node.getRoot(); // original.*** - nodeRoot = node.getClosestParentWithData("geoLocDataManager"); - - if (nodeRoot === undefined) - { return; } - - // now, extract all buildings of the nodeRoot. - var nodesArray = []; - nodeRoot.extractNodesByDataName(nodesArray, "neoBuilding"); - - var aNode; - var nodesCount = nodesArray.length; - for (var i=0; i 0 && arguments[0] !== undefined ? arguments[0] : noop; - this.buildingSeedList = new BuildingSeedList(); - this.readerWriter.getObjectIndexFileForSmartTile( - this.readerWriter.getCurrentDataPath() + Constant.OBJECT_INDEX_FILE + Constant.CACHE_VERSION + MagoConfig.getPolicy().content_cache_version, this, this.buildingSeedList); - -}; + if (!this.options.resources || this.options.partialBundledLanguages) { + if (this.language && this.language.toLowerCase() === 'cimode') return callback(); // avoid loading resources for cimode -/** - * object index 파일을 읽어서 빌딩 개수, 포지션, 크기 정보를 배열에 저장 - */ -MagoManager.prototype.makeNode = function(jasonObject, resultPhysicalNodesArray, buildingSeedMap, projectFolderName, projectId) -{ - var attributes = undefined; - var children = undefined; - var data_group_id = undefined; - var data_group_name = undefined; - var data_id = undefined; - var data_key = undefined; - var data_name = undefined; - var heading = undefined; - var height = undefined; - var latitude = undefined; - var longitude = undefined; - var pitch = undefined; - var roll = undefined; - var mapping_type = undefined; - - if (jasonObject !== undefined) - { - attributes = jasonObject.attributes; - children = jasonObject.children; - data_group_id = jasonObject.data_group_id; - data_group_name = jasonObject.data_group_name; - data_id = jasonObject.data_id; - data_key = jasonObject.data_key; - data_name = jasonObject.data_name; - heading = jasonObject.heading; - height = jasonObject.height; - latitude = jasonObject.latitude; - longitude = jasonObject.longitude; - pitch = jasonObject.pitch; - roll = jasonObject.roll; - mapping_type = jasonObject.mapping_type; - } - - // now make the node. - var buildingId; - var buildingSeed; - var node; - var bbox; - var childJason; - var childNode; - var childrenCount; - if (attributes !== undefined) - { - buildingId = data_key; - node = this.hierarchyManager.newNode(buildingId, projectId, attributes); - // set main data of the node. - node.data.projectFolderName = projectFolderName; - node.data.projectId = projectId; - node.data.data_name = data_name; - node.data.attributes = attributes; - node.data.mapping_type = mapping_type; - var tMatrix; - - if (attributes.isPhysical) - { - // find the buildingSeed. - buildingSeed = buildingSeedMap[buildingId]; - if (buildingSeed) - { - node.data.buildingSeed = buildingSeed; - resultPhysicalNodesArray.push(node); - } - } + var toLoad = []; - if (longitude && latitude) - { - // this is root node. - if (height === undefined) - { height = 0; } - - node.data.geographicCoord = new GeographicCoord(); - node.data.geographicCoord.setLonLatAlt(longitude, latitude, height); - - if (node.data.rotationsDegree === undefined) - { node.data.rotationsDegree = new Point3D(); } - node.data.rotationsDegree.set(pitch, roll, heading); - - - if (buildingSeed !== undefined) - { - if (buildingSeed.geographicCoord === undefined) - { buildingSeed.geographicCoord = new GeographicCoord(); } - - if (buildingSeed.rotationsDegree === undefined) - { buildingSeed.rotationsDegree = new Point3D(); } - - buildingSeed.geographicCoord.setLonLatAlt(longitude, latitude, height); - buildingSeed.rotationsDegree.set(pitch, roll, heading); - - // now calculate the geographic coord of the center of the bbox. - if (buildingSeed.geographicCoordOfBBox === undefined) - { buildingSeed.geographicCoordOfBBox = new GeographicCoord(); } - - // calculate the transformation matrix at (longitude, latitude, height). - var worldCoordPosition = ManagerUtils.geographicCoordToWorldPoint(longitude, latitude, height, worldCoordPosition, this); - tMatrix = ManagerUtils.calculateTransformMatrixAtWorldPosition(worldCoordPosition, heading, pitch, roll, undefined, tMatrix, this); - - // now calculate the geographicCoord of the center of the bBox. - var bboxCenterPoint; - //if(node.data.mapping_type !== undefined && node.data.mapping_type.toLowerCase() === "boundingboxcenter") - // bboxCenterPoint = new Point3D(0,0,0); + var append = function append(lng) { + if (!lng) return; - bboxCenterPoint = buildingSeed.bBox.getCenterPoint(bboxCenterPoint); - var bboxCenterPointWorldCoord = tMatrix.transformPoint3D(bboxCenterPoint, bboxCenterPointWorldCoord); - buildingSeed.geographicCoordOfBBox = ManagerUtils.pointToGeographicCoord(bboxCenterPointWorldCoord, buildingSeed.geographicCoordOfBBox, this); // original. - } - } + var lngs = _this3.services.languageUtils.toResolveHierarchy(lng); - // now, calculate the bbox.*** - node.data.bbox = new BoundingBox(); - - if (node.data.buildingSeed && node.data.buildingSeed.bBox) - { node.data.bbox.copyFrom(buildingSeed.bBox); } - - if (node.data.mapping_type && node.data.mapping_type.toLowerCase() === "boundingboxcenter") - { - node.data.bbox.translateToOrigin(); - } - - // calculate the geographicCoordOfTheBBox.*** - if (tMatrix !== undefined) - { - bboxCenterPoint = node.data.bbox.getCenterPoint(bboxCenterPoint); - var bboxCenterPointWorldCoord = tMatrix.transformPoint3D(bboxCenterPoint, bboxCenterPointWorldCoord); - node.data.bbox.geographicCoord = ManagerUtils.pointToGeographicCoord(bboxCenterPointWorldCoord, node.data.bbox.geographicCoord, this); - } + lngs.forEach(function (l) { + if (toLoad.indexOf(l) < 0) toLoad.push(l); + }); + }; - bbox = node.data.bbox; + if (!this.language) { + // at least load fallbacks in this case + var fallbacks = this.services.languageUtils.getFallbackCodes(this.options.fallbackLng); + fallbacks.forEach(function (l) { + return append(l); + }); + } else { + append(this.language); + } - if (children !== undefined) - { - childrenCount = children.length; - for (var i=0; i 2 ? _len3 - 2 : 0), _key3 = 2; _key3 < _len3; _key3++) { + rest[_key3 - 2] = arguments[_key3]; + } - if (distance > 3.5) - { - var bottomPositionCartographic = this.scene.globe.ellipsoid.cartesianToCartographic(bottomPosition); - var currentPositionCartographic = this.scene.globe.ellipsoid.cartesianToCartographic(position); - var currentHeight = currentPositionCartographic.height; - var bottomHeight = bottomPositionCartographic.height + 1.5; - - if ( bottomHeight < currentHeight ) - { - currentHeight -= 0.2; - } - - if ( bottomHeight > currentHeight || - (bottomHeight < currentHeight && currentHeight - bottomHeight > 1.5)) - { - currentHeight = bottomHeight; - } - var tmpLat = Cesium.Math.toDegrees(currentPositionCartographic.latitude); - var tmpLon = Cesium.Math.toDegrees(currentPositionCartographic.longitude); - - this.cameraFPV.camera.position = Cesium.Cartesian3.fromDegrees(tmpLon, tmpLat, currentHeight); + options = _this5.options.overloadTranslationOptionHandler([key, opts].concat(rest)); + } - return false; - } + options.lng = options.lng || fixedT.lng; + options.lngs = options.lngs || fixedT.lngs; + options.ns = options.ns || fixedT.ns; + return _this5.t(key, options); + }; - return true; -};; + if (typeof lng === 'string') { + fixedT.lng = lng; + } else { + fixedT.lngs = lng; + } -'use strict'; + fixedT.ns = ns; + return fixedT; + } + }, { + key: "t", + value: function t() { + var _this$translator; -/** - * Factory method 패턴을 사용해서 cesium, worldwind 등을 wrapping 해 주는 클래스 - * @class ManagerFactory - * - * @param viewer 타 시스템과의 연동의 경우 view 객체가 생성되어서 넘어 오는 경우가 있음 - * @param containerId 뷰에서 표시할 위치 id - * @param serverPolicy policy json object - * @param projectIdArray json object map에 저장하기 위한 key - * @param projectDataArray data json object - * @param projectDataFolderArray f4d data folder path - * @param imagePath 이미지 경로 - * @return api - */ -var ManagerFactory = function(viewer, containerId, serverPolicy, projectIdArray, projectDataArray, projectDataFolderArray, imagePath) -{ - if (!(this instanceof ManagerFactory)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } + return this.translator && (_this$translator = this.translator).translate.apply(_this$translator, arguments); + } + }, { + key: "exists", + value: function exists() { + var _this$translator2; - var magoManager = null; - var scene = null; - var magoManagerState = CODE.magoManagerState.INIT; - - //var startMousePosition = null; - //var nowMousePosition = null; + return this.translator && (_this$translator2 = this.translator).exists.apply(_this$translator2, arguments); + } + }, { + key: "setDefaultNamespace", + value: function setDefaultNamespace(ns) { + this.options.defaultNS = ns; + } + }, { + key: "loadNamespaces", + value: function loadNamespaces(ns, callback) { + var _this6 = this; - // 환경 설정 - MagoConfig.init(serverPolicy, projectIdArray, projectDataArray); - - // 카메라 행동 설정 - function disableCameraMotion(state) - { - viewer.scene.screenSpaceCameraController.enableRotate = state; - viewer.scene.screenSpaceCameraController.enableZoom = state; - viewer.scene.screenSpaceCameraController.enableLook = state; - viewer.scene.screenSpaceCameraController.enableTilt = state; - viewer.scene.screenSpaceCameraController.enableTranslate = state; - } - - // 이벤트 확장 - function addMouseAction() - { - magoManager.handler.setInputAction(function(click) - { - magoManager.mouseActionLeftDown(click.position.x, click.position.y); - }, Cesium.ScreenSpaceEventType.LEFT_DOWN); + var deferred = defer(); - magoManager.handler.setInputAction(function(click) - { - magoManager.mouseActionMiddleDown(click.position.x, click.position.y); - }, Cesium.ScreenSpaceEventType.MIDDLE_DOWN); - - magoManager.handler.setInputAction(function(click) - { - magoManager.mouseActionRightDown(click.position.x, click.position.y); - }, Cesium.ScreenSpaceEventType.RIGHT_DOWN); + if (!this.options.ns) { + callback && callback(); + return Promise.resolve(); + } - //var mousePosition; - magoManager.handler.setInputAction(function(movement) - { - //magoManager.mouseActionMove(movement.endPosition.x, movement.endPosition.y); - //mousePosition = movement.endPosition; - if (magoManager.mouseLeftDown) - { - if (movement.startPosition.x !== movement.endPosition.x || movement.startPosition.y !== movement.endPosition.y) - { - magoManager.manageMouseDragging(movement.startPosition.x, movement.startPosition.y); - magoManager.cameraMoved(); - } - } - else - { - magoManager.mouseDragging = false; - disableCameraMotion(true); - if (magoManager.mouseMiddleDown || magoManager.mouseRightDown) - { - magoManager.isCameraMoving = true; - magoManager.cameraMoved(); - } - } - - }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - /* - // disable wheel for cesium. - var handler = magoManager.scene.screenSpaceCameraController._aggregator._eventHandler; - handler.removeInputAction(Cesium.ScreenSpaceEventType.WHEEL); - for ( var modifierName in Cesium.KeyboardEventModifier) - { - if (Cesium.KeyboardEventModifier.hasOwnProperty(modifierName)) - { - var modifier = Cesium.KeyboardEventModifier[modifierName]; - if (modifier !== undefined) - { - handler.removeInputAction(Cesium.ScreenSpaceEventType.WHEEL, modifier); - } - } + if (typeof ns === 'string') ns = [ns]; + ns.forEach(function (n) { + if (_this6.options.ns.indexOf(n) < 0) _this6.options.ns.push(n); + }); + this.loadResources(function (err) { + deferred.resolve(); + if (callback) callback(err); + }); + return deferred; + } + }, { + key: "loadLanguages", + value: function loadLanguages(lngs, callback) { + var deferred = defer(); + if (typeof lngs === 'string') lngs = [lngs]; + var preloaded = this.options.preload || []; + var newLngs = lngs.filter(function (lng) { + return preloaded.indexOf(lng) < 0; + }); // Exit early if all given languages are already preloaded + + if (!newLngs.length) { + if (callback) callback(); + return Promise.resolve(); } - - // make mago wheel. - magoManager.handler.setInputAction(function (wheelZoomAmount) { - var cameraHeight, directionToZoom, zoomAmount; - if (mousePosition) { - cameraHeight = viewer.scene.globe.ellipsoid.cartesianToCartographic(viewer.camera.position).height || Number.MAX_VALUE; - directionToZoom = viewer.camera.getPickRay(mousePosition).direction; - zoomAmount = wheelZoomAmount * cameraHeight / 1000; - - if(wheelZoomAmount > magoManager.TEST_maxWheelZoomAmount) - magoManager.TEST_maxWheelZoomAmount = wheelZoomAmount; - - if(zoomAmount > magoManager.TEST_maxZoomAmount) - magoManager.TEST_maxZoomAmount = zoomAmount; - - if(cameraHeight < 1000) - { - if(wheelZoomAmount > 100) - wheelZoomAmount = 100; - - if(zoomAmount > 80) - zoomAmount = 80; - } - if(directionToZoom.x > 1 || directionToZoom.y > 1 || directionToZoom.z > 1 ) - var hola =0; - - viewer.camera.position.x = viewer.camera.position.x + directionToZoom.x * zoomAmount; - viewer.camera.position.y = viewer.camera.position.y + directionToZoom.y * zoomAmount; - viewer.camera.position.z = viewer.camera.position.z + directionToZoom.z * zoomAmount; - //viewer.camera.move(directionToZoom, zoomAmount); - } - }, Cesium.ScreenSpaceEventType.WHEEL); - */ - magoManager.handler.setInputAction(function(movement) - { - magoManager.mouseActionLeftUp(movement.position.x, movement.position.y); - // display current mouse position - var pickPosition = {lat: null, lon: null, alt: null}; - var position = magoManager.scene.camera.pickEllipsoid(movement.position); - if (position) - { - var cartographicPosition = Cesium.Cartographic.fromCartesian(position); - pickPosition.lat = Cesium.Math.toDegrees(cartographicPosition.latitude); - pickPosition.lon = Cesium.Math.toDegrees(cartographicPosition.longitude); - pickPosition.alt = cartographicPosition.height; - } - if (MagoConfig.getPolicy().geo_callback_enable === "true") - { - if (serverPolicy.geo_callback_clickposition !== '') - { - clickPositionCallback(serverPolicy.geo_callback_clickposition, pickPosition); - } - } - }, Cesium.ScreenSpaceEventType.LEFT_UP); - magoManager.handler.setInputAction(function(movement) - { - magoManager.mouseActionMiddleUp(movement.position.x, movement.position.y); - }, Cesium.ScreenSpaceEventType.MIDDLE_UP); - - magoManager.handler.setInputAction(function(movement) - { - magoManager.mouseActionRightUp(movement.position.x, movement.position.y); - }, Cesium.ScreenSpaceEventType.RIGHT_UP); - } + this.options.preload = preloaded.concat(newLngs); + this.loadResources(function (err) { + deferred.resolve(); + if (callback) callback(err); + }); + return deferred; + } + }, { + key: "dir", + value: function dir(lng) { + if (!lng) lng = this.languages && this.languages.length > 0 ? this.languages[0] : this.language; + if (!lng) return 'rtl'; + var rtlLngs = ['ar', 'shu', 'sqr', 'ssh', 'xaa', 'yhd', 'yud', 'aao', 'abh', 'abv', 'acm', 'acq', 'acw', 'acx', 'acy', 'adf', 'ads', 'aeb', 'aec', 'afb', 'ajp', 'apc', 'apd', 'arb', 'arq', 'ars', 'ary', 'arz', 'auz', 'avl', 'ayh', 'ayl', 'ayn', 'ayp', 'bbz', 'pga', 'he', 'iw', 'ps', 'pbt', 'pbu', 'pst', 'prp', 'prd', 'ur', 'ydd', 'yds', 'yih', 'ji', 'yi', 'hbo', 'men', 'xmn', 'fa', 'jpr', 'peo', 'pes', 'prs', 'dv', 'sam']; + return rtlLngs.indexOf(this.services.languageUtils.getLanguagePartFromCode(lng)) >= 0 ? 'rtl' : 'ltr'; + } + /* eslint class-methods-use-this: 0 */ + + }, { + key: "createInstance", + value: function createInstance() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var callback = arguments.length > 1 ? arguments[1] : undefined; + return new I18n(options, callback); + } + }, { + key: "cloneInstance", + value: function cloneInstance() { + var _this7 = this; + + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop; + + var mergedOptions = _objectSpread({}, this.options, options, { + isClone: true + }); + + var clone = new I18n(mergedOptions); + var membersToCopy = ['store', 'services', 'language']; + membersToCopy.forEach(function (m) { + clone[m] = _this7[m]; + }); + clone.translator = new Translator(clone.services, clone.options); + clone.translator.on('*', function (event) { + for (var _len4 = arguments.length, args = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) { + args[_key4 - 1] = arguments[_key4]; + } - // cesium을 구현체로서 이용 - function initWwwMago(manager, gl) - { - //var viewport = manager.wwd.viewport; - //manager.selection.init(gl, viewport.width, viewport.height); - manager.shadersManager.createDefaultShader(gl); - manager.postFxShadersManager.gl = gl; - manager.postFxShadersManager.createDefaultShaders(gl); // A1-OLD.*** - manager.createDefaultShaders(gl);// A1-Use this.*** + clone.emit.apply(clone, [event].concat(args)); + }); + clone.init(mergedOptions, callback); + clone.translator.options = clone.options; // sync options - // object index 파일을 읽어서 빌딩 개수, 포지션, 크기 정보를 배열에 저장 - //manager.getObjectIndexFile(); // old.*** - //viewer.scene.magoManager.getObjectIndexFile(); - if (projectIdArray !== null && projectIdArray.length > 0) - { - for (var i=0; i 0) - { - for (var i=0; i hidden - $(viewer._animation.container).css("visibility", "hidden"); - $(viewer._timeline.container).css("visibility", "hidden"); - viewer.forceResize(); - } - } - - var DEFALUT_IMAGE = "ESRI World Imagery"; - var DEFALUT_TERRAIN = "WGS84 Ellipsoid"; - - // pick baseLayer - function setDefaultDataset() - { - // WGS84 Ellipsoide - if (MagoConfig.getPolicy().geo_init_default_terrain !== null && MagoConfig.getPolicy().geo_init_default_terrain !== "") - { - DEFALUT_TERRAIN = MagoConfig.getPolicy().geo_init_default_terrain; - } - - // search default imageryProvider from baseLayerPicker - var imageryProvider = null; - var imageryProviderViewModels = viewer.baseLayerPicker.viewModel.imageryProviderViewModels; - for (var i in imageryProviderViewModels) - { - if (!imageryProviderViewModels.hasOwnProperty(i)) { continue; } + var cookie$1 = { + name: 'cookie', - var provider = imageryProviderViewModels[i]; - if (provider.name === DEFALUT_IMAGE) - { - imageryProvider = provider; - break; - } - } - if (imageryProvider) { viewer.baseLayerPicker.viewModel.selectedImagery = imageryProvider; } - - // search default terrainProvider from baseLayerPicker - var terrainProvider = null; - var terrainProviderViewModels = viewer.baseLayerPicker.viewModel.terrainProviderViewModels; - for (var i in terrainProviderViewModels) - { - if (!terrainProviderViewModels.hasOwnProperty(i)) { continue; } - var provider = terrainProviderViewModels[i]; - if (provider.name === DEFALUT_TERRAIN) - { - terrainProvider = provider; - break; - } - } - if (terrainProvider) { viewer.baseLayerPicker.viewModel.selectedTerrain = terrainProvider; } - } + lookup: function lookup(options) { + var found = void 0; - if (serverPolicy.geo_view_library === null || - serverPolicy.geo_view_library === '' || - serverPolicy.geo_view_library === Constant.CESIUM) - { - // webgl lost events.****************************************** - var canvas = document.getElementById(containerId); - canvas.addEventListener('webglcontextlost', function(e) - { - console.log(e); - }, false); - - canvas.addEventListener('webglcontextrestored', function(e) - { - console.log(e); - }, false); - //------------------------------------------------------------- + if (options.lookupCookie && typeof document !== 'undefined') { + var c = cookie.read(options.lookupCookie); + if (c) found = c; + } - if (serverPolicy.geo_server_enable === "true" && serverPolicy.geo_server_url !== null && serverPolicy.geo_server_url !== '') - { - var imageryProvider = new Cesium.WebMapServiceImageryProvider({ - url : serverPolicy.geo_server_url, - layers : serverPolicy.geo_server_layers, - parameters : { - service : serverPolicy.geo_server_parameters_service, - version : serverPolicy.geo_server_parameters_version, - request : serverPolicy.geo_server_parameters_request, - transparent : serverPolicy.geo_server_parameters_transparent, - format : serverPolicy.geo_server_parameters_format - }//, - //proxy: new Cesium.DefaultProxy('/proxy/') - }); - var options = {imageryProvider: imageryProvider, baseLayerPicker: false}; - if (viewer === null) { viewer = new Cesium.Viewer(containerId, options); } - } - else - { - if (serverPolicy.geo_cesium_ion_token !== null && serverPolicy.geo_cesium_ion_token !== "") - { - Cesium.Ion.defaultAccessToken = serverPolicy.geo_cesium_ion_token; - DEFALUT_TERRAIN = "Cesium World Terrain"; - } - if (viewer === null) { viewer = new Cesium.Viewer(containerId); } - // 기본 지도 설정 - setDefaultDataset(); - } - - viewer.scene.magoManager = new MagoManager(); - viewer.scene.magoManager.sceneState.textureFlipYAxis = false; - viewer.camera.frustum.fov = Cesium.Math.PI_OVER_THREE*1.8; - //viewer.camera.frustum.near = 0.1; - if (MagoConfig.getPolicy().geo_init_default_fov > 0) - { - viewer.camera.frustum.fov = Cesium.Math.PI_OVER_THREE * MagoConfig.getPolicy().geo_init_default_fov; - } + return found; + }, + cacheUserLanguage: function cacheUserLanguage(lng, options) { + if (options.lookupCookie && typeof document !== 'undefined') { + cookie.create(options.lookupCookie, lng, options.cookieMinutes, options.cookieDomain); + } + } + }; - // Layers 추가 적용 - if (serverPolicy.geo_server_enable === "true" && serverPolicy.geo_server_add_url !== null && serverPolicy.geo_server_add_url !== '') - { - addImageryLayers(); - } - - draw(); - // build을 rendering 할 위치 - initEntity(); - // terrain 적용 여부 - /*if() { - initTerrain(); - }*/ - // 최초 로딩시 카메라 이동 여부 - if (serverPolicy.geo_init_camera_enable === "true") { initCamera(); } - // render Mode 적용 - initRenderMode(); - } - else if (serverPolicy.geo_view_library === Constant.WORLDWIND) - { - - // Tell World Wind to log only warnings and errors. - WorldWind.Logger.setLoggingLevel(WorldWind.Logger.LEVEL_WARNING); + var querystring = { + name: 'querystring', + + lookup: function lookup(options) { + var found = void 0; + + if (typeof window !== 'undefined') { + var query = window.location.search.substring(1); + var params = query.split('&'); + for (var i = 0; i < params.length; i++) { + var pos = params[i].indexOf('='); + if (pos > 0) { + var key = params[i].substring(0, pos); + if (key === options.lookupQuerystring) { + found = params[i].substring(pos + 1); + } + } + } + } - // set to canvas the current gl.*** - var canvas = document.getElementById(containerId); - - var wwd; - if (serverPolicy.geo_server_enable === "true" && serverPolicy.geo_server_url !== null && serverPolicy.geo_server_url !== '') - { - wwd = new WorldWind.WorldWindow(containerId, new WorldWind.ZeroElevationModel()); - - // Web Map Service information - var serviceAddress = serverPolicy.geo_server_url + "?SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.3.0"; + return found; + } + }; - // Named layer displaying Average Temperature data - var layerName = "mago3d"; + var hasLocalStorageSupport = void 0; + try { + hasLocalStorageSupport = window !== 'undefined' && window.localStorage !== null; + var testKey = 'i18next.translate.boo'; + window.localStorage.setItem(testKey, 'foo'); + window.localStorage.removeItem(testKey); + } catch (e) { + hasLocalStorageSupport = false; + } - // Called asynchronously to parse and create the WMS layer - var createLayer = function (xmlDom) - { - // Create a WmsCapabilities object from the XML DOM - var wms = new WorldWind.WmsCapabilities(xmlDom); - // Retrieve a WmsLayerCapabilities object by the desired layer name - var wmsLayerCapabilities = wms.getNamedLayer(layerName); - // Form a configuration object from the WmsLayerCapability object - var wmsConfig = WorldWind.WmsLayer.formLayerConfiguration(wmsLayerCapabilities); - // Modify the configuration objects title property to a more user friendly title - wmsConfig.title = "imageProvider"; - // Create the WMS Layer from the configuration object - var wmsLayer = new WorldWind.WmsLayer(wmsConfig); + var localStorage = { + name: 'localStorage', - // Add the layers to WorldWind and update the layer manager - wwd.addLayer(wmsLayer); - }; + lookup: function lookup(options) { + var found = void 0; - // Called if an error occurs during WMS Capabilities document retrieval - var logError = function (jqXhr, text, exception) - { - console.log("There was a failure retrieving the capabilities document: " + text + " exception: " + exception); - }; + if (options.lookupLocalStorage && hasLocalStorageSupport) { + var lng = window.localStorage.getItem(options.lookupLocalStorage); + if (lng) found = lng; + } - $.get(serviceAddress).done(createLayer).fail(logError); - } - else - { - // Create the World Window. - wwd = new WorldWind.WorldWindow(containerId); - //wwd.depthBits = 32; - - var layers = [ - {layer: new WorldWind.BMNGLayer(), enabled: true}, - {layer: new WorldWind.BMNGLandsatLayer(), enabled: false}, - {layer: new WorldWind.BingAerialWithLabelsLayer(null), enabled: true}, - {layer: new WorldWind.OpenStreetMapImageLayer(null), enabled: false}, - {layer: new WorldWind.CompassLayer(), enabled: false}, - {layer: new WorldWind.CoordinatesDisplayLayer(wwd), enabled: true}, - {layer: new WorldWind.ViewControlsLayer(wwd), enabled: true} - ]; + return found; + }, + cacheUserLanguage: function cacheUserLanguage(lng, options) { + if (options.lookupLocalStorage && hasLocalStorageSupport) { + window.localStorage.setItem(options.lookupLocalStorage, lng); + } + } + }; - for (var l = 0; l < layers.length; l++) - { - layers[l].layer.enabled = layers[l].enabled; - wwd.addLayer(layers[l].layer); - } - } + var navigator$1 = { + name: 'navigator', - // Now set up to handle highlighting. - //var highlightController = new WorldWind.HighlightController(wwd); + lookup: function lookup(options) { + var found = []; - magoManager = new MagoManager(); - magoManager.wwd = wwd; - magoManager.sceneState.textureFlipYAxis = true; - - var newRenderableLayer = new WorldWind.RenderableLayer(); - newRenderableLayer.displayName = "F4D tiles"; - newRenderableLayer.inCurrentFrame = true; // Test.*** - wwd.addLayer(newRenderableLayer); - - //newRenderableLayer.addRenderable(f4d_wwwLayer);// old.*** - newRenderableLayer.addRenderable(magoManager); - // End Create a layer to hold the f4dBuildings.------------------------------------------------------- + if (typeof navigator !== 'undefined') { + if (navigator.languages) { + // chrome only; not an array, so can't use .push.apply instead of iterating + for (var i = 0; i < navigator.languages.length; i++) { + found.push(navigator.languages[i]); + } + } + if (navigator.userLanguage) { + found.push(navigator.userLanguage); + } + if (navigator.language) { + found.push(navigator.language); + } + } - var gl = wwd.drawContext.currentGlContext; - initWwwMago(magoManager, gl); + return found.length > 0 ? found : undefined; + } + }; - // Click event. - // The common gesture-handling function. - var handleClick = function (recognizer) - { - // Obtain the event location. - //magoManager.mouse_x = event.layerX, - //magoManager.mouse_y = event.layerY; - //magoManager.bPicking = true; - - // Perform the pick. Must first convert from window coordinates to canvas coordinates, which are - // relative to the upper left corner of the canvas rather than the upper left corner of the page. - //var pickList = wwd.pick(wwd.canvasCoordinates(x, y)); + var htmlTag = { + name: 'htmlTag', - // If only one thing is picked and it is the terrain, use a go-to animator to go to the picked location. - /* - if (pickList.objects.length === 1 && pickList.objects[0].isTerrain) { - var position = pickList.objects[0].position; - //wwd.goTo(new WorldWind.Location(position.latitude, position.longitude)); - //wwd.goTo(new WorldWind.Position(37.48666, 127.05618, 500)); - wwd.goToOriented(new WorldWind.Position(37.48666, 127.05618, 500.0), 120.0, 80.0); - } - */ - }; + lookup: function lookup(options) { + var found = void 0; + var htmlTag = options.htmlTag || (typeof document !== 'undefined' ? document.documentElement : null); - // Listen for mouse clicks. - var clickRecognizer = new WorldWind.ClickRecognizer(wwd, handleClick); - clickRecognizer.button = 0; //left mouse button - - var mouseDownEvent = function(event) - { - if (event.button === 0) - { - magoManager.mouseActionLeftDown(event.layerX, event.layerY); - } - else if (event.button === 1) - { - magoManager.mouseActionMiddleDown(event.layerX, event.layerY); - } - else if (event.button === 2) - { - magoManager.mouseActionRightDown(event.layerX, event.layerY); - } - }; - wwd.addEventListener("mousedown", mouseDownEvent, false); - - var mouseUpEvent = function(event) - { - if (event.button === 0) - { - magoManager.mouseActionLeftUp(event.layerX, event.layerY); - } - else if (event.button === 1) - { - magoManager.mouseActionMiddleUp(event.layerX, event.layerY); - } - else if (event.button === 2) - { - magoManager.mouseActionRightUp(event.layerX, event.layerY); - } + if (htmlTag && typeof htmlTag.getAttribute === 'function') { + found = htmlTag.getAttribute('lang'); + } - // display current mouse position - - var terrainObject; - var pickPosition = {lat: null, lon: null, alt: null}; - var pickPoint = wwd.canvasCoordinates(event.layerX, event.layerY); - if (pickPoint[0] >= 0 && pickPoint[0] < wwd.canvas.width && - pickPoint[1] >= 0 && pickPoint[1] < wwd.canvas.height) - { - terrainObject = wwd.pickTerrain(pickPoint).terrainObject(); - var terrainPosition = terrainObject ? terrainObject.position : null; - if (terrainPosition !== null) - { - pickPosition.lat = terrainPosition.latitude; - pickPosition.lon = terrainPosition.longitude; - pickPosition.alt = terrainPosition.altitude; - } - } - if (MagoConfig.getPolicy().geo_callback_enable === "true") - { - if (serverPolicy.geo_callback_clickposition !== '') - { - clickPositionCallback(serverPolicy.geo_callback_clickposition, pickPosition); - } - } - }; - wwd.addEventListener("mouseup", mouseUpEvent, false); - - var mouseMoveEvent = function(event) - { - magoManager.mouse_x = event.layerX, - magoManager.mouse_y = event.layerY; - if (magoManager.mouseLeftDown) - { - magoManager.manageMouseDragging(event.layerX, event.layerY); - magoManager.cameraMoved(); - } - else if (magoManager.mouseMiddleDown || magoManager.mouseRightDown) - { - magoManager.cameraMoved(); - } - - }; - wwd.addEventListener("mousemove", mouseMoveEvent, false); - - wwd.goToAnimator.travelTime = MagoConfig.getPolicy().geo_init_duration * 1000; - wwd.goTo(new WorldWind.Position(MagoConfig.getPolicy().geo_init_latitude, MagoConfig.getPolicy().geo_init_longitude, MagoConfig.getPolicy().geo_init_height)); - } - if (serverPolicy.geo_view_library === Constant.MAGOWORLD) - { - var canvas = document.getElementById(containerId); - var glAttrs = {antialias: false, stencil: true}; - var gl = canvas.getContext("webgl", glAttrs); - if (!gl) - { gl = canvas.getContext("experimental-webgl", glAttrs); } - - // Problem: canvas-width initially is 300 and canvas-height = 150.*** - canvas.width = canvas.clientWidth; - canvas.height = canvas.clientHeight; - - magoManager = new MagoManager(); - var sceneState = magoManager.sceneState; - sceneState.textureFlipYAxis = true; - sceneState.gl = gl; - sceneState.drawingBufferWidth[0] = canvas.clientWidth; - sceneState.drawingBufferHeight[0] = canvas.clientHeight; - sceneState.camera.frustum.aspectRatio = canvas.clientWidth/canvas.clientHeight; - sceneState.camera.frustum.fovRad[0] = Math.PI/3*1.8; - sceneState.camera.frustum.fovyRad[0] = sceneState.camera.frustum.fovRad[0]/sceneState.camera.frustum.aspectRatio; - sceneState.camera.frustum.tangentOfHalfFovy[0] = Math.tan(sceneState.camera.frustum.fovyRad[0]/2); - - - // initial camera position.*** - sceneState.camera.position.set(0.0, 0.0, 10000000.0); - sceneState.camera.direction.set(0.0, 0.0, -1.0); - sceneState.camera.up.set(0.0, 1.0, 0.0); - - // test init camera position.*** - //sphere.r = 6378137.0; - sceneState.encodedCamPosHigh[0] = 0; - sceneState.encodedCamPosHigh[1] = 0; - sceneState.encodedCamPosHigh[2] = 10000000.0; - - sceneState.encodedCamPosLow[0] = 0; - sceneState.encodedCamPosLow[1] = 0; - sceneState.encodedCamPosLow[2] = 0; + return found; + } + }; - - viewer = new MagoWorld(magoManager); - magoManager.magoWorld = viewer; - magoManager.globe = new Globe(); - // init matrices.*** - viewer.updateModelViewMatrixByCamera(sceneState.camera); - //magoManager.upDateSceneStateMatrices(sceneState); - - // event listener.*** - canvas.addEventListener('mousedown', function(event) - { - viewer.mousedown(event); - }, false); - - canvas.addEventListener('mouseup', function(event) - { - viewer.mouseup(event); - }, false); - - canvas.addEventListener('mousewheel', function(event) - { - viewer.mousewheel(event); - }, false); - - canvas.addEventListener('mousemove', function(event) - { - viewer.mousemove(event); - }, false); - - canvas.addEventListener('resize', function(event) - { - var hola = 0; // no works.*** - }, false); - - canvas.addEventListener('keydown', function(event) // no works.*** - { - viewer.keydown(event); // no works.*** - }, false); + var path = { + name: 'path', + + lookup: function lookup(options) { + var found = void 0; + if (typeof window !== 'undefined') { + var language = window.location.pathname.match(/\/([a-zA-Z-]*)/g); + if (language instanceof Array) { + if (typeof options.lookupFromPathIndex === 'number') { + if (typeof language[options.lookupFromPathIndex] !== 'string') { + return undefined; + } + found = language[options.lookupFromPathIndex].replace('/', ''); + } else { + found = language[0].replace('/', ''); + } + } + } + return found; + } + }; - - draw(); - } + var subdomain = { + name: 'subdomain', - // 이미지 경로 - magoManager.magoPolicy.imagePath = imagePath; - magoManagerState = CODE.magoManagerState.READY; + lookup: function lookup(options) { + var found = void 0; + if (typeof window !== 'undefined') { + var language = window.location.href.match(/(?:http[s]*\:\/\/)*(.*?)\.(?=[^\/]*\..{2,5})/gi); + if (language instanceof Array) { + if (typeof options.lookupFromSubdomainIndex === 'number') { + found = language[options.lookupFromSubdomainIndex].replace('http://', '').replace('https://', '').replace('.', ''); + } else { + found = language[0].replace('http://', '').replace('https://', '').replace('.', ''); + } + } + } + return found; + } + }; - // KeyPressEvents.************************************** - document.addEventListener('keydown', function(event) - { - // get current building selected - if (magoManager.magoPolicy.issueInsertEnable) { return; } + var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - var selectedBuilding = magoManager.buildingSelected; - if (selectedBuilding === undefined) { return; } + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - var nodeSelected = magoManager.selectionCandidates.currentNodeSelected; - if (nodeSelected === undefined) - { return; } - var rootNodeSelected = nodeSelected.getRoot(); - var geoLocationData = rootNodeSelected.data.geoLocDataManager.getCurrentGeoLocationData(); - if (geoLocationData === undefined) { return; } + function getDefaults() { + return { + order: ['querystring', 'cookie', 'localStorage', 'navigator', 'htmlTag'], + lookupQuerystring: 'lng', + lookupCookie: 'i18next', + lookupLocalStorage: 'i18nextLng', + + // cache user language + caches: ['localStorage'], + excludeCacheFor: ['cimode'] + //cookieMinutes: 10, + //cookieDomain: 'myDomain' + }; + } - var increDeg = 3.0; - var currentHeading = geoLocationData.heading || 0; - var currentPitch = geoLocationData.pitch || 0; - var currentRoll = geoLocationData.roll || 0; - - var increDist = 0.2; - var currentAlt = geoLocationData.geographicCoord.altitude || 0; - var displayData = false; - - // For Heading - if (event.keyCode === 'Q'.charCodeAt(0)) - { - currentHeading += increDeg; - displayData = true; - } - else if (event.keyCode === 'A'.charCodeAt(0)) - { - currentHeading -= increDeg; - displayData = true; - } - - // For Pitch - if (event.keyCode === 'W'.charCodeAt(0)) - { - currentPitch += increDeg; - displayData = true; - } - else if (event.keyCode === 'S'.charCodeAt(0)) - { - currentPitch -= increDeg; - displayData = true; - } + var Browser = function () { + function Browser(services) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - // For Roll - if (event.keyCode === 'E'.charCodeAt(0)) - { - currentRoll += increDeg; - displayData = true; - } - else if (event.keyCode === 'D'.charCodeAt(0)) - { - currentRoll -= increDeg; - displayData = true; - } - - // For Altitude - if (event.keyCode === 'Z'.charCodeAt(0)) - { - currentAlt += increDist; - displayData = true; - } - else if (event.keyCode === 'X'.charCodeAt(0)) - { - currentAlt -= increDist; - displayData = true; - } + _classCallCheck(this, Browser); - if (displayData) - { magoManager.changeLocationAndRotationNode(nodeSelected, geoLocationData.geographicCoord.latitude, geoLocationData.geographicCoord.longitude, currentAlt, currentHeading, currentPitch, currentRoll); } + this.type = 'languageDetector'; + this.detectors = {}; - }, false); - - // TODO API 객체를 생성해서 하나의 parameter로 전달하는 방식이 좀 더 깔끔할거 같지만 성능적인 부분에서 조금은 투박할거 같아서 일단 이렇게 처리 - return { - // api gateway 역할 - callAPI: function(api) - { - if (api.getReturnable()) - { - return magoManager.callAPI(api); - } - else - { - magoManager.callAPI(api); - } - }, - // flyTo: function(issueId, issueType, longitude, latitude, height, duration) - // { - // if (MagoConfig.getPolicy().geo_view_library === Constant.CESIUM) - // { - // viewer.camera.flyTo({ - // destination: Cesium.Cartesian3.fromDegrees(parseFloat(longitude), - // parseFloat(latitude), - // parseFloat(height) + 10), - // duration: parseInt(duration) - // }); - // } - // else - // { - // wwd.goToAnimator.travelTime = duration * 1000; - // wwd.goTo(new WorldWind.Position(parseFloat(latitude), parseFloat(longitude), parseFloat(height) + 50)); - // } - // // pin을 그림 - // if (issueId !== null && issueType !== undefined) - // { - // var api = new API("drawInsertIssueImage"); - // api.setDrawType(0); - // api.setIssueId(issueId); - // api.setIssueType(issueType); - // api.setDataKey(null); - // api.setLatitude(latitude); - // api.setLongitude(longitude); - // api.setElevation(height); - // magoManager.callAPI(api); - // } - // }, - // magoManager 상태 - getViewer: function() - { - return viewer; - }, - getMagoManagerState: function() - { - return magoManagerState; - } - }; -}; + this.init(services, options); + } -'use strict'; + _createClass(Browser, [{ + key: 'init', + value: function init(services) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var i18nOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; -/** - * 어떤 일을 하고 있습니까? - * @class Matrix4 - */ -var Matrix4 = function() -{ - if (!(this instanceof Matrix4)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } + this.services = services; + this.options = defaults(options, this.options || {}, getDefaults()); - this._floatArrays = [ 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - ]; -}; + // backwards compatibility + if (this.options.lookupFromUrlIndex) this.options.lookupFromPathIndex = this.options.lookupFromUrlIndex; -/** - * 어떤 일을 하고 있습니까? - */ -Matrix4.prototype.Identity = function() -{ - this._floatArrays = [ 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - ]; -}; + this.i18nOptions = i18nOptions; -/** - * 어떤 일을 하고 있습니까? - * @returns rowMajor_matrix - */ -Matrix4.prototype.deleteObjects = function() -{ - this._floatArrays = undefined; -}; + this.addDetector(cookie$1); + this.addDetector(querystring); + this.addDetector(localStorage); + this.addDetector(navigator$1); + this.addDetector(htmlTag); + this.addDetector(path); + this.addDetector(subdomain); + } + }, { + key: 'addDetector', + value: function addDetector(detector) { + this.detectors[detector.name] = detector; + } + }, { + key: 'detect', + value: function detect(detectionOrder) { + var _this = this; + + if (!detectionOrder) detectionOrder = this.options.order; + + var detected = []; + detectionOrder.forEach(function (detectorName) { + if (_this.detectors[detectorName]) { + var lookup = _this.detectors[detectorName].lookup(_this.options); + if (lookup && typeof lookup === 'string') lookup = [lookup]; + if (lookup) detected = detected.concat(lookup); + } + }); + + var found = void 0; + detected.forEach(function (lng) { + if (found) return; + var cleanedLng = _this.services.languageUtils.formatLanguageCode(lng); + if (_this.services.languageUtils.isWhitelisted(cleanedLng)) found = cleanedLng; + }); + + if (!found) { + var fallbacks = this.i18nOptions.fallbackLng; + if (typeof fallbacks === 'string') fallbacks = [fallbacks]; + if (!fallbacks) fallbacks = []; + + if (Object.prototype.toString.apply(fallbacks) === '[object Array]') { + found = fallbacks[0]; + } else { + found = fallbacks[0] || fallbacks.default && fallbacks.default[0]; + } + }; -/** - * 어떤 일을 하고 있습니까? - * @returns rowMajor_matrix - */ -Matrix4.prototype.getRowMajorMatrix = function() -{ - var rowMajor_matrix = new Float32Array(16); + return found; + } + }, { + key: 'cacheUserLanguage', + value: function cacheUserLanguage(lng, caches) { + var _this2 = this; + + if (!caches) caches = this.options.caches; + if (!caches) return; + if (this.options.excludeCacheFor && this.options.excludeCacheFor.indexOf(lng) > -1) return; + caches.forEach(function (cacheName) { + if (_this2.detectors[cacheName]) _this2.detectors[cacheName].cacheUserLanguage(lng, _this2.options); + }); + } + }]); - rowMajor_matrix[0] = this.get(0, 0); - rowMajor_matrix[1] = this.get(1, 0); - rowMajor_matrix[2] = this.get(2, 0); - rowMajor_matrix[3] = this.get(3, 0); + return Browser; + }(); - rowMajor_matrix[4] = this.get(0, 1); - rowMajor_matrix[5] = this.get(1, 1); - rowMajor_matrix[6] = this.get(2, 1); - rowMajor_matrix[7] = this.get(3, 1); + Browser.type = 'languageDetector'; - rowMajor_matrix[8] = this.get(0, 2); - rowMajor_matrix[9] = this.get(1, 2); - rowMajor_matrix[10] = this.get(2, 2); - rowMajor_matrix[11] = this.get(3, 2); + return Browser; - rowMajor_matrix[12] = this.get(0, 3); - rowMajor_matrix[13] = this.get(1, 3); - rowMajor_matrix[14] = this.get(2, 3); - rowMajor_matrix[15] = this.get(3, 3); - - return rowMajor_matrix; -}; - -/** - * 어떤 일을 하고 있습니까? - * @param angRad 변수 - * @param axis_x 변수 - * @param axis_y 변수 - * @param axis_z 변수 - */ -Matrix4.getRotationDegZXYMatrix = function(zRotDeg, xRotDeg, yRotDeg, resultMatrix4) -{ - // static function.*** - var xRotMatrix = new Matrix4(); // created as identity matrix. - var yRotMatrix = new Matrix4(); // created as identity matrix. - var zRotMatrix = new Matrix4(); // created as identity matrix. - - if (zRotDeg !== undefined && zRotDeg !== 0) - { zRotMatrix.rotationAxisAngDeg(zRotDeg, 0.0, 0.0, 1.0); } - - if (xRotDeg !== undefined && xRotDeg !== 0) - { xRotMatrix.rotationAxisAngDeg(xRotDeg, 1.0, 0.0, 0.0); } - - if (yRotDeg !== undefined && yRotDeg !== 0) - { yRotMatrix.rotationAxisAngDeg(yRotDeg, 0.0, 1.0, 0.0); } +})); +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.i18nextXHRBackend = factory()); +}(this, (function () { 'use strict'; +var arr = []; +var each = arr.forEach; +var slice = arr.slice; - if (resultMatrix4 === undefined) - { resultMatrix4 = new Matrix4(); } // created as identity matrix. - +function defaults(obj) { + each.call(slice.call(arguments, 1), function (source) { + if (source) { + for (var prop in source) { + if (obj[prop] === undefined) obj[prop] = source[prop]; + } + } + }); + return obj; +} - var zRotatedTMatrix; - var zxRotatedTMatrix; - var zxyRotatedTMatrix; +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; - zRotatedTMatrix = zRotMatrix; - zxRotatedTMatrix = xRotMatrix.getMultipliedByMatrix(zRotatedTMatrix, zxRotatedTMatrix); - zxyRotatedTMatrix = yRotMatrix.getMultipliedByMatrix(zxRotatedTMatrix, zxyRotatedTMatrix); - - resultMatrix4 = zxyRotatedTMatrix; - return resultMatrix4; -}; +function addQueryString(url, params) { + if (params && (typeof params === 'undefined' ? 'undefined' : _typeof(params)) === 'object') { + var queryString = '', + e = encodeURIComponent; -/** - * 어떤 일을 하고 있습니까? - * @param angDeg 변수 - * @param axis_x 변수 - * @param axis_y 변수 - * @param axis_z 변수 - */ -Matrix4.prototype.rotationAxisAngDeg = function(angDeg, axis_x, axis_y, axis_z) -{ - var quaternion = new Quaternion(); - quaternion.rotationAngDeg(angDeg, axis_x, axis_y, axis_z); - this.rotationByQuaternion(quaternion); - quaternion = undefined; -}; + // Must encode data + for (var paramName in params) { + queryString += '&' + e(paramName) + '=' + e(params[paramName]); + } -/** - * 어떤 일을 하고 있습니까? - * @param angRad 변수 - * @param axis_x 변수 - * @param axis_y 변수 - * @param axis_z 변수 - */ -Matrix4.prototype.rotationAxisAngRad = function(angRad, axis_x, axis_y, axis_z) -{ - var quaternion = new Quaternion(); - quaternion.rotationAngRad(angRad, axis_x, axis_y, axis_z); - this.rotationByQuaternion(quaternion); - quaternion = undefined; -}; + if (!queryString) { + return url; + } -/** - * 어떤 일을 하고 있습니까? - * @param quaternion 변수 - */ -Matrix4.prototype.rotationByQuaternion = function(quaternion) -{ - var w = quaternion.w; - var x = quaternion.x; - var y = quaternion.y; - var z = quaternion.z; + url = url + (url.indexOf('?') !== -1 ? '&' : '?') + queryString.slice(1); + } - this._floatArrays[this.getIndexOfArray(0, 0)] = 1 - 2*y*y - 2*z*z; - this._floatArrays[this.getIndexOfArray(0, 1)] = 2*x*y + 2*z*w; - this._floatArrays[this.getIndexOfArray(0, 2)] = 2*x*z - 2*y*w; - this._floatArrays[this.getIndexOfArray(0, 3)] = 0.0; + return url; +} - this._floatArrays[this.getIndexOfArray(1, 0)] = 2*x*y - 2*z*w; - this._floatArrays[this.getIndexOfArray(1, 1)] = 1 - 2*x*x - 2*z*z; - this._floatArrays[this.getIndexOfArray(1, 2)] = 2*y*z + 2*x*w; - this._floatArrays[this.getIndexOfArray(1, 3)] = 0.0; +// https://gist.github.com/Xeoncross/7663273 +function ajax(url, options, callback, data, cache) { - this._floatArrays[this.getIndexOfArray(2, 0)] = 2*x*z + 2*y*w; - this._floatArrays[this.getIndexOfArray(2, 1)] = 2*y*z - 2*x*w; - this._floatArrays[this.getIndexOfArray(2, 2)] = 1 - 2*x*x - 2*y*y; - this._floatArrays[this.getIndexOfArray(2, 3)] = 0.0; + if (data && (typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object') { + if (!cache) { + data['_t'] = new Date(); + } + // URL encoded form data must be in querystring format + data = addQueryString('', data).slice(1); + } - this._floatArrays[this.getIndexOfArray(3, 0)] = 0.0; - this._floatArrays[this.getIndexOfArray(3, 1)] = 0.0; - this._floatArrays[this.getIndexOfArray(3, 2)] = 0.0; - this._floatArrays[this.getIndexOfArray(3, 3)] = 1.0; -}; + if (options.queryStringParams) { + url = addQueryString(url, options.queryStringParams); + } -/** - * 어떤 일을 하고 있습니까? - * @param float32array 변수 - */ -Matrix4.prototype.setByFloat32Array = function(float32array) -{ - for (var i=0; i<16; i++) - { - this._floatArrays[i] = float32array[i]; - } -}; + try { + var x; + if (XMLHttpRequest) { + x = new XMLHttpRequest(); + } else { + x = new ActiveXObject('MSXML2.XMLHTTP.3.0'); + } + x.open(data ? 'POST' : 'GET', url, 1); + if (!options.crossDomain) { + x.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); + } + x.withCredentials = !!options.withCredentials; + if (data) { + x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); + } + if (x.overrideMimeType) { + x.overrideMimeType("application/json"); + } + var h = options.customHeaders; + if (h) { + for (var i in h) { + x.setRequestHeader(i, h[i]); + } + } + x.onreadystatechange = function () { + x.readyState > 3 && callback && callback(x.responseText, x); + }; + x.send(data); + } catch (e) { + console && console.log(e); + } +} -/** - * 어떤 일을 하고 있습니까? - * @param col 변수 - * @param row 변수 - */ -Matrix4.prototype.getIndexOfArray = function(col, row) -{ - return 4 * col + row; -}; +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); -/** - * 어떤 일을 하고 있습니까? - * @param col 변수 - * @param row 변수 - */ -Matrix4.prototype.get = function(col, row) -{ - if (this._floatArrays === null) - { return null; } - - return this._floatArrays[this.getIndexOfArray(col, row)]; -}; +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -/** - * 어떤 일을 하고 있습니까? - * @param col 변수 - * @param row 변수 - */ -Matrix4.prototype.set = function(col, row, value) -{ - this._floatArrays[this.getIndexOfArray(col, row)] = value; -}; +function getDefaults() { + return { + loadPath: '/locales/{{lng}}/{{ns}}.json', + addPath: '/locales/add/{{lng}}/{{ns}}', + allowMultiLoading: false, + parse: JSON.parse, + crossDomain: false, + ajax: ajax + }; +} -/** - * 어떤 일을 하고 있습니까? - * @param point3d 변수 - * @param result_point3d 변수 - * @returns result_point3d - */ -Matrix4.prototype.transformPoint3D = function(point3d, result_point3d) -{ - if (result_point3d === undefined) { result_point3d = new Point3D(); } +var Backend = function () { + function Backend(services) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var x = point3d.x; - var y = point3d.y; - var z = point3d.z; + _classCallCheck(this, Backend); - result_point3d.x = x*this.get(0, 0) + y*this.get(1, 0) + z*this.get(2, 0) + this.get(3, 0); - result_point3d.y = x*this.get(0, 1) + y*this.get(1, 1) + z*this.get(2, 1) + this.get(3, 1); - result_point3d.z = x*this.get(0, 2) + y*this.get(1, 2) + z*this.get(2, 2) + this.get(3, 2); + this.init(services, options); - return result_point3d; -}; + this.type = 'backend'; + } -/** - * 어떤 일을 하고 있습니까? - * @param point3d 변수 - * @param result_point3d 변수 - * @returns result_point3d - */ -Matrix4.prototype.rotatePoint3D = function(point3d, result_point3d) -{ - if (result_point3d === undefined) { result_point3d = new Point3D(); } + _createClass(Backend, [{ + key: 'init', + value: function init(services) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var x = point3d.x; - var y = point3d.y; - var z = point3d.z; + this.services = services; + this.options = defaults(options, this.options || {}, getDefaults()); + } + }, { + key: 'readMulti', + value: function readMulti(languages, namespaces, callback) { + var loadPath = this.options.loadPath; + if (typeof this.options.loadPath === 'function') { + loadPath = this.options.loadPath(languages, namespaces); + } - result_point3d.x = x*this.get(0, 0) + y*this.get(1, 0) + z*this.get(2, 0); - result_point3d.y = x*this.get(0, 1) + y*this.get(1, 1) + z*this.get(2, 1); - result_point3d.z = x*this.get(0, 2) + y*this.get(1, 2) + z*this.get(2, 2); + var url = this.services.interpolator.interpolate(loadPath, { lng: languages.join('+'), ns: namespaces.join('+') }); - return result_point3d; -}; + this.loadUrl(url, callback); + } + }, { + key: 'read', + value: function read(language, namespace, callback) { + var loadPath = this.options.loadPath; + if (typeof this.options.loadPath === 'function') { + loadPath = this.options.loadPath([language], [namespace]); + } -/** - * 어떤 일을 하고 있습니까? - * @param matrix 변수 - * @param resultMat 변수 - * @returns resultMat - */ -Matrix4.prototype.getMultipliedByMatrix = function(matrix, resultMat) -{ + var url = this.services.interpolator.interpolate(loadPath, { lng: language, ns: namespace }); - if (resultMat === undefined) { resultMat = new Matrix4(); } + this.loadUrl(url, callback); + } + }, { + key: 'loadUrl', + value: function loadUrl(url, callback) { + var _this = this; + + this.options.ajax(url, this.options, function (data, xhr) { + if (xhr.status >= 500 && xhr.status < 600) return callback('failed loading ' + url, true /* retry */); + if (xhr.status >= 400 && xhr.status < 500) return callback('failed loading ' + url, false /* no retry */); + + var ret = void 0, + err = void 0; + try { + ret = _this.options.parse(data, url); + } catch (e) { + err = 'failed parsing ' + url + ' to json'; + } + if (err) return callback(err, false); + callback(null, ret); + }); + } + }, { + key: 'create', + value: function create(languages, namespace, key, fallbackValue) { + var _this2 = this; - for (var i=0; i<4; i++) - { - for (var j=0; j<4; j++) - { - var idx = this.getIndexOfArray(i, j); - resultMat._floatArrays[idx] = 0.0; - for (var k=0; k<4; k++) - { - resultMat._floatArrays[idx] += matrix.get(k, j) * this.get(i, k); - } - } - } - return resultMat; -}; + if (typeof languages === 'string') languages = [languages]; -Matrix4.prototype.setToPerspectiveProjection = function (fovyrad, aspect, near, far) -{ - var yScale = 1.0 / Math.tan(fovyrad / 2); - var xScale = yScale / aspect; - var nearmfar = near - far; - this.setByFloat32Array([xScale, 0, 0, 0, - 0, yScale, 0, 0, - 0, 0, (far + near) / nearmfar, -1, - 0, 0, 2*far*near / nearmfar, 0 ]); -}; + var payload = {}; + payload[key] = fallbackValue || ''; -/** - * 어떤 일을 하고 있습니까? - * @param matrix 변수 - * @param resultMat 변수 - * @returns resultMat - */ -Matrix4.prototype.copyFromMatrix4 = function(matrix) -{ - for (var i=0; i<16; i++) - { - this._floatArrays[i] = matrix._floatArrays[i]; - } -}; + languages.forEach(function (lng) { + var url = _this2.services.interpolator.interpolate(_this2.options.addPath, { lng: lng, ns: namespace }); -/** - * 어떤 일을 하고 있습니까? - * @param matrix 변수 - * @param resultMat 변수 - * @returns resultMat - */ -Matrix4.prototype.copyFromFloatArray = function(floatArrays) -{ - for (var i=0; i<16; i++) - { - this._floatArrays[i] = floatArrays[i]; - } -}; + _this2.options.ajax(url, _this2.options, function (data, xhr) { + //const statusCode = xhr.status.toString(); + // TODO: if statusCode === 4xx do log + }, payload); + }); + } + }]); -/** - * Returns if the value is aproximately equal to the valueToCompare with error. - * @returns {boolean} are equal. - */ -Matrix4.prototype.computeMatrixType = function() -{ - // matrixType = 0 -> identity matrix. - // matrixType = 1 -> translate matrix. - // matrixType = 2 -> transform matrix. - - var error = 10E-8; - if (this.isRotationIdentity()) - { - // check if there are translation. - if (this.aproxEqual(this._floatArrays[3], 0, error)) - { - if (this.aproxEqual(this._floatArrays[7], 0, error)) - { - if (this.aproxEqual(this._floatArrays[11], 0, error)) - { - if (this.aproxEqual(this._floatArrays[12], 0, error)) - { - if (this.aproxEqual(this._floatArrays[13], 0, error)) - { - if (this.aproxEqual(this._floatArrays[14], 0, error)) - { - if (this.aproxEqual(this._floatArrays[15], 1, error)) - { - return 0; - } - else { return 1; } - } - else { return 1; } - } - else { return 1; } - } - else { return 1; } - } - else { return 1; } - } - else { return 1; } - } - else { return 1; } - } - else - { - return 2; - } -}; + return Backend; +}(); -/** - * Returns if the value is aproximately equal to the valueToCompare with error. - * @returns {boolean} are equal. - */ -Matrix4.prototype.aproxEqual = function(value, valueToCompare, error) -{ - if (error === undefined) - { error = 10E-8; } - - if (value === valueToCompare) - { - return true; - } - else - { - if (value > (valueToCompare - error) && value < (valueToCompare + error)) - { return true; } - else - { return false; } - } -}; +Backend.type = 'backend'; -/** - * Returns if the arrayA equal to the arrayB. - * @returns {boolean} are equal. - */ -Matrix4.areEqualArrays = function(arrayA, arrayB) -{ - var areEqual = true; - var i=0; - while (areEqual && i<16) - { - if (arrayA[i] !== arrayB[i]) - { - areEqual = false; - } - i++; - } - - return areEqual; -}; +return Backend; -/** - * Returns if the matrix is identity. - * @returns {boolean} matrixIsIdentity. - */ -Matrix4.prototype.isIdentity = function(error) -{ - if (this.isRotationIdentity()) - { - if (this.aproxEqual(this._floatArrays[3], 0, error)) - { - if (this.aproxEqual(this._floatArrays[7], 0, error)) - { - if (this.aproxEqual(this._floatArrays[11], 0, error)) - { - if (this.aproxEqual(this._floatArrays[12], 0, error)) - { - if (this.aproxEqual(this._floatArrays[13], 0, error)) - { - if (this.aproxEqual(this._floatArrays[14], 0, error)) - { - if (this.aproxEqual(this._floatArrays[15], 1, error)) - { - return true; - } - else { return false; } - } - else { return false; } - } - else { return false; } - } - else { return false; } - } - else { return false; } - } - else { return false; } - } - else { return false; } - } - else - { return false; } -}; +}))); /** - * Returns if the matrix is identity. - * @returns {boolean} matrixIsIdentity. + * @file tgajs - Javascript decoder & (experimental) encoder for TGA files + * @desc tgajs is a fork from https://github.com/vthibault/jsTGALoader + * @author Vincent Thibault (Original author) + * @author Lukas Schmitt + * @version 1.0.0 */ -Matrix4.prototype.isRotationIdentity = function(error) -{ - if (this.aproxEqual(this._floatArrays[0], 1, error)) - { - if (this.aproxEqual(this._floatArrays[1], 0, error)) - { - if (this.aproxEqual(this._floatArrays[2], 0, error)) - { - if (this.aproxEqual(this._floatArrays[4], 0, error)) - { - if (this.aproxEqual(this._floatArrays[5], 1, error)) - { - if (this.aproxEqual(this._floatArrays[6], 0, error)) - { - if (this.aproxEqual(this._floatArrays[8], 0, error)) - { - if (this.aproxEqual(this._floatArrays[9], 0, error)) - { - if (this.aproxEqual(this._floatArrays[10], 1, error)) - { - return true; - } - else { return false; } - } - else { return false; } - } - else { return false; } - } - else { return false; } - } - else { return false; } - } - else { return false; } - } - else { return false; } - } - else { return false; } - } - else { return false; } -}; - - - +/* Copyright (c) 2013, Vincent Thibault. All rights reserved. + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +(function (_global) { + 'use strict'; + /** + * @var {object} TGA type constants + */ + Targa.Type = { + NO_DATA: 0, + INDEXED: 1, + RGB: 2, + GREY: 3, + RLE_INDEXED: 9, + RLE_RGB: 10, + RLE_GREY: 11 + }; + /** + * @var {object} TGA origin constants + */ + Targa.Origin = { + BOTTOM_LEFT: 0x00, + BOTTOM_RIGHT: 0x01, + TOP_LEFT: 0x02, + TOP_RIGHT: 0x03, + SHIFT: 0x04, + MASK: 0x30, + ALPHA: 0x08 + }; + Targa.HEADER_SIZE = 18; + Targa.FOOTER_SIZE = 26; + Targa.LITTLE_ENDIAN = true; + Targa.RLE_BIT = 0x80; + Targa.RLE_MASK = 0x7f; + Targa.RLE_PACKET = 1; + Targa.RAW_PACKET = 2; + Targa.SIGNATURE = "TRUEVISION-XFILE.\0"; + /** + * TGA Namespace + * @constructor + */ + function Targa() { + if (arguments.length == 1) { + var h = arguments[0]; + this.header = createHeader(h); + setHeaderBooleans(this.header); + checkHeader(this.header); + } + } + /** + * Sets header or default values + * @param header header + * @returns {Object} + */ + function createHeader(header) { + return { + /* 0x00 BYTE */ idLength: defaultFor(header.idLength, 0), + /* 0x01 BYTE */ colorMapType: defaultFor(header.colorMapType, 0), + /* 0x02 BYTE */ imageType: defaultFor(header.imageType, Targa.Type.RGB), + /* 0x03 WORD */ colorMapIndex: defaultFor(header.colorMapIndex, 0), + /* 0x05 WORD */ colorMapLength: defaultFor(header.colorMapLength, 0), + /* 0x07 BYTE */ colorMapDepth: defaultFor(header.colorMapDepth, 0), + /* 0x08 WORD */ offsetX: defaultFor(header.offsetX, 0), + /* 0x0a WORD */ offsetY: defaultFor(header.offsetY, 0), + /* 0x0c WORD */ width: defaultFor(header.width, 0), + /* 0x0e WORD */ height: defaultFor(header.height, 0), + /* 0x10 BYTE */ pixelDepth: defaultFor(header.pixelDepth,32), + /* 0x11 BYTE */ flags: defaultFor(header.flags, 8) + }; + } + function defaultFor(arg, val) { return typeof arg !== 'undefined' ? arg : val; } + /** + * Write footer of TGA file to view + * Byte 0-3 - Extension Area Offset, 0 if no Extension Area exists + * Byte 4-7 - Developer Directory Offset, 0 if no Developer Area exists + * Byte 8-25 - Signature + * @param {Uint8Array} footer + */ + function writeFooter(footer) { + var signature = Targa.SIGNATURE; + var offset = footer.byteLength - signature.length; + for (var i = 0; i < signature.length; i++) { + footer[offset + i] = signature.charCodeAt(i); + } + } + /** + * Write header of TGA file to view + * @param header + * @param view DataView + */ + function writeHeader(header, view) { + var littleEndian = Targa.LITTLE_ENDIAN; + view.setUint8(0x00, header.idLength); + view.setUint8(0x01, header.colorMapType); + view.setUint8(0x02, header.imageType); + view.setUint16(0x03, header.colorMapIndex, littleEndian); + view.setUint16(0x05, header.colorMapLength, littleEndian); + view.setUint8(0x07, header.colorMapDepth); + view.setUint16(0x08, header.offsetX, littleEndian); + view.setUint16(0x0a, header.offsetY, littleEndian); + view.setUint16(0x0c, header.width, littleEndian); + view.setUint16(0x0e, header.height, littleEndian); + view.setUint8(0x10, header.pixelDepth); + view.setUint8(0x11, header.flags); + } + function readHeader(view) { + var littleEndian = Targa.LITTLE_ENDIAN; + // Not enough data to contain header ? + if (view.byteLength < 0x12) { + throw new Error('Targa::load() - Not enough data to contain header'); + } + var header = {}; + header.idLength = view.getUint8(0x00); + header.colorMapType = view.getUint8(0x01); + header.imageType = view.getUint8(0x02); + header.colorMapIndex = view.getUint16(0x03, littleEndian); + header.colorMapLength = view.getUint16(0x05, littleEndian); + header.colorMapDepth = view.getUint8(0x07); + header.offsetX = view.getUint16(0x08, littleEndian); + header.offsetY = view.getUint16(0x0a, littleEndian); + header.width = view.getUint16(0x0c, littleEndian); + header.height = view.getUint16(0x0e, littleEndian); + header.pixelDepth = view.getUint8(0x10); + header.flags = view.getUint8(0x11); + return header; + } -'use strict'; + /** + * Set additional header booleans + * @param header + */ + function setHeaderBooleans(header) { + header.hasEncoding = (header.imageType === Targa.Type.RLE_INDEXED || header.imageType === Targa.Type.RLE_RGB || header.imageType === Targa.Type.RLE_GREY); + header.hasColorMap = (header.imageType === Targa.Type.RLE_INDEXED || header.imageType === Targa.Type.INDEXED); + header.isGreyColor = (header.imageType === Targa.Type.RLE_GREY || header.imageType === Targa.Type.GREY); + header.bytePerPixel = header.pixelDepth >> 3; + header.origin = (header.flags & Targa.Origin.MASK) >> Targa.Origin.SHIFT; + header.alphaBits = header.flags & Targa.Origin.ALPHA; + } -var Messages = {}; + /** + * Check the header of TGA file to detect errors + * + * @param {object} header tga header structure + * @throws Error + */ + function checkHeader(header) { + // What the need of a file without data ? + if (header.imageType === Targa.Type.NO_DATA) { + throw new Error('Targa::checkHeader() - No data'); + } -Messages.CONSTRUCT_ERROR = "이 객체는 new를 사용하여 생성해야 합니다."; -'use strict'; + // Indexed type + if (header.hasColorMap) { + if (header.colorMapLength > 256 || header.colorMapType !== 1) { + throw new Error('Targa::checkHeader() - Unsupported colormap for indexed type'); + } + if (header.colorMapDepth !== 16 && header.colorMapDepth !== 24 && header.colorMapDepth !== 32) { + throw new Error('Targa::checkHeader() - Unsupported colormap depth'); + } + } + else { + if (header.colorMapType) { + throw new Error('Targa::checkHeader() - Why does the image contain a palette ?'); + } + } -/** - * 어떤 일을 하고 있습니까? - * @class MouseAction - */ -var MouseAction = function() -{ - if (!(this instanceof MouseAction)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - // current.*** - this.curX; - this.curY; - this.curCamCoordPoint; - this.curWorldPoint; - this.curWorldPoint2; - this.curModelViewMatrix = new Matrix4(); - this.curModelViewMatrixInv = new Matrix4(); - - // start.*** - this.strX; - this.strY; - this.strCamCoordPoint; - this.strWorldPoint; - - // cameraStatus.*** - this.curCamera = new Camera(); - this.curCameraTarget = new Float32Array([0.0, 0.0, 0.0]); - - // Camera rotation.*** - this.camRotPoint = new Point3D(); - this.camRotAxis = new Point3D(); - -}; + // Check image size + if (header.width <= 0 || header.height <= 0) { + throw new Error('Targa::checkHeader() - Invalid image size'); + } -MouseAction.prototype.saveCurrentToStart = function() -{ - this.strX = this.curX; - this.strY = this.curY; - - // world point.*** - if (this.strWorldPoint === undefined) - { this.strWorldPoint = new Point3D(); } - - if (this.curWorldPoint) - { - this.strWorldPoint.copyFrom(this.curWorldPoint); - } - - // camCoord point.*** - if (this.strCamCoordPoint === undefined) - { this.strCamCoordPoint = new Point3D(); } - - if (this.curCamCoordPoint) - { - this.strCamCoordPoint.copyFrom(this.curCamCoordPoint); - } -}; + // Check pixel size + if (header.pixelDepth !== 8 && + header.pixelDepth !== 16 && + header.pixelDepth !== 24 && + header.pixelDepth !== 32) { + throw new Error('Targa::checkHeader() - Invalid pixel size "' + header.pixelDepth + '"'); + } + // Check alpha size + if (header.alphaBits !== 0 && + header.alphaBits !== 1 && + header.alphaBits !== 8) { + throw new Error('Targa::checkHeader() - Unsuppported alpha size'); + } + } + /** + * Decode RLE compression + * + * @param {Uint8Array} data + * @param {number} bytesPerPixel bytes per Pixel + * @param {number} outputSize in byte: width * height * pixelSize + */ + function decodeRLE(data, bytesPerPixel, outputSize) { + var pos, c, count, i, offset; + var pixels, output; + output = new Uint8Array(outputSize); + pixels = new Uint8Array(bytesPerPixel); + offset = 0; // offset in data + pos = 0; // offset for output + while (pos < outputSize) { + c = data[offset++]; // current byte to check + count = (c & Targa.RLE_MASK) + 1; // repetition count of pixels, the lower 7 bits + 1 + // RLE packet, if highest bit is set to 1. + if (c & Targa.RLE_BIT) { + // Copy pixel values to be repeated to tmp array + for (i = 0; i < bytesPerPixel; ++i) { + pixels[i] = data[offset++]; + } + // Copy pixel values * count to output + for (i = 0; i < count; ++i) { + output.set(pixels, pos); + pos += bytesPerPixel; + } + } + // Raw packet (Non-Run-Length Encoded) + else { + count *= bytesPerPixel; + for (i = 0; i < count; ++i) { + output[pos++] = data[offset++]; + } + } + } + if (pos > outputSize) { + throw new Error("Targa::decodeRLE() - Read bytes: " + pos + " Expected bytes: " + outputSize); + } + return output; + } + /** + * Encode ImageData object with RLE compression + * + * @param header + * @param imageData from canvas to compress + */ + function encodeRLE(header, imageData) { + var maxRepetitionCount = 128; + var i; + var data = imageData; + var output = []; // output size is unknown + var pos = 0; // pos in imageData array + var bytesPerPixel = header.pixelDepth >> 3; + var offset = 0; + var packetType, packetLength, packetHeader; + var tgaLength = header.width * header.height * bytesPerPixel; + var isSamePixel = function isSamePixel(pos, offset) { + for (var i = 0; i < bytesPerPixel; i++) { + if (data[pos * bytesPerPixel + i] !== data[offset * bytesPerPixel + i]) { + return false; + } + } + return true; + }; + var getPacketType = function(pos) { + if (isSamePixel(pos, pos + 1)) { + return Targa.RLE_PACKET; + } + return Targa.RAW_PACKET; + }; + while (pos * bytesPerPixel < data.length && pos * bytesPerPixel < tgaLength) { + // determine packet type + packetType = getPacketType(pos); + // determine packet length + packetLength = 0; + if (packetType === Targa.RLE_PACKET) { + while (pos + packetLength < data.length + && packetLength < maxRepetitionCount + && isSamePixel(pos, pos + packetLength)) { + packetLength++; + } + } else { // packetType === Targa.RAW_PACKET + while (pos + packetLength < data.length + && packetLength < maxRepetitionCount + && getPacketType(pos + packetLength) === Targa.RAW_PACKET) { + packetLength++; + } + } + // write packet header + packetHeader = packetLength - 1; + if (packetType === Targa.RLE_PACKET) { + packetHeader |= Targa.RLE_BIT; + } + output[offset++] = packetHeader; + // write rle packet pixel OR raw pixels + if (packetType === Targa.RLE_PACKET) { + for (i = 0; i < bytesPerPixel; i++) { + output[i + offset] = data[i + pos * bytesPerPixel]; + } + offset += bytesPerPixel; + } else { + for (i = 0; i < bytesPerPixel * packetLength; i++) { + output[i + offset] = data[i + pos * bytesPerPixel]; + } + offset += bytesPerPixel * packetLength; + } + pos += packetLength; + } + return new Uint8Array(output); + } + /** + * Return a ImageData object from a TGA file (8bits) + * + * @param {Array} imageData - ImageData to bind + * @param {Array} indexes - index to colorMap + * @param {Array} colorMap + * @param {number} width + * @param {number} y_start - start at y pixel. + * @param {number} x_start - start at x pixel. + * @param {number} y_step - increment y pixel each time. + * @param {number} y_end - stop at pixel y. + * @param {number} x_step - increment x pixel each time. + * @param {number} x_end - stop at pixel x. + * @returns {Array} imageData + */ + function getImageData8bits(imageData, indexes, colorMap, width, y_start, y_step, y_end, x_start, x_step, x_end) { + var color, index, offset, i, x, y; + var bytePerPixel = this.header.colorMapDepth >> 3; + for (i = 0, y = y_start; y !== y_end; y += y_step) { + for (x = x_start; x !== x_end; x += x_step, i++) { + offset = (x + width * y) * 4; + index = indexes[i] * bytePerPixel; + if (bytePerPixel === 4) { + imageData[offset ] = colorMap[index + 2]; // red + imageData[offset + 1] = colorMap[index + 1]; // green + imageData[offset + 2] = colorMap[index ]; // blue + imageData[offset + 3] = colorMap[index + 3]; // alpha + } else if (bytePerPixel === 3) { + imageData[offset ] = colorMap[index + 2]; // red + imageData[offset + 1] = colorMap[index + 1]; // green + imageData[offset + 2] = colorMap[index ]; // blue + imageData[offset + 3] = 255; // alpha + } else if (bytePerPixel === 2) { + color = colorMap[index] | (colorMap[index + 1] << 8); + imageData[offset ] = (color & 0x7C00) >> 7; // red + imageData[offset + 1] = (color & 0x03E0) >> 2; // green + imageData[offset + 2] = (color & 0x001F) << 3; // blue + imageData[offset + 3] = (color & 0x8000) ? 0 : 255; // overlay 0 = opaque and 1 = transparent Discussion at: https://bugzilla.gnome.org/show_bug.cgi?id=683381 + } + } + } + return imageData; + } + /** + * Return a ImageData object from a TGA file (16bits) + * + * @param {Array} imageData - ImageData to bind + * @param {Array} pixels data + * @param {Array} colormap - not used + * @param {number} width + * @param {number} y_start - start at y pixel. + * @param {number} x_start - start at x pixel. + * @param {number} y_step - increment y pixel each time. + * @param {number} y_end - stop at pixel y. + * @param {number} x_step - increment x pixel each time. + * @param {number} x_end - stop at pixel x. + * @returns {Array} imageData + */ + function getImageData16bits(imageData, pixels, colormap, width, y_start, y_step, y_end, x_start, x_step, x_end) { + var color, offset, i, x, y; + for (i = 0, y = y_start; y !== y_end; y += y_step) { + for (x = x_start; x !== x_end; x += x_step, i += 2) { + color = pixels[i] | (pixels[i + 1] << 8); + offset = (x + width * y) * 4; + imageData[offset ] = (color & 0x7C00) >> 7; // red + imageData[offset + 1] = (color & 0x03E0) >> 2; // green + imageData[offset + 2] = (color & 0x001F) << 3; // blue + imageData[offset + 3] = (color & 0x8000) ? 0 : 255; // overlay 0 = opaque and 1 = transparent Discussion at: https://bugzilla.gnome.org/show_bug.cgi?id=683381 + } + } + return imageData; + } + /** + * Return a ImageData object from a TGA file (24bits) + * + * @param {Array} imageData - ImageData to bind + * @param {Array} pixels data + * @param {Array} colormap - not used + * @param {number} width + * @param {number} y_start - start at y pixel. + * @param {number} x_start - start at x pixel. + * @param {number} y_step - increment y pixel each time. + * @param {number} y_end - stop at pixel y. + * @param {number} x_step - increment x pixel each time. + * @param {number} x_end - stop at pixel x. + * @returns {Array} imageData + */ + function getImageData24bits(imageData, pixels, colormap, width, y_start, y_step, y_end, x_start, x_step, x_end) { + var offset, i, x, y; + var bpp = this.header.pixelDepth >> 3; + for (i = 0, y = y_start; y !== y_end; y += y_step) { + for (x = x_start; x !== x_end; x += x_step, i += bpp) { + offset = (x + width * y) * 4; + imageData[offset + 3] = 255; // alpha + imageData[offset + 2] = pixels[i ]; // blue + imageData[offset + 1] = pixels[i + 1]; // green + imageData[offset ] = pixels[i + 2]; // red + } + } + return imageData; + } + /** + * Return a ImageData object from a TGA file (32bits) + * + * @param {Array} imageData - ImageData to bind + * @param {Array} pixels data from TGA file + * @param {Array} colormap - not used + * @param {number} width + * @param {number} y_start - start at y pixel. + * @param {number} x_start - start at x pixel. + * @param {number} y_step - increment y pixel each time. + * @param {number} y_end - stop at pixel y. + * @param {number} x_step - increment x pixel each time. + * @param {number} x_end - stop at pixel x. + * @returns {Array} imageData + */ + function getImageData32bits(imageData, pixels, colormap, width, y_start, y_step, y_end, x_start, x_step, x_end) { + var i, x, y, offset; + for (i = 0, y = y_start; y !== y_end; y += y_step) { + for (x = x_start; x !== x_end; x += x_step, i += 4) { + offset = (x + width * y) * 4; + imageData[offset + 2] = pixels[i ]; // blue + imageData[offset + 1] = pixels[i + 1]; // green + imageData[offset ] = pixels[i + 2]; // red + imageData[offset + 3] = pixels[i + 3]; // alpha + } + } + return imageData; + } + /** + * Return a ImageData object from a TGA file (32bits). Uses pre multiplied alpha values + * + * @param {Array} imageData - ImageData to bind + * @param {Array} pixels data from TGA file + * @param {Array} colormap - not used + * @param {number} width + * @param {number} y_start - start at y pixel. + * @param {number} x_start - start at x pixel. + * @param {number} y_step - increment y pixel each time. + * @param {number} y_end - stop at pixel y. + * @param {number} x_step - increment x pixel each time. + * @param {number} x_end - stop at pixel x. + * @returns {Array} imageData + */ + function getImageData32bitsPre(imageData, pixels, colormap, width, y_start, y_step, y_end, x_start, x_step, x_end) { + var i, x, y, offset, alpha; + for (i = 0, y = y_start; y !== y_end; y += y_step) { + for (x = x_start; x !== x_end; x += x_step, i += 4) { + offset = (x + width * y) * 4; + alpha = pixels[i + 3] * 255; // TODO needs testing + imageData[offset + 2] = pixels[i ] / alpha; // blue + imageData[offset + 1] = pixels[i + 1] / alpha; // green + imageData[offset ] = pixels[i + 2] / alpha; // red + imageData[offset + 3] = pixels[i + 3]; // alpha + } + } + return imageData; + } + /** + * Return a ImageData object from a TGA file (8bits grey) + * + * @param {Array} imageData - ImageData to bind + * @param {Array} pixels data + * @param {Array} colormap - not used + * @param {number} width + * @param {number} y_start - start at y pixel. + * @param {number} x_start - start at x pixel. + * @param {number} y_step - increment y pixel each time. + * @param {number} y_end - stop at pixel y. + * @param {number} x_step - increment x pixel each time. + * @param {number} x_end - stop at pixel x. + * @returns {Array} imageData + */ + function getImageDataGrey8bits(imageData, pixels, colormap, width, y_start, y_step, y_end, x_start, x_step, x_end) { + var color, offset, i, x, y; + for (i = 0, y = y_start; y !== y_end; y += y_step) { + for (x = x_start; x !== x_end; x += x_step, i++) { + color = pixels[i]; + offset = (x + width * y) * 4; + imageData[offset ] = color; // red + imageData[offset + 1] = color; // green + imageData[offset + 2] = color; // blue + imageData[offset + 3] = 255; // alpha + } + } -'use strict'; + return imageData; + } -/** - * 어떤 일을 하고 있습니까? - * @class ObjectMarker - * - */ -var ObjectMarker = function() -{ - if (!(this instanceof ObjectMarker)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - this.geoLocationData = new GeoLocationData(); - this.issue_id = null; - this.issue_type = null; - //this.latitude = 0; - //this.longitude = 0; - //this.height = 0; -}; -ObjectMarker.prototype.copyFrom = function(objMarker) -{ - if (objMarker === undefined) { return; } - - if (objMarker.geoLocationData) - { - this.geoLocationData.copyFrom(objMarker.geoLocationData); - } - - this.issue_id = objMarker.issue_id; - this.issue_type = objMarker.issue_type; -}; + /** + * Return a ImageData object from a TGA file (16bits grey) 8 Bit RGB and 8 Bit Alpha + * + * @param {Array} imageData - ImageData to bind + * @param {Array} pixels data + * @param {Array} colormap - not used + * @param {number} width + * @param {number} y_start - start at y pixel. + * @param {number} x_start - start at x pixel. + * @param {number} y_step - increment y pixel each time. + * @param {number} y_end - stop at pixel y. + * @param {number} x_step - increment x pixel each time. + * @param {number} x_end - stop at pixel x. + * @returns {Array} imageData + */ + function getImageDataGrey16bits(imageData, pixels, colormap, width, y_start, y_step, y_end, x_start, x_step, x_end) { + var color, offset, i, x, y; -/** - * 어떤 일을 하고 있습니까? - * @class ObjectMarkerManager - * - */ -var ObjectMarkerManager = function() -{ - if (!(this instanceof ObjectMarkerManager)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - this.objectMarkerArray = []; + for (i = 0, y = y_start; y !== y_end; y += y_step) { + for (x = x_start; x !== x_end; x += x_step, i += 2) { + color = pixels[i]; + offset = (x + width * y) * 4; + imageData[offset] = color; + imageData[offset + 1] = color; + imageData[offset + 2] = color; + imageData[offset + 3] = pixels[i + 1]; + } + } -}; + return imageData; + } -/** - * 어떤 일을 하고 있습니까? - * @class ObjectMarkerManager - * - */ -ObjectMarkerManager.prototype.newObjectMarker = function() -{ - var objMarker = new ObjectMarker(); - this.objectMarkerArray.push(objMarker); - return objMarker; -}; -'use strict'; -/** - * 어떤 일을 하고 있습니까? - * @class OcclusionCullingOctreeCell - * @param occlusionCullingOctree_Cell_Owner 변수 - */ -var OcclusionCullingOctreeCell = function(occlusionCullingOctree_Cell_Owner) -{ - if (!(this instanceof OcclusionCullingOctreeCell)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - this._ocCulling_Cell_owner = occlusionCullingOctree_Cell_Owner; - this.minX = 0.0; - this.maxX = 0.0; - this.minY = 0.0; - this.maxY = 0.0; - this.minZ = 0.0; - this.maxZ = 0.0; - this._indicesArray = []; // Visible objects indices.*** - this._subBoxesArray = []; - this.modelReferencedGroupsList; // undefined initially. -}; + /** + * Open a targa file using XHR, be aware with Cross Domain files... + * + * @param {string} path - Path of the filename to load + * @param {function} callback - callback to trigger when the file is loaded + */ + Targa.prototype.open = function targaOpen(path, callback) { + var req, tga = this; + req = new XMLHttpRequest(); + req.open('GET', path, true); + req.responseType = 'arraybuffer'; + req.onload = function () { + if (this.status === 200) { + tga.arrayBuffer = req.response; + tga.load(tga.arrayBuffer); + if (callback) { + callback.call(tga); + } + } + }; + req.send(null); + }; + + + function readFooter(view) { + var offset = view.byteLength - Targa.FOOTER_SIZE; + var signature = Targa.SIGNATURE; + + var footer = {}; + + var signatureArray = new Uint8Array(view.buffer, offset + 0x08, signature.length); + var str = String.fromCharCode.apply(null, signatureArray); + + if (!isSignatureValid(str)) { + footer.hasFooter = false; + return footer; + } + + footer.hasFooter = true; + footer.extensionOffset = view.getUint32(offset, Targa.LITTLE_ENDIAN); + footer.developerOffset = view.getUint32(offset + 0x04, Targa.LITTLE_ENDIAN); + footer.hasExtensionArea = footer.extensionOffset !== 0; + footer.hasDeveloperArea = footer.developerOffset !== 0; + + if (footer.extensionOffset) { + footer.attributeType = view.getUint8(footer.extensionOffset + 494); + } + + return footer; + } + + function isSignatureValid(str) { + var signature = Targa.SIGNATURE; + + for (var i = 0; i < signature.length; i++) { + if (str.charCodeAt(i) !== signature.charCodeAt(i)) { + return false; + } + } + + return true; + } + + /** + * Load and parse a TGA file + * + * @param {ArrayBuffer} data - TGA file buffer array + */ + Targa.prototype.load = function targaLoad(data) { + var dataView = new DataView(data); + + this.headerData = new Uint8Array(data, 0, Targa.HEADER_SIZE); + + this.header = readHeader(dataView); // Parse Header + setHeaderBooleans(this.header); + checkHeader(this.header); // Check if a valid TGA file (or if we can load it) + + var offset = Targa.HEADER_SIZE; + // Move to data + offset += this.header.idLength; + if (offset >= data.byteLength) { + throw new Error('Targa::load() - No data'); + } + + // Read palette + if (this.header.hasColorMap) { + var colorMapSize = this.header.colorMapLength * (this.header.colorMapDepth >> 3); + this.palette = new Uint8Array(data, offset, colorMapSize); + offset += colorMapSize; + } + + var bytesPerPixel = this.header.pixelDepth >> 3; + var imageSize = this.header.width * this.header.height; + var pixelTotal = imageSize * bytesPerPixel; + + if (this.header.hasEncoding) { // RLE encoded + var RLELength = data.byteLength - offset - Targa.FOOTER_SIZE; + var RLEData = new Uint8Array(data, offset, RLELength); + this.imageData = decodeRLE(RLEData, bytesPerPixel, pixelTotal); + } else { // RAW pixels + this.imageData = new Uint8Array(data, offset, this.header.hasColorMap ? imageSize : pixelTotal); + } + + this.footer = readFooter(dataView); + + if (this.header.alphaBits !== 0 || this.footer.hasExtensionArea && (this.footer.attributeType === 3 || this.footer.attributeType === 4)) { + this.footer.usesAlpha = true; + } + }; + + + /** + * Return a ImageData object from a TGA file + * + * @param {object} imageData - Optional ImageData to work with + * @returns {object} imageData + */ + Targa.prototype.getImageData = function targaGetImageData(imageData) { + var width = this.header.width; + var height = this.header.height; + var origin = (this.header.flags & Targa.Origin.MASK) >> Targa.Origin.SHIFT; + var x_start, x_step, x_end, y_start, y_step, y_end; + var getImageData; + + // Create an imageData + if (!imageData) { + if (document) { + imageData = document.createElement('canvas').getContext('2d').createImageData(width, height); + } + // In Thread context ? + else { + imageData = { + width: width, + height: height, + data: new Uint8ClampedArray(width * height * 4) + }; + } + } + + if (origin === Targa.Origin.TOP_LEFT || origin === Targa.Origin.TOP_RIGHT) { + y_start = 0; + y_step = 1; + y_end = height; + } + else { + y_start = height - 1; + y_step = -1; + y_end = -1; + } + + if (origin === Targa.Origin.TOP_LEFT || origin === Targa.Origin.BOTTOM_LEFT) { + x_start = 0; + x_step = 1; + x_end = width; + } + else { + x_start = width - 1; + x_step = -1; + x_end = -1; + } + + // TODO: use this.header.offsetX and this.header.offsetY ? + + switch (this.header.pixelDepth) { + case 8: + getImageData = this.header.isGreyColor ? getImageDataGrey8bits : getImageData8bits; + break; + + case 16: + getImageData = this.header.isGreyColor ? getImageDataGrey16bits : getImageData16bits; + break; + + case 24: + getImageData = getImageData24bits; + break; + + case 32: + if (this.footer.hasExtensionArea) { + if (this.footer.attributeType === 3) { // straight alpha + getImageData = getImageData32bits; + } else if (this.footer.attributeType === 4) { // pre multiplied alpha + getImageData = getImageData32bitsPre; + } else { // ignore alpha values if attributeType set to 0, 1, 2 + getImageData = getImageData24bits; + } + } else { + if (this.header.alphaBits !== 0) { + getImageData = getImageData32bits; + } else { // 32 bits Depth, but alpha Bits set to 0 + getImageData = getImageData24bits; + } + } + + break; + } + + getImageData.call(this, imageData.data, this.imageData, this.palette, width, y_start, y_step, y_end, x_start, x_step, x_end); + return imageData; + }; + + /** (Experimental) + * Encodes imageData into TGA format + * Only TGA True Color 32 bit with optional RLE encoding is supported for now + * @param imageData + */ + Targa.prototype.setImageData = function targaSetImageData(imageData) { + + if (!imageData) { + throw new Error('Targa::setImageData() - imageData argument missing'); + } + + var width = this.header.width; + var height = this.header.height; + var expectedLength = width * height * (this.header.pixelDepth >> 3); + var origin = (this.header.flags & Targa.Origin.MASK) >> Targa.Origin.SHIFT; + var x_start, x_step, x_end, y_start, y_step, y_end; + + if (origin === Targa.Origin.TOP_LEFT || origin === Targa.Origin.TOP_RIGHT) { + y_start = 0; // start bottom, step upward + y_step = 1; + y_end = height; + } else { + y_start = height - 1; // start at top, step downward + y_step = -1; + y_end = -1; + } + + if (origin === Targa.Origin.TOP_LEFT || origin === Targa.Origin.BOTTOM_LEFT) { + x_start = 0; // start left, step right + x_step = 1; + x_end = width; + } else { + x_start = width - 1; // start right, step left + x_step = -1; + x_end = -1; + } + + if (!this.imageData) { + this.imageData = new Uint8Array(expectedLength); + } + + // start top left if origin is bottom left + // swapping order of first two arguments does the trick for writing + // this converts canvas data to internal tga representation + // this.imageData contains tga data + getImageData32bits(this.imageData, imageData.data, this.palette, width, y_start, y_step, y_end, x_start, x_step, x_end); + + var data = this.imageData; + + if (this.header.hasEncoding) { + data = encodeRLE(this.header, data); + } + + var bufferSize = Targa.HEADER_SIZE + data.length + Targa.FOOTER_SIZE; + var buffer = new ArrayBuffer(bufferSize); + + this.arrayBuffer = buffer; + // create array, useful for inspecting data while debugging + this.headerData = new Uint8Array(buffer, 0, Targa.HEADER_SIZE); + this.RLEData = new Uint8Array(buffer, Targa.HEADER_SIZE, data.length); + this.footerData = new Uint8Array(buffer, Targa.HEADER_SIZE + data.length, Targa.FOOTER_SIZE); + + var headerView = new DataView(this.headerData.buffer); + writeHeader(this.header, headerView); + this.RLEData.set(data); + writeFooter(this.footerData); + }; + + /** + * Return a canvas with the TGA render on it + * + * @returns {object} CanvasElement + */ + Targa.prototype.getCanvas = function targaGetCanvas() { + var canvas, ctx, imageData; + + canvas = document.createElement('canvas'); + ctx = canvas.getContext('2d'); + imageData = ctx.createImageData(this.header.width, this.header.height); + + canvas.width = this.header.width; + canvas.height = this.header.height; + + ctx.putImageData(this.getImageData(imageData), 0, 0); + + return canvas; + }; + + + /** + * Return a dataURI of the TGA file + * + * @param {string} type - Optional image content-type to output (default: image/png) + * @returns {string} url + */ + Targa.prototype.getDataURL = function targaGetDatURL(type) { + return this.getCanvas().toDataURL(type || 'image/png'); + }; + + /** + * Return a objectURL of the TGA file + * The url can be used in the download attribute of a link + * @returns {string} url + */ + Targa.prototype.getBlobURL = function targetGetBlobURL() { + if (!this.arrayBuffer) { + throw new Error('Targa::getBlobURL() - No data available for blob'); + } + var blob = new Blob([this.arrayBuffer], { type: "image/x-tga" }); + return URL.createObjectURL(blob); + }; + + + // Find Context + var shim = {}; + if (typeof(exports) === 'undefined') { + if (typeof(define) === 'function' && typeof(define.amd) === 'object' && define.amd) { + define(function () { + return Targa; + }); + } else { + // Browser + shim.exports = typeof(window) !== 'undefined' ? window : _global; + } + } + else { + // Commonjs + shim.exports = exports; + } + + + // Export + if (shim.exports) { + shim.exports.TGA = Targa; + } + +})(this); + +'use strict'; +var Mago3D = (function() +{ +'use strict'; /** - * 어떤 일을 하고 있습니까? - * @param neoRefsIndices 변수 - * @param motherNeoRefsList 변수 + * color 처리 관련 도메인 + * @class ColorAPI */ -OcclusionCullingOctreeCell.prototype.createModelReferencedGroups = function(motherNeoRefsList) +var ColorAPI = {}; + +ColorAPI.changeColor = function(api, magoManager) { - var subBoxesCount = this._subBoxesArray.length; - if (subBoxesCount === 0) + var projectId = api.getProjectId(); + var dataKey = api.getDataKey(); + var objectIds = api.getObjectIds(); + var property = api.getProperty(); + var propertyKey = null; + var propertyValue = null; + if (property !== null && property !== "") { - if (this._indicesArray.length === 0) - { return; } - - if (this.modelReferencedGroupsList === undefined) - { this.modelReferencedGroupsList = new ModelReferencedGroupsList(); } - - this.modelReferencedGroupsList.createModelReferencedGroups(this._indicesArray, motherNeoRefsList); + var properties = property.split("="); + propertyKey = properties[0]; + propertyValue = properties[1]; } - else + var colorString = api.getColor(); + if (colorString === undefined || colorString === 0) + { return; } + + var color = api.getColor().split(","); + var rgbColor = [ color[0]/255, color[1]/255, color[2]/255 ] ; + + var isExistObjectIds = false; + if (objectIds !== null && objectIds.length !== 0) { - for (var i=0; i X - // |----------|----------| |----------|----------| - - if (this._subBoxesArray.length > 0) - { - var half_x= (this.maxX + this.minX)/2.0; - var half_y= (this.maxY + this.minY)/2.0; - var half_z= (this.maxZ + this.minZ)/2.0; - - this._subBoxesArray[0].setDimensions(this.minX, half_x, this.minY, half_y, this.minZ, half_z); - this._subBoxesArray[1].setDimensions(half_x, this.maxX, this.minY, half_y, this.minZ, half_z); - this._subBoxesArray[2].setDimensions(half_x, this.maxX, half_y, this.maxY, this.minZ, half_z); - this._subBoxesArray[3].setDimensions(this.minX, half_x, half_y, this.maxY, this.minZ, half_z); +var LodAPI = {}; - this._subBoxesArray[4].setDimensions(this.minX, half_x, this.minY, half_y, half_z, this.maxZ); - this._subBoxesArray[5].setDimensions(half_x, this.maxX, this.minY, half_y, half_z, this.maxZ); - this._subBoxesArray[6].setDimensions(half_x, this.maxX, half_y, this.maxY, half_z, this.maxZ); - this._subBoxesArray[7].setDimensions(this.minX, half_x, half_y, this.maxY, half_z, this.maxZ); - - for (var i=0; i this.minX && x this.minY && y this.minZ && z 0) - { - var center_x = (this.minX + this.maxX)/2.0; - var center_y = (this.minY + this.maxY)/2.0; - var center_z = (this.minZ + this.maxZ)/2.0; - - var intersectedSubBox_aux = undefined; - var intersectedSubBox_idx; - if (x 0) - { - result_visibleIndicesArray = intersectedSubBox._indicesArray; - if (result_modelReferencedGroup) - { - result_modelReferencedGroup = this.modelReferencedGroupsList; - } - } + this.ssaoRadius = null; + // + this.FPVMode = false; + + // input x, y, z + this.inputPoint = null; + // result x, y, z + this.resultPoint = null; - return result_visibleIndicesArray; + // General magoMode. + this.magoMode = CODE.magoMode.NORMAL; + + //position unit + this.unit = CODE.units.DEGREE; + + //for staticModel instantiate + this.instantiateObj = null; + + //for staticModel add + this.staticModelAttributeObj = null; + + //animation option. + this.animationOption = null; }; -/** - * 어떤 일을 하고 있습니까? - * @param expansionDist 변수 - */ -OcclusionCullingOctreeCell.prototype.expandBox = function(expansionDist) +API.prototype.getMagoEnable = function() { - this.minX -= expansionDist; - this.maxX += expansionDist; - this.minY -= expansionDist; - this.maxY += expansionDist; - this.minZ -= expansionDist; - this.maxZ += expansionDist; + return this.magoEnable; +}; +API.prototype.setMagoEnable = function(magoEnable) +{ + this.magoEnable = magoEnable; }; -/** - * 어떤 일을 하고 있습니까? - * @param arrayBuffer 변수 - * @param bytes_readed 변수 - * @param f4dReaderWriter 변수 - * @returns bytes_readed - */ -OcclusionCullingOctreeCell.prototype.parseArrayBuffer = function(arrayBuffer, bytes_readed, f4dReaderWriter) +API.prototype.getReturnable = function() { - // Important note: this is the version of neoGeometry.*** - // Important note: this is the version of neoGeometry.*** - // Important note: this is the version of neoGeometry.*** - var is_mother_cell = f4dReaderWriter.readInt8(arrayBuffer, bytes_readed, bytes_readed+1); bytes_readed += 1; - if (is_mother_cell) - { - // read the mother dimensions.*** - var minX = f4dReaderWriter.readFloat32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; - var maxX = f4dReaderWriter.readFloat32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; - var minY = f4dReaderWriter.readFloat32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; - var maxY = f4dReaderWriter.readFloat32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; - var minZ = f4dReaderWriter.readFloat32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; - var maxZ = f4dReaderWriter.readFloat32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; - - this.setDimensions(minX, maxX, minY, maxY, minZ, maxZ); - } - - var subBoxes_count = f4dReaderWriter.readUInt32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; - - if (subBoxes_count === 0) - { - var objects_count = f4dReaderWriter.readUInt32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; - for (var i=0; i 10E-8) - { - var alfa = -((this.a*r + this.b*s + this.c*t + this.d)/(den)); - - if (intersectionPoint === undefined) { intersectionPoint = new Point3D(); } - - intersectionPoint.set(r+alfa*u, s+alfa*v, t+alfa*w); - return intersectionPoint; - } - else { return undefined; } + return this.pitch; }; - -/** - * 어떤 일을 하고 있습니까? - * @param line 변수 - * @param intersectionPoint 변수 - */ -Plane.prototype.intersectionSphere = function(sphere) +API.prototype.setPitch = function(pitch) { - if (sphere === undefined || sphere.centerPoint === undefined) - { return Constant.INTERSECTION_OUTSIDE; } - - var sphereCenter = sphere.centerPoint; - - // calculate the distance by dotProduct.*** - var distance = sphereCenter.x * this.a + sphereCenter.y * this.b + sphereCenter.z * this.c + this.d; - - if (distance < -sphere.r) - { - return Constant.INTERSECTION_OUTSIDE; - } - else if (distance < sphere.r) - { - return Constant.INTERSECTION_INTERSECT; - } - return Constant.INTERSECTION_INSIDE; + this.pitch = pitch; }; - - - - - -'use strict'; - -/** -* 어떤 일을 하고 있습니까? -* @class Quaternion -*/ -var Quaternion = function() +API.prototype.getRoll = function() { - if (!(this instanceof Quaternion)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - this.x = 0.0; - this.y = 0.0; - this.z = 0.0; - this.w = 1.0; + return this.roll; }; - -/** - * 어떤 일을 하고 있습니까? - * @returns Math.sqrt(this.x*this.x + this.y*this.y + this.z*this.z + this.w*this.w ) - */ -Quaternion.prototype.Modul = function() +API.prototype.setRoll = function(roll) { - return Math.sqrt(this.x*this.x + this.y*this.y + this.z*this.z + this.w*this.w ); + this.roll = roll; }; -/** - * 어떤 일을 하고 있습니까? - */ -Quaternion.prototype.Unitary = function() +API.prototype.getProperty = function() { - var modul = this.Modul(); - this.x /= modul; - this.y /= modul; - this.z /= modul; - this.w /= modul; + return this.property; }; - -/** - * 어떤 일을 하고 있습니까? - * @param angDeg 변수 - * @param axis_x 변수 - * @param axis_y 변수 - * @param axis_z 변수 - */ -Quaternion.prototype.rotationAngDeg = function(angDeg, axis_x, axis_y, axis_z) +API.prototype.setProperty = function(property) { - var angRad = angDeg*Math.PI/180.0; - this.rotationAngRad(angRad, axis_x, axis_y, axis_z); + this.property = property; }; -/** - * 어떤 일을 하고 있습니까? - * @param angRad 변수 - * @param axis_x 변수 - * @param axis_y 변수 - * @param axis_z 변수 - */ -Quaternion.prototype.rotationAngRad = function(angRad, axis_x, axis_y, axis_z) +API.prototype.getColor = function() { - var s = Math.sqrt(axis_x*axis_x + axis_y*axis_y + axis_z*axis_z); - var error = 10E-13; - if (!s < error) - { - var c = 1.0/s; - var omega = 0.5 * angRad; - s = Math.sin(omega); - this.x = axis_x * c * s; - this.y = axis_y * c * s; - this.z = axis_z * c * s; - this.w = Math.cos(omega); - this.Unitary(); - } - else - { - this.x = 0.0; - this.y = 0.0; - this.z = 0.0; - this.w = 1.0; - } + return this.color; }; - -'use strict'; - -/** - * Quadtree based tile with thickness. - * @class SmartTile - */ -var SmartTile = function(smartTileName) +API.prototype.setColor = function(color) { - // +-----+-----+ - // | 3 | 2 | - // +-----+-----+ - // | 0 | 1 | - // +-----+-----+ - - if (!(this instanceof SmartTile)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - this.name; - if (smartTileName) - { this.name = smartTileName; } - this.depth; // mother tile depth = 0. - this.minGeographicCoord; // longitude, latitude, altitude. - this.maxGeographicCoord; // longitude, latitude, altitude. - this.sphereExtent; // cartesian position sphere in worldCoord. - this.subTiles; // array. - - this.nodeSeedsArray; - this.nodesArray; // nodes with geometry data only (lowest nodes). - - this.isVisible; // var to manage the frustumCulling and delete buildings if necessary. + this.color = color; }; -/** - * 어떤 일을 하고 있습니까? - */ -SmartTile.prototype.deleteObjects = function() +API.prototype.getBlockType = function() { - this.name = undefined; - this.depth = undefined; - if (this.minGeographicCoord) - { this.minGeographicCoord.deleteObjects(); } - - if (this.maxGeographicCoord) - { this.maxGeographicCoord.deleteObjects(); } - - this.minGeographicCoord = undefined; - this.maxGeographicCoord = undefined; - if (this.sphereExtent) - { this.sphereExtent.deleteObjects(); } - - this.sphereExtent = undefined; - - // now, erase nodeSeeds. - if (this.nodeSeedsArray) - { - var nodeSeedsCount = this.nodeSeedsArray.length; - for (var i=0; i 0) - { - return true; - } - i++; - } - - return find; - + return this.frustumFarDistance; +}; +API.prototype.setFrustumFarDistance = function(frustumFarDistance) +{ + this.frustumFarDistance = frustumFarDistance; }; +API.prototype.getObjectMoveMode = function() +{ + return this.objectMoveMode; +}; +API.prototype.setObjectMoveMode = function(objectMoveMode) +{ + this.objectMoveMode = objectMoveMode; +}; -/** - * 어떤 일을 하고 있습니까? - * @param geoLocData 변수 - */ -SmartTile.prototype.makeSphereExtent = function(magoManager) +API.prototype.getIssueInsertEnable = function() { - this.sphereExtent = SmartTile.computeSphereExtent(magoManager, this.minGeographicCoord, this.maxGeographicCoord, this.sphereExtent); + return this.issueInsertEnable; +}; +API.prototype.setIssueInsertEnable = function(issueInsertEnable) +{ + this.issueInsertEnable = issueInsertEnable; +}; +API.prototype.getObjectInfoViewEnable = function() +{ + return this.objectInfoViewEnable; +}; +API.prototype.setObjectInfoViewEnable = function(objectInfoViewEnable) +{ + this.objectInfoViewEnable = objectInfoViewEnable; +}; +API.prototype.getOcclusionCullingEnable = function() +{ + return this.occlusionCullingEnable; +}; +API.prototype.setOcclusionCullingEnable = function(occlusionCullingEnable) +{ + this.occlusionCullingEnable = occlusionCullingEnable; +}; +API.prototype.getNearGeoIssueListEnable = function() +{ + return this.nearGeoIssueListEnable; +}; +API.prototype.setNearGeoIssueListEnable = function(nearGeoIssueListEnable) +{ + this.nearGeoIssueListEnable = nearGeoIssueListEnable; }; -/** - * 어떤 일을 하고 있습니까? - * @param geoLocData 변수 - */ -SmartTile.computeSphereExtent = function(magoManager, minGeographicCoord, maxGeographicCoord, resultSphereExtent) +API.prototype.getInsertIssueState = function() { - if (resultSphereExtent === undefined) - { resultSphereExtent = new Sphere(); } - - // calculate worldCoord center position. - var midLongitude = (maxGeographicCoord.longitude + minGeographicCoord.longitude)/2; - var midLatitude = (maxGeographicCoord.latitude + minGeographicCoord.latitude)/2; - var midAltitude = (maxGeographicCoord.altitude + minGeographicCoord.altitude)/2; - - resultSphereExtent.centerPoint = ManagerUtils.geographicCoordToWorldPoint(midLongitude, midLatitude, midAltitude, resultSphereExtent.centerPoint, magoManager); - - // calculate an aproximate radius. - var cornerPoint; - cornerPoint = ManagerUtils.geographicCoordToWorldPoint(minGeographicCoord.longitude, minGeographicCoord.latitude, minGeographicCoord.altitude, cornerPoint, magoManager); + return this.insertIssueState; +}; +API.prototype.setInsertIssueState = function(insertIssueState) +{ + this.insertIssueState = insertIssueState; +}; - resultSphereExtent.r = resultSphereExtent.centerPoint.distTo(cornerPoint.x, cornerPoint.y, cornerPoint.z) * 1.2; - return resultSphereExtent; +API.prototype.getDrawType = function() +{ + return this.drawType; +}; +API.prototype.setDrawType = function(drawType) +{ + this.drawType = drawType; }; -/** - * 어떤 일을 하고 있습니까? - * @param geoLocData 변수 - */ -SmartTile.prototype.makeTreeByDepth = function(targetDepth, magoManager) +API.prototype.getLod0DistInMeters = function() { - if (this.nodeSeedsArray === undefined || this.nodeSeedsArray.length === 0) - { return; } - - // if this has "nodeSeedsArray" then make sphereExtent. - this.makeSphereExtent(magoManager); - - // now, if the current depth < targetDepth, then descend. - if (this.depth < targetDepth) - { - // create 4 child smartTiles. - if (this.subTiles === undefined || this.subTiles.length === 0) - { - for (var i=0; i<4; i++) - { this.newSubTile(this); } - } - - // set the sizes to subTiles (The minLongitude, MaxLongitude, etc. is constant, but the minAlt & maxAlt can will be modified every time that insert new buildingSeeds). - this.setSizesToSubTiles(); + return this.lod0DistInMeters; +}; +API.prototype.setLod0DistInMeters = function(lod0DistInMeters) +{ + this.lod0DistInMeters = lod0DistInMeters; +}; +API.prototype.getLod1DistInMeters = function() +{ + return this.lod1DistInMeters; +}; +API.prototype.setLod1DistInMeters = function(lod1DistInMeters) +{ + this.lod1DistInMeters = lod1DistInMeters; +}; +API.prototype.getLod2DistInMeters = function() +{ + return this.lod2DistInMeters; +}; +API.prototype.setLod2DistInMeters = function(lod2DistInMeters) +{ + this.lod2DistInMeters = lod2DistInMeters; +}; +API.prototype.getLod3DistInMeters = function() +{ + return this.lod3DistInMeters; +}; +API.prototype.setLod3DistInMeters = function(lod3DistInMeters) +{ + this.lod3DistInMeters = lod3DistInMeters; +}; +API.prototype.getLod4DistInMeters = function() +{ + return this.lod4DistInMeters; +}; +API.prototype.setLod4DistInMeters = function(lod4DistInMeters) +{ + this.lod4DistInMeters = lod4DistInMeters; +}; +API.prototype.getLod5DistInMeters = function() +{ + return this.lod5DistInMeters; +}; +API.prototype.setLod5DistInMeters = function(lod5DistInMeters) +{ + this.lod5DistInMeters = lod5DistInMeters; +}; - // intercept buildingSeeds for each subTiles. - for (var i=0; i<4; i++) - { - this.subTiles[i].takeIntersectedBuildingSeeds(this.nodeSeedsArray, magoManager); - } - - // for each subTile that has intercepted buildingSeeds -> makeTree. - for (var i=0; i<4; i++) - { - this.subTiles[i].makeTreeByDepth(targetDepth, magoManager); - } - - } - //else - // var hola = 0; +API.prototype.getAmbientReflectionCoef = function() +{ + return this.ambientReflectionCoef; +}; +API.prototype.setAmbientReflectionCoef = function(ambientReflectionCoef) +{ + this.ambientReflectionCoef = ambientReflectionCoef; +}; +API.prototype.getDiffuseReflectionCoef = function() +{ + return this.diffuseReflectionCoef; +}; +API.prototype.setDiffuseReflectionCoef = function(diffuseReflectionCoef) +{ + this.diffuseReflectionCoef = diffuseReflectionCoef; +}; +API.prototype.getSpecularReflectionCoef = function() +{ + return this.specularReflectionCoef; +}; +API.prototype.setSpecularReflectionCoef = function(specularReflectionCoef) +{ + this.specularReflectionCoef = specularReflectionCoef; +}; +API.prototype.getAmbientColor = function() +{ + return this.ambientColor; +}; +API.prototype.setAmbientColor = function(ambientColor) +{ + this.ambientColor = ambientColor; +}; +API.prototype.getSpecularColor = function() +{ + return this.specularColor; +}; +API.prototype.setSpecularColor = function(specularColor) +{ + this.specularColor = specularColor; +}; +API.prototype.getSsaoRadius = function() +{ + return this.ssaoRadius; +}; +API.prototype.setSsaoRadius = function(ssaoRadius) +{ + this.ssaoRadius = ssaoRadius; +}; +API.prototype.getFPVMode = function() +{ + return this.FPVMode; +}; +API.prototype.setFPVMode = function(value) +{ + this.FPVMode = value; +}; +API.prototype.getMagoMode = function() +{ + return this.magoMode; +}; +API.prototype.setMagoMode = function(value) +{ + this.magoMode = value; +}; +API.prototype.getDuration = function() +{ + return this.duration; +}; +API.prototype.setDuration = function(duration) +{ + this.duration = duration; }; -/** - * 어떤 일을 하고 있습니까? - * @param geoLocData 변수 - */ -/* -SmartTile.prototype.getLowestTileWithNodeInside = function(node) +API.prototype.getInputPoint = function() { - // this function returns the lowestTile with "node" if exist. - if (this.subTiles === undefined) - { - var nodesCount = this.nodesArray.length; - var i=0; - while (i this.maxGeographicCoord.altitude) - { - this.maxGeographicCoord.altitude = altitude+bboxRadius; - } - } - } + return this.resultPoint; +}; +API.prototype.setResultPoint = function(resultPoint) +{ + this.resultPoint = resultPoint; }; -/** - * 어떤 일을 하고 있습니까? - * @param geoLocData 변수 - */ -/* -SmartTile.prototype.calculateAltitudeLimits = function() +API.prototype.getUnit = function() { - // this function calculates the minAltitude and maxAltitude of the tile. - // init the altitudes. - this.minGeographicCoord.altitude = 0; - this.maxGeographicCoord.altitude = 0; - - var buildingSeed; - var buildingSeedsCount = this.buildingSeedsArray.length; - for (var i=0; i this.maxGeographicCoord.altitude) + if (isNaN(unit) || unit > CODE.units.RADIAN) { - this.maxGeographicCoord.altitude = altitude+bboxRadius; + throw new Error('unit parameter needs CODE.units'); } + this.unit = unit; } }; -*/ -/** - * 어떤 일을 하고 있습니까? - * @param geographicCoord 변수 - */ -SmartTile.prototype.intersectPoint = function(longitude, latitude) +API.prototype.getInstantiateObj = function() { - if (longitude < this.minGeographicCoord.longitude || longitude > this.maxGeographicCoord.longitude) - { return false; } - - if (latitude < this.minGeographicCoord.latitude || latitude > this.maxGeographicCoord.latitude) - { return false; } - - return true; + return this.instantiateObj; +}; +API.prototype.setInstantiateObj = function(instantiateObj) +{ + this.instantiateObj = instantiateObj; }; -/** - * 어떤 일을 하고 있습니까? - * @param frustum 변수 - */ -SmartTile.prototype.extractLowestTiles = function(resultLowestTilesArray) +API.prototype.getStaticModelAttributeObj = function() { - if (this.subTiles === undefined) - { - if (this.nodeSeedsArray && this.nodeSeedsArray.length > 0) - { - resultLowestTilesArray.push(this); - } - return; - } - - var subTilesCount = this.subTiles.length; - for (var i=0; i 0) - { - for (var i=0; i 0) - { resultPartiallyIntersectedTilesArray.push(this); } - } + throw new Error(Messages.CONSTRUCT_ERROR); } + + this.moveHistory = false; + this.colorHistory = false; + this.rotationHistory = false; + + // move mode. ALL : 0 , OBJECT : 1, NONE : 2 + this.objectMoveMode = null; + + // project id + this.projectId = null; + // project data folder + this.projectDataFolder = null; + // data_key + this.dataKey = null; + // objectId + this.objectId = null; + // objectIndexOrder + this.objectIndexOrder = 0; + + // referenceObject aditional movement. + this.refObjectAditionalMove; + this.refObjectAditionalMoveRelToBuilding; + + // 위도 + this.latitude = 0.0; + // 경도 + this.longitude = 0.0; + // 높이 + this.elevation = 0.0; + // heading + this.heading = 0.0; + // pitch + this.pitch = 0.0; + // roll + this.roll = 0.0; + // duration + this.duration = 0; + // 색깔 + this.color = 0; + // color rgb + this.rgbColor = []; + // 속성 + this.property = null; + this.propertyKey = null; + this.propertyValue = null; }; -/** - * 어떤 일을 하고 있습니까? - * @param frustum 변수 - */ -SmartTile.selectTileAngleRangeByDepth = function(depth) +ChangeHistory.prototype.getReferenceObjectAditionalMovement = function() { - if (depth === undefined || depth < 0 || depth > 15) - { return undefined; } + if (this.refObjectAditionalMove === undefined) + { this.refObjectAditionalMove = new Point3D(); } - if (depth === 0) - { return 180; } - if (depth === 1) - { return 90; } - if (depth === 2) - { return 45; } - if (depth === 3) - { return 22.5; } - if (depth === 4) - { return 11.25; } - if (depth === 5) - { return 5.625; } - if (depth === 6) - { return 2.8125; } - if (depth === 7) - { return 1.40625; } - if (depth === 8) - { return 0.703125; } - if (depth === 9) - { return 0.3515625; } - if (depth === 10) - { return 0.17578125; } - if (depth === 11) - { return 0.087890625; } - if (depth === 12) - { return 0.043945313; } - if (depth === 13) - { return 0.021972656; } - if (depth === 14) - { return 0.010986328; } - if (depth === 15) - { return 0.010986328/2.0; } + return this.refObjectAditionalMove; }; -/** - * 어떤 일을 하고 있습니까? - * @param frustum 변수 - */ -SmartTile.selectTileName = function(depth, longitude, latitude, resultTileName) +ChangeHistory.prototype.getReferenceObjectAditionalMovementRelToBuilding = function() { - var xMin = -180.0; - var yMin = 90.0; - var angRange = SmartTile.selectTileAngleRangeByDepth(depth) ; + if (this.refObjectAditionalMoveRelToBuilding === undefined) + { this.refObjectAditionalMoveRelToBuilding = new Point3D(); } - var xIndex = Math.floor((longitude - xMin)/angRange); - // with yMin = -90.0; - //var yIndex = Math.floor((latitude - yMin)/angRange); - var yIndex = Math.floor((yMin - latitude)/angRange); - resultTileName = depth.toString() + "\\" + xIndex.toString() + "\\" + yIndex.toString(); - return resultTileName; + return this.refObjectAditionalMoveRelToBuilding; }; -/** - * 어떤 일을 하고 있습니까? - * @param frustum 변수 - */ - -SmartTile.getFrustumIntersectedTilesNames = function(frustum, maxDepth, camPos, magoManager, resultFullyIntersectedTilesNamesMap) +ChangeHistory.prototype.getProjectId = function() { - var currMinGeographicCoords = new GeographicCoord(); - var currMaxGeographicCoords = new GeographicCoord(); - var currDepth = 0; - - // America side. - currMinGeographicCoords.setLonLatAlt(-180, -90, 0); - currMaxGeographicCoords.setLonLatAlt(0, 90, 0); - currDepth = 0; - SmartTile.getFrustumIntersectedTilesNamesForGeographicExtent(frustum, maxDepth, currDepth, camPos, currMinGeographicCoords, currMaxGeographicCoords, magoManager, magoManager.boundingSphere_Aux, - resultFullyIntersectedTilesNamesMap); - - // Asia side. - currMinGeographicCoords.setLonLatAlt(0, -90, 0); - currMaxGeographicCoords.setLonLatAlt(180, 90, 0); - currDepth = 0; - SmartTile.getFrustumIntersectedTilesNamesForGeographicExtent(frustum, maxDepth, currDepth, camPos, currMinGeographicCoords, currMaxGeographicCoords, magoManager, magoManager.boundingSphere_Aux, - resultFullyIntersectedTilesNamesMap); + return this.projectId; +}; +ChangeHistory.prototype.setProjectId = function(projectId) +{ + this.projectId = projectId; }; -/** - * 어떤 일을 하고 있습니까? - * @param frustum 변수 - */ - -SmartTile.getFrustumIntersectedTilesNamesForGeographicExtent = function(frustum, maxDepth, currDepth, camPos, currMinGeographicCoords, currMaxGeographicCoords, magoManager, sphereExtentAux, resultFullyIntersectedTilesNamesMap) +ChangeHistory.prototype.getProjectDataFolder = function() { - // STATIC FUNCTION.*** - // 1rst, make a sphereExtent.*** - - sphereExtentAux = SmartTile.computeSphereExtent(magoManager, currMinGeographicCoords, currMaxGeographicCoords, sphereExtentAux); + return this.projectDataFolder; +}; +ChangeHistory.prototype.setProjectDataFolder = function(projectDataFolder) +{ + this.projectDataFolder = projectDataFolder; +}; - var intersectionType = frustum.intersectionSphere(sphereExtentAux); - - if (intersectionType === Constant.INTERSECTION_OUTSIDE) - { return; } - else if (intersectionType === Constant.INTERSECTION_INSIDE) - { - var midLon = (currMinGeographicCoords.longitude + currMaxGeographicCoords.longitude)/2; - var midLat = (currMinGeographicCoords.latitude + currMaxGeographicCoords.latitude)/2; - var tileName = SmartTile.selectTileName(currDepth, midLon, midLat, undefined); - var geographicExtent = new GeographicExtent(); - geographicExtent.minGeographicCoord = new GeographicCoord(currMinGeographicCoords.longitude, currMinGeographicCoords.latitude, currMinGeographicCoords.altitude); - geographicExtent.maxGeographicCoord = new GeographicCoord(currMaxGeographicCoords.longitude, currMaxGeographicCoords.latitude, currMaxGeographicCoords.altitude); - resultFullyIntersectedTilesNamesMap[tileName] = geographicExtent; - return; - } - else if (intersectionType === Constant.INTERSECTION_INTERSECT) - { - // check distance to camera.*** - var distToCam = camPos.distToSphere(sphereExtentAux); - if (distToCam > 2000) - { - var midLon = (currMinGeographicCoords.longitude + currMaxGeographicCoords.longitude)/2; - var midLat = (currMinGeographicCoords.latitude + currMaxGeographicCoords.latitude)/2; - var tileName = SmartTile.selectTileName(currDepth, midLon, midLat, undefined); - var geographicExtent = new GeographicExtent(); - geographicExtent.minGeographicCoord = new GeographicCoord(currMinGeographicCoords.longitude, currMinGeographicCoords.latitude, currMinGeographicCoords.altitude); - geographicExtent.maxGeographicCoord = new GeographicCoord(currMaxGeographicCoords.longitude, currMaxGeographicCoords.latitude, currMaxGeographicCoords.altitude); - resultFullyIntersectedTilesNamesMap[tileName] = geographicExtent; - return; - } - - if (currDepth < maxDepth) - { - // must descend.*** - currDepth += 1; - var minLon = currMinGeographicCoords.longitude; - var minLat = currMinGeographicCoords.latitude; - var minAlt = currMinGeographicCoords.altitude; - var maxLon = currMaxGeographicCoords.longitude; - var maxLat = currMaxGeographicCoords.latitude; - var maxAlt = currMaxGeographicCoords.altitude; - var midLon = (minLon + maxLon)/ 2; - var midLat = (minLat + maxLat)/ 2; - - // subTile 1.*** - currMaxGeographicCoords.setLonLatAlt(midLon, midLat, maxAlt); - this.getFrustumIntersectedTilesNamesForGeographicExtent(frustum, maxDepth, currDepth, camPos, currMinGeographicCoords, currMaxGeographicCoords, magoManager, sphereExtentAux, resultFullyIntersectedTilesNamesMap); - - // subTile 2.*** - currMinGeographicCoords.setLonLatAlt(midLon, minLat, minAlt); - currMaxGeographicCoords.setLonLatAlt(maxLon, midLat, maxAlt); - this.getFrustumIntersectedTilesNamesForGeographicExtent(frustum, maxDepth, currDepth, camPos, currMinGeographicCoords, currMaxGeographicCoords, magoManager, sphereExtentAux, resultFullyIntersectedTilesNamesMap); - - // subTile 3.*** - currMinGeographicCoords.setLonLatAlt(midLon, midLat, minAlt); - currMaxGeographicCoords.setLonLatAlt(maxLon, maxLat, maxAlt); - this.getFrustumIntersectedTilesNamesForGeographicExtent(frustum, maxDepth, currDepth, camPos, currMinGeographicCoords, currMaxGeographicCoords, magoManager, sphereExtentAux, resultFullyIntersectedTilesNamesMap); - - // subTile 4.*** - currMinGeographicCoords.setLonLatAlt(minLon, midLat, minAlt); - currMaxGeographicCoords.setLonLatAlt(midLon, maxLat, maxAlt); - this.getFrustumIntersectedTilesNamesForGeographicExtent(frustum, maxDepth, currDepth, camPos, currMinGeographicCoords, currMaxGeographicCoords, magoManager, sphereExtentAux, resultFullyIntersectedTilesNamesMap); - - } - else - { - var midLon = (currMinGeographicCoords.longitude + currMaxGeographicCoords.longitude)/2; - var midLat = (currMinGeographicCoords.latitude + currMaxGeographicCoords.latitude)/2; - var tileName = SmartTile.selectTileName(currDepth, midLon, midLat, undefined); - var geographicExtent = new GeographicExtent(); - geographicExtent.minGeographicCoord = new GeographicCoord(currMinGeographicCoords.longitude, currMinGeographicCoords.latitude, currMinGeographicCoords.altitude); - geographicExtent.maxGeographicCoord = new GeographicCoord(currMaxGeographicCoords.longitude, currMaxGeographicCoords.latitude, currMaxGeographicCoords.altitude); - resultFullyIntersectedTilesNamesMap[tileName] = geographicExtent; - return; - } - } - +ChangeHistory.prototype.getDataKey = function() +{ + return this.dataKey; }; - - -/** - * 어떤 일을 하고 있습니까? - * Extent(범위) - * @param frustum 변수 - */ -SmartTile.prototype.getSphereExtent = function() +ChangeHistory.prototype.setDataKey = function(dataKey) { - return this.sphereExtent; + this.dataKey = dataKey; }; -/** - * 어떤 일을 하고 있습니까? - */ -SmartTile.prototype.setSize = function(minLon, minLat, minAlt, maxLon, maxLat, maxAlt) +ChangeHistory.prototype.getObjectId = function() { - if (this.minGeographicCoord === undefined) - { this.minGeographicCoord = new GeographicCoord(); } - if (this.maxGeographicCoord === undefined) - { this.maxGeographicCoord = new GeographicCoord(); } - - this.minGeographicCoord.setLonLatAlt(minLon, minLat, minAlt); - this.maxGeographicCoord.setLonLatAlt(maxLon, maxLat, maxAlt); + return this.objectId; +}; +ChangeHistory.prototype.setObjectId = function(objectId) +{ + this.objectId = objectId; }; -/** - * 어떤 일을 하고 있습니까? - */ -SmartTile.prototype.setSizesToSubTiles = function() +ChangeHistory.prototype.getObjectIndexOrder = function() { - // +-----+-----+ - // | 3 | 2 | - // +-----+-----+ - // | 0 | 1 | - // +-----+-----+ - - var minLon = this.minGeographicCoord.longitude; - var maxLon = this.maxGeographicCoord.longitude; - var minLat = this.minGeographicCoord.latitude; - var maxLat = this.maxGeographicCoord.latitude; - var minAlt = this.minGeographicCoord.altitude; - var maxAlt = this.maxGeographicCoord.altitude; - - var midLon = (maxLon + minLon)/2; - var midLat = (maxLat + minLat)/2; - - var subTile = this.subTiles[0]; - subTile.setSize(minLon, minLat, minAlt, midLon, midLat, maxAlt); - - subTile = this.subTiles[1]; - subTile.setSize(midLon, minLat, minAlt, maxLon, midLat, maxAlt); - - subTile = this.subTiles[2]; - subTile.setSize(midLon, midLat, minAlt, maxLon, maxLat, maxAlt); - - subTile = this.subTiles[3]; - subTile.setSize(minLon, midLat, minAlt, midLon, maxLat, maxAlt); + return this.objectIndexOrder; +}; +ChangeHistory.prototype.setObjectIndexOrder = function(objectIndexOrder) +{ + this.objectIndexOrder = objectIndexOrder; }; -/** - * 어떤 일을 하고 있습니까? - * @param geoLocData 변수 - */ -SmartTile.prototype.getLongitudeRangeDegree = function() +ChangeHistory.prototype.getLatitude = function() { - return this.maxGeographicCoord.longitude - this.minGeographicCoord.longitude; + return this.latitude; +}; +ChangeHistory.prototype.setLatitude = function(latitude) +{ + this.latitude = latitude; }; -/** - * 어떤 일을 하고 있습니까? - * @param geoLocData 변수 - */ -SmartTile.prototype.getLatitudeRangeDegree = function() +ChangeHistory.prototype.getLongitude = function() { - return this.maxGeographicCoord.latitude - this.minGeographicCoord.latitude; + return this.longitude; +}; +ChangeHistory.prototype.setLongitude = function(longitude) +{ + this.longitude = longitude; }; +ChangeHistory.prototype.getElevation = function() +{ + return this.elevation; +}; +ChangeHistory.prototype.setElevation = function(elevation) +{ + this.elevation = elevation; +}; -/** - * Quadtree based tile with thickness. - * @class SmartTileManager - */ -var SmartTileManager = function() +ChangeHistory.prototype.getHeading = function() { - if (!(this instanceof SmartTileManager)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - this.tilesArray = []; // has 2 tiles (Asia side and America side). - this.createMainTiles(); + return this.heading; +}; +ChangeHistory.prototype.setHeading = function(heading) +{ + this.heading = heading; }; -/** - * 어떤 일을 하고 있습니까? - * @class GeoLocationData - * @param geoLocData 변수 - */ -SmartTileManager.prototype.createMainTiles = function() +ChangeHistory.prototype.getPitch = function() { - // tile 1 : longitude {-180, 0}, latitude {-90, 90} - // tile 2 : longitude {0, 180}, latitude {-90, 90} - - // America side. - var tile1 = this.newSmartTile("AmericaSide"); - if (tile1.minGeographicCoord === undefined) - { tile1.minGeographicCoord = new GeographicCoord(); } - if (tile1.maxGeographicCoord === undefined) - { tile1.maxGeographicCoord = new GeographicCoord(); } - - tile1.depth = 0; // mother tile. - tile1.minGeographicCoord.setLonLatAlt(-180, -90, 0); - tile1.maxGeographicCoord.setLonLatAlt(0, 90, 0); - - // Asia side. - var tile2 = this.newSmartTile("AsiaSide"); - if (tile2.minGeographicCoord === undefined) - { tile2.minGeographicCoord = new GeographicCoord(); } - if (tile2.maxGeographicCoord === undefined) - { tile2.maxGeographicCoord = new GeographicCoord(); } - - tile2.depth = 0; // mother tile. - tile2.minGeographicCoord.setLonLatAlt(0, -90, 0); - tile2.maxGeographicCoord.setLonLatAlt(180, 90, 0); + return this.pitch; +}; +ChangeHistory.prototype.setPitch = function(pitch) +{ + this.pitch = pitch; }; -/** - * 어떤 일을 하고 있습니까? - * @class GeoLocationData - * @param geoLocData 변수 - */ -SmartTileManager.prototype.deleteTiles = function() +ChangeHistory.prototype.getRoll = function() { - // this function deletes all children tiles. - if (this.tilesArray) - { - var tilesCount = this.tilesArray.length; // allways tilesCount = 2. (Asia & America sides). - for (var i=0; i 0) + { + for (var i=0; i mother_quadtree.*** - this._numberName = 1; // mother quadtree.*** - this._terranTile_owner; - //------------------------------------------------------------ - this.projectsArray = []; - this._BR_buildingsArray = []; // Old.*** - this._boundingBox; // dont use this.*** - this._pCloudMesh_array = []; // 1rst aproximation to the pointCloud data. Test.*** - - this.position; // absolute position, for do frustum culling.*** - this.radius; // aprox radius for this tile.*** - - this.leftDown_position; - this.rightDown_position; - this.rightUp_position; - this.leftUp_position; - this.visibilityType; - - this.subTiles_array = []; - this.terranIndexFile_readed = false; - this.empty_tile = false; - - // File.*************************************************** - this.fileReading_started = false; - this.fileReading_finished = false; - this.fileArrayBuffer; - this.fileBytesReaded = 0; - this.fileParsingFinished = false; - this.projectsParsed_count = 0; - - this.current_BRProject_parsing; - this.current_BRProject_parsing_state = 0; + // dataKey 별 Object을 검사 + var dataKeyObject = projectIdObject[dataKey]; + if (dataKeyObject === undefined) + { + dataKeyObject = {}; + projectIdObject[dataKey] = dataKeyObject; + } + + // objectIndexOrder 를 저장 + dataKeyObject[objectIndexOrder] = changeHistory; +}; - this.readWriter; +/** + * object 선택 내용을 삭제 + */ +MagoConfig.deleteSelectHistoryObject = function(projectId, dataKey, objectIndexOrder) +{ + // projectId 별 Object을 검사 + var projectIdObject = this.selectHistoryObject[projectId]; + if (projectIdObject === undefined) { return undefined; } + // dataKey 별 Object을 검사 + var dataKeyObject = projectIdObject[dataKey]; + if (dataKeyObject === undefined) { return undefined; } + // objectIndexOrder 를 저장 + return delete dataKeyObject[objectIndexOrder]; }; /** - * 어떤 일을 하고 있습니까? - * @returns br_buildingProject + * 모든 이동 히스토리 삭제 */ -TerranTile.prototype.newBRProject = function() +MagoConfig.clearMovingHistory = function() { - // Old.*** Old.*** Old.*** Old.*** Old.*** Old.*** Old.*** Old.*** - // dont use this. delete this.*** - var br_buildingProject = new BRBuildingProject(); - this._BR_buildingsArray.push(br_buildingProject); - return br_buildingProject; + this.movingHistoryObject = {}; }; /** - * 어떤 일을 하고 있습니까? - * @returns subTile + * 모든 object 선택 내용 이력을 취득 */ -TerranTile.prototype.newSubTerranTile = function() +MagoConfig.getAllMovingHistory = function() { - var subTiles_count = this.subTiles_array.length; - var subTile = new TerranTile(); - subTile._depth = this._depth + 1; - subTile._numberName = this._numberName*10 + subTiles_count + 1; - this.subTiles_array.push(subTile); - return subTile; + return this.movingHistoryObject; }; /** - * 어떤 일을 하고 있습니까? + * project별 입력키 값과 일치하는 object 이동 내용 이력을 취득 */ -TerranTile.prototype.make4subTiles = function() +MagoConfig.getMovingHistoryObjects = function(projectId, dataKey) { - for (var i = 0; i < 4; i++) - { - this.newSubTerranTile(); - } + // projectId 별 Object을 검사 + var projectIdObject = this.movingHistoryObject[projectId]; + if (projectIdObject === undefined) { return undefined; } + // dataKey 별 Object을 검사 + var dataKeyObject = projectIdObject[dataKey]; + return dataKeyObject; }; /** - * 어떤 일을 하고 있습니까? - * @param lonMin 변수 - * @param lonMax 변수 - * @param latMin 변수 - * @param latMax 변수 + * object 이동 내용 이력을 취득 */ -TerranTile.prototype.setDimensions = function(lonMin, lonMax, latMin, latMax) +MagoConfig.getMovingHistoryObject = function(projectId, dataKey, objectIndexOrder) { - this.longitudeMin = lonMin; - this.longitudeMax = lonMax; - this.latitudeMin = latMin; - this.latitudeMax = latMax; + // projectId 별 Object을 검사 + var projectIdObject = this.movingHistoryObject[projectId]; + if (projectIdObject === undefined) { return undefined; } + // dataKey 별 Object을 검사 + var dataKeyObject = projectIdObject[dataKey]; + if (dataKeyObject === undefined) { return undefined; } + // objectIndexOrder 를 저장 + return dataKeyObject[objectIndexOrder]; }; /** - * 어떤 일을 하고 있습니까? - * @param maxDepth 변수 + * object 이동 내용을 저장 */ -TerranTile.prototype.makeTree = function(maxDepth) +MagoConfig.saveMovingHistory = function(projectId, dataKey, objectIndexOrder, changeHistory) { - if (this._depth < maxDepth) + // projectId 별 Object을 검사 + var projectIdObject = this.movingHistoryObject[projectId]; + if (projectIdObject === undefined) { - var subTileAux; - for (var i = 0; i < 4; i++) - { - subTileAux = this.newSubTerranTile(); - subTileAux.makeTree(maxDepth); - } + projectIdObject = {}; + this.movingHistoryObject[projectId] = projectIdObject; } + + // dataKey 별 Object을 검사 + var dataKeyObject = projectIdObject[dataKey]; + if (dataKeyObject === undefined) + { + dataKeyObject = {}; + projectIdObject[dataKey] = dataKeyObject; + } + + // objectIndexOrder 를 저장 + dataKeyObject[objectIndexOrder] = changeHistory; }; /** - * 어떤 일을 하고 있습니까? + * object 이동 내용을 삭제 */ -TerranTile.prototype.calculatePositionByLonLat = function() +MagoConfig.deleteMovingHistoryObject = function(projectId, dataKey, objectIndexOrder) { - var lon_mid = (this.longitudeMax + this.longitudeMin)/2.0; - var lat_mid = (this.latitudeMax + this.latitudeMin)/2.0; - - this.position = Cesium.Cartesian3.fromDegrees(lon_mid, lat_mid, 0.0); - - this.leftDown_position = Cesium.Cartesian3.fromDegrees(this.longitudeMin, this.latitudeMin, 0.0); - this.rightDown_position = Cesium.Cartesian3.fromDegrees(this.longitudeMax, this.latitudeMin, 0.0); - this.rightUp_position = Cesium.Cartesian3.fromDegrees(this.longitudeMax, this.latitudeMax, 0.0); - this.leftUp_position = Cesium.Cartesian3.fromDegrees(this.longitudeMin, this.latitudeMax, 0.0); - - this.radius = Cesium.Cartesian3.distance(this.leftDown_position, this.rightUp_position)/2.0 * 0.9; + // projectId 별 Object을 검사 + var projectIdObject = this.movingHistoryObject[projectId]; + if (projectIdObject === undefined) { return undefined; } + // dataKey 별 Object을 검사 + var dataKeyObject = projectIdObject[dataKey]; + if (dataKeyObject === undefined) { return undefined; } + // objectIndexOrder 를 저장 + return delete dataKeyObject[objectIndexOrder]; }; /** - * 어떤 일을 하고 있습니까? + * 모든 색깔 변경 이력을 획득 */ -TerranTile.prototype.calculatePositionByLonLatSubTiles = function() +MagoConfig.getAllColorHistory = function() { - this.calculatePositionByLonLat(); - - var subTile; - var subTiles_count = this.subTiles_array.length; // subTiles_count must be 4.*** - - for (var i=0; i= fileLegth) - { return; } + this.colorHistoryObject = {}; +}; - var version_string_length = 5; - var intAux_scratch = 0; - //var auxScratch; - var header = BR_Project._header; - var arrayBuffer = this.fileArrayBuffer; - var bytes_readed = this.fileBytesReaded; +/** + * project별 키에 해당하는 모든 색깔 변경 이력을 획득 + */ +MagoConfig.getColorHistorys = function(projectId, dataKey) +{ + // projectId 별 Object을 검사 + var projectIdObject = this.colorHistoryObject[projectId]; + if (projectIdObject === undefined) { return undefined; } + // dataKey 별 Object을 검사 + var dataKeyObject = projectIdObject[dataKey]; + return dataKeyObject; +}; - if (this.readWriter === undefined) - { this.readWriter = new ReaderWriter(); } +/** + * 색깝 변경 이력을 획득 + */ +MagoConfig.getColorHistory = function(projectId, dataKey, objectId) +{ + // projectId 별 Object을 검사 + var projectIdObject = this.colorHistoryObject[projectId]; + if (projectIdObject === undefined) { return undefined; } + // dataKey 별 Object을 검사 + var dataKeyObject = projectIdObject[dataKey]; + if (dataKeyObject === undefined) { return undefined; } + // objectId 를 저장 + return dataKeyObject[objectId]; +}; - // 1) Version(5 chars).*********** - for (var j=0; j 40.0 || header._boundingBox.maxY - header._boundingBox.minY > 40.0) + if (objectId === null || objectId === "") { - isLarge = true; + dataKeyObject[dataKey] = changeHistory; } - - if (!isLarge && header._boundingBox.maxZ - header._boundingBox.minZ < 30.0) + else { - header.isSmall = true; + dataKeyObject[objectId] = changeHistory; } - - var imageLODs_count = this.readWriter.readUInt8(arrayBuffer, bytes_readed, bytes_readed+1); bytes_readed += 1; - - // Now, must calculate some params of the project.********************************************** - // 0) PositionMatrix.************************************************************************ - // Determine the elevation of the position.*********************************************************** - var position = Cesium.Cartesian3.fromDegrees(header._longitude, header._latitude, header._elevation); - var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position); - var height = cartographic.height; - // End Determine the elevation of the position.------------------------------------------------------- - - //var position = Cesium.Cartesian3.fromDegrees(header._longitude, header._latitude, header._elevation); // Original.*** - position = Cesium.Cartesian3.fromDegrees(header._longitude, header._latitude, height); - - BR_Project.buildingPosition = position; - - // High and Low values of the position.**************************************************** - var splitValue = Cesium.EncodedCartesian3.encode(position); - var splitVelue_X = Cesium.EncodedCartesian3.encode(position.x); - var splitVelue_Y = Cesium.EncodedCartesian3.encode(position.y); - var splitVelue_Z = Cesium.EncodedCartesian3.encode(position.z); - - BR_Project.buildingPositionHIGH = new Float32Array(3); - BR_Project.buildingPositionHIGH[0] = splitVelue_X.high; - BR_Project.buildingPositionHIGH[1] = splitVelue_Y.high; - BR_Project.buildingPositionHIGH[2] = splitVelue_Z.high; - - BR_Project.buildingPositionLOW = new Float32Array(3); - BR_Project.buildingPositionLOW[0] = splitVelue_X.low; - BR_Project.buildingPositionLOW[1] = splitVelue_Y.low; - BR_Project.buildingPositionLOW[2] = splitVelue_Z.low; - - this.fileBytesReaded = bytes_readed; }; - /** - * 어떤 일을 하고 있습니까? - * @param BR_Project 변수 + * 색깔 변경 이력을 삭제 */ -TerranTile.prototype.parseFileSimpleBuilding = function(BR_Project) +MagoConfig.deleteColorHistory = function(projectId, dataKey, objectId) { - var fileLegth = this.fileArrayBuffer.byteLength; - if (this.fileBytesReaded >= fileLegth) - { return; } - - if (this.readWriter === undefined) - { this.readWriter = new ReaderWriter(); } - - var bytes_readed = this.fileBytesReaded; - var startBuff; - var endBuff; - var arrayBuffer = this.fileArrayBuffer; - - if (BR_Project._simpleBuilding_v1 === undefined) - { BR_Project._simpleBuilding_v1 = new SimpleBuildingV1(); } - - var simpBuildingV1 = BR_Project._simpleBuilding_v1; - var vbo_objects_count = this.readWriter.readUInt32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; // Almost allways is 1.*** - - // single interleaved buffer mode.********************************************************************************* - for (var i=0; i>> 8; - //var r = (color_4byte_temp & 0xFF0000) >>> 16; - //var a = ( (color_4byte_temp & 0xFF000000) >>> 24 ) / 255 ; - - this.fileBytesReaded = bytes_readed; + // projectId 별 Object을 검사 + var projectIdObject = this.colorHistoryObject[projectId]; + if (projectIdObject === undefined) { return undefined; } + // dataKey 별 Object을 검사 + var dataKeyObject = projectIdObject[dataKey]; + if (dataKeyObject === undefined) { return undefined; } + // objectIndexOrder 를 저장 + return delete dataKeyObject[objectId]; }; /** - * 어떤 일을 하고 있습니까? - * @param BR_Project 변수 - * @param magoManager 변수 + * 모든 색깔변경 히스토리 삭제 */ -TerranTile.prototype.parseFileNailImage = function(BR_Project, magoManager) +MagoConfig.clearColorHistory = function() { - //BR_Project._f4d_nailImage_readed = true; - - if (BR_Project._simpleBuilding_v1 === undefined) - { BR_Project._simpleBuilding_v1 = new SimpleBuildingV1(); } - - if (this.readWriter === undefined) - { this.readWriter = new ReaderWriter(); } - - var simpBuildingV1 = BR_Project._simpleBuilding_v1; - - // Read the image.********************************************************************************** - var bytes_readed = this.fileBytesReaded; - var arrayBuffer = this.fileArrayBuffer; - - var nailImageSize = this.readWriter.readUInt32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; - var startBuff = bytes_readed; - var endBuff = bytes_readed + nailImageSize; - simpBuildingV1.textureArrayBuffer = new Uint8Array(arrayBuffer.slice(startBuff, endBuff)); - - bytes_readed += nailImageSize; - - this.fileBytesReaded = bytes_readed; + this.colorHistoryObject = {}; }; /** - * 어떤 일을 하고 있습니까? - * @param magoManager 변수 + * 모든 location and rotation 변경 이력을 획득 */ -TerranTile.prototype.parseFileAllBuildings = function(magoManager) +MagoConfig.getAllLocationAndRotationHistory = function() { - var fileLegth = this.fileArrayBuffer.byteLength; - if (this.fileBytesReaded >= fileLegth) - { - this.fileParsingFinished = true; - return; - } - - if (this.readWriter === undefined) - { this.readWriter = new ReaderWriter(); } - - var arrayBuffer = this.fileArrayBuffer; - var projects_count = this.readWriter.readInt32(arrayBuffer, 0, 4); this.fileBytesReaded += 4; - - if (projects_count === 0) - { this.empty_tile = true; } - - for (var i=0; i= fileLegth) - { - this.fileParsingFinished = true; - return; - } - - if (this.readWriter === undefined) - { this.readWriter = new ReaderWriter(); } - - var projects_count = this.readWriter.readInt32(this.fileArrayBuffer, 0, 4); // only debug test.*** - - if (this.projectsParsed_count >= projects_count) - { - this.fileParsingFinished = true; - this.fileBytesReaded = null; - return; - } - - if (this.current_BRProject_parsing_state === 0) - { - if (this.projectsParsed_count === 0) - { this.fileBytesReaded = 4; } - - this.current_BRProject_parsing = this.newBRProject(); - } - - var BR_Project = this.current_BRProject_parsing; - - // Read header, simpleBuilding, and the nailImage.*** - if (this.current_BRProject_parsing_state === 0) - { - this.parseFileHeader(BR_Project); - this.current_BRProject_parsing_state=1; - } - else if (this.current_BRProject_parsing_state === 1) - { - if (magoManager.backGround_imageReadings_count < 1) - { - this.parseFile_simpleBuilding_old(gl, BR_Project); - this.current_BRProject_parsing_state=2; - } - } - else if (this.current_BRProject_parsing_state === 2) - { - if (magoManager.backGround_imageReadings_count < 1) - { - this.parseFile_nailImage_old(gl, BR_Project, magoManager); - this.current_BRProject_parsing_state=0; - this.projectsParsed_count++; - magoManager.backGround_imageReadings_count ++; - } - } + // projectId 별 Object을 검사 + var projectIdObject = this.locationAndRotationHistoryObject[projectId]; + if (projectIdObject === undefined) { return undefined; } + // dataKey 별 Object을 검사 + var dataKeyObject = projectIdObject[dataKey]; + return dataKeyObject; }; /** - * 어떤 일을 하고 있습니까? + * location and rotation 이력을 획득 */ -TerranTile.prototype.setDimensionsSubTiles = function() +MagoConfig.getLocationAndRotationHistory = function(projectId, dataKey) { - var subTile; - var subTiles_count = this.subTiles_array.length; // subTiles_count must be 4.*** - if (subTiles_count === 4) - { - var lon_mid = (this.longitudeMax + this.longitudeMin)/2.0; - var lat_mid = (this.latitudeMax + this.latitudeMin)/2.0; - - subTile = this.subTiles_array[0]; - subTile.setDimensions(this.longitudeMin, lon_mid, this.latitudeMin, lat_mid); - - subTile = this.subTiles_array[1]; - subTile.setDimensions(lon_mid, this.longitudeMax, this.latitudeMin, lat_mid); - - subTile = this.subTiles_array[2]; - subTile.setDimensions(lon_mid, this.longitudeMax, lat_mid, this.latitudeMax); - - subTile = this.subTiles_array[3]; - subTile.setDimensions(this.longitudeMin, lon_mid, lat_mid, this.latitudeMax); - - for (var i=0; i 0) + // projectId 별 Object을 검사 + var projectIdObject = this.locationAndRotationHistoryObject[projectId]; + if (projectIdObject === undefined) { - for (var i=0; i 0) + if (!keyObject.hasxxxxx(key)) { - for (var i=0; i= 0) { - this.subTiles_array[i].getIntersectedTiles(frustumVolume, intersectedTiles_array); + // 지우는 처리가 있어야 함 } - } - else - { - intersectedTiles_array.push(this); + this.dataObject.delete(key); } } -}; +};*/ 'use strict'; - /** - * 맵 이미지. 머티리얼에는 텍스처에 대한 참조가 포함될 수 있으므로 머티리얼의 셰이더는 객체의 표면색을 계산하는 동안 텍스처를 사용할 수 있습니다. - * 오브제의 표면의 기본 색상 (알베도) 외에도 텍스쳐는 반사율이나 거칠기와 같은 재질 표면의 많은 다른면을 나타낼 수 있습니다. - * @class Texture + * Policy + * @class Policy */ -var Texture = function() +var Policy = function() { - if (!(this instanceof Texture)) + if (!(this instanceof Policy)) { throw new Error(Messages.CONSTRUCT_ERROR); } - this.textureTypeName = ""; - this.textureImageFileName = ""; - this.texId; - this.fileLoadState = CODE.fileLoadState.READY; + // mago3d 활성화/비활성화 여부 + this.magoEnable = true; + + // outfitting 표시 여부 + this.showOutFitting = false; + // label 표시/비표시 + this.showLabelInfo = false; + // boundingBox 표시/비표시 + this.showBoundingBox = false; + // 그림자 표시/비표시 + this.showShadow = false; + // squared far frustum 거리 + this.frustumFarSquaredDistance = 5000000; + // far frustum + this.frustumFarDistance = 20000; + + // highlighting + this.highLightedBuildings = []; + // color + this.colorBuildings = []; + // color + this.color = []; + // show/hide + this.hideBuildings = []; + // move mode + this.objectMoveMode = CODE.moveMode.NONE; + // 이슈 등록 표시 + this.issueInsertEnable = false; + // object 정보 표시 + this.objectInfoViewEnable = false; + // 이슈 목록 표시 + this.nearGeoIssueListEnable = false; + // occlusion culling + this.occlusionCullingEnable = false; + // origin axis XYZ + this.showOrigin = false; + // mago generalMode + this.magoMode = CODE.magoMode.NORMAL; + + // 이미지 경로 + this.imagePath = ""; + + // provisional. + this.colorChangedObjectId; + + // LOD1 + this.lod0DistInMeters = 15; + this.lod1DistInMeters = 50; + this.lod2DistInMeters = 90; + this.lod3DistInMeters = 200; + this.lod4DistInMeters = 1000; + this.lod5DistInMeters = 50000; + + // Lighting + this.ambientReflectionCoef = 0.45; // 0.2. + this.diffuseReflectionCoef = 0.75; // 1.0 + this.specularReflectionCoef = 0.6; // 0.7 + this.ambientColor = null; + this.specularColor = new Float32Array([0.6, 0.6, 0.6]); + + this.ssaoRadius = 0.15; + + // PointsCloud. + this.pointsCloudSettings = {}; + this.pointsCloudSettings.maxPartitionsLod0 = 8; + this.pointsCloudSettings.maxPartitionsLod1 = 4; + this.pointsCloudSettings.maxPartitionsLod2orLess = 1; + this.pointsCloudSettings.MaxPerUnitPointsRenderDistToCam0m = 1.0; + this.pointsCloudSettings.MaxPerUnitPointsRenderDistToCam100m = 1.0/6.0; + this.pointsCloudSettings.MaxPerUnitPointsRenderDistToCam200m = 1.0/12.0; + this.pointsCloudSettings.MaxPerUnitPointsRenderDistToCam400m = 1.0/24.0; + this.pointsCloudSettings.MaxPerUnitPointsRenderDistToCam800m = 1.0/48.0; + this.pointsCloudSettings.MaxPerUnitPointsRenderDistToCam1600m = 1.0/128.0; + this.pointsCloudSettings.MaxPerUnitPointsRenderDistToCamMoreThan1600m = 1.0/256.0; + }; -Texture.prototype.deleteObjects = function(gl) +Policy.prototype.getPointsCloudSettings = function() { - this.textureTypeName = undefined; - this.textureImageFileName = undefined; - if (this.texId) - { - gl.deleteTexture(this.texId); - } - this.texId = undefined; - this.fileLoadState = undefined; + return this.pointsCloudSettings; }; -'use strict'; +Policy.prototype.getShowOrigin = function() +{ + return this.showOrigin; +}; +Policy.prototype.setShowOrigin = function(showOrigin) +{ + this.showOrigin = showOrigin; +}; -/** - * 영역 박스 - * @class TriPolyhedron - */ -var TriPolyhedron = function() +Policy.prototype.getMagoEnable = function() { - if (!(this instanceof TriPolyhedron)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - this.vertexMatrix = new VertexMatrix(); - this.vertexList = this.vertexMatrix.newVertexList(); - this.triSurfacesArray = []; + return this.magoEnable; +}; +Policy.prototype.setMagoEnable = function(magoEnable) +{ + this.magoEnable = magoEnable; }; -TriPolyhedron.prototype.newTriSurface = function() +Policy.prototype.getShowOutFitting = function() { - var triSurface = new TriSurface(); - this.triSurfacesArray.push(triSurface); - return triSurface; + return this.showOutFitting; +}; +Policy.prototype.setShowOutFitting = function(showOutFitting) +{ + this.showOutFitting = showOutFitting; +}; +Policy.prototype.getShowLabelInfo = function() +{ + return this.showLabelInfo; +}; +Policy.prototype.setShowLabelInfo = function(showLabelInfo) +{ + this.showLabelInfo = showLabelInfo; +}; +Policy.prototype.getShowBoundingBox = function() +{ + return this.showBoundingBox; +}; +Policy.prototype.setShowBoundingBox = function(showBoundingBox) +{ + this.showBoundingBox = showBoundingBox; }; -TriPolyhedron.prototype.invertTrianglesSenses = function() +Policy.prototype.getShowShadow = function() { - var triSurfacesCount = this.triSurfacesArray.length; - for (var i=0; i 0) - { - var vboKey = this.vboKeysArray.pop(); - return vboKey; - } - else - { - if (!onlyReuse) - { - // there are no free key, so create one. - var vboKey = gl.createBuffer(); - this.keysCreated += 1; // increment key created counter. - keyNation.totalBytesUsed += this.classifiedSize; - keyWorld.totalBytesUsed += this.classifiedSize; - return vboKey; - } - return undefined; - } + var floatArray = this.vertexMatrix.getVBOVertexColorRGBAFloatArray(); + return floatArray; }; /** - * 어떤 일을 하고 있습니까? - * @returns boolean. + * 그래픽 카드에 데이터를 올릴때 사용(삼각형을 이루어 주는 순서) + * + * @returns shortArray */ -VBOKeysStore.prototype.storeBufferKey = function(bufferKey) +ShadowBlendingCube.prototype.getVBOIndicesShortArray = function() { - this.vboKeysArray.push(bufferKey); + this.vertexMatrix.setVertexIdxInList(); + var shortArray = this.tTrianglesMatrix.getVBOIndicesShortArray(); + this.indicesCount = shortArray.length; + + return shortArray; }; /** - * 어떤 일을 하고 있습니까? - * @class VBOKeysNation + * 구름 매니저 + * + * @class CloudsManager */ -var VBOKeysNation = function(bufferSizes, minSize) +var CloudsManager = function() { - if (!(this instanceof VBOKeysNation)) + if (!(this instanceof CloudsManager)) { throw new Error(Messages.CONSTRUCT_ERROR); } - // buffer sizes are in bytes. - this.vboKeysStoreMap = {}; - this.bufferSizes = bufferSizes; - this.minSize = minSize; - this.maxSize = bufferSizes[bufferSizes.length-1]; - this.totalBytesUsed = 0; - - var vboKeysStore; - var sizesCount = bufferSizes.length; - for (var i=0; i this.maxSize) { this.maxSize = bufferSizes[i]; } - } + this.circularCloudsArray = []; }; /** - * 어떤 일을 하고 있습니까? - * @returns vboBufferKey. + * 원형 구름 생성 + * + * @returns circularCloud */ -VBOKeysNation.prototype.getClassifiedBufferKey = function(gl, bufferSize, keyWorld, onlyReuse) +CloudsManager.prototype.newCircularCloud = function() { - // 1rst find the vboKeyStore for this bufferSize. - var vboKeyStore = this.vboKeysStoreMap[bufferSize]; - - if (vboKeyStore) - { - return vboKeyStore.getBufferKey(gl, this, keyWorld, onlyReuse); - } - else { return -1; } + var circularCloud = new CircularCloud(); + this.circularCloudsArray.push(circularCloud); + return circularCloud; }; /** - * 어떤 일을 하고 있습니까? - * @returns vboBufferKey. + * 원형 구름 + * + * @class CircularCloud */ -VBOKeysNation.prototype.storeClassifiedBufferKey = function(bufferKey, bufferSize) +var CircularCloud = function() { - // 1rst find the vboKeyStore for this bufferSize. - var vboKeyStore = this.vboKeysStoreMap[bufferSize]; - if (vboKeyStore) + if (!(this instanceof CircularCloud)) { - vboKeyStore.storeBufferKey(bufferKey); + throw new Error(Messages.CONSTRUCT_ERROR); } -}; -/** - * 어떤 일을 하고 있습니까? - * @returns boolean. true if the currentBufferSize is in the range of this nation. - */ -VBOKeysNation.prototype.getClosestBufferSize = function(currentBufferSize) -{ - if (!this.isInsideRange(currentBufferSize)) - { return -1; } - - var sizesCount = this.bufferSizes.length; - for (var i=0; i this.maxSize || bufferSize < this.minSize) - { return false; } + this.vertexMatrix = new VertexMatrix(); + this.tTrianglesMatrix = new TTrianglesMatrix(); + this.shadowVertexMatrix = new VertexMatrix(); + this.shadowTTrianglesMatrix = new TTrianglesMatrix(); - return true; + this.sunLightDirection = new Point3D(); + this.sunLightDirection.set(1, 1, -5); + this.sunLightDirection.unitary(); + + this.longitude; + this.latitude; + this.altitude; + this.position; + this.positionHIGH; + this.positionLOW; + + this.bbox = new BoundingBox(); + this.cullingPosition; + this.cullingRadius; + + this.vboVertexCacheKey; + this.vboIndexCacheKey; + this.vboShadowVertexCacheKey; + this.vboShadowIndexCacheKey; + this.indicesCount = 0; + + this.rendered = false; // Test. + + // SCRATCH. SCRATCH. SCRATCH. SCRATCH. SCRATCH. SCRATCH. + // SCRATCH. SCRATCH. + this.point3dSC = new Point3D(); + this.vertexSC = new Vertex(); }; /** - * 어떤 일을 하고 있습니까? + * 그래픽 카드에 올릴 데이터를 요청 + * + * @returns floatArray */ -var VBOKeysWorld = function() +CircularCloud.prototype.getVBOVertexColorFloatArray = function() { - if (!(this instanceof VBOKeysWorld)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - this.totalBytesUsed = 0; - this.bytesLimit = 1000; - - this.vboKeysNationsArray = []; - this.vboKeyNation12to128 = new VBOKeysNation(new Uint32Array([12, 16, 32, 48, 64, 76, 92, 128]), 0); - this.vboKeysNationsArray.push(this.vboKeyNation12to128); - this.vboKeyNation200to1000 = new VBOKeysNation(new Uint32Array([200, 300, 400, 500, 600, 700, 800, 900, 1000]), 129); - this.vboKeysNationsArray.push(this.vboKeyNation200to1000); - this.vboKeyNation1500to6000 = new VBOKeysNation(new Uint32Array([1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000, 5500, 6000]), 1001); - this.vboKeysNationsArray.push(this.vboKeyNation1500to6000); - this.vboKeyNation7000to16000 = new VBOKeysNation(new Uint32Array([7000, 8000, 9000, 10000, 11000, 12000, 13000, 14000, 15000, 16000]), 6001); - this.vboKeysNationsArray.push(this.vboKeyNation7000to16000); - this.vboKeyNation20000to56000 = new VBOKeysNation(new Uint32Array([20000, 24000, 28000, 32000, 36000, 40000, 44000, 48000, 52000, 56000]), 16001); - this.vboKeysNationsArray.push(this.vboKeyNation20000to56000); - this.vboKeyNation60000to150000 = new VBOKeysNation(new Uint32Array([60000, 70000, 80000, 90000, 100000, 110000, 120000, 130000, 140000, 150000]), 56001); - this.vboKeysNationsArray.push(this.vboKeyNation60000to150000); - this.vboKeyNation200000to1100000 = new VBOKeysNation(new Uint32Array([200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1000000, 1100000]), 150001); - this.vboKeysNationsArray.push(this.vboKeyNation200000to1100000); - this.vboKeyNation1500000to3000000 = new VBOKeysNation(new Uint32Array([1500000, 2000000, 2500000, 3000000]), 1100001); - this.vboKeysNationsArray.push(this.vboKeyNation1500000to3000000); + var floatArray; + floatArray = this.vertexMatrix.getVBOVertexColorFloatArray(floatArray); + return floatArray; }; /** - * 어떤 일을 하고 있습니까? - * @returns vboBufferCacheKey + * 그래픽 카드에 올릴 데이터를 요청(삼각형) + * + * @returns floatArray */ -VBOKeysWorld.prototype.getClassifiedBufferKey = function(gl, bufferSize) +CircularCloud.prototype.getVBOIndicesShortArray = function() { - // check gpuMemory limit. - var onlyReuse = false; - if (this.totalBytesUsed > this.bytesLimit) - { - onlyReuse = true; - } - - // 1rst, find the Nation for this bufferSize. - var keyNation = this.getKeyNationBySize(bufferSize); - var vboBufferKey = undefined; - if (keyNation) - { - vboBufferKey = keyNation.getClassifiedBufferKey(gl, bufferSize, this, onlyReuse); - } - return vboBufferKey; + this.vertexMatrix.setVertexIdxInList(); + var shortArray = this.tTrianglesMatrix.getVBOIndicesShortArray(); + this.indicesCount = shortArray.length; + + return shortArray; }; /** - * 어떤 일을 하고 있습니까? - * @returns vboBufferCacheKey + * 그래픽 카드에 올릴 데이터를 요청(Vertex) + * + * @returns floatArray */ -VBOKeysWorld.prototype.storeClassifiedBufferKey = function(bufferKey, bufferSize) +CircularCloud.prototype.getVBOShadowVertexFloatArray = function() { - // 1rst, find the Nation for this bufferSize. - var keyNation = this.getKeyNationBySize(bufferSize); - if (keyNation) - { keyNation.storeClassifiedBufferKey(bufferKey, bufferSize); } + var floatArray; + floatArray = this.shadowVertexMatrix.getVBOVertexFloatArray(floatArray); + return floatArray; }; /** - * 어떤 일을 하고 있습니까? - * @returns vboBufferCacheKey + * 그래픽 카드에 올릴 데이터를 요청(삼삭형 순서) + * + * @returns shortArray */ -VBOKeysWorld.prototype.getKeyNationBySize = function(bufferSize) +CircularCloud.prototype.getVBOShadowIndicesShortArray = function() { - // 1rst, find the Nation for this bufferSize. - var nationsCount = this.vboKeysNationsArray.length; - var i=0; - var vboBufferKey = -1; - while (i no management of the gpu memory. - this.enableMemoryManagement = false; - - this.buffersKeyWorld = new VBOKeysWorld(); - this.elementKeyWorld = new VBOKeysWorld(); - - this.buffersKeyWorld.bytesLimit = 800000000; - this.elementKeyWorld.bytesLimit = 300000000; + // matrix.rotationAxisAngDeg(90.0-this.latitude, Math.cos(longitudeRad-90), + // -Math.sin(longitudeRad-90), 0.0); + matrix.rotationAxisAngDeg(90.0 - this.latitude, pitchAxis.x, pitchAxis.y, + 0.0); + vtxMat.transformPointsByMatrix4(matrix); }; /** - * 어떤 일을 하고 있습니까? - * @returns vboBufferCacheKey + * 햇빛 방향으로 시작 */ -VBOMemoryManager.prototype.isGpuMemFull = function() +CircularCloud.prototype.doShadowMeshWithSunDirection = function() { - if (this.buffersKeyWorld.totalBytesUsed > this.buffersKeyWorld.bytesLimit || this.elementKeyWorld.totalBytesUsed > this.elementKeyWorld.bytesLimit) - { return true; } - else { return false; } -}; + var distance = 3000.0; + var vertexList = this.shadowVertexMatrix.getVertexList(5); // Bottom radius + // zero ring. + vertexList.translateVertices(this.sunLightDirection.x, + this.sunLightDirection.y, this.sunLightDirection.z, distance); -/** - * 어떤 일을 하고 있습니까? - * @returns vboBufferCacheKey - */ -VBOMemoryManager.prototype.getClassifiedBufferKey = function(gl, bufferSize) -{ - if (this.enableMemoryManagement) - { return this.buffersKeyWorld.getClassifiedBufferKey(gl, bufferSize); } - else - { return gl.createBuffer(); } -}; + vertexList = this.shadowVertexMatrix.getVertexList(4); // Bottom minor + // ring. + vertexList.translateVertices(this.sunLightDirection.x, + this.sunLightDirection.y, this.sunLightDirection.z, distance); -/** - * 어떤 일을 하고 있습니까? - * @returns vboBufferCacheKey - */ -VBOMemoryManager.prototype.storeClassifiedBufferKey = function(gl, bufferKey, bufferSize) -{ - if (this.enableMemoryManagement) - { this.buffersKeyWorld.storeClassifiedBufferKey(bufferKey, bufferSize); } - else - { gl.deleteBuffer(bufferKey); } + vertexList = this.shadowVertexMatrix.getVertexList(3); // Bottom major + // ring. + vertexList.translateVertices(this.sunLightDirection.x, + this.sunLightDirection.y, this.sunLightDirection.z, distance); }; /** - * 어떤 일을 하고 있습니까? - * @returns vboBufferCacheKey + * 구름 생성 + * + * @param logitude + * 경도 + * @param latitude + * 위도 + * @param radius + * 반지름 + * @param depth + * 깊이 + * @param numPointsForCircle + * 동그라미 하나당 점의 갯수 */ -VBOMemoryManager.prototype.getClassifiedElementKey = function(gl, bufferSize) +CircularCloud.prototype.createCloud = function(longitude, latitude, altitude, + radius, depth, numPointsForCircle) { - if (this.enableMemoryManagement) - { return this.elementKeyWorld.getClassifiedBufferKey(gl, bufferSize); } - else - { return gl.createBuffer(); } -}; + this.longitude = longitude; + this.latitude = latitude; + this.altitude = altitude; + this.radius = radius; + this.depth = depth; + this.numPointsForCicle = numPointsForCircle; -/** - * 어떤 일을 하고 있습니까? - * @returns vboBufferCacheKey - */ -VBOMemoryManager.prototype.storeClassifiedElementKey = function(gl, bufferKey, bufferSize) -{ - if (this.enableMemoryManagement) - { this.elementKeyWorld.storeClassifiedBufferKey(bufferKey, bufferSize); } - else - { gl.deleteBuffer(bufferKey); } + this.makeMesh(this.vertexMatrix, this.tTrianglesMatrix, + this.shadowVertexMatrix, this.shadowTTrianglesMatrix); + // this.makeMesh(this.shadowVertexMatrix, this.shadowTTrianglesMatrix, + // true); + // this.shadowTTrianglesMatrix.invertTrianglesSense();// TEST!!!!!! + this.doShadowMeshWithSunDirection(); + + this.rotateMeshByLocation(this.vertexMatrix); + this.rotateMeshByLocation(this.shadowVertexMatrix); + + var position = Cesium.Cartesian3.fromDegrees(this.longitude, this.latitude, + this.altitude); + this.position = position; + + // var splitValue = Cesium.EncodedCartesian3.encode(position); + var splitVelueX = Cesium.EncodedCartesian3.encode(position.x); + var splitVelueY = Cesium.EncodedCartesian3.encode(position.y); + var splitVelueZ = Cesium.EncodedCartesian3.encode(position.z); + + this.positionHIGH = new Float32Array([ splitVelueX.high, splitVelueY.high, + splitVelueZ.high ]); + this.positionLOW = new Float32Array([ splitVelueX.low, splitVelueY.low, + splitVelueZ.low ]); + + this.bbox = this.shadowVertexMatrix.getBoundingBox(this.bbox); + var cloudPoint3d; + cloudPoint3d = this.bbox.getCenterPoint(cloudPoint3d); + this.cullingPosition = new Cesium.Cartesian3(cloudPoint3d.x + + this.position.x, cloudPoint3d.y + this.position.y, cloudPoint3d.z + + this.position.z); + this.cullingRadius = this.bbox.getMaxLength() / 2; }; /** - * 어떤 일을 하고 있습니까? - * @returns vboBufferStandardSize + * mesh 생성 + * + * @param vtxMat + * 변수 + * @param tTriMat + * 변수 + * @param shadowVtxMat + * 변수 + * @param shadowTTriMat + * 변수 */ -VBOMemoryManager.prototype.getClassifiedBufferSize = function(currentBufferSize) +CircularCloud.prototype.makeMesh = function(vtxMat, tTriMat, shadowVtxMat, + shadowTTriMat) { - if (this.enableMemoryManagement) - { return this.buffersKeyWorld.getClassifiedBufferSize(currentBufferSize); } - else - { return currentBufferSize; } -}; + // use vertex_matrix. + // our cloud has 6 rings. Top ring and the bottom ring has radius zero. + var numPointsForRing = 16; + var increAngRad = (2.0 * Math.PI) / numPointsForRing; + var angRad = 0.0; + var vertex; + var shadowVertex; + var semiDepth = this.depth / 2.0; + var x = 0.0; + var y = 0.0; + var randomValue = 0; + // var cloudWhite = 0.98; + + // 1) Top ring. radius zero. + var vertexList = vtxMat.newVertexList(); + var shadowVertexList = shadowVtxMat.newVertexList(); + randomValue = 0.9 + 0.3 * Math.random(); + for (var i = 0; i < numPointsForRing; i++) + { + vertex = vertexList.newVertex(); + vertex.setPosition(x, y, semiDepth); + shadowVertex = shadowVertexList.newVertex(); + shadowVertex.setPosition(x, y, -semiDepth * 1.2); + vertex.setColorRGB(randomValue, randomValue, randomValue); + } + // 2) Top menor_ring. + angRad = 0.0; + var menorRingRadius = this.radius * 0.7; + vertexList = vtxMat.newVertexList(); + shadowVertexList = shadowVtxMat.newVertexList(); + for (var i = 0; i < numPointsForRing; i++) + { + // Math.random(); // returns from 0.0 to 1.0. + randomValue = (2 + Math.random()) / 2; + vertex = vertexList.newVertex(); + shadowVertex = shadowVertexList.newVertex(); + x = menorRingRadius * Math.cos(angRad) * randomValue; + y = menorRingRadius * Math.sin(angRad) * randomValue; + shadowVertex.setPosition(x, y, -semiDepth * 2); + vertex.setPosition(x, y, semiDepth * 0.8); + randomValue = 0.9 + 0.3 * Math.random(); + vertex.setColorRGB(randomValue, randomValue, randomValue); + angRad += increAngRad; + } + // 3) Top major_ring. + angRad = 0.0; + vertexList = vtxMat.newVertexList(); + shadowVertexList = shadowVtxMat.newVertexList(); + for (var i = 0; i < numPointsForRing; i++) + { + randomValue = (2 + Math.random()) / 2; + vertex = vertexList.newVertex(); + shadowVertex = shadowVertexList.newVertex(); + x = this.radius * Math.cos(angRad) * randomValue; + y = this.radius * Math.sin(angRad) * randomValue; + shadowVertex.setPosition(x, y, -semiDepth * 2); + vertex.setPosition(x, y, semiDepth * 0.4); + randomValue = 0.9 + 0.3 * Math.random(); + vertex.setColorRGB(randomValue, randomValue, randomValue); + angRad += increAngRad; + } + // 4) Bottom major_ring. + angRad = 0.0; + vertexList = vtxMat.newVertexList(); + shadowVertexList = shadowVtxMat.newVertexList(); + for ( var i = 0; i < numPointsForRing; i++ ) + { + randomValue = (2 + Math.random()) / 2; + vertex = vertexList.newVertex(); + shadowVertex = shadowVertexList.newVertex(); + x = this.radius * Math.cos(angRad) * randomValue; + y = this.radius * Math.sin(angRad) * randomValue; + shadowVertex.setPosition(x, y, -semiDepth * 2); + vertex.setPosition(x, y, -semiDepth * 0.4); + randomValue = 0.8 + 0.3 * Math.random(); + vertex.setColorRGB(randomValue, randomValue, randomValue); + angRad += increAngRad; + } + // 5) Bottom menor_ring. + angRad = 0.0; + menorRingRadius = this.radius * 0.7; + vertexList = vtxMat.newVertexList(); + shadowVertexList = shadowVtxMat.newVertexList(); + for (var i = 0; i < numPointsForRing; i++ ) + { + randomValue = (2 + Math.random()) / 2; + vertex = vertexList.newVertex(); + shadowVertex = shadowVertexList.newVertex(); + x = menorRingRadius * Math.cos(angRad) * randomValue; + y = menorRingRadius * Math.sin(angRad) * randomValue; + vertex.setPosition(x, y, -semiDepth * 0.8); + shadowVertex.setPosition(x, y, -semiDepth * 1.2); + randomValue = 0.6 + 0.3 * Math.random(); + vertex.setColorRGB(randomValue, randomValue, randomValue); + // vertex.setColorRGB(0.58, 0.58, 0.58); + angRad += increAngRad; + } + // 6) Bottom ring. radius zero. + vertexList = vtxMat.newVertexList(); + shadowVertexList = shadowVtxMat.newVertexList(); + randomValue = 0.6 + 0.3 * Math.random(); + for ( var i = 0; i < numPointsForRing; i++ ) + { + // randomValue = (2+Math.random())/2; + vertex = vertexList.newVertex(); + shadowVertex = shadowVertexList.newVertex(); + vertex.setPosition(0.0, 0.0, -semiDepth); + shadowVertex.setPosition(0.0, 0.0, -semiDepth); + vertex.setColorRGB(randomValue, randomValue, randomValue); + // vertex.setColorRGB(0.58, 0.58, 0.58); + } + // Now, make the tTrianglesMatrix. + vtxMat.makeTTrianglesLateralSidesLOOP(tTriMat); + shadowVtxMat.makeTTrianglesLateralSidesLOOP(shadowTTriMat); + // tTriMat.invertTrianglesSense(); // No. + // Now, calculate the culling bbox. +}; 'use strict'; /** - * 어떤 일을 하고 있습니까? - * @class VisibleObjectsController + * Bounding box + * 영역박스 + * + * @alias BoundingBox + * @class BoundingBox */ -var VisibleObjectsController = function() +var BoundingBox = function() { - if (!(this instanceof VisibleObjectsController)) + if (!(this instanceof BoundingBox)) { throw new Error(Messages.CONSTRUCT_ERROR); } - - this.currentVisibles0 = []; - this.currentVisibles1 = []; - this.currentVisibles2 = []; - this.currentVisibles3 = []; - this.currentVisiblesAux = []; + + this.minX = 1000000.0; + this.minY = 1000000.0; + this.minZ = 1000000.0; + + this.maxX = -1000000.0; + this.maxY = -1000000.0; + this.maxZ = -1000000.0; }; -VisibleObjectsController.prototype.initArrays = function() +/** + * Initiate the value of the bounding box + * @param {Point3D} point 3차원 점 + */ +BoundingBox.prototype.init = function(point) { - this.currentVisibles0 = []; - this.currentVisibles1 = []; - this.currentVisibles2 = []; - this.currentVisibles3 = []; - this.currentVisiblesAux = []; -}; + point = point || new Point3D(); -VisibleObjectsController.prototype.clear = function() -{ - this.currentVisibles0.length = 0; - this.currentVisibles1.length = 0; - this.currentVisibles2.length = 0; - this.currentVisibles3.length = 0; - this.currentVisiblesAux.length = 0; + this.minX = point.x; + this.minY = point.y; + this.minZ = point.z; + + this.maxX = point.x; + this.maxY = point.y; + this.maxZ = point.z; }; /** + * Delete bounding box + * 영역박스 삭제 + * */ -VisibleObjectsController.prototype.getNodeIdxSortedByDist = function(nodesArray, startIdx, endIdx, node) +BoundingBox.prototype.deleteObjects = function() { - // this do a dicotomic search of idx in a ordered table. - // 1rst, check the range. - var neoBuilding = node.data.neoBuilding; - var range = endIdx - startIdx; - if (range < 6) - { - // in this case do a lineal search. - var finished = false; - var i = startIdx; - var idx; + this.minX = undefined; + this.minY = undefined; + this.minZ = undefined; - while (!finished && i<=endIdx) - { - var aNeoBuilding = nodesArray[i].data.neoBuilding; - if (neoBuilding.distToCam < aNeoBuilding.distToCam) - { - idx = i; - finished = true; - } - i++; - } - - if (finished) - { return idx; } - else - { return endIdx+1; } - } - else - { - // in this case do the dicotomic search. - var middleIdx = startIdx + Math.floor(range/2); - var newStartIdx; - var newEndIdx; - var middleNeoBuilding = nodesArray[middleIdx].data.neoBuilding; - if (middleNeoBuilding.distToCam > neoBuilding.distToCam) - { - newStartIdx = startIdx; - newEndIdx = middleIdx; - } - else - { - newStartIdx = middleIdx; - newEndIdx = endIdx; - } - return this.getNodeIdxSortedByDist(nodesArray, newStartIdx, newEndIdx, node); - } + this.maxX = undefined; + this.maxY = undefined; + this.maxZ = undefined; }; /** + * + * Copy other box + * @param bbox box */ -VisibleObjectsController.prototype.putNodeToArraySortedByDist = function(nodesArray, node) +BoundingBox.prototype.copyFrom = function(bbox) { - if (nodesArray.length > 0) - { - var startIdx = 0; - var endIdx = nodesArray.length - 1; - var idx = this.getNodeIdxSortedByDist(nodesArray, startIdx, endIdx, node); - - nodesArray.splice(idx, 0, node); - } - else - { - nodesArray.push(node); - } -}; - - + this.minX = bbox.minX; + this.minY = bbox.minY; + this.minZ = bbox.minZ; + this.maxX = bbox.maxX; + this.maxY = bbox.maxY; + this.maxZ = bbox.maxZ; +}; +/** + * Move the center of the box to the origin + */ +BoundingBox.prototype.translateToOrigin = function() +{ + var semiXLength = this.getXLength() /2; + var semiYLength = this.getYLength() /2; + var semiZLength = this.getZLength() /2; + + this.minX = -semiXLength; + this.minY = -semiYLength; + this.minZ = -semiZLength; + this.maxX = semiXLength; + this.maxY = semiYLength; + this.maxZ = semiZLength; +}; +/** + * Expane the size of the box as double of the given distance + * 영역박스 확대 + * + * @param {Number} distance + */ +BoundingBox.prototype.expand = function(distance) +{ + distance = distance || 0.0; + distance = Math.abs(distance); + this.minX -= distance; + this.minY -= distance; + this.minZ -= distance; + this.maxX += distance; + this.maxY += distance; + this.maxZ += distance; +}; +/** + * 주어진 3차원 점을 포함하는 영역으로 영역박스 크기를 변경 + * + * @param {Point3D} point 3차원 점 + */ +BoundingBox.prototype.addPoint = function(point) +{ + if (point === undefined) { return; } + if (point.x < this.minX) { this.minX = point.x; } + else if (point.x > this.maxX) { this.maxX = point.x; } + if (point.y < this.minY) { this.minY = point.y; } + else if (point.y > this.maxY) { this.maxY = point.y; } + if (point.z < this.minZ) { this.minZ = point.z; } + else if (point.z > this.maxZ) { this.maxZ = point.z; } +}; +/** + * Set the range of the box which contain given box + * 주어진 영역박스를 포함하는 영역으로 영역박스 크기를 변경 + * + * @param {BoundingBox} box 영역박스 + */ +BoundingBox.prototype.addBox = function(box) +{ + if (box === undefined) { return; } + if (box.minX < this.minX) { this.minX = box.minX; } + if (box.maxX > this.maxX) { this.maxX = box.maxX; } + if (box.minY < this.minY) { this.minY = box.minY; } + if (box.maxY > this.maxY) { this.maxY = box.maxY; } -/* eslint-env jquery */ -'use strict'; + if (box.minZ < this.minZ) { this.minZ = box.minZ; } + if (box.maxZ > this.maxZ) { this.maxZ = box.maxZ; } +}; /** - * An API that interacts with the on-screen UI. Class name to be modified by APIGateWay or API class - * @class MagoFacade - */ -/** - * mago3d 활성화/비활성화 - * @param {ManagerFactory} managerFactoryInstance - * @param {boolean} isShow true = show, false = hide + * Get the minimum length among x, y, z edges' lengths + * 영역박스의 가로, 세로, 높이 중에서 최소값 + * + * @returns {Number} 최소값 */ -function changeMagoStateAPI(managerFactoryInstance, isShow) +BoundingBox.prototype.getMinLength = function() { - if (managerFactoryInstance === null) { return; } - - var api = new API("changeMagoState"); - api.setMagoEnable(isShow); - managerFactoryInstance.callAPI(api); + return Math.min(this.maxX - this.minX, this.maxY - this.minY, this.maxZ - this.minZ); }; /** - * Label show/hide - * @param {ManagerFactory} managerFactoryInstance - * @param {boolean} isShow true = show, false = hide + * Get the maximum length among x, y, z edges' lengths + * @returns {Number} 최대값 */ -function changeLabelAPI(managerFactoryInstance, isShow) +BoundingBox.prototype.getMaxLength = function() { - if (managerFactoryInstance === null) { return; } - - var api = new API("changeLabel"); - api.setShowLabelInfo(isShow); - managerFactoryInstance.callAPI(api); -} + return Math.max(this.maxX - this.minX, this.maxY - this.minY, this.maxZ - this.minZ); +}; /** - * Origin show/hide - * @param {ManagerFactory} managerFactoryInstance - * @param {boolean} isShow true = show, false = hide + * Get the length of the edge which is parallel to x axis + * 영역박스의 X축 방향의 길이 + * + * @returns {Number} 길이값 */ -function changeOriginAPI(managerFactoryInstance, isShow) +BoundingBox.prototype.getXLength = function() { - if (managerFactoryInstance === null) { return; } - - var api = new API("changeOrigin"); - api.setShowOrigin(isShow); - managerFactoryInstance.callAPI(api); -} + return this.maxX - this.minX; +}; /** - * boundingBox show/hide - * @param {ManagerFactory} managerFactoryInstance - * @param {boolean} isShow true = show, false = hide + * Get the length of the edge which is parallel to y axis + * 영역박스의 Y축 방향의 길이 + * + * @returns {Number} 길이값 */ -function changeBoundingBoxAPI(managerFactoryInstance, isShow) +BoundingBox.prototype.getYLength = function() { - if (managerFactoryInstance === null) { return; } - - var api = new API("changeBoundingBox"); - api.setShowBoundingBox(isShow); - managerFactoryInstance.callAPI(api); -} + return this.maxY - this.minY; +}; /** - * 속성값에 의한 가시화 유무설정 - * @param {ManagerFactory} managerFactoryInstance - * @param {boolean} isShow true = 표시, false = 비표시 + * Get the length of the edge which is parallel to z axis + * 영역박스의 Z축 방향의 길이 + * + * @returns {Number} 길이값 */ -function changePropertyRenderingAPI(managerFactoryInstance, isShow, projectId, property) +BoundingBox.prototype.getZLength = function() { - if (managerFactoryInstance === null) { return; } - - var api = new API("changePropertyRendering"); - api.setShowShadow(isShow); - api.setProjectId(projectId); - api.setProperty(property); - managerFactoryInstance.callAPI(api); -} + return this.maxZ - this.minZ; +}; /** - * 그림자 표시/비표시 - * @param {ManagerFactory} managerFactoryInstance - * @param {boolean} isShow true = 활성화, false = 비활성화 + * Get the center point of this box + * 영역박스의 중심점을 구한다. + * + * @param {Point3D} result 영역박스의 중심점 + * + * @returns {Point3D} 영역박스의 중심점 */ -function changeShadowAPI(managerFactoryInstance, isShow) +BoundingBox.prototype.getCenterPoint = function(result) { - if (managerFactoryInstance === null) { return; } - - var api = new API("changeShadow"); - api.setShowShadow(isShow); - managerFactoryInstance.callAPI(api); -} + if ( result === undefined ) { result = new Point3D(); } -/** - * color 변경 - * @param {ManagerFactory} managerFactoryInstance - * @param {string} projectId 프로젝트 아이디 - * @param {string} dataKey data key - * @param {string} objectIds object id. 복수개의 경우 , 로 입력 - * @param {string} property 속성값 예)isMain=true - * @param {string} color R, G, B 색깔을 ',' 로 연결한 string 값을 받음. - */ -function changeColorAPI(managerFactoryInstance, projectId, dataKey, objectIds, property, color) -{ - if (managerFactoryInstance === null) { return; } - - var api = new API("changeColor"); - api.setProjectId(projectId); - api.setDataKey(dataKey); - api.setObjectIds(objectIds); - api.setProperty(property); - api.setColor(color); - managerFactoryInstance.callAPI(api); -} + result.set((this.maxX + this.minX)/2, (this.maxY + this.minY)/2, (this.maxZ + this.minZ)/2); + + return result; +}; /** - * location and rotation 변경 - * @param {ManagerFactory} managerFactoryInstance - * @param {string} projectId - * @param {string} dataKey - * @param {string} latitude 위도 - * @param {string} longitude 경도 - * @param {string} height 높이 - * @param {string} heading 좌, 우 - * @param {string} pitch 위, 아래 - * @param {string} roll 좌, 우 기울기 + * + * 영역박스의 중심점을 구한다. + * + * @returns {Number} apriximately radius. */ -function changeLocationAndRotationAPI(managerFactoryInstance, projectId, dataKey, latitude, longitude, height, heading, pitch, roll) +BoundingBox.prototype.getRadiusAprox = function() { - if (managerFactoryInstance === null) { return; } - - var api = new API("changeLocationAndRotation"); - api.setProjectId(projectId); - api.setDataKey(dataKey); - api.setLatitude(latitude); - api.setLongitude(longitude); - api.setElevation(height); - api.setHeading(heading); - api.setPitch(pitch); - api.setRoll(roll); - managerFactoryInstance.callAPI(api); -} + var maxLength = this.getMaxLength(); + return maxLength/1.5; +}; + /** - * 마우스 클릭 객체 이동 대상 변경 - * @param {ManagerFactory} managerFactoryInstance - * @param {string} objectMoveMode 0 = All, 1 = object, 2 = None + * 영역박스와 점과의 교차 여부를 판단 + * + * @param {Point3D} point 3차원 점 + * @returns {Boolean} 교차 여부 */ -function changeObjectMoveAPI(managerFactoryInstance, objectMoveMode) +BoundingBox.prototype.intersectWithPoint = function(point) { - if (managerFactoryInstance === null) { return; } - - var api = new API("changeObjectMove"); - api.setObjectMoveMode(objectMoveMode); - managerFactoryInstance.callAPI(api); -} + if (point === undefined) { return false; } + + if (point.x < this.minX || point.x > this.maxX || + point.y < this.minY || point.y > this.maxY || + point.z < this.minZ || point.z > this.maxZ) + { + return false; + } + + //return this.isPoint3dInside(point.x, point.y, point.z); + return true; +}; /** - * 마우스로 이동한 객체 정보를 브라우저내 저장 - * @param {ManagerFactory} managerFactoryInstance - * @param {string} objectMoveMode 0 = All, 1 = object, 2 = None + * Check whether the given point is contained or intersected with this box + * 영역박스와 점과의 교차 여부를 판단 + * + * @param {Number} x x성분 + * @param {Number} y y성분 + * @param {Number} z z성분 + * @returns {Boolean} 교차 여부 */ -function saveObjectMoveAPI(managerFactoryInstance, objectMoveMode) +BoundingBox.prototype.isPoint3dInside = function(x, y, z) { - if (managerFactoryInstance === null) { return; } - - var api = new API("saveObjectMove"); - api.setObjectMoveMode(objectMoveMode); - managerFactoryInstance.callAPI(api); -} + if (x < this.minX || x > this.maxX) + { + return false; + } + else if (y < this.minY || y > this.maxY) + { + return false; + } + else if (z < this.minZ || z > this.maxZ) + { + return false; + } + + return true; +}; /** - * 브라우저내 모든 마우스 이동 정보를 삭제 - * @param {ManagerFactory} managerFactoryInstance - * @param {string} objectMoveMode 0 = All, 1 = object, 2 = None + * 영역박스와 주어진 영역박스와의 교차 여부를 판단 + * + * @param {BoundingBox} box 영역박스 + * @returns {Boolean} 교차 여부 */ -function deleteAllObjectMoveAPI(managerFactoryInstance, objectMoveMode) +BoundingBox.prototype.intersectWithBox = function(box) { - if (managerFactoryInstance === null) { return; } - - var api = new API("deleteAllObjectMove"); - api.setObjectMoveMode(objectMoveMode); - managerFactoryInstance.callAPI(api); -} + if (box === undefined) { return false; } + + if (box.minX > this.maxX || box.maxX < this.minX || + box.minY > this.maxY || box.maxY < this.minY || + box.minZ > this.maxZ || box.maxZ < this.minZ) + { + return false; + } + + return true; +}; /** - * 브라우저내 모든 색깔 변경 이력을 삭제 - * @param {ManagerFactory} managerFactoryInstance + * Check whether this box and the given box are intersected by each others. + * 영역박스와 주어진 영역박스와의 교차 여부를 판단 + * + * @param {BoundingBox} box Bounding box 영역박스 + * @returns {Boolean} the flag whether they are intersected or not 교차 여부 */ -function deleteAllChangeColorAPI(managerFactoryInstance) +BoundingBox.prototype.intersectsWithBBox = function(box) { - if (managerFactoryInstance === null) { return; } - - var api = new API("deleteAllChangeColor"); - managerFactoryInstance.callAPI(api); -} + var intersection = true; + + if (this.maxX < box.minX) + { + intersection = false; + } + else if (this.minX > box.maxX) + { + intersection = false; + } + else if (this.maxY < box.minY) + { + intersection = false; + } + else if (this.minY > box.maxY) + { + intersection = false; + } + else if (this.maxZ < box.minZ) + { + intersection = false; + } + else if (this.minZ > box.maxZ) + { + intersection = false; + } + + return intersection; +}; + +'use strict'; /** - * 이슈 등록 활성화 유무 - * @param {ManagerFactory} managerFactoryInstance - * @param {boolean} flag true = 활성화, false = 비활성화 + * This class is needed to be implemented at the future. not yet implemented fully. + * @class BoundingSphere */ -function changeInsertIssueModeAPI(managerFactoryInstance, flag) +var BoundingSphere = function() { - if (managerFactoryInstance === null) { return; } - - var api = new API("changeInsertIssueMode"); - api.setIssueInsertEnable(flag); - managerFactoryInstance.callAPI(api); -} + if (!(this instanceof BoundingSphere)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + + this.center = new Point3D(); + this.radius = 0.0; +}; +'use strict'; /** - * object 정보 표시 활성화 유무 - * @param {ManagerFactory} managerFactoryInstance - * @param {boolean} flag true = 활성화, false = 비활성화 + * This class is needed to be implemented more, but it will be used at the future. + * @class Box */ -function changeObjectInfoViewModeAPI(managerFactoryInstance, flag) +var Box = function(width, length, height) { - if (managerFactoryInstance === null) { return; } + if (!(this instanceof Box)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } - var api = new API("changeObjectInfoViewMode"); - api.setObjectInfoViewEnable(flag); - managerFactoryInstance.callAPI(api); -} + this.mesh; + this.vbo_vicks_container; + this.vbo_vicks_containerEdges; + this.centerPoint; + this.width; + this.length; + this.height; + + if (width !== undefined) + { this.width = width; } + + if (length !== undefined) + { this.length = length; } + + if (height !== undefined) + { this.height = height; } + +}; /** - * Object Occlusion culling - * @param {ManagerFactory} managerFactoryInstance - * @param {boolean} flag true = 활성화, false = 비활성화 - * @param {string} dataKey + * Get the VBO key container */ -function changeOcclusionCullingAPI(managerFactoryInstance, flag, dataKey) +Box.prototype.getVboKeysContainer = function() { - if (managerFactoryInstance === null) { return; } - - var api = new API("changeOcclusionCulling"); - api.setOcclusionCullingEnable(flag); - api.setDataKey(dataKey); - managerFactoryInstance.callAPI(api); -} + return this.vbo_vicks_container; +}; /** - * 1인칭, 3인칭 모드 개발중... - * @param {ManagerFactory} managerFactoryInstance - * @param {boolean} flag true = 활성화, false = 비활성화 + * Render this box feature + * @param {MagoManager} magoManager + * @param {Shader} shader + * @param {Number} renderType */ -function changeFPVModeAPI(managerFactoryInstance, flag) +Box.prototype.render = function(magoManager, shader, renderType) { - if (managerFactoryInstance === null) { return; } - - var api = new API("changeFPVMode"); - api.setFPVMode(flag); - managerFactoryInstance.callAPI(api); -} + if (this.mesh === undefined) + { + this.mesh = this.makeMesh(this.width, this.length, this.height); + return; + } + + this.mesh.render(magoManager, shader, renderType); +}; /** - * 현재 위치 근처 issue list. false인 경우 clear - * @param {ManagerFactory} managerFactoryInstance - * @param {boolean} flag true = 활성화, false = 비활성화 + * Set the width,length, height of this feature + * @param {Number} width + * @param {Number} length + * @param {Number} height */ -function changeNearGeoIssueListViewModeAPI(managerFactoryInstance, flag) +Box.prototype.makeMesh = function(width, length, height) { - if (managerFactoryInstance === null) { return; } + // check dimensions of the box. + if (width !== undefined) + { this.width = width; } - var api = new API("changeNearGeoIssueListViewMode"); - api.setNearGeoIssueListEnable(flag); - managerFactoryInstance.callAPI(api); -} - -/** - * TODO 이건 위에 이슈 등록 활성화, 비활성화 api로 통합이 가능할거 같음 - * issue 등록 geo 정보 관련 상태 변경 - * @param {ManagerFactory} managerFactoryInstance - * @param {string} insertIssueState 이슈 등록 좌표 상태 - */ -function changeInsertIssueStateAPI(managerFactoryInstance, insertIssueState) -{ - if (managerFactoryInstance === null) { return; } + if (length !== undefined) + { this.length = length; } - var api = new API("changeInsertIssueState"); - api.setInsertIssueState(insertIssueState); - managerFactoryInstance.callAPI(api); -} - -/** - * LOD 설정을 변경 - * @param {ManagerFactory} managerFactoryInstance - * @param {string} lod0DistInMeters - * @param {string} lod1DistInMeters - * @param {string} lod2DistInMeters - * @param {string} lod3DistInMeters - * @param {string} lod4DistInMeters - * @param {string} lod5DistInMeters - */ -function changeLodAPI(managerFactoryInstance, lod0DistInMeters, lod1DistInMeters, lod2DistInMeters, lod3DistInMeters, lod4DistInMeters, lod5DistInMeters) -{ - if (managerFactoryInstance === null) { return; } + if (height !== undefined) + { this.height = height; } - var api = new API("changeLod"); - api.setLod0DistInMeters(lod0DistInMeters); - api.setLod1DistInMeters(lod1DistInMeters); - api.setLod2DistInMeters(lod2DistInMeters); - api.setLod3DistInMeters(lod3DistInMeters); - api.setLod4DistInMeters(lod4DistInMeters); - api.setLod5DistInMeters(lod5DistInMeters); - managerFactoryInstance.callAPI(api); -} - -/** - * Lighting 설정 - * @param {ManagerFactory} managerFactoryInstance - * @param {string} ambientReflectionCoef - * @param {string} diffuseReflectionCoef - * @param {string} specularReflectionCoef - * @param {string} ambientColor - * @param {string} specularColor - */ -function changeLightingAPI(managerFactoryInstance, ambientReflectionCoef, diffuseReflectionCoef, specularReflectionCoef, ambientColor, specularColor) -{ - if (managerFactoryInstance === null) { return; } + if (this.width === undefined) + { this.width = 1; } - var api = new API("changeLighting"); - api.setAmbientReflectionCoef(ambientReflectionCoef); - api.setDiffuseReflectionCoef(diffuseReflectionCoef); - api.setSpecularReflectionCoef(specularReflectionCoef); - api.setAmbientColor(ambientColor); - api.setSpecularColor(specularColor); - managerFactoryInstance.callAPI(api); -} - -/** - * SSAO Radius 설정 - * @param {ManagerFactory} managerFactoryInstance - * @param {string} ssaoRadius - */ -function changeSsaoRadiusAPI(managerFactoryInstance, ssaoRadius) -{ - if (managerFactoryInstance === null) { return; } + if (this.length === undefined) + { this.length = 1; } - var api = new API("changeSsaoRadius"); - api.setSsaoRadius(ssaoRadius); - managerFactoryInstance.callAPI(api); -} - -/** - * 화면에 있는 모든 데이터를 삭제, 비표시 - * @param {ManagerFactory} managerFactoryInstance - */ -function clearAllDataAPI(managerFactoryInstance) -{ - if (managerFactoryInstance === null) { return; } + if (this.height === undefined) + { this.height = 1; } - var api = new API("clearAllData"); - MagoConfig.clearAllData(); - managerFactoryInstance.callAPI(api); -} - -/** - * pin image를 그림 - * @param {ManagerFactory} managerFactoryInstance - * @param {string} drawType 이미지를 그리는 유형 0 : DB, 1 : 이슈등록 - * @param {string} issue_id 이슈 고유키 - * @param {string} issue_type 이슈 고유키 - * @param {string} data_key 데이터 고유키 - * @param {string} latitude 데이터 고유키 - * @param {string} longitude 데이터 고유키 - * @param {string} height 데이터 고유키 - */ -function drawInsertIssueImageAPI(managerFactoryInstance, drawType, issue_id, issue_type, data_key, latitude, longitude, height) -{ - if (managerFactoryInstance === null) { return; } + if (this.centerPoint === undefined) + { this.centerPoint = new Point3D(0, 0, 0); } - var api = new API("drawInsertIssueImage"); - api.setDrawType(drawType); - api.setIssueId(issue_id); - api.setIssueId(issue_type); - api.setDataKey(data_key); - api.setLatitude(latitude); - api.setLongitude(longitude); - api.setElevation(height); - managerFactoryInstance.callAPI(api); -} - -/** - * 해당 프로젝트를 로딩하고 이동하기 - * @param {ManagerFactory} managerFactoryInstance - * @param {string} projectId project id - * @param {string} latitude 데이터 고유키 - * @param {string} longitude 데이터 고유키 - * @param {string} height 데이터 고유키 - * @param {string} duration 이동하는 시간 - */ -function gotoProjectAPI(managerFactoryInstance, projectId, projectData, projectDataFolder, longitude, latitude, height, duration) -{ - if (managerFactoryInstance === null) { return; } + if (this.vbo_vicks_container === undefined) + { this.vbo_vicks_container = new VBOVertexIdxCacheKeysContainer(); } - MagoConfig.setData(CODE.PROJECT_ID_PREFIX + projectId, projectData); - MagoConfig.setProjectDataFolder(CODE.PROJECT_DATA_FOLDER_PREFIX + projectDataFolder, projectDataFolder); + if (this.vbo_vicks_containerEdges === undefined) + { this.vbo_vicks_containerEdges = new VBOVertexIdxCacheKeysContainer(); } - var api = new API("gotoProject"); - api.setProjectId(projectId); - api.setProjectDataFolder(projectDataFolder); - api.setLatitude(latitude); - api.setLongitude(longitude); - api.setElevation(height); - api.setDuration(duration); - managerFactoryInstance.callAPI(api); -} - -/** - * 해당 프로젝트를 로딩하고 Issue 등록 지점으로 이동하기 - * @param {ManagerFactory} managerFactoryInstance - * @param {string} projectId project id - * @param {string} issueId issue id - * @param {string} issueType issue type - * @param {string} latitude 데이터 고유키 - * @param {string} longitude 데이터 고유키 - * @param {string} height 데이터 고유키 - * @param {string} duration 이동하는 시간 - */ -function gotoIssueAPI(managerFactoryInstance, projectId, projectData, projectDataFolder, issueId, issueType, longitude, latitude, height, duration) -{ - if (managerFactoryInstance === null) { return; } + // Create a parametric mesh. + var pMesh = new ParametricMesh(); + + // Create a Profile2d. + pMesh.profile = new Profile2D(); + var profileAux = pMesh.profile; - MagoConfig.setData(CODE.PROJECT_ID_PREFIX + projectId, projectData); - MagoConfig.setProjectDataFolder(CODE.PROJECT_DATA_FOLDER_PREFIX + projectDataFolder, projectDataFolder); + // Create a outer ring in the Profile2d. + var outerRing = profileAux.newOuterRing(); + var rect = outerRing.newElement("RECTANGLE"); + rect.setCenterPosition(this.centerPoint.x, this.centerPoint.y); + rect.setDimensions(this.width, this.length); - var api = new API("gotoIssue"); - api.setProjectId(projectId); - api.setProjectDataFolder(projectDataFolder); - api.setIssueId(issueId); - api.setIssueType(issueType); - api.setLatitude(latitude); - api.setLongitude(longitude); - api.setElevation(height); - api.setDuration(duration); - managerFactoryInstance.callAPI(api); -} + // Extrude the Profile. + var extrudeSegmentsCount = 1; + var extrusionVector = undefined; + pMesh.extrude(profileAux, this.height, extrudeSegmentsCount, extrusionVector); + + var bIncludeBottomCap = true; + var bIncludeTopCap = true; + var mesh = pMesh.getSurfaceIndependentMesh(undefined, bIncludeBottomCap, bIncludeTopCap); + + // translate the box bcos center the origen to the center of the box. + mesh.translate(0, 0, -this.height/2); + + return mesh; +}; + + + + + + + + + + + + + + + + + + + + + + + -/** - * 마우스를 사용할 수 없는 환경에서 버튼 이벤트로 대체 - * @param {ManagerFactory} managerFactoryInstance - * @param {string} eventType 어떤 마우스 동작을 원하는지를 구분 - */ -function mouseMoveAPI(managerFactoryInstance, eventType) -{ - if (managerFactoryInstance === null) { return; } - - managerFactoryInstance.mouseMove(eventType); -} -/** - * 데이터 검색 - * @param {ManagerFactory} managerFactoryInstance - * @param {string} projectId 데이터 고유키 - * @param {string} dataKey 데이터 고유키 - */ -function searchDataAPI(managerFactoryInstance, projectId, dataKey) -{ - if (managerFactoryInstance === null) { return; } - - var api = new API("searchData"); - api.setProjectId(projectId); - api.setDataKey(dataKey); - managerFactoryInstance.callAPI(api); -} -/** - * 환경 설정 data Object에 key 값의 존재 유무를 판별 - * @param {string} key 검색 키 - * @param - */ -function isDataExistAPI(key) -{ - if (MagoConfig.isDataExist(key)) { return true; } - else { return false; } -} -/** - * 환경 설정 data map에서 key 값을 취득 - * @param {string} key 검색 키 - * @param - */ -function getDataAPI(key) -{ - return MagoConfig.getData(key); -} -/** - * Data Key 를 이용하여 Geo Spatial Info를 취득 - * @param {ManagerFactory} managerFactoryInstance - * @param {String} projectId 고유키 - * @param {String} dataKey Data 고유키 - * @param - */ -function getDataInfoByDataKeyAPI(managerFactoryInstance, projectId, dataKey) -{ - if (managerFactoryInstance === null) { return; } - var api = new API("getDataInfoByDataKey"); - api.setProjectId(projectId); - api.setDataKey(dataKey); - managerFactoryInstance.callAPI(api); -} -/** - * 데이터를 Rendering - * @param {ManagerFactory} managerFactoryInstance - * @param {Object[]} projectIdArray 프로젝트 이름들 - * @param {Object[]} projectDataArray 프로젝트 데이터들 - * @param {Object[]} projectDataFolderArray 프로젝트 f4d 파일 경로 - * @param - */ -function drawAppendDataAPI(managerFactoryInstance, projectIdArray, projectDataArray, projectDataFolderArray) -{ - if (managerFactoryInstance === null) { return; } - - if (projectIdArray.length <= 0) { return; } - - var api = new API("drawAppendData"); - projectIdArray.forEach(function(dataName, index) - { - - MagoConfig.setData(CODE.PROJECT_ID_PREFIX + dataName, projectDataArray[index]); - MagoConfig.setProjectDataFolder(CODE.PROJECT_DATA_FOLDER_PREFIX + projectDataFolderArray[index], projectDataFolderArray[index]); - - api.setProjectId(dataName); - api.setProjectDataFolder(projectDataFolderArray[index]); - managerFactoryInstance.callAPI(api); - }); -} -/** - * get coodinate relative to building - * @param {ManagerFactory} managerFactoryInstance - * @param {string} projectId project primary key - * @param {string} dataKey data key - * @param {string} inputPoint input x, y, z - * @param {string} resultPoint return point - */ -function getCoordinateRelativeToBuildingAPI(managerFactoryInstance, projectId, dataKey, inputPoint, resultPoint) -{ - if (managerFactoryInstance === null) { return; } - var api = new API("getCoordinateRelativeToBuilding"); - api.setReturnable(true); - api.setProjectId(projectId); - api.setDataKey(dataKey); - api.setInputPoint(inputPoint); - api.setResultPoint(resultPoint); - return managerFactoryInstance.callAPI(api); -} -/** - * get absolte coodinate of building point - * @param {ManagerFactory} managerFactoryInstance - * @param {string} projectId project primary key - * @param {string} dataKey data key - * @param {string} inputPoint input x, y, z - * @param {string} resultPoint return point - */ -function getAbsoluteCoodinateOfBuildingPointAPI(managerFactoryInstance, projectId, dataKey, inputPoint, resultPoint) -{ - if (managerFactoryInstance === null) { return; } - var api = new API("getAbsoluteCoodinateOfBuildingPoint"); - api.setReturnable(true); - api.setProjectId(projectId); - api.setDataKey(dataKey); - api.setInputPoint(inputPoint); - api.setResultPoint(resultPoint); - return managerFactoryInstance.callAPI(api); -} 'use strict'; /** - * color 처리 관련 도메인 - * @class ColorAPI + * buildings seed. + * Represent single building feature. + * @class BuildingSeed */ -var ColorAPI = {}; - -ColorAPI.changeColor = function(api, magoManager) +var BuildingSeed = function() { - var projectId = api.getProjectId(); - var dataKey = api.getDataKey(); - var objectIds = api.getObjectIds(); - var property = api.getProperty(); - var propertyKey = null; - var propertyValue = null; - if (property !== null && property !== "") - { - var properties = property.split("="); - propertyKey = properties[0]; - propertyValue = properties[1]; - } - var color = api.getColor().split(","); - var rgbColor = [ color[0]/255, color[1]/255, color[2]/255 ] ; - - var isExistObjectIds = false; - if (objectIds !== null && objectIds.length !== 0) - { - isExistObjectIds = true; - } - - var changeHistorys = []; - if (isExistObjectIds) - { - for (var i=0, objectCount = objectIds.length; i we must develope lookAt function in magoworld. + } + } }; -API.prototype.getShowOrigin = function() -{ - return this.showOrigin; -}; -API.prototype.setShowOrigin = function(showOrigin) +/** + * stop track + * @param {Object} magoManager + */ +Camera.prototype.stopTrack = function(magoManager) { - this.showOrigin = showOrigin; + this.tracked = undefined; + if (MagoConfig.getPolicy().geo_view_library === Constant.CESIUM) + { + magoManager.scene.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); //set camera transform + } + else + { + //this.lookAtStop() -> we must develope lookAtStop function in magoworld. + } }; -API.prototype.getShowBoundingBox = function() -{ - return this.showBoundingBox; -}; -API.prototype.setShowBoundingBox = function(showBoundingBox) +/** + * set track node. + * Node is a single feature at F4D specification + * Implement this function for tracking moving objects such as automatically moving vehicle + * @param {Object} node + */ +Camera.prototype.setTrack = function(node) { - this.showBoundingBox = showBoundingBox; + this.tracked = node; }; +'use strict'; -API.prototype.getShowShadow = function() -{ - return this.showShadow; -}; -API.prototype.setShowShadow = function(showShadow) +/** + * 카메라 + * @class CCTV + */ +var CCTV = function(name) { - this.showShadow = showShadow; -}; + if (!(this instanceof CCTV)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + + this.name = "noName"; + if (name !== undefined) + { this.name = name; } -API.prototype.getFrustumFarDistance = function() -{ - return this.frustumFarDistance; -}; -API.prototype.setFrustumFarDistance = function(frustumFarDistance) -{ - this.frustumFarDistance = frustumFarDistance; + this.geoLocationData = new GeoLocationData(); + this.minHeading = 0.0; + this.maxHeading = 90.0; + + this.heading = 0.0; + this.pitch = 0.0; + this.roll = 0.0; + this.targetHeading; + this.targetPitch; + this.targetRoll; + + this.rotMat = new Matrix4(); + this.camera = new Camera(); + this.vboKeyContainer; // class: VBOVertexIdxCacheKeyContainer. + this.vboKeyContainerEdges; // class: VBOVertexIdxCacheKeyContainer. + this.color = new Color(); + this.color.setRGBA(0.0, 0.5, 0.9, 0.3); + this.greenFactorSpeed = 1.0; + this.blueFactorSpeed = 2.0; + this.alphaFactorSpeed = 2.0; + + this.headingAngularSpeed = 25.0; // deg per second. + this.pitchAngularSpeed; + this.rollAngularSpeed; + this.lastTime; + + this.greenFactor = 1.0; + this.blueFactor = 1.0; + this.alphaFactor = 1.0; }; -API.prototype.getObjectMoveMode = function() -{ - return this.objectMoveMode; -}; -API.prototype.setObjectMoveMode = function(objectMoveMode) +/** + * Update time as current time + * @param currTime current time + */ +CCTV.prototype.updateTime = function(currTime) { - this.objectMoveMode = objectMoveMode; + this.lastTime = currTime; }; -API.prototype.getIssueInsertEnable = function() -{ - return this.issueInsertEnable; -}; -API.prototype.setIssueInsertEnable = function(issueInsertEnable) -{ - this.issueInsertEnable = issueInsertEnable; -}; -API.prototype.getObjectInfoViewEnable = function() -{ - return this.objectInfoViewEnable; -}; -API.prototype.setObjectInfoViewEnable = function(objectInfoViewEnable) -{ - this.objectInfoViewEnable = objectInfoViewEnable; -}; -API.prototype.getOcclusionCullingEnable = function() -{ - return this.occlusionCullingEnable; -}; -API.prototype.setOcclusionCullingEnable = function(occlusionCullingEnable) -{ - this.occlusionCullingEnable = occlusionCullingEnable; -}; -API.prototype.getNearGeoIssueListEnable = function() -{ - return this.nearGeoIssueListEnable; -}; -API.prototype.setNearGeoIssueListEnable = function(nearGeoIssueListEnable) +/** + * Calculate the angularSpped to rotate the CCTV with the three direction : heading, pitch, roll + * @param headingDeg + * @param pitchDeg + * @param rollDeg + * @param transitionTimeSec + * + */ +CCTV.prototype.setOrientation = function(headingDeg, pitchDeg, rollDeg, transitionTimeSec) { - this.nearGeoIssueListEnable = nearGeoIssueListEnable; + this.targetHeading = headingDeg; + this.targetPitch = pitchDeg; + this.targetRoll = rollDeg; + + // Now, calculate angularSpeeds. + // Heading. + if (this.targetHeading !== undefined) + { + var increHeading = this.targetHeading - this.heading; + this.headingAngularSpeed = increHeading/transitionTimeSec; + + if (this.headingAngularSpeed === 0) + { + this.targetHeading = undefined; + this.headingAngularSpeed = undefined; + } + } + + // Pitch. + if (this.targetPitch !== undefined) + { + var increPitch = this.targetPitch - this.pitch; + this.pitchAngularSpeed = increPitch/transitionTimeSec; + + if (this.pitchAngularSpeed === 0) + { + this.targetPitch = undefined; + this.pitchAngularSpeed = undefined; + } + } + + // Roll. + if (this.targetRoll !== undefined) + { + var increRoll = this.targetRoll - this.roll; + this.rollAngularSpeed = increRoll/transitionTimeSec; + + if (this.rollAngularSpeed === 0) + { + this.targetRoll = undefined; + this.rollAngularSpeed = undefined; + } + } }; -API.prototype.getInsertIssueState = function() -{ - return this.insertIssueState; -}; -API.prototype.setInsertIssueState = function(insertIssueState) +/** + * Rotate the CCTV with current time and pre-calculated angular speed + * @param currTime current time + */ +CCTV.prototype.updateOrientation = function(currTime) { - this.insertIssueState = insertIssueState; -}; + // Check if camera is rotating. + if (this.targetHeading === undefined && this.targetPitch === undefined && this.targetRoll === undefined) + { return; } + + if (this.lastTime === undefined) + { this.lastTime = currTime; } -API.prototype.getDrawType = function() -{ - return this.drawType; -}; -API.prototype.setDrawType = function(drawType) -{ - this.drawType = drawType; + var timeAmount = (currTime - this.lastTime)/1000; + + // Heading. + if (this.headingAngularSpeed !== undefined) + { + this.heading += timeAmount * this.headingAngularSpeed; + // Check if heading arrived to targetHeading. + if (this.headingAngularSpeed > 0) + { + // Camera is rotating ccw. + if (this.heading >= this.targetHeading) + { + this.heading = this.targetHeading; + this.targetHeading = undefined; + } + } + else + { + // Camera is rotating cw. + if (this.heading <= this.targetHeading) + { + this.heading = this.targetHeading; + this.targetHeading = undefined; + } + } + + if (this.headingAngularSpeed === 0) + { + this.targetHeading = undefined; + this.headingAngularSpeed = undefined; + } + } + + // Pitch. + if (this.pitchAngularSpeed !== undefined) + { + this.pitch += timeAmount * this.pitchAngularSpeed; + + // Check if pitch arrived to targetPitch. + if (this.pitchAngularSpeed > 0) + { + // Camera is rotating ccw. + if (this.pitch >= this.targetPitch) + { + this.pitch = this.targetPitch; + this.targetPitch = undefined; + } + } + else + { + // Camera is rotating cw. + if (this.pitch <= this.targetPitch) + { + this.pitch = this.targetPitch; + this.targetPitch = undefined; + } + } + + if (this.pitchAngularSpeed === 0) + { + this.targetPitch = undefined; + this.pitchAngularSpeed = 0; + } + } + + // Roll. + if (this.rollAngularSpeed !== undefined) + { + this.roll += timeAmount * this.rollAngularSpeed; + // Check if pitch arrived to targetPitch. + if (this.rollAngularSpeed > 0) + { + // Camera is rotating ccw. + if (this.roll >= this.targetRoll) + { + this.roll = this.targetRoll; + this.targetRoll = undefined; + } + } + else + { + // Camera is rotating cw. + if (this.roll <= this.targetRoll) + { + this.roll = this.targetRoll; + this.targetRoll = undefined; + } + } + + if (this.rollAngularSpeed === 0) + { + this.targetRoll = undefined; + this.rollAngularSpeed = undefined; + } + } + + this.calculateRotationMatrix(); }; -API.prototype.getLod0DistInMeters = function() -{ - return this.lod0DistInMeters; -}; -API.prototype.setLod0DistInMeters = function(lod0DistInMeters) -{ - this.lod0DistInMeters = lod0DistInMeters; -}; -API.prototype.getLod1DistInMeters = function() +/** + * only rotating with the heading direction + * @param currTime current time + */ +CCTV.prototype.updateHeading = function(currTime) { - return this.lod1DistInMeters; + // Old function. + if (this.lastTime === undefined) + { this.lastTime = currTime; } + + var timeAmount = (currTime - this.lastTime)/1000; + this.heading += timeAmount * this.headingAngularSpeed; + + if (this.heading > this.maxHeading) + { + this.heading = this.maxHeading; + this.headingAngularSpeed *= -1.0; + } + else if (this.heading < this.minHeading) + { + this.heading = this.minHeading; + this.headingAngularSpeed *= -1.0; + } + + this.calculateRotationMatrix(); }; -API.prototype.setLod1DistInMeters = function(lod1DistInMeters) + +/** + * Update the color of the screen shown at the CCTV + * @param currTime + */ +CCTV.prototype.updateColor = function(currTime) { - this.lod1DistInMeters = lod1DistInMeters; + if (this.lastTime === undefined) + { this.lastTime = currTime; } + + var timeAmount = (currTime - this.lastTime)/1000; + + // change color. + if (this.greenFactor === undefined) + { this.greenFactor = 1.0; } + + if (this.blueFactor === undefined) + { this.blueFactor = 1.0; } + + if (this.alphaFactor === undefined) + { this.alphaFactor = 1.0; } + + this.greenFactor += this.greenFactorSpeed * timeAmount; + this.blueFactor += this.blueFactorSpeed * timeAmount; + + if (this.greenFactor > 0.5 ) + { + this.greenFactor = 0.5; + this.greenFactorSpeed *= -1; + } + + if (this.greenFactor < 0.0 ) + { + this.greenFactor = 0.0; + this.greenFactorSpeed *= -1; + } + + if (this.blueFactor > 0.9 ) + { + this.blueFactor = 0.9; + this.blueFactorSpeed *= -1; + } + + if (this.blueFactor < 0.0 ) + { + this.blueFactor = 0.0; + this.blueFactorSpeed *= -1; + } + + + if (this.alphaFactor > 0.6 ) + { + this.alphaFactor = 0.6; + this.alphaFactorSpeed *= -1; + } + + if (this.alphaFactor < 0.0 ) + { + this.alphaFactor = 0.0; + this.alphaFactorSpeed *= -1; + } + + this.color.setRGBA(0.0, this.greenFactor, this.blueFactor, this.alphaFactor); }; -API.prototype.getLod2DistInMeters = function() + +/** + * Calculate the matrix when update the orientation of the matrix + */ +CCTV.prototype.calculateRotationMatrix = function() { - return this.lod2DistInMeters; + var rotMatAux; + rotMatAux = Matrix4.getRotationDegZXYMatrix(this.heading, this.pitch, this.roll, rotMatAux); + this.rotMat = rotMatAux.getMultipliedByMatrix(this.geoLocationData.rotMatrix, this.rotMat); }; -API.prototype.setLod2DistInMeters = function(lod2DistInMeters) + +/** + * get the Vbo of the mesh which consist of the frustum of this CCTV + * @param resultVboContainer + * @param resultVboContainerEdges + * @param vboMemManager + */ +CCTV.prototype.getVbo = function(resultVboContainer, resultVboContainerEdges, vboMemManager) { - this.lod2DistInMeters = lod2DistInMeters; + if (resultVboContainer === undefined) + { resultVboContainer = new VBOVertexIdxCacheKeysContainer(); } + + if (this.vboKeyContainerEdges === undefined) + { this.vboKeyContainerEdges = new VBOVertexIdxCacheKeysContainer(); } + + var frustumMesh; + + // make vbo. + frustumMesh = this.makeFrustumGeometry_2(frustumMesh); + var bIncludeBottomCap = true; + var bIncludeTopCap = true; + + // now rotate in X axis. + var rotMatAux = new Matrix4(); + var frustum = this.camera.bigFrustum; + var halfFovyRad = frustum.fovyRad / 2.0; + rotMatAux.rotationAxisAngDeg((-halfFovyRad) * 180.0 / Math.PI, 1.0, 0.0, 0.0); + + var surfIndepMesh = frustumMesh.getSurfaceIndependentMesh(undefined, bIncludeBottomCap, bIncludeTopCap); + surfIndepMesh.transformByMatrix4(rotMatAux); + surfIndepMesh.setColor(0.0, 0.5, 0.9, 0.3); + + surfIndepMesh.getVbo(resultVboContainer, vboMemManager); + surfIndepMesh.getVboEdges(this.vboKeyContainerEdges, vboMemManager); + + return resultVboContainer; }; -API.prototype.getLod3DistInMeters = function() + +/** + * + */ +CCTV.prototype.render = function(gl, magoManager, shader) { - return this.lod3DistInMeters; -}; -API.prototype.setLod3DistInMeters = function(lod3DistInMeters) -{ - this.lod3DistInMeters = lod3DistInMeters; -}; -API.prototype.getLod4DistInMeters = function() -{ - return this.lod4DistInMeters; -}; -API.prototype.setLod4DistInMeters = function(lod4DistInMeters) -{ - this.lod4DistInMeters = lod4DistInMeters; -}; -API.prototype.getLod5DistInMeters = function() -{ - return this.lod5DistInMeters; -}; -API.prototype.setLod5DistInMeters = function(lod5DistInMeters) -{ - this.lod5DistInMeters = lod5DistInMeters; + if (this.vboKeyContainer === undefined) + { return; } + + var cacheKeys_count = this.vboKeyContainer.vboCacheKeysArray.length; + + //gl.uniform1i(shader.bApplySpecularLighting_loc, false); + + // Must applicate the transformMatrix. + gl.uniformMatrix4fv(shader.buildingRotMatrix_loc, false, this.geoLocationData.rotMatrix._floatArrays); + gl.uniform3fv(shader.buildingPosHIGH_loc, this.geoLocationData.positionHIGH); + gl.uniform3fv(shader.buildingPosLOW_loc, this.geoLocationData.positionLOW); + + gl.uniform1i(shader.hasTexture_loc, false); //. + + gl.enable(gl.POLYGON_OFFSET_FILL); + gl.polygonOffset(1, 3); + + var renderWireframe; + + var refMatrixType = 2; + gl.uniform1i(shader.refMatrixType_loc, refMatrixType); + gl.uniformMatrix4fv(shader.refMatrix_loc, false, this.rotMat._floatArrays); + + var renderer = magoManager.renderer; + + // render wireframe. + renderWireframe = true; + renderer.renderNormals = false; + gl.uniform4fv(shader.oneColor4_loc, [0.0, 0.0, 0.0, 1.0]); + renderer.renderVboContainer(gl, this.vboKeyContainerEdges, magoManager, shader, renderWireframe); + + // now render fill. + gl.enable(gl.BLEND); + renderWireframe = false; + renderer.renderNormals = true; + //gl.uniform4fv(shader.oneColor4_loc, [this.blueFactor, this.greenFactor, 0.0, this.alphaFactor]); + gl.uniform4fv(shader.oneColor4_loc, [this.blueFactor, 0.0, 0.0, this.alphaFactor]); + renderer.renderVboContainer(gl, this.vboKeyContainer, magoManager, shader, renderWireframe); + gl.disable(gl.BLEND); + + gl.disable(gl.POLYGON_OFFSET_FILL); }; -API.prototype.getAmbientReflectionCoef = function() -{ - return this.ambientReflectionCoef; -}; -API.prototype.setAmbientReflectionCoef = function(ambientReflectionCoef) -{ - this.ambientReflectionCoef = ambientReflectionCoef; -}; -API.prototype.getDiffuseReflectionCoef = function() -{ - return this.diffuseReflectionCoef; -}; -API.prototype.setDiffuseReflectionCoef = function(diffuseReflectionCoef) -{ - this.diffuseReflectionCoef = diffuseReflectionCoef; -}; -API.prototype.getSpecularReflectionCoef = function() -{ - return this.specularReflectionCoef; -}; -API.prototype.setSpecularReflectionCoef = function(specularReflectionCoef) -{ - this.specularReflectionCoef = specularReflectionCoef; -}; -API.prototype.getAmbientColor = function() -{ - return this.ambientColor; -}; -API.prototype.setAmbientColor = function(ambientColor) -{ - this.ambientColor = ambientColor; -}; -API.prototype.getSpecularColor = function() -{ - return this.specularColor; -}; -API.prototype.setSpecularColor = function(specularColor) -{ - this.specularColor = specularColor; -}; -API.prototype.getSsaoRadius = function() -{ - return this.ssaoRadius; -}; -API.prototype.setSsaoRadius = function(ssaoRadius) -{ - this.ssaoRadius = ssaoRadius; -}; -API.prototype.getFPVMode = function() -{ - return this.FPVMode; -}; -API.prototype.setFPVMode = function(value) +/** + * Make Frustum Geometry for this CCTV + * @param resultMesh the frustum + */ +CCTV.prototype.makeFrustumGeometry_2 = function(resultMesh) { - this.FPVMode = value; -}; + // 1rst, make the profile: icecream shape. + if (resultMesh === undefined) + { resultMesh = new ParametricMesh(); } -API.prototype.getDuration = function() -{ - return this.duration; -}; -API.prototype.setDuration = function(duration) -{ - this.duration = duration; + resultMesh.profile = new Profile2D(); + var profileAux = resultMesh.profile; + + // camera geometry values. + var frustum = this.camera.bigFrustum; + var far = frustum.far; + var halfFovyRad = frustum.fovyRad / 2.0; + var halfFovxRad = frustum.fovRad / 2.0; + + var left = -far * Math.tan(halfFovxRad); + var right = -left; + var top = far * Math.tan(halfFovyRad); + var bottom = -top; + + // Outer ring.** + var outerRing = profileAux.newOuterRing(); + var polyLine, point3d, arc; + + polyLine = outerRing.newElement("POLYLINE"); + point3d = polyLine.newPoint2d(-far * Math.sin(halfFovxRad), far * Math.cos(halfFovxRad)); // 0 + point3d = polyLine.newPoint2d(0.0, 0.0); // 1 + point3d = polyLine.newPoint2d(far * Math.sin(halfFovxRad), far * Math.cos(halfFovxRad)); // 2 + + var startAngDeg = 90.0 - halfFovxRad * 180.0 / Math.PI; + var endAngDeg = 90.0 + halfFovxRad * 180.0 / Math.PI; + arc = outerRing.newElement("ARC"); + this.sweepSense = 1; + arc.setCenterPosition(0.0, 0.0); + arc.setRadius(far); + ////arc.setStartPoint(far * Math.sin(halfFovxRad), far * Math.cos(halfFovxRad)); + ////arc.setEndPoint(-far * Math.sin(halfFovxRad), far * Math.cos(halfFovxRad)); + arc.setStartAngleDegree(startAngDeg); + arc.setSweepAngleDegree(endAngDeg - startAngDeg); + arc.numPointsFor360Deg = 36; + + // now revolve. + var revolveAngDeg, revolveSegmentsCount, revolveSegment2d; + revolveAngDeg = (halfFovyRad * 2) * 180.0 / Math.PI; + revolveSegment2d = new Segment2D(); + var strPoint2d = new Point2D(-1, 0); + var endPoint2d = new Point2D(1, 0); + revolveSegment2d.setPoints(strPoint2d, endPoint2d); + revolveSegmentsCount = 6; + resultMesh.revolve(profileAux, revolveAngDeg, revolveSegmentsCount, revolveSegment2d); + + return resultMesh; }; -API.prototype.getInputPoint = function() -{ - return this.inputPoint; -}; -API.prototype.setInputPoint = function(inputPoint) +/** + * Make Frustum Geometry for this CCTV + * @param resultMesh the frustum + */ +CCTV.prototype.makeFrustumGeometry = function(resultMesh) { - this.inputPoint = inputPoint; -}; + // make a frustum mesh. + if (resultMesh === undefined) + { resultMesh = new Mesh(); } -API.prototype.getResultPoint = function() -{ - return this.resultPoint; -}; -API.prototype.setResultPoint = function(resultPoint) -{ - this.resultPoint = resultPoint; + if (resultMesh.hedgesList === undefined) + { resultMesh.hedgesList = new HalfEdgesList(); } + + // 1rst, calculate the positions of 5 vertices. + var focusPosition = new Point3D(0.0, 0.0, 0.0); + + var frustum = this.camera.bigFrustum; + var far = frustum.far; + var halfFovyRad = frustum.fovyRad / 2.0; + var halfFovxRad = frustum.fovRad / 2.0; + + var left = -far * Math.tan(halfFovxRad); + var right = -left; + var top = far * Math.tan(halfFovyRad); + var bottom = -top; + + var farLeftDown = new Point3D(left, bottom, -far); + var farRightDown = new Point3D(right, bottom, -far); + var farRightTop = new Point3D(right, top, -far); + var farLeftTop = new Point3D(left, top, -far); + + // now make vertices. 5 vertices in total. + var focusVertex = new Vertex(focusPosition); + var farLeftDownVertex = new Vertex(farLeftDown); + var farRightDownVertex = new Vertex(farRightDown); + var farRightTopVertex = new Vertex(farRightTop); + var farLeftTopVertex = new Vertex(farLeftTop); + + // provisionally make wireframe here. + if (this.vboKeyContainerEdges === undefined) + { this.vboKeyContainerEdges = new VBOVertexIdxCacheKeysContainer(); } + + var face; + + // there are no near polygon. + // 1- far polygon. + var farSurface = resultMesh.newSurface(); + face = farSurface.newFace(); + // ad vertices in ccw order. + face.addVertex(farLeftDownVertex); + face.addVertex(farLeftTopVertex); + face.addVertex(farRightTopVertex); + face.addVertex(farRightDownVertex); + + // make wireframe vbo. + var vertex_1, vertex_2, pos_1, pos_2; + var next_idx; + var curr_edge_idx = 0; + var posDataArray = []; + var indicesDataArray = []; + + var vertexCount = face.vertexArray.length; + for (var i=0; i 1.0){ gray = 1.0; } + else if (gray<0.0){ gray = 0.0; } - this.serverPolicy = serverPolicy; - if (projectIdArray !== null && projectIdArray.length > 0) + var r, g, b; + + r = -gray + 1.0; + + if (gray > 0.5) { - for (var i=0; i= 254) + { + this.color.b = 0; + this.color.g += 1; + if (this.color.g >= 254) + { + this.color.g = 0; + this.color.r += 1; + if (this.color.r >= 254) + { + this.color.r = 0; + this.cycle += 1; + } + } + } + + return resultColor; }; /** - * 모든 object 선택 내용 이력을 취득 + * Change the RGB code to color code. + * (255,255,255) is used to white color so 254 number is used + * @param {Number} r + * @param {Number} g + * @param {Number} b + * @returns Color code */ -MagoConfig.getAllMovingHistory = function() +SelectionColor.prototype.decodeColor3 = function(r, g, b) { - return this.movingHistoryObject; + return 64516*r + 254*g + b; }; -/** - * project별 입력키 값과 일치하는 object 이동 내용 이력을 취득 - */ -MagoConfig.getMovingHistoryObjects = function(projectId, dataKey) -{ - // projectId 별 Object을 검사 - var projectIdObject = this.movingHistoryObject[projectId]; - if (projectIdObject === undefined) { return undefined; } - // dataKey 별 Object을 검사 - var dataKeyObject = projectIdObject[dataKey]; - return dataKeyObject; -}; -/** - * object 이동 내용 이력을 취득 - */ -MagoConfig.getMovingHistoryObject = function(projectId, dataKey, objectIndexOrder) -{ - // projectId 별 Object을 검사 - var projectIdObject = this.movingHistoryObject[projectId]; - if (projectIdObject === undefined) { return undefined; } - // dataKey 별 Object을 검사 - var dataKeyObject = projectIdObject[dataKey]; - if (dataKeyObject === undefined) { return undefined; } - // objectIndexOrder 를 저장 - return dataKeyObject[objectIndexOrder]; -}; + + + + + +'use strict'; /** - * object 이동 내용을 저장 + * Frame Buffer Object + * @class FBO + * @param {WebGLRenderingContext} gl WebGL rendering context. + * @param {Number} width Framebuffer width. + * @param {Number} height Framebuffer height. */ -MagoConfig.saveMovingHistory = function(projectId, dataKey, objectIndexOrder, changeHistory) +var FBO = function(gl, width, height) { - // projectId 별 Object을 검사 - var projectIdObject = this.movingHistoryObject[projectId]; - if (projectIdObject === undefined) + if (!(this instanceof FBO)) { - projectIdObject = {}; - this.movingHistoryObject[projectId] = projectIdObject; + throw new Error(Messages.CONSTRUCT_ERROR); } - // dataKey 별 Object을 검사 - var dataKeyObject = projectIdObject[dataKey]; - if (dataKeyObject === undefined) + /** + * WebGL rendering context. + * @type {WebGLRenderingContext} + * @default WebGLRenderingContext + */ + this.gl = gl; + + /** + * Framebuffer width. + * @type {Number} + * @default 0 + */ + this.width = new Int32Array(1); + + /** + * Framebuffer height. + * @type {Number} + * @default 0 + */ + this.height = new Int32Array(1); + + /** + * WebGL Framebuffer. + * @type {WebGLFramebuffer} + * @default WebGLFramebuffer + */ + this.fbo = gl.createFramebuffer(); + + + /** + * WebGL Renderbuffer. + * @type {WebGLRenderbuffer} + * @default WebGLRenderbuffer + */ + this.depthBuffer = gl.createRenderbuffer(); + + /** + * WebGL texture. + * @type {WebGLTexture} + * @default WebGLTexture + */ + this.colorBuffer = gl.createTexture(); + + /** + * Boolean var that indicates that the parameters must be updated. + * @type {Boolean} + * @default true + */ + this.dirty = true; + + // Init process. + this.width[0] = width; + this.height[0] = height; + + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, this.colorBuffer); + + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); //LINEAR_MIPMAP_LINEAR + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + //gl.generateMipmap(gl.TEXTURE_2D) + + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width[0], height[0], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + + gl.bindFramebuffer(gl.FRAMEBUFFER, this.fbo); + gl.bindRenderbuffer(gl.RENDERBUFFER, this.depthBuffer); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width[0], height[0]); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.depthBuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.colorBuffer, 0); + if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) { - dataKeyObject = {}; - projectIdObject[dataKey] = dataKeyObject; + throw "Incomplete frame buffer object."; } - - // objectIndexOrder 를 저장 - dataKeyObject[objectIndexOrder] = changeHistory; -}; + + gl.bindFramebuffer(gl.FRAMEBUFFER, null); +}; /** - * object 이동 내용을 삭제 + * Binds the framebuffer. */ -MagoConfig.deleteMovingHistoryObject = function(projectId, dataKey, objectIndexOrder) +FBO.prototype.bind = function() { - // projectId 별 Object을 검사 - var projectIdObject = this.movingHistoryObject[projectId]; - if (projectIdObject === undefined) { return undefined; } - // dataKey 별 Object을 검사 - var dataKeyObject = projectIdObject[dataKey]; - if (dataKeyObject === undefined) { return undefined; } - // objectIndexOrder 를 저장 - return delete dataKeyObject[objectIndexOrder]; + this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.fbo); }; /** - * 모든 색깔 변경 이력을 획득 + * Unbinds the framebuffer. */ -MagoConfig.getAllColorHistory = function() +FBO.prototype.unbind = function() { - return this.colorHistoryObject; + this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null); }; /** - * 모든 색깔변경 히스토리 삭제 + * Deletes all objects. + * @param gl */ -MagoConfig.clearColorHistory = function() +FBO.prototype.deleteObjects = function(gl) { - this.colorHistoryObject = {}; + if (this.depthBuffer) + { gl.deleteRenderbuffer(this.depthBuffer); } + this.depthBuffer = undefined; + + if (this.colorBuffer) + { gl.deleteTexture(this.colorBuffer); } + this.colorBuffer = undefined; + + if (this.fbo) + { gl.deleteFramebuffer(this.fbo); } + this.fbo = undefined; + + }; /** - * project별 키에 해당하는 모든 색깔 변경 이력을 획득 + * Returns a new WebGL buffer. + * @param {WebGLRenderingContext} gl WebGL Rendering Context. + * @param {TypedArray} data Data array to bind. + * @returns {WebGLBuffer} WebGL Buffer. */ -MagoConfig.getColorHistorys = function(projectId, dataKey) +FBO.createBuffer = function(gl, data) { - // projectId 별 Object을 검사 - var projectIdObject = this.colorHistoryObject[projectId]; - if (projectIdObject === undefined) { return undefined; } - // dataKey 별 Object을 검사 - var dataKeyObject = projectIdObject[dataKey]; - return dataKeyObject; + const buffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW); + return buffer; }; /** - * 색깝 변경 이력을 획득 + * Binds a framebuffer and texture to this instance + * @param {WebGLRenderingContext} gl WebGL Rendering Context. + * @param {WebGLFramebuffer} framebuffer WebGL Framebuffer. + * @param {WebGLTexture} texture WebGL Texture. */ -MagoConfig.getColorHistory = function(projectId, dataKey, objectId) +FBO.bindFramebuffer = function(gl, framebuffer, texture) { - // projectId 별 Object을 검사 - var projectIdObject = this.colorHistoryObject[projectId]; - if (projectIdObject === undefined) { return undefined; } - // dataKey 별 Object을 검사 - var dataKeyObject = projectIdObject[dataKey]; - if (dataKeyObject === undefined) { return undefined; } - // objectId 를 저장 - return dataKeyObject[objectId]; + gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); + if (texture) + { + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + } +}; +/** + * Binds the attribute of each + */ +FBO.bindAttribute = function(gl, buffer, attribute, numComponents) +{ + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.enableVertexAttribArray(attribute); + gl.vertexAttribPointer(attribute, numComponents, gl.FLOAT, false, 0, 0); +}; + +FBO.bindTexture = function(gl, texture, unit) +{ + gl.activeTexture(gl.TEXTURE0 + unit); + gl.bindTexture(gl.TEXTURE_2D, texture); }; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +'use strict'; + /** - * 색깝 변경 내용을 저장 + * xmlhttprequest 요청 개수를 저장하기 위한 객체 + * @class FileRequestControler */ -MagoConfig.saveColorHistory = function(projectId, dataKey, objectId, changeHistory) +var FileRequestControler = function() { - // projectId 별 Object을 검사 - var projectIdObject = this.colorHistoryObject[projectId]; - if (projectIdObject === undefined) + if (!(this instanceof FileRequestControler)) { - projectIdObject = {}; - this.colorHistoryObject[projectId] = projectIdObject; + throw new Error(Messages.CONSTRUCT_ERROR); } - // dataKey 별 Object을 검사 - var dataKeyObject = projectIdObject[dataKey]; - if (dataKeyObject === undefined) + this.maxFilesRequestedCount = 1; + this.filesRequestedCount = 0; + this.headerFilesRequestedCount = 0; + this.modelRefFilesRequestedCount = 0; + this.lowLodDataRequestedCount = 0; + this.lowLodImagesRequestedCount = 0; +}; + +FileRequestControler.prototype.isFull = function () +{ + return this.filesRequestedCount >= this.maxFilesRequestedCount; +}; + +FileRequestControler.prototype.isFullHeaders = function () +{ + return this.headerFilesRequestedCount >= 1; +}; + +FileRequestControler.prototype.isFullPlus = function (extraCount) +{ + if (extraCount === undefined) + { extraCount = 0; } + + return this.filesRequestedCount >= (this.maxFilesRequestedCount + extraCount); +}; + +FileRequestControler.prototype.isFullPlusModelReferences = function (extraCount) +{ + if (extraCount === undefined) + { extraCount = 0; } + + return this.modelRefFilesRequestedCount >= (this.maxFilesRequestedCount + extraCount); +}; + +FileRequestControler.prototype.isFullPlusLowLodData = function (extraCount) +{ + if (extraCount === undefined) + { extraCount = 0; } + + return this.lowLodDataRequestedCount >= (this.maxFilesRequestedCount + extraCount); +}; + +FileRequestControler.prototype.isFullPlusLowLodImages = function (extraCount) +{ + if (extraCount === undefined) + { extraCount = 0; } + + return this.lowLodImagesRequestedCount >= (this.maxFilesRequestedCount + extraCount); +}; + +'use strict'; + +var keyFlags = { + moveForward : false, + moveBackward : false, + moveLeft : false, + moveRight : false +}; + +function getFlagFromKeyCode(code) +{ + switch (code) { - dataKeyObject = {}; - projectIdObject[dataKey] = dataKeyObject; + case 37 : // Arrow-Left + { + //console.log("KeyDown Left"); + return 'moveLeft'; } - - if (objectId === null || objectId === "") + case 38 : // Arrow-Up { - dataKeyObject[dataKey] = changeHistory; + //console.log("KeyDown Up"); + return 'moveForward'; } - else + case 39 : // Arrow-Right { - dataKeyObject[objectId] = changeHistory; + //console.log("KeyDown Right"); + return 'moveRight'; + } + case 40 : // Arrow-Down + { + //console.log("KeyDown Down"); + return 'moveBackward'; + } + default : + { + return undefined; + } } }; -/** - * 색깔 변경 이력을 삭제 - */ -MagoConfig.deleteColorHistory = function(projectId, dataKey, objectId) +function onKeyDown(event) { - // projectId 별 Object을 검사 - var projectIdObject = this.colorHistoryObject[projectId]; - if (projectIdObject === undefined) { return undefined; } - // dataKey 별 Object을 검사 - var dataKeyObject = projectIdObject[dataKey]; - if (dataKeyObject === undefined) { return undefined; } - // objectIndexOrder 를 저장 - return delete dataKeyObject[objectId]; + var flag = getFlagFromKeyCode(event.keyCode); + if ( typeof flag !== 'undefined') + { + keyFlags[flag] = true; + } }; -/** - * 모든 색깔변경 히스토리 삭제 - */ -MagoConfig.clearColorHistory = function() +function onKeyUp(event) { - this.colorHistoryObject = {}; + var flag = getFlagFromKeyCode(event.keyCode); + if ( typeof flag !== 'undefined') + { + keyFlags[flag] = false; + } }; /** - * 모든 location and rotation 변경 이력을 획득 + * 카메라 1인칭 시점 모드 + * */ -MagoConfig.getAllLocationAndRotationHistory = function() +function FirstPersonView () { - return this.locationAndRotationHistoryObject; + this._camera = undefined; + this._cameraBAK = undefined; + this._position = new Point3D(); + this._rotation = new Point3D(); + this._positionSpeed = 1.0; + this._ratationSpeed = 1.0; +} + +Object.defineProperties(FirstPersonView.prototype, { + "camera": { + get : function () { return this._camera; }, + set : function (value) { this._camera = value; } + }, + "position": { + get : function () { return this._position; }, + set : function (value) { this._position = value; } + }, + "rotation": { + get : function () { return this._rotation; }, + set : function (value) { this._rotation = value; } + }, + "positionSpeed": { + get : function () { return this._positionSpeed; }, + set : function (value) { this._positionSpeed = value; } + }, + "rotationSpeed": { + get : function () { return this._ratationSpeed; }, + set : function (value) { this._ratationSpeed = value; } + } +}); + +FirstPersonView.prototype.init = function () +{ + this._position.set(0.0, 0.0, 0.0); + this._rotation.set(0.0, 0.0, 0.0); + + document.addEventListener('keydown', onKeyDown, false); + document.addEventListener('keyup', onKeyUp, false); }; -/** - * 프로젝트별 해당 키 값을 갖는 모든 location and rotation 이력을 획득 - */ -MagoConfig.getLocationAndRotationHistorys = function(projectId, dataKey) +FirstPersonView.prototype.release = function () { - // projectId 별 Object을 검사 - var projectIdObject = this.locationAndRotationHistoryObject[projectId]; - if (projectIdObject === undefined) { return undefined; } - // dataKey 별 Object을 검사 - var dataKeyObject = projectIdObject[dataKey]; - return dataKeyObject; + this._camera = undefined; + this._cameraBAK = undefined; + document.removeEventListener('keydown', onKeyDown, false); + document.removeEventListener('keyup', onKeyUp, false); }; -/** - * location and rotation 이력을 획득 - */ -MagoConfig.getLocationAndRotationHistory = function(projectId, dataKey) +FirstPersonView.prototype.move = function (vector) { - // projectId 별 Object을 검사 - var projectIdObject = this.locationAndRotationHistoryObject[projectId]; - if (projectIdObject === undefined) { return undefined; } - // dataKey 별 Object을 검사 - var dataKeyObject = projectIdObject[dataKey]; - - return dataKeyObject; + var position = glMatrix.vec3.fromValues(this._position.x, this._position.y, this.position.z); + var matrix = glMatrix.mat4.create(); + glMatrix.mat4.rotateY(matrix, matrix, this._rotation.y); + glMatrix.vec3.transformMat4(vector, vector, matrix); + glMatrix.vec3.add(position, position, vector); + this._position.set(position[0], position[1], position[2]); +}; +FirstPersonView.prototype.update = function(manager) +{ + if (this._camera === undefined) { return; } + if (keyFlags.moveForward) + { + //var isBlocked = manager.checkCollision(this._camera.position, this._camera.direction); + //if (isBlocked) { return; } + this._camera.moveForward(0.5); + this.move(vec3.fromValues(0.0, 1.0, 0.0)); + } + if (keyFlags.moveBackward) + { + this._camera.moveBackward(0.5); + this.move(vec3.fromValues(0.0, -1.0, 0.0)); + } + if (keyFlags.moveLeft) + { + this._camera.lookLeft(0.1); + this.move(vec3.fromValues(-1.0, 0.0, 0.0)); + } + if (keyFlags.moveRight) + { + this._camera.lookRight(0.1); + this.move(vec3.fromValues(1.0, 0.0, 0.0)); + } }; +'use strict'; + /** - * location and rotation 내용을 저장 + * Furstum used by camera + * @class Frustum */ -MagoConfig.saveLocationAndRotationHistory = function(projectId, dataKey, changeHistory) +var Frustum = function() { - // projectId 별 Object을 검사 - var projectIdObject = this.locationAndRotationHistoryObject[projectId]; - if (projectIdObject === undefined) + if (!(this instanceof Frustum)) { - projectIdObject = {}; - this.locationAndRotationHistoryObject[projectId] = projectIdObject; + throw new Error(Messages.CONSTRUCT_ERROR); } - // dataKey 별 Object을 검사 - var dataKeyObject = projectIdObject[dataKey]; - if (dataKeyObject === undefined) + this.near = new Float32Array([0.1]); + this.far = new Float32Array([1000.0]); + this.fovyRad = new Float32Array([0.8037]); //vertical viewing angle + this.tangentOfHalfFovy = new Float32Array([0.0]); // to get the length of the horizontal angle of fov + this.fovRad = new Float32Array([1.047]);//horizontal viewing angle + this.aspectRatio = new Float32Array([1.3584]); + this.planesArray = []; + this.dirty = true; + + // plane[0] = near, plane[1] = far. + for (var i=0; i<6; i++) { - dataKeyObject = {}; + var plane = new Plane(); + this.planesArray.push(plane); } - - dataKeyObject[dataKey] = changeHistory; }; /** - * location and rotation 이력을 삭제 + * copy the other frustum + * @param {Frustum} frustum */ -MagoConfig.deleteLocationAndRotationHistory = function(projectId, dataKey) +Frustum.prototype.copyParametersFrom = function(frustum) { - // projectId 별 Object을 검사 - var projectIdObject = this.locationAndRotationHistoryObject[projectId]; - if (projectIdObject === undefined) { return undefined; } - // dataKey 별 Object을 검사 - var dataKeyObject = delete projectIdObject[dataKey]; + this.near[0] = frustum.near[0]; + this.far[0] = frustum.far[0]; + this.fovyRad[0] = frustum.fovyRad[0]; + this.tangentOfHalfFovy[0] = frustum.tangentOfHalfFovy[0]; + this.fovRad[0] = frustum.fovRad[0]; + this.aspectRatio[0] = frustum.aspectRatio[0]; }; /** - * 모든 location and rotation 히스토리 삭제 + * Set the near of frustum by distance + * @param {Float32} near */ -MagoConfig.clearLocationAndRotationHistory = function() +Frustum.prototype.setNear = function(near) { - this.locationAndRotationHistoryObject = {}; + this.near[0] = near; }; - + /** - * TODO 이건 나중에 활요. 사용하지 않음 - * check 되지 않은 데이터들을 삭제함 - * @param keyObject 비교할 맵 + * Set the fart of frustum by distance + * @param {Float32} far */ -/*MagoConfig.clearUnSelectedData = function(keyObject) +Frustum.prototype.setFar = function(far) { - for (var key of this.dataObject.keys()) - { - if (!keyObject.hasxxxxx(key)) - { - // data folder path가 존재하면.... - if (key.indexOf(CODE.PROJECT_DATA_FOLDER_PREFIX) >= 0) - { - // 지우는 처리가 있어야 함 - } - this.dataObject.delete(key); - } - } -};*/ - -'use strict'; + this.far[0] = far; +}; /** - * Policy - * @class Policy + * Check whether the bounding sphere of the feature is intersected with the near and far of the frustum for frustum culling + * @param {Sphere} sphere + * @returns {Boolean} */ -var Policy = function() +Frustum.prototype.intersectionNearFarSphere = function(sphere) { - if (!(this instanceof Policy)) + var intersects = false; + for (var i=0; i<2; i++) { - throw new Error(Messages.CONSTRUCT_ERROR); + var intersectionType = this.planesArray[i].intersectionSphere(sphere); + if (intersectionType === Constant.INTERSECTION_OUTSIDE) + { return Constant.INTERSECTION_OUTSIDE; } + else if (intersectionType === Constant.INTERSECTION_INTERSECT) + { intersects = true; } } - - // mago3d 활성화/비활성화 여부 - this.magoEnable = true; - - // outfitting 표시 여부 - this.showOutFitting = false; - // label 표시/비표시 - this.showLabelInfo = false; - // boundingBox 표시/비표시 - this.showBoundingBox = false; - // 그림자 표시/비표시 - this.showShadow = false; - // squared far frustum 거리 - this.frustumFarSquaredDistance = 5000000; - // far frustum - this.frustumFarDistance = 20000; - - // highlighting - this.highLightedBuildings = []; - // color - this.colorBuildings = []; - // color - this.color = []; - // show/hide - this.hideBuildings = []; - // move mode - this.objectMoveMode = CODE.moveMode.NONE; - // 이슈 등록 표시 - this.issueInsertEnable = false; - // object 정보 표시 - this.objectInfoViewEnable = false; - // 이슈 목록 표시 - this.nearGeoIssueListEnable = false; - // occlusion culling - this.occlusionCullingEnable = false; - // origin axis XYZ - this.showOrigin = false; - - // 이미지 경로 - this.imagePath = ""; - - // provisional.*** - this.colorChangedObjectId; - - // LOD1 - this.lod0DistInMeters = 15; - this.lod1DistInMeters = 50; - this.lod2DistInMeters = 90; - this.lod3DistInMeters = 200; - this.lod4DistInMeters = 1000; - this.lod5DistInMeters = 50000; - - // Lighting - this.ambientReflectionCoef = 0.45; // 0.2. - this.diffuseReflectionCoef = 0.75; // 1.0 - this.specularReflectionCoef = 0.6; // 0.7 - this.ambientColor = null; - this.specularColor = new Float32Array([0.6, 0.6, 0.6]); - this.ssaoRadius = 0.15; + if (intersects) + { return Constant.INTERSECTION_INTERSECT; } + else + { return Constant.INTERSECTION_INSIDE; } }; -Policy.prototype.getShowOrigin = function() + +/** + * Check whether the bounding sphere of the feature is intersected with this frustum for frustum culling + * @param {Sphere} sphere + * @returns {Boolean} + */ +Frustum.prototype.intersectionSphere = function(sphere) { - return this.showOrigin; + var intersects = false; + for (var i=0; i<6; i++) + { + var intersectionType = this.planesArray[i].intersectionSphere(sphere); + if (intersectionType === Constant.INTERSECTION_OUTSIDE) + { return Constant.INTERSECTION_OUTSIDE; } + else if (intersectionType === Constant.INTERSECTION_INTERSECT) + { intersects = true; } + } + + if (intersects) + { return Constant.INTERSECTION_INTERSECT; } + else + { return Constant.INTERSECTION_INSIDE; } }; -Policy.prototype.setShowOrigin = function(showOrigin) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +'use strict'; + +/** + * Manage the objects which is shown at each volume of this frustum + * @class FrustumVolumeControl + */ +var FrustumVolumeControl = function() { - this.showOrigin = showOrigin; + if (!(this instanceof FrustumVolumeControl)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + + this.frustumVolumensMap = {}; }; -Policy.prototype.getMagoEnable = function() +/** + * Find the specific volumn by the key of this.frustumVolumensMap + * @param {Number} key + * @returns {Frustum} + */ +FrustumVolumeControl.prototype.getFrustumVolumeCulling = function(key) { - return this.magoEnable; + // 1rst, check if exist. If no exist create it. + if (!this.frustumVolumensMap.hasOwnProperty(key)) + { + this.frustumVolumensMap[key] = {}; + this.frustumVolumensMap[key].fullyIntersectedLowestTilesArray = []; + this.frustumVolumensMap[key].partiallyIntersectedLowestTilesArray = []; + this.frustumVolumensMap[key].visibleNodes = new VisibleObjectsController(); + } + + return this.frustumVolumensMap[key]; }; -Policy.prototype.setMagoEnable = function(magoEnable) + +/** + * Initiate and clear all the objects in the array + */ +FrustumVolumeControl.prototype.initArrays = function() { - this.magoEnable = magoEnable; + var frustumVolumeObject; + for (var key in this.frustumVolumensMap) + { + if (Object.prototype.hasOwnProperty.call(this.frustumVolumensMap, key)) + { + frustumVolumeObject = this.frustumVolumensMap[key]; + frustumVolumeObject.fullyIntersectedLowestTilesArray.length = 0; + frustumVolumeObject.partiallyIntersectedLowestTilesArray.length = 0; + frustumVolumeObject.visibleNodes.initArrays(); + } + } }; +'use strict'; -Policy.prototype.getShowOutFitting = function() +/** + * This class represents the coordinate as geographic coordinate system + * @class GeographicCoord + */ +var GeographicCoord = function(lon, lat, alt) { - return this.showOutFitting; + if (!(this instanceof GeographicCoord)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + + this.longitude; + this.latitude; + this.altitude; + + if (lon !== undefined) + { this.longitude = lon; } + + if (lat !== undefined) + { this.latitude = lat; } + + if (alt !== undefined) + { this.altitude = alt; } + + this.absolutePoint; // x, y, z of the coordinate in wgs84. + this.vboKeysContainer; + this.geoLocDataManager; + this.owner; }; -Policy.prototype.setShowOutFitting = function(showOutFitting) + +/** + * Clear the value of this instance from the vbo key container and geoLocDataManager + * @param {VBOMemoryManager}vboMemManager + */ +GeographicCoord.prototype.deleteObjects = function(vboMemManager) { - this.showOutFitting = showOutFitting; + this.longitude = undefined; + this.latitude = undefined; + this.altitude = undefined; + + if (this.absolutePoint !== undefined) + { + this.absolutePoint.deleteObjects(); + this.absolutePoint = undefined; + } + + if (this.vboKeysContainer !== undefined) + { + this.vboKeysContainer.deleteGlObjects(vboMemManager.gl, vboMemManager); + } + + if (this.geoLocDataManager !== undefined) + { + this.geoLocDataManager.deleteObjects(); + } + + this.owner = undefined; }; -Policy.prototype.getShowLabelInfo = function() + +/** + * Change this GeographicCoord point to Point3D point + * @param {Point3D} resultPoint3D + */ +GeographicCoord.prototype.getWgs84Point3D = function(resultPoint3d) { - return this.showLabelInfo; + var cartesianAux = Globe.geographicToCartesianWgs84(this.longitude, this.latitude, this.altitude, undefined); + + if (resultPoint3d === undefined) + { resultPoint3d = new Point3D(); } + + resultPoint3d.set(cartesianAux[0], cartesianAux[1], cartesianAux[2]); + return resultPoint3d; }; -Policy.prototype.setShowLabelInfo = function(showLabelInfo) + +/** + * Change this GeographicCoord point to Point2D point using Mercator projection + * @param {Point2D} resultPoint2d + */ +GeographicCoord.prototype.getMercatorProjection = function(resultPoint2d) { - this.showLabelInfo = showLabelInfo; + return Globe.geographicToMercatorProjection(this.longitude, this.latitude, resultPoint2d); }; -Policy.prototype.getShowBoundingBox = function() + +/** + * get the GeoLocationDataManager of this feature + */ +GeographicCoord.prototype.getGeoLocationDataManager = function() { - return this.showBoundingBox; + if (this.geoLocDataManager === undefined) + { this.geoLocDataManager = new GeoLocationDataManager(); } + + return this.geoLocDataManager ; }; -Policy.prototype.setShowBoundingBox = function(showBoundingBox) + +/** + * Copy the value of the other GeographicCoord feature + * @param {GeographicCoord} geographicCoord + */ +GeographicCoord.prototype.copyFrom = function(geographicCoord) { - this.showBoundingBox = showBoundingBox; + this.longitude = geographicCoord.longitude; + this.latitude = geographicCoord.latitude; + this.altitude = geographicCoord.altitude; }; -Policy.prototype.getShowShadow = function() +/** + * Set lon,lat,alt at this feature + * @param longitude 경도 + * @param latitude 위도 + * @param altitude 고도 + */ +GeographicCoord.prototype.setLonLatAlt = function(longitude, latitude, altitude) { - return this.showShadow; + if (longitude !== undefined) + { this.longitude = longitude; } + if (latitude !== undefined) + { this.latitude = latitude; } + if (altitude !== undefined) + { this.altitude = altitude; } }; -Policy.prototype.setShowShadow = function(showShadow) + +/** + * get the middle point between two GeopraphicCoord features + * @param {GeographicCoord} geographicCoordA + * @param {GeographicCoord} geographicCoordB + * @param {GeographicCoord} resultGeographicCoord + * @returns {GeographicCoord} + */ +GeographicCoord.getMidPoint = function(geographicCoordA, geographicCoordB, resultGeographicCoord) { - this.showShadow = showShadow; + var midLat = ( geographicCoordA.latitude + geographicCoordB.latitude) / 2.0; + var midLon = ( geographicCoordA.longitude + geographicCoordB.longitude) / 2.0; + var midAlt = ( geographicCoordA.altitude + geographicCoordB.altitude) / 2.0; + + if (resultGeographicCoord === undefined) + { resultGeographicCoord = new GeographicCoord(midLon, midLat, midAlt); } + else + { + resultGeographicCoord.setLonLatAlt(midLon, midLat, midAlt); + } + + return resultGeographicCoord; }; -Policy.prototype.getFrustumFarSquaredDistance = function() +/** + * make the vbo data of this feature + * @param {VBOMemoryManager} vboMemManager + */ + +GeographicCoord.prototype.prepareData = function(vboMemManager) { - return this.frustumFarSquaredDistance; + if (this.vboKeysContainer === undefined) + { this.vboKeysContainer = new VBOVertexIdxCacheKeysContainer(); } + + if (this.vboKeysContainer.getVbosCount() === 0) + { + var vboKey = this.vboKeysContainer.newVBOVertexIdxCacheKey(); + + // Position. + var pos = new Float32Array([0.0, 0.0, 0.0]); + vboKey.setDataArrayPos(pos, vboMemManager); + } + + return true; }; -Policy.prototype.setFrustumFarSquaredDistance = function(frustumFarSquaredDistance) + +/** + * Render this feature + */ +GeographicCoord.prototype.renderPoint = function(magoManager, shader, gl, renderType) { - this.frustumFarSquaredDistance = frustumFarSquaredDistance; + if (!this.prepareData(magoManager.vboMemoryManager)) + { return false; } + + var buildingGeoLocation = this.geoLocDataManager.getCurrentGeoLocationData(); + buildingGeoLocation.bindGeoLocationUniforms(gl, shader); + + if (renderType === 2) + { + var selectionManager = magoManager.selectionManager; + var selectionColor = magoManager.selectionColor; + + var selColor = selectionColor.getAvailableColor(undefined); + var idxKey = selectionColor.decodeColor3(selColor.r, selColor.g, selColor.b); + + selectionManager.setCandidateGeneral(idxKey, this); + gl.uniform4fv(shader.oneColor4_loc, [selColor.r/255.0, selColor.g/255.0, selColor.b/255.0, 1.0]); + } + + var vbo_vicky = this.vboKeysContainer.vboCacheKeysArray[0]; // there are only one. + if (!vbo_vicky.bindDataPosition(shader, magoManager.vboMemoryManager)) + { return false; } + + gl.drawArrays(gl.POINTS, 0, vbo_vicky.vertexCount); + + }; -Policy.prototype.getFrustumFarDistance = function() + +//* +//* +//* +/** + * 어떤 일을 하고 있습니까? + * @class GeographicCoordsList + */ +var GeographicCoordsList = function() { - return this.frustumFarDistance; + if (!(this instanceof GeographicCoordsList)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + + this.geographicCoordsArray = []; + this.vboKeysContainer; + this.owner; + + // Aux vars. + this.points3dList; // used to render. }; -Policy.prototype.setFrustumFarDistance = function(frustumFarDistance) + +/** + * push single point + * @param {GeographicCoord} + */ +GeographicCoordsList.prototype.addGeoCoord = function(geographicPoint) { - this.frustumFarDistance = frustumFarDistance; + this.geographicCoordsArray.push(geographicPoint); + geographicPoint.owner = this; }; -Policy.prototype.getHighLightedBuildings = function() +/** + * get single point + * @param {Number} idx the index of target + */ +GeographicCoordsList.prototype.getGeoCoord = function(idx) { - return this.highLightedBuildings; + if (this.geographicCoordsArray === undefined) + { return undefined; } + + return this.geographicCoordsArray[idx]; }; -Policy.prototype.setHighLightedBuildings = function(highLightedBuildings) + +/** + * Get the number of the point in this list + * @returns {Number} the number of the points + */ +GeographicCoordsList.prototype.getGeoCoordsCount = function() { - this.highLightedBuildings = highLightedBuildings; + if (this.geographicCoordsArray === undefined) + { return 0; } + + return this.geographicCoordsArray.length; }; -Policy.prototype.getColorBuildings = function() +/** + * This function returns points3dArray relative to the geoLocIn. + * @param {GeoLocationData} geoLocIn the information about the axis of this GeographicCoord + * @param resultPoint3dArray + * + */ +GeographicCoordsList.prototype.getPointsRelativeToGeoLocation = function(geoLocIn, resultPoints3dArray) { - return this.colorBuildings; + + if (resultPoints3dArray === undefined) + { resultPoints3dArray = []; } + + var geoPointsCount = this.getGeoCoordsCount(); + + for (var i=0; i= 0 && screenCoord.y >= 0) + { + var word = "lon: " + geoCoord.longitude.toFixed(5) + ", lat: " + geoCoord.latitude.toFixed(5); + ctx.strokeText(word, screenCoord.x, screenCoord.y); + ctx.fillText(word, screenCoord.x, screenCoord.y); + } + } + ctx.restore(); + }; -Policy.prototype.setHideBuildings = function(hideBuildings) + +/** + * Change Point3D features from WGS84 Points + * @param resultPoint3DArray the target + */ +GeographicCoordsList.prototype.getWgs84Points3D = function(resultPoint3DArray) { - this.hideBuildings = hideBuildings; + if (resultPoint3DArray === undefined) + { resultPoint3DArray = []; } + + var geoCoord; + var geoCoordsCount = this.geographicCoordsArray.length; + for (var i=0; i= 0 && screenCoord.y >= 0) + { + var word = "lon: " + geoCoord.longitude.toFixed(5) + ", lat: " + geoCoord.latitude.toFixed(5); + ctx.strokeText(word, screenCoord.x, screenCoord.y); + ctx.fillText(word, screenCoord.x, screenCoord.y); + } + } + ctx.restore(); + }; -Policy.prototype.setSsaoRadius = function(ssaoRadius) + +/** + * Change Point3D features from WGS84 Points + * @param resultPoint3DArray the target + */ +GeographicCoordsList.prototype.getWgs84Points3D = function(resultPoint3DArray) { - this.ssaoRadius = ssaoRadius; + if (resultPoint3DArray === undefined) + { resultPoint3DArray = []; } + + var geoCoord; + var geoCoordsCount = this.geographicCoordsArray.length; + for (var i=0; i this._byteLength) { - this._byteLength = req; - } - return; - } - if (blen < 1) { - blen = 1; - } - while (req > blen) { - blen *= 2; - } - var buf = new ArrayBuffer(blen); - var src = new Uint8Array(this._buffer); - var dst = new Uint8Array(buf, 0, src.length); - dst.set(src); - this.buffer = buf; - this._byteLength = req; -}; -/** - Internal function to trim the DataStream buffer when required. - Used for stripping out the extra bytes from the backing buffer when - the virtual byteLength is smaller than the buffer byteLength (happens after - growing the buffer with writes and not filling the extra space completely). - @return {null} - */ -DataStream.prototype._trimAlloc = function() { - if (this._byteLength == this._buffer.byteLength) { - return; - } - var buf = new ArrayBuffer(this._byteLength); - var dst = new Uint8Array(buf); - var src = new Uint8Array(this._buffer, 0, dst.length); - dst.set(src); - this.buffer = buf; -}; -/** - Sets the DataStream read/write position to given position. - Clamps between 0 and DataStream length. - @param {number} pos Position to seek to. - @return {null} - */ -DataStream.prototype.seek = function(pos) { - var npos = Math.max(0, Math.min(this.byteLength, pos)); - this.position = (isNaN(npos) || !isFinite(npos)) ? 0 : npos; -}; -/** - Returns true if the DataStream seek pointer is at the end of buffer and - there's no more data to read. - @return {boolean} True if the seek pointer is at the end of the buffer. - */ -DataStream.prototype.isEof = function() { - return (this.position >= this.byteLength); -}; -/** - Maps an Int32Array into the DataStream buffer, swizzling it to native - endianness in-place. The current offset from the start of the buffer needs to - be a multiple of element size, just like with typed array views. - Nice for quickly reading in data. Warning: potentially modifies the buffer - contents. - @param {number} length Number of elements to map. - @param {?boolean} e Endianness of the data to read. - @return {Object} Int32Array to the DataStream backing buffer. - */ -DataStream.prototype.mapInt32Array = function(length, e) { - this._realloc(length * 4); - var arr = new Int32Array(this._buffer, this.byteOffset+this.position, length); - DataStream.arrayToNative(arr, e == null ? this.endianness : e); - this.position += length * 4; - return arr; -}; -/** - Maps an Int16Array into the DataStream buffer, swizzling it to native - endianness in-place. The current offset from the start of the buffer needs to - be a multiple of element size, just like with typed array views. - Nice for quickly reading in data. Warning: potentially modifies the buffer - contents. - @param {number} length Number of elements to map. - @param {?boolean} e Endianness of the data to read. - @return {Object} Int16Array to the DataStream backing buffer. - */ -DataStream.prototype.mapInt16Array = function(length, e) { - this._realloc(length * 2); - var arr = new Int16Array(this._buffer, this.byteOffset+this.position, length); - DataStream.arrayToNative(arr, e == null ? this.endianness : e); - this.position += length * 2; - return arr; -}; -/** - Maps an Int8Array into the DataStream buffer. - Nice for quickly reading in data. - @param {number} length Number of elements to map. - @param {?boolean} e Endianness of the data to read. - @return {Object} Int8Array to the DataStream backing buffer. - */ -DataStream.prototype.mapInt8Array = function(length) { - this._realloc(length * 1); - var arr = new Int8Array(this._buffer, this.byteOffset+this.position, length); - this.position += length * 1; - return arr; -}; -/** - Maps a Uint32Array into the DataStream buffer, swizzling it to native - endianness in-place. The current offset from the start of the buffer needs to - be a multiple of element size, just like with typed array views. - Nice for quickly reading in data. Warning: potentially modifies the buffer - contents. - @param {number} length Number of elements to map. - @param {?boolean} e Endianness of the data to read. - @return {Object} Uint32Array to the DataStream backing buffer. - */ -DataStream.prototype.mapUint32Array = function(length, e) { - this._realloc(length * 4); - var arr = new Uint32Array(this._buffer, this.byteOffset+this.position, length); - DataStream.arrayToNative(arr, e == null ? this.endianness : e); - this.position += length * 4; - return arr; -}; -/** - Maps a Uint16Array into the DataStream buffer, swizzling it to native - endianness in-place. The current offset from the start of the buffer needs to - be a multiple of element size, just like with typed array views. - Nice for quickly reading in data. Warning: potentially modifies the buffer - contents. - @param {number} length Number of elements to map. - @param {?boolean} e Endianness of the data to read. - @return {Object} Uint16Array to the DataStream backing buffer. - */ -DataStream.prototype.mapUint16Array = function(length, e) { - this._realloc(length * 2); - var arr = new Uint16Array(this._buffer, this.byteOffset+this.position, length); - DataStream.arrayToNative(arr, e == null ? this.endianness : e); - this.position += length * 2; - return arr; -}; -/** - Maps a Uint8Array into the DataStream buffer. - Nice for quickly reading in data. - @param {number} length Number of elements to map. - @param {?boolean} e Endianness of the data to read. - @return {Object} Uint8Array to the DataStream backing buffer. - */ -DataStream.prototype.mapUint8Array = function(length) { - this._realloc(length * 1); - var arr = new Uint8Array(this._buffer, this.byteOffset+this.position, length); - this.position += length * 1; - return arr; -}; -/** - Maps a Float64Array into the DataStream buffer, swizzling it to native - endianness in-place. The current offset from the start of the buffer needs to - be a multiple of element size, just like with typed array views. - Nice for quickly reading in data. Warning: potentially modifies the buffer - contents. - @param {number} length Number of elements to map. - @param {?boolean} e Endianness of the data to read. - @return {Object} Float64Array to the DataStream backing buffer. - */ -DataStream.prototype.mapFloat64Array = function(length, e) { - this._realloc(length * 8); - var arr = new Float64Array(this._buffer, this.byteOffset+this.position, length); - DataStream.arrayToNative(arr, e == null ? this.endianness : e); - this.position += length * 8; - return arr; -}; -/** - Maps a Float32Array into the DataStream buffer, swizzling it to native - endianness in-place. The current offset from the start of the buffer needs to - be a multiple of element size, just like with typed array views. - Nice for quickly reading in data. Warning: potentially modifies the buffer - contents. - - @param {number} length Number of elements to map. - @param {?boolean} e Endianness of the data to read. - @return {Object} Float32Array to the DataStream backing buffer. - */ -DataStream.prototype.mapFloat32Array = function(length, e) { - this._realloc(length * 4); - var arr = new Float32Array(this._buffer, this.byteOffset+this.position, length); - DataStream.arrayToNative(arr, e == null ? this.endianness : e); - this.position += length * 4; - return arr; -}; +'use strict'; /** - Reads an Int32Array of desired length and endianness from the DataStream. - - @param {number} length Number of elements to map. - @param {?boolean} e Endianness of the data to read. - @return {Object} The read Int32Array. + * Bouonding box which has vertexs represented as lon,lat,alt. + * @class GeographicExtent */ -DataStream.prototype.readInt32Array = function(length, e) { - length = length == null ? (this.byteLength-this.position / 4) : length; - var arr = new Int32Array(length); - DataStream.memcpy(arr.buffer, 0, - this.buffer, this.byteOffset+this.position, - length*arr.BYTES_PER_ELEMENT); - DataStream.arrayToNative(arr, e == null ? this.endianness : e); - this.position += arr.byteLength; - return arr; +var GeographicExtent = function() +{ + if (!(this instanceof GeographicExtent)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + + this.minGeographicCoord; + this.maxGeographicCoord; }; /** - Reads an Int16Array of desired length and endianness from the DataStream. - - @param {number} length Number of elements to map. - @param {?boolean} e Endianness of the data to read. - @return {Object} The read Int16Array. + * Clear the value of this instance */ -DataStream.prototype.readInt16Array = function(length, e) { - length = length == null ? (this.byteLength-this.position / 2) : length; - var arr = new Int16Array(length); - DataStream.memcpy(arr.buffer, 0, - this.buffer, this.byteOffset+this.position, - length*arr.BYTES_PER_ELEMENT); - DataStream.arrayToNative(arr, e == null ? this.endianness : e); - this.position += arr.byteLength; - return arr; +GeographicExtent.prototype.deleteObjects = function() +{ + if (this.minGeographicCoord !== undefined) + { + this.minGeographicCoord.deleteObjects(); + this.minGeographicCoord = undefined; + } + + if (this.maxGeographicCoord !== undefined) + { + this.maxGeographicCoord.deleteObjects(); + this.maxGeographicCoord = undefined; + } }; /** - Reads an Int8Array of desired length from the DataStream. - - @param {number} length Number of elements to map. - @param {?boolean} e Endianness of the data to read. - @return {Object} The read Int8Array. + * set the value of this instance + * @param minLon the value of lon of the lower bound + * @param minLat the value of lat of the lower bound + * @param minAlt the value of alt of the lower bound + * @param maxLon the value of lon of the lower bound + * @param maxLat the value of lat of the lower bound + * @param maxAlt the value of alt of the lower bound */ -DataStream.prototype.readInt8Array = function(length) { - length = length == null ? (this.byteLength-this.position) : length; - var arr = new Int8Array(length); - DataStream.memcpy(arr.buffer, 0, - this.buffer, this.byteOffset+this.position, - length*arr.BYTES_PER_ELEMENT); - this.position += arr.byteLength; - return arr; +GeographicExtent.prototype.setExtent = function(minLon, minLat, minAlt, maxLon, maxLat, maxAlt) +{ + if (this.minGeographicCoord === undefined) + { this.minGeographicCoord = new GeographicCoord(); } + + this.minGeographicCoord.setLonLatAlt(minLon, minLat, minAlt); + + if (this.maxGeographicCoord === undefined) + { this.maxGeographicCoord = new GeographicCoord(); } + + this.maxGeographicCoord.setLonLatAlt(maxLon, maxLat, maxAlt); }; /** - Reads a Uint32Array of desired length and endianness from the DataStream. - - @param {number} length Number of elements to map. - @param {?boolean} e Endianness of the data to read. - @return {Object} The read Uint32Array. + * Get the middle point of the lower bound point and uppper bound point + * @param resultGeographicCoord the point which will save the result + * @returns {GeographicCoord} */ -DataStream.prototype.readUint32Array = function(length, e) { - length = length == null ? (this.byteLength-this.position / 4) : length; - var arr = new Uint32Array(length); - DataStream.memcpy(arr.buffer, 0, - this.buffer, this.byteOffset+this.position, - length*arr.BYTES_PER_ELEMENT); - DataStream.arrayToNative(arr, e == null ? this.endianness : e); - this.position += arr.byteLength; - return arr; +GeographicExtent.prototype.getMidPoint = function(resultGeographicCoord) +{ + return GeographicCoord.getMidPoint(this.minGeographicCoord, this.maxGeographicCoord, resultGeographicCoord); }; -/** - Reads a Uint16Array of desired length and endianness from the DataStream. - @param {number} length Number of elements to map. - @param {?boolean} e Endianness of the data to read. - @return {Object} The read Uint16Array. - */ -DataStream.prototype.readUint16Array = function(length, e) { - length = length == null ? (this.byteLength-this.position / 2) : length; - var arr = new Uint16Array(length); - DataStream.memcpy(arr.buffer, 0, - this.buffer, this.byteOffset+this.position, - length*arr.BYTES_PER_ELEMENT); - DataStream.arrayToNative(arr, e == null ? this.endianness : e); - this.position += arr.byteLength; - return arr; -}; -/** - Reads a Uint8Array of desired length from the DataStream. - @param {number} length Number of elements to map. - @param {?boolean} e Endianness of the data to read. - @return {Object} The read Uint8Array. - */ -DataStream.prototype.readUint8Array = function(length) { - length = length == null ? (this.byteLength-this.position) : length; - var arr = new Uint8Array(length); - DataStream.memcpy(arr.buffer, 0, - this.buffer, this.byteOffset+this.position, - length*arr.BYTES_PER_ELEMENT); - this.position += arr.byteLength; - return arr; -}; -/** - Reads a Float64Array of desired length and endianness from the DataStream. - @param {number} length Number of elements to map. - @param {?boolean} e Endianness of the data to read. - @return {Object} The read Float64Array. - */ -DataStream.prototype.readFloat64Array = function(length, e) { - length = length == null ? (this.byteLength-this.position / 8) : length; - var arr = new Float64Array(length); - DataStream.memcpy(arr.buffer, 0, - this.buffer, this.byteOffset+this.position, - length*arr.BYTES_PER_ELEMENT); - DataStream.arrayToNative(arr, e == null ? this.endianness : e); - this.position += arr.byteLength; - return arr; -}; -/** - Reads a Float32Array of desired length and endianness from the DataStream. - @param {number} length Number of elements to map. - @param {?boolean} e Endianness of the data to read. - @return {Object} The read Float32Array. - */ -DataStream.prototype.readFloat32Array = function(length, e) { - length = length == null ? (this.byteLength-this.position / 4) : length; - var arr = new Float32Array(length); - DataStream.memcpy(arr.buffer, 0, - this.buffer, this.byteOffset+this.position, - length*arr.BYTES_PER_ELEMENT); - DataStream.arrayToNative(arr, e == null ? this.endianness : e); - this.position += arr.byteLength; - return arr; -}; -/** - Writes an Int32Array of specified endianness to the DataStream. - @param {Object} arr The array to write. - @param {?boolean} e Endianness of the data to write. - */ -DataStream.prototype.writeInt32Array = function(arr, e) { - this._realloc(arr.length * 4); - if (arr instanceof Int32Array && - (this.byteOffset+this.position) % arr.BYTES_PER_ELEMENT == 0) { - DataStream.memcpy(this._buffer, this.byteOffset+this.position, - arr.buffer, arr.byteOffset, - arr.byteLength); - this.mapInt32Array(arr.length, e); - } else { - for (var i=0; i 0; +GeoLocationData.prototype.copyFrom = function(geoLocData) +{ + if (geoLocData === undefined) + { return; } + + this.name = geoLocData.name; + if (geoLocData.geographicCoord) + { + if (this.geographicCoord === undefined) + { this.geographicCoord = new GeographicCoord(); } + + this.geographicCoord.copyFrom(geoLocData.geographicCoord); // longitude, latitude, altitude. + } + + this.heading = geoLocData.heading; + this.pitch = geoLocData.pitch; + this.roll = geoLocData.roll; + + this.date = geoLocData.date; // year - month - day - hour - min - seg - miliseg. + + if (geoLocData.position) + { + if (this.position === undefined) + { this.position = new Point3D(); } + this.position.copyFrom(geoLocData.position); + } + if (geoLocData.positionHIGH) + { + if (this.positionHIGH === undefined) + { this.positionHIGH = new Float32Array(3); } + + this.positionHIGH[0]= geoLocData.positionHIGH[0]; + this.positionHIGH[1]= geoLocData.positionHIGH[1]; + this.positionHIGH[2]= geoLocData.positionHIGH[2]; + } + if (geoLocData.positionLOW) + { + if (this.positionLOW === undefined) + { this.positionLOW = new Float32Array(3); } + + this.positionLOW[0]= geoLocData.positionLOW[0]; + this.positionLOW[1]= geoLocData.positionLOW[1]; + this.positionLOW[2]= geoLocData.positionLOW[2]; + } + if (geoLocData.pivotPoint) + { + if (this.pivotPoint === undefined) + { this.pivotPoint = new Point3D(); } + + this.pivotPoint.copyFrom(geoLocData.pivotPoint); + } + + // F4D Matrix4.* + if (geoLocData.geoLocMatrix) + { + if (this.geoLocMatrix === undefined) + { this.geoLocMatrix = new Matrix4(); } + + this.geoLocMatrix.copyFromMatrix4(geoLocData.geoLocMatrix); + } + if (geoLocData.geoLocMatrixInv) + { + if (this.geoLocMatrixInv === undefined) + { this.geoLocMatrixInv = new Matrix4(); } + + this.geoLocMatrixInv.copyFromMatrix4(geoLocData.geoLocMatrixInv); + } + if (geoLocData.tMatrix) + { + if (this.tMatrix === undefined) + { this.tMatrix = new Matrix4(); } + + this.tMatrix.copyFromMatrix4(geoLocData.tMatrix); + } + if (geoLocData.tMatrixInv) + { + if (this.tMatrixInv === undefined) + { this.tMatrixInv = new Matrix4(); } + + this.tMatrixInv.copyFromMatrix4(geoLocData.tMatrixInv); + } + if (geoLocData.rotMatrix) + { + if (this.rotMatrix === undefined) + { this.rotMatrix = new Matrix4(); } + + this.rotMatrix.copyFromMatrix4(geoLocData.rotMatrix); + } + if (geoLocData.rotMatrixInv) + { + if (this.rotMatrixInv === undefined) + { this.rotMatrixInv = new Matrix4(); } + + this.rotMatrixInv.copyFromMatrix4(geoLocData.rotMatrixInv); + } + + if (geoLocData.aditionalTraslation) + { + if (this.aditionalTraslation === undefined) + { this.aditionalTraslation = new Point3D(); } + + this.aditionalTraslation.copyFrom(geoLocData.aditionalTraslation); + } + +}; /** - Copies byteLength bytes from the src buffer at srcOffset to the - dst buffer at dstOffset. - - @param {Object} dst Destination ArrayBuffer to write to. - @param {number} dstOffset Offset to the destination ArrayBuffer. - @param {Object} src Source ArrayBuffer to read from. - @param {number} srcOffset Offset to the source ArrayBuffer. - @param {number} byteLength Number of bytes to copy. + * This function transforms a local position of this geoLocation to world position. + * @param localCoord instance of Point3D. + * @param resultWorldCoord. instance of Point3D. + * @returns resultWorldCoord. instance of Point3D. */ -DataStream.memcpy = function(dst, dstOffset, src, srcOffset, byteLength) { - var dstU8 = new Uint8Array(dst, dstOffset, byteLength); - var srcU8 = new Uint8Array(src, srcOffset, byteLength); - dstU8.set(srcU8); +GeoLocationData.prototype.localCoordToWorldCoord = function(localCoord, resultWorldCoord) +{ + if (localCoord === undefined || this.tMatrix === undefined) + { return undefined; } + + if (resultWorldCoord === undefined) + { resultWorldCoord = new Point3D(); } + + resultWorldCoord = this.tMatrix.transformPoint3D(localCoord, resultWorldCoord); + return resultWorldCoord; }; /** - Converts array to native endianness in-place. - - @param {Object} array Typed array to convert. - @param {boolean} arrayIsLittleEndian True if the data in the array is - little-endian. Set false for big-endian. - @return {Object} The converted typed array. + * This function transforms an absolute position to local position for this geoLocation. + * @param worldCoord instance of Point3D. + * @param resultLocalCoord. instance of Point3D. + * @returns resultLocalCoord. instance of Point3D. */ -DataStream.arrayToNative = function(array, arrayIsLittleEndian) { - if (arrayIsLittleEndian == this.endianness) { - return array; - } else { - return this.flipArrayEndianness(array); - } +GeoLocationData.prototype.worldCoordToLocalCoord = function(worldCoord, resultLocalCoord) +{ + var tMatrixInv = this.getTMatrixInv(); + if (worldCoord === undefined || tMatrixInv === undefined) + { return undefined; } + + if (resultLocalCoord === undefined) + { resultLocalCoord = new Point3D(); } + + resultLocalCoord = tMatrixInv.transformPoint3D(worldCoord, resultLocalCoord); + return resultLocalCoord; }; /** - Converts native endianness array to desired endianness in-place. - - @param {Object} array Typed array to convert. - @param {boolean} littleEndian True if the converted array should be - little-endian. Set false for big-endian. - @return {Object} The converted typed array. + * + * @returns this.locMatrixInv. */ -DataStream.nativeToEndian = function(array, littleEndian) { - if (this.endianness == littleEndian) { - return array; - } else { - return this.flipArrayEndianness(array); - } +GeoLocationData.prototype.getLocMatrixInv = function() +{ + if (this.geoLocMatrixInv === undefined) + { + var locMatrixInv = glMatrix.mat4.create(); + locMatrixInv = glMatrix.mat4.invert(locMatrixInv, this.geoLocMatrix._floatArrays ); + + this.geoLocMatrixInv = new Matrix4(); + this.geoLocMatrixInv.setByFloat32Array(locMatrixInv); + } + + return this.geoLocMatrixInv; }; /** - Flips typed array endianness in-place. - - @param {Object} array Typed array to flip. - @return {Object} The converted typed array. + * + * @returns this.rotMatrixInv. */ -DataStream.flipArrayEndianness = function(array) { - var u8 = new Uint8Array(array.buffer, array.byteOffset, array.byteLength); - for (var i=0; ik; j--, k++) { - var tmp = u8[k]; - u8[k] = u8[j]; - u8[j] = tmp; - } - } - return array; +GeoLocationData.prototype.getRotMatrixInv = function() +{ + if (this.rotMatrixInv === undefined) + { + var rotMatrixInv = glMatrix.mat4.create(); + rotMatrixInv = glMatrix.mat4.invert(rotMatrixInv, this.rotMatrix._floatArrays ); + + this.rotMatrixInv = new Matrix4(); + this.rotMatrixInv.setByFloat32Array(rotMatrixInv); + } + + return this.rotMatrixInv; }; /** - Creates an array from an array of character codes. - Uses String.fromCharCode in chunks for memory efficiency and then concatenates - the resulting string chunks. - - @param {array} array Array of character codes. - @return {string} String created from the character codes. -**/ -DataStream.createStringFromArray = function(array) { - var chunk_size = 0x8000; - var chunks = []; - for (var i=0; i < array.length; i += chunk_size) { - chunks.push(String.fromCharCode.apply(null, array.subarray(i, i + chunk_size))); - } - return chunks.join(""); + * + * @returns this.tMatrixInv. + */ +GeoLocationData.prototype.getTMatrixInv = function() +{ + if (this.tMatrixInv === undefined) + { + var tMatrixInv = glMatrix.mat4.create(); + tMatrixInv = glMatrix.mat4.invert(tMatrixInv, this.tMatrix._floatArrays); + + this.tMatrixInv = new Matrix4(); + this.tMatrixInv.setByFloat32Array(tMatrixInv); + } + + return this.tMatrixInv; }; /** - Seek position where DataStream#readStruct ran into a problem. - Useful for debugging struct parsing. - - @type {number} + * + * @returns this.geoLocMatrixInv. */ -DataStream.prototype.failurePosition = 0; +GeoLocationData.prototype.getGeoLocationMatrixInv = function() +{ + if (this.geoLocMatrixInv === undefined) + { + var geoLocMatrixInv = glMatrix.mat4.create(); + geoLocMatrixInv = glMatrix.mat4.invert(geoLocMatrixInv, this.geoLocMatrix._floatArrays ); + + this.geoLocMatrixInv = new Matrix4(); + this.geoLocMatrixInv.setByFloat32Array(geoLocMatrixInv); + } + + return this.geoLocMatrixInv; +}; /** - Reads a struct of data from the DataStream. The struct is defined as - a flat array of [name, type]-pairs. See the example below: - - ds.readStruct([ - 'headerTag', 'uint32', // Uint32 in DataStream endianness. - 'headerTag2', 'uint32be', // Big-endian Uint32. - 'headerTag3', 'uint32le', // Little-endian Uint32. - 'array', ['[]', 'uint32', 16], // Uint32Array of length 16. - 'array2Length', 'uint32', - 'array2', ['[]', 'uint32', 'array2Length'] // Uint32Array of length array2Length - ]); - - The possible values for the type are as follows: - - // Number types - - // Unsuffixed number types use DataStream endianness. - // To explicitly specify endianness, suffix the type with - // 'le' for little-endian or 'be' for big-endian, - // e.g. 'int32be' for big-endian int32. - - 'uint8' -- 8-bit unsigned int - 'uint16' -- 16-bit unsigned int - 'uint32' -- 32-bit unsigned int - 'int8' -- 8-bit int - 'int16' -- 16-bit int - 'int32' -- 32-bit int - 'float32' -- 32-bit float - 'float64' -- 64-bit float - - // String types - 'cstring' -- ASCII string terminated by a zero byte. - 'string:N' -- ASCII string of length N, where N is a literal integer. - 'string:variableName' -- ASCII string of length $variableName, - where 'variableName' is a previously parsed number in the current struct. - 'string,CHARSET:N' -- String of byteLength N encoded with given CHARSET. - 'u16string:N' -- UCS-2 string of length N in DataStream endianness. - 'u16stringle:N' -- UCS-2 string of length N in little-endian. - 'u16stringbe:N' -- UCS-2 string of length N in big-endian. - - // Complex types - [name, type, name_2, type_2, ..., name_N, type_N] -- Struct - function(dataStream, struct) {} -- Callback function to read and return data. - {get: function(dataStream, struct) {}, - set: function(dataStream, struct) {}} - -- Getter/setter functions to read and return data, handy for using the same - struct definition for reading and writing structs. - ['[]', type, length] -- Array of given type and length. The length can be either - a number, a string that references a previously-read - field, or a callback function(struct, dataStream, type){}. - If length is '*', reads in as many elements as it can. - - @param {Object} structDefinition Struct definition object. - @return {Object} The read struct. Null if failed to read struct. + * This function transforms an absolute camera (world coord) into a relative camera (local coord) for this geoLocation. + * @param absoluteCamera instance of Camera. + * @param resultCamera instance of Camera. This is the transformed camera. + * @returns resultCamera */ -DataStream.prototype.readStruct = function(structDefinition) { - var struct = {}, t, v, n; - var p = this.position; - for (var i=0; i this.geoLocationDataArrayMaxLengthAllowed) + { + this.geoLocationDataArray.pop(); + // delete extracted geoLocdata. TODO: + } - @param {Object} structDefinition Type definition of the struct. - @param {Object} struct The struct data object. - */ -DataStream.prototype.writeStruct = function(structDefinition, struct) { - for (var i = 0; i < structDefinition.length; i+=2) { - var t = structDefinition[i+1]; - this.writeType(t, struct[structDefinition[i]], struct); - } + return geoLocationData; }; /** - Writes object v of type t to the DataStream. - - @param {Object} t Type of data to write. - @param {Object} v Value of data to write. - @param {Object} struct Struct to pass to write callback functions. - */ -DataStream.prototype.writeType = function(t, v, struct) { - if (typeof t == "function") { - return t(this, v); - } else if (typeof t == "object" && !(t instanceof Array)) { - return t.set(this, v, struct); - } - var lengthOverride = null; - var charset = "ASCII"; - var pos = this.position; - if (typeof(t) == 'string' && /:/.test(t)) { - var tp = t.split(":"); - t = tp[0]; - lengthOverride = parseInt(tp[1]); - } - if (typeof t == 'string' && /,/.test(t)) { - var tp = t.split(","); - t = tp[0]; - charset = parseInt(tp[1]); - } - - switch(t) { - case 'uint8': - this.writeUint8(v); - break; - case 'int8': - this.writeInt8(v); - break; - - case 'uint16': - this.writeUint16(v, this.endianness); - break; - case 'int16': - this.writeInt16(v, this.endianness); - break; - case 'uint32': - this.writeUint32(v, this.endianness); - break; - case 'int32': - this.writeInt32(v, this.endianness); - break; - case 'float32': - this.writeFloat32(v, this.endianness); - break; - case 'float64': - this.writeFloat64(v, this.endianness); - break; - - case 'uint16be': - this.writeUint16(v, DataStream.BIG_ENDIAN); - break; - case 'int16be': - this.writeInt16(v, DataStream.BIG_ENDIAN); - break; - case 'uint32be': - this.writeUint32(v, DataStream.BIG_ENDIAN); - break; - case 'int32be': - this.writeInt32(v, DataStream.BIG_ENDIAN); - break; - case 'float32be': - this.writeFloat32(v, DataStream.BIG_ENDIAN); - break; - case 'float64be': - this.writeFloat64(v, DataStream.BIG_ENDIAN); - break; - - case 'uint16le': - this.writeUint16(v, DataStream.LITTLE_ENDIAN); - break; - case 'int16le': - this.writeInt16(v, DataStream.LITTLE_ENDIAN); - break; - case 'uint32le': - this.writeUint32(v, DataStream.LITTLE_ENDIAN); - break; - case 'int32le': - this.writeInt32(v, DataStream.LITTLE_ENDIAN); - break; - case 'float32le': - this.writeFloat32(v, DataStream.LITTLE_ENDIAN); - break; - case 'float64le': - this.writeFloat64(v, DataStream.LITTLE_ENDIAN); - break; - - case 'cstring': - this.writeCString(v, lengthOverride); - break; - - case 'string': - this.writeString(v, charset, lengthOverride); - break; - - case 'u16string': - this.writeUCS2String(v, this.endianness, lengthOverride); - break; - - case 'u16stringle': - this.writeUCS2String(v, DataStream.LITTLE_ENDIAN, lengthOverride); - break; - - case 'u16stringbe': - this.writeUCS2String(v, DataStream.BIG_ENDIAN, lengthOverride); - break; - - default: - if (t.length == 3) { - var ta = t[1]; - for (var i=0; i this.geoLocationDataArray.length - 1) + { return undefined; } + return this.geoLocationDataArray[idx]; +}; -/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ - -(function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define([], factory); - else { - var a = factory(); - for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; - } -})(this, function() { -return /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 4); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.setMatrixArrayType = setMatrixArrayType; -exports.toRadian = toRadian; -exports.equals = equals; -/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +/** + * provisionally return the first data of GeoLocationDataArray + * @class GeoLocationData + * @param {Number}idx + * @returns {GeoLocationData}this.geoLoactionDataArray[idx] + */ +GeoLocationDataManager.prototype.getCurrentGeoLocationData = function() +{ + if (this.geoLocationDataArray.length === 0) + { + return undefined; + } + return this.geoLocationDataArray[0]; // provisionally return the 1rst. +}; -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +'use strict'; -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ /** - * Common utilities - * @module glMatrix + * GeoLocationDataManager is a class object that contains GeoLocationData objects in an array. + * + * @class GeoLocationDataManager + * @constructor */ - -// Configuration Constants -var EPSILON = exports.EPSILON = 0.000001; -var ARRAY_TYPE = exports.ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array; -var RANDOM = exports.RANDOM = Math.random; +var GeoLocationDataManager = function() +{ + if (!(this instanceof GeoLocationDataManager)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + + this.geoLocationDataArray = []; + this.geoLocationDataArrayMaxLengthAllowed = 15; +}; /** - * Sets the type of array used when creating new vectors and matrices - * - * @param {Type} type Array type, such as Float32Array or Array + * Clear all object of GeoLocationDataManager */ -function setMatrixArrayType(type) { - exports.ARRAY_TYPE = ARRAY_TYPE = type; -} - -var degree = Math.PI / 180; +GeoLocationDataManager.prototype.deleteObjects = function() +{ + if (this.geoLocationDataArray) + { + for (var i=0; i this.geoLocationDataArrayMaxLengthAllowed) + { + this.geoLocationDataArray.pop(); + // delete extracted geoLocdata. TODO: + } -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.sub = exports.mul = undefined; -exports.create = create; -exports.fromMat4 = fromMat4; -exports.clone = clone; -exports.copy = copy; -exports.fromValues = fromValues; -exports.set = set; -exports.identity = identity; -exports.transpose = transpose; -exports.invert = invert; -exports.adjoint = adjoint; -exports.determinant = determinant; -exports.multiply = multiply; -exports.translate = translate; -exports.rotate = rotate; -exports.scale = scale; -exports.fromTranslation = fromTranslation; -exports.fromRotation = fromRotation; -exports.fromScaling = fromScaling; -exports.fromMat2d = fromMat2d; -exports.fromQuat = fromQuat; -exports.normalFromMat4 = normalFromMat4; -exports.projection = projection; -exports.str = str; -exports.frob = frob; -exports.add = add; -exports.subtract = subtract; -exports.multiplyScalar = multiplyScalar; -exports.multiplyScalarAndAdd = multiplyScalarAndAdd; -exports.exactEquals = exactEquals; -exports.equals = equals; - -var _common = __webpack_require__(0); - -var glMatrix = _interopRequireWildcard(_common); - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } - -/** - * 3x3 Matrix - * @module mat3 - */ - -/** - * Creates a new identity mat3 - * - * @returns {mat3} a new 3x3 matrix - */ -function create() { - var out = new glMatrix.ARRAY_TYPE(9); - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 0; - out[4] = 1; - out[5] = 0; - out[6] = 0; - out[7] = 0; - out[8] = 1; - return out; -} + return geoLocationData; +}; /** - * Copies the upper-left 3x3 values into the given mat3. - * - * @param {mat3} out the receiving 3x3 matrix - * @param {mat4} a the source 4x4 matrix - * @returns {mat3} out + * return the length of this geoLocationDataArray + * @returns {Number} the length of this geoLocationDataArray */ -/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. +GeoLocationDataManager.prototype.getGeoLocationDatasCount = function() +{ + return this.geoLocationDataArray.length; +}; -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ - -function fromMat4(out, a) { - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - out[3] = a[4]; - out[4] = a[5]; - out[5] = a[6]; - out[6] = a[8]; - out[7] = a[9]; - out[8] = a[10]; - return out; -} - -/** - * Creates a new mat3 initialized with values from an existing matrix - * - * @param {mat3} a matrix to clone - * @returns {mat3} a new 3x3 matrix - */ -function clone(a) { - var out = new glMatrix.ARRAY_TYPE(9); - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - out[3] = a[3]; - out[4] = a[4]; - out[5] = a[5]; - out[6] = a[6]; - out[7] = a[7]; - out[8] = a[8]; - return out; -} - -/** - * Copy the values from one mat3 to another - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the source matrix - * @returns {mat3} out - */ -function copy(out, a) { - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - out[3] = a[3]; - out[4] = a[4]; - out[5] = a[5]; - out[6] = a[6]; - out[7] = a[7]; - out[8] = a[8]; - return out; -} - -/** - * Create a new mat3 with the given values - * - * @param {Number} m00 Component in column 0, row 0 position (index 0) - * @param {Number} m01 Component in column 0, row 1 position (index 1) - * @param {Number} m02 Component in column 0, row 2 position (index 2) - * @param {Number} m10 Component in column 1, row 0 position (index 3) - * @param {Number} m11 Component in column 1, row 1 position (index 4) - * @param {Number} m12 Component in column 1, row 2 position (index 5) - * @param {Number} m20 Component in column 2, row 0 position (index 6) - * @param {Number} m21 Component in column 2, row 1 position (index 7) - * @param {Number} m22 Component in column 2, row 2 position (index 8) - * @returns {mat3} A new mat3 - */ -function fromValues(m00, m01, m02, m10, m11, m12, m20, m21, m22) { - var out = new glMatrix.ARRAY_TYPE(9); - out[0] = m00; - out[1] = m01; - out[2] = m02; - out[3] = m10; - out[4] = m11; - out[5] = m12; - out[6] = m20; - out[7] = m21; - out[8] = m22; - return out; -} - -/** - * Set the components of a mat3 to the given values - * - * @param {mat3} out the receiving matrix - * @param {Number} m00 Component in column 0, row 0 position (index 0) - * @param {Number} m01 Component in column 0, row 1 position (index 1) - * @param {Number} m02 Component in column 0, row 2 position (index 2) - * @param {Number} m10 Component in column 1, row 0 position (index 3) - * @param {Number} m11 Component in column 1, row 1 position (index 4) - * @param {Number} m12 Component in column 1, row 2 position (index 5) - * @param {Number} m20 Component in column 2, row 0 position (index 6) - * @param {Number} m21 Component in column 2, row 1 position (index 7) - * @param {Number} m22 Component in column 2, row 2 position (index 8) - * @returns {mat3} out - */ -function set(out, m00, m01, m02, m10, m11, m12, m20, m21, m22) { - out[0] = m00; - out[1] = m01; - out[2] = m02; - out[3] = m10; - out[4] = m11; - out[5] = m12; - out[6] = m20; - out[7] = m21; - out[8] = m22; - return out; -} - -/** - * Set a mat3 to the identity matrix - * - * @param {mat3} out the receiving matrix - * @returns {mat3} out - */ -function identity(out) { - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 0; - out[4] = 1; - out[5] = 0; - out[6] = 0; - out[7] = 0; - out[8] = 1; - return out; -} - -/** - * Transpose the values of a mat3 - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the source matrix - * @returns {mat3} out - */ -function transpose(out, a) { - // If we are transposing ourselves we can skip a few steps but have to cache some values - if (out === a) { - var a01 = a[1], - a02 = a[2], - a12 = a[5]; - out[1] = a[3]; - out[2] = a[6]; - out[3] = a01; - out[5] = a[7]; - out[6] = a02; - out[7] = a12; - } else { - out[0] = a[0]; - out[1] = a[3]; - out[2] = a[6]; - out[3] = a[1]; - out[4] = a[4]; - out[5] = a[7]; - out[6] = a[2]; - out[7] = a[5]; - out[8] = a[8]; - } - - return out; -} +/** + * 어떤 일을 하고 있습니까? + * @class GeoLocationData + * @param {Number} idx + * @returns this.geoLoactionDataArray[idx] + */ +GeoLocationDataManager.prototype.getGeoLocationData = function(idx) +{ + if (idx > this.geoLocationDataArray.length - 1) + { return undefined; } + return this.geoLocationDataArray[idx]; +}; /** - * Inverts a mat3 - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the source matrix - * @returns {mat3} out + * provisionally return the first data of GeoLocationDataArray + * @class GeoLocationData + * @param {Number}idx + * @returns {GeoLocationData}this.geoLoactionDataArray[idx] */ -function invert(out, a) { - var a00 = a[0], - a01 = a[1], - a02 = a[2]; - var a10 = a[3], - a11 = a[4], - a12 = a[5]; - var a20 = a[6], - a21 = a[7], - a22 = a[8]; - - var b01 = a22 * a11 - a12 * a21; - var b11 = -a22 * a10 + a12 * a20; - var b21 = a21 * a10 - a11 * a20; - - // Calculate the determinant - var det = a00 * b01 + a01 * b11 + a02 * b21; - - if (!det) { - return null; - } - det = 1.0 / det; - - out[0] = b01 * det; - out[1] = (-a22 * a01 + a02 * a21) * det; - out[2] = (a12 * a01 - a02 * a11) * det; - out[3] = b11 * det; - out[4] = (a22 * a00 - a02 * a20) * det; - out[5] = (-a12 * a00 + a02 * a10) * det; - out[6] = b21 * det; - out[7] = (-a21 * a00 + a01 * a20) * det; - out[8] = (a11 * a00 - a01 * a10) * det; - return out; -} +GeoLocationDataManager.prototype.getCurrentGeoLocationData = function() +{ + if (this.geoLocationDataArray.length === 0) + { + return undefined; + } + return this.geoLocationDataArray[0]; // provisionally return the 1rst. +}; +'use strict'; /** - * Calculates the adjugate of a mat3 - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the source matrix - * @returns {mat3} out + * This class is used to assume the real globe of earth as ellipsoid + * @class Globe */ -function adjoint(out, a) { - var a00 = a[0], - a01 = a[1], - a02 = a[2]; - var a10 = a[3], - a11 = a[4], - a12 = a[5]; - var a20 = a[6], - a21 = a[7], - a22 = a[8]; - - out[0] = a11 * a22 - a12 * a21; - out[1] = a02 * a21 - a01 * a22; - out[2] = a01 * a12 - a02 * a11; - out[3] = a12 * a20 - a10 * a22; - out[4] = a00 * a22 - a02 * a20; - out[5] = a02 * a10 - a00 * a12; - out[6] = a10 * a21 - a11 * a20; - out[7] = a01 * a20 - a00 * a21; - out[8] = a00 * a11 - a01 * a10; - return out; -} +var Globe = function() +{ + if (!(this instanceof Globe)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + //WGS 84. + // Extracted from WikiPedia "Geodetic datum". + // WGS 84 Defining Parameters + // semi-major axis a 6378137.0 m + // Reciprocal of flattening 1/f 298.257223563 + + // WGS 84 derived geometric constants + // Semi-minor axis b = a(1 − f) 6356752.3142 m + // First eccentricity squared e2 = (1 − b2/a2 = 2f − f2) = 6.69437999014 x 10−3 + // Second eccentricity squared e′2 = (a2/b2 − 1 = f(2 − f)/(1 − f)2) = 6.73949674228 x 10−3 + //---------------------------------------------------------- + + this.equatorialRadius = 6378137.0; // meters. + this.polarRadius = 6356752.3142; // meters. + this.firstEccentricitySquared = 6.69437999014E-3; + this.secondEccentricitySquared = 6.73949674228E-3; + this.degToRadFactor = Math.PI/180.0; +}; /** - * Calculates the determinant of a mat3 - * - * @param {mat3} a the source matrix - * @returns {Number} determinant of a + * @returns {Number} equatorial Radius */ -function determinant(a) { - var a00 = a[0], - a01 = a[1], - a02 = a[2]; - var a10 = a[3], - a11 = a[4], - a12 = a[5]; - var a20 = a[6], - a21 = a[7], - a22 = a[8]; - - return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20); -} - -/** - * Multiplies two mat3's - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the first operand - * @param {mat3} b the second operand - * @returns {mat3} out - */ -function multiply(out, a, b) { - var a00 = a[0], - a01 = a[1], - a02 = a[2]; - var a10 = a[3], - a11 = a[4], - a12 = a[5]; - var a20 = a[6], - a21 = a[7], - a22 = a[8]; - - var b00 = b[0], - b01 = b[1], - b02 = b[2]; - var b10 = b[3], - b11 = b[4], - b12 = b[5]; - var b20 = b[6], - b21 = b[7], - b22 = b[8]; - - out[0] = b00 * a00 + b01 * a10 + b02 * a20; - out[1] = b00 * a01 + b01 * a11 + b02 * a21; - out[2] = b00 * a02 + b01 * a12 + b02 * a22; - - out[3] = b10 * a00 + b11 * a10 + b12 * a20; - out[4] = b10 * a01 + b11 * a11 + b12 * a21; - out[5] = b10 * a02 + b11 * a12 + b12 * a22; - - out[6] = b20 * a00 + b21 * a10 + b22 * a20; - out[7] = b20 * a01 + b21 * a11 + b22 * a21; - out[8] = b20 * a02 + b21 * a12 + b22 * a22; - return out; -} - -/** - * Translate a mat3 by the given vector - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the matrix to translate - * @param {vec2} v vector to translate by - * @returns {mat3} out - */ -function translate(out, a, v) { - var a00 = a[0], - a01 = a[1], - a02 = a[2], - a10 = a[3], - a11 = a[4], - a12 = a[5], - a20 = a[6], - a21 = a[7], - a22 = a[8], - x = v[0], - y = v[1]; - - out[0] = a00; - out[1] = a01; - out[2] = a02; - - out[3] = a10; - out[4] = a11; - out[5] = a12; - - out[6] = x * a00 + y * a10 + a20; - out[7] = x * a01 + y * a11 + a21; - out[8] = x * a02 + y * a12 + a22; - return out; -} - -/** - * Rotates a mat3 by the given angle - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat3} out - */ -function rotate(out, a, rad) { - var a00 = a[0], - a01 = a[1], - a02 = a[2], - a10 = a[3], - a11 = a[4], - a12 = a[5], - a20 = a[6], - a21 = a[7], - a22 = a[8], - s = Math.sin(rad), - c = Math.cos(rad); - - out[0] = c * a00 + s * a10; - out[1] = c * a01 + s * a11; - out[2] = c * a02 + s * a12; - - out[3] = c * a10 - s * a00; - out[4] = c * a11 - s * a01; - out[5] = c * a12 - s * a02; - - out[6] = a20; - out[7] = a21; - out[8] = a22; - return out; -}; - -/** - * Scales the mat3 by the dimensions in the given vec2 - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the matrix to rotate - * @param {vec2} v the vec2 to scale the matrix by - * @returns {mat3} out - **/ -function scale(out, a, v) { - var x = v[0], - y = v[1]; - - out[0] = x * a[0]; - out[1] = x * a[1]; - out[2] = x * a[2]; - - out[3] = y * a[3]; - out[4] = y * a[4]; - out[5] = y * a[5]; - - out[6] = a[6]; - out[7] = a[7]; - out[8] = a[8]; - return out; -} - -/** - * Creates a matrix from a vector translation - * This is equivalent to (but much faster than): - * - * mat3.identity(dest); - * mat3.translate(dest, dest, vec); - * - * @param {mat3} out mat3 receiving operation result - * @param {vec2} v Translation vector - * @returns {mat3} out - */ -function fromTranslation(out, v) { - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 0; - out[4] = 1; - out[5] = 0; - out[6] = v[0]; - out[7] = v[1]; - out[8] = 1; - return out; -} +Globe.equatorialRadius = function() +{ + return 6378137.0; +}; /** - * Creates a matrix from a given angle - * This is equivalent to (but much faster than): - * - * mat3.identity(dest); - * mat3.rotate(dest, dest, rad); - * - * @param {mat3} out mat3 receiving operation result - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat3} out - */ -function fromRotation(out, rad) { - var s = Math.sin(rad), - c = Math.cos(rad); - - out[0] = c; - out[1] = s; - out[2] = 0; - - out[3] = -s; - out[4] = c; - out[5] = 0; - - out[6] = 0; - out[7] = 0; - out[8] = 1; - return out; -} + * @returns {Number} + */ +Globe.equatorialRadiusSquared = function() +{ + return 40680631590769.0; +}; /** - * Creates a matrix from a vector scaling - * This is equivalent to (but much faster than): - * - * mat3.identity(dest); - * mat3.scale(dest, dest, vec); - * - * @param {mat3} out mat3 receiving operation result - * @param {vec2} v Scaling vector - * @returns {mat3} out - */ -function fromScaling(out, v) { - out[0] = v[0]; - out[1] = 0; - out[2] = 0; - - out[3] = 0; - out[4] = v[1]; - out[5] = 0; - - out[6] = 0; - out[7] = 0; - out[8] = 1; - return out; -} + * @returns {Number} + */ +Globe.polarRadius = function() +{ + return 6356752.3142; +}; /** - * Copies the values from a mat2d into a mat3 - * - * @param {mat3} out the receiving matrix - * @param {mat2d} a the matrix to copy - * @returns {mat3} out - **/ -function fromMat2d(out, a) { - out[0] = a[0]; - out[1] = a[1]; - out[2] = 0; - - out[3] = a[2]; - out[4] = a[3]; - out[5] = 0; - - out[6] = a[4]; - out[7] = a[5]; - out[8] = 1; - return out; -} - + * @returns {Number} + */ +Globe.polarRadiusSquared = function() +{ + return 40408299984087.05552164; +}; /** -* Calculates a 3x3 matrix from the given quaternion -* -* @param {mat3} out mat3 receiving operation result -* @param {quat} q Quaternion to create matrix from -* -* @returns {mat3} out -*/ -function fromQuat(out, q) { - var x = q[0], - y = q[1], - z = q[2], - w = q[3]; - var x2 = x + x; - var y2 = y + y; - var z2 = z + z; - - var xx = x * x2; - var yx = y * x2; - var yy = y * y2; - var zx = z * x2; - var zy = z * y2; - var zz = z * z2; - var wx = w * x2; - var wy = w * y2; - var wz = w * z2; - - out[0] = 1 - yy - zz; - out[3] = yx - wz; - out[6] = zx + wy; - - out[1] = yx + wz; - out[4] = 1 - xx - zz; - out[7] = zy - wx; - - out[2] = zx - wy; - out[5] = zy + wx; - out[8] = 1 - xx - yy; - - return out; -} + * This function returns the radius of earth at the latitude "latDeg". + * @param latDeg the latitude + * @returns {Number} + */ +Globe.radiusAtLatitudeDeg = function(latDeg) +{ + // a = equatorialRadius, b = polarRadius. + // r = a*b / sqrt(a2*sin2(lat) + b2*cos2(lat)). + //------------------------------------------------------ + + var latRad = latDeg * Math.PI/180.0; + var a = Globe.equatorialRadius(); + var b = Globe.polarRadius(); + var a2 = Globe.equatorialRadiusSquared(); + var b2 = Globe.polarRadiusSquared(); + + var sin = Math.sin(latRad); + var cos = Math.cos(latRad); + var sin2 = sin*sin; + var cos2 = cos*cos; + + var radius = (a*b)/(Math.sqrt(a2*sin2 + b2*cos2)); + return radius; +}; /** -* Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix -* -* @param {mat3} out mat3 receiving operation result -* @param {mat4} a Mat4 to derive the normal matrix from -* -* @returns {mat3} out -*/ -function normalFromMat4(out, a) { - var a00 = a[0], - a01 = a[1], - a02 = a[2], - a03 = a[3]; - var a10 = a[4], - a11 = a[5], - a12 = a[6], - a13 = a[7]; - var a20 = a[8], - a21 = a[9], - a22 = a[10], - a23 = a[11]; - var a30 = a[12], - a31 = a[13], - a32 = a[14], - a33 = a[15]; - - var b00 = a00 * a11 - a01 * a10; - var b01 = a00 * a12 - a02 * a10; - var b02 = a00 * a13 - a03 * a10; - var b03 = a01 * a12 - a02 * a11; - var b04 = a01 * a13 - a03 * a11; - var b05 = a02 * a13 - a03 * a12; - var b06 = a20 * a31 - a21 * a30; - var b07 = a20 * a32 - a22 * a30; - var b08 = a20 * a33 - a23 * a30; - var b09 = a21 * a32 - a22 * a31; - var b10 = a21 * a33 - a23 * a31; - var b11 = a22 * a33 - a23 * a32; - - // Calculate the determinant - var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; - - if (!det) { - return null; - } - det = 1.0 / det; - - out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; - out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det; - out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det; - - out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det; - out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det; - out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det; - - out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det; - out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det; - out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det; - - return out; -} + * Normalize the elements of the 3D feature + * @param {Float32Array} cartesian this can be any feature such as a point or a axis to make unitary + * + */ +Globe.prototype.normalizeCartesian = function(cartesian) +{ + if (cartesian === undefined) + { return; } -/** - * Generates a 2D projection matrix with the given bounds - * - * @param {mat3} out mat3 frustum matrix will be written into - * @param {number} width Width of your gl context - * @param {number} height Height of gl context - * @returns {mat3} out - */ -function projection(out, width, height) { - out[0] = 2 / width; - out[1] = 0; - out[2] = 0; - out[3] = 0; - out[4] = -2 / height; - out[5] = 0; - out[6] = -1; - out[7] = 1; - out[8] = 1; - return out; -} + var modul = Math.sqrt(cartesian[0]*cartesian[0] + cartesian[1]*cartesian[1] + cartesian[2]*cartesian[2] ); + cartesian[0] /= modul; + cartesian[1] /= modul; + cartesian[2] /= modul; + + return cartesian; +}; /** - * Returns a string representation of a mat3 - * - * @param {mat3} a matrix to represent as a string - * @returns {String} string representation of the matrix + * Return the transformation matrix which transform the cartesian point to wgs84 + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @param {Float32Array} float32Array + * @returns {Float32Array} float32Array + * */ -function str(a) { - return 'mat3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' + a[8] + ')'; -} - +Globe.prototype.transformMatrixAtCartesianPointWgs84 = function(x, y, z, float32Array) +{ + var xAxis, yAxis, zAxis; + + zAxis = this.normalAtCartesianPointWgs84(x, y, z, zAxis); + + // Check if zAxis is vertical vector. PENDENT. + + // now, calculate the east direction. + // project zAxis to plane XY and calculate the left perpendicular. + xAxis = new Float32Array(3); + xAxis[0] = -y; + xAxis[1] = x; + xAxis[2] = 0.0; + xAxis = this.normalizeCartesian(xAxis); + + // finally calculate the north direction. + var xAxisVector = new Point3D(xAxis[0], xAxis[1], xAxis[2]); + var yAxisVector = new Point3D(); + var zAxisVector = new Point3D(zAxis[0], zAxis[1], zAxis[2]); + + yAxisVector = zAxisVector.crossProduct(xAxisVector, yAxisVector); + + if (float32Array === undefined) + { float32Array = new Float32Array(16); } + + float32Array[0] = xAxisVector.x; + float32Array[1] = xAxisVector.y; + float32Array[2] = xAxisVector.z; + float32Array[3] = 0.0; + + float32Array[4] = yAxisVector.x; + float32Array[5] = yAxisVector.y; + float32Array[6] = yAxisVector.z; + float32Array[7] = 0.0; + + float32Array[8] = zAxisVector.x; + float32Array[9] = zAxisVector.y; + float32Array[10] = zAxisVector.z; + float32Array[11] = 0.0; + + float32Array[12] = x; + float32Array[13] = y; + float32Array[14] = z; + float32Array[15] = 1.0; + + return float32Array; +}; /** - * Returns Frobenius norm of a mat3 - * - * @param {mat3} a the matrix to calculate Frobenius norm of - * @returns {Number} Frobenius norm + * function used by "MagoWorld" to paning & rotate the globe by dragging mouse. + * @param {Line} line + * @param {Float32Array} resultCartesian + * @param {Number} radius + * @returns {Float32Array} resultCartesian */ -function frob(a) { - return Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + Math.pow(a[6], 2) + Math.pow(a[7], 2) + Math.pow(a[8], 2)); -} - -/** - * Adds two mat3's - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the first operand - * @param {mat3} b the second operand - * @returns {mat3} out - */ -function add(out, a, b) { - out[0] = a[0] + b[0]; - out[1] = a[1] + b[1]; - out[2] = a[2] + b[2]; - out[3] = a[3] + b[3]; - out[4] = a[4] + b[4]; - out[5] = a[5] + b[5]; - out[6] = a[6] + b[6]; - out[7] = a[7] + b[7]; - out[8] = a[8] + b[8]; - return out; -} - -/** - * Subtracts matrix b from matrix a - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the first operand - * @param {mat3} b the second operand - * @returns {mat3} out - */ -function subtract(out, a, b) { - out[0] = a[0] - b[0]; - out[1] = a[1] - b[1]; - out[2] = a[2] - b[2]; - out[3] = a[3] - b[3]; - out[4] = a[4] - b[4]; - out[5] = a[5] - b[5]; - out[6] = a[6] - b[6]; - out[7] = a[7] - b[7]; - out[8] = a[8] - b[8]; - return out; -} +Globe.prototype.intersectionLineWgs84 = function(line, resultCartesian, radius) +{ + // + // line: (x, y, z) = x1 + t(x2 - x1), y1 + t(y2 - y1), z1 + t(z2 - z1) + // sphere: (x - x3)^2 + (y - y3)^2 + (z - z3)^2 = r^2, where x3, y3, z3 is the center of the sphere. + + // line: + var p1 = line.point; + var lineDir = line.direction; + var dist = 1000.0;// any value is ok. + var p2 = new Point3D(p1.x + lineDir.x * dist, p1.y + lineDir.y * dist, p1.z + lineDir.z * dist); + var x1 = p1.x; + var y1 = p1.y; + var z1 = p1.z; + var x2 = p2.x; + var y2 = p2.y; + var z2 = p2.z; -/** - * Multiply each element of the matrix by a scalar. - * - * @param {mat3} out the receiving matrix - * @param {mat3} a the matrix to scale - * @param {Number} b amount to scale the matrix's elements by - * @returns {mat3} out - */ -function multiplyScalar(out, a, b) { - out[0] = a[0] * b; - out[1] = a[1] * b; - out[2] = a[2] * b; - out[3] = a[3] * b; - out[4] = a[4] * b; - out[5] = a[5] * b; - out[6] = a[6] * b; - out[7] = a[7] * b; - out[8] = a[8] * b; - return out; -} + // sphere: + var x3 = 0; + var y3 = 0; + var z3 = 0; + var r = this.equatorialRadius; // provisionally. + if (radius !== undefined) + { r = radius; } + + // resolve: + var x21 = (x2-x1); + var y21 = (y2-y1); + var z21 = (z2-z1); + + var a = x21*x21 + y21*y21 + z21*z21; + + var x13 = (x1-x3); + var y13 = (y1-y3); + var z13 = (z1-z3); + + var b = 2*(x21 * x13 + y21 * y13 + z21 * z13); + + var c = x3*x3 + y3*y3 + z3*z3 + x1*x1 + y1*y1 + z1*z1 - 2*(x3*x1 + y3*y1+ z3*z1) - r*r; + + var discriminant = b*b - 4*a*c; + + if (discriminant < 0) + { + // no intersection. + return undefined; + } + else if (discriminant === 0) + { + // this is tangent. + if (resultCartesian === undefined) + { resultCartesian = []; } // Float32Array has no enough precision. + + var t1 = (-b)/(2*a); + var intersectPoint1 = new Point3D(x1 + (x2 - x1)*t1, y1 + (y2 - y1)*t1, z1 + (z2 - z1)*t1); + resultCartesian[0] = intersectPoint1.x; + resultCartesian[1] = intersectPoint1.y; + resultCartesian[2] = intersectPoint1.z; + + } + else + { + // find the nearest to p1. + var sqrtDiscriminant = Math.sqrt(discriminant); + var t1 = (-b + sqrtDiscriminant)/(2*a); + var t2 = (-b - sqrtDiscriminant)/(2*a); + + // solution 1. + var intersectPoint1 = new Point3D(x1 + (x2 - x1)*t1, y1 + (y2 - y1)*t1, z1 + (z2 - z1)*t1); + var intersectPoint2 = new Point3D(x1 + (x2 - x1)*t2, y1 + (y2 - y1)*t2, z1 + (z2 - z1)*t2); + + var dist1 = p1.squareDistToPoint(intersectPoint1); + var dist2 = p1.squareDistToPoint(intersectPoint2); + + if (resultCartesian === undefined) + { resultCartesian = []; } // Float32Array has no enough precision. + + if (dist1 < dist2) + { + resultCartesian[0] = intersectPoint1.x; + resultCartesian[1] = intersectPoint1.y; + resultCartesian[2] = intersectPoint1.z; + } + else + { + resultCartesian[0] = intersectPoint2.x; + resultCartesian[1] = intersectPoint2.y; + resultCartesian[2] = intersectPoint2.z; + } + } + + return resultCartesian; + +}; -/** - * Adds two mat3's after multiplying each element of the second operand by a scalar value. - * - * @param {mat3} out the receiving vector - * @param {mat3} a the first operand - * @param {mat3} b the second operand - * @param {Number} scale the amount to scale b's elements by before adding - * @returns {mat3} out - */ -function multiplyScalarAndAdd(out, a, b, scale) { - out[0] = a[0] + b[0] * scale; - out[1] = a[1] + b[1] * scale; - out[2] = a[2] + b[2] * scale; - out[3] = a[3] + b[3] * scale; - out[4] = a[4] + b[4] * scale; - out[5] = a[5] + b[5] * scale; - out[6] = a[6] + b[6] * scale; - out[7] = a[7] + b[7] * scale; - out[8] = a[8] + b[8] * scale; - return out; -} /** - * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) - * - * @param {mat3} a The first matrix. - * @param {mat3} b The second matrix. - * @returns {Boolean} True if the matrices are equal, false otherwise. + * Change cartesian point to WGS84 and nromalize that. + * @param {Number} x the x coordi value of input cartesian point + * @param {Number} y the y coordi value of input cartesian point + * @param {Number} z the z coordi value of input cartesian point + * @param {Float32Array} resultNormal the cartesian point which will hold the calculated result + * @returns {Float32Array} resultNormal */ -function exactEquals(a, b) { - return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8]; -} +Globe.prototype.normalAtCartesianPointWgs84 = function(x, y, z, resultNormal) +{ + if (resultNormal === undefined) + { resultNormal = new Float32Array(3); } -/** - * Returns whether or not the matrices have approximately the same elements in the same position. - * - * @param {mat3} a The first matrix. - * @param {mat3} b The second matrix. - * @returns {Boolean} True if the matrices are equal, false otherwise. - */ -function equals(a, b) { - var a0 = a[0], - a1 = a[1], - a2 = a[2], - a3 = a[3], - a4 = a[4], - a5 = a[5], - a6 = a[6], - a7 = a[7], - a8 = a[8]; - var b0 = b[0], - b1 = b[1], - b2 = b[2], - b3 = b[3], - b4 = b[4], - b5 = b[5], - b6 = b[6], - b7 = b[7], - b8 = b[8]; - return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8)); -} + var equatorialRadiusSquared = this.equatorialRadius * this.equatorialRadius; + var polarRadiusSquared = this.polarRadius * this.polarRadius; + + resultNormal[0] = x / equatorialRadiusSquared; + resultNormal[1] = y / equatorialRadiusSquared; + resultNormal[2] = z / polarRadiusSquared; + + // Normalize cartesian. + resultNormal = this.normalizeCartesian(resultNormal); + + return resultNormal; +}; /** - * Alias for {@link mat3.multiply} - * @function + * Calculate atan + * @param {Number} y + * @param {Number} x + * @returns {Number} */ -var mul = exports.mul = multiply; +Globe.atan2Test = function(y, x) +{ + var M_PI = Math.PI; + if (x > 0.0) + { + return Math.atan(y/x); + } + else if (x < 0.0) + { + if (y >= 0.0) + { + return Math.atan(y/x) + M_PI; + } + else + { + return Math.atan(y/x) - M_PI; + } + } + else if (x === 0.0) + { + if (y>0.0) + { + return M_PI/2.0; + } + else if (y<0.0) + { + return -M_PI/2.0; + } + else + { + return 0.0; // return undefined. + } + } +}; /** - * Alias for {@link mat3.subtract} - * @function + * Change absolute coordinate to WGS84 coordinate + * @param {Number} x the x coordi of the point of absolute coordinate + * @param {Number} y the y coordi of the point of absolute coordinate + * @param {Number} z the z coordi of the point of absolute coordinate + * @param {Float32Array} result the cartesian point which will contain the calculated point + * @param {Boolean} bStoreAbsolutePosition This decide whether store absolute value at the 'result' point or not as the property + * @param {Float32Array} result + * */ -var sub = exports.sub = subtract; +Globe.CartesianToGeographicWgs84 = function (x, y, z, result, bStoreAbsolutePosition) +{ + // From WebWorldWind. + // According to H. Vermeille, "An analytical method to transform geocentric into geodetic coordinates" + // http://www.springerlink.com/content/3t6837t27t351227/fulltext.pdf + // Journal of Geodesy, accepted 10/2010, not yet published + + /* + this.equatorialRadius = 6378137.0; // meters. + this.polarRadius = 6356752.3142; // meters. + this.firstEccentricitySquared = 6.69437999014E-3; + this.secondEccentricitySquared = 6.73949674228E-3; + this.degToRadFactor = Math.PI/180.0; + */ + var firstEccentricitySquared = 6.69437999014E-3; + var equatorialRadius = 6378137.0; + /* + var X = z, + Y = x, + Z = y, + */ + var X = x, + Y = y, + Z = z, + XXpYY = X * X + Y * Y, + sqrtXXpYY = Math.sqrt(XXpYY), + a = equatorialRadius, + ra2 = 1 / (a * a), + e2 = firstEccentricitySquared, + e4 = e2 * e2, + p = XXpYY * ra2, + q = Z * Z * (1 - e2) * ra2, + r = (p + q - e4) / 6, + h, + phi, + u, + evoluteBorderTest = 8 * r * r * r + e4 * p * q, + rad1, + rad2, + rad3, + atan, + v, + w, + k, + D, + sqrtDDpZZ, + e, + lambda, + s2; -/***/ }), -/* 2 */ -/***/ (function(module, exports, __webpack_require__) { + if (evoluteBorderTest > 0 || q !== 0) + { + if (evoluteBorderTest > 0) + { + // Step 2: general case + rad1 = Math.sqrt(evoluteBorderTest); + rad2 = Math.sqrt(e4 * p * q); -"use strict"; + // 10*e2 is my arbitrary decision of what Vermeille means by "near... the cusps of the evolute". + if (evoluteBorderTest > 10 * e2) + { + rad3 = Math.cbrt((rad1 + rad2) * (rad1 + rad2)); + u = r + 0.5 * rad3 + 2 * r * r / rad3; + } + else + { + u = r + 0.5 * Math.cbrt((rad1 + rad2) * (rad1 + rad2)) + + 0.5 * Math.cbrt((rad1 - rad2) * (rad1 - rad2)); + } + } + else + { + // Step 3: near evolute + rad1 = Math.sqrt(-evoluteBorderTest); + rad2 = Math.sqrt(-8 * r * r * r); + rad3 = Math.sqrt(e4 * p * q); + //atan = 2 * Math.atan2(rad3, rad1 + rad2) / 3; + atan = 2 * Globe.atan2Test(rad3, rad1 + rad2) / 3; + u = -4 * r * Math.sin(atan) * Math.cos(Math.PI / 6 + atan); + } -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.forEach = exports.sqrLen = exports.len = exports.sqrDist = exports.dist = exports.div = exports.mul = exports.sub = undefined; -exports.create = create; -exports.clone = clone; -exports.length = length; -exports.fromValues = fromValues; -exports.copy = copy; -exports.set = set; -exports.add = add; -exports.subtract = subtract; -exports.multiply = multiply; -exports.divide = divide; -exports.ceil = ceil; -exports.floor = floor; -exports.min = min; -exports.max = max; -exports.round = round; -exports.scale = scale; -exports.scaleAndAdd = scaleAndAdd; -exports.distance = distance; -exports.squaredDistance = squaredDistance; -exports.squaredLength = squaredLength; -exports.negate = negate; -exports.inverse = inverse; -exports.normalize = normalize; -exports.dot = dot; -exports.cross = cross; -exports.lerp = lerp; -exports.hermite = hermite; -exports.bezier = bezier; -exports.random = random; -exports.transformMat4 = transformMat4; -exports.transformMat3 = transformMat3; -exports.transformQuat = transformQuat; -exports.rotateX = rotateX; -exports.rotateY = rotateY; -exports.rotateZ = rotateZ; -exports.angle = angle; -exports.str = str; -exports.exactEquals = exactEquals; -exports.equals = equals; - -var _common = __webpack_require__(0); - -var glMatrix = _interopRequireWildcard(_common); - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } - -/** - * 3 Dimensional Vector - * @module vec3 - */ - -/** - * Creates a new, empty vec3 - * - * @returns {vec3} a new 3D vector - */ -function create() { - var out = new glMatrix.ARRAY_TYPE(3); - out[0] = 0; - out[1] = 0; - out[2] = 0; - return out; -} + v = Math.sqrt(u * u + e4 * q); + w = e2 * (u + v - q) / (2 * v); + k = (u + v) / (Math.sqrt(w * w + u + v) + w); + D = k * sqrtXXpYY / (k + e2); + sqrtDDpZZ = Math.sqrt(D * D + Z * Z); -/** - * Creates a new vec3 initialized with values from an existing vector - * - * @param {vec3} a vector to clone - * @returns {vec3} a new 3D vector - */ -/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. + h = (k + e2 - 1) * sqrtDDpZZ / k; + //phi = 2 * Math.atan2(Z, sqrtDDpZZ + D); + phi = 2 * Globe.atan2Test(Z, sqrtDDpZZ + D); + } + else + { + // Step 4: singular disk + rad1 = Math.sqrt(1 - e2); + rad2 = Math.sqrt(e2 - p); + e = Math.sqrt(e2); -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: + h = -a * rad1 * rad2 / e; + phi = rad2 / (e * rad2 + rad1 * Math.sqrt(p)); + } -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. + // Compute lambda + s2 = Math.sqrt(2); + if ((s2 - 1) * Y < sqrtXXpYY + X) + { + // case 1 - -135deg < lambda < 135deg + //lambda = 2 * Math.atan2(Y, sqrtXXpYY + X); + lambda = 2 * Globe.atan2Test(Y, sqrtXXpYY + X); + } + else if (sqrtXXpYY + Y < (s2 + 1) * X) + { + // case 2 - -225deg < lambda < 45deg + //lambda = -Math.PI * 0.5 + 2 * Math.atan2(X, sqrtXXpYY - Y); + lambda = -Math.PI * 0.5 + 2 * Globe.atan2Test(X, sqrtXXpYY - Y); + } + else + { + // if (sqrtXXpYY-Y<(s2=1)*X) { // is the test, if needed, but it's not + // case 3: - -45deg < lambda < 225deg + //lambda = Math.PI * 0.5 - 2 * Math.atan2(X, sqrtXXpYY + Y); + lambda = Math.PI * 0.5 - 2 * Globe.atan2Test(X, sqrtXXpYY + Y); + } -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ - -function clone(a) { - var out = new glMatrix.ARRAY_TYPE(3); - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - return out; -} + if (result === undefined) + { result = new GeographicCoord(); } -/** - * Calculates the length of a vec3 - * - * @param {vec3} a vector to calculate length of - * @returns {Number} length of a - */ -function length(a) { - var x = a[0]; - var y = a[1]; - var z = a[2]; - return Math.sqrt(x * x + y * y + z * z); -} + var factor = 180.0 / Math.PI; + result.latitude = factor * phi; + result.longitude = factor * lambda; + result.altitude = h; + + if (bStoreAbsolutePosition !== undefined && bStoreAbsolutePosition === true) + { + // In this case, store into result_geographicCoord the x, y, z values. + if (result.absolutePoint === undefined) + { result.absolutePoint = new Point3D(x, y, z); } + else + { result.absolutePoint.set(x, y, z); } + } -/** - * Creates a new vec3 initialized with the given values - * - * @param {Number} x X component - * @param {Number} y Y component - * @param {Number} z Z component - * @returns {vec3} a new 3D vector - */ -function fromValues(x, y, z) { - var out = new glMatrix.ARRAY_TYPE(3); - out[0] = x; - out[1] = y; - out[2] = z; - return out; -} + return result; +}; /** - * Copy the values from one vec3 to another - * - * @param {vec3} out the receiving vector - * @param {vec3} a the source vector - * @returns {vec3} out - */ -function copy(out, a) { - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - return out; -} + * This change the GeographicCoord feature to Point2D feature + * @param {Number} longitude + * @param {Number} latitude + * @param {Point2D} resultPoint2d + * @returns {Point2D} + */ +Globe.geographicToMercatorProjection = function(longitude, latitude, resultPoint2d) +{ + // longitude = [-180, 180]. + // latitude = [-90, 90]. + var degToRadFactor = Math.PI/180.0; + var lonRad = longitude * degToRadFactor; + var latRad = latitude * degToRadFactor; + + return Globe.geographicRadianToMercatorProjection(lonRad, latRad, resultPoint2d); +}; /** - * Set the components of a vec3 to the given values - * - * @param {vec3} out the receiving vector - * @param {Number} x X component - * @param {Number} y Y component - * @param {Number} z Z component - * @returns {vec3} out - */ -function set(out, x, y, z) { - out[0] = x; - out[1] = y; - out[2] = z; - return out; -} + * This change the GeographicCoord feature to Point2D feature using Mercator projection + * @param {Number} lonRad + * @param {Number} latRad + * @param {Point2D} resultPoint2d + * @returns {Point2D} + */ +Globe.geographicRadianToMercatorProjection = function(lonRad, latRad, resultPoint2d) +{ + // longitude = [-pi, pi]. + // latitude = [-pi/2, pi/2]. + var equatorialRadius = Globe.equatorialRadius(); + if (resultPoint2d === undefined) + { resultPoint2d = new Point2D(); } + + resultPoint2d.set(equatorialRadius * lonRad, equatorialRadius * latRad); + + return resultPoint2d; +}; /** - * Adds two vec3's - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {vec3} out - */ -function add(out, a, b) { - out[0] = a[0] + b[0]; - out[1] = a[1] + b[1]; - out[2] = a[2] + b[2]; - return out; -} - -/** - * Subtracts vector b from vector a - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {vec3} out - */ -function subtract(out, a, b) { - out[0] = a[0] - b[0]; - out[1] = a[1] - b[1]; - out[2] = a[2] - b[2]; - return out; -} - -/** - * Multiplies two vec3's - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {vec3} out - */ -function multiply(out, a, b) { - out[0] = a[0] * b[0]; - out[1] = a[1] * b[1]; - out[2] = a[2] * b[2]; - return out; -} - -/** - * Divides two vec3's - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {vec3} out - */ -function divide(out, a, b) { - out[0] = a[0] / b[0]; - out[1] = a[1] / b[1]; - out[2] = a[2] / b[2]; - return out; -} - -/** - * Math.ceil the components of a vec3 - * - * @param {vec3} out the receiving vector - * @param {vec3} a vector to ceil - * @returns {vec3} out - */ -function ceil(out, a) { - out[0] = Math.ceil(a[0]); - out[1] = Math.ceil(a[1]); - out[2] = Math.ceil(a[2]); - return out; -} - -/** - * Math.floor the components of a vec3 - * - * @param {vec3} out the receiving vector - * @param {vec3} a vector to floor - * @returns {vec3} out - */ -function floor(out, a) { - out[0] = Math.floor(a[0]); - out[1] = Math.floor(a[1]); - out[2] = Math.floor(a[2]); - return out; -} - -/** - * Returns the minimum of two vec3's - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {vec3} out - */ -function min(out, a, b) { - out[0] = Math.min(a[0], b[0]); - out[1] = Math.min(a[1], b[1]); - out[2] = Math.min(a[2], b[2]); - return out; -} - -/** - * Returns the maximum of two vec3's - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {vec3} out - */ -function max(out, a, b) { - out[0] = Math.max(a[0], b[0]); - out[1] = Math.max(a[1], b[1]); - out[2] = Math.max(a[2], b[2]); - return out; -} - -/** - * Math.round the components of a vec3 - * - * @param {vec3} out the receiving vector - * @param {vec3} a vector to round - * @returns {vec3} out - */ -function round(out, a) { - out[0] = Math.round(a[0]); - out[1] = Math.round(a[1]); - out[2] = Math.round(a[2]); - return out; -} - -/** - * Scales a vec3 by a scalar number - * - * @param {vec3} out the receiving vector - * @param {vec3} a the vector to scale - * @param {Number} b amount to scale the vector by - * @returns {vec3} out - */ -function scale(out, a, b) { - out[0] = a[0] * b; - out[1] = a[1] * b; - out[2] = a[2] * b; - return out; -} - -/** - * Adds two vec3's after scaling the second operand by a scalar value - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @param {Number} scale the amount to scale b by before adding - * @returns {vec3} out - */ -function scaleAndAdd(out, a, b, scale) { - out[0] = a[0] + b[0] * scale; - out[1] = a[1] + b[1] * scale; - out[2] = a[2] + b[2] * scale; - return out; -} - + * This change the GeographicCoord feature to the cartesian WGS84 point using the blow method. + * defined in the LINZ standard LINZS25000 (Standard for New Zealand Geodetic Datum 2000) + * https://www.linz.govt.nz/data/geodetic-system/coordinate-conversion/geodetic-datum-conversions/equations-used-datum + * @param {Number} longitude + * @param {Number} latitude + * @param {Number} altitude + * @param {Float32Array} resultCartesian + * @returns {Float32Array} resultCartesian + */ +Globe.geographicToCartesianWgs84 = function(longitude, latitude, altitude, resultCartesian) +{ + // a = semi-major axis. + // e2 = firstEccentricitySquared. + // v = a / sqrt(1 - e2 * sin2(lat)). + // x = (v+h)*cos(lat)*cos(lon). + // y = (v+h)*cos(lat)*sin(lon). + // z = [v*(1-e2)+h]*sin(lat). + var degToRadFactor = Math.PI/180.0; + var equatorialRadius = Globe.equatorialRadius(); + var firstEccentricitySquared = 6.69437999014E-3; + var lonRad = longitude * degToRadFactor; + var latRad = latitude * degToRadFactor; + var cosLon = Math.cos(lonRad); + var cosLat = Math.cos(latRad); + var sinLon = Math.sin(lonRad); + var sinLat = Math.sin(latRad); + var a = equatorialRadius; + var e2 = firstEccentricitySquared; + var v = a/Math.sqrt(1.0 - e2 * sinLat * sinLat); + var h = altitude; + + if (resultCartesian === undefined) + { resultCartesian = []; } + + resultCartesian[0]=(v+h)*cosLat*cosLon; + resultCartesian[1]=(v+h)*cosLat*sinLon; + resultCartesian[2]=(v*(1.0-e2)+h)*sinLat; + + return resultCartesian; +}; /** - * Calculates the euclidian distance between two vec3's - * - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {Number} distance between a and b - */ -function distance(a, b) { - var x = b[0] - a[0]; - var y = b[1] - a[1]; - var z = b[2] - a[2]; - return Math.sqrt(x * x + y * y + z * z); -} + * This change the array of the absolute coordinates represented as the angle to the array of WGS84 + * @param {Number} longitude + * @param {Number} latitude + * @param {Number} altitude + * @param {Float32Array} resultCartesian + * @returns {Float32Array} resultCartesian + */ -/** - * Calculates the squared euclidian distance between two vec3's - * - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {Number} squared distance between a and b - */ -function squaredDistance(a, b) { - var x = b[0] - a[0]; - var y = b[1] - a[1]; - var z = b[2] - a[2]; - return x * x + y * y + z * z; -} +Globe.geographicRadianArrayToFloat32ArrayWgs84 = function(lonArray, latArray, altArray, resultCartesianArray) +{ + // defined in the LINZ standard LINZS25000 (Standard for New Zealand Geodetic Datum 2000) + // https://www.linz.govt.nz/data/geodetic-system/coordinate-conversion/geodetic-datum-conversions/equations-used-datum + // a = semi-major axis. + // e2 = firstEccentricitySquared. + // v = a / sqrt(1 - e2 * sin2(lat)). + // x = (v+h)*cos(lat)*cos(lon). + // y = (v+h)*cos(lat)*sin(lon). + // z = [v*(1-e2)+h]*sin(lat). + var equatorialRadius = 6378137.0; // meters. + var firstEccentricitySquared = 6.69437999014E-3; + + var lonRad; + var latRad; + var cosLon; + var cosLat; + var sinLon; + var sinLat; + var a = equatorialRadius; + var e2 = firstEccentricitySquared; + var e2a = 1.0 - e2; + var v; + var h; + + var coordsCount = lonArray.length; + if (resultCartesianArray === undefined) + { + resultCartesianArray = new Float32Array(coordsCount*3); + } + for (var i=0; i 0) { - //TODO: evaluate use of glm_invsqrt here? - len = 1 / Math.sqrt(len); - out[0] = a[0] * len; - out[1] = a[1] * len; - out[2] = a[2] * len; - } - return out; -} + /** + * Depth framebuffer object. + * @type {FBO} + * @default undefined. + */ + this.depthFboNeo; + + /** + * Depth framebuffer object for auxiliary and test use. + * @type {FBO} + * @default undefined. + */ + this.depthFboAux; + + /** + * Framebuffer object used for color coding selection. + * @type {FBO} + * @default undefined. + */ + this.selectionFbo; + + /** + * Current x position of the mouse in screen coordinates. + * @type {Number} + * @default 0. + */ + this.mouse_x = 0; + + /** + * Current y position of the mouse in screen coordinates. + * @type {Number} + * @default 0. + */ + this.mouse_y = 0; + + + this.mouseLeftDown = false; + this.mouseMiddleDown = false; + this.mouseDragging = false; + this.selObjMovePlane; -/** - * Calculates the dot product of two vec3's - * - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {Number} dot product of a and b - */ -function dot(a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; -} + this.objectSelected; + this.buildingSelected; + this.octreeSelected; + this.nodeSelected; -/** - * Computes the cross product of two vec3's - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @returns {vec3} out - */ -function cross(out, a, b) { - var ax = a[0], - ay = a[1], - az = a[2]; - var bx = b[0], - by = b[1], - bz = b[2]; - - out[0] = ay * bz - az * by; - out[1] = az * bx - ax * bz; - out[2] = ax * by - ay * bx; - return out; -} + this.mustCheckIfDragging = true; + this.thereAreStartMovePoint = false; + this.startMovPoint = new Point3D(); + + this.configInformation; + this.cameraFPV = new FirstPersonView(); + this.myCameraSCX; + + var serverPolicy = MagoConfig.getPolicy(); + if (serverPolicy !== undefined) + { + this.magoPolicy.setLod0DistInMeters(serverPolicy.geo_lod0); + this.magoPolicy.setLod1DistInMeters(serverPolicy.geo_lod1); + this.magoPolicy.setLod2DistInMeters(serverPolicy.geo_lod2); + this.magoPolicy.setLod3DistInMeters(serverPolicy.geo_lod3); + this.magoPolicy.setLod4DistInMeters(serverPolicy.geo_lod4); + this.magoPolicy.setLod5DistInMeters(serverPolicy.geo_lod5); + } -/** - * Performs a linear interpolation between two vec3's - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @param {Number} t interpolation amount between the two inputs - * @returns {vec3} out - */ -function lerp(out, a, b, t) { - var ax = a[0]; - var ay = a[1]; - var az = a[2]; - out[0] = ax + t * (b[0] - ax); - out[1] = ay + t * (b[1] - ay); - out[2] = az + t * (b[2] - az); - return out; -} + this.kernel = [ 0.33, 0.0, 0.85, + 0.25, 0.3, 0.5, + 0.1, 0.3, 0.85, + -0.15, 0.2, 0.85, + -0.33, 0.05, 0.6, + -0.1, -0.15, 0.85, + -0.05, -0.32, 0.25, + 0.2, -0.15, 0.85, + 0.6, 0.0, 0.55, + 0.5, 0.6, 0.45, + -0.01, 0.7, 0.35, + -0.33, 0.5, 0.45, + -0.45, 0.0, 0.55, + -0.65, -0.5, 0.7, + 0.0, -0.5, 0.55, + 0.33, 0.3, 0.35]; -/** - * Performs a hermite interpolation with two control points - * - * @param {vec3} out the receiving vector - * @param {vec3} a the first operand - * @param {vec3} b the second operand - * @param {vec3} c the third operand - * @param {vec3} d the fourth operand - * @param {Number} t interpolation amount between the two inputs - * @returns {vec3} out - */ -function hermite(out, a, b, c, d, t) { - var factorTimes2 = t * t; - var factor1 = factorTimes2 * (2 * t - 3) + 1; - var factor2 = factorTimes2 * (t - 2) + t; - var factor3 = factorTimes2 * (t - 1); - var factor4 = factorTimes2 * (3 - 2 * t); - - out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4; - out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4; - out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4; - - return out; -} + // Test for sphere.*** + this.sphereKernel = []; + var kernelSize = 16; + for (var i=0; i 1.0) { - return 0; - } else if (cosine < -1.0) { - return Math.PI; - } else { - return Math.acos(cosine); - } -} + this.objMarkerManager = new ObjectMarkerManager(); + this.pin = new Pin(); + + //this.weatherStation = new WeatherStation(); + + // renderWithTopology === 0 -> render only CityGML.*** + // renderWithTopology === 1 -> render only IndoorGML.*** + // renderWithTopology === 2 -> render both.*** + this.tempSettings = {}; + this.tempSettings.renderWithTopology = 1; + this.tempSettings.renderSpaces = true; + this.tempSettings.spacesAlpha = 0.6; + + //this.tinTerrainManager = new TinTerrainManager(); +}; /** - * Returns a string representation of a vector - * - * @param {vec3} a vector to represent as a string - * @returns {String} string representation of the vector + * object 를 그리는 두가지 종류의 function을 호출 */ -function str(a) { - return 'vec3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ')'; -} +MagoManager.prototype.init = function(gl) +{ + this.bInit = true; + + if (this.sceneState.gl === undefined) + { this.sceneState.gl = gl; } + if (this.vboMemoryManager.gl === undefined) + { this.vboMemoryManager.gl = gl; } +}; /** - * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===) - * - * @param {vec3} a The first vector. - * @param {vec3} b The second vector. - * @returns {Boolean} True if the vectors are equal, false otherwise. + * object 를 그리는 두가지 종류의 function을 호출 + * @param scene 변수 Cesium Scene. + * @param pass 변수 + * @param frustumIdx 변수 + * @param numFrustums 변수 */ -function exactEquals(a, b) { - return a[0] === b[0] && a[1] === b[1] && a[2] === b[2]; -} +MagoManager.prototype.start = function(scene, pass, frustumIdx, numFrustums) +{ + // Calculate FPS. + //var start = new Date().getTime(); + + // this is cesium version.*** + // mago3d 활성화가 아니면 화면을 그리지 않음 + if (!this.magoPolicy.getMagoEnable()) { return; } -/** - * Returns whether or not the vectors have approximately the same elements in the same position. - * - * @param {vec3} a The first vector. - * @param {vec3} b The second vector. - * @returns {Boolean} True if the vectors are equal, false otherwise. - */ -function equals(a, b) { - var a0 = a[0], - a1 = a[1], - a2 = a[2]; - var b0 = b[0], - b1 = b[1], - b2 = b[2]; - return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)); -} + var isLastFrustum = false; + this.numFrustums = numFrustums; + this.currentFrustumIdx = this.numFrustums-frustumIdx-1; + if (this.currentFrustumIdx === numFrustums-1) + { + isLastFrustum = true; + this.isLastFrustum = true; + } -/** - * Alias for {@link vec3.subtract} - * @function - */ -var sub = exports.sub = subtract; + // cesium 새 버전에서 지원하지 않음 + var picking = pass.pick; + if (picking) + { + // + } + else + { + if (this.configInformation === undefined) + { + this.configInformation = MagoConfig.getPolicy(); + } + if (scene) + { + var gl = scene.context._gl; + gl.getExtension("EXT_frag_depth"); + + if (!this.bInit) + { this.init(gl); } + + if (gl.isContextLost()) + { return; } -/** - * Alias for {@link vec3.multiply} - * @function - */ -var mul = exports.mul = multiply; + + } -/** - * Alias for {@link vec3.divide} - * @function - */ -var div = exports.div = divide; + this.startRender(isLastFrustum, this.currentFrustumIdx, numFrustums); + + } +}; /** - * Alias for {@link vec3.distance} - * @function + * Swaps the current rendering Phase. */ -var dist = exports.dist = distance; +MagoManager.prototype.swapRenderingFase = function() +{ + this.renderingFase = !this.renderingFase; +}; /** - * Alias for {@link vec3.squaredDistance} - * @function + * 빌딩을 준비(새버전) + * @param {gl} gl */ -var sqrDist = exports.sqrDist = squaredDistance; +MagoManager.prototype.prepareNeoBuildingsAsimetricVersion = function(gl, visibleObjControlerNodes) +{ + // for all renderables, prepare data.*** + var neoBuilding; + var node, rootNode; + var projectFolderName; + var neoBuildingFolderName; + //var geometryDataPath = this.readerWriter.getCurrentDataPath(); + var geometryDataPath = this.readerWriter.geometryDataPath; // default geometryDataPath = "/f4d".*** + if (this.headersRequestedCounter === undefined) + { this.headersRequestedCounter = 0; } -/** - * Alias for {@link vec3.length} - * @function - */ -var len = exports.len = length; + var currentVisibleNodes = [].concat(visibleObjControlerNodes.currentVisibles0, visibleObjControlerNodes.currentVisibles2, visibleObjControlerNodes.currentVisibles3, visibleObjControlerNodes.currentVisiblesAux); + for (var i=0, length = currentVisibleNodes.length; i 0) { - len = 1 / Math.sqrt(len); - out[0] = x * len; - out[1] = y * len; - out[2] = z * len; - out[3] = w * len; - } - return out; -} + * start rendering. + * @param scene 변수 + * @param isLastFrustum 변수 + */ + +MagoManager.prototype.load_testTextures = function() +{ + if (this.pin.texture === undefined) + { + var gl = this.sceneState.gl; + + this.pin.texture = new Texture(); + var filePath_inServer = this.magoPolicy.imagePath + "/bugger.png"; + this.pin.texture.texId = gl.createTexture(); + this.readerWriter.readNeoReferenceTexture(gl, filePath_inServer, this.pin.texture, undefined, this); + this.pin.texturesArray.push(this.pin.texture); + + var cabreadoTex = new Texture(); + filePath_inServer = this.magoPolicy.imagePath + "/improve.png"; + cabreadoTex.texId = gl.createTexture(); + this.readerWriter.readNeoReferenceTexture(gl, filePath_inServer, cabreadoTex, undefined, this); + this.pin.texturesArray.push(cabreadoTex); + + cabreadoTex = new Texture(); + filePath_inServer = this.magoPolicy.imagePath + "/etc.png"; + cabreadoTex.texId = gl.createTexture(); + this.readerWriter.readNeoReferenceTexture(gl, filePath_inServer, cabreadoTex, undefined, this); + this.pin.texturesArray.push(cabreadoTex); + + cabreadoTex = new Texture(); + filePath_inServer = this.magoPolicy.imagePath + "/new.png"; + cabreadoTex.texId = gl.createTexture(); + this.readerWriter.readNeoReferenceTexture(gl, filePath_inServer, cabreadoTex, undefined, this); + this.pin.texturesArray.push(cabreadoTex); + + cabreadoTex = new Texture(); + filePath_inServer = this.magoPolicy.imagePath + "/funny.jpg"; + cabreadoTex.texId = gl.createTexture(); + this.readerWriter.readNeoReferenceTexture(gl, filePath_inServer, cabreadoTex, undefined, this); + this.pin.texturesArray.push(cabreadoTex); + } +}; /** - * Calculates the dot product of two vec4's - * - * @param {vec4} a the first operand - * @param {vec4} b the second operand - * @returns {Number} dot product of a and b + * start rendering. + * @param scene 변수 + * @param isLastFrustum 변수 */ -function dot(a, b) { - return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; -} +MagoManager.prototype.getCurrentTime = function() +{ + if (this.currTime === undefined) + { + this.dateSC = new Date(); + this.currTime = this.dateSC.getTime(); + } + return this.currTime; +}; /** - * Performs a linear interpolation between two vec4's - * - * @param {vec4} out the receiving vector - * @param {vec4} a the first operand - * @param {vec4} b the second operand - * @param {Number} t interpolation amount between the two inputs - * @returns {vec4} out - */ -function lerp(out, a, b, t) { - var ax = a[0]; - var ay = a[1]; - var az = a[2]; - var aw = a[3]; - out[0] = ax + t * (b[0] - ax); - out[1] = ay + t * (b[1] - ay); - out[2] = az + t * (b[2] - az); - out[3] = aw + t * (b[3] - aw); - return out; -} + * Returns WebGL Rendering Context. + */ +MagoManager.prototype.getGl = function() +{ + if (this.sceneState === undefined) + { return undefined; } + + return this.sceneState.gl; +}; /** - * Generates a random vector with the given scale - * - * @param {vec4} out the receiving vector - * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned - * @returns {vec4} out - */ -function random(out, vectorScale) { - vectorScale = vectorScale || 1.0; - - //TODO: This is a pretty awful way of doing this. Find something better. - out[0] = glMatrix.RANDOM(); - out[1] = glMatrix.RANDOM(); - out[2] = glMatrix.RANDOM(); - out[3] = glMatrix.RANDOM(); - normalize(out, out); - scale(out, out, vectorScale); - return out; -} + * Loads necessary data. + */ +MagoManager.prototype.loadAndPrepareData = function() +{ + var gl = this.getGl(); + + // 1) LOD 0.*********************************************************************************** + this.visibleObjControlerOctrees.initArrays(); // init.****** -/** - * Transforms the vec4 with a mat4. - * - * @param {vec4} out the receiving vector - * @param {vec4} a the vector to transform - * @param {mat4} m matrix to transform with - * @returns {vec4} out - */ -function transformMat4(out, a, m) { - var x = a[0], - y = a[1], - z = a[2], - w = a[3]; - out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w; - out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w; - out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w; - out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w; - return out; -} + var neoBuilding; + var node; + var octree; + // lod 0 & lod 1. + this.checkPropertyFilters(this.visibleObjControlerNodes.currentVisibles0); + this.checkPropertyFilters(this.visibleObjControlerNodes.currentVisibles2); + var nodesCount = this.visibleObjControlerNodes.currentVisibles0.length; + for (var i=0; i 5) + { return; } + + // Prepare lod3, lod4 and lod5 meshes.*** + // check "this.visibleObjControlerNodes.currentVisibles3".*** + var node; + var neoBuilding; + var extraCount = 5; + + var lowLodNodesCount = lowLodNodesArray.length; + for (var i=0; i 5) + { return; } + } +}; /** - * Inverts a mat2 - * - * @param {mat2} out the receiving matrix - * @param {mat2} a the source matrix - * @returns {mat2} out + * Draw building names on scene. */ -function invert(out, a) { - var a0 = a[0], - a1 = a[1], - a2 = a[2], - a3 = a[3]; - - // Calculate the determinant - var det = a0 * a3 - a2 * a1; - - if (!det) { - return null; - } - det = 1.0 / det; +MagoManager.prototype.drawBuildingNames = function(visibleObjControlerNodes) +{ + var canvas = this.getObjectLabel(); + var ctx = canvas.getContext("2d"); + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); - out[0] = a3 * det; - out[1] = -a1 * det; - out[2] = -a2 * det; - out[3] = a0 * det; + // lod2. + var gl = this.getGl(); + var node; + var nodeRoot; + var geoLocDataManager; + var geoLoc; + var neoBuilding; + var worldPosition; + var screenCoord; + + // 1rst, collect rootNodes. + var rootNodesMap = {}; + var currentVisiblesArray = visibleObjControlerNodes.currentVisibles2.concat(visibleObjControlerNodes.currentVisibles3); + var nodesCount = currentVisiblesArray.length; + for (var i=0; i= 0 && screenCoord.y >= 0) + { + ctx.font = "13px Arial"; + //ctx.strokeText(nodeRoot.data.nodeId, screenCoord.x, screenCoord.y); + //ctx.fillText(nodeRoot.data.nodeId, screenCoord.x, screenCoord.y); + ctx.strokeText(nodeRoot.data.data_name, screenCoord.x, screenCoord.y); + ctx.fillText(nodeRoot.data.data_name, screenCoord.x, screenCoord.y); + } + } + } + + rootNodesMap = {}; -/** - * Calculates the adjugate of a mat2 - * - * @param {mat2} out the receiving matrix - * @param {mat2} a the source matrix - * @returns {mat2} out - */ -function adjoint(out, a) { - // Caching this value is nessecary if out == a - var a0 = a[0]; - out[0] = a[3]; - out[1] = -a[1]; - out[2] = -a[2]; - out[3] = a0; - - return out; -} + ctx.restore(); +}; /** - * Calculates the determinant of a mat2 - * - * @param {mat2} a the source matrix - * @returns {Number} determinant of a + * The camera was moved. */ -function determinant(a) { - return a[0] * a[3] - a[2] * a[1]; -} - -/** - * Multiplies two mat2's - * - * @param {mat2} out the receiving matrix - * @param {mat2} a the first operand - * @param {mat2} b the second operand - * @returns {mat2} out - */ -function multiply(out, a, b) { - var a0 = a[0], - a1 = a[1], - a2 = a[2], - a3 = a[3]; - var b0 = b[0], - b1 = b[1], - b2 = b[2], - b3 = b[3]; - out[0] = a0 * b0 + a2 * b1; - out[1] = a1 * b0 + a3 * b1; - out[2] = a0 * b2 + a2 * b3; - out[3] = a1 * b2 + a3 * b3; - return out; -} +MagoManager.prototype.cameraMoved = function() +{ + this.sceneState.camera.setDirty(true); + + if (this.selectionFbo === undefined) + { this.selectionFbo = new FBO(this.sceneState.gl, this.sceneState.drawingBufferWidth, this.sceneState.drawingBufferHeight); } -/** - * Rotates a mat2 by the given angle - * - * @param {mat2} out the receiving matrix - * @param {mat2} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat2} out - */ -function rotate(out, a, rad) { - var a0 = a[0], - a1 = a[1], - a2 = a[2], - a3 = a[3]; - var s = Math.sin(rad); - var c = Math.cos(rad); - out[0] = a0 * c + a2 * s; - out[1] = a1 * c + a3 * s; - out[2] = a0 * -s + a2 * c; - out[3] = a1 * -s + a3 * c; - return out; -} + this.selectionFbo.dirty = true; +}; /** - * Scales the mat2 by the dimensions in the given vec2 - * - * @param {mat2} out the receiving matrix - * @param {mat2} a the matrix to rotate - * @param {vec2} v the vec2 to scale the matrix by - * @returns {mat2} out - **/ -function scale(out, a, v) { - var a0 = a[0], - a1 = a[1], - a2 = a[2], - a3 = a[3]; - var v0 = v[0], - v1 = v[1]; - out[0] = a0 * v0; - out[1] = a1 * v0; - out[2] = a2 * v1; - out[3] = a3 * v1; - return out; -} + * Selects an object of the current visible objects that's under mouse. + * @param {GL} gl. + * @param {int} mouseX Screen x position of the mouse. + * @param {int} mouseY Screen y position of the mouse. + * @param {VisibleObjectsControler} visibleObjControlerBuildings Contains the current visible objects clasified by LOD. + * @returns {Array} resultSelectedArray + */ +MagoManager.prototype.getSelectedObjects = function(gl, mouseX, mouseY, resultSelectedArray) +{ + // Read the picked pixel and find the object.********************************************************* + var mosaicWidth = 9; + var mosaicHeight = 9; + var totalPixelsCount = mosaicWidth*mosaicHeight; + var pixels = new Uint8Array(4 * mosaicWidth * mosaicHeight); // 4 x 3x3 pixel, total 9 pixels select.*** + var pixelX = mouseX - Math.floor(mosaicWidth/2); + var pixelY = this.sceneState.drawingBufferHeight - mouseY - Math.floor(mosaicHeight/2); // origin is bottom.*** + + if (pixelX < 0){ pixelX = 0; } + if (pixelY < 0){ pixelY = 0; } + + gl.readPixels(pixelX, pixelY, mosaicWidth, mosaicHeight, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); // unbind framebuffer.*** + + //this.selectionManager.clearCurrents(); -/** - * Creates a matrix from a given angle - * This is equivalent to (but much faster than): - * - * mat2.identity(dest); - * mat2.rotate(dest, dest, rad); - * - * @param {mat2} out mat2 receiving operation result - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat2} out - */ -function fromRotation(out, rad) { - var s = Math.sin(rad); - var c = Math.cos(rad); - out[0] = c; - out[1] = s; - out[2] = -s; - out[3] = c; - return out; -} + // now, select the object.*** + // The center pixel of the selection is 12, 13, 14.*** + var centerPixel = Math.floor(totalPixelsCount/2); + var idx = this.selectionColor.decodeColor3(pixels[centerPixel*3], pixels[centerPixel*3+1], pixels[centerPixel*3+2]); + this.selectionManager.selectObjects(idx); + + var selectedObject = this.selectionManager.currentReferenceSelected; -/** - * Creates a matrix from a vector scaling - * This is equivalent to (but much faster than): - * - * mat2.identity(dest); - * mat2.scale(dest, dest, vec); - * - * @param {mat2} out mat2 receiving operation result - * @param {vec2} v Scaling vector - * @returns {mat2} out - */ -function fromScaling(out, v) { - out[0] = v[0]; - out[1] = 0; - out[2] = 0; - out[3] = v[1]; - return out; -} + resultSelectedArray[0] = this.selectionManager.currentBuildingSelected; + resultSelectedArray[1] = this.selectionManager.currentOctreeSelected; + resultSelectedArray[2] = this.selectionManager.currentReferenceSelected; + resultSelectedArray[3] = this.selectionManager.currentNodeSelected; + + // Aditionally check if selected an edge of topology.*** + var selNetworkEdges = this.selectionManager.getSelectionCandidatesFamily("networkEdges"); + if (selNetworkEdges) + { + var currEdgeSelected = selNetworkEdges.currentSelected; + var i = 0; + while (currEdgeSelected === undefined && i< totalPixelsCount) + { + var idx = this.selectionColor.decodeColor3(pixels[i*3], pixels[i*3+1], pixels[i*3+2]); + currEdgeSelected = selNetworkEdges.selectObject(idx); + i++; + } + } + + // TEST: Check if selected a cuttingPlane.*** + var selGeneralObjects = this.selectionManager.getSelectionCandidatesFamily("general"); + if (selGeneralObjects) + { + var currObjectSelected = selGeneralObjects.currentSelected; + var i = 0; + while (currObjectSelected === undefined && i< totalPixelsCount) + { + var idx = this.selectionColor.decodeColor3(pixels[i*3], pixels[i*3+1], pixels[i*3+2]); + currObjectSelected = selGeneralObjects.selectObject(idx); + i++; + } + } + + return selectedObject; +}; /** - * Returns a string representation of a mat2 - * - * @param {mat2} a matrix to represent as a string - * @returns {String} string representation of the matrix + * Calculates the plane on move an object. + * @param {GL} gl 변수 + * @param {int} pixelX Screen x position of the pixel. + * @param {int} pixelY Screen y position of the pixel. + * @returns {Plane} resultSelObjMovePlane Calculated plane. */ -function str(a) { - return 'mat2(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')'; -} +MagoManager.prototype.calculateSelObjMovePlaneAsimetricMode = function(gl, pixelX, pixelY, resultSelObjMovePlane) +{ + if (this.pointSC === undefined) + { this.pointSC = new Point3D(); } + + if (this.pointSC2 === undefined) + { this.pointSC2 = new Point3D(); } + + var geoLocDataManager = this.nodeSelected.getNodeGeoLocDataManager(); + + ManagerUtils.calculatePixelPositionWorldCoord(gl, pixelX, pixelY, this.pointSC2, undefined, undefined, this); + var buildingGeoLocation = geoLocDataManager.getCurrentGeoLocationData(); + var tMatrixInv = buildingGeoLocation.getTMatrixInv(); + this.pointSC = tMatrixInv.transformPoint3D(this.pointSC2, this.pointSC); // buildingSpacePoint.*** -/** - * Returns Frobenius norm of a mat2 - * - * @param {mat2} a the matrix to calculate Frobenius norm of - * @returns {Number} Frobenius norm - */ -function frob(a) { - return Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2)); -} + if (resultSelObjMovePlane === undefined) + { resultSelObjMovePlane = new Plane(); } + // the plane is in world coord.*** + resultSelObjMovePlane.setPointAndNormal(this.pointSC.x, this.pointSC.y, this.pointSC.z, 0.0, 0.0, 1.0); + return resultSelObjMovePlane; +}; /** - * Returns L, D and U matrices (Lower triangular, Diagonal and Upper triangular) by factorizing the input matrix - * @param {mat2} L the lower triangular matrix - * @param {mat2} D the diagonal matrix - * @param {mat2} U the upper triangular matrix - * @param {mat2} a the input matrix to factorize + * Returns true if is dragging. + * + * @returns {Boolean} 드래그 여부 */ +MagoManager.prototype.isDragging = function() +{ + // test function.*** + var bIsDragging = false; + var gl = this.sceneState.gl; -function LDU(L, D, U, a) { - L[2] = a[2] / a[0]; - U[0] = a[0]; - U[1] = a[1]; - U[3] = a[3] - L[2] * U[1]; - return [L, D, U]; -} - -/** - * Adds two mat2's - * - * @param {mat2} out the receiving matrix - * @param {mat2} a the first operand - * @param {mat2} b the second operand - * @returns {mat2} out - */ -function add(out, a, b) { - out[0] = a[0] + b[0]; - out[1] = a[1] + b[1]; - out[2] = a[2] + b[2]; - out[3] = a[3] + b[3]; - return out; -} - -/** - * Subtracts matrix b from matrix a - * - * @param {mat2} out the receiving matrix - * @param {mat2} a the first operand - * @param {mat2} b the second operand - * @returns {mat2} out - */ -function subtract(out, a, b) { - out[0] = a[0] - b[0]; - out[1] = a[1] - b[1]; - out[2] = a[2] - b[2]; - out[3] = a[3] - b[3]; - return out; -} - -/** - * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) - * - * @param {mat2} a The first matrix. - * @param {mat2} b The second matrix. - * @returns {Boolean} True if the matrices are equal, false otherwise. - */ -function exactEquals(a, b) { - return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]; -} + if (this.magoPolicy.objectMoveMode === CODE.moveMode.ALL) // Moving all + { + this.arrayAuxSC.length = 0; + this.selectionFbo.bind(); + var current_objectSelected = this.getSelectedObjects(gl, this.mouse_x, this.mouse_y, this.arrayAuxSC); + var currentBuildingSelected = this.arrayAuxSC[0]; + var currentNodeSelected = this.arrayAuxSC[3]; + var currentRootNodeSelected; + if (currentNodeSelected) + { + currentRootNodeSelected = currentNodeSelected.getRoot(); + } + this.arrayAuxSC.length = 0; -/** - * Returns whether or not the matrices have approximately the same elements in the same position. - * - * @param {mat2} a The first matrix. - * @param {mat2} b The second matrix. - * @returns {Boolean} True if the matrices are equal, false otherwise. - */ -function equals(a, b) { - var a0 = a[0], - a1 = a[1], - a2 = a[2], - a3 = a[3]; - var b0 = b[0], - b1 = b[1], - b2 = b[2], - b3 = b[3]; - return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)); -} + if (currentRootNodeSelected === this.rootNodeSelected) + { + bIsDragging = true; + } + else + { + bIsDragging = false; + } + } + else if (this.magoPolicy.objectMoveMode === CODE.moveMode.OBJECT) // Moving object + { + this.arrayAuxSC.length = 0; + this.selectionFbo.bind(); + var current_objectSelected = this.getSelectedObjects(gl, this.mouse_x, this.mouse_y, this.arrayAuxSC); + this.arrayAuxSC.length = 0; -/** - * Multiply each element of the matrix by a scalar. - * - * @param {mat2} out the receiving matrix - * @param {mat2} a the matrix to scale - * @param {Number} b amount to scale the matrix's elements by - * @returns {mat2} out - */ -function multiplyScalar(out, a, b) { - out[0] = a[0] * b; - out[1] = a[1] * b; - out[2] = a[2] * b; - out[3] = a[3] * b; - return out; -} + if (current_objectSelected === this.objectSelected) + { + bIsDragging = true; + } + else + { + bIsDragging = false; + } + } + else if (this.magoPolicy.objectMoveMode === CODE.moveMode.GEOGRAPHICPOINTS) + { + // Compare currentSelectedObject with the nowSelectedObject.*** + var currSelected = this.selectionManager.getSelectedGeneral(); + this.arrayAuxSC.length = 0; + this.selectionFbo.bind(); + this.getSelectedObjects(gl, this.mouse_x, this.mouse_y, this.arrayAuxSC); + var nowSelected = this.selectionManager.getSelectedGeneral(); + if (nowSelected !== undefined && nowSelected === currSelected) + { + var className = nowSelected.constructor.name; + if (className === "GeographicCoord") + { + bIsDragging = true; + } + else + { + bIsDragging = false; + } + } + } + else + { + if (this.weatherStation) + { + // check if there are cuttingPlanes to move.*** + this.selectionFbo.bind(); + var current_objectSelected = this.getSelectedObjects(gl, this.mouse_x, this.mouse_y, this.arrayAuxSC); + var selGeneralObjects = this.selectionManager.getSelectionCandidatesFamily("general"); + if (selGeneralObjects) + { + var currObjectSelected = selGeneralObjects.currentSelected; + if (currObjectSelected) + { + // check if is a cuttingPlane.*** + if (currObjectSelected instanceof CuttingPlane) + { + bIsDragging = true; + } + } + else + { + + bIsDragging = false; + } + } + else + { bIsDragging = false; } + } + } + + if (!bIsDragging) + { + this.selectionManager.clearCandidates(); + } -/** - * Adds two mat2's after multiplying each element of the second operand by a scalar value. - * - * @param {mat2} out the receiving vector - * @param {mat2} a the first operand - * @param {mat2} b the second operand - * @param {Number} scale the amount to scale b's elements by before adding - * @returns {mat2} out - */ -function multiplyScalarAndAdd(out, a, b, scale) { - out[0] = a[0] + b[0] * scale; - out[1] = a[1] + b[1] * scale; - out[2] = a[2] + b[2] * scale; - out[3] = a[3] + b[3] * scale; - return out; -} + return bIsDragging; +}; /** - * Alias for {@link mat2.multiply} - * @function + * 카메라 motion 활성 또는 비활성 + * + * @param {Boolean} state 카메라 모션 활성화 여부 */ -var mul = exports.mul = multiply; +MagoManager.prototype.setCameraMotion = function(state) +{ + if (this.configInformation.geo_view_library === Constant.CESIUM) + { + this.scene.screenSpaceCameraController.enableRotate = state; + this.scene.screenSpaceCameraController.enableZoom = state; + this.scene.screenSpaceCameraController.enableLook = state; + this.scene.screenSpaceCameraController.enableTilt = state; + this.scene.screenSpaceCameraController.enableTranslate = state; + } +}; /** - * Alias for {@link mat2.subtract} - * @function + * 선택 객체를 asimetric mode 로 이동 + * @param gl 변수 + * @param scene 변수 */ -var sub = exports.sub = subtract; - -/***/ }), -/* 6 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - +MagoManager.prototype.mouseActionLeftUp = function(mouseX, mouseY) +{ + if (this.objectMoved) + { + this.objectMoved = false; + var nodeSelected = this.selectionManager.currentNodeSelected; + if (nodeSelected === undefined) + { return; } + + this.saveHistoryObjectMovement(this.objectSelected, nodeSelected); + } + + this.isCameraMoving = false; + this.mouseLeftDown = false; + this.mouseDragging = false; + this.selObjMovePlane = undefined; + this.mustCheckIfDragging = true; + this.thereAreStartMovePoint = false; -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.sub = exports.mul = undefined; -exports.create = create; -exports.clone = clone; -exports.copy = copy; -exports.identity = identity; -exports.fromValues = fromValues; -exports.set = set; -exports.invert = invert; -exports.determinant = determinant; -exports.multiply = multiply; -exports.rotate = rotate; -exports.scale = scale; -exports.translate = translate; -exports.fromRotation = fromRotation; -exports.fromScaling = fromScaling; -exports.fromTranslation = fromTranslation; -exports.str = str; -exports.frob = frob; -exports.add = add; -exports.subtract = subtract; -exports.multiplyScalar = multiplyScalar; -exports.multiplyScalarAndAdd = multiplyScalarAndAdd; -exports.exactEquals = exactEquals; -exports.equals = equals; - -var _common = __webpack_require__(0); - -var glMatrix = _interopRequireWildcard(_common); - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } - -/** - * 2x3 Matrix - * @module mat2d - * - * @description - * A mat2d contains six elements defined as: - *
- * [a, c, tx,
- *  b, d, ty]
- * 
- * This is a short form for the 3x3 matrix: - *
- * [a, c, tx,
- *  b, d, ty,
- *  0, 0, 1]
- * 
- * The last row is ignored so the array is shorter and operations are faster. - */ - -/** - * Creates a new identity mat2d - * - * @returns {mat2d} a new 2x3 matrix - */ -function create() { - var out = new glMatrix.ARRAY_TYPE(6); - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 1; - out[4] = 0; - out[5] = 0; - return out; -} + this.dateSC = new Date(); + this.currentTimeSC = this.dateSC.getTime(); + var miliSecondsUsed = this.currentTimeSC - this.startTimeSC; + if (miliSecondsUsed < 1500) + { + if (this.mouse_x === mouseX && this.mouse_y === mouseY) + { + this.bPicking = true; + } + } + + this.setCameraMotion(true); + + // Clear startPositions of mouseAction.*** + var mouseAction = this.sceneState.mouseAction; + mouseAction.clearStartPositionsAux(); // provisionally only clear the aux.*** +}; /** - * Creates a new mat2d initialized with values from an existing matrix - * - * @param {mat2d} a matrix to clone - * @returns {mat2d} a new 2x3 matrix + * 선택 객체를 asimetric mode 로 이동 + * @param gl 변수 + * @param scene 변수 */ -/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ - -function clone(a) { - var out = new glMatrix.ARRAY_TYPE(6); - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - out[3] = a[3]; - out[4] = a[4]; - out[5] = a[5]; - return out; -} - -/** - * Copy the values from one mat2d to another - * - * @param {mat2d} out the receiving matrix - * @param {mat2d} a the source matrix - * @returns {mat2d} out - */ -function copy(out, a) { - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - out[3] = a[3]; - out[4] = a[4]; - out[5] = a[5]; - return out; -} - -/** - * Set a mat2d to the identity matrix - * - * @param {mat2d} out the receiving matrix - * @returns {mat2d} out - */ -function identity(out) { - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 1; - out[4] = 0; - out[5] = 0; - return out; -} +MagoManager.prototype.keyDown = function(key) +{ + if (key === 32) // 32 = 'space'.*** + { + if (this.pointsCloudSsao === undefined) + { this.pointsCloudSsao = true; } + + if (this.pointsCloudSsao) + { this.pointsCloudSsao = false; } + else + { this.pointsCloudSsao = true; } + + + } + /* + else if (key === 37) // 37 = 'left'.*** + { + + } + else if (key === 38) // 38 = 'up'.*** + { + + } + else if (key === 39) // 39 = 'right'.*** + { + + } + else if (key === 40) // 40 = 'down'.*** + { + + } + */ + else if (key === 49) // 49 = '1'.*** + { + if (this.pointsCloudWhite === undefined) + { this.pointsCloudWhite = true; } + + if (this.pointsCloudWhite) + { this.pointsCloudWhite = false; } + else + { this.pointsCloudWhite = true; } + } + else if (key === 80) // 80 = 'p'.*** + { + var projectId = "AutonomousBus"; + var dataKey = "AutonomousBus_0"; + + // Do a test.*** + //var projectId = "3ds.json"; + //var dataKey = "GyeomjaeJeongSeon_del"; + + var node = this.hierarchyManager.getNodeByDataKey(projectId, dataKey); + node.data.isTrailRender = true; // test.*** + + var geoLocDataManager = node.getNodeGeoLocDataManager(); + var geoLocData = geoLocDataManager.getCurrentGeoLocationData(); + var geoCoords = geoLocData.getGeographicCoords(); + var currLon = geoCoords.longitude; + var currLat = geoCoords.latitude; + var currAlt = geoCoords.altitude; -/** - * Create a new mat2d with the given values - * - * @param {Number} a Component A (index 0) - * @param {Number} b Component B (index 1) - * @param {Number} c Component C (index 2) - * @param {Number} d Component D (index 3) - * @param {Number} tx Component TX (index 4) - * @param {Number} ty Component TY (index 5) - * @returns {mat2d} A new mat2d - */ -function fromValues(a, b, c, d, tx, ty) { - var out = new glMatrix.ARRAY_TYPE(6); - out[0] = a; - out[1] = b; - out[2] = c; - out[3] = d; - out[4] = tx; - out[5] = ty; - return out; -} + // Move a little.*** + var latitude = currLat + 0.001 * 10*(Math.random()*2-1); + var longitude = currLon + 0.001 * 10*(Math.random()*2-1); + var elevation = currAlt + 10.0 * 10*(Math.random()*2-1); + + latitude = currLat + 0.01; + longitude = currLon + 0.01; + elevation = currAlt; + + + var heading; + var pitch; + var roll; + var durationTimeInSeconds = 100; + this.changeLocationAndRotation(projectId, dataKey, latitude, longitude, elevation, heading, pitch, roll, durationTimeInSeconds); + } + else if (key === 84) // 84 = 't'.*** + { + // do test.*** + var excavation = this.modeler.getExcavation(); + if (excavation !== undefined) + { + excavation.makeExtrudeObject(this); + } + + var tunnel = this.modeler.getTunnel(); + if (tunnel !== undefined) + { + tunnel.getProfileGeographicCoordsList(); // executed this only to create the profile.*** TEST.*** + tunnel.makeMesh(this); + + } + + // Another test: Change color by projectId & objectId.*** + var api = new API(); + api.apiName = "changeColor"; + api.setProjectId("AutonomousBus"); + api.setDataKey("AutonomousBus_0"); + api.setObjectIds("13"); + api.setColor("220,150,20"); + this.callAPI(api); + } + else if (key === 89) // 89 = 'y'.*** + { + if (this.magoMode === undefined) + { this.magoMode = CODE.magoMode.NORMAL; } + + if (this.magoMode === CODE.magoMode.NORMAL) + { this.magoMode = CODE.magoMode.DRAWING; } + else if (this.magoMode === CODE.magoMode.DRAWING) + { + this.magoMode = CODE.magoMode.NORMAL; + this.modeler.mode = CODE.modelerMode.INACTIVE; + } + } + + +}; /** - * Set the components of a mat2d to the given values - * - * @param {mat2d} out the receiving matrix - * @param {Number} a Component A (index 0) - * @param {Number} b Component B (index 1) - * @param {Number} c Component C (index 2) - * @param {Number} d Component D (index 3) - * @param {Number} tx Component TX (index 4) - * @param {Number} ty Component TY (index 5) - * @returns {mat2d} out - */ -function set(out, a, b, c, d, tx, ty) { - out[0] = a; - out[1] = b; - out[2] = c; - out[3] = d; - out[4] = tx; - out[5] = ty; - return out; -} + * 선택 객체를 asimetric mode 로 이동 + * @param gl 변수 + * @param scene 변수 + */ +MagoManager.prototype.mouseActionLeftClick = function(mouseX, mouseY) +{ + // Note: the "mouseActionLeftClick" runs after "mouseActionLeftDown" & "mouseActionLeftUp".*** + //-------------------------------------------------------------------------------------------- + if (this.magoMode === CODE.magoMode.DRAWING)// then process to draw.***// Test code.***// Test code.*** + { + // Test code.*** + // Test code.***// Test code.***// Test code.***// Test code.***// Test code.***// Test code.***// Test code.*** + if (this.modeler === undefined) + { this.modeler = new Modeler(); } + // CODE.modelerMode = { + // "INACTIVE" : 0, + // "DRAWING_POLYLINE" : 1, + // "DRAWING_GEOGRAPHICPOINTS" : 2, + //}; + + //this.modeler.mode = CODE.modelerMode.DRAWING_GEOGRAPHICPOINTS; + //this.modeler.mode = CODE.modelerMode.DRAWING_PLANEGRID; + //this.modeler.mode = CODE.modelerMode.DRAWING_EXCAVATIONPOINTS; + //this.modeler.mode = CODE.modelerMode.DRAWING_TUNNELPOINTS; + this.modeler.mode = CODE.modelerMode.DRAWING_STATICGEOMETRY; + + // Calculate the geographicCoord of the click position.**** + var geoCoord; + var strWorldPoint; + if (this.configInformation.geo_view_library === Constant.CESIUM) + { + var camera = this.scene.frameState.camera; + var scene = this.scene; + var ray = camera.getPickRay(new Cesium.Cartesian2(mouseX, mouseY)); + strWorldPoint = scene.globe.pick(ray, scene); + } + else + { + var mouseAction = this.sceneState.mouseAction; + strWorldPoint = mouseAction.strWorldPoint; + } + geoCoord = Globe.CartesianToGeographicWgs84(strWorldPoint.x, strWorldPoint.y, strWorldPoint.z, undefined, true); + geoCoord.absolutePoint = strWorldPoint; + + var modelerMode = this.modeler.mode; + if (this.modeler.mode === CODE.modelerMode.DRAWING_PLANEGRID && this.modeler.planeGrid === undefined) + { + // Calculate the click position and create the planeGrid geoLocation.*** + this.modeler.createPlaneGrid(); + this.modeler.planeGrid.makeVbo(this.vboMemoryManager); + + if (this.modeler.planeGrid.geoLocDataManager === undefined) + { this.modeler.planeGrid.geoLocDataManager = new GeoLocationDataManager(); } + + var geoLocDataManager = this.modeler.planeGrid.geoLocDataManager; + var geoLocData = geoLocDataManager.newGeoLocationData("noName"); + geoLocData = ManagerUtils.calculateGeoLocationData(geoCoord.longitude, geoCoord.latitude, geoCoord.altitude+1, undefined, undefined, undefined, geoLocData, this); + return; + } + + // For each "click" add geographicPoint to the modeler's geographicPointsList.*** + else if (this.modeler.mode === CODE.modelerMode.DRAWING_GEOGRAPHICPOINTS) + { + var geoLocDataManager = geoCoord.getGeoLocationDataManager(); + var geoLocData = geoLocDataManager.newGeoLocationData("noName"); + geoLocData = ManagerUtils.calculateGeoLocationData(geoCoord.longitude, geoCoord.latitude, geoCoord.altitude+1, undefined, undefined, undefined, geoLocData, this); + + var geoCoordsList = this.modeler.getGeographicCoordsList(); + geoCoordsList.addGeoCoord(geoCoord); + } + + // Excavation.*** + else if (this.modeler.mode === CODE.modelerMode.DRAWING_EXCAVATIONPOINTS) + { + var geoLocDataManager = geoCoord.getGeoLocationDataManager(); + var geoLocData = geoLocDataManager.newGeoLocationData("noName"); + geoLocData = ManagerUtils.calculateGeoLocationData(geoCoord.longitude, geoCoord.latitude, geoCoord.altitude+1, undefined, undefined, undefined, geoLocData, this); + + var excavation = this.modeler.getExcavation(); + var geoCoordsList = excavation.getGeographicCoordsList(); + geoCoordsList.addGeoCoord(geoCoord); + geoCoordsList.makeLines(this); + } + + // Tunnel.*** + else if (this.modeler.mode === CODE.modelerMode.DRAWING_TUNNELPOINTS) + { + var geoLocDataManager = geoCoord.getGeoLocationDataManager(); + var geoLocData = geoLocDataManager.newGeoLocationData("noName"); + geoLocData = ManagerUtils.calculateGeoLocationData(geoCoord.longitude, geoCoord.latitude, geoCoord.altitude+1, undefined, undefined, undefined, geoLocData, this); + + var tunnel = this.modeler.getTunnel(); + var geoCoordsList = tunnel.getPathGeographicCoordsList(); + geoCoordsList.addGeoCoord(geoCoord); + geoCoordsList.makeLines(this); + } + + // StaticGeometries.*** + else if (this.modeler.mode === CODE.modelerMode.DRAWING_STATICGEOMETRY) + { + // create a "node" & insert into smartTile.*** + var projectId = "AutonomousBus"; + var attributes = { + "isPhysical" : true, + "nodeType" : "TEST", + "isReference" : true, + "projectFolderName" : "staticModels", + "buildingFolderName" : "F4D_AutonomousBus", + "heading" : 0, + "pitch" : 0, + "roll" : 0}; + /* + var attributes = { + "isPhysical" : true, + "nodeType" : "TEST", + "isReference" : true, + "projectFolderName" : "3ds", + "buildingFolderName" : "F4D_GyeomjaeJeongSeon_del", + "heading" : 0, + "pitch" : 0, + "roll" : 0}; + + attributes.pitch = 90.0; + */ + if (!this.isExistStaticModel('AutonomousBus')) + { + this.addStaticModel({ + projectId : 'AutonomousBus', + projectFolderName : 'staticModels', + buildingFolderName : 'F4D_AutonomousBus' + }); + } + + var nodesMap = this.hierarchyManager.getNodesMap(projectId, undefined); + var existentNodesCount = Object.keys(nodesMap).length; + var buildingId = "AutonomousBus_" + existentNodesCount.toString(); + + this.instantiateStaticModel({ + projectId : 'AutonomousBus', + instanceId : buildingId, + longitude : geoCoord.longitude, + latitude : geoCoord.latitude, + height : geoCoord.altitude+1 + }); + /*var geoLocDataManager = geoCoord.getGeoLocationDataManager(); + var geoLocData = geoLocDataManager.newGeoLocationData("noName"); + geoLocData = ManagerUtils.calculateGeoLocationData(geoCoord.longitude, geoCoord.latitude, geoCoord.altitude+1, attributes.heading, attributes.pitch, attributes.roll, geoLocData, this); + + // test to insert an staticGeometry AutonomousBus.*** + var staticGeometryFilePath = ""; -/** - * Inverts a mat2d - * - * @param {mat2d} out the receiving matrix - * @param {mat2d} a the source matrix - * @returns {mat2d} out - */ -function invert(out, a) { - var aa = a[0], - ab = a[1], - ac = a[2], - ad = a[3]; - var atx = a[4], - aty = a[5]; - - var det = aa * ad - ab * ac; - if (!det) { - return null; - } - det = 1.0 / det; - - out[0] = ad * det; - out[1] = -ab * det; - out[2] = -ac * det; - out[3] = aa * det; - out[4] = (ac * aty - ad * atx) * det; - out[5] = (ab * atx - aa * aty) * det; - return out; -} + var nodesMap = this.hierarchyManager.getNodesMap(projectId, undefined); + var existentNodesCount = Object.keys(nodesMap).length; + var buildingId = "AutonomousBus_" + existentNodesCount.toString(); + + // Do a test.*** + //var projectId = "3ds.json"; + //buildingId = "GyeomjaeJeongSeon_del"; + + var node = this.hierarchyManager.newNode(buildingId, projectId, undefined); + + // Now, create the geoLocdataManager of node.*** + node.data.attributes = attributes; + node.data.geographicCoord = geoCoord; + node.data.rotationsDegree = new Point3D(attributes.pitch, attributes.roll, attributes.heading); + node.data.geoLocDataManager = geoLocDataManager; + node.data.rotationsDegree.set(attributes.pitch, attributes.roll, attributes.heading); + var geoLocDataManager = node.data.geoLocDataManager; + var geoLocData = geoLocDataManager.getCurrentGeoLocationData(); + + geoLocData.setRotationHeadingPitchRoll(attributes.heading, attributes.pitch, attributes.roll); + + // Now, insert node into smartTile.*** + var targetDepth = this.smartTileManager.targetDepth; + this.smartTileManager.putNode(targetDepth, node, this);*/ + } + + } + +}; /** - * Calculates the determinant of a mat2d - * - * @param {mat2d} a the source matrix - * @returns {Number} determinant of a + * 선택 객체를 asimetric mode 로 이동 + * @param gl 변수 + * @param scene 변수 */ -function determinant(a) { - return a[0] * a[3] - a[1] * a[2]; -} +MagoManager.prototype.mouseActionLeftDown = function(mouseX, mouseY) +{ + this.dateSC = new Date(); + this.startTimeSC = this.dateSC.getTime(); -/** - * Multiplies two mat2d's - * - * @param {mat2d} out the receiving matrix - * @param {mat2d} a the first operand - * @param {mat2d} b the second operand - * @returns {mat2d} out - */ -function multiply(out, a, b) { - var a0 = a[0], - a1 = a[1], - a2 = a[2], - a3 = a[3], - a4 = a[4], - a5 = a[5]; - var b0 = b[0], - b1 = b[1], - b2 = b[2], - b3 = b[3], - b4 = b[4], - b5 = b[5]; - out[0] = a0 * b0 + a2 * b1; - out[1] = a1 * b0 + a3 * b1; - out[2] = a0 * b2 + a2 * b3; - out[3] = a1 * b2 + a3 * b3; - out[4] = a0 * b4 + a2 * b5 + a4; - out[5] = a1 * b4 + a3 * b5 + a5; - return out; -} + this.mouse_x = mouseX; + this.mouse_y = mouseY; + this.mouseLeftDown = true; + //this.isCameraMoving = true; + + MagoWorld.updateMouseStartClick(mouseX, mouseY, this); + /* + // Test.********************************************************************************************************************** + var selGeneralObjects = this.selectionManager.getSelectionCandidatesFamily("general"); + if (selGeneralObjects) + { + var currObjectSelected = selGeneralObjects.currentSelected; + if (currObjectSelected) + { + // check if is a cuttingPlane.*** + if (currObjectSelected instanceof CuttingPlane) + { + var mouseAction = this.sceneState.mouseAction; + mouseAction.claculateStartPositionsAux(this); + } + } + } + */ + // End test.------------------------------------------------------------------------------------------------------------------- +}; /** - * Rotates a mat2d by the given angle - * - * @param {mat2d} out the receiving matrix - * @param {mat2d} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat2d} out - */ -function rotate(out, a, rad) { - var a0 = a[0], - a1 = a[1], - a2 = a[2], - a3 = a[3], - a4 = a[4], - a5 = a[5]; - var s = Math.sin(rad); - var c = Math.cos(rad); - out[0] = a0 * c + a2 * s; - out[1] = a1 * c + a3 * s; - out[2] = a0 * -s + a2 * c; - out[3] = a1 * -s + a3 * c; - out[4] = a4; - out[5] = a5; - return out; -} + * 선택 객체를 asimetric mode 로 이동 + * @param gl 변수 + * @param scene 변수 + */ +MagoManager.prototype.saveHistoryObjectMovement = function(refObject, node) +{ + var changeHistory = new ChangeHistory(); + var refMove = changeHistory.getReferenceObjectAditionalMovement(); + var refMoveRelToBuilding = changeHistory.getReferenceObjectAditionalMovementRelToBuilding(); + + if (refObject.moveVector === undefined) + { refObject.moveVector = new Point3D(); } + + if (refObject.moveVectorRelToBuilding === undefined) + { refObject.moveVectorRelToBuilding = new Point3D(); } + + refMove.set(refObject.moveVector.x, refObject.moveVector.y, refObject.moveVector.z); + refMoveRelToBuilding.set(refObject.moveVectorRelToBuilding.x, refObject.moveVectorRelToBuilding.y, refObject.moveVectorRelToBuilding.z); + if (node === undefined) + { return; } -/** - * Scales the mat2d by the dimensions in the given vec2 - * - * @param {mat2d} out the receiving matrix - * @param {mat2d} a the matrix to translate - * @param {vec2} v the vec2 to scale the matrix by - * @returns {mat2d} out - **/ -function scale(out, a, v) { - var a0 = a[0], - a1 = a[1], - a2 = a[2], - a3 = a[3], - a4 = a[4], - a5 = a[5]; - var v0 = v[0], - v1 = v[1]; - out[0] = a0 * v0; - out[1] = a1 * v0; - out[2] = a2 * v1; - out[3] = a3 * v1; - out[4] = a4; - out[5] = a5; - return out; -} + var projectId = node.data.projectId; + var dataKey = node.data.nodeId; + var objectIndex = refObject._id; + + changeHistory.setProjectId(projectId); + changeHistory.setDataKey(dataKey); + changeHistory.setObjectIndexOrder(objectIndex); + MagoConfig.saveMovingHistory(projectId, dataKey, objectIndex, changeHistory); +}; -/** - * Translates the mat2d by the dimensions in the given vec2 - * - * @param {mat2d} out the receiving matrix - * @param {mat2d} a the matrix to translate - * @param {vec2} v the vec2 to translate the matrix by - * @returns {mat2d} out - **/ -function translate(out, a, v) { - var a0 = a[0], - a1 = a[1], - a2 = a[2], - a3 = a[3], - a4 = a[4], - a5 = a[5]; - var v0 = v[0], - v1 = v[1]; - out[0] = a0; - out[1] = a1; - out[2] = a2; - out[3] = a3; - out[4] = a0 * v0 + a2 * v1 + a4; - out[5] = a1 * v0 + a3 * v1 + a5; - return out; -} -/** - * Creates a matrix from a given angle - * This is equivalent to (but much faster than): - * - * mat2d.identity(dest); - * mat2d.rotate(dest, dest, rad); - * - * @param {mat2d} out mat2d receiving operation result - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat2d} out - */ -function fromRotation(out, rad) { - var s = Math.sin(rad), - c = Math.cos(rad); - out[0] = c; - out[1] = s; - out[2] = -s; - out[3] = c; - out[4] = 0; - out[5] = 0; - return out; -} /** - * Creates a matrix from a vector scaling - * This is equivalent to (but much faster than): - * - * mat2d.identity(dest); - * mat2d.scale(dest, dest, vec); - * - * @param {mat2d} out mat2d receiving operation result - * @param {vec2} v Scaling vector - * @returns {mat2d} out - */ -function fromScaling(out, v) { - out[0] = v[0]; - out[1] = 0; - out[2] = 0; - out[3] = v[1]; - out[4] = 0; - out[5] = 0; - return out; -} + * 선택 객체를 asimetric mode 로 이동 + * @param gl 변수 + * @param scene 변수 + */ +MagoManager.prototype.mouseActionMiddleDown = function(mouseX, mouseY) +{ + this.dateSC = new Date(); + this.startTimeSC = this.dateSC.getTime(); -/** - * Creates a matrix from a vector translation - * This is equivalent to (but much faster than): - * - * mat2d.identity(dest); - * mat2d.translate(dest, dest, vec); - * - * @param {mat2d} out mat2d receiving operation result - * @param {vec2} v Translation vector - * @returns {mat2d} out - */ -function fromTranslation(out, v) { - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 1; - out[4] = v[0]; - out[5] = v[1]; - return out; -} + this.mouse_x = mouseX; + this.mouse_y = mouseY; + this.mouseMiddleDown = true; + this.isCameraMoving = true; +}; /** - * Returns a string representation of a mat2d - * - * @param {mat2d} a matrix to represent as a string - * @returns {String} string representation of the matrix + * 선택 객체를 asimetric mode 로 이동 + * @param gl 변수 + * @param scene 변수 */ -function str(a) { - return 'mat2d(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + a[4] + ', ' + a[5] + ')'; -} +MagoManager.prototype.mouseActionMiddleUp = function(mouseX, mouseY) +{ + this.isCameraMoving = false; + this.mouseMiddleDown = false; + this.mouseDragging = false; + this.selObjMovePlane = undefined; + this.mustCheckIfDragging = true; + this.thereAreStartMovePoint = false; + this.setCameraMotion(false); +}; /** - * Returns Frobenius norm of a mat2d - * - * @param {mat2d} a the matrix to calculate Frobenius norm of - * @returns {Number} Frobenius norm + * 선택 객체를 asimetric mode 로 이동 + * @param gl 변수 + * @param scene 변수 */ -function frob(a) { - return Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2) + Math.pow(a[2], 2) + Math.pow(a[3], 2) + Math.pow(a[4], 2) + Math.pow(a[5], 2) + 1); -} - -/** - * Adds two mat2d's - * - * @param {mat2d} out the receiving matrix - * @param {mat2d} a the first operand - * @param {mat2d} b the second operand - * @returns {mat2d} out - */ -function add(out, a, b) { - out[0] = a[0] + b[0]; - out[1] = a[1] + b[1]; - out[2] = a[2] + b[2]; - out[3] = a[3] + b[3]; - out[4] = a[4] + b[4]; - out[5] = a[5] + b[5]; - return out; -} - -/** - * Subtracts matrix b from matrix a - * - * @param {mat2d} out the receiving matrix - * @param {mat2d} a the first operand - * @param {mat2d} b the second operand - * @returns {mat2d} out - */ -function subtract(out, a, b) { - out[0] = a[0] - b[0]; - out[1] = a[1] - b[1]; - out[2] = a[2] - b[2]; - out[3] = a[3] - b[3]; - out[4] = a[4] - b[4]; - out[5] = a[5] - b[5]; - return out; -} - -/** - * Multiply each element of the matrix by a scalar. - * - * @param {mat2d} out the receiving matrix - * @param {mat2d} a the matrix to scale - * @param {Number} b amount to scale the matrix's elements by - * @returns {mat2d} out - */ -function multiplyScalar(out, a, b) { - out[0] = a[0] * b; - out[1] = a[1] * b; - out[2] = a[2] * b; - out[3] = a[3] * b; - out[4] = a[4] * b; - out[5] = a[5] * b; - return out; -} +MagoManager.prototype.mouseActionRightDown = function(mouseX, mouseY) +{ + /* + this.dateSC = new Date(); + this.startTimeSC = this.dateSC.getTime(); -/** - * Adds two mat2d's after multiplying each element of the second operand by a scalar value. - * - * @param {mat2d} out the receiving vector - * @param {mat2d} a the first operand - * @param {mat2d} b the second operand - * @param {Number} scale the amount to scale b's elements by before adding - * @returns {mat2d} out - */ -function multiplyScalarAndAdd(out, a, b, scale) { - out[0] = a[0] + b[0] * scale; - out[1] = a[1] + b[1] * scale; - out[2] = a[2] + b[2] * scale; - out[3] = a[3] + b[3] * scale; - out[4] = a[4] + b[4] * scale; - out[5] = a[5] + b[5] * scale; - return out; -} + this.mouse_x = mouseX; + this.mouse_y = mouseY; + this.mouseRightDown = true; + this.isCameraMoving = true; + */ +}; /** - * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===) - * - * @param {mat2d} a The first matrix. - * @param {mat2d} b The second matrix. - * @returns {Boolean} True if the matrices are equal, false otherwise. + * 선택 객체를 asimetric mode 로 이동 + * @param gl 변수 + * @param scene 변수 */ -function exactEquals(a, b) { - return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5]; -} - -/** - * Returns whether or not the matrices have approximately the same elements in the same position. - * - * @param {mat2d} a The first matrix. - * @param {mat2d} b The second matrix. - * @returns {Boolean} True if the matrices are equal, false otherwise. - */ -function equals(a, b) { - var a0 = a[0], - a1 = a[1], - a2 = a[2], - a3 = a[3], - a4 = a[4], - a5 = a[5]; - var b0 = b[0], - b1 = b[1], - b2 = b[2], - b3 = b[3], - b4 = b[4], - b5 = b[5]; - return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)); -} +MagoManager.prototype.mouseActionRightUp = function(mouseX, mouseY) +{ + /* + this.isCameraMoving = false; + this.setCameraMotion(false); + */ +}; /** - * Alias for {@link mat2d.multiply} - * @function + * 선택 객체를 asimetric mode 로 이동 + * @param gl 변수 + * @param scene 변수 */ -var mul = exports.mul = multiply; +MagoManager.prototype.mouseActionMove = function(mouseX, mouseY) +{ + if (this.mouseLeftDown) + { + this.manageMouseDragging(mouseX, mouseY); + } + else if (this.mouseMiddleDown) + { + this.sceneState.camera.setDirty(true); + } + else if (this.mouseRightDown) + { + this.sceneState.camera.setDirty(true); + } + else + { + this.mouseDragging = false; + this.setCameraMotion(false); + if (this.mouseMiddleDown) + { + this.isCameraMoving = true; + } + + } +}; + /** - * Alias for {@link mat2d.subtract} - * @function + * 선택 객체를 asimetric mode 로 이동 + * @param gl 변수 + * @param scene 변수 + * @param renderables_neoRefLists_array 변수 */ -var sub = exports.sub = subtract; +MagoManager.prototype.manageMouseDragging = function(mouseX, mouseY) +{ + this.sceneState.camera.setDirty(true); + + this.mouse_x = mouseX; + this.mouse_y = mouseY; + + // distinguish 2 modes.****************************************************** + if (this.magoPolicy.objectMoveMode === CODE.moveMode.ALL) // blocks move.*** + { + if (this.buildingSelected !== undefined) + { + // 1rst, check if there are objects to move.*** + if (this.mustCheckIfDragging) + { + if (this.isDragging()) + { + this.mouseDragging = true; + this.setCameraMotion(false); + } + this.mustCheckIfDragging = false; + } + // Display geoLocationData while moving building.*** + var nodeOwner = this.buildingSelected.nodeOwner; + if (nodeOwner === undefined) + { return; } -/***/ }), -/* 7 */ -/***/ (function(module, exports, __webpack_require__) { + var geoLocDataManager = nodeOwner.data.geoLocDataManager; + if (geoLocDataManager === undefined) + { return; } -"use strict"; + var geoLocation = geoLocDataManager.getGeoLocationData(0); + if (geoLocation === undefined) + { return; } + var geographicCoords = geoLocation.geographicCoord; + if (geographicCoords === undefined) + { return; } + + movedDataCallback( MagoConfig.getPolicy().geo_callback_moveddata, + nodeOwner.data.projectId, + nodeOwner.data.nodeId, + null, + geographicCoords.latitude, + geographicCoords.longitude, + geographicCoords.altitude, + geoLocation.heading, + geoLocation.pitch, + geoLocation.roll); + + } + else + { + this.isCameraMoving = true; // if no object is selected.*** + } + } + else if (this.magoPolicy.objectMoveMode === CODE.moveMode.OBJECT) // objects move.*** + { + if (this.objectSelected !== undefined) + { + // 1rst, check if there are objects to move.*** + if (this.mustCheckIfDragging) + { + if (this.isDragging()) + { + this.mouseDragging = true; + this.setCameraMotion(false); + } + this.mustCheckIfDragging = false; + } + } + else + { + this.isCameraMoving = true; // if no object is selected.*** + } + } + else if (this.magoPolicy.objectMoveMode === CODE.moveMode.GEOGRAPHICPOINTS) + { + var currSelected = this.selectionManager.getSelectedGeneral(); + if (currSelected) + { + var className = currSelected.constructor.name; + if (className === "GeographicCoord") + { + // 1rst, check if there are objects to move.*** + if (this.mustCheckIfDragging) + { + if (this.isDragging()) + { + this.mouseDragging = true; + this.setCameraMotion(false); + } + this.mustCheckIfDragging = false; + } + } + } + } + else + { + // 1rst, check if there are objects to move.*** + if (this.mustCheckIfDragging) + { + if (this.isDragging()) + { + this.mouseDragging = true; + this.setCameraMotion(false); + } + this.mustCheckIfDragging = false; + } + } + //--------------------------------------------------------------------------------- + this.isCameraMoving = true; // test.*** + if (this.mouseDragging) + { + this.moveSelectedObjectAsimetricMode(this.sceneState.gl); + } +}; -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.sub = exports.mul = undefined; -exports.create = create; -exports.clone = clone; -exports.copy = copy; -exports.fromValues = fromValues; -exports.set = set; -exports.identity = identity; -exports.transpose = transpose; -exports.invert = invert; -exports.adjoint = adjoint; -exports.determinant = determinant; -exports.multiply = multiply; -exports.translate = translate; -exports.scale = scale; -exports.rotate = rotate; -exports.rotateX = rotateX; -exports.rotateY = rotateY; -exports.rotateZ = rotateZ; -exports.fromTranslation = fromTranslation; -exports.fromScaling = fromScaling; -exports.fromRotation = fromRotation; -exports.fromXRotation = fromXRotation; -exports.fromYRotation = fromYRotation; -exports.fromZRotation = fromZRotation; -exports.fromRotationTranslation = fromRotationTranslation; -exports.getTranslation = getTranslation; -exports.getScaling = getScaling; -exports.getRotation = getRotation; -exports.fromRotationTranslationScale = fromRotationTranslationScale; -exports.fromRotationTranslationScaleOrigin = fromRotationTranslationScaleOrigin; -exports.fromQuat = fromQuat; -exports.frustum = frustum; -exports.perspective = perspective; -exports.perspectiveFromFieldOfView = perspectiveFromFieldOfView; -exports.ortho = ortho; -exports.lookAt = lookAt; -exports.targetTo = targetTo; -exports.str = str; -exports.frob = frob; -exports.add = add; -exports.subtract = subtract; -exports.multiplyScalar = multiplyScalar; -exports.multiplyScalarAndAdd = multiplyScalarAndAdd; -exports.exactEquals = exactEquals; -exports.equals = equals; - -var _common = __webpack_require__(0); - -var glMatrix = _interopRequireWildcard(_common); - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } - -/** - * 4x4 Matrix - * @module mat4 - */ - -/** - * Creates a new identity mat4 - * - * @returns {mat4} a new 4x4 matrix - */ -function create() { - var out = new glMatrix.ARRAY_TYPE(16); - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 0; - out[4] = 0; - out[5] = 1; - out[6] = 0; - out[7] = 0; - out[8] = 0; - out[9] = 0; - out[10] = 1; - out[11] = 0; - out[12] = 0; - out[13] = 0; - out[14] = 0; - out[15] = 1; - return out; -} /** - * Creates a new mat4 initialized with values from an existing matrix - * - * @param {mat4} a matrix to clone - * @returns {mat4} a new 4x4 matrix + * Moves an object. + * @param {WebGLRenderingContext} gl WebGLRenderingContext. */ -/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. +MagoManager.prototype.moveSelectedObjectAsimetricMode = function(gl) +{ + if (this.magoPolicy.objectMoveMode === CODE.moveMode.ALL) // buildings move.*** + { + if (this.selectionManager.currentNodeSelected === undefined) + { return; } + + var geoLocDataManager = this.selectionManager.currentNodeSelected.getNodeGeoLocDataManager(); + var geoLocationData = geoLocDataManager.getCurrentGeoLocationData(); + + var mouseAction = this.sceneState.mouseAction; + + // create a XY_plane in the selected_pixel_position.*** + if (this.selObjMovePlane === undefined) + { + this.selObjMovePlane = new Plane(); + // create a local XY plane. + // find the pixel position relative to building. + var tMatrixInv = geoLocationData.getGeoLocationMatrixInv(); + var pixelPosBuildingCoord = tMatrixInv.transformPoint3D(mouseAction.strWorldPoint, pixelPosBuildingCoord); + this.selObjMovePlane.setPointAndNormal(pixelPosBuildingCoord.x, pixelPosBuildingCoord.y, pixelPosBuildingCoord.z, 0.0, 0.0, 1.0); + } -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: + if (this.lineSC === undefined) + { this.lineSC = new Line(); } + + this.lineSC = ManagerUtils.getRayWorldSpace(gl, this.mouse_x, this.mouse_y, this.lineSC, this); // rayWorldSpace.*** -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. + // transform world_ray to building_ray.*** + var camPosBuilding = new Point3D(); + var camDirBuilding = new Point3D(); + + var geoLocMatrixInv = geoLocationData.getGeoLocationMatrixInv(); + camPosBuilding = geoLocMatrixInv.transformPoint3D(this.lineSC.point, camPosBuilding); + this.pointSC = geoLocMatrixInv.rotatePoint3D(this.lineSC.direction, this.pointSC); + camDirBuilding.x = this.pointSC.x; + camDirBuilding.y = this.pointSC.y; + camDirBuilding.z = this.pointSC.z; -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ - -function clone(a) { - var out = new glMatrix.ARRAY_TYPE(16); - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - out[3] = a[3]; - out[4] = a[4]; - out[5] = a[5]; - out[6] = a[6]; - out[7] = a[7]; - out[8] = a[8]; - out[9] = a[9]; - out[10] = a[10]; - out[11] = a[11]; - out[12] = a[12]; - out[13] = a[13]; - out[14] = a[14]; - out[15] = a[15]; - return out; -} + // now, intersect building_ray with the selObjMovePlane.*** + var line = new Line(); + line.setPointAndDir(camPosBuilding.x, camPosBuilding.y, camPosBuilding.z, camDirBuilding.x, camDirBuilding.y, camDirBuilding.z); -/** - * Copy the values from one mat4 to another - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the source matrix - * @returns {mat4} out - */ -function copy(out, a) { - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - out[3] = a[3]; - out[4] = a[4]; - out[5] = a[5]; - out[6] = a[6]; - out[7] = a[7]; - out[8] = a[8]; - out[9] = a[9]; - out[10] = a[10]; - out[11] = a[11]; - out[12] = a[12]; - out[13] = a[13]; - out[14] = a[14]; - out[15] = a[15]; - return out; -} + var intersectionPoint = new Point3D(); + intersectionPoint = this.selObjMovePlane.intersectionLine(line, intersectionPoint); + intersectionPoint.set(-intersectionPoint.x, -intersectionPoint.y, -intersectionPoint.z); + + // Now, calculate the intersectionPoint in world coordinates.*** + var intersectionPointWC = new Point3D(); + intersectionPointWC = geoLocationData.geoLocMatrix.transformPoint3D(intersectionPoint, intersectionPointWC); -/** - * Create a new mat4 with the given values - * - * @param {Number} m00 Component in column 0, row 0 position (index 0) - * @param {Number} m01 Component in column 0, row 1 position (index 1) - * @param {Number} m02 Component in column 0, row 2 position (index 2) - * @param {Number} m03 Component in column 0, row 3 position (index 3) - * @param {Number} m10 Component in column 1, row 0 position (index 4) - * @param {Number} m11 Component in column 1, row 1 position (index 5) - * @param {Number} m12 Component in column 1, row 2 position (index 6) - * @param {Number} m13 Component in column 1, row 3 position (index 7) - * @param {Number} m20 Component in column 2, row 0 position (index 8) - * @param {Number} m21 Component in column 2, row 1 position (index 9) - * @param {Number} m22 Component in column 2, row 2 position (index 10) - * @param {Number} m23 Component in column 2, row 3 position (index 11) - * @param {Number} m30 Component in column 3, row 0 position (index 12) - * @param {Number} m31 Component in column 3, row 1 position (index 13) - * @param {Number} m32 Component in column 3, row 2 position (index 14) - * @param {Number} m33 Component in column 3, row 3 position (index 15) - * @returns {mat4} A new mat4 - */ -function fromValues(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) { - var out = new glMatrix.ARRAY_TYPE(16); - out[0] = m00; - out[1] = m01; - out[2] = m02; - out[3] = m03; - out[4] = m10; - out[5] = m11; - out[6] = m12; - out[7] = m13; - out[8] = m20; - out[9] = m21; - out[10] = m22; - out[11] = m23; - out[12] = m30; - out[13] = m31; - out[14] = m32; - out[15] = m33; - return out; -} + // register the movement.*** + if (!this.thereAreStartMovePoint) + { + var cartographic = ManagerUtils.pointToGeographicCoord(intersectionPointWC, cartographic, this); + this.startMovPoint.x = cartographic.longitude; + this.startMovPoint.y = cartographic.latitude; + this.thereAreStartMovePoint = true; + } + else + { + var cartographic = ManagerUtils.pointToGeographicCoord(intersectionPointWC, cartographic, this); + var difX = cartographic.longitude - this.startMovPoint.x; + var difY = cartographic.latitude - this.startMovPoint.y; -/** - * Set the components of a mat4 to the given values - * - * @param {mat4} out the receiving matrix - * @param {Number} m00 Component in column 0, row 0 position (index 0) - * @param {Number} m01 Component in column 0, row 1 position (index 1) - * @param {Number} m02 Component in column 0, row 2 position (index 2) - * @param {Number} m03 Component in column 0, row 3 position (index 3) - * @param {Number} m10 Component in column 1, row 0 position (index 4) - * @param {Number} m11 Component in column 1, row 1 position (index 5) - * @param {Number} m12 Component in column 1, row 2 position (index 6) - * @param {Number} m13 Component in column 1, row 3 position (index 7) - * @param {Number} m20 Component in column 2, row 0 position (index 8) - * @param {Number} m21 Component in column 2, row 1 position (index 9) - * @param {Number} m22 Component in column 2, row 2 position (index 10) - * @param {Number} m23 Component in column 2, row 3 position (index 11) - * @param {Number} m30 Component in column 3, row 0 position (index 12) - * @param {Number} m31 Component in column 3, row 1 position (index 13) - * @param {Number} m32 Component in column 3, row 2 position (index 14) - * @param {Number} m33 Component in column 3, row 3 position (index 15) - * @returns {mat4} out - */ -function set(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) { - out[0] = m00; - out[1] = m01; - out[2] = m02; - out[3] = m03; - out[4] = m10; - out[5] = m11; - out[6] = m12; - out[7] = m13; - out[8] = m20; - out[9] = m21; - out[10] = m22; - out[11] = m23; - out[12] = m30; - out[13] = m31; - out[14] = m32; - out[15] = m33; - return out; -} + var newLongitude = geoLocationData.geographicCoord.longitude - difX; + var newlatitude = geoLocationData.geographicCoord.latitude - difY; -/** - * Set a mat4 to the identity matrix - * - * @param {mat4} out the receiving matrix - * @returns {mat4} out - */ -function identity(out) { - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 0; - out[4] = 0; - out[5] = 1; - out[6] = 0; - out[7] = 0; - out[8] = 0; - out[9] = 0; - out[10] = 1; - out[11] = 0; - out[12] = 0; - out[13] = 0; - out[14] = 0; - out[15] = 1; - return out; -} + this.changeLocationAndRotationNode(this.selectionManager.currentNodeSelected, newlatitude, newLongitude, undefined, undefined, undefined, undefined); + this.displayLocationAndRotation(this.buildingSelected); + + this.startMovPoint.x -= difX; + this.startMovPoint.y -= difY; + } + } + else if (this.magoPolicy.objectMoveMode === CODE.moveMode.OBJECT) // objects move.*** + { + if (this.objectSelected === undefined) + { return; } -/** - * Transpose the values of a mat4 - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the source matrix - * @returns {mat4} out - */ -function transpose(out, a) { - // If we are transposing ourselves we can skip a few steps but have to cache some values - if (out === a) { - var a01 = a[1], - a02 = a[2], - a03 = a[3]; - var a12 = a[6], - a13 = a[7]; - var a23 = a[11]; + // create a XY_plane in the selected_pixel_position.*** + if (this.selObjMovePlane === undefined) + { + this.selObjMovePlane = this.calculateSelObjMovePlaneAsimetricMode(gl, this.mouse_x, this.mouse_y, this.selObjMovePlane); + } + + var geoLocDataManager = this.selectionManager.currentNodeSelected.getNodeGeoLocDataManager(); - out[1] = a[4]; - out[2] = a[8]; - out[3] = a[12]; - out[4] = a01; - out[6] = a[9]; - out[7] = a[13]; - out[8] = a02; - out[9] = a12; - out[11] = a[14]; - out[12] = a03; - out[13] = a13; - out[14] = a23; - } else { - out[0] = a[0]; - out[1] = a[4]; - out[2] = a[8]; - out[3] = a[12]; - out[4] = a[1]; - out[5] = a[5]; - out[6] = a[9]; - out[7] = a[13]; - out[8] = a[2]; - out[9] = a[6]; - out[10] = a[10]; - out[11] = a[14]; - out[12] = a[3]; - out[13] = a[7]; - out[14] = a[11]; - out[15] = a[15]; - } + // world ray = camPos + lambda*camDir.*** + if (this.lineSC === undefined) + { this.lineSC = new Line(); } + + this.lineSC = ManagerUtils.getRayWorldSpace(gl, this.mouse_x, this.mouse_y, this.lineSC, this); // rayWorldSpace.*** + var buildingGeoLocation = geoLocDataManager.getCurrentGeoLocationData(); + var camPosBuilding = new Point3D(); + var camDirBuilding = new Point3D(); + var tMatrixInv = buildingGeoLocation.getTMatrixInv(); + camPosBuilding = tMatrixInv.transformPoint3D(this.lineSC.point, camPosBuilding); + camDirBuilding = tMatrixInv.rotatePoint3D(this.lineSC.direction, camDirBuilding); + + // now, intersect building_ray with the selObjMovePlane.*** + var line = new Line(); + line.setPointAndDir(camPosBuilding.x, camPosBuilding.y, camPosBuilding.z, camDirBuilding.x, camDirBuilding.y, camDirBuilding.z);// original.*** - return out; -} + var intersectionPoint = new Point3D(); + intersectionPoint = this.selObjMovePlane.intersectionLine(line, intersectionPoint); -/** - * Inverts a mat4 - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the source matrix - * @returns {mat4} out - */ -function invert(out, a) { - var a00 = a[0], - a01 = a[1], - a02 = a[2], - a03 = a[3]; - var a10 = a[4], - a11 = a[5], - a12 = a[6], - a13 = a[7]; - var a20 = a[8], - a21 = a[9], - a22 = a[10], - a23 = a[11]; - var a30 = a[12], - a31 = a[13], - a32 = a[14], - a33 = a[15]; - - var b00 = a00 * a11 - a01 * a10; - var b01 = a00 * a12 - a02 * a10; - var b02 = a00 * a13 - a03 * a10; - var b03 = a01 * a12 - a02 * a11; - var b04 = a01 * a13 - a03 * a11; - var b05 = a02 * a13 - a03 * a12; - var b06 = a20 * a31 - a21 * a30; - var b07 = a20 * a32 - a22 * a30; - var b08 = a20 * a33 - a23 * a30; - var b09 = a21 * a32 - a22 * a31; - var b10 = a21 * a33 - a23 * a31; - var b11 = a22 * a33 - a23 * a32; - - // Calculate the determinant - var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; - - if (!det) { - return null; - } - det = 1.0 / det; - - out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; - out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det; - out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det; - out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det; - out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det; - out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det; - out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det; - out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det; - out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det; - out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det; - out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det; - out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det; - out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det; - out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det; - out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det; - out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det; - - return out; -} + //the movement of an object must multiply by buildingRotMatrix.*** + if (this.objectSelected.moveVectorRelToBuilding === undefined) + { this.objectSelected.moveVectorRelToBuilding = new Point3D(); } + + // move vector rel to building. + if (!this.thereAreStartMovePoint) + { + this.startMovPoint = intersectionPoint; + this.startMovPoint.add(-this.objectSelected.moveVectorRelToBuilding.x, -this.objectSelected.moveVectorRelToBuilding.y, -this.objectSelected.moveVectorRelToBuilding.z); + this.thereAreStartMovePoint = true; + } + else + { + var difX = intersectionPoint.x - this.startMovPoint.x; + var difY = intersectionPoint.y - this.startMovPoint.y; + var difZ = intersectionPoint.z - this.startMovPoint.z; -/** - * Calculates the adjugate of a mat4 - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the source matrix - * @returns {mat4} out - */ -function adjoint(out, a) { - var a00 = a[0], - a01 = a[1], - a02 = a[2], - a03 = a[3]; - var a10 = a[4], - a11 = a[5], - a12 = a[6], - a13 = a[7]; - var a20 = a[8], - a21 = a[9], - a22 = a[10], - a23 = a[11]; - var a30 = a[12], - a31 = a[13], - a32 = a[14], - a33 = a[15]; - - out[0] = a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22); - out[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22)); - out[2] = a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12); - out[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12)); - out[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22)); - out[5] = a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22); - out[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12)); - out[7] = a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12); - out[8] = a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21); - out[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21)); - out[10] = a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11); - out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11)); - out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21)); - out[13] = a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21); - out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11)); - out[15] = a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11); - return out; -} + this.objectSelected.moveVectorRelToBuilding.set(difX, difY, difZ); + this.objectSelected.moveVector = buildingGeoLocation.tMatrix.rotatePoint3D(this.objectSelected.moveVectorRelToBuilding, this.objectSelected.moveVector); + } + + var projectId = this.selectionManager.currentNodeSelected.data.projectId; + var data_key = this.selectionManager.currentNodeSelected.data.nodeId; + var objectIndexOrder = this.objectSelected._id; + + MagoConfig.deleteMovingHistoryObject(projectId, data_key, objectIndexOrder); + this.objectMoved = true; // this provoques that on leftMouseUp -> saveHistoryObjectMovement + + } + else if (this.magoPolicy.objectMoveMode === CODE.moveMode.GEOGRAPHICPOINTS) + { + // Move the current geographic point selected.*** + var currSelected = this.selectionManager.getSelectedGeneral(); + if (currSelected) + { + var className = currSelected.constructor.name; + if (className === "GeographicCoord") + { + var geoLocDataManager = currSelected.getGeoLocationDataManager(); + var geoLocationData = geoLocDataManager.getCurrentGeoLocationData(); + + var geoCoord; + var strWorldPoint; + if (this.configInformation.geo_view_library === Constant.CESIUM) + { + var camera = this.scene.frameState.camera; + var scene = this.scene; + var ray = camera.getPickRay(new Cesium.Cartesian2(this.mouse_x, this.mouse_y)); + strWorldPoint = scene.globe.pick(ray, scene); + geoCoord = Globe.CartesianToGeographicWgs84(strWorldPoint.x, strWorldPoint.y, strWorldPoint.z, undefined, true); + } + else + { + var mouseAction = this.sceneState.mouseAction; + strWorldPoint = mouseAction.strWorldPoint; + geoCoord = Globe.CartesianToGeographicWgs84(strWorldPoint.x, strWorldPoint.y, strWorldPoint.z, undefined, true); + } + + currSelected.setLonLatAlt(geoCoord.longitude, geoCoord.latitude, undefined); // no set altitude.*** + + var geoLocDataManager = currSelected.getGeoLocationDataManager(); + var geoLocData = geoLocDataManager.getCurrentGeoLocationData(); + geoLocData = ManagerUtils.calculateGeoLocationData(currSelected.longitude, currSelected.latitude, currSelected.altitude, undefined, undefined, undefined, geoLocData, this); + + // Now, must check the moved object's owner.*** + var owner = currSelected.owner; + if (owner) + { + // 1rst, check if is a geoCoordsList.*** + if (owner.constructor.name === "GeographicCoordsList") + { + owner.makeLines(this); + } + + var owner2 = owner.owner; + if (owner2) + { + if (owner2.constructor.name === "Excavation") + { + owner2.remakeExtrudeObject(this); + } + else if (owner2.constructor.name === "Tunnel") + { + owner2.remakeMesh(this); + } + } + } + } + } -/** - * Calculates the determinant of a mat4 - * - * @param {mat4} a the source matrix - * @returns {Number} determinant of a - */ -function determinant(a) { - var a00 = a[0], - a01 = a[1], - a02 = a[2], - a03 = a[3]; - var a10 = a[4], - a11 = a[5], - a12 = a[6], - a13 = a[7]; - var a20 = a[8], - a21 = a[9], - a22 = a[10], - a23 = a[11]; - var a30 = a[12], - a31 = a[13], - a32 = a[14], - a33 = a[15]; - - var b00 = a00 * a11 - a01 * a10; - var b01 = a00 * a12 - a02 * a10; - var b02 = a00 * a13 - a03 * a10; - var b03 = a01 * a12 - a02 * a11; - var b04 = a01 * a13 - a03 * a11; - var b05 = a02 * a13 - a03 * a12; - var b06 = a20 * a31 - a21 * a30; - var b07 = a20 * a32 - a22 * a30; - var b08 = a20 * a33 - a23 * a30; - var b09 = a21 * a32 - a22 * a31; - var b10 = a21 * a33 - a23 * a31; - var b11 = a22 * a33 - a23 * a32; - - // Calculate the determinant - return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; -} + } + else + { + if (this.weatherStation) + { + // Test. Check if there are cuttingPlanes to move.*** + var selGeneralObjects = this.selectionManager.getSelectionCandidatesFamily("general"); + if (selGeneralObjects) + { + var currObjectSelected = selGeneralObjects.currentSelected; + if (currObjectSelected) + { + // check if is a cuttingPlane.*** + if (currObjectSelected instanceof CuttingPlane) + { + // Move the cuttingPlane.*** + var geoLocDataManager = currObjectSelected.geoLocDataManager; + var geoLocationData = geoLocDataManager.getCurrentGeoLocationData(); + + var mouseAction = this.sceneState.mouseAction; + + // New Test.******************************************************* + var camRay = ManagerUtils.getRayWorldSpace(gl, this.mouse_x, this.mouse_y, undefined, this); // rayWorldSpace.*** + var strWorldPoint = mouseAction.strWorldPointAux; // original.*** + ////var strWorldPoint = mouseAction.strWorldPoint; + if (strWorldPoint) + { + var strEarthRadius = strWorldPoint.getModul(); + + var curWorldPosAux; + curWorldPosAux = this.globe.intersectionLineWgs84(camRay, curWorldPosAux, strEarthRadius); + if (curWorldPosAux) + { + var curWorldPointAux = new Point3D(curWorldPosAux[0], curWorldPosAux[1], curWorldPosAux[2]); + var curLocation = ManagerUtils.pointToGeographicCoord(curWorldPointAux, undefined, this); + var strLocation = mouseAction.strLocationAux; + var objectGeoLoc = geoLocationData.geographicCoord; + + var difLocation = new GeographicCoord(); + difLocation.setLonLatAlt(curLocation.longitude - strLocation.longitude, curLocation.latitude - strLocation.latitude, curLocation.altitude - strLocation.altitude); + var newLongitude = objectGeoLoc.longitude + difLocation.longitude; + var newlatitude = objectGeoLoc.latitude + difLocation.latitude; + + geoLocationData = ManagerUtils.calculateGeoLocationData(newLongitude, newlatitude, undefined, undefined, undefined, undefined, geoLocationData, this); + mouseAction.strLocationAux.setLonLatAlt(curLocation.longitude, curLocation.latitude, curLocation.altitude); + } + } + } + } + } + } + } +}; + +MagoManager.prototype.test_renderDepth_objectSelected = function(currObjectSelected) +{ + // Test function. Provisional.*** + // Test function. Provisional.*** + // Test function. Provisional.*** + // Test. Render depth only for the selected object.*************************** + var gl = this.sceneState.gl; + + if (this.depthFboAux === undefined) + { + this.depthFboAux = new FBO(gl, this.sceneState.drawingBufferWidth, this.sceneState.drawingBufferHeight); + } + if (this.sceneState.drawingBufferWidth[0] !== this.depthFboAux.width[0] || this.sceneState.drawingBufferHeight[0] !== this.depthFboAux.height[0]) + { + // move this to onResize.*** + this.depthFboAux.deleteObjects(gl); + this.depthFboAux = new FBO(gl, this.sceneState.drawingBufferWidth, this.sceneState.drawingBufferHeight); + } + this.depthFboAux.bind(); + + if (this.isFarestFrustum()) + { + gl.clearColor(1, 1, 1, 1); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + } + gl.disable(gl.BLEND); + + gl.frontFace(gl.CCW); + gl.enable(gl.DEPTH_TEST); + gl.depthFunc(gl.LEQUAL); + gl.enable(gl.CULL_FACE); + + // Now, renderDepth the selected object. Fix the frustumFar for adequate precision on depthPacking.*** + var shader = this.postFxShadersManager.getShader("modelRefDepth"); + shader.useProgram(); + shader.bindUniformGenerals(); + shader.enableVertexAttribArray(shader.position3_loc); + + var geoLocDataManager = currObjectSelected.geoLocDataManager; + var geoLocationData = geoLocDataManager.getCurrentGeoLocationData(); + + // test: in depth, set frustumFar = 1000000000(100M).*** + var frustumFarLoc = shader.uniformsMapGeneral.frustumFar.uniformLocation; + gl.uniform1f(frustumFarLoc, new Float32Array([100000000.0])); + + var renderType = 0; + //this.weatherStation.test_renderCuttingPlanes(this, renderType); + + geoLocationData.bindGeoLocationUniforms(gl, shader); + gl.uniform3fv(shader.aditionalMov_loc, [0.0, 0.0, 0.0]); //.*** + currObjectSelected.render(this, shader, renderType); + + + this.depthFboAux.unbind(); + // End test.------------------------------------------------------------------ +}; -/** - * Multiplies two mat4s - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the first operand - * @param {mat4} b the second operand - * @returns {mat4} out - */ -function multiply(out, a, b) { - var a00 = a[0], - a01 = a[1], - a02 = a[2], - a03 = a[3]; - var a10 = a[4], - a11 = a[5], - a12 = a[6], - a13 = a[7]; - var a20 = a[8], - a21 = a[9], - a22 = a[10], - a23 = a[11]; - var a30 = a[12], - a31 = a[13], - a32 = a[14], - a33 = a[15]; - - // Cache only the current line of the second matrix - var b0 = b[0], - b1 = b[1], - b2 = b[2], - b3 = b[3]; - out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; - out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; - out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; - out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; - - b0 = b[4];b1 = b[5];b2 = b[6];b3 = b[7]; - out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; - out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; - out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; - out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; - - b0 = b[8];b1 = b[9];b2 = b[10];b3 = b[11]; - out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; - out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; - out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; - out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; - - b0 = b[12];b1 = b[13];b2 = b[14];b3 = b[15]; - out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; - out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; - out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; - out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; - return out; -} /** - * Translate a mat4 by the given vector - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to translate - * @param {vec3} v vector to translate by - * @returns {mat4} out + * Frustum 안의 VisibleOctree 를 검색하여 currentVisibleOctreesControler 를 준비 + * + * @param {any} gl + * @param {any} scene + * @param {any} neoBuilding + * @param {VisibleObjectsController} visibleObjControlerOctrees + * @param {any} lod */ -function translate(out, a, v) { - var x = v[0], - y = v[1], - z = v[2]; - var a00 = void 0, - a01 = void 0, - a02 = void 0, - a03 = void 0; - var a10 = void 0, - a11 = void 0, - a12 = void 0, - a13 = void 0; - var a20 = void 0, - a21 = void 0, - a22 = void 0, - a23 = void 0; - - if (a === out) { - out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; - out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; - out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; - out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; - } else { - a00 = a[0];a01 = a[1];a02 = a[2];a03 = a[3]; - a10 = a[4];a11 = a[5];a12 = a[6];a13 = a[7]; - a20 = a[8];a21 = a[9];a22 = a[10];a23 = a[11]; - - out[0] = a00;out[1] = a01;out[2] = a02;out[3] = a03; - out[4] = a10;out[5] = a11;out[6] = a12;out[7] = a13; - out[8] = a20;out[9] = a21;out[10] = a22;out[11] = a23; +MagoManager.prototype.getRenderablesDetailedNeoBuildingAsimetricVersion = function(gl, node, globalVisibleObjControlerOctrees, lod) +{ + var data = node.data; + var neoBuilding = data.neoBuilding; + var currentLod = data.currentLod; + + // chaek if the neoBuilding has availableLod_0.*** + if (neoBuilding === undefined || neoBuilding.octree === undefined) { return false; } + + // Check if for the current lod, the building is modelRefType.*** + var lodBuildingData = neoBuilding.getLodBuildingData(data.currentLod); + if (lodBuildingData === undefined) + { return false; } + + if (!lodBuildingData.isModelRef) + { return true; } // return true, bcos the caller pops the building from the "visibleObjControlerNodes" if return false.*** - out[12] = a00 * x + a10 * y + a20 * z + a[12]; - out[13] = a01 * x + a11 * y + a21 * z + a[13]; - out[14] = a02 * x + a12 * y + a22 * z + a[14]; - out[15] = a03 * x + a13 * y + a23 * z + a[15]; - } + var rootGeoLocDataManager = node.getNodeGeoLocDataManager(); + var rootGeoLoc = rootGeoLocDataManager.getCurrentGeoLocationData(); + + //var nodeGeoLocation = geoLocDataManager.getCurrentGeoLocationData(); // original.*** + var nodeGeoLocation = rootGeoLocDataManager.getCurrentGeoLocationData(); + if (nodeGeoLocation === undefined) + { return false; } - return out; -} + // Create if necessary, the visibleObjectsControler of the node.*** + if (data.currentVisibleOctreesControler === undefined) + { data.currentVisibleOctreesControler = new VisibleObjectsController(); } -/** - * Scales the mat4 by the dimensions in the given vec3 not using vectorization - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to scale - * @param {vec3} v the vec3 to scale the matrix by - * @returns {mat4} out - **/ -function scale(out, a, v) { - var x = v[0], - y = v[1], - z = v[2]; - - out[0] = a[0] * x; - out[1] = a[1] * x; - out[2] = a[2] * x; - out[3] = a[3] * x; - out[4] = a[4] * y; - out[5] = a[5] * y; - out[6] = a[6] * y; - out[7] = a[7] * y; - out[8] = a[8] * z; - out[9] = a[9] * z; - out[10] = a[10] * z; - out[11] = a[11] * z; - out[12] = a[12]; - out[13] = a[13]; - out[14] = a[14]; - out[15] = a[15]; - return out; -} + var distLod0 = this.magoPolicy.getLod0DistInMeters(); + var distLod1 = this.magoPolicy.getLod1DistInMeters(); + var distLod2 = this.magoPolicy.getLod2DistInMeters(); + var distLod3 = this.magoPolicy.getLod3DistInMeters(); + var distLod4 = this.magoPolicy.getLod4DistInMeters(); + var distLod5 = this.magoPolicy.getLod5DistInMeters(); -/** - * Rotates a mat4 by the given angle around the given axis - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @param {vec3} axis the axis to rotate around - * @returns {mat4} out - */ -function rotate(out, a, rad, axis) { - var x = axis[0], - y = axis[1], - z = axis[2]; - var len = Math.sqrt(x * x + y * y + z * z); - var s = void 0, - c = void 0, - t = void 0; - var a00 = void 0, - a01 = void 0, - a02 = void 0, - a03 = void 0; - var a10 = void 0, - a11 = void 0, - a12 = void 0, - a13 = void 0; - var a20 = void 0, - a21 = void 0, - a22 = void 0, - a23 = void 0; - var b00 = void 0, - b01 = void 0, - b02 = void 0; - var b10 = void 0, - b11 = void 0, - b12 = void 0; - var b20 = void 0, - b21 = void 0, - b22 = void 0; - - if (Math.abs(len) < glMatrix.EPSILON) { - return null; - } - - len = 1 / len; - x *= len; - y *= len; - z *= len; - - s = Math.sin(rad); - c = Math.cos(rad); - t = 1 - c; - - a00 = a[0];a01 = a[1];a02 = a[2];a03 = a[3]; - a10 = a[4];a11 = a[5];a12 = a[6];a13 = a[7]; - a20 = a[8];a21 = a[9];a22 = a[10];a23 = a[11]; - - // Construct the elements of the rotation matrix - b00 = x * x * t + c;b01 = y * x * t + z * s;b02 = z * x * t - y * s; - b10 = x * y * t - z * s;b11 = y * y * t + c;b12 = z * y * t + x * s; - b20 = x * z * t + y * s;b21 = y * z * t - x * s;b22 = z * z * t + c; - - // Perform rotation-specific matrix multiplication - out[0] = a00 * b00 + a10 * b01 + a20 * b02; - out[1] = a01 * b00 + a11 * b01 + a21 * b02; - out[2] = a02 * b00 + a12 * b01 + a22 * b02; - out[3] = a03 * b00 + a13 * b01 + a23 * b02; - out[4] = a00 * b10 + a10 * b11 + a20 * b12; - out[5] = a01 * b10 + a11 * b11 + a21 * b12; - out[6] = a02 * b10 + a12 * b11 + a22 * b12; - out[7] = a03 * b10 + a13 * b11 + a23 * b12; - out[8] = a00 * b20 + a10 * b21 + a20 * b22; - out[9] = a01 * b20 + a11 * b21 + a21 * b22; - out[10] = a02 * b20 + a12 * b21 + a22 * b22; - out[11] = a03 * b20 + a13 * b21 + a23 * b22; - - if (a !== out) { - // If the source and destination differ, copy the unchanged last row - out[12] = a[12]; - out[13] = a[13]; - out[14] = a[14]; - out[15] = a[15]; - } - return out; -} + var find = false; + if (data.myCameraRelative === undefined) + { data.myCameraRelative = new Camera(); } + + data.myCameraRelative.frustum.copyParametersFrom(this.myCameraSCX.bigFrustum); + data.myCameraRelative = nodeGeoLocation.getTransformedRelativeCamera(this.sceneState.camera, data.myCameraRelative); + //var isCameraInsideOfBuilding = neoBuilding.isCameraInsideOfBuilding(data.myCameraRelative.position.x, data.myCameraRelative.position.y, data.myCameraRelative.position.z); // old.*** + + data.currentVisibleOctreesControler.clear(); + + if (lod === 2) + { + // In this case is not necessary calculate the frustum planes. + neoBuilding.octree.extractLowestOctreesByLOD(data.currentVisibleOctreesControler, globalVisibleObjControlerOctrees, this.boundingSphere_Aux, + data.myCameraRelative.position, distLod0, distLod1, distLod5); + find = true; + } + else + { + // Must calculate the frustum planes. + data.myCameraRelative.calculateFrustumsPlanes(); + + // 1rst, check if there are octrees very close. + var frustum0 = data.myCameraRelative.bigFrustum; + find = neoBuilding.octree.getFrustumVisibleLowestOctreesByLOD( frustum0, data.currentVisibleOctreesControler, globalVisibleObjControlerOctrees, this.boundingSphere_Aux, + data.myCameraRelative.position, distLod0, distLod1, distLod2*100); + } -/** - * Rotates a matrix by the given angle around the X axis - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat4} out - */ -function rotateX(out, a, rad) { - var s = Math.sin(rad); - var c = Math.cos(rad); - var a10 = a[4]; - var a11 = a[5]; - var a12 = a[6]; - var a13 = a[7]; - var a20 = a[8]; - var a21 = a[9]; - var a22 = a[10]; - var a23 = a[11]; - - if (a !== out) { - // If the source and destination differ, copy the unchanged rows - out[0] = a[0]; - out[1] = a[1]; - out[2] = a[2]; - out[3] = a[3]; - out[12] = a[12]; - out[13] = a[13]; - out[14] = a[14]; - out[15] = a[15]; - } + if (!find) + { + // If the building is far to camera, then delete it. + if (data.distToCam > 100) // default: 60.*** + { this.processQueue.putNodeToDeleteModelReferences(node, 1); } + + // TODO: must check if some part of the building is in parseQueue.*** + return false; + } + else + { + this.processQueue.eraseNodeToDeleteModelReferences(node); + } + + return true; +}; - // Perform axis-specific matrix multiplication - out[4] = a10 * c + a20 * s; - out[5] = a11 * c + a21 * s; - out[6] = a12 * c + a22 * s; - out[7] = a13 * c + a23 * s; - out[8] = a20 * c - a10 * s; - out[9] = a21 * c - a11 * s; - out[10] = a22 * c - a12 * s; - out[11] = a23 * c - a13 * s; - return out; -} /** - * Rotates a matrix by the given angle around the Y axis - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat4} out + * LOD0, LOD1 에 대한 F4D ModelData, ReferenceData 를 요청 + * + * @param {any} gl + * @param {any} scene + * @param {any} neoBuilding */ -function rotateY(out, a, rad) { - var s = Math.sin(rad); - var c = Math.cos(rad); - var a00 = a[0]; - var a01 = a[1]; - var a02 = a[2]; - var a03 = a[3]; - var a20 = a[8]; - var a21 = a[9]; - var a22 = a[10]; - var a23 = a[11]; - - if (a !== out) { - // If the source and destination differ, copy the unchanged rows - out[4] = a[4]; - out[5] = a[5]; - out[6] = a[6]; - out[7] = a[7]; - out[12] = a[12]; - out[13] = a[13]; - out[14] = a[14]; - out[15] = a[15]; - } +MagoManager.prototype.manageQueue = function() +{ + var gl = this.sceneState.gl; + + + + + // 1rst, manage deleting queue.*************** + this.processQueue.manageDeleteQueue(this); + + + + // 2nd, parse pendent data.********************************************************************************** + // is desirable to parse octrees references ordered by the current eye distance. + // in the "visibleObjControlerOctrees" there are the octrees sorted by distance, so must use it. + this.parseQueue.initCounters(); + + // parse octrees lod0 & lod1 references.*** + this.parseQueue.parseArrayOctreesLod0References(gl, this.visibleObjControlerOctrees.currentVisibles0, this); + this.parseQueue.parseArrayOctreesLod0References(gl, this.visibleObjControlerOctrees.currentVisibles1, this); + + - // Perform axis-specific matrix multiplication - out[0] = a00 * c - a20 * s; - out[1] = a01 * c - a21 * s; - out[2] = a02 * c - a22 * s; - out[3] = a03 * c - a23 * s; - out[8] = a00 * s + a20 * c; - out[9] = a01 * s + a21 * c; - out[10] = a02 * s + a22 * c; - out[11] = a03 * s + a23 * c; - return out; -} + // parse octrees lod0 & lod1 models.*** + this.parseQueue.parseArrayOctreesLod0Models(gl, this.visibleObjControlerOctrees.currentVisibles0, this); + this.parseQueue.parseArrayOctreesLod0Models(gl, this.visibleObjControlerOctrees.currentVisibles1, this); + + + + // parse octrees lod2 (lego).*** + this.parseQueue.parseArrayOctreesLod2Legos(gl, this.visibleObjControlerOctrees.currentVisibles2, this); -/** - * Rotates a matrix by the given angle around the Z axis - * - * @param {mat4} out the receiving matrix - * @param {mat4} a the matrix to rotate - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat4} out - */ -function rotateZ(out, a, rad) { - var s = Math.sin(rad); - var c = Math.cos(rad); - var a00 = a[0]; - var a01 = a[1]; - var a02 = a[2]; - var a03 = a[3]; - var a10 = a[4]; - var a11 = a[5]; - var a12 = a[6]; - var a13 = a[7]; - - if (a !== out) { - // If the source and destination differ, copy the unchanged last row - out[8] = a[8]; - out[9] = a[9]; - out[10] = a[10]; - out[11] = a[11]; - out[12] = a[12]; - out[13] = a[13]; - out[14] = a[14]; - out[15] = a[15]; - } + // parse PCloud octree.*** + this.parseQueue.parseArrayOctreesPCloud(gl, this.visibleObjControlerOctrees.currentVisiblesAux, this); + this.parseQueue.parseArrayOctreesPCloudPartition(gl, this.visibleObjControlerOctrees.currentVisiblesAux, this); - // Perform axis-specific matrix multiplication - out[0] = a00 * c + a10 * s; - out[1] = a01 * c + a11 * s; - out[2] = a02 * c + a12 * s; - out[3] = a03 * c + a13 * s; - out[4] = a10 * c - a00 * s; - out[5] = a11 * c - a01 * s; - out[6] = a12 * c - a02 * s; - out[7] = a13 * c - a03 * s; - return out; -} + // parse skin-lego.*** + this.parseQueue.parseArraySkins(gl, this.visibleObjControlerNodes.currentVisibles0, this); + this.parseQueue.parseArraySkins(gl, this.visibleObjControlerNodes.currentVisibles2, this); + this.parseQueue.parseArraySkins(gl, this.visibleObjControlerNodes.currentVisibles3, this); + + -/** - * Creates a matrix from a vector translation - * This is equivalent to (but much faster than): - * - * mat4.identity(dest); - * mat4.translate(dest, dest, vec); - * - * @param {mat4} out mat4 receiving operation result - * @param {vec3} v Translation vector - * @returns {mat4} out - */ -function fromTranslation(out, v) { - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 0; - out[4] = 0; - out[5] = 1; - out[6] = 0; - out[7] = 0; - out[8] = 0; - out[9] = 0; - out[10] = 1; - out[11] = 0; - out[12] = v[0]; - out[13] = v[1]; - out[14] = v[2]; - out[15] = 1; - return out; -} + // parse TinTerrain.*** + var tinTerrain; + var parsedsCount = 0; + for (var key in this.parseQueue.tinTerrainsToParseMap) + { + if (Object.prototype.hasOwnProperty.call(this.parseQueue.tinTerrainsToParseMap, key)) + { + var tinTerrain = this.parseQueue.tinTerrainsToParseMap[key]; + if (tinTerrain !== undefined) + { + if (this.parseQueue.eraseTinTerrainToParse(tinTerrain)) // check if is inside of the queue to parse.*** + { + tinTerrain.parseData(tinTerrain.dataArrayBuffer); + parsedsCount++; + } + } + + if (parsedsCount > 1) + { break; } + } + } + /* + var visibleTilesArray = this.tinTerrainManager.visibleTilesArray; + var visiblesTilesCount = visibleTilesArray.length; + for(var i=0; i 5) + { return; } + + var extraCount = fileRequestExtraCount; + + var currentVisibles = globalVisibleObjControlerOctrees.getAllVisibles(); + //var currentVisibles = globalVisibleObjControlerOctrees.currentVisiblesAux; -/** - * Creates a matrix from a given angle around a given axis - * This is equivalent to (but much faster than): - * - * mat4.identity(dest); - * mat4.rotate(dest, dest, rad, axis); - * - * @param {mat4} out mat4 receiving operation result - * @param {Number} rad the angle to rotate the matrix by - * @param {vec3} axis the axis to rotate around - * @returns {mat4} out - */ -function fromRotation(out, rad, axis) { - var x = axis[0], - y = axis[1], - z = axis[2]; - var len = Math.sqrt(x * x + y * y + z * z); - var s = void 0, - c = void 0, - t = void 0; - - if (Math.abs(len) < glMatrix.EPSILON) { - return null; - } - - len = 1 / len; - x *= len; - y *= len; - z *= len; - - s = Math.sin(rad); - c = Math.cos(rad); - t = 1 - c; - - // Perform rotation-specific matrix multiplication - out[0] = x * x * t + c; - out[1] = y * x * t + z * s; - out[2] = z * x * t - y * s; - out[3] = 0; - out[4] = x * y * t - z * s; - out[5] = y * y * t + c; - out[6] = z * y * t + x * s; - out[7] = 0; - out[8] = x * z * t + y * s; - out[9] = y * z * t - x * s; - out[10] = z * z * t + c; - out[11] = 0; - out[12] = 0; - out[13] = 0; - out[14] = 0; - out[15] = 1; - return out; -} + if (currentVisibles === undefined) + { return; } -/** - * Creates a matrix from the given angle around the X axis - * This is equivalent to (but much faster than): - * - * mat4.identity(dest); - * mat4.rotateX(dest, dest, rad); - * - * @param {mat4} out mat4 receiving operation result - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat4} out - */ -function fromXRotation(out, rad) { - var s = Math.sin(rad); - var c = Math.cos(rad); - - // Perform axis-specific matrix multiplication - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 0; - out[4] = 0; - out[5] = c; - out[6] = s; - out[7] = 0; - out[8] = 0; - out[9] = -s; - out[10] = c; - out[11] = 0; - out[12] = 0; - out[13] = 0; - out[14] = 0; - out[15] = 1; - return out; -} + var geometryDataPath = this.readerWriter.geometryDataPath; + var projectFolderName; + var neoBuilding; + var buildingFolderName; -/** - * Creates a matrix from the given angle around the Y axis - * This is equivalent to (but much faster than): - * - * mat4.identity(dest); - * mat4.rotateY(dest, dest, rad); - * - * @param {mat4} out mat4 receiving operation result - * @param {Number} rad the angle to rotate the matrix by - * @returns {mat4} out - */ -function fromYRotation(out, rad) { - var s = Math.sin(rad); - var c = Math.cos(rad); - - // Perform axis-specific matrix multiplication - out[0] = c; - out[1] = 0; - out[2] = -s; - out[3] = 0; - out[4] = 0; - out[5] = 1; - out[6] = 0; - out[7] = 0; - out[8] = s; - out[9] = 0; - out[10] = c; - out[11] = 0; - out[12] = 0; - out[13] = 0; - out[14] = 0; - out[15] = 1; - return out; -} + // LOD2 + // Check if the lod2lowestOctrees must load and parse data + var lowestOctree; + for (var i=0, length = currentVisibles.length; i 5) + { return; } + } + } +}; /** - * Returns the translation vector component of a transformation - * matrix. If a matrix is built with fromRotationTranslation, - * the returned vector will be the same as the translation vector - * originally supplied. - * @param {vec3} out Vector to receive translation component - * @param {mat4} mat Matrix to be decomposed (input) - * @return {vec3} out + * LOD0, LOD1 에 대한 F4D ModelData, ReferenceData 를 요청 + * + * @param {any} gl + * @param {any} scene + * @param {any} neoBuilding */ -function getTranslation(out, mat) { - out[0] = mat[12]; - out[1] = mat[13]; - out[2] = mat[14]; - - return out; -} +MagoManager.prototype.prepareVisibleOctreesSortedByDistance = function(gl, globalVisibleObjControlerOctrees) +{ + if (this.readerWriter.referencesList_requested > 5) + { return; } -/** - * Returns the scaling factor component of a transformation - * matrix. If a matrix is built with fromRotationTranslationScale - * with a normalized Quaternion paramter, the returned vector will be - * the same as the scaling vector - * originally supplied. - * @param {vec3} out Vector to receive scaling factor component - * @param {mat4} mat Matrix to be decomposed (input) - * @return {vec3} out - */ -function getScaling(out, mat) { - var m11 = mat[0]; - var m12 = mat[1]; - var m13 = mat[2]; - var m21 = mat[4]; - var m22 = mat[5]; - var m23 = mat[6]; - var m31 = mat[8]; - var m32 = mat[9]; - var m33 = mat[10]; - - out[0] = Math.sqrt(m11 * m11 + m12 * m12 + m13 * m13); - out[1] = Math.sqrt(m21 * m21 + m22 * m22 + m23 * m23); - out[2] = Math.sqrt(m31 * m31 + m32 * m32 + m33 * m33); - - return out; -} + // LOD0 & LOD1 + // Check if the lod0lowestOctrees, lod1lowestOctrees must load and parse data + var currentVisibleOctrees = [].concat(globalVisibleObjControlerOctrees.currentVisibles0, globalVisibleObjControlerOctrees.currentVisibles1); + var lowestOctree; + this.thereAreUrgentOctrees = false; -/** - * Returns a quaternion representing the rotational component - * of a transformation matrix. If a matrix is built with - * fromRotationTranslation, the returned quaternion will be the - * same as the quaternion originally supplied. - * @param {quat} out Quaternion to receive the rotation component - * @param {mat4} mat Matrix to be decomposed (input) - * @return {quat} out - */ -function getRotation(out, mat) { - // Algorithm taken from http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm - var trace = mat[0] + mat[5] + mat[10]; - var S = 0; - - if (trace > 0) { - S = Math.sqrt(trace + 1.0) * 2; - out[3] = 0.25 * S; - out[0] = (mat[6] - mat[9]) / S; - out[1] = (mat[8] - mat[2]) / S; - out[2] = (mat[1] - mat[4]) / S; - } else if (mat[0] > mat[5] & mat[0] > mat[10]) { - S = Math.sqrt(1.0 + mat[0] - mat[5] - mat[10]) * 2; - out[3] = (mat[6] - mat[9]) / S; - out[0] = 0.25 * S; - out[1] = (mat[1] + mat[4]) / S; - out[2] = (mat[8] + mat[2]) / S; - } else if (mat[5] > mat[10]) { - S = Math.sqrt(1.0 + mat[5] - mat[0] - mat[10]) * 2; - out[3] = (mat[8] - mat[2]) / S; - out[0] = (mat[1] + mat[4]) / S; - out[1] = 0.25 * S; - out[2] = (mat[6] + mat[9]) / S; - } else { - S = Math.sqrt(1.0 + mat[10] - mat[0] - mat[5]) * 2; - out[3] = (mat[1] - mat[4]) / S; - out[0] = (mat[8] + mat[2]) / S; - out[1] = (mat[6] + mat[9]) / S; - out[2] = 0.25 * S; - } + // now, prepare the ocree normally. + var maxFilesLoad = 2; + var filesLoadCounter = 0; + + for (var i=0, length = currentVisibleOctrees.length; i 5) + { return; } + + if (filesLoadCounter > maxFilesLoad) + { return; } + } + + +}; /** - * Creates a matrix from a quaternion rotation, vector translation and vector scale, rotating and scaling around the given origin - * This is equivalent to (but much faster than): - * - * mat4.identity(dest); - * mat4.translate(dest, vec); - * mat4.translate(dest, origin); - * let quatMat = mat4.create(); - * quat4.toMat4(quat, quatMat); - * mat4.multiply(dest, quatMat); - * mat4.scale(dest, scale) - * mat4.translate(dest, negativeOrigin); - * - * @param {mat4} out mat4 receiving operation result - * @param {quat4} q Rotation quaternion - * @param {vec3} v Translation vector - * @param {vec3} s Scaling vector - * @param {vec3} o The origin vector around which to scale and rotate - * @returns {mat4} out + * LOD2 에 대한 F4D LegoData 를 요청 + * + * @param {any} gl + * @param {any} scene + * @param {any} neoBuilding */ -function fromRotationTranslationScaleOrigin(out, q, v, s, o) { - // Quaternion math - var x = q[0], - y = q[1], - z = q[2], - w = q[3]; - var x2 = x + x; - var y2 = y + y; - var z2 = z + z; - - var xx = x * x2; - var xy = x * y2; - var xz = x * z2; - var yy = y * y2; - var yz = y * z2; - var zz = z * z2; - var wx = w * x2; - var wy = w * y2; - var wz = w * z2; - - var sx = s[0]; - var sy = s[1]; - var sz = s[2]; - - var ox = o[0]; - var oy = o[1]; - var oz = o[2]; - - out[0] = (1 - (yy + zz)) * sx; - out[1] = (xy + wz) * sx; - out[2] = (xz - wy) * sx; - out[3] = 0; - out[4] = (xy - wz) * sy; - out[5] = (1 - (xx + zz)) * sy; - out[6] = (yz + wx) * sy; - out[7] = 0; - out[8] = (xz + wy) * sz; - out[9] = (yz - wx) * sz; - out[10] = (1 - (xx + yy)) * sz; - out[11] = 0; - out[12] = v[0] + ox - (out[0] * ox + out[4] * oy + out[8] * oz); - out[13] = v[1] + oy - (out[1] * ox + out[5] * oy + out[9] * oz); - out[14] = v[2] + oz - (out[2] * ox + out[6] * oy + out[10] * oz); - out[15] = 1; - - return out; -} +MagoManager.prototype.prepareVisibleOctreesSortedByDistanceLOD2 = function(gl, currentVisibles) +{ + if (this.readerWriter.octreesSkinLegos_requested > 5) + { return; } -/** - * Calculates a 4x4 matrix from the given quaternion - * - * @param {mat4} out mat4 receiving operation result - * @param {quat} q Quaternion to create matrix from - * - * @returns {mat4} out - */ -function fromQuat(out, q) { - var x = q[0], - y = q[1], - z = q[2], - w = q[3]; - var x2 = x + x; - var y2 = y + y; - var z2 = z + z; - - var xx = x * x2; - var yx = y * x2; - var yy = y * y2; - var zx = z * x2; - var zy = z * y2; - var zz = z * z2; - var wx = w * x2; - var wy = w * y2; - var wz = w * z2; - - out[0] = 1 - yy - zz; - out[1] = yx + wz; - out[2] = zx - wy; - out[3] = 0; - - out[4] = yx - wz; - out[5] = 1 - xx - zz; - out[6] = zy + wx; - out[7] = 0; - - out[8] = zx + wy; - out[9] = zy - wx; - out[10] = 1 - xx - yy; - out[11] = 0; - - out[12] = 0; - out[13] = 0; - out[14] = 0; - out[15] = 1; - - return out; -} + if (currentVisibles === undefined) + { return; } -/** - * Generates a frustum matrix with the given bounds - * - * @param {mat4} out mat4 frustum matrix will be written into - * @param {Number} left Left bound of the frustum - * @param {Number} right Right bound of the frustum - * @param {Number} bottom Bottom bound of the frustum - * @param {Number} top Top bound of the frustum - * @param {Number} near Near bound of the frustum - * @param {Number} far Far bound of the frustum - * @returns {mat4} out - */ -function frustum(out, left, right, bottom, top, near, far) { - var rl = 1 / (right - left); - var tb = 1 / (top - bottom); - var nf = 1 / (near - far); - out[0] = near * 2 * rl; - out[1] = 0; - out[2] = 0; - out[3] = 0; - out[4] = 0; - out[5] = near * 2 * tb; - out[6] = 0; - out[7] = 0; - out[8] = (right + left) * rl; - out[9] = (top + bottom) * tb; - out[10] = (far + near) * nf; - out[11] = -1; - out[12] = 0; - out[13] = 0; - out[14] = far * near * 2 * nf; - out[15] = 0; - return out; -} + // LOD2 + // Check if the lod2lowestOctrees must load and parse data + var lowestOctree; + for (var i=0, length = currentVisibles.length; i 5) + { return; } + } +}; /** - * Generates a perspective projection matrix with the given field of view. - * This is primarily useful for generating projection matrices to be used - * with the still experiemental WebVR API. - * - * @param {mat4} out mat4 frustum matrix will be written into - * @param {Object} fov Object containing the following values: upDegrees, downDegrees, leftDegrees, rightDegrees - * @param {number} near Near bound of the frustum - * @param {number} far Far bound of the frustum - * @returns {mat4} out + * 어떤 일을 하고 있습니까? + * @param gl 변수 + * @param cameraPosition 카메라 입장에서 화면에 그리기 전에 객체를 그릴 필요가 있는지 유무를 판단하는 값 + * @param scene 변수 + * @param shader 변수 + * @param renderTexture 변수 + * @param ssao_idx 변수 + * @param neoRefLists_array 변수 */ -function perspectiveFromFieldOfView(out, fov, near, far) { - var upTan = Math.tan(fov.upDegrees * Math.PI / 180.0); - var downTan = Math.tan(fov.downDegrees * Math.PI / 180.0); - var leftTan = Math.tan(fov.leftDegrees * Math.PI / 180.0); - var rightTan = Math.tan(fov.rightDegrees * Math.PI / 180.0); - var xScale = 2.0 / (leftTan + rightTan); - var yScale = 2.0 / (upTan + downTan); - - out[0] = xScale; - out[1] = 0.0; - out[2] = 0.0; - out[3] = 0.0; - out[4] = 0.0; - out[5] = yScale; - out[6] = 0.0; - out[7] = 0.0; - out[8] = -((leftTan - rightTan) * xScale * 0.5); - out[9] = (upTan - downTan) * yScale * 0.5; - out[10] = far / (near - far); - out[11] = -1.0; - out[12] = 0.0; - out[13] = 0.0; - out[14] = far * near / (near - far); - out[15] = 0.0; - return out; -} -/** - * Generates a orthogonal projection matrix with the given bounds - * - * @param {mat4} out mat4 frustum matrix will be written into - * @param {number} left Left bound of the frustum - * @param {number} right Right bound of the frustum - * @param {number} bottom Bottom bound of the frustum - * @param {number} top Top bound of the frustum - * @param {number} near Near bound of the frustum - * @param {number} far Far bound of the frustum - * @returns {mat4} out - */ -function ortho(out, left, right, bottom, top, near, far) { - var lr = 1 / (left - right); - var bt = 1 / (bottom - top); - var nf = 1 / (near - far); - out[0] = -2 * lr; - out[1] = 0; - out[2] = 0; - out[3] = 0; - out[4] = 0; - out[5] = -2 * bt; - out[6] = 0; - out[7] = 0; - out[8] = 0; - out[9] = 0; - out[10] = 2 * nf; - out[11] = 0; - out[12] = (left + right) * lr; - out[13] = (top + bottom) * bt; - out[14] = (far + near) * nf; - out[15] = 1; - return out; -} +MagoManager.prototype.checkChangesHistoryMovements = function(nodesArray) +{ + var nodesCount = nodesArray.length; + var node; + var rootNode; + var projectId; + var dataKey; + var moveHistoryMap; + var colorChangedHistoryMap; + var objectIndexOrder; + var neoBuilding; + var refObject; + var moveVector; + var moveVectorRelToBuilding; + var geoLocdataManager; + var geoLoc; + + // check movement of objects. + for (var i=0; i 0) { - len = 1 / Math.sqrt(len); - z0 *= len; - z1 *= len; - z2 *= len; - } - var x0 = upy * z2 - upz * z1, - x1 = upz * z0 - upx * z2, - x2 = upx * z1 - upy * z0; +MagoManager.prototype.checkChangesHistoryColors = function(nodesArray) +{ + var nodesCount = nodesArray.length; + var node; + var rootNode; + var projectId; + var dataKey; + var moveHistoryMap; + var colorChangedHistoryMap; + var objectIndexOrder; + var neoBuilding; + var refObject; + + // check movement of objects. + for (var i=0; i= 0 && screenCoord.y >= 0) + { + ctx.font = "13px Arial"; + ctx.strokeText(cctv.name, screenCoord.x, screenCoord.y); + ctx.fillText(cctv.name, screenCoord.x, screenCoord.y); + } + + } -/** - * Returns whether or not the matrices have approximately the same elements in the same position. - * - * @param {mat4} a The first matrix. - * @param {mat4} b The second matrix. - * @returns {Boolean} True if the matrices are equal, false otherwise. - */ -function equals(a, b) { - var a0 = a[0], - a1 = a[1], - a2 = a[2], - a3 = a[3]; - var a4 = a[4], - a5 = a[5], - a6 = a[6], - a7 = a[7]; - var a8 = a[8], - a9 = a[9], - a10 = a[10], - a11 = a[11]; - var a12 = a[12], - a13 = a[13], - a14 = a[14], - a15 = a[15]; - - var b0 = b[0], - b1 = b[1], - b2 = b[2], - b3 = b[3]; - var b4 = b[4], - b5 = b[5], - b6 = b[6], - b7 = b[7]; - var b8 = b[8], - b9 = b[9], - b10 = b[10], - b11 = b[11]; - var b12 = b[12], - b13 = b[13], - b14 = b[14], - b15 = b[15]; - - return Math.abs(a0 - b0) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8)) && Math.abs(a9 - b9) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a9), Math.abs(b9)) && Math.abs(a10 - b10) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a10), Math.abs(b10)) && Math.abs(a11 - b11) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a11), Math.abs(b11)) && Math.abs(a12 - b12) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a12), Math.abs(b12)) && Math.abs(a13 - b13) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a13), Math.abs(b13)) && Math.abs(a14 - b14) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a14), Math.abs(b14)) && Math.abs(a15 - b15) <= glMatrix.EPSILON * Math.max(1.0, Math.abs(a15), Math.abs(b15)); -} + ctx.restore(); +}; -/** - * Alias for {@link mat4.multiply} - * @function - */ -var mul = exports.mul = multiply; /** - * Alias for {@link mat4.subtract} - * @function + * 어떤 일을 하고 있습니까? + * @param gl 변수 */ -var sub = exports.sub = subtract; - -/***/ }), -/* 8 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - +MagoManager.prototype.createDefaultShaders = function(gl) +{ + // here creates the necessary shaders for mago3d.*** + // 1) ModelReferences ssaoShader.****************************************************************************** + var shaderName = "modelRefSsao"; + var shader = this.postFxShadersManager.newShader(shaderName); + var ssao_vs_source = ShaderSource.ModelRefSsaoVS; + var ssao_fs_source = ShaderSource.ModelRefSsaoFS; -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.setAxes = exports.sqlerp = exports.rotationTo = exports.equals = exports.exactEquals = exports.normalize = exports.sqrLen = exports.squaredLength = exports.len = exports.length = exports.lerp = exports.dot = exports.scale = exports.mul = exports.add = exports.set = exports.copy = exports.fromValues = exports.clone = undefined; -exports.create = create; -exports.identity = identity; -exports.setAxisAngle = setAxisAngle; -exports.getAxisAngle = getAxisAngle; -exports.multiply = multiply; -exports.rotateX = rotateX; -exports.rotateY = rotateY; -exports.rotateZ = rotateZ; -exports.calculateW = calculateW; -exports.slerp = slerp; -exports.invert = invert; -exports.conjugate = conjugate; -exports.fromMat3 = fromMat3; -exports.fromEuler = fromEuler; -exports.str = str; + shader.program = gl.createProgram(); + shader.shader_vertex = this.postFxShadersManager.createShader(gl, ssao_vs_source, gl.VERTEX_SHADER, "VERTEX"); + shader.shader_fragment = this.postFxShadersManager.createShader(gl, ssao_fs_source, gl.FRAGMENT_SHADER, "FRAGMENT"); -var _common = __webpack_require__(0); + gl.attachShader(shader.program, shader.shader_vertex); + gl.attachShader(shader.program, shader.shader_fragment); + gl.linkProgram(shader.program); + + shader.createUniformGenerals(gl, shader, this.sceneState); + shader.createUniformLocals(gl, shader, this.sceneState); + + // 1.1) ModelReferences depthShader.****************************************************************************** + var shaderName = "modelRefDepth"; + var shader = this.postFxShadersManager.newShader(shaderName); + var showDepth_vs_source = ShaderSource.RenderShowDepthVS; + var showDepth_fs_source = ShaderSource.RenderShowDepthFS; -var glMatrix = _interopRequireWildcard(_common); + shader.program = gl.createProgram(); + shader.shader_vertex = this.postFxShadersManager.createShader(gl, showDepth_vs_source, gl.VERTEX_SHADER, "VERTEX"); + shader.shader_fragment = this.postFxShadersManager.createShader(gl, showDepth_fs_source, gl.FRAGMENT_SHADER, "FRAGMENT"); + gl.attachShader(shader.program, shader.shader_vertex); + gl.attachShader(shader.program, shader.shader_fragment); + gl.linkProgram(shader.program); + + shader.createUniformGenerals(gl, shader, this.sceneState); + shader.createUniformLocals(gl, shader, this.sceneState); + + // 2) ModelReferences colorCoding shader.*********************************************************************** + var shaderName = "modelRefColorCoding"; + var shader = this.postFxShadersManager.newShader(shaderName); + var showDepth_vs_source = ShaderSource.ColorSelectionSsaoVS; + var showDepth_fs_source = ShaderSource.ColorSelectionSsaoFS; -var _mat = __webpack_require__(1); + shader.program = gl.createProgram(); + shader.shader_vertex = this.postFxShadersManager.createShader(gl, showDepth_vs_source, gl.VERTEX_SHADER, "VERTEX"); + shader.shader_fragment = this.postFxShadersManager.createShader(gl, showDepth_fs_source, gl.FRAGMENT_SHADER, "FRAGMENT"); + gl.attachShader(shader.program, shader.shader_vertex); + gl.attachShader(shader.program, shader.shader_fragment); + gl.linkProgram(shader.program); + + shader.createUniformGenerals(gl, shader, this.sceneState); + shader.createUniformLocals(gl, shader, this.sceneState); + + // 3) TinTerrain shader.**************************************************************************************** + shaderName = "tinTerrain"; + shader = this.postFxShadersManager.newShader(shaderName); + ssao_vs_source = ShaderSource.TinTerrainVS; + ssao_fs_source = ShaderSource.TinTerrainFS; + + shader.program = gl.createProgram(); + shader.shader_vertex = this.postFxShadersManager.createShader(gl, ssao_vs_source, gl.VERTEX_SHADER, "VERTEX"); + shader.shader_fragment = this.postFxShadersManager.createShader(gl, ssao_fs_source, gl.FRAGMENT_SHADER, "FRAGMENT"); -var mat3 = _interopRequireWildcard(_mat); + gl.attachShader(shader.program, shader.shader_vertex); + gl.attachShader(shader.program, shader.shader_fragment); + gl.linkProgram(shader.program); + + shader.createUniformGenerals(gl, shader, this.sceneState); + shader.createUniformLocals(gl, shader, this.sceneState); + shader.bIsMakingDepth_loc = gl.getUniformLocation(shader.program, "bIsMakingDepth"); + + // 4) PointsCloud shader.**************************************************************************************** + shaderName = "pointsCloud"; + shader = this.postFxShadersManager.newShader(shaderName); + ssao_vs_source = ShaderSource.PointCloudVS; + ssao_fs_source = ShaderSource.PointCloudFS; + + shader.program = gl.createProgram(); + shader.shader_vertex = this.postFxShadersManager.createShader(gl, ssao_vs_source, gl.VERTEX_SHADER, "VERTEX"); + shader.shader_fragment = this.postFxShadersManager.createShader(gl, ssao_fs_source, gl.FRAGMENT_SHADER, "FRAGMENT"); -var _vec = __webpack_require__(2); + gl.attachShader(shader.program, shader.shader_vertex); + gl.attachShader(shader.program, shader.shader_fragment); + gl.linkProgram(shader.program); + + shader.createUniformGenerals(gl, shader, this.sceneState); + shader.createUniformLocals(gl, shader, this.sceneState); + + // pointsCloud shader locals.*** + shader.bPositionCompressed_loc = gl.getUniformLocation(shader.program, "bPositionCompressed"); + shader.minPosition_loc = gl.getUniformLocation(shader.program, "minPosition"); + shader.bboxSize_loc = gl.getUniformLocation(shader.program, "bboxSize"); + + // 5) Test Quad shader.**************************************************************************************** + shaderName = "testQuad"; // used by temperatura layer.*** + shader = this.postFxShadersManager.newShader(shaderName); + ssao_vs_source = ShaderSource.Test_QuadVS; + ssao_fs_source = ShaderSource.Test_QuadFS; + + shader.program = gl.createProgram(); + shader.shader_vertex = this.postFxShadersManager.createShader(gl, ssao_vs_source, gl.VERTEX_SHADER, "VERTEX"); + shader.shader_fragment = this.postFxShadersManager.createShader(gl, ssao_fs_source, gl.FRAGMENT_SHADER, "FRAGMENT"); -var vec3 = _interopRequireWildcard(_vec); + gl.attachShader(shader.program, shader.shader_vertex); + gl.attachShader(shader.program, shader.shader_fragment); + gl.linkProgram(shader.program); + + shader.createUniformGenerals(gl, shader, this.sceneState); + shader.createUniformLocals(gl, shader, this.sceneState); + + // 6) Filter silhouette shader.************************************************************************************* + shaderName = "filterSilhouette"; + shader = this.postFxShadersManager.newShader(shaderName); + ssao_vs_source = ShaderSource.wgs84_volumVS; // simple screen quad v-shader.*** + ssao_fs_source = ShaderSource.filterSilhouetteFS; + + shader.program = gl.createProgram(); + shader.shader_vertex = this.postFxShadersManager.createShader(gl, ssao_vs_source, gl.VERTEX_SHADER, "VERTEX"); + shader.shader_fragment = this.postFxShadersManager.createShader(gl, ssao_fs_source, gl.FRAGMENT_SHADER, "FRAGMENT"); -var _vec2 = __webpack_require__(3); + gl.attachShader(shader.program, shader.shader_vertex); + gl.attachShader(shader.program, shader.shader_fragment); + gl.linkProgram(shader.program); + + shader.createUniformGenerals(gl, shader, this.sceneState); + shader.createUniformLocals(gl, shader, this.sceneState); + + // 7) PointsCloud Depth shader.**************************************************************************************** + shaderName = "pointsCloudDepth"; + shader = this.postFxShadersManager.newShader(shaderName); + ssao_vs_source = ShaderSource.PointCloudDepthVS; + ssao_fs_source = ShaderSource.RenderShowDepthFS; + + shader.program = gl.createProgram(); + shader.shader_vertex = this.postFxShadersManager.createShader(gl, ssao_vs_source, gl.VERTEX_SHADER, "VERTEX"); + shader.shader_fragment = this.postFxShadersManager.createShader(gl, ssao_fs_source, gl.FRAGMENT_SHADER, "FRAGMENT"); -var vec4 = _interopRequireWildcard(_vec2); + gl.attachShader(shader.program, shader.shader_vertex); + gl.attachShader(shader.program, shader.shader_fragment); + gl.linkProgram(shader.program); + + shader.createUniformGenerals(gl, shader, this.sceneState); + shader.createUniformLocals(gl, shader, this.sceneState); + + // pointsCloud shader locals.*** + shader.bPositionCompressed_loc = gl.getUniformLocation(shader.program, "bPositionCompressed"); + shader.minPosition_loc = gl.getUniformLocation(shader.program, "minPosition"); + shader.bboxSize_loc = gl.getUniformLocation(shader.program, "bboxSize"); + + // 8) PointsCloud shader.**************************************************************************************** + shaderName = "pointsCloudSsao"; + shader = this.postFxShadersManager.newShader(shaderName); + ssao_vs_source = ShaderSource.PointCloudVS; + ssao_fs_source = ShaderSource.PointCloudSsaoFS; + + shader.program = gl.createProgram(); + shader.shader_vertex = this.postFxShadersManager.createShader(gl, ssao_vs_source, gl.VERTEX_SHADER, "VERTEX"); + shader.shader_fragment = this.postFxShadersManager.createShader(gl, ssao_fs_source, gl.FRAGMENT_SHADER, "FRAGMENT"); -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + gl.attachShader(shader.program, shader.shader_vertex); + gl.attachShader(shader.program, shader.shader_fragment); + gl.linkProgram(shader.program); + + shader.createUniformGenerals(gl, shader, this.sceneState); + shader.createUniformLocals(gl, shader, this.sceneState); + + // pointsCloud shader locals.*** + shader.bPositionCompressed_loc = gl.getUniformLocation(shader.program, "bPositionCompressed"); + shader.minPosition_loc = gl.getUniformLocation(shader.program, "minPosition"); + shader.bboxSize_loc = gl.getUniformLocation(shader.program, "bboxSize"); +}; /** - * Quaternion - * @module quat + * 카메라 영역에 벗어난 오브젝트의 렌더링은 비 활성화 */ +MagoManager.prototype.isFarestFrustum = function() +{ + if (this.numFrustums - this.currentFrustumIdx - 1 === 0) + { return true; } + else + { return false; } +}; /** - * Creates a new identity quat - * - * @returns {quat} a new quaternion + * 카메라 영역에 벗어난 오브젝트의 렌더링은 비 활성화 + * + * @param frustumVolume 변수 + * @param cameraPosition 변수 */ -/* Copyright (c) 2015, Brandon Jones, Colin MacKenzie IV. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ - -function create() { - var out = new glMatrix.ARRAY_TYPE(4); - out[0] = 0; - out[1] = 0; - out[2] = 0; - out[3] = 1; - return out; -} +MagoManager.prototype.doMultiFrustumCullingSmartTiles = function(camera) +{ + // Here uses a frustum that is the sum of all frustums.*** + var frustumVolume = this.myCameraSCX.bigFrustum; + + // This makes the visible buildings array. + var smartTile1 = this.smartTileManager.tilesArray[0]; // America side tile. + var smartTile2 = this.smartTileManager.tilesArray[1]; // Asia side tile. + + if (this.frustumVolumeControl === undefined) + { this.frustumVolumeControl = new FrustumVolumeControl(); } + + if (this.fullyIntersectedLowestTilesArray === undefined) + { this.fullyIntersectedLowestTilesArray = []; } -/** - * Set a quat to the identity quaternion - * - * @param {quat} out the receiving quaternion - * @returns {quat} out - */ -function identity(out) { - out[0] = 0; - out[1] = 0; - out[2] = 0; - out[3] = 1; - return out; -} - -/** - * Sets a quat from the given angle and rotation axis, - * then returns it. - * - * @param {quat} out the receiving quaternion - * @param {vec3} axis the axis around which to rotate - * @param {Number} rad the angle in radians - * @returns {quat} out - **/ -function setAxisAngle(out, axis, rad) { - rad = rad * 0.5; - var s = Math.sin(rad); - out[0] = s * axis[0]; - out[1] = s * axis[1]; - out[2] = s * axis[2]; - out[3] = Math.cos(rad); - return out; -} - -/** - * Gets the rotation axis and angle for a given - * quaternion. If a quaternion is created with - * setAxisAngle, this method will return the same - * values as providied in the original parameter list - * OR functionally equivalent values. - * Example: The quaternion formed by axis [0, 0, 1] and - * angle -90 is the same as the quaternion formed by - * [0, 0, 1] and 270. This method favors the latter. - * @param {vec3} out_axis Vector receiving the axis of rotation - * @param {quat} q Quaternion to be decomposed - * @return {Number} Angle, in radians, of the rotation - */ -function getAxisAngle(out_axis, q) { - var rad = Math.acos(q[3]) * 2.0; - var s = Math.sin(rad / 2.0); - if (s != 0.0) { - out_axis[0] = q[0] / s; - out_axis[1] = q[1] / s; - out_axis[2] = q[2] / s; - } else { - // If s is zero, return any axis (no rotation - axis does not matter) - out_axis[0] = 1; - out_axis[1] = 0; - out_axis[2] = 0; - } - return rad; -} - -/** - * Multiplies two quat's - * - * @param {quat} out the receiving quaternion - * @param {quat} a the first operand - * @param {quat} b the second operand - * @returns {quat} out - */ -function multiply(out, a, b) { - var ax = a[0], - ay = a[1], - az = a[2], - aw = a[3]; - var bx = b[0], - by = b[1], - bz = b[2], - bw = b[3]; - - out[0] = ax * bw + aw * bx + ay * bz - az * by; - out[1] = ay * bw + aw * by + az * bx - ax * bz; - out[2] = az * bw + aw * bz + ax * by - ay * bx; - out[3] = aw * bw - ax * bx - ay * by - az * bz; - return out; -} + if (this.partiallyIntersectedLowestTilesArray === undefined) + { this.partiallyIntersectedLowestTilesArray = []; } + + if (this.lastIntersectedLowestTilesArray === undefined) + { this.lastIntersectedLowestTilesArray = []; } + + // save the last frustumCulled lowestTiles to delete if necessary. + this.lastIntersectedLowestTilesArray.push.apply(this.lastIntersectedLowestTilesArray, this.fullyIntersectedLowestTilesArray); + this.lastIntersectedLowestTilesArray.push.apply(this.lastIntersectedLowestTilesArray, this.partiallyIntersectedLowestTilesArray); + + // mark all last_tiles as "no visible". + var lastLowestTilesCount = this.lastIntersectedLowestTilesArray.length; + var lowestTile; + for (var i=0; i= 0 ; j--) + { + frustum = this.myCameraSCX.frustumsArray[j]; + if (frustum.intersectionNearFarSphere(lowestTile.sphereExtent) !== Constant.INTERSECTION_OUTSIDE) + { + var frustumVolumeControlObject = this.frustumVolumeControl.getFrustumVolumeCulling(j); + frustumVolumeControlObject.fullyIntersectedLowestTilesArray.push(lowestTile); + //break; + } + } + } + + currentLowestTilesCount = this.partiallyIntersectedLowestTilesArray.length; + for (var i=0; i= 0 ; j--) + { + frustum = this.myCameraSCX.frustumsArray[j]; + if (frustum.intersectionNearFarSphere(lowestTile.sphereExtent) !== Constant.INTERSECTION_OUTSIDE) + { + var frustumVolumeControlObject = this.frustumVolumeControl.getFrustumVolumeCulling(j); + frustumVolumeControlObject.partiallyIntersectedLowestTilesArray.push(lowestTile); + //break; + } + } + } + + // Now, delete all tiles that is no visible in the all frustumVolumes.*** + // Put to deleting queue.*** + var lastLowestTilesCount = this.lastIntersectedLowestTilesArray.length; + var lowestTile; + for (var i=0; i Number(lod5_minDist)) + { continue; } -/** - * Calculates the W component of a quat from the X, Y, and Z components. - * Assumes that quaternion is 1 unit in length. - * Any existing W component will be ignored. - * - * @param {quat} out the receiving quaternion - * @param {quat} a quat to calculate W component of - * @returns {quat} out - */ -function calculateW(out, a) { - var x = a[0], - y = a[1], - z = a[2]; - - out[0] = x; - out[1] = y; - out[2] = z; - out[3] = Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z)); - return out; -} + if (lowestTile.nodesArray && lowestTile.nodesArray.length > 0) + { + // the neoBuildings are made. + var nodesCount = lowestTile.nodesArray.length; + for (var j=0; j 0.000001) { - // standard case (slerp) - omega = Math.acos(cosom); - sinom = Math.sin(omega); - scale0 = Math.sin((1.0 - t) * omega) / sinom; - scale1 = Math.sin(t * omega) / sinom; - } else { - // "from" and "to" quaternions are very close - // ... so we can do a linear interpolation - scale0 = 1.0 - t; - scale1 = t; - } - // calculate final values - out[0] = scale0 * ax + scale1 * bx; - out[1] = scale0 * ay + scale1 * by; - out[2] = scale0 * az + scale1 * bz; - out[3] = scale0 * aw + scale1 * bw; - - return out; -} + // now, create a geoLocDataManager for node if no exist. + if (nodeRoot.data.geoLocDataManager === undefined) + { + geoLoc = node.calculateGeoLocData(this); + continue; + } + neoBuilding = node.data.neoBuilding; + + if (neoBuilding === undefined) + { + // This node is a reference node.*** + visibleNodes.currentVisiblesAux.push(node); + continue; + } + + if (this.boundingSphere_Aux === undefined) + { this.boundingSphere_Aux = new Sphere(); } + + distToCamera = node.getDistToCamera(cameraPosition, this.boundingSphere_Aux); + + var data = node.data; + data.currentLod; + data.distToCam = distToCamera; + + + if (data.distToCam < lod0Dist) + { data.currentLod = 0; } + else if (data.distToCam < lod1Dist) + { data.currentLod = 1; } + else if (data.distToCam < lod2Dist) + { data.currentLod = 2; } + else if (data.distToCam < lod3Dist) + { data.currentLod = 3; } + else if (data.distToCam < lod4Dist) + { data.currentLod = 4; } + else if (data.distToCam < lod5Dist) + { data.currentLod = 5; } + + var frustumFar = magoPolicy.getFrustumFarDistance(); + if (distToCamera > frustumFar) + { + // put this node to delete into queue.*** + this.processQueue.putNodeToDelete(node, 0); + continue; + } + + + + // If necessary do frustum culling.************************************************************************* + if (doFrustumCullingToBuildings) + { + var frustumCull = frustumVolume.intersectionSphere(this.boundingSphere_Aux); // cesium.*** + // intersect with Frustum + if (frustumCull === Constant.INTERSECTION_OUTSIDE) + { + // put this node to delete into queue.*** + //this.processQueue.putNodeToDeleteModelReferences(node, 0); + this.processQueue.putNodeToDeleteLessThanLod3(node, 0); + continue; + } + } + + + //------------------------------------------------------------------------------------------- + + + + // provisionally fork versions.*** + var version = neoBuilding.getHeaderVersion(); + if (version === undefined) + { continue; } + + if (version[0] === 'v') + { + if (distToCamera < lod0_minDist) + { + visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles0, node); + } + else if (distToCamera < lod1_minDist) + { + visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles1, node); + } + else if (distToCamera < lod2_minDist) + { + visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles2, node); + } + else if (distToCamera < lod5_minDist) + { + visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles3, node); + } + } + else + { + // provisional test for pointsCloud data.************ + var metaData = neoBuilding.metaData; + var projectsType = metaData.projectDataType; + if (projectsType && (projectsType === 4 || projectsType === 5)) + { + // Project_data_type (new in version 002).*** + // 1 = 3d model data type (normal 3d with interior & exterior data).*** + // 2 = single building skin data type (as vWorld or googleEarth data).*** + // 3 = multi building skin data type (as Shibuya & Odaiba data).*** + // 4 = pointsCloud data type.*** + visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisiblesAux, node); + } + // end provisional test.----------------------------- + else + { + if (distToCamera < lod0_minDist) + { + // check if the lod0, lod1, lod2 are modelReference type.*** + var lodBuildingData = neoBuilding.getLodBuildingData(0); + if (lodBuildingData && lodBuildingData.isModelRef) + { + visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles0, node); + } + else + { + //visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles3, node); + visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles0, node); + } + } + else if (distToCamera < lod1_minDist) + { + var lodBuildingData = neoBuilding.getLodBuildingData(1); + if (lodBuildingData && lodBuildingData.isModelRef) + { + visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles1, node); + } + else + { + //visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles3, node); + visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles1, node); + } + } + else if (distToCamera < lod2_minDist) + { + var lodBuildingData = neoBuilding.getLodBuildingData(2); + if (lodBuildingData && lodBuildingData.isModelRef) + { + visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles2, node); + } + else + { + visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles3, node); + } + } + else if (distToCamera < lod5_minDist) + { + visibleNodes.putNodeToArraySortedByDist(visibleNodes.currentVisibles3, node); + } + } + } + } + + if (lowestTile.nodesArray.length !== lowestTile.nodeSeedsArray.length) + { + // create the buildings by buildingSeeds. + this.createBuildingsByBuildingSeedsOnLowestTile(lowestTile); + + } + + + } + else + { + // create the buildings by buildingSeeds. + this.createBuildingsByBuildingSeedsOnLowestTile(lowestTile); + + } + + + } + +}; -/** - * Calculates the inverse of a quat - * - * @param {quat} out the receiving quaternion - * @param {quat} a quat to calculate inverse of - * @returns {quat} out - */ -function invert(out, a) { - var a0 = a[0], - a1 = a[1], - a2 = a[2], - a3 = a[3]; - var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3; - var invDot = dot ? 1.0 / dot : 0; - - // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0 - - out[0] = -a0 * invDot; - out[1] = -a1 * invDot; - out[2] = -a2 * invDot; - out[3] = a3 * invDot; - return out; -} /** - * Calculates the conjugate of a quat - * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result. - * - * @param {quat} out the receiving quaternion - * @param {quat} a quat to calculate conjugate of - * @returns {quat} out - */ -function conjugate(out, a) { - out[0] = -a[0]; - out[1] = -a[1]; - out[2] = -a[2]; - out[3] = a[3]; - return out; -} + */ +MagoManager.prototype.createBuildingsByBuildingSeedsOnLowestTile = function(lowestTile) +{ + // create the buildings by buildingSeeds. + var node; + var neoBuilding; + var nodeBbox; + var buildingSeed; + var startIndex = 0; + + // if exist nodesArray (there are buildings) and add a nodeSeed, we must make nodes of the added nodeSeeds.*** + if (lowestTile.nodesArray) + { startIndex = lowestTile.nodesArray.length; } -/** - * Creates a quaternion from the given 3x3 rotation matrix. - * - * NOTE: The resultant quaternion is not normalized, so you should be sure - * to renormalize the quaternion yourself where necessary. - * - * @param {quat} out the receiving quaternion - * @param {mat3} m rotation matrix - * @returns {quat} out - * @function - */ -function fromMat3(out, m) { - // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes - // article "Quaternion Calculus and Fast Animation". - var fTrace = m[0] + m[4] + m[8]; - var fRoot = void 0; - - if (fTrace > 0.0) { - // |w| > 1/2, may as well choose w > 1/2 - fRoot = Math.sqrt(fTrace + 1.0); // 2w - out[3] = 0.5 * fRoot; - fRoot = 0.5 / fRoot; // 1/(4w) - out[0] = (m[5] - m[7]) * fRoot; - out[1] = (m[6] - m[2]) * fRoot; - out[2] = (m[1] - m[3]) * fRoot; - } else { - // |w| <= 1/2 - var i = 0; - if (m[4] > m[0]) i = 1; - if (m[8] > m[i * 3 + i]) i = 2; - var j = (i + 1) % 3; - var k = (i + 2) % 3; + if (lowestTile.nodesArray === undefined) + { lowestTile.nodesArray = []; } + + var nodeSeedsCount = lowestTile.nodeSeedsArray.length; + for (var j=startIndex; j 0.999999) { - out[0] = 0; - out[1] = 0; - out[2] = 0; - out[3] = 1; - return out; - } else { - vec3.cross(tmpvec3, a, b); - out[0] = tmpvec3[0]; - out[1] = tmpvec3[1]; - out[2] = tmpvec3[2]; - out[3] = 1 + dot; - return normalize(out, out); - } - }; -}(); - -/** - * Performs a spherical linear interpolation with two control points - * - * @param {quat} out the receiving quaternion - * @param {quat} a the first operand - * @param {quat} b the second operand - * @param {quat} c the third operand - * @param {quat} d the fourth operand - * @param {Number} t interpolation amount - * @returns {quat} out - */ -var sqlerp = exports.sqlerp = function () { - var temp1 = create(); - var temp2 = create(); - - return function (out, a, b, c, d, t) { - slerp(temp1, a, d, t); - slerp(temp2, b, c, t); - slerp(out, temp1, temp2, 2 * t * (1 - t)); +MagoManager.prototype.getObjectIndexFile_xxxx = function() +{ + if (this.configInformation === undefined) + { + this.configInformation = MagoConfig.getPolicy(); + } - return out; - }; -}(); + this.buildingSeedList = new BuildingSeedList(); + this.readerWriter.getObjectIndexFileForSmartTile( + this.readerWriter.getCurrentDataPath() + Constant.OBJECT_INDEX_FILE + Constant.CACHE_VERSION + MagoConfig.getPolicy().content_cache_version, this, this.buildingSeedList); + +}; /** - * Sets the specified quaternion with values corresponding to the given - * axes. Each axis is a vec3 and is expected to be unit length and - * perpendicular to all other specified axes. - * - * @param {vec3} view the vector representing the viewing direction - * @param {vec3} right the vector representing the local "right" direction - * @param {vec3} up the vector representing the local "up" direction - * @returns {quat} out + * object index 파일을 읽어서 빌딩 개수, 포지션, 크기 정보를 배열에 저장 */ -var setAxes = exports.setAxes = function () { - var matr = mat3.create(); - - return function (out, view, right, up) { - matr[0] = right[0]; - matr[3] = right[1]; - matr[6] = right[2]; - - matr[1] = up[0]; - matr[4] = up[1]; - matr[7] = up[2]; +MagoManager.prototype.makeNode = function(jasonObject, resultPhysicalNodesArray, buildingSeedMap, projectFolderName, projectId) +{ + var attributes = undefined; + var children = undefined; + var data_group_id = undefined; + var data_group_name = undefined; + var data_id = undefined; + var data_key = undefined; + var data_name = undefined; + var heading = undefined; + var height = undefined; + var latitude = undefined; + var longitude = undefined; + var pitch = undefined; + var roll = undefined; + var mapping_type = undefined; + + if (jasonObject !== undefined) + { + attributes = jasonObject.attributes; + children = jasonObject.children; + data_group_id = jasonObject.data_group_id; + data_group_name = jasonObject.data_group_name; + data_id = jasonObject.data_id; + data_key = jasonObject.data_key; + data_name = jasonObject.data_name; + heading = jasonObject.heading; + height = jasonObject.height; + latitude = jasonObject.latitude; + longitude = jasonObject.longitude; + pitch = jasonObject.pitch; + roll = jasonObject.roll; + mapping_type = jasonObject.mapping_type; + } + + // now make the node. + var buildingId; + var buildingSeed; + var node; + var bbox; + var childJason; + var childNode; + var childrenCount; + if (attributes !== undefined) + { + if (!attributes.isReference) + { + buildingId = data_key; + node = this.hierarchyManager.newNode(buildingId, projectId, attributes); + // set main data of the node. + node.data.projectFolderName = projectFolderName; + node.data.projectId = projectId; + node.data.data_name = data_name; + node.data.attributes = attributes; + node.data.mapping_type = mapping_type; + var tMatrix; + + + + if (attributes.isPhysical) + { + // find the buildingSeed. + buildingSeed = buildingSeedMap[buildingId]; + if (buildingSeed) + { + node.data.buildingSeed = buildingSeed; + resultPhysicalNodesArray.push(node); + } + } - matr[2] = -view[0]; - matr[5] = -view[1]; - matr[8] = -view[2]; + if (longitude && latitude) + { + // this is root node. + if (height === undefined) + { height = 0; } + + node.data.geographicCoord = new GeographicCoord(); + node.data.geographicCoord.setLonLatAlt(longitude, latitude, height); + + if (node.data.rotationsDegree === undefined) + { node.data.rotationsDegree = new Point3D(); } + node.data.rotationsDegree.set(pitch, roll, heading); + + + if (buildingSeed !== undefined) + { + if (buildingSeed.geographicCoord === undefined) + { buildingSeed.geographicCoord = new GeographicCoord(); } + + if (buildingSeed.rotationsDegree === undefined) + { buildingSeed.rotationsDegree = new Point3D(); } + + buildingSeed.geographicCoord.setLonLatAlt(longitude, latitude, height); + buildingSeed.rotationsDegree.set(pitch, roll, heading); + + // now calculate the geographic coord of the center of the bbox. + if (buildingSeed.geographicCoordOfBBox === undefined) + { buildingSeed.geographicCoordOfBBox = new GeographicCoord(); } + + // calculate the transformation matrix at (longitude, latitude, height). + var worldCoordPosition = ManagerUtils.geographicCoordToWorldPoint(longitude, latitude, height, worldCoordPosition, this); + tMatrix = ManagerUtils.calculateTransformMatrixAtWorldPosition(worldCoordPosition, heading, pitch, roll, undefined, tMatrix, this); + + // now calculate the geographicCoord of the center of the bBox. + var bboxCenterPoint; - return normalize(out, fromMat3(out, matr)); - }; -}(); + bboxCenterPoint = buildingSeed.bBox.getCenterPoint(bboxCenterPoint); + var bboxCenterPointWorldCoord = tMatrix.transformPoint3D(bboxCenterPoint, bboxCenterPointWorldCoord); + buildingSeed.geographicCoordOfBBox = ManagerUtils.pointToGeographicCoord(bboxCenterPointWorldCoord, buildingSeed.geographicCoordOfBBox, this); // original. + } + } -/***/ }), -/* 9 */ -/***/ (function(module, exports, __webpack_require__) { + // now, calculate the bbox.*** + node.data.bbox = new BoundingBox(); + + if (node.data.buildingSeed && node.data.buildingSeed.bBox) + { node.data.bbox.copyFrom(buildingSeed.bBox); } + + if (node.data.mapping_type && node.data.mapping_type.toLowerCase() === "boundingboxcenter") + { + node.data.bbox.translateToOrigin(); + } + + // calculate the geographicCoordOfTheBBox.*** + if (tMatrix !== undefined) + { + bboxCenterPoint = node.data.bbox.getCenterPoint(bboxCenterPoint); + var bboxCenterPointWorldCoord = tMatrix.transformPoint3D(bboxCenterPoint, bboxCenterPointWorldCoord); + node.data.bbox.geographicCoord = ManagerUtils.pointToGeographicCoord(bboxCenterPointWorldCoord, node.data.bbox.geographicCoord, this); + } -"use strict"; + //bbox = node.data.bbox; + if (children !== undefined) + { + childrenCount = children.length; + for (var i=0; i 0) { - //TODO: evaluate use of glm_invsqrt here? - len = 1 / Math.sqrt(len); - out[0] = a[0] * len; - out[1] = a[1] * len; - } - return out; -}; +MagoManager.prototype.callAPI = function(api) +{ + var apiName = api.getAPIName(); + if (apiName === "changeMagoState") + { + this.magoPolicy.setMagoEnable(api.getMagoEnable()); + } + else if (apiName === "searchData") + { + return this.flyToBuilding(apiName, api.getProjectId(), api.getDataKey()); + } + else if (apiName === "changeColor") + { + ColorAPI.changeColor(api, this); + } + else if (apiName === "show") + { + this.magoPolicy.setHideBuildings.length = 0; + } + else if (apiName === "hide") + { + this.magoPolicy.setHideBuildings(api.gethideBuilds()); + } + else if (apiName === "changeOutFitting") + { + this.magoPolicy.setShowOutFitting(api.getShowOutFitting()); + } + else if (apiName === "changeLabel") + { + this.magoPolicy.setShowLabelInfo(api.getShowLabelInfo()); + + // clear the text canvas. + var canvas = document.getElementById("objectLabel"); + var ctx = canvas.getContext("2d"); + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); -/** - * Calculates the dot product of two vec2's - * - * @param {vec2} a the first operand - * @param {vec2} b the second operand - * @returns {Number} dot product of a and b - */ -function dot(a, b) { - return a[0] * b[0] + a[1] * b[1]; -}; + } + else if (apiName === "changeOrigin") + { + this.magoPolicy.setShowOrigin(api.getShowOrigin()); + } + else if (apiName === "changeBoundingBox") + { + this.magoPolicy.setShowBoundingBox(api.getShowBoundingBox()); + } + else if (apiName === "changeShadow") + { + this.magoPolicy.setShowShadow(api.getShowShadow()); + + } + else if (apiName === "changefrustumFarDistance") + { + // frustum culling 가시 거리 + this.magoPolicy.setFrustumFarSquaredDistance(api.getFrustumFarDistance() * api.getFrustumFarDistance()); + } + else if (apiName === "changeLocationAndRotation") + { + LocationAndRotationAPI.changeLocationAndRotation(api, this); + } + else if (apiName === "changeObjectMove") + { + this.magoPolicy.setObjectMoveMode(api.getObjectMoveMode()); + } + else if (apiName === "saveObjectMove") + { + // var changeHistory = new ChangeHistory(); + // changeHistory.setObjectMoveMode(api.getObjectMoveMode()); + // MagoConfig.saveMovingHistory(api.getProjectId(), api.getDataKey(), api.getObjectIndexOrder(), changeHistory); + } + else if (apiName === "deleteAllObjectMove") + { + // delete "aditionalMove" of the objects.*** + var moveHistoryMap = MagoConfig.getAllMovingHistory(); // get colorHistoryMap.*** + if (moveHistoryMap === undefined) + { + MagoConfig.clearMovingHistory(); + return; + } + + for (var key_projectId in moveHistoryMap) + { + if (Object.prototype.hasOwnProperty.call(moveHistoryMap, key_projectId)) + { + var projectId = key_projectId; + var buildingsMap = moveHistoryMap[projectId]; + if (buildingsMap === undefined) + { continue; } + + for (var key_dataKey in buildingsMap) + { + if (Object.prototype.hasOwnProperty.call(buildingsMap, key_dataKey)) + { + var dataKey = key_dataKey; + var dataValue = buildingsMap[key_dataKey]; + + if (dataValue === undefined) + { continue; } + + for (var objectIdx in dataValue) + { + if (Object.prototype.hasOwnProperty.call(dataValue, objectIdx)) + { + var node = this.hierarchyManager.getNodeByDataKey(projectId, dataKey); + if (node === undefined || node.data === undefined) + { continue; } + + var neoBuilding = node.data.neoBuilding; + if (neoBuilding === undefined) + { continue; } + + var refObject = neoBuilding.getReferenceObject(objectIdx); + if (refObject) + { + refObject.moveVector = undefined; + refObject.moveVectorRelToBuilding = undefined; + } + } + } + } + } + } + } + + MagoConfig.clearMovingHistory(); + } + else if (apiName === "deleteAllChangeColor") + { + // 1rst, must delete the aditionalColors of objects.*** + var colorHistoryMap = MagoConfig.getAllColorHistory(); // get colorHistoryMap.*** + + if (colorHistoryMap === undefined) + { + MagoConfig.clearColorHistory(); + return; + } + + for (var key_projectId in colorHistoryMap) + { + if (Object.prototype.hasOwnProperty.call(colorHistoryMap, key_projectId)) + { + var projectId = key_projectId; + var buildingsMap = colorHistoryMap[projectId]; + if (buildingsMap === undefined) + { continue; } + + for (var key_dataKey in buildingsMap) + { + if (Object.prototype.hasOwnProperty.call(buildingsMap, key_dataKey)) + { + var dataKey = key_dataKey; + var dataValue = buildingsMap[key_dataKey]; + if (dataValue === undefined) + { continue; } + + for (var objectId in dataValue) + { + if (Object.prototype.hasOwnProperty.call(dataValue, objectId)) + { + var node = this.hierarchyManager.getNodeByDataKey(projectId, dataKey); + if (node === undefined || node.data === undefined) + { continue; } + + node.data.isColorChanged = false; + + var neoBuilding = node.data.neoBuilding; + if (neoBuilding === undefined) + { continue; } + + var refObjectArray = neoBuilding.getReferenceObjectsArrayByObjectId(objectId); + if (refObjectArray === undefined) + { continue; } + + var refObjectsCount = refObjectArray.length; + for (var i=0; i 3.5) + { + var bottomPositionCartographic = this.scene.globe.ellipsoid.cartesianToCartographic(bottomPosition); + var currentPositionCartographic = this.scene.globe.ellipsoid.cartesianToCartographic(position); + var currentHeight = currentPositionCartographic.height; + var bottomHeight = bottomPositionCartographic.height + 1.5; + + if ( bottomHeight < currentHeight ) + { + currentHeight -= 0.2; + } + + if ( bottomHeight > currentHeight || + (bottomHeight < currentHeight && currentHeight - bottomHeight > 1.5)) + { + currentHeight = bottomHeight; + } + var tmpLat = Cesium.Math.toDegrees(currentPositionCartographic.latitude); + var tmpLon = Cesium.Math.toDegrees(currentPositionCartographic.longitude); + + this.cameraFPV.camera.position = Cesium.Cartesian3.fromDegrees(tmpLon, tmpLat, currentHeight); -/** - * Alias for {@link vec2.squaredDistance} - * @function - */ -var sqrDist = exports.sqrDist = squaredDistance; + return false; + } -/** - * Alias for {@link vec2.squaredLength} - * @function - */ -var sqrLen = exports.sqrLen = squaredLength; + return true; +}; +'use strict'; /** - * Perform some operation over an array of vec2s. + * Factory method 패턴을 사용해서 cesium, worldwind 등을 wrapping 해 주는 클래스 + * @class ManagerFactory * - * @param {Array} a the array of vectors to iterate over - * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed - * @param {Number} offset Number of elements to skip at the beginning of the array - * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array - * @param {Function} fn Function to call for each vector in the array - * @param {Object} [arg] additional argument to pass to fn - * @returns {Array} a - * @function - */ -var forEach = exports.forEach = function () { - var vec = create(); - - return function (a, stride, offset, count, fn, arg) { - var i = void 0, - l = void 0; - if (!stride) { - stride = 2; - } - - if (!offset) { - offset = 0; - } - - if (count) { - l = Math.min(count * stride + offset, a.length); - } else { - l = a.length; - } + * @param viewer 타 시스템과의 연동의 경우 view 객체가 생성되어서 넘어 오는 경우가 있음 + * @param containerId 뷰에서 표시할 위치 id + * @param serverPolicy policy json object + * @param projectIdArray json object map에 저장하기 위한 key + * @param projectDataArray data json object + * @param projectDataFolderArray f4d data folder path + * @param imagePath 이미지 경로 + * @returns api + */ +var ManagerFactory = function(viewer, containerId, serverPolicy, projectIdArray, projectDataArray, projectDataFolderArray, imagePath) +{ + if (!(this instanceof ManagerFactory)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } - for (i = offset; i < l; i += stride) { - vec[0] = a[i];vec[1] = a[i + 1]; - fn(vec, vec, arg); - a[i] = vec[0];a[i + 1] = vec[1]; - } + var magoManager = null; + var scene = null; + var magoManagerState = CODE.magoManagerState.INIT; + + //var startMousePosition = null; + //var nowMousePosition = null; - return a; - }; -}(); + // 환경 설정 + MagoConfig.init(serverPolicy, projectIdArray, projectDataArray); + + // 카메라 행동 설정 + function disableCameraMotion(state) + { + viewer.scene.screenSpaceCameraController.enableRotate = state; + viewer.scene.screenSpaceCameraController.enableZoom = state; + viewer.scene.screenSpaceCameraController.enableLook = state; + viewer.scene.screenSpaceCameraController.enableTilt = state; + viewer.scene.screenSpaceCameraController.enableTranslate = state; + } + + // 이벤트 확장 + function addMouseAction() + { + magoManager.handler.setInputAction(function(click) + { + magoManager.mouseActionLeftDown(click.position.x, click.position.y); + }, Cesium.ScreenSpaceEventType.LEFT_DOWN); -/***/ }) -/******/ ]); -}); -/** - * @file tgajs - Javascript decoder & (experimental) encoder for TGA files - * @desc tgajs is a fork from https://github.com/vthibault/jsTGALoader - * @author Vincent Thibault (Original author) - * @author Lukas Schmitt - * @version 1.0.0 - */ + magoManager.handler.setInputAction(function(click) + { + magoManager.mouseActionMiddleDown(click.position.x, click.position.y); + }, Cesium.ScreenSpaceEventType.MIDDLE_DOWN); + + magoManager.handler.setInputAction(function(click) + { + magoManager.mouseActionRightDown(click.position.x, click.position.y); + }, Cesium.ScreenSpaceEventType.RIGHT_DOWN); -/* Copyright (c) 2013, Vincent Thibault. All rights reserved. + //var mousePosition; + magoManager.handler.setInputAction(function(movement) + { + //magoManager.mouseActionMove(movement.endPosition.x, movement.endPosition.y); + //mousePosition = movement.endPosition; + if (magoManager.mouseLeftDown) + { + if (movement.startPosition.x !== movement.endPosition.x || movement.startPosition.y !== movement.endPosition.y) + { + magoManager.manageMouseDragging(movement.startPosition.x, movement.startPosition.y); + magoManager.cameraMoved(); + } + } + else + { + magoManager.mouseDragging = false; + disableCameraMotion(true); + if (magoManager.mouseMiddleDown || magoManager.mouseRightDown) + { + magoManager.isCameraMoving = true; + magoManager.cameraMoved(); + } + } + + }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: + magoManager.handler.setInputAction(function(movement) + { + magoManager.mouseActionLeftUp(movement.position.x, movement.position.y); + // display current mouse position + var pickPosition = {lat: null, lon: null, alt: null}; + var position = magoManager.scene.camera.pickEllipsoid(movement.position); + if (position) + { + var cartographicPosition = Cesium.Cartographic.fromCartesian(position); + pickPosition.lat = Cesium.Math.toDegrees(cartographicPosition.latitude); + pickPosition.lon = Cesium.Math.toDegrees(cartographicPosition.longitude); + pickPosition.alt = cartographicPosition.height; + } + if (MagoConfig.getPolicy().geo_callback_enable === "true") + { + if (serverPolicy.geo_callback_clickposition !== '') + { + clickPositionCallback(serverPolicy.geo_callback_clickposition, pickPosition); + } + } + }, Cesium.ScreenSpaceEventType.LEFT_UP); - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. + magoManager.handler.setInputAction(function(movement) + { + magoManager.mouseActionMiddleUp(movement.position.x, movement.position.y); + }, Cesium.ScreenSpaceEventType.MIDDLE_UP); + + magoManager.handler.setInputAction(function(movement) + { + magoManager.mouseActionRightUp(movement.position.x, movement.position.y); + }, Cesium.ScreenSpaceEventType.RIGHT_UP); + + magoManager.handler.setInputAction(function(movement) + { + magoManager.mouseActionLeftClick(movement.position.x, movement.position.y); + }, Cesium.ScreenSpaceEventType.LEFT_CLICK); + } - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + // cesium을 구현체로서 이용 + function initWwwMago(manager, gl) + { + //var viewport = manager.wwd.viewport; + //manager.selection.init(gl, viewport.width, viewport.height); + manager.postFxShadersManager.gl = gl; + manager.postFxShadersManager.createDefaultShaders(gl); // A1-OLD.*** + manager.createDefaultShaders(gl);// A1-Use this.*** -(function (_global) { - 'use strict'; + // object index 파일을 읽어서 빌딩 개수, 포지션, 크기 정보를 배열에 저장 + //manager.getObjectIndexFile(); // old.*** + //viewer.scene.magoManager.getObjectIndexFile(); + if (projectIdArray !== null && projectIdArray.length > 0) + { + for (var i=0; i 0) + { + for (var i=0; i hidden + $(viewer._animation.container).css("visibility", "hidden"); + $(viewer._timeline.container).css("visibility", "hidden"); + viewer.forceResize(); + } + } + + var DEFALUT_IMAGE = "ESRI World Imagery"; + var DEFALUT_TERRAIN = "WGS84 Ellipsoid"; + + // pick baseLayer + function setDefaultDataset() + { + // WGS84 Ellipsoide + if (MagoConfig.getPolicy().geo_init_default_terrain !== null && MagoConfig.getPolicy().geo_init_default_terrain !== "") + { + DEFALUT_TERRAIN = MagoConfig.getPolicy().geo_init_default_terrain; + } + + // search default imageryProvider from baseLayerPicker + var imageryProvider = null; + var imageryProviderViewModels = viewer.baseLayerPicker.viewModel.imageryProviderViewModels; + for (var i in imageryProviderViewModels) + { + if (!imageryProviderViewModels.hasOwnProperty(i)) { continue; } - function readHeader(view) { - var littleEndian = Targa.LITTLE_ENDIAN; + var provider = imageryProviderViewModels[i]; + if (provider.name === DEFALUT_IMAGE) + { + imageryProvider = provider; + break; + } + } + if (imageryProvider) { viewer.baseLayerPicker.viewModel.selectedImagery = imageryProvider; } + + // search default terrainProvider from baseLayerPicker + var terrainProvider = null; + var terrainProviderViewModels = viewer.baseLayerPicker.viewModel.terrainProviderViewModels; + for (var i in terrainProviderViewModels) + { + if (!terrainProviderViewModels.hasOwnProperty(i)) { continue; } + var provider = terrainProviderViewModels[i]; + if (provider.name === DEFALUT_TERRAIN) + { + terrainProvider = provider; + break; + } + } + if (terrainProvider) { viewer.baseLayerPicker.viewModel.selectedTerrain = terrainProvider; } + } - // Not enough data to contain header ? - if (view.byteLength < 0x12) { - throw new Error('Targa::load() - Not enough data to contain header'); - } + if (serverPolicy.geo_view_library === null || + serverPolicy.geo_view_library === '' || + serverPolicy.geo_view_library === Constant.CESIUM) + { + // webgl lost events.****************************************** + var canvas = document.getElementById(containerId); + canvas.addEventListener('webglcontextlost', function(e) + { + console.log(e); + }, false); + + canvas.addEventListener('webglcontextrestored', function(e) + { + console.log(e); + }, false); + //------------------------------------------------------------- + + if (serverPolicy.geo_server_enable === "true" && serverPolicy.geo_server_url !== null && serverPolicy.geo_server_url !== '') + { + var imageryProvider = new Cesium.WebMapServiceImageryProvider({ + url : serverPolicy.geo_server_url, + layers : serverPolicy.geo_server_layers, + parameters : { + service : serverPolicy.geo_server_parameters_service, + version : serverPolicy.geo_server_parameters_version, + request : serverPolicy.geo_server_parameters_request, + transparent : serverPolicy.geo_server_parameters_transparent, + format : serverPolicy.geo_server_parameters_format + }//, + //proxy: new Cesium.DefaultProxy('/proxy/') + }); + var options = {imageryProvider: imageryProvider, baseLayerPicker: false}; + if (viewer === null) { viewer = new Cesium.Viewer(containerId, options); } + } + else + { + if (serverPolicy.geo_cesium_ion_token !== null && serverPolicy.geo_cesium_ion_token !== "") + { + Cesium.Ion.defaultAccessToken = serverPolicy.geo_cesium_ion_token; + DEFALUT_TERRAIN = "Cesium World Terrain"; + } + if (viewer === null) { viewer = new Cesium.Viewer(containerId, {shouldAnimate: true}); } + // 기본 지도 설정 + setDefaultDataset(); + } + + viewer.scene.magoManager = new MagoManager(); + viewer.scene.magoManager.sceneState.textureFlipYAxis = false; + viewer.camera.frustum.fov = Cesium.Math.PI_OVER_THREE*1.8; + //viewer.camera.frustum.near = 0.1; + if (MagoConfig.getPolicy().geo_init_default_fov > 0) + { + viewer.camera.frustum.fov = Cesium.Math.PI_OVER_THREE * MagoConfig.getPolicy().geo_init_default_fov; + } - var header = {}; - header.idLength = view.getUint8(0x00); - header.colorMapType = view.getUint8(0x01); - header.imageType = view.getUint8(0x02); - header.colorMapIndex = view.getUint16(0x03, littleEndian); - header.colorMapLength = view.getUint16(0x05, littleEndian); - header.colorMapDepth = view.getUint8(0x07); - header.offsetX = view.getUint16(0x08, littleEndian); - header.offsetY = view.getUint16(0x0a, littleEndian); - header.width = view.getUint16(0x0c, littleEndian); - header.height = view.getUint16(0x0e, littleEndian); - header.pixelDepth = view.getUint8(0x10); - header.flags = view.getUint8(0x11); + // Layers 추가 적용 + if (serverPolicy.geo_server_enable === "true" && serverPolicy.geo_server_add_url !== null && serverPolicy.geo_server_add_url !== '') + { + addImageryLayers(); + } + + draw(); + // build을 rendering 할 위치 + initEntity(); + // terrain 적용 여부 + /*if() { + initTerrain(); + }*/ + // 최초 로딩시 카메라 이동 여부 + if (serverPolicy.geo_init_camera_enable === "true") { initCamera(); } + // render Mode 적용 + initRenderMode(); + } + else if (serverPolicy.geo_view_library === Constant.WORLDWIND) + { + + // Tell World Wind to log only warnings and errors. + WorldWind.Logger.setLoggingLevel(WorldWind.Logger.LEVEL_WARNING); - return header; - } + // set to canvas the current gl.*** + var canvas = document.getElementById(containerId); + + var wwd; + if (serverPolicy.geo_server_enable === "true" && serverPolicy.geo_server_url !== null && serverPolicy.geo_server_url !== '') + { + wwd = new WorldWind.WorldWindow(containerId, new WorldWind.ZeroElevationModel()); + + // Web Map Service information + var serviceAddress = serverPolicy.geo_server_url + "?SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.3.0"; - /** - * Set additional header booleans - * @param header - */ - function setHeaderBooleans(header) { - header.hasEncoding = (header.imageType === Targa.Type.RLE_INDEXED || header.imageType === Targa.Type.RLE_RGB || header.imageType === Targa.Type.RLE_GREY); - header.hasColorMap = (header.imageType === Targa.Type.RLE_INDEXED || header.imageType === Targa.Type.INDEXED); - header.isGreyColor = (header.imageType === Targa.Type.RLE_GREY || header.imageType === Targa.Type.GREY); - header.bytePerPixel = header.pixelDepth >> 3; - header.origin = (header.flags & Targa.Origin.MASK) >> Targa.Origin.SHIFT; - header.alphaBits = header.flags & Targa.Origin.ALPHA; - } + // Named layer displaying Average Temperature data + var layerName = "mago3d"; - /** - * Check the header of TGA file to detect errors - * - * @param {object} header tga header structure - * @throws Error - */ - function checkHeader(header) { - // What the need of a file without data ? - if (header.imageType === Targa.Type.NO_DATA) { - throw new Error('Targa::checkHeader() - No data'); - } + // Called asynchronously to parse and create the WMS layer + var createLayer = function (xmlDom) + { + // Create a WmsCapabilities object from the XML DOM + var wms = new WorldWind.WmsCapabilities(xmlDom); + // Retrieve a WmsLayerCapabilities object by the desired layer name + var wmsLayerCapabilities = wms.getNamedLayer(layerName); + // Form a configuration object from the WmsLayerCapability object + var wmsConfig = WorldWind.WmsLayer.formLayerConfiguration(wmsLayerCapabilities); + // Modify the configuration objects title property to a more user friendly title + wmsConfig.title = "imageProvider"; + // Create the WMS Layer from the configuration object + var wmsLayer = new WorldWind.WmsLayer(wmsConfig); - // Indexed type - if (header.hasColorMap) { - if (header.colorMapLength > 256 || header.colorMapType !== 1) { - throw new Error('Targa::checkHeader() - Unsupported colormap for indexed type'); - } - if (header.colorMapDepth !== 16 && header.colorMapDepth !== 24 && header.colorMapDepth !== 32) { - throw new Error('Targa::checkHeader() - Unsupported colormap depth'); - } - } - else { - if (header.colorMapType) { - throw new Error('Targa::checkHeader() - Why does the image contain a palette ?'); - } - } + // Add the layers to WorldWind and update the layer manager + wwd.addLayer(wmsLayer); + }; - // Check image size - if (header.width <= 0 || header.height <= 0) { - throw new Error('Targa::checkHeader() - Invalid image size'); - } + // Called if an error occurs during WMS Capabilities document retrieval + var logError = function (jqXhr, text, exception) + { + console.log("There was a failure retrieving the capabilities document: " + text + " exception: " + exception); + }; - // Check pixel size - if (header.pixelDepth !== 8 && - header.pixelDepth !== 16 && - header.pixelDepth !== 24 && - header.pixelDepth !== 32) { - throw new Error('Targa::checkHeader() - Invalid pixel size "' + header.pixelDepth + '"'); - } + $.get(serviceAddress).done(createLayer).fail(logError); + } + else + { + // Create the World Window. + wwd = new WorldWind.WorldWindow(containerId); + //wwd.depthBits = 32; + + var layers = [ + {layer: new WorldWind.BMNGLayer(), enabled: true}, + {layer: new WorldWind.BMNGLandsatLayer(), enabled: false}, + {layer: new WorldWind.BingAerialWithLabelsLayer(null), enabled: true}, + {layer: new WorldWind.OpenStreetMapImageLayer(null), enabled: false}, + {layer: new WorldWind.CompassLayer(), enabled: false}, + {layer: new WorldWind.CoordinatesDisplayLayer(wwd), enabled: true}, + {layer: new WorldWind.ViewControlsLayer(wwd), enabled: true} + ]; - // Check alpha size - if (header.alphaBits !== 0 && - header.alphaBits !== 1 && - header.alphaBits !== 8) { - throw new Error('Targa::checkHeader() - Unsuppported alpha size'); - } - } + for (var l = 0; l < layers.length; l++) + { + layers[l].layer.enabled = layers[l].enabled; + wwd.addLayer(layers[l].layer); + } + } + // Now set up to handle highlighting. + //var highlightController = new WorldWind.HighlightController(wwd); - /** - * Decode RLE compression - * - * @param {Uint8Array} data - * @param {number} bytesPerPixel bytes per Pixel - * @param {number} outputSize in byte: width * height * pixelSize - */ - function decodeRLE(data, bytesPerPixel, outputSize) { - var pos, c, count, i, offset; - var pixels, output; + magoManager = new MagoManager(); + magoManager.wwd = wwd; + magoManager.sceneState.textureFlipYAxis = true; + + var newRenderableLayer = new WorldWind.RenderableLayer(); + newRenderableLayer.displayName = "F4D tiles"; + newRenderableLayer.inCurrentFrame = true; // Test.*** + wwd.addLayer(newRenderableLayer); + + //newRenderableLayer.addRenderable(f4d_wwwLayer);// old.*** + newRenderableLayer.addRenderable(magoManager); + // End Create a layer to hold the f4dBuildings.------------------------------------------------------- - output = new Uint8Array(outputSize); - pixels = new Uint8Array(bytesPerPixel); - offset = 0; // offset in data - pos = 0; // offset for output + var gl = wwd.drawContext.currentGlContext; + initWwwMago(magoManager, gl); - while (pos < outputSize) { - c = data[offset++]; // current byte to check - count = (c & Targa.RLE_MASK) + 1; // repetition count of pixels, the lower 7 bits + 1 + // Click event. + // The common gesture-handling function. + var handleClick = function (recognizer) + { + // Obtain the event location. + //magoManager.mouse_x = event.layerX, + //magoManager.mouse_y = event.layerY; + //magoManager.bPicking = true; + + // Perform the pick. Must first convert from window coordinates to canvas coordinates, which are + // relative to the upper left corner of the canvas rather than the upper left corner of the page. + //var pickList = wwd.pick(wwd.canvasCoordinates(x, y)); - // RLE packet, if highest bit is set to 1. - if (c & Targa.RLE_BIT) { - // Copy pixel values to be repeated to tmp array - for (i = 0; i < bytesPerPixel; ++i) { - pixels[i] = data[offset++]; - } + // If only one thing is picked and it is the terrain, use a go-to animator to go to the picked location. + /* + if (pickList.objects.length === 1 && pickList.objects[0].isTerrain) { + var position = pickList.objects[0].position; + //wwd.goTo(new WorldWind.Location(position.latitude, position.longitude)); + //wwd.goTo(new WorldWind.Position(37.48666, 127.05618, 500)); + wwd.goToOriented(new WorldWind.Position(37.48666, 127.05618, 500.0), 120.0, 80.0); + } + */ + }; - // Copy pixel values * count to output - for (i = 0; i < count; ++i) { - output.set(pixels, pos); - pos += bytesPerPixel; - } - } + // Listen for mouse clicks. + var clickRecognizer = new WorldWind.ClickRecognizer(wwd, handleClick); + clickRecognizer.button = 0; //left mouse button + + var mouseDownEvent = function(event) + { + if (event.button === 0) + { + magoManager.mouseActionLeftDown(event.layerX, event.layerY); + } + else if (event.button === 1) + { + magoManager.mouseActionMiddleDown(event.layerX, event.layerY); + } + else if (event.button === 2) + { + magoManager.mouseActionRightDown(event.layerX, event.layerY); + } + }; + wwd.addEventListener("mousedown", mouseDownEvent, false); + + var mouseUpEvent = function(event) + { + if (event.button === 0) + { + magoManager.mouseActionLeftUp(event.layerX, event.layerY); + } + else if (event.button === 1) + { + magoManager.mouseActionMiddleUp(event.layerX, event.layerY); + } + else if (event.button === 2) + { + magoManager.mouseActionRightUp(event.layerX, event.layerY); + } - // Raw packet (Non-Run-Length Encoded) - else { - count *= bytesPerPixel; - for (i = 0; i < count; ++i) { - output[pos++] = data[offset++]; - } - } - } + // display current mouse position + + var terrainObject; + var pickPosition = {lat: null, lon: null, alt: null}; + var pickPoint = wwd.canvasCoordinates(event.layerX, event.layerY); + if (pickPoint[0] >= 0 && pickPoint[0] < wwd.canvas.width && + pickPoint[1] >= 0 && pickPoint[1] < wwd.canvas.height) + { + terrainObject = wwd.pickTerrain(pickPoint).terrainObject(); + var terrainPosition = terrainObject ? terrainObject.position : null; + if (terrainPosition !== null) + { + pickPosition.lat = terrainPosition.latitude; + pickPosition.lon = terrainPosition.longitude; + pickPosition.alt = terrainPosition.altitude; + } + } + if (MagoConfig.getPolicy().geo_callback_enable === "true") + { + if (serverPolicy.geo_callback_clickposition !== '') + { + clickPositionCallback(serverPolicy.geo_callback_clickposition, pickPosition); + } + } + }; + wwd.addEventListener("mouseup", mouseUpEvent, false); + + var mouseMoveEvent = function(event) + { + magoManager.mouse_x = event.layerX, + magoManager.mouse_y = event.layerY; + if (magoManager.mouseLeftDown) + { + magoManager.manageMouseDragging(event.layerX, event.layerY); + magoManager.cameraMoved(); + } + else if (magoManager.mouseMiddleDown || magoManager.mouseRightDown) + { + magoManager.cameraMoved(); + } + + }; + wwd.addEventListener("mousemove", mouseMoveEvent, false); + + + wwd.goToAnimator.travelTime = MagoConfig.getPolicy().geo_init_duration * 1000; + wwd.goTo(new WorldWind.Position(MagoConfig.getPolicy().geo_init_latitude, MagoConfig.getPolicy().geo_init_longitude, MagoConfig.getPolicy().geo_init_height)); + } + if (serverPolicy.geo_view_library === Constant.MAGOWORLD) + { + var canvas = document.getElementById(containerId); + var glAttrs = {antialias: false, stencil: true}; + var gl = canvas.getContext("webgl", glAttrs); + if (!gl) + { gl = canvas.getContext("experimental-webgl", glAttrs); } + + // Problem: canvas-width initially is 300 and canvas-height = 150.*** + canvas.width = canvas.clientWidth; + canvas.height = canvas.clientHeight; + + magoManager = new MagoManager(); + var sceneState = magoManager.sceneState; + sceneState.textureFlipYAxis = true; + sceneState.gl = gl; + sceneState.drawingBufferWidth[0] = canvas.clientWidth; + sceneState.drawingBufferHeight[0] = canvas.clientHeight; + sceneState.camera.frustum.aspectRatio = canvas.clientWidth/canvas.clientHeight; + sceneState.camera.frustum.fovRad[0] = Math.PI/3*1.8; + sceneState.camera.frustum.fovyRad[0] = sceneState.camera.frustum.fovRad[0]/sceneState.camera.frustum.aspectRatio; + sceneState.camera.frustum.tangentOfHalfFovy[0] = Math.tan(sceneState.camera.frustum.fovyRad[0]/2); + + + // initial camera position.*** + sceneState.camera.position.set(0.0, 0.0, 10000000.0); + sceneState.camera.direction.set(0.0, 0.0, -1.0); + sceneState.camera.up.set(0.0, 1.0, 0.0); + + // test init camera position.*** + //sphere.r = 6378137.0; + sceneState.encodedCamPosHigh[0] = 0; + sceneState.encodedCamPosHigh[1] = 0; + sceneState.encodedCamPosHigh[2] = 10000000.0; + + sceneState.encodedCamPosLow[0] = 0; + sceneState.encodedCamPosLow[1] = 0; + sceneState.encodedCamPosLow[2] = 0; - if (pos > outputSize) { - throw new Error("Targa::decodeRLE() - Read bytes: " + pos + " Expected bytes: " + outputSize); - } + + viewer = new MagoWorld(magoManager); + magoManager.magoWorld = viewer; + magoManager.globe = new Globe(); + // init matrices.*** + viewer.updateModelViewMatrixByCamera(sceneState.camera); + //magoManager.upDateSceneStateMatrices(sceneState); + + // event listener.*** + canvas.addEventListener('mousedown', function(event) + { + viewer.mousedown(event); + }, false); + + canvas.addEventListener('mouseup', function(event) + { + viewer.mouseup(event); + }, false); + + canvas.addEventListener('mousewheel', function(event) + { + viewer.mousewheel(event); + }, false); + + canvas.addEventListener('mousemove', function(event) + { + viewer.mousemove(event); + }, false); + + canvas.addEventListener('click', function(event) + { + viewer.mouseclick(event); + }, false); + + canvas.addEventListener('resize', function(event) + { + // TODO: + console.log("resize"); + }, false); + + canvas.addEventListener('keydown', function(event) // no works.*** + { + viewer.keydown(event); // no works.*** + }, false); - return output; - } + + draw(); + } - /** - * Encode ImageData object with RLE compression - * - * @param header - * @param imageData from canvas to compress - */ - function encodeRLE(header, imageData) { - var maxRepetitionCount = 128; - var i; - var data = imageData; - var output = []; // output size is unknown - var pos = 0; // pos in imageData array - var bytesPerPixel = header.pixelDepth >> 3; - var offset = 0; - var packetType, packetLength, packetHeader; - var tgaLength = header.width * header.height * bytesPerPixel; - var isSamePixel = function isSamePixel(pos, offset) { - for (var i = 0; i < bytesPerPixel; i++) { - if (data[pos * bytesPerPixel + i] !== data[offset * bytesPerPixel + i]) { - return false; - } - } - return true; - }; - var getPacketType = function(pos) { - if (isSamePixel(pos, pos + 1)) { - return Targa.RLE_PACKET; - } - return Targa.RAW_PACKET; - }; + // 이미지 경로 + magoManager.magoPolicy.imagePath = imagePath; + magoManagerState = CODE.magoManagerState.READY; - while (pos * bytesPerPixel < data.length && pos * bytesPerPixel < tgaLength) { - // determine packet type - packetType = getPacketType(pos); + // KeyPressEvents.************************************** + document.addEventListener('keydown', function(event) + { + // get current building selected + if (magoManager.magoPolicy.issueInsertEnable) { return; } + + magoManager.keyDown(event.keyCode); - // determine packet length - packetLength = 0; - if (packetType === Targa.RLE_PACKET) { - while (pos + packetLength < data.length - && packetLength < maxRepetitionCount - && isSamePixel(pos, pos + packetLength)) { - packetLength++; - } - } else { // packetType === Targa.RAW_PACKET - while (pos + packetLength < data.length - && packetLength < maxRepetitionCount - && getPacketType(pos + packetLength) === Targa.RAW_PACKET) { - packetLength++; - } - } + var selectedBuilding = magoManager.buildingSelected; + if (selectedBuilding === undefined) { return; } - // write packet header - packetHeader = packetLength - 1; - if (packetType === Targa.RLE_PACKET) { - packetHeader |= Targa.RLE_BIT; - } - output[offset++] = packetHeader; + var nodeSelected = magoManager.selectionManager.currentNodeSelected; + if (nodeSelected === undefined) + { return; } + var rootNodeSelected = nodeSelected.getRoot(); + var geoLocationData = rootNodeSelected.data.geoLocDataManager.getCurrentGeoLocationData(); + if (geoLocationData === undefined) { return; } - // write rle packet pixel OR raw pixels - if (packetType === Targa.RLE_PACKET) { - for (i = 0; i < bytesPerPixel; i++) { - output[i + offset] = data[i + pos * bytesPerPixel]; - } - offset += bytesPerPixel; - } else { - for (i = 0; i < bytesPerPixel * packetLength; i++) { - output[i + offset] = data[i + pos * bytesPerPixel]; - } - offset += bytesPerPixel * packetLength; - } - pos += packetLength; - } + if (magoManager.magoPolicy.objectMoveMode === CODE.moveMode.ALL) + { + var increDeg = 3.0; + var currentHeading = geoLocationData.heading || 0; + var currentPitch = geoLocationData.pitch || 0; + var currentRoll = geoLocationData.roll || 0; + + var increDist = 0.2; + var currentAlt = geoLocationData.geographicCoord.altitude || 0; + var displayData = false; + + // For Heading + if (event.keyCode === 'Q'.charCodeAt(0)) + { + currentHeading += increDeg; + displayData = true; + } + else if (event.keyCode === 'A'.charCodeAt(0)) + { + currentHeading -= increDeg; + displayData = true; + } + + // For Pitch + if (event.keyCode === 'W'.charCodeAt(0)) + { + currentPitch += increDeg; + displayData = true; + } + else if (event.keyCode === 'S'.charCodeAt(0)) + { + currentPitch -= increDeg; + displayData = true; + } - return new Uint8Array(output); - } + // For Roll + if (event.keyCode === 'E'.charCodeAt(0)) + { + currentRoll += increDeg; + displayData = true; + } + else if (event.keyCode === 'D'.charCodeAt(0)) + { + currentRoll -= increDeg; + displayData = true; + } + + // For Altitude + if (event.keyCode === 'Z'.charCodeAt(0)) + { + currentAlt += increDist; + displayData = true; + } + else if (event.keyCode === 'X'.charCodeAt(0)) + { + currentAlt -= increDist; + displayData = true; + } + + + if (displayData) + { + magoManager.changeLocationAndRotationNode(nodeSelected, geoLocationData.geographicCoord.latitude, geoLocationData.geographicCoord.longitude, + currentAlt, currentHeading, currentPitch, currentRoll); + } + } - /** - * Return a ImageData object from a TGA file (8bits) - * - * @param {Array} imageData - ImageData to bind - * @param {Array} indexes - index to colorMap - * @param {Array} colorMap - * @param {number} width - * @param {number} y_start - start at y pixel. - * @param {number} x_start - start at x pixel. - * @param {number} y_step - increment y pixel each time. - * @param {number} y_end - stop at pixel y. - * @param {number} x_step - increment x pixel each time. - * @param {number} x_end - stop at pixel x. - * @returns {Array} imageData - */ - function getImageData8bits(imageData, indexes, colorMap, width, y_start, y_step, y_end, x_start, x_step, x_end) { - var color, index, offset, i, x, y; - var bytePerPixel = this.header.colorMapDepth >> 3; + }, false); + + // TODO API 객체를 생성해서 하나의 parameter로 전달하는 방식이 좀 더 깔끔할거 같지만 성능적인 부분에서 조금은 투박할거 같아서 일단 이렇게 처리 + return { + // api gateway 역할 + callAPI: function(api) + { + if (api.getReturnable()) + { + return magoManager.callAPI(api); + } + else + { + magoManager.callAPI(api); + } + }, + // flyTo: function(issueId, issueType, longitude, latitude, height, duration) + // { + // if (MagoConfig.getPolicy().geo_view_library === Constant.CESIUM) + // { + // viewer.camera.flyTo({ + // destination: Cesium.Cartesian3.fromDegrees(parseFloat(longitude), + // parseFloat(latitude), + // parseFloat(height) + 10), + // duration: parseInt(duration) + // }); + // } + // else + // { + // wwd.goToAnimator.travelTime = duration * 1000; + // wwd.goTo(new WorldWind.Position(parseFloat(latitude), parseFloat(longitude), parseFloat(height) + 50)); + // } + // // pin을 그림 + // if (issueId !== null && issueType !== undefined) + // { + // var api = new API("drawInsertIssueImage"); + // api.setDrawType(0); + // api.setIssueId(issueId); + // api.setIssueType(issueType); + // api.setDataKey(null); + // api.setLatitude(latitude); + // api.setLongitude(longitude); + // api.setElevation(height); + // magoManager.callAPI(api); + // } + // }, + // magoManager 상태 + getViewer: function() + { + return viewer; + }, + getMagoManagerState: function() + { + return magoManagerState; + }, + getMagoManager: function() + { + return magoManager; + } + }; +}; - for (i = 0, y = y_start; y !== y_end; y += y_step) { - for (x = x_start; x !== x_end; x += x_step, i++) { - offset = (x + width * y) * 4; - index = indexes[i] * bytePerPixel; - if (bytePerPixel === 4) { - imageData[offset ] = colorMap[index + 2]; // red - imageData[offset + 1] = colorMap[index + 1]; // green - imageData[offset + 2] = colorMap[index ]; // blue - imageData[offset + 3] = colorMap[index + 3]; // alpha - } else if (bytePerPixel === 3) { - imageData[offset ] = colorMap[index + 2]; // red - imageData[offset + 1] = colorMap[index + 1]; // green - imageData[offset + 2] = colorMap[index ]; // blue - imageData[offset + 3] = 255; // alpha - } else if (bytePerPixel === 2) { - color = colorMap[index] | (colorMap[index + 1] << 8); - imageData[offset ] = (color & 0x7C00) >> 7; // red - imageData[offset + 1] = (color & 0x03E0) >> 2; // green - imageData[offset + 2] = (color & 0x001F) << 3; // blue - imageData[offset + 3] = (color & 0x8000) ? 0 : 255; // overlay 0 = opaque and 1 = transparent Discussion at: https://bugzilla.gnome.org/show_bug.cgi?id=683381 - } - } - } +'use strict'; - return imageData; - } +/** + * 열우선 배열 방식의 4차원 행렬 + * + */ +var Matrix4 = function() +{ + if (!(this instanceof Matrix4)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } - /** - * Return a ImageData object from a TGA file (16bits) - * - * @param {Array} imageData - ImageData to bind - * @param {Array} pixels data - * @param {Array} colormap - not used - * @param {number} width - * @param {number} y_start - start at y pixel. - * @param {number} x_start - start at x pixel. - * @param {number} y_step - increment y pixel each time. - * @param {number} y_end - stop at pixel y. - * @param {number} x_step - increment x pixel each time. - * @param {number} x_end - stop at pixel x. - * @returns {Array} imageData - */ - function getImageData16bits(imageData, pixels, colormap, width, y_start, y_step, y_end, x_start, x_step, x_end) { - var color, offset, i, x, y; + /** + * @type {Float32Array} + */ + this._floatArrays = new Float32Array([ 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1]); +}; - for (i = 0, y = y_start; y !== y_end; y += y_step) { - for (x = x_start; x !== x_end; x += x_step, i += 2) { - color = pixels[i] | (pixels[i + 1] << 8); - offset = (x + width * y) * 4; - imageData[offset ] = (color & 0x7C00) >> 7; // red - imageData[offset + 1] = (color & 0x03E0) >> 2; // green - imageData[offset + 2] = (color & 0x001F) << 3; // blue - imageData[offset + 3] = (color & 0x8000) ? 0 : 255; // overlay 0 = opaque and 1 = transparent Discussion at: https://bugzilla.gnome.org/show_bug.cgi?id=683381 - } - } +/** + * 단위행렬로 설정한다. + */ +Matrix4.prototype.Identity = function() +{ + this._floatArrays[0] = 1.0; // I(1,1) + this._floatArrays[1] = 0.0; // I(2,1) + this._floatArrays[2] = 0.0; // I(3,1) + this._floatArrays[3] = 0.0; // I(4,1) + + this._floatArrays[4] = 0.0; // I(1,2) + this._floatArrays[5] = 1.0; // I(2,2) + this._floatArrays[6] = 0.0; // I(3,2) + this._floatArrays[7] = 0.0; // I(4,2) + + this._floatArrays[8] = 0.0; // I(1,3) + this._floatArrays[9] = 0.0; // I(2,3) + this._floatArrays[10] = 1.0; // I(3,3) + this._floatArrays[11] = 0.0; // I(4,3) + + this._floatArrays[12] = 0.0; // I(1,4) + this._floatArrays[13] = 0.0; // I(2,4) + this._floatArrays[14] = 0.0; // I(3,4) + this._floatArrays[15] = 1.0; // I(4,4) +}; - return imageData; - } +/** + * 행렬 정보 삭제 + */ +Matrix4.prototype.deleteObjects = function() +{ + this._floatArrays = undefined; +}; - /** - * Return a ImageData object from a TGA file (24bits) - * - * @param {Array} imageData - ImageData to bind - * @param {Array} pixels data - * @param {Array} colormap - not used - * @param {number} width - * @param {number} y_start - start at y pixel. - * @param {number} x_start - start at x pixel. - * @param {number} y_step - increment y pixel each time. - * @param {number} y_end - stop at pixel y. - * @param {number} x_step - increment x pixel each time. - * @param {number} x_end - stop at pixel x. - * @returns {Array} imageData - */ - function getImageData24bits(imageData, pixels, colormap, width, y_start, y_step, y_end, x_start, x_step, x_end) { - var offset, i, x, y; - var bpp = this.header.pixelDepth >> 3; - for (i = 0, y = y_start; y !== y_end; y += y_step) { - for (x = x_start; x !== x_end; x += x_step, i += bpp) { - offset = (x + width * y) * 4; - imageData[offset + 3] = 255; // alpha - imageData[offset + 2] = pixels[i ]; // blue - imageData[offset + 1] = pixels[i + 1]; // green - imageData[offset ] = pixels[i + 2]; // red - } - } +/** + * 행우선 배열 방식의 4차원 행렬을 제공한다. + * + * @returns {Float32Array} 행우선 4차원 행렬 + * + * @see Matrix4#get + */ +Matrix4.prototype.getRowMajorMatrix = function() +{ + var rowMajor_matrix = new Float32Array(16); - return imageData; - } + rowMajor_matrix[0] = this.get(0, 0); + rowMajor_matrix[1] = this.get(1, 0); + rowMajor_matrix[2] = this.get(2, 0); + rowMajor_matrix[3] = this.get(3, 0); + rowMajor_matrix[4] = this.get(0, 1); + rowMajor_matrix[5] = this.get(1, 1); + rowMajor_matrix[6] = this.get(2, 1); + rowMajor_matrix[7] = this.get(3, 1); - /** - * Return a ImageData object from a TGA file (32bits) - * - * @param {Array} imageData - ImageData to bind - * @param {Array} pixels data from TGA file - * @param {Array} colormap - not used - * @param {number} width - * @param {number} y_start - start at y pixel. - * @param {number} x_start - start at x pixel. - * @param {number} y_step - increment y pixel each time. - * @param {number} y_end - stop at pixel y. - * @param {number} x_step - increment x pixel each time. - * @param {number} x_end - stop at pixel x. - * @returns {Array} imageData - */ - function getImageData32bits(imageData, pixels, colormap, width, y_start, y_step, y_end, x_start, x_step, x_end) { - var i, x, y, offset; + rowMajor_matrix[8] = this.get(0, 2); + rowMajor_matrix[9] = this.get(1, 2); + rowMajor_matrix[10] = this.get(2, 2); + rowMajor_matrix[11] = this.get(3, 2); - for (i = 0, y = y_start; y !== y_end; y += y_step) { - for (x = x_start; x !== x_end; x += x_step, i += 4) { - offset = (x + width * y) * 4; - imageData[offset + 2] = pixels[i ]; // blue - imageData[offset + 1] = pixels[i + 1]; // green - imageData[offset ] = pixels[i + 2]; // red - imageData[offset + 3] = pixels[i + 3]; // alpha - } - } + rowMajor_matrix[12] = this.get(0, 3); + rowMajor_matrix[13] = this.get(1, 3); + rowMajor_matrix[14] = this.get(2, 3); + rowMajor_matrix[15] = this.get(3, 3); - return imageData; - } + return rowMajor_matrix; +}; - /** - * Return a ImageData object from a TGA file (32bits). Uses pre multiplied alpha values - * - * @param {Array} imageData - ImageData to bind - * @param {Array} pixels data from TGA file - * @param {Array} colormap - not used - * @param {number} width - * @param {number} y_start - start at y pixel. - * @param {number} x_start - start at x pixel. - * @param {number} y_step - increment y pixel each time. - * @param {number} y_end - stop at pixel y. - * @param {number} x_step - increment x pixel each time. - * @param {number} x_end - stop at pixel x. - * @returns {Array} imageData - */ - function getImageData32bitsPre(imageData, pixels, colormap, width, y_start, y_step, y_end, x_start, x_step, x_end) { - var i, x, y, offset, alpha; +/** + * XYZ축에 대한 회전양에 따라 회전된 4차원 행렬을 구한다. + * + * @param {Number} zRotDeg z축에 대한 회전양(Degree) + * @param {Number} xRotDeg x축에 대한 회전양(Degree) + * @param {Number} yRotDeg y축에 대한 회전양(Degree) + * @param {Matrix4} result 회전된 4차원 행렬 + * @returns {Matrix4} 회전된 4차원 행렬 + * + * @see Matrix4#rotationAxisAngDeg + * @see Matrix4#getMultipliedByMatrix + */ +Matrix4.getRotationDegZXYMatrix = function(zRotDeg, xRotDeg, yRotDeg, result) +{ + // created as identity matrix. + if (result === undefined) + { + result = new Matrix4(); + } - for (i = 0, y = y_start; y !== y_end; y += y_step) { - for (x = x_start; x !== x_end; x += x_step, i += 4) { - offset = (x + width * y) * 4; - alpha = pixels[i + 3] * 255; // TODO needs testing - imageData[offset + 2] = pixels[i ] / alpha; // blue - imageData[offset + 1] = pixels[i + 1] / alpha; // green - imageData[offset ] = pixels[i + 2] / alpha; // red - imageData[offset + 3] = pixels[i + 3]; // alpha - } - } + var xRotMatrix = new Matrix4(); // created as identity matrix. + var yRotMatrix = new Matrix4(); // created as identity matrix. + var zRotMatrix = new Matrix4(); // created as identity matrix. + + + if (xRotDeg !== undefined && xRotDeg !== 0) + { xRotMatrix.rotationAxisAngDeg(xRotDeg, 1.0, 0.0, 0.0); } + + if (yRotDeg !== undefined && yRotDeg !== 0) + { yRotMatrix.rotationAxisAngDeg(yRotDeg, 0.0, 1.0, 0.0); } + + if (zRotDeg !== undefined && zRotDeg !== 0) + { zRotMatrix.rotationAxisAngDeg(zRotDeg, 0.0, 0.0, 1.0); } - return imageData; - } + var zRotatedTMatrix; + var zxRotatedTMatrix; + var zxyRotatedTMatrix; + zRotatedTMatrix = zRotMatrix; + zxRotatedTMatrix = xRotMatrix.getMultipliedByMatrix(zRotatedTMatrix, zxRotatedTMatrix); + zxyRotatedTMatrix = yRotMatrix.getMultipliedByMatrix(zxRotatedTMatrix, zxyRotatedTMatrix); + + result = zxyRotatedTMatrix; - /** - * Return a ImageData object from a TGA file (8bits grey) - * - * @param {Array} imageData - ImageData to bind - * @param {Array} pixels data - * @param {Array} colormap - not used - * @param {number} width - * @param {number} y_start - start at y pixel. - * @param {number} x_start - start at x pixel. - * @param {number} y_step - increment y pixel each time. - * @param {number} y_end - stop at pixel y. - * @param {number} x_step - increment x pixel each time. - * @param {number} x_end - stop at pixel x. - * @returns {Array} imageData - */ - function getImageDataGrey8bits(imageData, pixels, colormap, width, y_start, y_step, y_end, x_start, x_step, x_end) { - var color, offset, i, x, y; + return result; +}; - for (i = 0, y = y_start; y !== y_end; y += y_step) { - for (x = x_start; x !== x_end; x += x_step, i++) { - color = pixels[i]; - offset = (x + width * y) * 4; - imageData[offset ] = color; // red - imageData[offset + 1] = color; // green - imageData[offset + 2] = color; // blue - imageData[offset + 3] = 255; // alpha - } - } +/** + * 좌표값과 회전양을 통해 회전된 4차원 행렬을 구한다. + * + * @param {Number} angDeg 회전양(Degree) + * @param {Number} axis_x X축 좌표 + * @param {Number} axis_y Y축 좌표 + * @param {Number} axis_z Z축 좌표 + * + * @see Quaternion + * @see Quaternion#rotationAngDeg + * @see Matrix4#rotationByQuaternion + */ +Matrix4.prototype.rotationAxisAngDeg = function(angDeg, axis_x, axis_y, axis_z) +{ + var quaternion = new Quaternion(); + quaternion.rotationAngDeg(angDeg, axis_x, axis_y, axis_z); + this.rotationByQuaternion(quaternion); + quaternion = undefined; +}; - return imageData; - } +/** + * 좌표값과 회전양을 통해 회전된 4차원 행렬을 구한다. + * + * @param {Number} angRad 회전양(Radian) + * @param {Number} axis_x X축 좌표 + * @param {Number} axis_y Y축 좌표 + * @param {Number} axis_z Z축 좌표 + * + * @see Quaternion + * @see Quaternion#rotationAngRad + * @see Matrix4#rotationByQuaternion + */ +Matrix4.prototype.rotationAxisAngRad = function(angRad, axis_x, axis_y, axis_z) +{ + var quaternion = new Quaternion(); + quaternion.rotationAngRad(angRad, axis_x, axis_y, axis_z); + this.rotationByQuaternion(quaternion); + quaternion = undefined; +}; +/** + * 쿼터니언(사원수)을 통한 회전된 4차원 행렬을 구한다. + * + * @param {Quaternion} quaternion 사원수 + */ +Matrix4.prototype.rotationByQuaternion = function(quaternion) +{ + var x = quaternion.x; + var y = quaternion.y; + var z = quaternion.z; + var w = quaternion.w; - /** - * Return a ImageData object from a TGA file (16bits grey) 8 Bit RGB and 8 Bit Alpha - * - * @param {Array} imageData - ImageData to bind - * @param {Array} pixels data - * @param {Array} colormap - not used - * @param {number} width - * @param {number} y_start - start at y pixel. - * @param {number} x_start - start at x pixel. - * @param {number} y_step - increment y pixel each time. - * @param {number} y_end - stop at pixel y. - * @param {number} x_step - increment x pixel each time. - * @param {number} x_end - stop at pixel x. - * @returns {Array} imageData - */ - function getImageDataGrey16bits(imageData, pixels, colormap, width, y_start, y_step, y_end, x_start, x_step, x_end) { - var color, offset, i, x, y; + this._floatArrays[this.getIndexOfArray(0, 0)] = 1 - 2*y*y - 2*z*z; + this._floatArrays[this.getIndexOfArray(0, 1)] = 2*x*y + 2*z*w; + this._floatArrays[this.getIndexOfArray(0, 2)] = 2*x*z - 2*y*w; + this._floatArrays[this.getIndexOfArray(0, 3)] = 0.0; - for (i = 0, y = y_start; y !== y_end; y += y_step) { - for (x = x_start; x !== x_end; x += x_step, i += 2) { - color = pixels[i]; - offset = (x + width * y) * 4; - imageData[offset] = color; - imageData[offset + 1] = color; - imageData[offset + 2] = color; - imageData[offset + 3] = pixels[i + 1]; - } - } + this._floatArrays[this.getIndexOfArray(1, 0)] = 2*x*y - 2*z*w; + this._floatArrays[this.getIndexOfArray(1, 1)] = 1 - 2*x*x - 2*z*z; + this._floatArrays[this.getIndexOfArray(1, 2)] = 2*y*z + 2*x*w; + this._floatArrays[this.getIndexOfArray(1, 3)] = 0.0; - return imageData; - } + this._floatArrays[this.getIndexOfArray(2, 0)] = 2*x*z + 2*y*w; + this._floatArrays[this.getIndexOfArray(2, 1)] = 2*y*z - 2*x*w; + this._floatArrays[this.getIndexOfArray(2, 2)] = 1 - 2*x*x - 2*y*y; + this._floatArrays[this.getIndexOfArray(2, 3)] = 0.0; + this._floatArrays[this.getIndexOfArray(3, 0)] = 0.0; + this._floatArrays[this.getIndexOfArray(3, 1)] = 0.0; + this._floatArrays[this.getIndexOfArray(3, 2)] = 0.0; + this._floatArrays[this.getIndexOfArray(3, 3)] = 1.0; +}; - /** - * Open a targa file using XHR, be aware with Cross Domain files... - * - * @param {string} path - Path of the filename to load - * @param {function} callback - callback to trigger when the file is loaded - */ - Targa.prototype.open = function targaOpen(path, callback) { - var req, tga = this; - req = new XMLHttpRequest(); - req.open('GET', path, true); - req.responseType = 'arraybuffer'; - req.onload = function () { - if (this.status === 200) { - tga.arrayBuffer = req.response; - tga.load(tga.arrayBuffer); - if (callback) { - callback.call(tga); - } - } - }; - req.send(null); - }; - - - function readFooter(view) { - var offset = view.byteLength - Targa.FOOTER_SIZE; - var signature = Targa.SIGNATURE; - - var footer = {}; - - var signatureArray = new Uint8Array(view.buffer, offset + 0x08, signature.length); - var str = String.fromCharCode.apply(null, signatureArray); - - if (!isSignatureValid(str)) { - footer.hasFooter = false; - return footer; - } - - footer.hasFooter = true; - footer.extensionOffset = view.getUint32(offset, Targa.LITTLE_ENDIAN); - footer.developerOffset = view.getUint32(offset + 0x04, Targa.LITTLE_ENDIAN); - footer.hasExtensionArea = footer.extensionOffset !== 0; - footer.hasDeveloperArea = footer.developerOffset !== 0; - - if (footer.extensionOffset) { - footer.attributeType = view.getUint8(footer.extensionOffset + 494); - } - - return footer; - } - - function isSignatureValid(str) { - var signature = Targa.SIGNATURE; - - for (var i = 0; i < signature.length; i++) { - if (str.charCodeAt(i) !== signature.charCodeAt(i)) { - return false; - } - } - - return true; - } - - /** - * Load and parse a TGA file - * - * @param {ArrayBuffer} data - TGA file buffer array - */ - Targa.prototype.load = function targaLoad(data) { - var dataView = new DataView(data); - - this.headerData = new Uint8Array(data, 0, Targa.HEADER_SIZE); - - this.header = readHeader(dataView); // Parse Header - setHeaderBooleans(this.header); - checkHeader(this.header); // Check if a valid TGA file (or if we can load it) - - var offset = Targa.HEADER_SIZE; - // Move to data - offset += this.header.idLength; - if (offset >= data.byteLength) { - throw new Error('Targa::load() - No data'); - } - - // Read palette - if (this.header.hasColorMap) { - var colorMapSize = this.header.colorMapLength * (this.header.colorMapDepth >> 3); - this.palette = new Uint8Array(data, offset, colorMapSize); - offset += colorMapSize; - } - - var bytesPerPixel = this.header.pixelDepth >> 3; - var imageSize = this.header.width * this.header.height; - var pixelTotal = imageSize * bytesPerPixel; - - if (this.header.hasEncoding) { // RLE encoded - var RLELength = data.byteLength - offset - Targa.FOOTER_SIZE; - var RLEData = new Uint8Array(data, offset, RLELength); - this.imageData = decodeRLE(RLEData, bytesPerPixel, pixelTotal); - } else { // RAW pixels - this.imageData = new Uint8Array(data, offset, this.header.hasColorMap ? imageSize : pixelTotal); - } - - this.footer = readFooter(dataView); - - if (this.header.alphaBits !== 0 || this.footer.hasExtensionArea && (this.footer.attributeType === 3 || this.footer.attributeType === 4)) { - this.footer.usesAlpha = true; - } - }; - - - /** - * Return a ImageData object from a TGA file - * - * @param {object} imageData - Optional ImageData to work with - * @returns {object} imageData - */ - Targa.prototype.getImageData = function targaGetImageData(imageData) { - var width = this.header.width; - var height = this.header.height; - var origin = (this.header.flags & Targa.Origin.MASK) >> Targa.Origin.SHIFT; - var x_start, x_step, x_end, y_start, y_step, y_end; - var getImageData; - - // Create an imageData - if (!imageData) { - if (document) { - imageData = document.createElement('canvas').getContext('2d').createImageData(width, height); - } - // In Thread context ? - else { - imageData = { - width: width, - height: height, - data: new Uint8ClampedArray(width * height * 4) - }; - } - } - - if (origin === Targa.Origin.TOP_LEFT || origin === Targa.Origin.TOP_RIGHT) { - y_start = 0; - y_step = 1; - y_end = height; - } - else { - y_start = height - 1; - y_step = -1; - y_end = -1; - } - - if (origin === Targa.Origin.TOP_LEFT || origin === Targa.Origin.BOTTOM_LEFT) { - x_start = 0; - x_step = 1; - x_end = width; - } - else { - x_start = width - 1; - x_step = -1; - x_end = -1; - } - - // TODO: use this.header.offsetX and this.header.offsetY ? - - switch (this.header.pixelDepth) { - case 8: - getImageData = this.header.isGreyColor ? getImageDataGrey8bits : getImageData8bits; - break; - - case 16: - getImageData = this.header.isGreyColor ? getImageDataGrey16bits : getImageData16bits; - break; - - case 24: - getImageData = getImageData24bits; - break; - - case 32: - if (this.footer.hasExtensionArea) { - if (this.footer.attributeType === 3) { // straight alpha - getImageData = getImageData32bits; - } else if (this.footer.attributeType === 4) { // pre multiplied alpha - getImageData = getImageData32bitsPre; - } else { // ignore alpha values if attributeType set to 0, 1, 2 - getImageData = getImageData24bits; - } - } else { - if (this.header.alphaBits !== 0) { - getImageData = getImageData32bits; - } else { // 32 bits Depth, but alpha Bits set to 0 - getImageData = getImageData24bits; - } - } - - break; - } - - getImageData.call(this, imageData.data, this.imageData, this.palette, width, y_start, y_step, y_end, x_start, x_step, x_end); - return imageData; - }; - - /** (Experimental) - * Encodes imageData into TGA format - * Only TGA True Color 32 bit with optional RLE encoding is supported for now - * @param imageData - */ - Targa.prototype.setImageData = function targaSetImageData(imageData) { - - if (!imageData) { - throw new Error('Targa::setImageData() - imageData argument missing'); - } - - var width = this.header.width; - var height = this.header.height; - var expectedLength = width * height * (this.header.pixelDepth >> 3); - var origin = (this.header.flags & Targa.Origin.MASK) >> Targa.Origin.SHIFT; - var x_start, x_step, x_end, y_start, y_step, y_end; - - if (origin === Targa.Origin.TOP_LEFT || origin === Targa.Origin.TOP_RIGHT) { - y_start = 0; // start bottom, step upward - y_step = 1; - y_end = height; - } else { - y_start = height - 1; // start at top, step downward - y_step = -1; - y_end = -1; - } - - if (origin === Targa.Origin.TOP_LEFT || origin === Targa.Origin.BOTTOM_LEFT) { - x_start = 0; // start left, step right - x_step = 1; - x_end = width; - } else { - x_start = width - 1; // start right, step left - x_step = -1; - x_end = -1; - } - - if (!this.imageData) { - this.imageData = new Uint8Array(expectedLength); - } - - // start top left if origin is bottom left - // swapping order of first two arguments does the trick for writing - // this converts canvas data to internal tga representation - // this.imageData contains tga data - getImageData32bits(this.imageData, imageData.data, this.palette, width, y_start, y_step, y_end, x_start, x_step, x_end); - - var data = this.imageData; - - if (this.header.hasEncoding) { - data = encodeRLE(this.header, data); - } - - var bufferSize = Targa.HEADER_SIZE + data.length + Targa.FOOTER_SIZE; - var buffer = new ArrayBuffer(bufferSize); - - this.arrayBuffer = buffer; - // create array, useful for inspecting data while debugging - this.headerData = new Uint8Array(buffer, 0, Targa.HEADER_SIZE); - this.RLEData = new Uint8Array(buffer, Targa.HEADER_SIZE, data.length); - this.footerData = new Uint8Array(buffer, Targa.HEADER_SIZE + data.length, Targa.FOOTER_SIZE); - - var headerView = new DataView(this.headerData.buffer); - writeHeader(this.header, headerView); - this.RLEData.set(data); - writeFooter(this.footerData); - }; - - /** - * Return a canvas with the TGA render on it - * - * @returns {object} CanvasElement - */ - Targa.prototype.getCanvas = function targaGetCanvas() { - var canvas, ctx, imageData; - - canvas = document.createElement('canvas'); - ctx = canvas.getContext('2d'); - imageData = ctx.createImageData(this.header.width, this.header.height); - - canvas.width = this.header.width; - canvas.height = this.header.height; - - ctx.putImageData(this.getImageData(imageData), 0, 0); +/** + * Float32 형식의 4차원 행렬로 행렬값을 설정한다. + * + * @param {Float32Array} float32array + */ +Matrix4.prototype.setByFloat32Array = function(float32array) +{ + for (var i=0; i<16; i++) + { + this._floatArrays[i] = float32array[i]; + } +}; - return canvas; - }; +/** + * 열우선 방식으로 행렬의 인덱스값을 계산한다. + * + * @param {Number} col 열의 위치 + * @param {Number} row 행의 위치 + * @returns {Number} 행렬의 인덱스 + */ +Matrix4.prototype.getIndexOfArray = function(col, row) +{ + var _col = col || 0; + var _row = row || 0; + return 4 * _col + _row; +}; - /** - * Return a dataURI of the TGA file - * - * @param {string} type - Optional image content-type to output (default: image/png) - * @returns {string} url - */ - Targa.prototype.getDataURL = function targaGetDatURL(type) { - return this.getCanvas().toDataURL(type || 'image/png'); - }; +/** + * 지정된 행/열의 위치에 있는 값을 구한다. + * + * @param {Number} col 열의 위치 + * @param {Number} row 행의 위치 + * @returns {Number} 행렬값 + */ +Matrix4.prototype.get = function(col, row) +{ + return this._floatArrays[this.getIndexOfArray(col, row)]; +}; - /** - * Return a objectURL of the TGA file - * The url can be used in the download attribute of a link - * @returns {string} url - */ - Targa.prototype.getBlobURL = function targetGetBlobURL() { - if (!this.arrayBuffer) { - throw new Error('Targa::getBlobURL() - No data available for blob'); - } - var blob = new Blob([this.arrayBuffer], { type: "image/x-tga" }); - return URL.createObjectURL(blob); - }; +/** + * XYZ축으로 이동한다. + * + * @param {Number} x X축 이동량 + * @param {Number} y Y축 이동량 + * @param {Number} z Z축 이동량 + */ +Matrix4.prototype.setTranslation = function(x, y, z) +{ + this.set(3, 0, x); + this.set(3, 1, y); + this.set(3, 2, z); +}; - // Find Context - var shim = {}; - if (typeof(exports) === 'undefined') { - if (typeof(define) === 'function' && typeof(define.amd) === 'object' && define.amd) { - define(function () { - return Targa; - }); - } else { - // Browser - shim.exports = typeof(window) !== 'undefined' ? window : _global; - } - } - else { - // Commonjs - shim.exports = exports; - } +/** + * 4차원 행렬의 특정 위치의 값을 설정한다. + * + * @param {Number} col 열의 위치 + * @param {Number} row 행의 위치 + * @param {Number} value 설정값 + */ +Matrix4.prototype.set = function(col, row, value) +{ + this._floatArrays[this.getIndexOfArray(col, row)] = value; +}; +/** + * 행렬연산을 통해 주어진 포인트를 이동한다. + * + * @param {Point3D} point3d 입력 포인트 + * @param {Point3D} result 출력 포인트 + * @returns {Point3D} 출력 포인트 + */ +Matrix4.prototype.transformPoint3D = function(point3d, result) +{ + if (result === undefined) { result = new Point3D(); } - // Export - if (shim.exports) { - shim.exports.TGA = Targa; - } + var x = point3d.x; + var y = point3d.y; + var z = point3d.z; -})(this); + result.x = x*this.get(0, 0) + y*this.get(1, 0) + z*this.get(2, 0) + this.get(3, 0); + result.y = x*this.get(0, 1) + y*this.get(1, 1) + z*this.get(2, 1) + this.get(3, 1); + result.z = x*this.get(0, 2) + y*this.get(1, 2) + z*this.get(2, 2) + this.get(3, 2); -'use strict'; + return result; +}; /** - * 버퍼 안의 데이터를 어떻게 읽어야 할지 키가 되는 객체 - * - * @alias Accessor - * @class Accessor + * 행렬연산을 통해 주어진 포인트를 회전한다. + * + * @param {Point3D} point3d 입력 포인트 + * @param {Point3D} result 출력 포인트 + * @returns {Point3D} 출력 포인트 */ -var Accessor = function () +Matrix4.prototype.rotatePoint3D = function(point3d, result) { + if (result === undefined) { result = new Point3D(); } - if (!(this instanceof Accessor)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } + var x = point3d.x; + var y = point3d.y; + var z = point3d.z; - this.bufferId; - // 0= position, 1= normal, 2= color, 3= texcoord.*** - this.accesorType; - this.bufferStart; - // 버퍼의 시작 시점 - this.stride; - // character, int 등 - this.dataType; - // 2차원, 3차원 - this.dimension; + result.x = x*this.get(0, 0) + y*this.get(1, 0) + z*this.get(2, 0); + result.y = x*this.get(0, 1) + y*this.get(1, 1) + z*this.get(2, 1); + result.z = x*this.get(0, 2) + y*this.get(1, 2) + z*this.get(2, 2); - // 데이터가 포함되어 있는 x,y,z의 한계를 바운드라고 한다. 바운드 좌표 - this.minX = 0.0; - this.minY = 0.0; - this.minZ = 0.0; - this.maxX = 0.0; - this.maxY = 0.0; - this.maxZ = 0.0; + return result; }; -'use strict'; - /** - * 블럭 모델 - * @class Block + * From gl-matrix.js + * Generates a look-at matrix with the given eye position, focal point, and up axis + * + * @param {mat4} out mat4 frustum matrix will be written into + * @param {vec3} eye Position of the viewer + * @param {vec3} center Point the viewer is looking at + * @param {vec3} up vec3 pointing up + * @returns {mat4} out */ -var Block = function() -{ - if (!(this instanceof Block)) +Matrix4.lookAt = function(out, eye, center, up) +{ + var x0 = void 0, + x1 = void 0, + x2 = void 0, + y0 = void 0, + y1 = void 0, + y2 = void 0, + z0 = void 0, + z1 = void 0, + z2 = void 0, + len = void 0; + var eyex = eye[0]; + var eyey = eye[1]; + var eyez = eye[2]; + var upx = up[0]; + var upy = up[1]; + var upz = up[2]; + var centerx = center[0]; + var centery = center[1]; + var centerz = center[2]; + + if (Math.abs(eyex - centerx) < glMatrix.EPSILON && Math.abs(eyey - centery) < glMatrix.EPSILON && Math.abs(eyez - centerz) < glMatrix.EPSILON) + { + return glMatrix.mat4.identity(out); + } + + z0 = eyex - centerx; + z1 = eyey - centery; + z2 = eyez - centerz; + + len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2); + z0 *= len; + z1 *= len; + z2 *= len; + + x0 = upy * z2 - upz * z1; + x1 = upz * z0 - upx * z2; + x2 = upx * z1 - upy * z0; + len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2); + if (!len) + { + x0 = 0; + x1 = 0; + x2 = 0; + } + else { - throw new Error(Messages.CONSTRUCT_ERROR); + len = 1 / len; + x0 *= len; + x1 *= len; + x2 *= len; } - // This has "VertexIdxVBOArraysContainer" because the "indices" cannot to be greater than 65000, because indices are short type.*** - this.vBOVertexIdxCacheKeysContainer = new VBOVertexIdxCacheKeysContainer(); // Change this for "vbo_VertexIdx_CacheKeys_Container__idx".*** - this.mIFCEntityType = -1; - this.isSmallObj = false; - this.radius = 10; - this.vertexCount = 0; // only for test.*** delete this.*** + y0 = z1 * x2 - z2 * x1; + y1 = z2 * x0 - z0 * x2; + y2 = z0 * x1 - z1 * x0; + + len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2); + if (!len) + { + y0 = 0; + y1 = 0; + y2 = 0; + } + else + { + len = 1 / len; + y0 *= len; + y1 *= len; + y2 *= len; + } - this.lego; // legoBlock.*** + out[0] = x0; + out[1] = y0; + out[2] = z0; + out[3] = 0; + out[4] = x1; + out[5] = y1; + out[6] = z1; + out[7] = 0; + out[8] = x2; + out[9] = y2; + out[10] = z2; + out[11] = 0; + out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez); + out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez); + out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez); + out[15] = 1; + + return out; }; /** - * 블럭이 가지는 데이터 삭제 - * @returns block + * 4차원 행렬의 곱셈을 계산한다.(Rm = AmBm) + * Rm(j,i) = (AmBm)(j,i) = Sum( Am(j,k)*Bm(k,i) )(k=1,4) + * + * @param {Matrix4} matrix 입력 행렬(Am) + * @param {Matrix4} result 결과 행렬(Rm) + * @returns {Matrix4} 결과 행렬(Rm) */ -Block.prototype.deleteObjects = function(gl, vboMemManager) +Matrix4.prototype.getMultipliedByMatrix = function(matrix, result) { - this.vBOVertexIdxCacheKeysContainer.deleteGlObjects(gl, vboMemManager); - this.vBOVertexIdxCacheKeysContainer = undefined; - this.mIFCEntityType = undefined; - this.isSmallObj = undefined; - this.radius = undefined; - this.vertexCount = undefined; // only for test.*** delete this.*** - - if (this.lego) { this.lego.deleteGlObjects(gl); } + if (result === undefined) { result = new Matrix4(); } - this.lego = undefined; + for (var i=0; i<4; i++) + { + for (var j=0; j<4; j++) + { + var idx = this.getIndexOfArray(i, j); + result._floatArrays[idx] = 0.0; + for (var k=0; k<4; k++) + { + result._floatArrays[idx] += matrix.get(k, j) * this.get(i, k); + } + } + } + return result; }; /** - * 블록 목록 - * @class BlocksList + * 원근 투영 행렬을 생성한다. + * normalized device coordinates (NDC) uses the left-handed coordinate system + * Always use right-handed coordinate system + * + * @param {*} fovyrad Radian 단위의 시야각(Field of view) + * @param {*} aspect 화면비율(Aspect Ratio:가로값/세로값) + * @param {*} near 근거리 + * @param {*} far 원거리 + * + * @see http://ogldev.atspace.co.uk/www/tutorial12/tutorial12.html + * @see https://www.gamedev.net/articles/programming/graphics/perspective-projections-in-lh-and-rh-systems-r3598/ + * @see http://www.songho.ca/opengl/gl_projectionmatrix.html */ -var BlocksList = function() +Matrix4.prototype.setToPerspectiveProjection = function (fovyrad, aspect, near, far) { - if (!(this instanceof BlocksList)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } + var yScale = 1.0 / Math.tan(fovyrad / 2); + var xScale = yScale / aspect; + var zRange = near - far; - this.name = ""; - this.blocksArray; - // 0 = no started to load. 1 = started loading. 2 = finished loading. 3 = parse started. 4 = parse finished.*** - this.fileLoadState = CODE.fileLoadState.READY; - this.dataArraybuffer; // file loaded data, that is no parsed yet.*** + this.setByFloat32Array([xScale, 0, 0, 0, + 0, yScale, 0, 0, + 0, 0, (far + near) / zRange, -1, + 0, 0, 2*far*near / zRange, 0 ]); }; /** - * 새 블록 생성 - * @returns block + * 입력된 4차원 행렬로부터 행렬값을 복사한다. + * + * @param {Matrix4} matrix 4차원 행렬 */ -BlocksList.prototype.newBlock = function() +Matrix4.prototype.copyFromMatrix4 = function(matrix) { - if (this.blocksArray === undefined) { this.blocksArray = []; } - - var block = new Block(); - this.blocksArray.push(block); - return block; + for (var i=0; i<16; i++) + { + this._floatArrays[i] = matrix._floatArrays[i]; + } }; + /** - * 블록 획득 - * @param idx 변수 - * @returns block + * 입력된 배열로부터 4차원 행렬값을 복사한다. + * + * @param {Object[]} floatArrays 배열 */ -BlocksList.prototype.getBlock = function(idx) +Matrix4.prototype.copyFromFloatArray = function(floatArrays) { - if (this.blocksArray === undefined) { return null; } - - if (idx >= 0 && idx < this.blocksArray.length) + for (var i=0; i<16; i++) { - return this.blocksArray[idx]; + this._floatArrays[i] = floatArrays[i]; } - return null; }; /** - * 블록을 삭제 - * @param idx 변수 - * @returns block + * 행렬의 타입을 알려준다. + * + * @returns {Number} 행렬의 타입 */ -BlocksList.prototype.deleteGlObjects = function(gl, vboMemManager) +Matrix4.prototype.computeMatrixType = function() { - if (this.blocksArray === undefined) { return; } - - for (var i = 0, blocksCount = this.blocksArray.length; i < blocksCount; i++ ) + // matrixType = 0 -> identity matrix. + // matrixType = 1 -> translate matrix. + // matrixType = 2 -> transform matrix. + + var error = 10E-8; + if (this.isRotationIdentity()) { - var block = this.blocksArray[i]; - block.vBOVertexIdxCacheKeysContainer.deleteGlObjects(gl, vboMemManager); - block.vBOVertexIdxCacheKeysContainer = undefined; // Change this for "vbo_VertexIdx_CacheKeys_Container__idx".*** - block.mIFCEntityType = undefined; - block.isSmallObj = undefined; - block.radius = undefined; - block.vertexCount = undefined; // only for test.*** delete this.*** - if (block.lego) + // check if there are translation. + if (this.aproxEqual(this._floatArrays[3], 0, error)) { - block.lego.vbo_vicks_container.deleteGlObjects(gl, vboMemManager); - block.lego.vbo_vicks_container = undefined; + if (this.aproxEqual(this._floatArrays[7], 0, error)) + { + if (this.aproxEqual(this._floatArrays[11], 0, error)) + { + if (this.aproxEqual(this._floatArrays[12], 0, error)) + { + if (this.aproxEqual(this._floatArrays[13], 0, error)) + { + if (this.aproxEqual(this._floatArrays[14], 0, error)) + { + if (this.aproxEqual(this._floatArrays[15], 1, error)) + { + return 0; + } + else { return 1; } + } + else { return 1; } + } + else { return 1; } + } + else { return 1; } + } + else { return 1; } + } + else { return 1; } } - block.lego = undefined; // legoBlock.*** - this.blocksArray[i] = undefined; + else { return 1; } + } + else + { + return 2; } - this.blocksArray = undefined; - this.name = undefined; - this.fileLoadState = undefined; - this.dataArraybuffer = undefined; // file loaded data, that is no parsed yet.*** }; /** - * 블록리스트 버퍼를 파싱(비대칭적) - * This function parses the geometry data from binary arrayBuffer. - * - * @param {arrayBuffer} arrayBuffer Binary data to parse. - * @param {ReadWriter} readWriter Helper to read inside of the arrayBuffer. - * @param {Array} motherBlocksArray Global blocks array. + * 오차범위내에 두 값의 동일 여부를 확인한다. + * Returns if the value is aproximately equal to the valueToCompare with error. + * + * @param {Number} value 비교값 + * @param {Number} valueToCompare 비교값 + * @param {Number} error 오차율 + * @returns {Boolean} 비교값의 일치여부 */ -BlocksList.prototype.stepOverBlockVersioned = function(arrayBuffer, bytesReaded, readWriter) +Matrix4.prototype.aproxEqual = function(value, valueToCompare, error) { - var vertexCount; - var verticesFloatValuesCount; - var normalByteValuesCount; - var shortIndicesValuesCount; - var sizeLevels; - var startBuff, endBuff; + if (error === undefined) + { error = 10E-8; } - var vboDatasCount = readWriter.readInt32(arrayBuffer, bytesReaded, bytesReaded+4); - bytesReaded += 4; - for ( var j = 0; j < vboDatasCount; j++ ) + if (value === valueToCompare) { - // 1) Positions array. - vertexCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4);bytesReaded += 4; - verticesFloatValuesCount = vertexCount * 3; - startBuff = bytesReaded; - endBuff = bytesReaded + 4 * verticesFloatValuesCount; - bytesReaded = bytesReaded + 4 * verticesFloatValuesCount; // updating data.*** - - // 2) Normals. - vertexCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4);bytesReaded += 4; - normalByteValuesCount = vertexCount * 3; - bytesReaded = bytesReaded + 1 * normalByteValuesCount; // updating data.*** - - // 3) Indices. - shortIndicesValuesCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4);bytesReaded += 4; - sizeLevels = readWriter.readUInt8(arrayBuffer, bytesReaded, bytesReaded+1);bytesReaded += 1; - bytesReaded = bytesReaded + sizeLevels * 4; - bytesReaded = bytesReaded + sizeLevels * 4; - bytesReaded = bytesReaded + 2 * shortIndicesValuesCount; // updating data.*** + return true; + } + else + { + if (value > (valueToCompare - error) && value < (valueToCompare + error)) + { return true; } + else + { return false; } } - - return bytesReaded; }; /** - * 블록리스트 버퍼를 파싱(비대칭적) - * This function parses the geometry data from binary arrayBuffer. - * - * @param {arrayBuffer} arrayBuffer Binary data to parse. - * @param {ReadWriter} readWriter Helper to read inside of the arrayBuffer. - * @param {Array} motherBlocksArray Global blocks array. + * 두 배열의 일치여부를 확인한다. + * Returns if the arrayA equal to the arrayB. + * + * @param {Object[]} arrayA + * @param {Object[]} arrayB + * @returns {Boolean} 두 배열의 일치여부 */ -BlocksList.prototype.parseBlockVersioned = function(arrayBuffer, bytesReaded, block, readWriter, magoManager) +Matrix4.areEqualArrays = function(arrayA, arrayB) { - var posByteSize; - var norByteSize; - var idxByteSize; - var classifiedPosByteSize; - var classifiedNorByteSize; - var classifiedIdxByteSize; - var startBuff, endBuff; - var vboMemManager = magoManager.vboMemoryManager; - - var vboDatasCount = readWriter.readInt32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; - for ( var j = 0; j < vboDatasCount; j++ ) + var areEqual = true; + var i=0; + while (areEqual && i<16) { - // 1) Positions array. - var vertexCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; - var verticesFloatValuesCount = vertexCount * 3; - // now padding the array to adjust to standard memory size of pool. - //posByteSize = 4 * verticesFloatValuesCount; - posByteSize = verticesFloatValuesCount; - classifiedPosByteSize = vboMemManager.getClassifiedBufferSize(posByteSize); - - block.vertexCount = vertexCount; - startBuff = bytesReaded; - endBuff = bytesReaded + 4 * verticesFloatValuesCount; - var vboViCacheKey = block.vBOVertexIdxCacheKeysContainer.newVBOVertexIdxCacheKey(); - vboViCacheKey.posVboDataArray = new Float32Array(classifiedPosByteSize); - vboViCacheKey.posVboDataArray.set(new Float32Array(arrayBuffer.slice(startBuff, endBuff))); - vboViCacheKey.posArrayByteSize = classifiedPosByteSize; - bytesReaded = bytesReaded + 4 * verticesFloatValuesCount; // updating data.*** - - // 2) Normals. - vertexCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; - var normalByteValuesCount = vertexCount * 3; - // now padding the array to adjust to standard memory size of pool. - norByteSize = 1 * normalByteValuesCount; - classifiedNorByteSize = vboMemManager.getClassifiedBufferSize(norByteSize); - - startBuff = bytesReaded; - endBuff = bytesReaded + 1 * normalByteValuesCount; - vboViCacheKey.norVboDataArray = new Int8Array(classifiedNorByteSize); - vboViCacheKey.norVboDataArray.set(new Int8Array(arrayBuffer.slice(startBuff, endBuff))); - vboViCacheKey.norArrayByteSize = classifiedNorByteSize; - bytesReaded = bytesReaded + 1 * normalByteValuesCount; // updating data.*** - - // 3) Indices. - var shortIndicesValuesCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; - // now padding the array to adjust to standard memory size of pool. - //idxByteSize = 2 * shortIndicesValuesCount; - idxByteSize = shortIndicesValuesCount; - classifiedIdxByteSize = vboMemManager.getClassifiedBufferSize(idxByteSize); - - var sizeLevels = readWriter.readUInt8(arrayBuffer, bytesReaded, bytesReaded+1); bytesReaded +=1; - var sizeThresholds = []; - for ( var k = 0; k < sizeLevels; k++ ) - { - sizeThresholds.push(new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4))); bytesReaded += 4; - } - var indexMarkers = []; - for ( var k = 0; k < sizeLevels; k++ ) + if (arrayA[i] !== arrayB[i]) { - indexMarkers.push(readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4)); bytesReaded += 4; + areEqual = false; } - var bigTrianglesShortIndicesValues_count = indexMarkers[sizeLevels-1]; - vboViCacheKey.bigTrianglesIndicesCount = bigTrianglesShortIndicesValues_count; - startBuff = bytesReaded; - endBuff = bytesReaded + 2 * shortIndicesValuesCount; - - vboViCacheKey.idxVboDataArray = new Int16Array(classifiedIdxByteSize); - vboViCacheKey.idxVboDataArray.set(new Int16Array(arrayBuffer.slice(startBuff, endBuff))); - vboViCacheKey.idxArrayByteSize = classifiedIdxByteSize; - bytesReaded = bytesReaded + 2 * shortIndicesValuesCount; // updating data.*** - vboViCacheKey.indicesCount = shortIndicesValuesCount; + i++; } - return bytesReaded; + return areEqual; }; /** - * 블록리스트 버퍼를 파싱(비대칭적) - * This function parses the geometry data from binary arrayBuffer. - * - * @param {arrayBuffer} arrayBuffer Binary data to parse. - * @param {ReadWriter} readWriter Helper to read inside of the arrayBuffer. - * @param {Array} motherBlocksArray Global blocks array. + * 회전/이동을 위한 단위행렬 여부를 확인한다. + * + * @param {Number} error + * @returns {Boolean} */ -BlocksList.prototype.parseBlocksListVersioned = function(arrayBuffer, readWriter, motherBlocksArray, magoManager) +Matrix4.prototype.isRotationIdentity = function(error) { - this.fileLoadState = CODE.fileLoadState.PARSE_STARTED; - var bytesReaded = 0; - var startBuff, endBuff; - var posByteSize, norByteSize, idxByteSize; - var vboMemManager = magoManager.vboMemoryManager; - var classifiedPosByteSize = 0, classifiedNorByteSize = 0, classifiedIdxByteSize = 0; - var gl = magoManager.sceneState.gl; - var succesfullyGpuDataBinded = true; - - // read the version. - var versionLength = 5; - var version = String.fromCharCode.apply(null, new Int8Array(arrayBuffer.slice(bytesReaded, bytesReaded+versionLength))); - bytesReaded += versionLength; - - var blocksCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded + 4); bytesReaded += 4; - for ( var i = 0; i< blocksCount; i++ ) + if (this.aproxEqual(this._floatArrays[0], 1, error)) { - var blockIdx = readWriter.readInt32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; - - // Check if block exist. - if (motherBlocksArray[blockIdx]) + if (this.aproxEqual(this._floatArrays[1], 0, error)) { - // The block exists, then read data but no create a new block. - bytesReaded += 4 * 6; // boundingBox. - // step over vbo datas of the model. - bytesReaded = this.stepOverBlockVersioned(arrayBuffer, bytesReaded, readWriter) ; - - // read lego if exist. (note: lego is exactly same of a model, is a mesh). - var existLego = readWriter.readUInt8(arrayBuffer, bytesReaded, bytesReaded+1); bytesReaded += 1; - if (existLego) + if (this.aproxEqual(this._floatArrays[2], 0, error)) { - bytesReaded = this.stepOverBlockVersioned(arrayBuffer, bytesReaded, readWriter) ; - } - - continue; - } - - // The block doesn't exist, so creates a new block and read data. - var block = new Block(); - block.idx = blockIdx; - motherBlocksArray[blockIdx] = block; - - // 1rst, read bbox. - var bbox = new BoundingBox(); - bbox.minX = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); bytesReaded += 4; - bbox.minY = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); bytesReaded += 4; - bbox.minZ = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); bytesReaded += 4; - - bbox.maxX = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); bytesReaded += 4; - bbox.maxY = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); bytesReaded += 4; - bbox.maxZ = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); bytesReaded += 4; - - var maxLength = bbox.getMaxLength(); - if (maxLength < 0.5) { block.isSmallObj = true; } - else { block.isSmallObj = false; } - - block.radius = maxLength/2.0; - - bbox.deleteObjects(); - bbox = undefined; - - bytesReaded = this.parseBlockVersioned(arrayBuffer, bytesReaded, block, readWriter, magoManager) ; - - // now bind vbo buffer datas. - var vboDatasCount = block.vBOVertexIdxCacheKeysContainer.vboCacheKeysArray.length; - for (var j=0; j X + // |----------|----------| |----------|----------| + if (this._subBoxesArray.length > 0) + { + var half_x= (this.maxX + this.minX)/2.0; + var half_y= (this.maxY + this.minY)/2.0; + var half_z= (this.maxZ + this.minZ)/2.0; + + this._subBoxesArray[0].setDimensions(this.minX, half_x, this.minY, half_y, this.minZ, half_z); + this._subBoxesArray[1].setDimensions(half_x, this.maxX, this.minY, half_y, this.minZ, half_z); + this._subBoxesArray[2].setDimensions(half_x, this.maxX, half_y, this.maxY, this.minZ, half_z); + this._subBoxesArray[3].setDimensions(this.minX, half_x, half_y, this.maxY, this.minZ, half_z); + this._subBoxesArray[4].setDimensions(this.minX, half_x, this.minY, half_y, half_z, this.maxZ); + this._subBoxesArray[5].setDimensions(half_x, this.maxX, this.minY, half_y, half_z, this.maxZ); + this._subBoxesArray[6].setDimensions(half_x, this.maxX, half_y, this.maxY, half_z, this.maxZ); + this._subBoxesArray[7].setDimensions(this.minX, half_x, half_y, this.maxY, half_z, this.maxZ); + + for (var i=0; i this.minX && x this.minY && y this.minZ && z 0) { - this.texture.deleteObjects(gl); + var center_x = (this.minX + this.maxX)/2.0; + var center_y = (this.minY + this.maxY)/2.0; + var center_z = (this.minZ + this.maxZ)/2.0; + + var intersectedSubBox_aux = undefined; + var intersectedSubBox_idx; + if (x 70000000) - { var hola = 0; } - - var vboMemManager = magoManager.vboMemoryManager; - this.fileLoadState = CODE.fileLoadState.PARSE_STARTED; - - this.bbox = new BoundingBox(); - var bbox = this.bbox; - var vboCacheKey = this.vbo_vicks_container.newVBOVertexIdxCacheKey(); - - // BoundingBox in float values.*** - bbox.minX = stream.readFloat32(); - bbox.minY = stream.readFloat32(); - bbox.minZ = stream.readFloat32(); - bbox.maxX = stream.readFloat32(); - bbox.maxY = stream.readFloat32(); - bbox.maxZ = stream.readFloat32(); - - // positionsBuffer.*** - // read bPositionsCompressed. If this var is true -> positions is in uShort).*** - this.bPositionsCompressed = stream.readInt8(); - var posByteSize = verticesCount * 3; - var classifiedPosByteSize = vboMemManager.getClassifiedBufferSize(posByteSize); - var positionBuffer; - - if (this.bPositionsCompressed) - { - positionBuffer = new Uint16Array(classifiedPosByteSize); - positionBuffer.set(stream.readUint16Array(verticesCount * 3)); - } - else - { - positionBuffer = new Float32Array(classifiedPosByteSize); - positionBuffer.set(stream.readFloat32Array(verticesCount * 3)); - } - - vboCacheKey.vertexCount = verticesCount; - vboCacheKey.posVboDataArray = positionBuffer; - vboCacheKey.posArrayByteSize = classifiedPosByteSize; - // (5120 : signed byte), (5121 : unsigned byte), (5122 : signed short), (5123 : unsigned short), (5126 : float).*** - vboCacheKey.posArrayByteType = 5123; // unsigned short.*** - - // normals.*** - this.hasNormals = stream.readInt8(); + var intersectedSubBox = this.getIntersectedSubBoxByPoint3D(eye_x, eye_y, eye_z); - // colors.*** - this.hasColors = stream.readInt8(); - if (this.hasColors) + if (intersectedSubBox !== undefined && intersectedSubBox._indicesArray.length > 0) { - var numColors = verticesCount; - var colByteSize = numColors * 4; - var classifiedColByteSize = vboMemManager.getClassifiedBufferSize(colByteSize); - var colorBuffer = new Uint8Array(classifiedColByteSize); - colorBuffer.set(stream.readUint8Array(numColors * 4)); - - vboCacheKey.colVboDataArray = colorBuffer; - vboCacheKey.colArrayByteSize = classifiedColByteSize; - vboCacheKey.colArrayByteType = 5121; // unsigned byte.*** + result_visibleIndicesArray = intersectedSubBox._indicesArray; + if (result_modelReferencedGroup) + { + result_modelReferencedGroup = this.modelReferencedGroupsList; + } } - // texCoords.*** - this.hasTexCoords = stream.readInt8(); - - // indices.*** - this.hasIndices = stream.readInt8(); - - this.fileLoadState = CODE.fileLoadState.PARSE_FINISHED; - + return result_visibleIndicesArray; }; /** - * F4D Lego 자료를 읽는다 - * - * @param {ArrayBuffer} buffer + * 어떤 일을 하고 있습니까? + * @param expansionDist 변수 */ -Lego.prototype.parseLegoData = function(buffer, gl, magoManager) +OcclusionCullingOctreeCell.prototype.expandBox = function(expansionDist) { - if (this.fileLoadState !== CODE.fileLoadState.LOADING_FINISHED) { return; } - - var vboMemManager = magoManager.vboMemoryManager; - - var stream = new DataStream(buffer, 0, DataStream.LITTLE_ENDIAN); - this.fileLoadState = CODE.fileLoadState.PARSE_STARTED; - - this.bbox = new BoundingBox(); - var bbox = this.bbox; - var vboCacheKey = this.vbo_vicks_container.newVBOVertexIdxCacheKey(); - - // BoundingBox - bbox.minX = stream.readFloat32(); - bbox.minY = stream.readFloat32(); - bbox.minZ = stream.readFloat32(); - bbox.maxX = stream.readFloat32(); - bbox.maxY = stream.readFloat32(); - bbox.maxZ = stream.readFloat32(); - - // VBO(Position Buffer) - x,y,z - var numPositions = stream.readUint32(); - var posByteSize = numPositions * 3; - var classifiedPosByteSize = vboMemManager.getClassifiedBufferSize(posByteSize); - var positionBuffer = new Float32Array(classifiedPosByteSize); - positionBuffer.set(stream.readFloat32Array(numPositions * 3)); - - vboCacheKey.vertexCount = numPositions; - vboCacheKey.posVboDataArray = positionBuffer; - vboCacheKey.posArrayByteSize = classifiedPosByteSize; - // (5120 : signed byte), (5121 : unsigned byte), (5122 : signed short), (5123 : unsigned short), (5126 : float).*** - //vboCacheKey.posArrayByteType = 5123; // unsigned short.*** + this.minX -= expansionDist; + this.maxX += expansionDist; + this.minY -= expansionDist; + this.maxY += expansionDist; + this.minZ -= expansionDist; + this.maxZ += expansionDist; +}; - // VBO(Normal Buffer) - i,j,k - var hasNormals = stream.readUint8(); - if (hasNormals) +/** + * 어떤 일을 하고 있습니까? + * @param arrayBuffer 변수 + * @param bytes_readed 변수 + * @param f4dReaderWriter 변수 + * @returns bytes_readed + */ +OcclusionCullingOctreeCell.prototype.parseArrayBuffer = function(arrayBuffer, bytes_readed, f4dReaderWriter) +{ + // Important note: this is the version of neoGeometry. + // Important note: this is the version of neoGeometry. + // Important note: this is the version of neoGeometry. + var is_mother_cell = f4dReaderWriter.readInt8(arrayBuffer, bytes_readed, bytes_readed+1); bytes_readed += 1; + if (is_mother_cell) { - var numNormals = stream.readUint32(); - var norByteSize = numNormals * 3; - var classifiedNorByteSize = vboMemManager.getClassifiedBufferSize(norByteSize); - var normalBuffer = new Int8Array(classifiedNorByteSize); - normalBuffer.set(stream.readInt8Array(numNormals * 3)); - - vboCacheKey.norVboDataArray = normalBuffer; - vboCacheKey.norArrayByteSize = classifiedNorByteSize; + // read the mother dimensions. + var minX = f4dReaderWriter.readFloat32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; + var maxX = f4dReaderWriter.readFloat32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; + var minY = f4dReaderWriter.readFloat32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; + var maxY = f4dReaderWriter.readFloat32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; + var minZ = f4dReaderWriter.readFloat32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; + var maxZ = f4dReaderWriter.readFloat32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; + + this.setDimensions(minX, maxX, minY, maxY, minZ, maxZ); } - - // VBO(Color Buffer) - r,g,b,a - var hasColors = stream.readUint8(); - if (hasColors) + + var subBoxes_count = f4dReaderWriter.readUInt32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; + + if (subBoxes_count === 0) { - var numColors = stream.readUint32(); - var colByteSize = numColors * 4; - var classifiedColByteSize = vboMemManager.getClassifiedBufferSize(colByteSize); - var colorBuffer = new Uint8Array(classifiedColByteSize); - colorBuffer.set(stream.readUint8Array(numColors * 4)); - - vboCacheKey.colVboDataArray = colorBuffer; - vboCacheKey.colArrayByteSize = classifiedColByteSize; + var objects_count = f4dReaderWriter.readUInt32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; + for (var i=0; i // there are parallels & the same sense. + // relativeOrientation = 1 -> // there are parallels & opposite sense. + // relativeOrientation = 2 -> // there are NO parallels. + var matrixAux = glMatrix.mat4.create(); // creates as identityMatrix. + if (relativeOrientation === 0) { - var loadData = this.lod2SkinDataMap[key]; - if (loadData.octree === undefined || loadData.octree.lego === undefined) - { continue; } - - loadData.octree.lego.fileLoadState = CODE.fileLoadState.READY; + // there are parallels & the same sense. + // In this case, the resultMatrix is a identityMatrix, so do nothing. } - - this.lod2SkinDataMap = {}; - - // Low lod meshes.*** - for (var key in this.lowLodSkinDataMap) + else if (relativeOrientation === 1) { - var loadData = this.lowLodSkinDataMap[key]; - if (loadData.skinMesh === undefined) - { continue; } - - loadData.skinMesh.fileLoadState = CODE.fileLoadState.READY; + // there are parallels & opposite sense. + // Rotate 180 degree in xAxis. + var identityMat = glMatrix.mat4.create(); + matrixAux = glMatrix.mat4.rotateX(matrixAux, identityMat, Math.PI); } - - this.lowLodSkinDataMap = {}; - - for (var key in this.lowLodSkinTextureMap) + else if (relativeOrientation === 2) { - var loadData = this.lowLodSkinTextureMap[key]; - if (loadData.texture === undefined) - { continue; } + // there are NO parallels. + // Calculate rotation axis. CrossProduct between initialNormal and the transformedNormal. + var rotAxis = initialNormal.crossProduct(transformedNormal, undefined); + rotAxis.unitary(); + var angRad = initialNormal.angleRadToVector(transformedNormal); + var axis = glMatrix.vec3.fromValues(rotAxis.x, rotAxis.y, rotAxis.z); + var quaternion = quat.create(); + quaternion = quat.setAxisAngle(quaternion, axis, angRad); - loadData.texture.fileLoadState = CODE.fileLoadState.READY; + // Now, make matrix4 from quaternion. + var identityMat = glMatrix.mat4.create(); + matrixAux = glMatrix.mat4.fromQuat(identityMat, quaternion); } - this.lowLodSkinTextureMap = {}; + if (resultTMatrix === undefined) + { resultTMatrix = new Matrix4(); } - for (var key in this.lod2PCloudDataMap) - { - var loadData = this.lod2PCloudDataMap[key]; - if (loadData.octree === undefined || loadData.octree.lego === undefined) - { continue; } - - loadData.octree.lego.fileLoadState = CODE.fileLoadState.READY; - } + resultTMatrix._floatArrays = matrixAux; - this.lod2PCloudDataMap = {}; + return resultTMatrix; }; -LoadQueue.prototype.manageQueue = function() +/** + * Get the point of the intersecting point of line and this plane + * @param line 변수 + * @param intersectionPoint 변수 + */ +Plane.prototype.intersectionLine = function(line, intersectionPoint) { - var maxFileLoad = 1; - var readerWriter = this.magoManager.readerWriter; - var gl = this.magoManager.sceneState.gl; - var counter = 0; - var remainLod2 = false; + var r = line.point.x; + var s = line.point.y; + var t = line.point.z; - // Lod2 meshes, 1rst load texture.***.*** - counter = 0; - for (var key in this.lod2SkinDataMap) - { - var loadData = this.lod2SkinDataMap[key]; - var octree = loadData.octree; - var filePath = loadData.filePath; - - if (octree.lego !== undefined) - { - if (loadData.texture !== undefined && loadData.texture.fileLoadState === CODE.fileLoadState.READY) - { - readerWriter.readLegoSimpleBuildingTexture(gl, loadData.texFilePath, loadData.texture, this.magoManager); - counter += 4; - } - - readerWriter.getOctreeLegoArraybuffer(filePath, octree, this.magoManager); - } - else - { var hola = 0; } - - delete this.lod2SkinDataMap[key]; - loadData.deleteObjects(); - loadData = undefined; - - counter++; - if (counter > 4) - { - //this.lod2SkinDataMap = {}; - remainLod2 = true; - break; - } - } + var u = line.direction.x; + var v = line.direction.y; + var w = line.direction.z; - if (this.magoManager.fileRequestControler.isFullPlusLowLodImages()) - { - return; - } + var den = this.a*u + this.b*v + this.c*w; - // Low lod meshes ( lod 3, 4, 5).*** - counter = 0; - for (var key in this.lowLodSkinTextureMap) + if (Math.abs(den) > 10E-8) { - var loadData = this.lowLodSkinTextureMap[key]; - var skinMesh = loadData.skinMesh; - var filePath = loadData.filePath; - readerWriter.readLegoSimpleBuildingTexture(gl, filePath, loadData.texture, this.magoManager); + var alfa = -((this.a*r + this.b*s + this.c*t + this.d)/(den)); - delete this.lowLodSkinTextureMap[key]; - loadData.deleteObjects(); - loadData = undefined; + if (intersectionPoint === undefined) { intersectionPoint = new Point3D(); } - counter++; - if (counter > maxFileLoad) - { break; } + intersectionPoint.set(r+alfa*u, s+alfa*v, t+alfa*w); + return intersectionPoint; } + else { return undefined; } +}; + +/** + * Check whether the given sphere is intersected with this plane or not + * @param sphere sphere + */ +Plane.prototype.intersectionSphere = function(sphere) +{ + if (sphere === undefined || sphere.centerPoint === undefined) + { return Constant.INTERSECTION_OUTSIDE; } - counter = 0; - for (var key in this.lowLodSkinDataMap) + var sphereCenter = sphere.centerPoint; + + // calculate the distance by dotProduct. + // sphere centerPoint = (x1, y1, z1), distance = |ax1 + by1 + cz1 + d|/sqrt(a*a +b*b + c*c*). + // note: the module sqrt(a*a +b*b + c*c*) = 1, so no necessary divide distance by module. + var distance = sphereCenter.x * this.a + sphereCenter.y * this.b + sphereCenter.z * this.c + this.d; + + if (distance < -sphere.r) { - var loadData = this.lowLodSkinDataMap[key]; - var skinMesh = loadData.skinMesh; - var filePath = loadData.filePath; - readerWriter.getLegoArraybuffer(filePath, skinMesh, this.magoManager); - - delete this.lowLodSkinDataMap[key]; - loadData.deleteObjects(); - loadData = undefined; - - counter++; - if (counter > maxFileLoad) - { break; } + return Constant.INTERSECTION_OUTSIDE; } - - // pCloud data.*** - counter = 0; - for (var key in this.lod2PCloudDataMap) + else if (distance < sphere.r) { - var loadData = this.lod2PCloudDataMap[key]; - var octree = loadData.octree; - var filePath = loadData.filePath; - - if (octree.lego !== undefined) - { - readerWriter.getOctreePCloudArraybuffer(filePath, octree, this.magoManager); - } - else - { var hola = 0; } - - delete this.lod2PCloudDataMap[key]; - loadData.deleteObjects(); - loadData = undefined; - - counter++; - if (counter > 4) - { - //this.lod2PCloudDataMap = {}; - remainLod2 = true; - break; - } + return Constant.INTERSECTION_INTERSECT; } - - this.resetQueue(); + return Constant.INTERSECTION_INSIDE; }; @@ -31917,5758 +29581,5787 @@ LoadQueue.prototype.manageQueue = function() - - - - - - - - - - - - - - - - - - - - - - - - 'use strict'; /** - * F4D LodBuildingData 클래스 + * 쿼터니언 * - * @alias LodBuildingData - * @class LodBuildingData + * @class */ -var LodBuildingData = function() +var Quaternion = function() { - if (!(this instanceof LodBuildingData)) + if (!(this instanceof Quaternion)) { throw new Error(Messages.CONSTRUCT_ERROR); } - this.lod; - this.isModelRef; - this.geometryFileName; - this.textureFileName; - //this.dataType; // no used yet.*** + /** + * x 속성값 + * @type {Number} + */ + this.x = 0.0; + + /** + * y 속성값 + * @type {Number} + */ + this.y = 0.0; + + /** + * z 속성값 + * @type {Number} + */ + this.z = 0.0; + + /** + * w 속성값 + * @type {Number} + */ + this.w = 1.0; }; -'use strict'; /** - * F4D MetaData 클래스 - * - * @alias MetaData - * @class MetaData + * 어떤 일을 하고 있습니까? + * @returns Math.sqrt(this.x*this.x + this.y*this.y + this.z*this.z + this.w*this.w ) */ -var MetaData = function() +Quaternion.prototype.Modul = function() { - if (!(this instanceof MetaData)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - this.guid; // must be undefined initially.*** - this.version = ""; - this.geographicCoord; // longitude, latitude, altitude.*** - - this.heading; - this.pitch; - this.roll; - - this.bbox; // BoundingBox.*** - this.imageLodCount; - - this.projectDataType; - this.offSetX; - this.offSetY; - this.offSetZ; - - // Buildings octree mother size.*** - this.oct_min_x = 0.0; - this.oct_max_x = 0.0; - this.oct_min_y = 0.0; - this.oct_max_y = 0.0; - this.oct_min_z = 0.0; - this.oct_max_z = 0.0; - - this.isSmall = false; - this.fileLoadState = CODE.fileLoadState.READY; + return Math.sqrt(this.x*this.x + this.y*this.y + this.z*this.z + this.w*this.w ); }; /** * 어떤 일을 하고 있습니까? - * @param arrayBuffer 변수 - * @param readWriter 변수 */ -MetaData.prototype.deleteObjects = function() +Quaternion.prototype.Unitary = function() { - this.guid = undefined; // must be undefined initially.*** - //this.version = undefined; - if (this.geographicCoord) - { this.geographicCoord.deleteObjects(); } - this.geographicCoord = undefined; // longitude, latitude, altitude.*** - - this.heading = undefined; - this.pitch = undefined; - this.roll = undefined; - - if (this.bbox) - { this.bbox.deleteObjects(); } - this.bbox = undefined; // BoundingBox.*** - this.imageLodCount = undefined; - - // Buildings octree mother size.*** - this.oct_min_x = undefined; - this.oct_max_x = undefined; - this.oct_min_y = undefined; - this.oct_max_y = undefined; - this.oct_min_z = undefined; - this.oct_max_z = undefined; - - this.isSmall = undefined; - this.fileLoadState = undefined; + var modul = this.Modul(); + this.x /= modul; + this.y /= modul; + this.z /= modul; + this.w /= modul; }; /** * 어떤 일을 하고 있습니까? - * @param arrayBuffer 변수 - * @param readWriter 변수 + * @param angDeg 변수 + * @param axis_x 변수 + * @param axis_y 변수 + * @param axis_z 변수 */ -MetaData.prototype.parseFileHeaderAsimetricVersion = function(arrayBuffer, readWriter) +Quaternion.prototype.rotationAngDeg = function(angDeg, axis_x, axis_y, axis_z) { - var version_string_length = 5; - var intAux_scratch = 0; - var bytes_readed = 0; - - if (readWriter === undefined) { readWriter = new ReaderWriter(); } - - // 1) Version(5 chars).*********** - this.version = ""; - for (var j=0; j 40.0 || this.bbox.maxY - this.bbox.minY > 40.0) - { - isLarge = true; - } + var angRad = angDeg*Math.PI/180.0; + this.rotationAngRad(angRad, axis_x, axis_y, axis_z); +}; - if (!isLarge && this.bbox.maxZ - this.bbox.minZ < 30.0) +/** + * 어떤 일을 하고 있습니까? + * @param angRad 변수 + * @param axis_x 변수 + * @param axis_y 변수 + * @param axis_z 변수 + */ +Quaternion.prototype.rotationAngRad = function(angRad, axis_x, axis_y, axis_z) +{ + var s = Math.sqrt(axis_x*axis_x + axis_y*axis_y + axis_z*axis_z); + var error = 10E-13; + if (!s < error) { - this.isSmall = true; + var c = 1.0/s; + var omega = 0.5 * angRad; + s = Math.sin(omega); + this.x = axis_x * c * s; + this.y = axis_y * c * s; + this.z = axis_z * c * s; + this.w = Math.cos(omega); + this.Unitary(); } - - // if header version is "0.0.2", then must read extra parameters.*** - if (this.version === "0.0.2") + else { - // parse dataType (unsigned short).*** - this.projectDataType = (new Uint16Array(arrayBuffer.slice(bytes_readed, bytes_readed+2)))[0]; bytes_readed += 2; - - // parse Project's offSet (double x 6).*** - this.offSetX = (new Float64Array(arrayBuffer.slice(bytes_readed, bytes_readed+8)))[0]; bytes_readed += 8; - this.offSetY = (new Float64Array(arrayBuffer.slice(bytes_readed, bytes_readed+8)))[0]; bytes_readed += 8; - this.offSetZ = (new Float64Array(arrayBuffer.slice(bytes_readed, bytes_readed+8)))[0]; bytes_readed += 8; + this.x = 0.0; + this.y = 0.0; + this.z = 0.0; + this.w = 1.0; } - - return bytes_readed; }; - - - - - - - - - - - - - - - - - - - - - - - - - 'use strict'; /** - * 어떤 일을 하고 있습니까? - * @class ModelReferencedGroup + * This class is used for color code of GL + * @class SelectionColor */ -var ModelReferencedGroup = function() +var SelectionColor = function() { - if (!(this instanceof ModelReferencedGroup)) + if (!(this instanceof SelectionColor)) { throw new Error(Messages.CONSTRUCT_ERROR); } - this.modelIdx; // there are only one model. - this.referencesIdxArray = []; // all references has the same model. + /** + * Color + * @type {Color} + */ + this.color = new Color(); }; - /** - * 어떤 일을 하고 있습니까? - * @class ModelReferencedGroupsList + * Initiate the color value of this feature */ -var ModelReferencedGroupsList = function() +SelectionColor.prototype.init = function() { - if (!(this instanceof ModelReferencedGroupsList)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - this.modelReferencedGroupsMap = []; - this.modelReferencedGroupsArray = []; + this.color.r = 0; + this.color.g = 0; + this.color.b = 0; + this.cycle = 0; }; /** - * 어떤 일을 하고 있습니까? - * @param treeDepth 변수 + * get the color code of given RGB color + * @param {Color} resultColor target color instance */ -ModelReferencedGroupsList.prototype.getModelReferencedGroup = function(modelIdx) +SelectionColor.prototype.getAvailableColor = function(resultColor) { - var modelReferencedGroup = this.modelReferencedGroupsMap[modelIdx]; + if (resultColor === undefined) + { resultColor = new Color(); } - if (modelReferencedGroup === undefined) - { - modelReferencedGroup = new ModelReferencedGroup(); - modelReferencedGroup.modelIdx = modelIdx; - this.modelReferencedGroupsMap[modelIdx] = modelReferencedGroup; - } - - return modelReferencedGroup; -}; - -/** - * 어떤 일을 하고 있습니까? - * @param treeDepth 변수 - */ -ModelReferencedGroupsList.prototype.makeModelReferencedGroupsArray = function() -{ - this.modelReferencedGroupsArray.length = 0; + resultColor.setRGB(this.color.r, this.color.g, this.color.b); - var modelRefGroupsCount = this.modelReferencedGroupsMap.length; - for (var i=0; i= 254) { - if (this.modelReferencedGroupsMap[i] !== undefined) - { this.modelReferencedGroupsArray.push(this.modelReferencedGroupsMap[i]); } + this.color.b = 0; + this.color.g += 1; + if (this.color.g >= 254) + { + this.color.g = 0; + this.color.r += 1; + if (this.color.r >= 254) + { + this.color.r = 0; + this.cycle += 1; + } + } } - this.modelReferencedGroupsMap.length = 0; + return resultColor; }; /** - * 어떤 일을 하고 있습니까? - * @param treeDepth 변수 + * Change the RGB code to color code. + * (255,255,255) is used to white color so 254 number is used + * @param {Number} r + * @param {Number} g + * @param {Number} b + * @returns Color code */ -ModelReferencedGroupsList.prototype.createModelReferencedGroups = function(neoRefsIndices, motherNeoRefsList) +SelectionColor.prototype.decodeColor3 = function(r, g, b) { - // Group all the references that has the same model. - if (neoRefsIndices === undefined) - { return; } - - if (motherNeoRefsList === undefined) - { return; } - - var referenceIdx; - var modelIdx; - var modelRefGroup; - var referencesCount = neoRefsIndices.length; - for (var i=0; i 0) { - legoSkin.deleteObjects(gl, vboMemoryManager); - legoSkin = undefined; + return true; } + i++; } + + return find; + }; + /** - * 어떤 일을 하고 있습니까? - * @param texture 변수 - * @returns texId + * 타일의 min max coord를 이용하여 타원체를 생성 후 this.sphereExtent에 할당 + * @param {MagoManager} magoManager + * + * @see SmartTile#computeSphereExtent */ -NeoBuilding.prototype.getBBoxCenterPositionWorldCoord = function(geoLoc) +SmartTile.prototype.makeSphereExtent = function(magoManager) { - if (this.bboxAbsoluteCenterPos === undefined) - { - this.calculateBBoxCenterPositionWorldCoord(geoLoc); - } - - return this.bboxAbsoluteCenterPos; + this.sphereExtent = SmartTile.computeSphereExtent(magoManager, this.minGeographicCoord, this.maxGeographicCoord, this.sphereExtent); }; /** - * 어떤 일을 하고 있습니까? - * @param texture 변수 - * @returns texId + * Sphere에 반지름과 중심점을 담아서 반환. + * @static + * @param {MagoManager} magoManager + * @param {GeographicCoord} minGeographicCoord + * @param {GeographicCoord} maxGeographicCoord + * @param {Sphere} resultSphereExtent + * + * @returns {Sphere} resultSphereExtent */ -NeoBuilding.prototype.calculateBBoxCenterPositionWorldCoord = function(geoLoc) +SmartTile.computeSphereExtent = function(magoManager, minGeographicCoord, maxGeographicCoord, resultSphereExtent) { - var bboxCenterPoint; + if (minGeographicCoord === undefined || maxGeographicCoord === undefined) + { return undefined; } - bboxCenterPoint = this.bbox.getCenterPoint(bboxCenterPoint); // local bbox. - this.bboxAbsoluteCenterPos = geoLoc.tMatrix.transformPoint3D(bboxCenterPoint, this.bboxAbsoluteCenterPos); + if (resultSphereExtent === undefined) + { resultSphereExtent = new Sphere(); } - // Now, must applicate the aditional translation vector. Aditional translation is made when we translate the pivot point. - if (geoLoc.pivotPointTraslation) - { - var traslationVector; - traslationVector = geoLoc.tMatrix.rotatePoint3D(geoLoc.pivotPointTraslation, traslationVector ); - this.bboxAbsoluteCenterPos.add(traslationVector.x, traslationVector.y, traslationVector.z); - } + // calculate worldCoord center position. + var midLongitude = (maxGeographicCoord.longitude + minGeographicCoord.longitude)/2; + var midLatitude = (maxGeographicCoord.latitude + minGeographicCoord.latitude)/2; + var midAltitude = (maxGeographicCoord.altitude + minGeographicCoord.altitude)/2; + + resultSphereExtent.centerPoint = ManagerUtils.geographicCoordToWorldPoint(midLongitude, midLatitude, midAltitude, resultSphereExtent.centerPoint, magoManager); + + // calculate an aproximate radius. + var cornerPoint; + cornerPoint = ManagerUtils.geographicCoordToWorldPoint(minGeographicCoord.longitude, minGeographicCoord.latitude, minGeographicCoord.altitude, cornerPoint, magoManager); + + resultSphereExtent.r = resultSphereExtent.centerPoint.distTo(cornerPoint.x, cornerPoint.y, cornerPoint.z) * 1.1; + return resultSphereExtent; }; /** * 어떤 일을 하고 있습니까? - * @param texture 변수 - * @returns texId + * @param geoLocData 변수 */ -NeoBuilding.prototype.getTextureId = function(texture) +SmartTile.prototype.putNode = function(targetDepth, node, magoManager) { - var texId; - var texturesLoadedCount = this.texturesLoaded.length; - var find = false; - var i=0; - while (!find && i < texturesLoadedCount ) + if (this.sphereExtent === undefined) + { this.makeSphereExtent(magoManager); } + + // now, if the current depth < targetDepth, then descend. + if (this.depth < targetDepth) { - if (this.texturesLoaded[i].textureImageFileName === texture.textureImageFileName) + // create 4 child smartTiles. + if (this.subTiles === undefined || this.subTiles.length === 0) { - find = true; - texId = this.texturesLoaded[i].texId; + for (var i=0; i<4; i++) + { this.newSubTile(this); } } - i++; - } + + // set the sizes to subTiles (The minLongitude, MaxLongitude, etc. is constant, but the minAlt & maxAlt can will be modified every time that insert new buildingSeeds). + this.setSizesToSubTiles(); - return texId; + // intercept buildingSeeds for each subTiles. + var subSmartTile; + var finish = false; + var i=0; + while (!finish && i<4) + { + subSmartTile = this.subTiles[i]; + if (subSmartTile.intersectsNode(node)) + { + subSmartTile.putNode(targetDepth, node, magoManager); + finish = true; + } + + i++; + } + } + else if (this.depth === targetDepth) + { + if (this.nodeSeedsArray === undefined) + { this.nodeSeedsArray = []; } + + if (this.nodesArray === undefined) + { this.nodesArray = []; } + + node.data.smartTileOwner = this; + + this.nodeSeedsArray.push(node); + this.nodesArray.push(node); + + // todo: Must recalculate the smartTile sphereExtent. + //this.makeSphereExtent(magoManager); + + + return true; + } }; /** - * 어떤 일을 하고 있습니까? - * @param texture 변수 - * @returns texId + * 목표레벨까지 각 타일의 SUB타일 생성 및 노드의 위치와 교점이 있는지 파악 후 노드를 보관. + * @param {Number} targetDepth + * @param {MagoManager} magoManager */ -NeoBuilding.prototype.getSameTexture = function(texture) +SmartTile.prototype.makeTreeByDepth = function(targetDepth, magoManager) { - var sameTexture; - var texturesLoadedCount = this.texturesLoaded.length; - var find = false; - var i=0; - while (!find && i < texturesLoadedCount ) + if (this.nodeSeedsArray === undefined || this.nodeSeedsArray.length === 0) + { return; } + + this.targetDepth = targetDepth; + + // if this has "nodeSeedsArray" then make sphereExtent. + this.makeSphereExtent(magoManager); + + // now, if the current depth < targetDepth, then descend. + if (this.depth < targetDepth) { - if (this.texturesLoaded[i].textureImageFileName === texture.textureImageFileName) + // create 4 child smartTiles. + if (this.subTiles === undefined || this.subTiles.length === 0) { - find = true; - sameTexture = this.texturesLoaded[i]; + for (var i=0; i<4; i++) + { this.newSubTile(this); } } - i++; - } - - return sameTexture; -}; + + // set the sizes to subTiles (The minLongitude, MaxLongitude, etc. is constant, but the minAlt & maxAlt can will be modified every time that insert new buildingSeeds). + this.setSizesToSubTiles(); -/** - * 어떤 일을 하고 있습니까? - * @param eyeX 변수 - * @param eyeY 변수 - * @param eyeZ 변수 - */ -NeoBuilding.prototype.updateCurrentVisibleIndicesExterior = function(eyeX, eyeY, eyeZ) -{ - this._neoRefLists_Container.updateCurrentVisibleIndicesOfLists(eyeX, eyeY, eyeZ); + // intercept buildingSeeds for each subTiles. + for (var i=0; i<4; i++) + { + this.subTiles[i].takeIntersectedBuildingSeeds(this.nodeSeedsArray, magoManager); + } + + // for each subTile that has intercepted buildingSeeds -> makeTree. + for (var i=0; i<4; i++) + { + this.subTiles[i].makeTreeByDepth(targetDepth, magoManager); + } + + } }; /** * 어떤 일을 하고 있습니까? + * @param geoLocData 변수 */ -NeoBuilding.prototype.updateCurrentAllIndicesExterior = function() +/* +SmartTile.prototype.getLowestTileWithNodeInside = function(node) { - this._neoRefLists_Container.updateCurrentAllIndicesOfLists(); + // this function returns the lowestTile with "node" if exist. + if (this.subTiles === undefined) + { + var nodesCount = this.nodesArray.length; + var i=0; + while (i 0) - return true; - else - return false; + longitude = rootNode.data.bbox.geographicCoord.longitude; + latitude = rootNode.data.bbox.geographicCoord.latitude; + } + else if (buildingSeed !== undefined) + { + // in this case take the data from buildingSeed. + longitude = buildingSeed.geographicCoordOfBBox.longitude; + latitude = buildingSeed.geographicCoordOfBBox.latitude; } else - return false; - */ -}; - -/** - * 어떤 일을 하고 있습니까? - * @param absoluteEyeX 변수 - * @param absoluteEyeY 변수 - * @param absoluteEyeZ 변수 - * @returns point3dScrath2 - */ -NeoBuilding.prototype.getTransformedRelativeEyePositionToBuilding = function(absoluteEyeX, absoluteEyeY, absoluteEyeZ, resultRelEyePosToBuilding) -{ - // 1rst, calculate the relative eye position.*** - var buildingPosition = this.buildingPosition; - var relativeEyePosX = absoluteEyeX - buildingPosition.x; - var relativeEyePosY = absoluteEyeY - buildingPosition.y; - var relativeEyePosZ = absoluteEyeZ - buildingPosition.z; - - if (this.buildingPosMatInv === undefined) { - this.buildingPosMatInv = new Matrix4(); - this.buildingPosMatInv.setByFloat32Array(this.moveMatrixInv); + longitude = node.data.geographicCoord.longitude; + latitude = node.data.geographicCoord.latitude; } - - var point3dScratch = new Point3D(); - if (resultRelEyePosToBuilding === undefined) - { resultRelEyePosToBuilding = new Point3D(); } + if (this.intersectPoint(longitude, latitude)) + { + intersects = true; + } - point3dScratch.set(relativeEyePosX, relativeEyePosY, relativeEyePosZ); - resultRelEyePosToBuilding = this.buildingPosMatInv.transformPoint3D(point3dScratch, resultRelEyePosToBuilding); - - return resultRelEyePosToBuilding; + return intersects; }; /** * 어떤 일을 하고 있습니까? - * @param neoReference 변수 + * @param geoLocData 변수 */ -NeoBuilding.prototype.getHeaderVersion = function() +SmartTile.prototype.takeIntersectedBuildingSeeds = function(nodeSeedsArray) { - return this.metaData.version; + // this function intersects the buildingSeeds with this tile. + // this function is used only one time when load a initial buildings distributions on the globe. + var buildingSeed; + var node, rootNode; + var buildingSeedsCount = nodeSeedsArray.length; + for (var i=0; i this.maxGeographicCoord.altitude) + { + this.maxGeographicCoord.altitude = altitude+bboxRadius; + } + } + } }; - /** * 어떤 일을 하고 있습니까? - * @param lod 변수 + * @param geoLocData 변수 */ -NeoBuilding.prototype.getLodBuildingData = function(lod) +/* +SmartTile.prototype.calculateAltitudeLimits = function() { - if (this.lodBuildingDatasMap === undefined) - { return undefined; } + // this function calculates the minAltitude and maxAltitude of the tile. + // init the altitudes. + this.minGeographicCoord.altitude = 0; + this.maxGeographicCoord.altitude = 0; - return this.lodBuildingDatasMap[lod]; + var buildingSeed; + var buildingSeedsCount = this.buildingSeedsArray.length; + for (var i=0; i this.maxGeographicCoord.altitude) + { + this.maxGeographicCoord.altitude = altitude+bboxRadius; + } + } }; +*/ /** * 어떤 일을 하고 있습니까? - * @param neoReference 변수 + * @param geographicCoord 변수 */ -NeoBuilding.prototype.getCurrentLodString = function() +SmartTile.prototype.intersectPoint = function(longitude, latitude) { - var currentLodString = undefined; - var lodBuildingData = this.getLodBuildingData(this.currentLod); - currentLodString = lodBuildingData.geometryFileName; - return currentLodString; + if (longitude < this.minGeographicCoord.longitude || longitude > this.maxGeographicCoord.longitude) + { return false; } + + if (latitude < this.minGeographicCoord.latitude || latitude > this.maxGeographicCoord.latitude) + { return false; } + + return true; }; /** * 어떤 일을 하고 있습니까? - * @param neoReference 변수 + * @param frustum 변수 */ -NeoBuilding.prototype.getCurrentSkin = function() +SmartTile.prototype.eraseNode = function(node) { - if (this.lodMeshesMap === undefined) - { return undefined; } + //this.nodeSeedsArray; + //this.nodesArray; - var skinLego; - //var currLodString = this.getCurrentLodString(); - //skinLego = this.lodMeshesMap[currLodString]; - //if(skinLego) - //var hola = 0; - - //return skinLego; - - var lodBuildingData = this.getLodBuildingData(this.currentLod); - if (lodBuildingData === undefined) - { return; } - - //textureFileName = lodBuildingData.textureFileName; - var lodString = lodBuildingData.geometryFileName; - skinLego = this.lodMeshesMap[lodString]; - - if (skinLego !== undefined && skinLego.isReadyToRender()) - { return skinLego; } - - - if (this.currentLod === 0) - { - skinLego = this.lodMeshesMap.lod0; - - if (skinLego === undefined || !skinLego.isReadyToRender()) - { - skinLego = this.lodMeshesMap.lod1; - if (skinLego === undefined || !skinLego.isReadyToRender()) - { - skinLego = this.lodMeshesMap.lod2; - if (skinLego === undefined || !skinLego.isReadyToRender()) - { - skinLego = this.lodMeshesMap.lod3; - if (skinLego === undefined || !skinLego.isReadyToRender()) - { - skinLego = this.lodMeshesMap.lod4; - if (skinLego === undefined || !skinLego.isReadyToRender()) - { - skinLego = this.lodMeshesMap.lod5; - } - } - } - } - } - - } - else if (this.currentLod === 1) + // Erase from this.nodeSeedsArray & this.nodesArray. + if (this.nodeSeedsArray !== undefined) { - skinLego = this.lodMeshesMap.lod1; - - if (skinLego === undefined || !skinLego.isReadyToRender()) + var nodeSeedsCount = this.nodeSeedsArray.length; + var finished = false; + var i = 0; + while (!finished && i 0) { - skinLego = this.lodMeshesMap.lod4; - if (skinLego === undefined || !skinLego.isReadyToRender()) - { - skinLego = this.lodMeshesMap.lod5; - } + resultLowestTilesArray.push(this); } - + return; } - else if (this.currentLod === 4) - { - skinLego = this.lodMeshesMap.lod4; - - if (skinLego === undefined || !skinLego.isReadyToRender()) - { - skinLego = this.lodMeshesMap.lod5; - if (skinLego === undefined || !skinLego.isReadyToRender()) - { - skinLego = this.lodMeshesMap.lod3; - } - } - } - else if (this.currentLod === 5) + var subTilesCount = this.subTiles.length; + for (var i=0; i 10) - { return; } - - if (neoReference.texture.fileLoadState === CODE.fileLoadState.READY) - { - var gl = magoManager.sceneState.gl; - neoReference.texture.texId = gl.createTexture(); - // Load the texture.*** - var projectFolderName = this.projectFolderName; - var geometryDataPath = magoManager.readerWriter.geometryDataPath; - var filePath_inServer = geometryDataPath + "/" + projectFolderName + "/" + this.buildingFileName + "/Images_Resized/" + neoReference.texture.textureImageFileName; - - this.texturesLoaded.push(neoReference.texture); - magoManager.readerWriter.readNeoReferenceTexture(gl, filePath_inServer, neoReference.texture, this, magoManager); - magoManager.backGround_fileReadings_count ++; - } - } - else - { - if (sameTexture.fileLoadState === CODE.fileLoadState.LOADING_FINISHED) - { - neoReference.texture = sameTexture; - } - } - } - - return neoReference.texture.fileLoadState; - } - else if (this.metaData.version[0] === '0' && this.metaData.version[2] === '0' && this.metaData.version[4] === '1' ) + var intersectedTilesCount = fullyIntersectedTiles.length; + for (var i=0; i 10) - { return undefined; } - - if (texture.fileLoadState === CODE.fileLoadState.READY) - { - var gl = magoManager.sceneState.gl; - texture.texId = gl.createTexture(); - // Load the texture.*** - var projectFolderName = this.projectFolderName; - var geometryDataPath = magoManager.readerWriter.getCurrentDataPath(); - var filePath_inServer = geometryDataPath + "/" + projectFolderName + "/" + this.buildingFileName + "/Images_Resized/" + texture.textureImageFileName; - - magoManager.readerWriter.readNeoReferenceTexture(gl, filePath_inServer, texture, this, magoManager); - magoManager.backGround_fileReadings_count ++; - } - } - } - - return neoReference.texture.fileLoadState; + fullyIntersectedTiles[i].extractLowestTiles(resultFullyIntersectedTilesArray); } - }; - -'use strict'; - /** * 어떤 일을 하고 있습니까? - * @class NeoBuildingsList + * @param frustum 변수 */ -var NeoBuildingsList = function() +SmartTile.prototype.getFrustumIntersectedTiles = function(frustum, resultFullyIntersectedTilesArray, resultPartiallyIntersectedTilesArray) { - if (!(this instanceof NeoBuildingsList)) + if (this.sphereExtent === undefined) + { return Constant.INTERSECTION_OUTSIDE; } + + var intersectionType = frustum.intersectionSphere(this.sphereExtent); + + if (intersectionType === Constant.INTERSECTION_OUTSIDE) + { return; } + else if (intersectionType === Constant.INTERSECTION_INSIDE) { - throw new Error(Messages.CONSTRUCT_ERROR); + resultFullyIntersectedTilesArray.push(this); + return; + } + else if (intersectionType === Constant.INTERSECTION_INTERSECT) + { + if (this.subTiles && this.subTiles.length > 0) + { + for (var i=0; i 0) + { resultPartiallyIntersectedTilesArray.push(this); } + } } - //Array.apply(this, arguments); - - this.neoBuildingsArray = []; }; -//NeoBuildingsList.prototype = Object.create(Array.prototype); /** * 어떤 일을 하고 있습니까? - * @returns neoBuilding + * @param frustum 변수 */ -NeoBuildingsList.prototype.newNeoBuilding = function() +SmartTile.selectTileAngleRangeByDepth = function(depth) { - var neoBuilding = new NeoBuilding(); - this.neoBuildingsArray.push(neoBuilding); - return neoBuilding; + if (depth === undefined || depth < 0 || depth > 15) + { return undefined; } + + if (depth === 0) + { return 180; } + if (depth === 1) + { return 90; } + if (depth === 2) + { return 45; } + if (depth === 3) + { return 22.5; } + if (depth === 4) + { return 11.25; } + if (depth === 5) + { return 5.625; } + if (depth === 6) + { return 2.8125; } + if (depth === 7) + { return 1.40625; } + if (depth === 8) + { return 0.703125; } + if (depth === 9) + { return 0.3515625; } + if (depth === 10) + { return 0.17578125; } + if (depth === 11) + { return 0.087890625; } + if (depth === 12) + { return 0.043945313; } + if (depth === 13) + { return 0.021972656; } + if (depth === 14) + { return 0.010986328; } + if (depth === 15) + { return 0.010986328/2.0; } }; /** * 어떤 일을 하고 있습니까? - * @returns neoBuilding + * @param frustum 변수 */ -NeoBuildingsList.prototype.getNeoBuildingByTypeId = function(buildingType, buildingId) +SmartTile.selectTileName = function(depth, longitude, latitude, resultTileName) { - var resultBuilding; - var buildingsCount = this.neoBuildingsArray.length; - var found = false; - var i=0; - while (!found && i < buildingsCount) - { - if (this.neoBuildingsArray[i].buildingType === buildingType && this.neoBuildingsArray[i].buildingId === buildingId) - { - found = true; - resultBuilding = this.neoBuildingsArray[i]; - } - i++; - } - - return resultBuilding; + var xMin = -180.0; + var yMin = 90.0; + var angRange = SmartTile.selectTileAngleRangeByDepth(depth) ; + + var xIndex = Math.floor((longitude - xMin)/angRange); + // with yMin = -90.0; + //var yIndex = Math.floor((latitude - yMin)/angRange); + var yIndex = Math.floor((yMin - latitude)/angRange); + resultTileName = depth.toString() + "\\" + xIndex.toString() + "\\" + yIndex.toString(); + return resultTileName; }; -NeoBuildingsList.prototype.get = function (index) -{ - return this.neoBuildingsArray[index]; -}; - -NeoBuildingsList.prototype.add = function (item) +/** + * 어떤 일을 하고 있습니까? + * @param frustum 변수 + */ + +SmartTile.getFrustumIntersectedTilesNames = function(frustum, maxDepth, camPos, magoManager, resultFullyIntersectedTilesNamesMap) { - if (item !== undefined) { this.neoBuildingsArray.push(item); } + var currMinGeographicCoords = new GeographicCoord(); + var currMaxGeographicCoords = new GeographicCoord(); + var currDepth = 0; + + // America side. + currMinGeographicCoords.setLonLatAlt(-180, -90, 0); + currMaxGeographicCoords.setLonLatAlt(0, 90, 0); + currDepth = 0; + SmartTile.getFrustumIntersectedTilesNamesForGeographicExtent(frustum, maxDepth, currDepth, camPos, currMinGeographicCoords, currMaxGeographicCoords, magoManager, magoManager.boundingSphere_Aux, + resultFullyIntersectedTilesNamesMap); + + // Asia side. + currMinGeographicCoords.setLonLatAlt(0, -90, 0); + currMaxGeographicCoords.setLonLatAlt(180, 90, 0); + currDepth = 0; + SmartTile.getFrustumIntersectedTilesNamesForGeographicExtent(frustum, maxDepth, currDepth, camPos, currMinGeographicCoords, currMaxGeographicCoords, magoManager, magoManager.boundingSphere_Aux, + resultFullyIntersectedTilesNamesMap); }; -'use strict'; /** * 어떤 일을 하고 있습니까? - * @class NeoReference + * @param frustum 변수 */ -var NeoReference = function() + +SmartTile.getFrustumIntersectedTilesNamesForGeographicExtent = function(frustum, maxDepth, currDepth, camPos, currMinGeographicCoords, currMaxGeographicCoords, magoManager, sphereExtentAux, resultFullyIntersectedTilesNamesMap) { - if (!(this instanceof NeoReference)) + // STATIC FUNCTION. + // 1rst, make a sphereExtent. + + sphereExtentAux = SmartTile.computeSphereExtent(magoManager, currMinGeographicCoords, currMaxGeographicCoords, sphereExtentAux); + + var intersectionType = frustum.intersectionSphere(sphereExtentAux); + + if (intersectionType === Constant.INTERSECTION_OUTSIDE) + { return; } + else if (intersectionType === Constant.INTERSECTION_INSIDE) { - throw new Error(Messages.CONSTRUCT_ERROR); + var midLon = (currMinGeographicCoords.longitude + currMaxGeographicCoords.longitude)/2; + var midLat = (currMinGeographicCoords.latitude + currMaxGeographicCoords.latitude)/2; + var tileName = SmartTile.selectTileName(currDepth, midLon, midLat, undefined); + var geographicExtent = new GeographicExtent(); + geographicExtent.minGeographicCoord = new GeographicCoord(currMinGeographicCoords.longitude, currMinGeographicCoords.latitude, currMinGeographicCoords.altitude); + geographicExtent.maxGeographicCoord = new GeographicCoord(currMaxGeographicCoords.longitude, currMaxGeographicCoords.latitude, currMaxGeographicCoords.altitude); + resultFullyIntersectedTilesNamesMap[tileName] = geographicExtent; + return; } - - // 1) Object IDX.*** - this._id = 0; - - this.objectId = ""; - - // 2) Block Idx.*** - this._block_idx = -1; - - // 3) Transformation Matrix.*** - this._matrix4 = new Matrix4(); // initial and necessary matrix.*** - this._originalMatrix4 = new Matrix4(); // original matrix, for use with block-reference (do not modify).*** - this.tMatrixAuxArray; // use for deploying mode, cronological transformations for example.*** - this.refMatrixType = 2; // 0 = identity matrix, 1 = translate matrix, 2 = transformation matrix. - this.refTranslationVec; // use this if "refMatrixType" === 1. - // 4) VBO datas container.*** - this.vBOVertexIdxCacheKeysContainer; // initially undefined.*** - - // 5) The texture image.*** - this.materialId; - this.hasTexture = false; - this.texture; // Texture - - // 6) 1 color.*** - this.color4; //new Color(); - this.aditionalColor; // used when object color was changed.*** - - this.vertexCount = 0;// provisional. for checking vertexCount of the block.*** delete this.**** - - // 7) movement of the object.*** - this.moveVectorRelToBuilding; // Point3D.*** - this.moveVector; // Point3D.*** - - // 8) check for render.*** - this.renderingFase = false; + else if (intersectionType === Constant.INTERSECTION_INTERSECT) + { + // check distance to camera. + var distToCam = camPos.distToSphere(sphereExtentAux); + if (distToCam > 2000) + { + var midLon = (currMinGeographicCoords.longitude + currMaxGeographicCoords.longitude)/2; + var midLat = (currMinGeographicCoords.latitude + currMaxGeographicCoords.latitude)/2; + var tileName = SmartTile.selectTileName(currDepth, midLon, midLat, undefined); + var geographicExtent = new GeographicExtent(); + geographicExtent.minGeographicCoord = new GeographicCoord(currMinGeographicCoords.longitude, currMinGeographicCoords.latitude, currMinGeographicCoords.altitude); + geographicExtent.maxGeographicCoord = new GeographicCoord(currMaxGeographicCoords.longitude, currMaxGeographicCoords.latitude, currMaxGeographicCoords.altitude); + resultFullyIntersectedTilesNamesMap[tileName] = geographicExtent; + return; + } + + if (currDepth < maxDepth) + { + // must descend. + currDepth += 1; + var minLon = currMinGeographicCoords.longitude; + var minLat = currMinGeographicCoords.latitude; + var minAlt = currMinGeographicCoords.altitude; + var maxLon = currMaxGeographicCoords.longitude; + var maxLat = currMaxGeographicCoords.latitude; + var maxAlt = currMaxGeographicCoords.altitude; + var midLon = (minLon + maxLon)/ 2; + var midLat = (minLat + maxLat)/ 2; + + // subTile 1. + currMaxGeographicCoords.setLonLatAlt(midLon, midLat, maxAlt); + this.getFrustumIntersectedTilesNamesForGeographicExtent(frustum, maxDepth, currDepth, camPos, currMinGeographicCoords, currMaxGeographicCoords, magoManager, sphereExtentAux, resultFullyIntersectedTilesNamesMap); + + // subTile 2. + currMinGeographicCoords.setLonLatAlt(midLon, minLat, minAlt); + currMaxGeographicCoords.setLonLatAlt(maxLon, midLat, maxAlt); + this.getFrustumIntersectedTilesNamesForGeographicExtent(frustum, maxDepth, currDepth, camPos, currMinGeographicCoords, currMaxGeographicCoords, magoManager, sphereExtentAux, resultFullyIntersectedTilesNamesMap); + + // subTile 3. + currMinGeographicCoords.setLonLatAlt(midLon, midLat, minAlt); + currMaxGeographicCoords.setLonLatAlt(maxLon, maxLat, maxAlt); + this.getFrustumIntersectedTilesNamesForGeographicExtent(frustum, maxDepth, currDepth, camPos, currMinGeographicCoords, currMaxGeographicCoords, magoManager, sphereExtentAux, resultFullyIntersectedTilesNamesMap); + + // subTile 4. + currMinGeographicCoords.setLonLatAlt(minLon, midLat, minAlt); + currMaxGeographicCoords.setLonLatAlt(midLon, maxLat, maxAlt); + this.getFrustumIntersectedTilesNamesForGeographicExtent(frustum, maxDepth, currDepth, camPos, currMinGeographicCoords, currMaxGeographicCoords, magoManager, sphereExtentAux, resultFullyIntersectedTilesNamesMap); + + } + else + { + var midLon = (currMinGeographicCoords.longitude + currMaxGeographicCoords.longitude)/2; + var midLat = (currMinGeographicCoords.latitude + currMaxGeographicCoords.latitude)/2; + var tileName = SmartTile.selectTileName(currDepth, midLon, midLat, undefined); + var geographicExtent = new GeographicExtent(); + geographicExtent.minGeographicCoord = new GeographicCoord(currMinGeographicCoords.longitude, currMinGeographicCoords.latitude, currMinGeographicCoords.altitude); + geographicExtent.maxGeographicCoord = new GeographicCoord(currMaxGeographicCoords.longitude, currMaxGeographicCoords.latitude, currMaxGeographicCoords.altitude); + resultFullyIntersectedTilesNamesMap[tileName] = geographicExtent; + return; + } + } + }; + /** - * 카메라가 이동중인지를 확인 - * @param cameraPosition 변수 - * @param squareDistUmbral 변수 - * @returns camera_was_moved + * 어떤 일을 하고 있습니까? + * Extent(범위) + * @param frustum 변수 */ -NeoReference.prototype.swapRenderingFase = function() +SmartTile.prototype.getSphereExtent = function() { - this.renderingFase = !this.renderingFase; + return this.sphereExtent; }; /** * 어떤 일을 하고 있습니까? */ -NeoReference.prototype.multiplyTransformMatrix = function(matrix) +SmartTile.prototype.setSize = function(minLon, minLat, minAlt, maxLon, maxLat, maxAlt) { - this._matrix4 = this._originalMatrix4.getMultipliedByMatrix(matrix); // Original.*** + if (this.minGeographicCoord === undefined) + { this.minGeographicCoord = new GeographicCoord(); } + if (this.maxGeographicCoord === undefined) + { this.maxGeographicCoord = new GeographicCoord(); } + + this.minGeographicCoord.setLonLatAlt(minLon, minLat, minAlt); + this.maxGeographicCoord.setLonLatAlt(maxLon, maxLat, maxAlt); }; /** * 어떤 일을 하고 있습니까? */ -NeoReference.prototype.multiplyKeyTransformMatrix = function(idxKey, matrix) +SmartTile.prototype.setSizesToSubTiles = function() { - // this function multiplies the originalMatrix by "matrix" and stores it in the "idxKey" position.*** - if (this.tMatrixAuxArray === undefined) - { this.tMatrixAuxArray = []; } - - this.tMatrixAuxArray[idxKey] = this._originalMatrix4.getMultipliedByMatrix(matrix, this.tMatrixAuxArray[idxKey]); + // +-----+-----+ + // | 3 | 2 | + // +-----+-----+ + // | 0 | 1 | + // +-----+-----+ - if (this.moveVectorRelToBuilding) - { - this.moveVector = matrix.rotatePoint3D(this.moveVectorRelToBuilding, this.moveVector); - } + var minLon = this.minGeographicCoord.longitude; + var maxLon = this.maxGeographicCoord.longitude; + var minLat = this.minGeographicCoord.latitude; + var maxLat = this.maxGeographicCoord.latitude; + var minAlt = this.minGeographicCoord.altitude; + var maxAlt = this.maxGeographicCoord.altitude; + + var midLon = (maxLon + minLon)/2; + var midLat = (maxLat + minLat)/2; + + var subTile = this.subTiles[0]; + subTile.setSize(minLon, minLat, minAlt, midLon, midLat, maxAlt); + + subTile = this.subTiles[1]; + subTile.setSize(midLon, minLat, minAlt, maxLon, midLat, maxAlt); + + subTile = this.subTiles[2]; + subTile.setSize(midLon, midLat, minAlt, maxLon, maxLat, maxAlt); + + subTile = this.subTiles[3]; + subTile.setSize(minLon, midLat, minAlt, midLon, maxLat, maxAlt); }; /** * 어떤 일을 하고 있습니까? + * @param geoLocData 변수 */ -NeoReference.prototype.hasKeyMatrix = function(idxKey) +SmartTile.prototype.getLongitudeRangeDegree = function() { - if (this.tMatrixAuxArray === undefined) - { return false; } - - if (this.tMatrixAuxArray[idxKey] === undefined) - { return false; } - else - { return true; } + return this.maxGeographicCoord.longitude - this.minGeographicCoord.longitude; }; /** * 어떤 일을 하고 있습니까? + * @param geoLocData 변수 */ -NeoReference.prototype.deleteObjects = function(gl, vboMemManager) +SmartTile.prototype.getLatitudeRangeDegree = function() { - // 1) Object ID.*** - this._id = undefined; - - // 2) Block Idx.*** - this._block_idx = undefined; - - // 3) Transformation Matrix.*** - this._matrix4._floatArrays = undefined; - this._matrix4 = undefined; - this._originalMatrix4._floatArrays = undefined; - this._originalMatrix4 = undefined; // - - // 5) The texture image.*** - this.hasTexture = undefined; - // no delete the texture, only break the referencing. - this.texture = undefined; // Texture - - // 6) 1 color.*** - if (this.color4) - { this.color4.deleteObjects(); } - this.color4 = undefined; //new Color(); - - // 7) selection color.*** - if (this.selColor4) - { this.selColor4.deleteObjects(); } - this.selColor4 = undefined; //new Color(); // use for selection only.*** - - this.vertexCount = undefined;// provisional. for checking vertexCount of the block.*** delete this.**** - - // 8) movement of the object.*** - if (this.moveVector) - { this.moveVector.deleteObjects(); } - this.moveVector = undefined; // Point3D.*** - - this.bRendered = undefined; - - if (this.vBOVertexIdxCacheKeysContainer !== undefined) - { - this.vBOVertexIdxCacheKeysContainer.deleteGlObjects(gl, vboMemManager); - this.vBOVertexIdxCacheKeysContainer = undefined; - } + return this.maxGeographicCoord.latitude - this.minGeographicCoord.latitude; }; +'use strict'; -//************************************************************************************************************************************************************* -//************************************************************************************************************************************************************* -//************************************************************************************************************************************************************* /** - * 어떤 일을 하고 있습니까? - * @class NeoReferencesMotherAndIndices + * 4분할 타일링 수행 및 타일 객체 보관 객체 + * 인스턴스 생성 시 mother tile 생성 + * @class SmartTileManager + * + * @exception {Error} Messages.CONSTRUCT_ERROR + * @see SmartTile */ -var NeoReferencesMotherAndIndices = function() +var SmartTileManager = function() { - if (!(this instanceof NeoReferencesMotherAndIndices)) + if (!(this instanceof SmartTileManager)) { throw new Error(Messages.CONSTRUCT_ERROR); } + + /** + * 타일 배열 + * has 2 tiles (Asia side and America side). + * @type {Array.} + */ + this.tilesArray = []; + + /** + * mother 타일 생성 + */ + this.createMainTiles(); +}; - this.motherNeoRefsList; // this is a NeoReferencesList pointer.*** - this.neoRefsIndices = []; // All objects(references) of this class. - this.modelReferencedGroupsList; // (for new format). - this.blocksList; - - this.fileLoadState = 0; // init as "READY". - this.dataArraybuffer; - this.succesfullyGpuDataBinded; - - this.exterior_ocCullOctree; // octree that contains the visible indices. - this.interior_ocCullOctree; // octree that contains the visible indices. +/** + * 아메리카쪽 아시아쪽으로 구분하여 두개의 mother 타일 생성 + */ +SmartTileManager.prototype.createMainTiles = function() +{ + // tile 1 : longitude {-180, 0}, latitude {-90, 90} + // tile 2 : longitude {0, 180}, latitude {-90, 90} - this.currentVisibleIndices = []; - this.currentVisibleMRG; // MRG = ModelReferencedGroup (for new format). + // America side. + var tile1 = this.newSmartTile("AmericaSide"); + if (tile1.minGeographicCoord === undefined) + { tile1.minGeographicCoord = new GeographicCoord(); } + if (tile1.maxGeographicCoord === undefined) + { tile1.maxGeographicCoord = new GeographicCoord(); } + + tile1.depth = 0; // mother tile. + tile1.minGeographicCoord.setLonLatAlt(-180, -90, 0); + tile1.maxGeographicCoord.setLonLatAlt(0, 90, 0); + + // Asia side. + var tile2 = this.newSmartTile("AsiaSide"); + if (tile2.minGeographicCoord === undefined) + { tile2.minGeographicCoord = new GeographicCoord(); } + if (tile2.maxGeographicCoord === undefined) + { tile2.maxGeographicCoord = new GeographicCoord(); } + + tile2.depth = 0; // mother tile. + tile2.minGeographicCoord.setLonLatAlt(0, -90, 0); + tile2.maxGeographicCoord.setLonLatAlt(180, 90, 0); }; /** - * 어떤 일을 하고 있습니까? - * @param matrix 변수 + * f4d들의 object index 파일을 읽고 생성한 물리적인 노드들을 타일에 배치. + * @param {Number} targetDepth 없을 시 17, 일반적으로 17레벨까지 생성. + * @param {Array.} physicalNodesArray geometry정보가 있는 화면에 표출할 수 있는 Node 배열 + * @param {MagoManager} magoManager 마고매니저. + * + * @see Node */ -NeoReferencesMotherAndIndices.prototype.multiplyKeyTransformMatrix = function(idxKey, matrix) +SmartTileManager.prototype.makeTreeByDepth = function(targetDepth, physicalNodesArray, magoManager) { - var refIndicesCount = this.neoRefsIndices.length; - for (var i=0; i 0) - { thisHasOcCullData = true; } - - if (thisHasOcCullData && applyOcclusionCulling) - { - //if (this.currentVisibleMRG === undefined) - //{ this.currentVisibleMRG = new ModelReferencedGroupsList(); } - - var intersectedSubBox = this.interior_ocCullOctree.getIntersectedSubBoxByPoint3D(eye_x, eye_y, eye_z); - if (intersectedSubBox !== undefined && intersectedSubBox._indicesArray.length > 0) - { - this.currentVisibleIndices = intersectedSubBox._indicesArray; - //if (result_modelReferencedGroup) - //{ - // result_modelReferencedGroup = this.modelReferencedGroupsList; - //} - isExterior = false; - } - else - { - isExterior = true; - } - } - else + var tilesCount = this.tilesArray.length; // allways tilesCount = 2. (Asia & America sides). + for (var i=0; i 0) - { thisHasOcCullData = true; } - - if (thisHasOcCullData && applyOcclusionCulling) - { - if (this.currentVisibleMRG === undefined) - { this.currentVisibleMRG = new ModelReferencedGroupsList(); } - - this.currentVisibleIndices = this.exterior_ocCullOctree.getIndicesVisiblesForEye(eye_x, eye_y, eye_z, this.currentVisibleIndices, this.currentVisibleMRG); - } - else - { - // In this case there are no occlusionCulling data. - this.currentVisibleIndices = this.neoRefsIndices; - this.currentVisibleMRG = this.modelReferencedGroupsList; - } + this.tilesArray[i].deleteObjects(); + this.tilesArray[i] = undefined; } + this.tilesArray.length = 0; } }; /** - * Returns the neoReference - * @param matrix 변수 + * 어떤 일을 하고 있습니까? + * @class GeoLocationData + * @param geoLocData 변수 */ -NeoReferencesMotherAndIndices.prototype.getNeoReference = function(idx) +SmartTileManager.prototype.resetTiles = function() { - return this.motherNeoRefsList[this.neoRefsIndices[idx]]; + this.deleteTiles(); + + // now create the main tiles. + this.createMainTiles(); }; /** - * 어떤 일을 하고 있습니까? - * @param treeDepth 변수 + * 새로운 스마트타일을 생성하여 tilesArray에 넣고 반환. + * @param {String} smartTileName tile name\ + * @returns {SmartTile} */ -NeoReferencesMotherAndIndices.prototype.deleteObjects = function(gl, vboMemManager) +SmartTileManager.prototype.newSmartTile = function(smartTileName) { - this.motherNeoRefsList = undefined; // this is a NeoReferencesList pointer.*** - this.neoRefsIndices = undefined; - this.blocksList = undefined; - - this.fileLoadState = undefined; - this.dataArraybuffer = undefined; - - this.exterior_ocCullOctree = undefined; - this.interior_ocCullOctree = undefined; + if (this.tilesArray === undefined) + { this.tilesArray = []; } + + var smartTile = new SmartTile(smartTileName); + this.tilesArray.push(smartTile); + return smartTile; }; /** * 어떤 일을 하고 있습니까? - * @param treeDepth 변수 */ -NeoReferencesMotherAndIndices.prototype.setRenderedFalseToAllReferences = function() +SmartTileManager.prototype.getNeoBuildingById = function(buildingType, buildingId) { - var refIndicesCount = this.neoRefsIndices.length; - for (var i=0; i 0) - { - if (neoRef.vBOVertexIdxCacheKeysContainer === undefined) - { neoRef.vBOVertexIdxCacheKeysContainer = new VBOVertexIdxCacheKeysContainer(); } - } - - for (var j=0; j 0) - { - // Now, read the texture_type and texture_file_name.*** - var texture_type_nameLegth = readWriter.readUInt32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; - for (var j=0; j 0) - { - if (neoRef.vBOVertexIdxCacheKeysContainer === undefined) - { neoRef.vBOVertexIdxCacheKeysContainer = new VBOVertexIdxCacheKeysContainer(); } - } - - for (var j=0; j 0) - { - var textureTypeName = ""; - var textureImageFileName = ""; - - // Now, read the texture_type and texture_file_name.*** - var texture_type_nameLegth = readWriter.readUInt32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; - for (var j=0; j 0) - { - neoRef.texture = new Texture(); - neoRef.hasTexture = true; - neoRef.texture.textureTypeName = textureTypeName; - neoRef.texture.textureImageFileName = textureImageFileName; - } - - /* - // 1pixel texture, wait for texture to load.******************************************** - if(neoRef.texture.texId === undefined) - neoRef.texture.texId = gl.createTexture(); - gl.bindTexture(gl.TEXTURE_2D, neoRef.texture.texId); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([90, 80, 85, 255])); // red - gl.bindTexture(gl.TEXTURE_2D, null); - */ - } - else - { - neoRef.hasTexture = false; - } - - if (tMatrix4) - { - neoRef.multiplyTransformMatrix(tMatrix4); - } - } - - } - - //this.createModelReferencedGroups(); // test for new format. - - - // Now occlusion cullings.*** - // Occlusion culling octree data.***** - if (this.exterior_ocCullOctree === undefined) - { this.exterior_ocCullOctree = new OcclusionCullingOctreeCell(); } - - var infiniteOcCullBox = this.exterior_ocCullOctree; - //bytes_readed = this.readOcclusionCullingOctreeCell(arrayBuffer, bytes_readed, infiniteOcCullBox); // old.*** - bytes_readed = this.exterior_ocCullOctree.parseArrayBuffer(arrayBuffer, bytes_readed, readWriter); - infiniteOcCullBox.expandBox(1000); // Only for the infinite box.*** - infiniteOcCullBox.setSizesSubBoxes(); - infiniteOcCullBox.createModelReferencedGroups(this.motherNeoRefsList); - if (this.interior_ocCullOctree === undefined) - { this.interior_ocCullOctree = new OcclusionCullingOctreeCell(); } +'use strict'; - var ocCullBox = this.interior_ocCullOctree; - //bytes_readed = this.readOcclusionCullingOctreeCell(arrayBuffer, bytes_readed, ocCullBox); // old.*** - bytes_readed = this.interior_ocCullOctree.parseArrayBuffer(arrayBuffer, bytes_readed, readWriter); - ocCullBox.setSizesSubBoxes(); - ocCullBox.createModelReferencedGroups(this.motherNeoRefsList); +/** + * ?? + * @class SceneState + */ - this.fileLoadState = CODE.fileLoadState.PARSE_FINISHED; - return this.succesfullyGpuDataBinded; +var SplitValue = function() +{ + this.high = undefined; + this.low = undefined; }; - - - - - - - - - - - - 'use strict'; /** * 어떤 일을 하고 있습니까? - * @class NeoSimpleBuilding + * @class TerranTile */ -var NeoSimpleBuilding = function() +var TerranTile = function() { - if (!(this instanceof NeoSimpleBuilding)) + if (!(this instanceof TerranTile)) { throw new Error(Messages.CONSTRUCT_ERROR); } - this.accesorsArray = []; - this.vbo_vicks_container = new VBOVertexIdxCacheKeysContainer(); - this.texturesArray = []; + // +-----+-----+ + // | 3 | 2 | + // +-----+-----+ + // | 0 | 1 | + // +-----+-----+ + + this._depth = 0; // qudtree depth. 0 => mother_quadtree. + this._numberName = 1; // mother quadtree. + this._terranTile_owner; + //------------------------------------------------------------ + this.projectsArray = []; + + this._BR_buildingsArray = []; // Old. + this._boundingBox; // dont use this. + this._pCloudMesh_array = []; // 1rst aproximation to the pointCloud data. Test. + + this.position; // absolute position, for do frustum culling. + this.radius; // aprox radius for this tile. + + this.leftDown_position; + this.rightDown_position; + this.rightUp_position; + this.leftUp_position; + this.visibilityType; + + this.subTiles_array = []; + this.terranIndexFile_readed = false; + this.empty_tile = false; + + // File. + this.fileReading_started = false; + this.fileReading_finished = false; + this.fileArrayBuffer; + this.fileBytesReaded = 0; + this.fileParsingFinished = false; + this.projectsParsed_count = 0; + + this.current_BRProject_parsing; + this.current_BRProject_parsing_state = 0; + + this.readWriter; }; /** * 어떤 일을 하고 있습니까? - * @returns accesor + * @returns br_buildingProject */ -NeoSimpleBuilding.prototype.newAccesor = function() +TerranTile.prototype.newBRProject = function() { - var accesor = new Accessor(); - this.accesorsArray.push(accesor); - return accesor; + // Old. Old. Old. Old. Old. Old. Old. Old. + // dont use this. delete this. + var br_buildingProject = new BRBuildingProject(); + this._BR_buildingsArray.push(br_buildingProject); + return br_buildingProject; }; /** * 어떤 일을 하고 있습니까? - * @returns texture + * @returns subTile */ -NeoSimpleBuilding.prototype.newTexture = function() +TerranTile.prototype.newSubTerranTile = function() { - var texture = new NeoTexture(); - this.texturesArray.push(texture); - return texture; + var subTiles_count = this.subTiles_array.length; + var subTile = new TerranTile(); + subTile._depth = this._depth + 1; + subTile._numberName = this._numberName*10 + subTiles_count + 1; + this.subTiles_array.push(subTile); + return subTile; }; -'use strict'; - /** * 어떤 일을 하고 있습니까? - * @class NeoTexture */ -var NeoTexture = function() +TerranTile.prototype.make4subTiles = function() { - if (!(this instanceof NeoTexture)) + for (var i = 0; i < 4; i++) { - throw new Error(Messages.CONSTRUCT_ERROR); + this.newSubTerranTile(); } - - this.lod; - this.textureId; // texture id in gl.*** - this.texImage; // image. delete this once upload to gl.*** - this.loadStarted = false; - this.loadFinished = false; }; -'use strict'; /** - * @class Node + * 어떤 일을 하고 있습니까? + * @param lonMin 변수 + * @param lonMax 변수 + * @param latMin 변수 + * @param latMax 변수 */ -var Node = function() +TerranTile.prototype.setDimensions = function(lonMin, lonMax, latMin, latMax) { - if (!(this instanceof Node)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - // parent. - this.parent; - - // children array. - this.children = []; - - // data. - this.data; // {}. + this.longitudeMin = lonMin; + this.longitudeMax = lonMax; + this.latitudeMin = latMin; + this.latitudeMax = latMax; }; /** * 어떤 일을 하고 있습니까? + * @param maxDepth 변수 */ -Node.prototype.deleteObjects = function(gl, vboMemoryManager) +TerranTile.prototype.makeTree = function(maxDepth) { - this.parent = undefined; - if (this.data) - { - if (this.data.neoBuilding) - { - this.data.neoBuilding.deleteObjects(gl, vboMemoryManager); - this.data.neoBuilding = undefined; - } - - if (this.data.geographicCoord) - { - this.data.geographicCoord.deleteObjects(); - this.data.geographicCoord = undefined; - } - - if (this.data.rotationsDegree) - { - this.data.rotationsDegree.deleteObjects(); - this.data.rotationsDegree = undefined; - } - - if (this.data.bbox) - { - this.data.bbox.deleteObjects(); - this.data.bbox = undefined; - } - - this.data = undefined; - } - - if (this.children) + if (this._depth < maxDepth) { - var childrenCount = this.children.length; - for (var i=0; i= fileLegth) + { return; } + + var version_string_length = 5; + var intAux_scratch = 0; + //var auxScratch; + var header = BR_Project._header; + var arrayBuffer = this.fileArrayBuffer; + var bytes_readed = this.fileBytesReaded; + + if (this.readWriter === undefined) + { this.readWriter = new ReaderWriter(); } + + // 1) Version(5 chars).** + for (var j=0; j 40.0 || header._boundingBox.maxY - header._boundingBox.minY > 40.0) { - nodesArray.push(this); + isLarge = true; } - - var childrenCount = this.children.length; - for (var i=0; i= fileLegth) + { return; } -/** - * 어떤 일을 하고 있습니까? - * @param texture 변수 - * @returns texId - */ -Node.prototype.getBBoxCenterPositionWorldCoord = function(geoLoc) -{ - if (this.bboxAbsoluteCenterPos === undefined) - { - this.calculateBBoxCenterPositionWorldCoord(geoLoc); - } - - return this.bboxAbsoluteCenterPos; -}; + if (this.readWriter === undefined) + { this.readWriter = new ReaderWriter(); } -/** - * 어떤 일을 하고 있습니까? - * @param texture 변수 - * @returns texId - */ -Node.prototype.calculateBBoxCenterPositionWorldCoord = function(geoLoc) -{ - var bboxCenterPoint; - bboxCenterPoint = this.data.bbox.getCenterPoint(bboxCenterPoint); // local bbox. - this.bboxAbsoluteCenterPos = geoLoc.tMatrix.transformPoint3D(bboxCenterPoint, this.bboxAbsoluteCenterPos); - - // Now, must applicate the aditional translation vector. Aditional translation is made when we translate the pivot point. - if (geoLoc.pivotPointTraslation) - { - var traslationVector; - traslationVector = geoLoc.tMatrix.rotatePoint3D(geoLoc.pivotPointTraslation, traslationVector ); - this.bboxAbsoluteCenterPos.add(traslationVector.x, traslationVector.y, traslationVector.z); - } -}; + var bytes_readed = this.fileBytesReaded; + var startBuff; + var endBuff; + var arrayBuffer = this.fileArrayBuffer; + + if (BR_Project._simpleBuilding_v1 === undefined) + { BR_Project._simpleBuilding_v1 = new SimpleBuildingV1(); } + var simpBuildingV1 = BR_Project._simpleBuilding_v1; + var vbo_objects_count = this.readWriter.readUInt32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; // Almost allways is 1. + // single interleaved buffer mode. + for (var i=0; i>> 8; + //var r = (color_4byte_temp & 0xFF0000) >>> 16; + //var a = ( (color_4byte_temp & 0xFF000000) >>> 24 ) / 255 ; + this.fileBytesReaded = bytes_readed; +}; +/** + * 어떤 일을 하고 있습니까? + * @param BR_Project 변수 + * @param magoManager 변수 + */ +TerranTile.prototype.parseFileNailImage = function(BR_Project, magoManager) +{ + //BR_Project._f4d_nailImage_readed = true; + if (BR_Project._simpleBuilding_v1 === undefined) + { BR_Project._simpleBuilding_v1 = new SimpleBuildingV1(); } + if (this.readWriter === undefined) + { this.readWriter = new ReaderWriter(); } + var simpBuildingV1 = BR_Project._simpleBuilding_v1; + // Read the image.* + var bytes_readed = this.fileBytesReaded; + var arrayBuffer = this.fileArrayBuffer; + var nailImageSize = this.readWriter.readUInt32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; + var startBuff = bytes_readed; + var endBuff = bytes_readed + nailImageSize; + simpBuildingV1.textureArrayBuffer = new Uint8Array(arrayBuffer.slice(startBuff, endBuff)); + bytes_readed += nailImageSize; -'use strict'; + this.fileBytesReaded = bytes_readed; +}; /** * 어떤 일을 하고 있습니까? - * @class Octree - * - * @param octreeOwner 변수 + * @param magoManager 변수 */ -var Octree = function(octreeOwner) +TerranTile.prototype.parseFileAllBuildings = function(magoManager) { - if (!(this instanceof Octree)) + var fileLegth = this.fileArrayBuffer.byteLength; + if (this.fileBytesReaded >= fileLegth) { - throw new Error(Messages.CONSTRUCT_ERROR); + this.fileParsingFinished = true; + return; } - // Note: an octree is a cube, not a box.*** - this.centerPos = new Point3D(); - this.half_dx = 0.0; // half width.*** - this.half_dy = 0.0; // half length.*** - this.half_dz = 0.0; // half height.*** + if (this.readWriter === undefined) + { this.readWriter = new ReaderWriter(); } - this.octree_owner; - this.octree_level = 0; - this.octree_number_name = 0; - this.neoBuildingOwnerId; - this.octreeKey; - this.distToCamera; - this.triPolyhedronsCount = 0; // no calculated. Readed when parsing.*** - this.fileLoadState = CODE.fileLoadState.READY; + var arrayBuffer = this.fileArrayBuffer; + var projects_count = this.readWriter.readInt32(arrayBuffer, 0, 4); this.fileBytesReaded += 4; - if (octreeOwner) + if (projects_count === 0) + { this.empty_tile = true; } + + for (var i=0; i= fileLegth) + { + this.fileParsingFinished = true; + return; + } - this.neoReferencesMotherAndIndices = undefined; + if (this.readWriter === undefined) + { this.readWriter = new ReaderWriter(); } + + var projects_count = this.readWriter.readInt32(this.fileArrayBuffer, 0, 4); // only debug test. - // delete the blocksList.*** - if (this.neoRefsList_Array !== undefined) + if (this.projectsParsed_count >= projects_count) { - for (var i=0, neoRefListsCount = this.neoRefsList_Array.length; i 0) { - for (var i=0, subOctreesCount = this.subOctrees_array.length; i 0) { - this.subOctrees_array[i].deleteLod2GlObjects(gl, vboMemManager); + for (var i=0; i 0) + // static function. + // example of filter: gl.NEAREST + var texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter); + if (data instanceof Uint8Array) { - var numDigits = Math.floor(Math.log10(intNumber)+1); - return numDigits; + //Reference : https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texImage2D + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, data); } else { - return 1; + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, data); } + gl.bindTexture(gl.TEXTURE_2D, null); + return texture; }; +'use strict'; + /** - * 어떤 일을 하고 있습니까? + * Manages textures of the Mago3D. + * @class TexturesManager */ -Octree.prototype.getMotherOctree = function() +var TexturesManager = function(magoManager) { - if (this.octree_owner === undefined) { return this; } + if (!(this instanceof TexturesManager)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + + /** + * Main Mago3D manager. + * @type {MagoManager} + * @default undefined. + */ + this._magoManager = magoManager; + + /** + * WebGL rendering context. + * @type {WebGLRenderingContext} + * @default undefined. + */ + this._gl = this._magoManager.getGl(); - return this.octree_owner.getMotherOctree(); + /** + * Auxiliar texture 1x1 pixel. + * @type {WebGLTexture} + * @default undefined. + */ + this._textureAux_1x1; + + /** + * Noise texture 4x4 pixels used for ssao. + * @type {WebGLTexture} + * @default undefined. + */ + this._noiseTexture_4x4; }; /** - * 어떤 일을 하고 있습니까? - * @param octreeNumberName 변수 - * @param numDigits 변수 - * @returns subOctrees_array[idx-1].getOctree(rest_octreeNumberName, numDigits-1) + * Returns WebGL Rendering Context. */ -Octree.prototype.getOctree = function(octreeNumberName, numDigits) +TexturesManager.prototype.getGl = function() { - if (numDigits === 1) + if (this._gl === undefined) { - if (octreeNumberName === 0) { return this.getMotherOctree(); } - else { return this.subOctrees_array[octreeNumberName-1]; } + this._gl = this._magoManager.getGl(); } + + return this._gl; +}; - // determine the next level octree.*** - var exp = numDigits-1; - var denominator = Math.pow(10, exp); - var idx = Math.floor(octreeNumberName /denominator) % 10; - var rest_octreeNumberName = octreeNumberName - idx * denominator; - return this.subOctrees_array[idx-1].getOctree(rest_octreeNumberName, numDigits-1); + +/** + * Handles the loaded image. + * + * @param {WebGLRenderingContext} gl WebGL rendering context. + * @param {image} image + * @param {WebGLTexture} texture + * @param {Boolean} flip_y_texCoords //if need vertical mirror of the image + */ +function handleTextureLoaded(gl, image, texture, flip_y_texCoords) +{ + if (flip_y_texCoords === undefined) + { flip_y_texCoords = true; } + + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flip_y_texCoords); // if need vertical mirror of the image. + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); // Original. + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST); + gl.generateMipmap(gl.TEXTURE_2D); + gl.bindTexture(gl.TEXTURE_2D, null); }; + /** - * 어떤 일을 하고 있습니까? - * @param octreeNumberName 변수 - * @returns motherOctree.subOctrees_array[idx-1].getOctree(rest_octreeNumberName, numDigits-1) + * Returns the auxiliar texture 1x1 pixel. If is undefined, then creates it. */ -Octree.prototype.getOctreeByNumberName = function(octreeNumberName) +TexturesManager.prototype.getTextureAux1x1 = function() { - var motherOctree = this.getMotherOctree(); - var numDigits = this.getNumberOfDigits(octreeNumberName); - if (numDigits === 1) + if (this._textureAux_1x1 === undefined) { - if (octreeNumberName === 0) { return motherOctree; } - else { return motherOctree.subOctrees_array[octreeNumberName-1]; } + var gl = this.getGl(); + this._textureAux_1x1 = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, this._textureAux_1x1); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([150, 150, 150, 255])); // clear grey + gl.bindTexture(gl.TEXTURE_2D, null); } + + return this._textureAux_1x1; +}; + - if (motherOctree.subOctrees_array.length === 0) { return undefined; } - // determine the next level octree.*** - var exp = numDigits-1; - var denominator = Math.pow(10, exp); - var idx = Math.floor(octreeNumberName /denominator) % 10; - var rest_octreeNumberName = octreeNumberName - idx * denominator; - return motherOctree.subOctrees_array[idx-1].getOctree(rest_octreeNumberName, numDigits-1); -}; /** - * 어떤 일을 하고 있습니까? + * Generates a noise texture. + * It detects the coner or the area which need to be shaded by the distance to camera + * @param {WebGLRenderingContext} gl WebGL rendering context. + * @param {Number} w The width of the texture. + * @param {Number} h The height of the texture. + * @param {Uint8Array} pixels Optional. + * @returns {WebGLTexture} texture Returns WebGLTexture. */ -Octree.prototype.setSizesSubBoxes = function() +function genNoiseTextureRGBA(gl, w, h, pixels) { - // Octree number name.******************************** - // Bottom Top - // |---------|---------| |---------|---------| - // | | | | | | Y - // | 3 | 2 | | 7 | 6 | ^ - // | | | | | | | - // |---------+---------| |---------+---------| | - // | | | | | | | - // | 0 | 1 | | 4 | 5 | | - // | | | | | | |-----------> X - // |---------|---------| |---------|---------| + var texture = gl.createTexture(); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, texture); - if (this.subOctrees_array.length > 0) + if (pixels === undefined) + { pixels = new Uint8Array(4*4*4); } + + if (w === 4 && h === 4) { - var half_x = this.centerPos.x; - var half_y = this.centerPos.y; - var half_z = this.centerPos.z; - - var min_x = this.centerPos.x - this.half_dx; - var min_y = this.centerPos.y - this.half_dy; - var min_z = this.centerPos.z - this.half_dz; - - var max_x = this.centerPos.x + this.half_dx; - var max_y = this.centerPos.y + this.half_dy; - var max_z = this.centerPos.z + this.half_dz; - - this.subOctrees_array[0].setBoxSize(min_x, half_x, min_y, half_y, min_z, half_z); - this.subOctrees_array[1].setBoxSize(half_x, max_x, min_y, half_y, min_z, half_z); - this.subOctrees_array[2].setBoxSize(half_x, max_x, half_y, max_y, min_z, half_z); - this.subOctrees_array[3].setBoxSize(min_x, half_x, half_y, max_y, min_z, half_z); - - this.subOctrees_array[4].setBoxSize(min_x, half_x, min_y, half_y, half_z, max_z); - this.subOctrees_array[5].setBoxSize(half_x, max_x, min_y, half_y, half_z, max_z); - this.subOctrees_array[6].setBoxSize(half_x, max_x, half_y, max_y, half_z, max_z); - this.subOctrees_array[7].setBoxSize(min_x, half_x, half_y, max_y, half_z, max_z); - - for (var i=0; i<8; i++) + var i = 0; + pixels[i] = 50; i++; + pixels[i] = 58; i++; + pixels[i] = 229; i++; + pixels[i] = 120; i++; + pixels[i] = 212; i++; + pixels[i] = 236; i++; + pixels[i] = 251; i++; + pixels[i] = 148; i++; + pixels[i] = 75; i++; + pixels[i] = 92; i++; + pixels[i] = 246; i++; + pixels[i] = 59; i++; + pixels[i] = 197; i++; + pixels[i] = 95; i++; + pixels[i] = 235; i++; + pixels[i] = 216; i++; + pixels[i] = 130; i++; + pixels[i] = 124; i++; + pixels[i] = 215; i++; + pixels[i] = 154; i++; + pixels[i] = 25; i++; + pixels[i] = 41; i++; + pixels[i] = 221; i++; + pixels[i] = 146; i++; + pixels[i] = 187; i++; + pixels[i] = 217; i++; + pixels[i] = 130; i++; + pixels[i] = 199; i++; + pixels[i] = 142; i++; + pixels[i] = 112; i++; + pixels[i] = 61; i++; + pixels[i] = 135; i++; + pixels[i] = 67; i++; + pixels[i] = 125; i++; + pixels[i] = 159; i++; + pixels[i] = 153; i++; + pixels[i] = 215; i++; + pixels[i] = 49; i++; + pixels[i] = 49; i++; + pixels[i] = 69; i++; + pixels[i] = 126; i++; + pixels[i] = 168; i++; + pixels[i] = 61; i++; + pixels[i] = 215; i++; + pixels[i] = 21; i++; + pixels[i] = 93; i++; + pixels[i] = 183; i++; + pixels[i] = 1; i++; + pixels[i] = 125; i++; + pixels[i] = 44; i++; + pixels[i] = 22; i++; + pixels[i] = 130; i++; + pixels[i] = 197; i++; + pixels[i] = 118; i++; + pixels[i] = 109; i++; + pixels[i] = 23; i++; + pixels[i] = 195; i++; + pixels[i] = 4; i++; + pixels[i] = 148; i++; + pixels[i] = 245; i++; + pixels[i] = 124; i++; + pixels[i] = 125; i++; + pixels[i] = 185; i++; + pixels[i] = 28; i++; + } + else + { + for (var y=0; y 0) - { - for (var i=0; i0) // original.*** - //if(this.triPolyhedronsCount>0) - { - result_NeoRefListsArray.push(this.neoRefsList_Array[0]); // there are only 1.*** - } + this.triSurfacesArray[i].invertTrianglesSenses(); } }; /** - * 어떤 일을 하고 있습니까? - * @param cullingVolume 변수 - * @param result_NeoRefListsArray 변수 - * @param boundingSphere_scratch 변수 - * @param eye_x 변수 - * @param eye_y 변수 - * @param eye_z 변수 + * Get the information of the VBO key of the triangles which consist of the TriPolyhedron + * @param {VBOVertexIdxCacheKey} resultVBOVertexIdxCacheKey the array which will hold the VBO key of the triangular meshes + * @param {VBOMemoryManager} vboMemManager + * @returns {VBOVertexIdxCacheKey} */ -Octree.prototype.getFrustumVisibleLowestOctreesByLOD = function(cullingVolume, visibleObjControlerOctrees, globalVisibleObjControlerOctrees, - boundingSphere_scratch, cameraPosition, squaredDistLod0, squaredDistLod1, squaredDistLod2) +TriPolyhedron.prototype.getVBOArrayModePosNorCol = function(resultVBOVertexIdxCacheKey, vboMemManager) { - var visibleOctreesArray = []; - var find = false; + // there are "arrayMode" and the "elementMode". "elementMode" uses indices. + if (resultVBOVertexIdxCacheKey === undefined) + { resultVBOVertexIdxCacheKey = new VBOVertexIdxCacheKey(); } - //this.getAllSubOctrees(visibleOctreesArray); // Test.*** - this.getFrustumVisibleOctreesNeoBuildingAsimetricVersion(cullingVolume, visibleOctreesArray, boundingSphere_scratch); // Original.*** + if (resultVBOVertexIdxCacheKey.posVboDataArray === undefined) + { resultVBOVertexIdxCacheKey.posVboDataArray = []; } - // Now, we must sort the subOctrees near->far from eye.*** - var visibleOctrees_count = visibleOctreesArray.length; - for (var i=0; i 0) - { - if (globalVisibleObjControlerOctrees) - { this.putOctreeInEyeDistanceSortedArray(globalVisibleObjControlerOctrees.currentVisibles0, visibleOctreesArray[i]); } - visibleObjControlerOctrees.currentVisibles0.push(visibleOctreesArray[i]); - find = true; - } - } - else if (visibleOctreesArray[i].distToCamera < squaredDistLod1) - { - if (visibleOctreesArray[i].triPolyhedronsCount > 0) - { - if (globalVisibleObjControlerOctrees) - { this.putOctreeInEyeDistanceSortedArray(globalVisibleObjControlerOctrees.currentVisibles1, visibleOctreesArray[i]); } - visibleObjControlerOctrees.currentVisibles1.push(visibleOctreesArray[i]); - find = true; - } - } - else if (visibleOctreesArray[i].distToCamera < squaredDistLod2) + triSurface = this.triSurfacesArray[i]; + trianglesCount = triSurface.trianglesArray.length; + for (var j = 0; j < trianglesCount; j++) { - if (visibleOctreesArray[i].triPolyhedronsCount > 0) + triangle = triSurface.trianglesArray[j]; + if (triangle.normal === undefined) + { triangle.calculatePlaneNormal(); } + + // position. + vertex0 = triangle.vertex0; + vertex1 = triangle.vertex1; + vertex2 = triangle.vertex2; + + positionArray.push(vertex0.point3d.x); + positionArray.push(vertex0.point3d.y); + positionArray.push(vertex0.point3d.z); + + positionArray.push(vertex1.point3d.x); + positionArray.push(vertex1.point3d.y); + positionArray.push(vertex1.point3d.z); + + positionArray.push(vertex2.point3d.x); + positionArray.push(vertex2.point3d.y); + positionArray.push(vertex2.point3d.z); + + // normal (use planeNormal). + normalsArray.push(triangle.normal.x); + normalsArray.push(triangle.normal.y); + normalsArray.push(triangle.normal.z); + + normalsArray.push(triangle.normal.x); + normalsArray.push(triangle.normal.y); + normalsArray.push(triangle.normal.z); + + normalsArray.push(triangle.normal.x); + normalsArray.push(triangle.normal.y); + normalsArray.push(triangle.normal.z); + + // colors. + if (vertex0.color4 === undefined) { - if (globalVisibleObjControlerOctrees) - { this.putOctreeInEyeDistanceSortedArray(globalVisibleObjControlerOctrees.currentVisibles2, visibleOctreesArray[i]); } - visibleObjControlerOctrees.currentVisibles2.push(visibleOctreesArray[i]); - find = true; + colorsArray.push(200); + colorsArray.push(200); + colorsArray.push(200); + colorsArray.push(200); + + colorsArray.push(200); + colorsArray.push(200); + colorsArray.push(200); + colorsArray.push(200); + + colorsArray.push(200); + colorsArray.push(200); + colorsArray.push(200); + colorsArray.push(200); } - } - else - { - if (visibleOctreesArray[i].triPolyhedronsCount > 0) + else { - if (globalVisibleObjControlerOctrees) - { globalVisibleObjControlerOctrees.currentVisibles3.push(visibleOctreesArray[i]); } - visibleObjControlerOctrees.currentVisibles3.push(visibleOctreesArray[i]); - find = true; + colorsArray.push(vertex0.color4.r); + colorsArray.push(vertex0.color4.g); + colorsArray.push(vertex0.color4.b); + colorsArray.push(vertex0.color4.a); + + colorsArray.push(vertex1.color4.r); + colorsArray.push(vertex1.color4.g); + colorsArray.push(vertex1.color4.b); + colorsArray.push(vertex1.color4.a); + + colorsArray.push(vertex2.color4.r); + colorsArray.push(vertex2.color4.g); + colorsArray.push(vertex2.color4.b); + colorsArray.push(vertex2.color4.a); } + + resultVBOVertexIdxCacheKey.vertexCount += 3; } } - visibleOctreesArray = undefined; - return find; + var vertexCount = resultVBOVertexIdxCacheKey.vertexCount; + + var float32PosArray = new Float32Array(vertexCount*3); + float32PosArray.set(positionArray); + + var int8NorArray = new Int8Array(vertexCount*3); + int8NorArray.set(normalsArray); + + var uint8ColArray = new Uint8Array(vertexCount*4); + uint8ColArray.set(colorsArray); + + //////////////////////////////////////////////////////////////////////////////// + // Positions + resultVBOVertexIdxCacheKey.setDataArrayPos(float32PosArray, vboMemManager); + + // Normals. + resultVBOVertexIdxCacheKey.setDataArrayNor(int8NorArray, vboMemManager); + + // Colors. + resultVBOVertexIdxCacheKey.setDataArrayCol(uint8ColArray, vboMemManager); + //////////////////////////////////////////////////////////////////////////////// + + return resultVBOVertexIdxCacheKey; }; + + + + + + + + + + + + + + + +'use strict'; + /** - * 어떤 일을 하고 있습니까? - * @param x 변수 - * @param y 변수 - * @param z 변수 - * @returns intersects + * This feature consists of TriPolyhedron + * Using this feature, we can save the lid, bottom, and side surface. + * @class TriSurface */ -Octree.prototype.intersectsWithPoint3D = function(x, y, z) +var TriSurface = function() { - //this.centerPos = new Point3D(); - //this.half_dx = 0.0; // half width.*** - //this.half_dy = 0.0; // half length.*** - //this.half_dz = 0.0; // half height.*** - var minX = this.centerPos.x - this.half_dx; - var minY = this.centerPos.y - this.half_dz; - var minZ = this.centerPos.z - this.half_dz; - var maxX = this.centerPos.x + this.half_dx; - var maxY = this.centerPos.y + this.half_dz; - var maxZ = this.centerPos.z + this.half_dz; - - var intersects = false; - if (x> minX && x minY && y minZ && z 0) - { - var center_x = this.centerPos.x; - var center_y = this.centerPos.y; - var center_z = this.centerPos.z; - - var intersectedSubBox_aux = undefined; - var intersectedSubBox_idx; - if (xfar from eye.*** - var visibleOctrees_count = this.lowestOctrees_array.length; - for (var i=0; i 0) - { - if (globalVisibleObjControlerOctrees) - { this.putOctreeInEyeDistanceSortedArray(globalVisibleObjControlerOctrees.currentVisibles0, this.lowestOctrees_array[i]); } - visibleObjControlerOctrees.currentVisibles0.push(this.lowestOctrees_array[i]); - find = true; - } - } - else if (this.lowestOctrees_array[i].distToCamera < squaredDistLod1) - { - if (this.lowestOctrees_array[i].triPolyhedronsCount > 0) - { - if (globalVisibleObjControlerOctrees) - { this.putOctreeInEyeDistanceSortedArray(globalVisibleObjControlerOctrees.currentVisibles1, this.lowestOctrees_array[i]); } - visibleObjControlerOctrees.currentVisibles1.push(this.lowestOctrees_array[i]); - find = true; - } - } - else if (this.lowestOctrees_array[i].distToCamera < squaredDistLod2) - { - if (this.lowestOctrees_array[i].triPolyhedronsCount > 0) - { - if (globalVisibleObjControlerOctrees) - { this.putOctreeInEyeDistanceSortedArray(globalVisibleObjControlerOctrees.currentVisibles2, this.lowestOctrees_array[i]); } - visibleObjControlerOctrees.currentVisibles2.push(this.lowestOctrees_array[i]); - find = true; - } - } - else + if (this.dataArray === undefined) { return false; } + if (this.dataLength === undefined) { - if (this.lowestOctrees_array[i].triPolyhedronsCount > 0) - { - if (globalVisibleObjControlerOctrees) - { globalVisibleObjControlerOctrees.currentVisibles3.push(this.lowestOctrees_array[i]); } - visibleObjControlerOctrees.currentVisibles3.push(this.lowestOctrees_array[i]); - find = true; - } + this.dataLength = this.dataArray.length; } + this.key = vboMemManager.getClassifiedBufferKey(gl, this.dataLength); + if (this.key === undefined) + { return false; } + gl.bindBuffer(this.dataTarget, this.key); + gl.bufferData(this.dataTarget, this.dataArray, gl.STATIC_DRAW); + this.dataArray = undefined; + return true; } - - return find; + return true; }; - /** * 어떤 일을 하고 있습니까? - * @param cesium_cullingVolume 변수 - * @param result_octreesArray 변수 - * @param boundingSphere_scratch 변수 */ -Octree.prototype.getFrustumVisibleOctreesNeoBuildingAsimetricVersion = function(cullingVolume, result_octreesArray, boundingSphere_scratch) +VboBuffer.getGlTypeOfArray = function(dataArray) { - //if(this.subOctrees_array.length === 0 && this.neoRefsList_Array.length === 0) // original.*** - if (this.subOctrees_array === undefined) { return; } - - if (this.subOctrees_array.length === 0 && this.triPolyhedronsCount === 0) - //if(this.subOctrees_array.length === 0 && this.compRefsListArray.length === 0) // For use with ifc buildings.*** - { return; } - - if (result_octreesArray === undefined) { result_octreesArray = []; } + var glType = -1; + if (dataArray.constructor === Float32Array) + { glType = 5126; } // gl.FLOAT. + else if (dataArray.constructor === Int16Array) + { glType = 5122; } // gl.SHORT. + else if (dataArray.constructor === Uint16Array) + { glType = 5123; } // gl.UNSIGNED_SHORT. + else if (dataArray.constructor === Int8Array) + { glType = 5120; } // gl.BYTE. + else if (dataArray.constructor === Uint8Array) + { glType = 5121; } // gl.UNSIGNED_BYTE. - if (boundingSphere_scratch === undefined) - { boundingSphere_scratch = new Sphere(); } - - boundingSphere_scratch.centerPoint.x = this.centerPos.x; - boundingSphere_scratch.centerPoint.y = this.centerPos.y; - boundingSphere_scratch.centerPoint.z = this.centerPos.z; - boundingSphere_scratch.r = this.getRadiusAprox(); + return glType; +}; - var frustumCull = cullingVolume.intersectionSphere(boundingSphere_scratch); - if (frustumCull === Constant.INTERSECTION_INSIDE ) +/** + * 어떤 일을 하고 있습니까? + */ +VboBuffer.newTypedArray = function(arrayLength, glType) +{ + var typedArray; + if (glType === 5126)// gl.FLOAT. + { typedArray = new Float32Array(arrayLength); } + else if (glType === 5122)// gl.SHORT. + { typedArray = new Int16Array(arrayLength); } + else if (glType === 5123)// gl.UNSIGNED_SHORT. + { typedArray = new Uint16Array(arrayLength); } + else if (glType === 5120)// gl.BYTE. + { typedArray = new Int8Array(arrayLength); } + else if (glType === 5121)// gl.UNSIGNED_BYTE. + { typedArray = new Uint8Array(arrayLength); } + + return typedArray; +}; +'use strict'; +/** + * 어떤 일을 하고 있습니까? + * @class VBOKeysNation + */ +var VBOKeysNation = function(bufferSizes, minSize) +{ + if (!(this instanceof VBOKeysNation)) { - //result_octreesArray.push(this); - this.getAllSubOctreesIfHasRefLists(result_octreesArray); + throw new Error(Messages.CONSTRUCT_ERROR); } - else if (frustumCull === Constant.INTERSECTION_INTERSECT ) + // buffer sizes are in bytes. + this.vboKeysStoreMap = {}; + this.bufferSizes = bufferSizes; + this.minSize = minSize; + this.maxSize = bufferSizes[bufferSizes.length-1]; + this.totalBytesUsed = 0; + + var vboKeysStore; + var sizesCount = bufferSizes.length; + for (var i=0; i 0) // original.*** - //if(this.triPolyhedronsCount > 0) - result_octreesArray.push(this); - } - else - { - for (var i=0, subOctreesArrayLength = this.subOctrees_array.length; i this.maxSize) { this.maxSize = bufferSizes[i]; } } }; /** * 어떤 일을 하고 있습니까? - * @param cesium_cullingVolume 변수 - * @param result_octreesArray 변수 - * @param boundingSphere_scratch 변수 + * @returns vboBufferKey. */ -Octree.prototype.getBBoxIntersectedOctreesNeoBuildingAsimetricVersion = function(bbox, result_octreesArray, bbox_scratch) +VBOKeysNation.prototype.getClassifiedBufferKey = function(gl, bufferSize, keyWorld, onlyReuse) { - if (this.subOctrees_array === undefined) { return; } - - if (this.subOctrees_array.length === 0 && this.triPolyhedronsCount === 0) - { return; } - - if (result_octreesArray === undefined) { result_octreesArray = []; } - - if (bbox_scratch === undefined) - { bbox_scratch = new BoundingBox(); } + // 1rst find the vboKeyStore for this bufferSize. + var closestBufferSize = this.getClosestBufferSize(bufferSize); + var vboKeyStore = this.vboKeysStoreMap[closestBufferSize]; - - bbox_scratch.minX = this.centerPos.x - this.half_dx; - bbox_scratch.maxX = this.centerPos.x + this.half_dx; - bbox_scratch.minY = this.centerPos.y - this.half_dy; - bbox_scratch.maxY = this.centerPos.y + this.half_dy; - bbox_scratch.minZ = this.centerPos.z - this.half_dz; - bbox_scratch.maxZ = this.centerPos.z + this.half_dz; - - var intersects = bbox.intersectsWithBBox(bbox_scratch); - if (intersects) + if (vboKeyStore) { - this.getAllSubOctreesIfHasRefLists(result_octreesArray); + return vboKeyStore.getBufferKey(gl, this, keyWorld, onlyReuse); } + else { return -1; } }; /** * 어떤 일을 하고 있습니까? - * @param eye_x 변수 - * @param eye_y 변수 - * @param eye_z 변수 + * @returns vboBufferKey. */ -Octree.prototype.setDistToCamera = function(cameraPosition) +VBOKeysNation.prototype.storeClassifiedBufferKey = function(bufferKey, bufferSize) { - // distance to camera as a sphere. - var distToCamera = this.centerPos.distToPoint(cameraPosition) - this.getRadiusAprox(); - this.distToCamera = distToCamera; - return distToCamera; + // 1rst find the vboKeyStore for this bufferSize. + var vboKeyStore = this.vboKeysStoreMap[bufferSize]; + if (vboKeyStore) + { + vboKeyStore.storeBufferKey(bufferKey); + } }; /** * 어떤 일을 하고 있습니까? - * @param octreesArray 변수 - * @param octree 변수 - * @returns result_idx + * @returns boolean. true if the currentBufferSize is in the range of this nation. */ -Octree.prototype.getIndexToInsertBySquaredDistToEye = function(octreesArray, octree, startIdx, endIdx) +VBOKeysNation.prototype.getClosestBufferSize = function(currentBufferSize) { - // this do a dicotomic search of idx in a ordered table. - // 1rst, check the range. - if (startIdx === undefined) - { startIdx = 0; } - - if (endIdx === undefined) - { endIdx = octreesArray.length-1; } - - var range = endIdx - startIdx; - - if (range <= 0) - { return 0; } + if (!this.isInsideRange(currentBufferSize)) + { return -1; } - if (range < 6) - { - // in this case do a lineal search. - var finished = false; - var i = startIdx; - var idx; - var octreesCount = octreesArray.length; - while (!finished && i<=endIdx) - { - if (octree.distToCamera < octreesArray[i].distToCamera) - { - idx = i; - finished = true; - } - i++; - } - - if (finished) - { - return idx; - } - else - { - return endIdx+1; - } - } - else + var sizesCount = this.bufferSizes.length; + for (var i=0; i octree.distToCamera) - { - newStartIdx = startIdx; - newEndIdx = middleIdx; - } - else + if (currentBufferSize <= this.bufferSizes[i]) { - newStartIdx = middleIdx; - newEndIdx = endIdx; + return this.bufferSizes[i]; } - return this.getIndexToInsertBySquaredDistToEye(octreesArray, octree, newStartIdx, newEndIdx); } + return -1; }; /** * 어떤 일을 하고 있습니까? - * @param result_octreesArray 변수 - * @param octree 변수 + * @returns boolean. true if the currentBufferSize is in the range of this nation. */ -Octree.prototype.putOctreeInEyeDistanceSortedArray = function(result_octreesArray, octree) +VBOKeysNation.prototype.isInsideRange = function(bufferSize) { - // sorting is from minDist to maxDist.*** - if (result_octreesArray.length > 0) - { - var startIdx = 0; - var endIdx = result_octreesArray.length - 1; - var insert_idx= this.getIndexToInsertBySquaredDistToEye(result_octreesArray, octree, startIdx, endIdx); + if (bufferSize > this.maxSize || bufferSize < this.minSize) + { return false; } - result_octreesArray.splice(insert_idx, 0, octree); - } - else + return true; +}; + +'use strict'; + +/** + * 어떤 일을 하고 있습니까? + * @class VBOKeysStore + */ +var VBOKeysStore = function(bufferSize) +{ + if (!(this instanceof VBOKeysStore)) { - result_octreesArray.push(octree); + throw new Error(Messages.CONSTRUCT_ERROR); } + + this.classifiedSize = bufferSize; + this.vboKeysArray = []; + this.keysCreated = 0; // total keys created for this size. }; /** * 어떤 일을 하고 있습니까? - * @param result_octreesArray 변수 + * @returns boolean. */ -Octree.prototype.getAllSubOctreesIfHasRefLists = function(result_octreesArray) +VBOKeysStore.prototype.getBufferKey = function(gl, keyNation, keyWorld, onlyReuse) { - if (this.subOctrees_array === undefined) { return; } - - if (result_octreesArray === undefined) { result_octreesArray = []; } - - if (this.subOctrees_array.length > 0) + if (this.vboKeysArray.length > 0) { - for (var i=0, subOctreesArrayLength = this.subOctrees_array.length; i 0) - if (this.triPolyhedronsCount > 0) { result_octreesArray.push(this); } // there are only 1.*** + if (!onlyReuse) + { + // there are no free key, so create one. + var vboKey = gl.createBuffer(); + this.keysCreated += 1; // increment key created counter. + keyNation.totalBytesUsed += this.classifiedSize; + keyWorld.totalBytesUsed += this.classifiedSize; + return vboKey; + } + return undefined; } }; /** * 어떤 일을 하고 있습니까? - * @param result_octreesArray 변수 + * @returns boolean. */ -Octree.prototype.getAllSubOctrees = function(result_octreesArray) +VBOKeysStore.prototype.storeBufferKey = function(bufferKey) { - if (result_octreesArray === undefined) { result_octreesArray = []; } + this.vboKeysArray.push(bufferKey); +}; - if (this.subOctrees_array.length > 0) - { - for (var i=0, subOctreesArrayLength = this.subOctrees_array.length; i 0) + // check gpuMemory limit. + // If current totalBytesUsed is greater than bytesLimit, then enters in mode "onlyReuse". + // "onlyReuse" = no allocate GPU memory, only use the existent + var onlyReuse = false; + if (this.totalBytesUsed > this.bytesLimit) { - lowestOctreesArray.push(this); + onlyReuse = true; } - else + + // 1rst, find the Nation for this bufferSize. + var keyNation = this.getKeyNationBySize(bufferSize); + var vboBufferKey = undefined; + if (keyNation) { - for (var i=0; i 0) - { - if (this.neoReferencesMotherAndIndices) - { this.neoReferencesMotherAndIndices.multiplyKeyTransformMatrix(idxKey, matrix); } - } - else +/** + * 어떤 일을 하고 있습니까? + * @returns vboBufferCacheKey + */ +VBOKeysWorld.prototype.getKeyNationBySize = function(bufferSize) +{ + // 1rst, find the Nation for this bufferSize. + var nationsCount = this.vboKeysNationsArray.length; + var i=0; + var vboBufferKey = -1; + while (i 0) - { this.neoBuildingOwner = neoBuildingOwner; } - - // 1rst, create the 8 subOctrees.*** - for (var i=0; i no management of the gpu memory. + this.enableMemoryManagement = false; + + this.buffersKeyWorld = new VBOKeysWorld(); + this.elementKeyWorld = new VBOKeysWorld(); + + this.buffersKeyWorld.bytesLimit = 800000000; + this.elementKeyWorld.bytesLimit = 300000000; + + this.currentMemoryUsage = 0.0; }; - - -ParseQueue.prototype.putTinTerrainToParse = function(tinTerrain, aValue) +/** + * 어떤 일을 하고 있습니까? + * @returns vboBufferCacheKey + */ +VBOMemoryManager.prototype.isGpuMemFull = function() { - // provisionally "aValue" can be anything. - if (aValue === undefined) - { aValue = 0; } - - this.tinTerrainsToParseMap[tinTerrain.pathName] = tinTerrain; + if (this.buffersKeyWorld.totalBytesUsed > this.buffersKeyWorld.bytesLimit || this.elementKeyWorld.totalBytesUsed > this.elementKeyWorld.bytesLimit) + { return true; } + else { return false; } }; -ParseQueue.prototype.eraseTinTerrainToParse = function(tinTerrain) +/** + * 어떤 일을 하고 있습니까? + * @returns vboBufferCacheKey + */ +VBOMemoryManager.prototype.getClassifiedBufferKey = function(gl, bufferSize) { - if (tinTerrain === undefined) - { return; } - - var key = tinTerrain.pathName; - if (this.tinTerrainsToParseMap.hasOwnProperty(key)) - { - delete this.tinTerrainsToParseMap[key]; - return true; + if (this.enableMemoryManagement) + { + var bufferKey = this.buffersKeyWorld.getClassifiedBufferKey(gl, bufferSize); + if (bufferKey !== undefined) + { this.currentMemoryUsage += bufferSize; } + return bufferKey; + } + else + { + this.currentMemoryUsage += bufferSize; + return gl.createBuffer(); } - return false; }; -ParseQueue.prototype.parseOctreesPCloud = function(gl, visibleObjControlerOctrees, magoManager, maxParsesCount) +/** + * 어떤 일을 하고 있습니까? + * @returns vboBufferCacheKey + */ +VBOMemoryManager.prototype.storeClassifiedBufferKey = function(gl, bufferKey, bufferSize) { - var neoBuilding; - var lowestOctree; - var headerVersion; - var node; - var rootNode; - var geoLocDataManager; - - if (this.matrix4SC === undefined) - { this.matrix4SC = new Matrix4(); } - - var octreesParsedCount = 0; - if (maxParsesCount === undefined) - { maxParsesCount = 20; } - - var octreesCount = Object.keys(this.octreesLod0ReferencesToParseMap).length; - if (octreesCount > 0) + if (this.enableMemoryManagement) + { this.buffersKeyWorld.storeClassifiedBufferKey(bufferKey, bufferSize); } + else + { gl.deleteBuffer(bufferKey); } + + this.currentMemoryUsage -= bufferSize; + if (this.currentMemoryUsage < 0.0) + { this.currentMemoryUsage = 0.0; } +}; + +/** + * 어떤 일을 하고 있습니까? + * @returns vboBufferCacheKey + */ +VBOMemoryManager.prototype.getClassifiedElementKey = function(gl, bufferSize) +{ + if (this.enableMemoryManagement) + { return this.elementKeyWorld.getClassifiedBufferKey(gl, bufferSize); } + else + { return gl.createBuffer(); } +}; + +/** + * 어떤 일을 하고 있습니까? + * @returns vboBufferCacheKey + */ +VBOMemoryManager.prototype.storeClassifiedElementKey = function(gl, bufferKey, bufferSize) +{ + if (this.enableMemoryManagement) + { this.elementKeyWorld.storeClassifiedBufferKey(bufferKey, bufferSize); } + else + { gl.deleteBuffer(bufferKey); } +}; + +/** + * 어떤 일을 하고 있습니까? + * @returns vboBufferStandardSize + */ +VBOMemoryManager.prototype.getClassifiedBufferSize = function(currentBufferSize) +{ + if (this.enableMemoryManagement) + { return this.buffersKeyWorld.getClassifiedBufferSize(currentBufferSize); } + else + { return currentBufferSize; } +}; +'use strict'; +/** + * 어떤 일을 하고 있습니까? + * @class VBOVertexIdxCacheKey + */ +var VBOVertexIdxCacheKey = function() +{ + if (!(this instanceof VBOVertexIdxCacheKey)) { - // 1rst parse the currently closest lowestOctrees to camera. - var octreesLod0Count = visibleObjControlerOctrees.currentVisibles0.length; - for (var i=0; i maxParsesCount) - { break; } - } - - // now clear queue.*** - - - // if no parsed any octree, then parse some octrees of the queue. - if (octreesParsedCount === 0) - { - //var octreesArray = Array.from(this.octreesLod0ReferencesToParseMap.keys()); - //var octreesArray = Object.keys(this.octreesLod0ReferencesToParseMap); - ///for (var i=0; i maxParsesCount) - { break; } - } - } - } + throw new Error(Messages.CONSTRUCT_ERROR); } + + this.indicesCount = -1; + this.vertexCount = -1; + this.bigTrianglesIndicesCount = -1; - if (octreesParsedCount > 0) - { return true; } - else { return false; } + this.vboBufferPos; + this.vboBufferNor; + this.vboBufferIdx; + this.vboBufferCol; + this.vboBufferTCoord; + }; -ParseQueue.prototype.parseOctreesLod0References = function(gl, visibleObjControlerOctrees, magoManager, maxParsesCount) +/** + * 어떤 일을 하고 있습니까? + */ +VBOVertexIdxCacheKey.prototype.stepOverPosNorIdx = function(arrayBuffer, readWriter, vboMemManager, bytesReaded) { - var neoBuilding; - var lowestOctree; - var headerVersion; - var node; - var rootNode; - var geoLocDataManager; + var startBuff, endBuff; - if (this.matrix4SC === undefined) - { this.matrix4SC = new Matrix4(); } + // 1) Positions array. + var vertexCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4); + bytesReaded += 4; + var verticesFloatValuesCount = vertexCount * 3; + startBuff = bytesReaded; + endBuff = bytesReaded + 4 * verticesFloatValuesCount; + bytesReaded = bytesReaded + 4 * verticesFloatValuesCount; // updating data. - var octreesParsedCount = 0; - if (maxParsesCount === undefined) - { maxParsesCount = 20; } + // 2) Normals. + vertexCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4); + bytesReaded += 4; + var normalByteValuesCount = vertexCount * 3; + startBuff = bytesReaded; + endBuff = bytesReaded + 1 * normalByteValuesCount; + bytesReaded = bytesReaded + 1 * normalByteValuesCount; // updating data. - var octreesCount = Object.keys(this.octreesLod0ReferencesToParseMap).length; - if (octreesCount > 0) + // 3) Indices. + var shortIndicesValuesCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4); + + bytesReaded += 4; + var sizeLevels = readWriter.readUInt8(arrayBuffer, bytesReaded, bytesReaded+1); + bytesReaded +=1; + //var sizeThresholds = []; + for ( var k = 0; k < sizeLevels; k++ ) { - // 1rst parse the currently closest lowestOctrees to camera. - var octreesLod0Count = visibleObjControlerOctrees.currentVisibles0.length; - for (var i=0; i maxParsesCount) - { break; } - } - - // clear queue.*** - this.octreesLod0ReferencesToParseMap = {}; - /* - - // if no parsed any octree, then parse some octrees of the queue. - if (octreesParsedCount === 0) - { - //var octreesArray = Array.from(this.octreesLod0ReferencesToParseMap.keys()); - //var octreesArray = Object.keys(this.octreesLod0ReferencesToParseMap); - ///for (var i=0; i maxParsesCount) - { break; } - } - } - } - */ + //sizeThresholds.push(new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4))); + bytesReaded += 4; } - - if (octreesParsedCount > 0) - { return true; } - else { return false; } + //var indexMarkers = []; + for ( var k = 0; k < sizeLevels; k++ ) + { + //indexMarkers.push(readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4)); + bytesReaded += 4; + } + //var bigTrianglesShortIndicesValues_count = indexMarkers[sizeLevels-1]; + //this.bigTrianglesIndicesCount = bigTrianglesShortIndicesValues_count; + startBuff = bytesReaded; + endBuff = bytesReaded + 2 * shortIndicesValuesCount; + //var idxDataArray = new Uint16Array(arrayBuffer.slice(startBuff, endBuff)); + //this.setDataArrayIdx(idxDataArray, vboMemManager); + + bytesReaded = bytesReaded + 2 * shortIndicesValuesCount; // updating data. + return bytesReaded; }; -ParseQueue.prototype.parseOctreesLod0References = function(gl, lowestOctree, magoManager) +/** + * 어떤 일을 하고 있습니까? + */ +VBOVertexIdxCacheKey.prototype.readPosNorIdx = function(arrayBuffer, readWriter, vboMemManager, bytesReaded) { - var parsed = false; - if (this.octreesLod0ReferencesToParseMap.hasOwnProperty(lowestOctree.octreeKey)) - { - delete this.octreesLod0ReferencesToParseMap[lowestOctree.octreeKey]; - if (lowestOctree.neoReferencesMotherAndIndices === undefined) - { return false; } - - if (lowestOctree.neoReferencesMotherAndIndices.dataArraybuffer === undefined) - { return false; } + var startBuff, endBuff; - if (lowestOctree.neoReferencesMotherAndIndices.fileLoadState !== CODE.fileLoadState.LOADING_FINISHED) - { return false; } - - var neoBuilding = lowestOctree.neoBuildingOwner; - var node = neoBuilding.nodeOwner; - var rootNode; - if (node) - { rootNode = node.getRoot(); } - else - { rootNode = undefined; } - - if (rootNode === undefined) - { return false; } - - if (rootNode.data === undefined) - { return false; } - - var geoLocDataManager = rootNode.data.geoLocDataManager; - - if (geoLocDataManager === undefined) - { return false; } + // 1) Positions array. + var vertexCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4); + this.vertexCount = vertexCount; + bytesReaded += 4; + var verticesFloatValuesCount = vertexCount * 3; - if (this.matrix4SC === undefined) - { this.matrix4SC = new Matrix4(); } - - //var buildingGeoLocation = neoBuilding.getGeoLocationData(); // old.*** - var buildingGeoLocation = geoLocDataManager.getCurrentGeoLocationData(); - var headerVersion = neoBuilding.getHeaderVersion(); - this.matrix4SC.setByFloat32Array(buildingGeoLocation.rotMatrix._floatArrays); - if (headerVersion[0] === "v") - { - // parse beta version. - lowestOctree.neoReferencesMotherAndIndices.parseArrayBufferReferences(gl, lowestOctree.neoReferencesMotherAndIndices.dataArraybuffer, magoManager.readerWriter, neoBuilding, this.matrix4SC, magoManager); - } - else - { - // parse vesioned. - lowestOctree.neoReferencesMotherAndIndices.parseArrayBufferReferencesVersioned(gl, lowestOctree.neoReferencesMotherAndIndices.dataArraybuffer, magoManager.readerWriter, neoBuilding, this.matrix4SC, magoManager); - } - lowestOctree.neoReferencesMotherAndIndices.multiplyKeyTransformMatrix(0, buildingGeoLocation.rotMatrix); - lowestOctree.neoReferencesMotherAndIndices.dataArraybuffer = undefined; - parsed = true; - } + startBuff = bytesReaded; + endBuff = bytesReaded + 4 * verticesFloatValuesCount; + var posDataArray = new Float32Array(arrayBuffer.slice(startBuff, endBuff)); + this.setDataArrayPos(posDataArray, vboMemManager); + + bytesReaded = bytesReaded + 4 * verticesFloatValuesCount; // updating data. - return parsed; -}; + // 2) Normals. + vertexCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4); + bytesReaded += 4; + var normalByteValuesCount = vertexCount * 3; + startBuff = bytesReaded; + endBuff = bytesReaded + 1 * normalByteValuesCount; + var norDataArray = new Int8Array(arrayBuffer.slice(startBuff, endBuff)); + this.setDataArrayNor(norDataArray, vboMemManager); + + bytesReaded = bytesReaded + 1 * normalByteValuesCount; // updating data. + + // 3) Indices. + var shortIndicesValuesCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4); + bytesReaded += 4; + var sizeLevels = readWriter.readUInt8(arrayBuffer, bytesReaded, bytesReaded+1); + bytesReaded +=1; + var sizeThresholds = []; + for ( var k = 0; k < sizeLevels; k++ ) + { + sizeThresholds.push(new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4))); + bytesReaded += 4; + } + var indexMarkers = []; + for ( var k = 0; k < sizeLevels; k++ ) + { + indexMarkers.push(readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4)); + bytesReaded += 4; + } + var bigTrianglesShortIndicesValues_count = indexMarkers[sizeLevels-1]; + this.bigTrianglesIndicesCount = bigTrianglesShortIndicesValues_count; + startBuff = bytesReaded; + endBuff = bytesReaded + 2 * shortIndicesValuesCount; + var idxDataArray = new Uint16Array(arrayBuffer.slice(startBuff, endBuff)); + this.setDataArrayIdx(idxDataArray, vboMemManager); -ParseQueue.prototype.putOctreeLod0ReferencesToParse = function(octree, aValue) -{ - // provisionally "aValue" can be anything. - if (aValue === undefined) - { aValue = 0; } - - ///this.octreesLod0ReferencesToParseMap.set(octree, aValue); - this.octreesLod0ReferencesToParseMap[octree.octreeKey] = octree; + bytesReaded = bytesReaded + 2 * shortIndicesValuesCount; // updating data. + return bytesReaded; }; -ParseQueue.prototype.eraseOctreeLod0ReferencesToParse = function(octree) +/** + * 어떤 일을 하고 있습니까? + */ +VBOVertexIdxCacheKey.prototype.bindDataPosition = function(shader, vboMemManager) { - delete this.octreesLod0ReferencesToParseMap[octree.octreeKey]; + if (shader === undefined) + { return false; } + + var gl = shader.gl; + var vboBufferPos = this.vboBufferPos; + if (!vboBufferPos.isReady(gl, vboMemManager)) + { return false; } + + if (shader.position3_loc !== undefined && shader.position3_loc !== -1) + { + shader.enableVertexAttribArray(shader.position3_loc); + if (vboBufferPos.key !== shader.last_vboPos_binded) + { + gl.bindBuffer(vboBufferPos.dataTarget, vboBufferPos.key); + gl.vertexAttribPointer(shader.position3_loc, 3, vboBufferPos.dataGlType, false, 0, 0); + shader.last_vboPos_binded = vboBufferPos.key; + } + return true; + } + else { shader.disableVertexAttribArray(shader.position3_loc); } + return false; }; -ParseQueue.prototype.putOctreeLod0ModelsToParse = function(octree, aValue) +/** + * 어떤 일을 하고 있습니까? + */ +VBOVertexIdxCacheKey.prototype.bindDataNormal = function(shader, vboMemManager) { - // provisionally "aValue" can be anything. - if (aValue === undefined) - { aValue = 0; } + if (shader === undefined) + { return false; } - this.octreesLod0ModelsToParseMap[octree.octreeKey] = octree; + var vboBufferNor = this.vboBufferNor; + if (vboBufferNor === undefined) + { + shader.disableVertexAttribArray(shader.normal3_loc); + return true; // Return "true" bcos there are no "normal" data, that is different that having "normal" data and not prepared yet. + } + + var gl = shader.gl; + if (!vboBufferNor.isReady(gl, vboMemManager)) + { return false; } + + if (shader.normal3_loc !== undefined && shader.normal3_loc !== -1) + { + shader.enableVertexAttribArray(shader.normal3_loc); + if (vboBufferNor.key !== shader.last_vboNor_binded) + { + gl.bindBuffer(vboBufferNor.dataTarget, vboBufferNor.key); + gl.vertexAttribPointer(shader.normal3_loc, 3, vboBufferNor.dataGlType, true, 0, 0); + shader.last_vboNor_binded = vboBufferNor.key; + } + return true; + } + else { shader.disableVertexAttribArray(shader.normal3_loc); } + return false; }; -ParseQueue.prototype.eraseOctreeLod0ModelsToParse = function(octree) +/** + * 어떤 일을 하고 있습니까? + */ +VBOVertexIdxCacheKey.prototype.bindDataTexCoord = function(shader, vboMemManager) { - delete this.octreesLod0ModelsToParseMap[octree.octreeKey]; + if (shader === undefined) + { return false; } + + var vboBufferTCoord = this.vboBufferTCoord; + if (vboBufferTCoord === undefined) + { + shader.disableVertexAttribArray(shader.texCoord2_loc); + return true; // Return "true" bcos there are no "tCoord" data, that is different that having "tCoord" data and not prepared yet. + } + + var gl = shader.gl; + if (!vboBufferTCoord.isReady(gl, vboMemManager)) + { return false; } + if (shader.texCoord2_loc !== undefined && shader.texCoord2_loc !== -1) + { + shader.enableVertexAttribArray(shader.texCoord2_loc); + if (vboBufferTCoord.key !== shader.last_vboTexCoord_binded) + { + gl.bindBuffer(vboBufferTCoord.dataTarget, vboBufferTCoord.key); + gl.vertexAttribPointer(shader.texCoord2_loc, 2, vboBufferTCoord.dataGlType, false, 0, 0); + shader.last_vboTexCoord_binded = vboBufferTCoord.key; + } + return true; + } + else { shader.disableVertexAttribArray(shader.texCoord2_loc); } }; -ParseQueue.prototype.putOctreeLod2LegosToParse = function(octree, aValue) +/** + * 어떤 일을 하고 있습니까? + */ +VBOVertexIdxCacheKey.prototype.bindDataColor = function(shader, vboMemManager) { - // provisionally "aValue" can be anything. - if (aValue === undefined) - { aValue = 0; } + if (shader === undefined) + { return false; } - this.octreesLod2LegosToParseMap[octree.octreeKey] = octree; -}; + var vboBufferCol = this.vboBufferCol; + if (vboBufferCol === undefined) + { + shader.disableVertexAttribArray(shader.color4_loc); + return true; // Return "true" bcos there are no "color" data, that is different that having "color" data and not prepared yet. + } + + var gl = shader.gl; + if (!vboBufferCol.isReady(gl, vboMemManager)) + { return false; } -ParseQueue.prototype.eraseOctreeLod2LegosToParse = function(octree) -{ - delete this.octreesLod2LegosToParseMap[octree.octreeKey]; + if (shader.color4_loc !== undefined && shader.color4_loc !== -1) + { + shader.enableVertexAttribArray(shader.color4_loc); + if (vboBufferCol.key !== shader.last_vboCol_binded) + { + gl.bindBuffer(vboBufferCol.dataTarget, vboBufferCol.key); + gl.vertexAttribPointer(shader.color4_loc, 4, vboBufferCol.dataGlType, true, 0, 0); + shader.last_vboCol_binded = vboBufferCol.key; + } + return true; + } + else { shader.disableVertexAttribArray(shader.color4_loc); } + return false; }; -ParseQueue.prototype.putOctreePCloudToParse = function(octree, aValue) +/** + * 어떤 일을 하고 있습니까? + */ +VBOVertexIdxCacheKey.prototype.bindDataIndice = function(shader, vboMemManager) { - // provisionally "aValue" can be anything. - if (aValue === undefined) - { aValue = 0; } + if (shader === undefined) + { return false; } - this.octreesPCloudToParseMap[octree.octreeKey] = octree; -}; - -ParseQueue.prototype.eraseOctreePCloudToParse = function(octree) -{ - if (octree === undefined) + var gl = shader.gl; + + var vboBufferIdx = this.vboBufferIdx; + if (!vboBufferIdx.isReady(gl, vboMemManager)) { return false; } - var key = octree.octreeKey; - if (this.octreesPCloudToParseMap.hasOwnProperty(key)) + if (vboBufferIdx.key !== shader.last_vboIdx_binded) { - delete this.octreesPCloudToParseMap[key]; - return true; + gl.bindBuffer(vboBufferIdx.dataTarget, vboBufferIdx.key); + shader.last_vboIdx_binded = vboBufferIdx.key; } - return false; + return true; }; -ParseQueue.prototype.putSkinLegosToParse = function(skinLego, aValue) +/** + * 어떤 일을 하고 있습니까? + */ +VBOVertexIdxCacheKey.prototype.setDataArrayPos = function(posDataArray, vboMemManager) { - // provisionally "aValue" can be anything. - if (aValue === undefined) - { aValue = 0; } + if (posDataArray === undefined) + { return; } - this.skinLegosToParseMap[skinLego.legoKey] = skinLego; + var gl = vboMemManager.gl; + if (this.vboBufferPos === undefined) + { this.vboBufferPos = new VboBuffer(gl.ARRAY_BUFFER); } + + this.vboBufferPos.setDataArray(posDataArray, vboMemManager); + this.vertexCount = this.vboBufferPos.dataLength/3; }; -ParseQueue.prototype.eraseSkinLegosToParse = function(skinLego) +/** + * 어떤 일을 하고 있습니까? + */ +VBOVertexIdxCacheKey.prototype.setDataArrayNor = function(norDataArray, vboMemManager) { - delete this.skinLegosToParseMap[skinLego.legoKey]; + var gl = vboMemManager.gl; + if (this.vboBufferNor === undefined) + { this.vboBufferNor = new VboBuffer(gl.ARRAY_BUFFER); } + + this.vboBufferNor.setDataArray(norDataArray, vboMemManager); }; -ParseQueue.prototype.clearAll = function() +/** + * 어떤 일을 하고 있습니까? + */ +VBOVertexIdxCacheKey.prototype.setDataArrayIdx = function(idxDataArray, vboMemManager) { - this.octreesLod0ReferencesToParseMap = {}; - this.octreesLod0ModelsToParseMap = {}; - this.octreesLod2LegosToParseMap = {}; + var gl = vboMemManager.gl; + if (this.vboBufferIdx === undefined) + { this.vboBufferIdx = new VboBuffer(gl.ELEMENT_ARRAY_BUFFER); } + this.vboBufferIdx.setDataArray(idxDataArray, vboMemManager); + this.indicesCount = this.vboBufferIdx.dataLength; }; -ParseQueue.prototype.eraseAny = function(octree) +/** + * 어떤 일을 하고 있습니까? + */ +VBOVertexIdxCacheKey.prototype.setDataArrayCol = function(colDataArray, vboMemManager) { - this.eraseOctreeLod0ReferencesToParse(octree); - this.eraseOctreeLod0ModelsToParse(octree); - this.eraseOctreeLod2LegosToParse(octree); + + var gl = vboMemManager.gl; + if (this.vboBufferCol === undefined) + { this.vboBufferCol = new VboBuffer(gl.ARRAY_BUFFER); } + + this.vboBufferCol.setDataArray(colDataArray, vboMemManager); }; +/** + * 어떤 일을 하고 있습니까? + */ +VBOVertexIdxCacheKey.prototype.setDataArrayTexCoord = function(texCoordDataArray, vboMemManager) +{ + var gl = vboMemManager.gl; + + if (this.vboBufferTCoord === undefined) + { this.vboBufferTCoord = new VboBuffer(gl.ARRAY_BUFFER); } + + this.vboBufferTCoord.setDataArray(texCoordDataArray, vboMemManager); +}; - - - - - - - - - - - - - - - - +/** + * 어떤 일을 하고 있습니까? + * @returns vboViCacheKey + */ +VBOVertexIdxCacheKey.prototype.deleteGlObjects = function(gl, vboMemManager) +{ + if (this.vboBufferPos !== undefined) + { + this.vboBufferPos.deleteGlObjects(vboMemManager); + this.vboBufferPos = undefined; + } + if (this.vboBufferNor !== undefined) + { + this.vboBufferNor.deleteGlObjects(vboMemManager); + this.vboBufferNor = undefined; + } + if (this.vboBufferIdx !== undefined) + { + this.vboBufferIdx.deleteGlObjects(vboMemManager); + this.vboBufferIdx = undefined; + } + if (this.vboBufferCol !== undefined) + { + this.vboBufferCol.deleteGlObjects(vboMemManager); + this.vboBufferCol = undefined; + } + if (this.vboBufferTCoord !== undefined) + { + this.vboBufferTCoord.deleteGlObjects(vboMemManager); + this.vboBufferTCoord = undefined; + } +}; 'use strict'; + /** - * ProcessQueue - * - * @alias ProcessQueue - * @class ProcessQueue + * This class is the container which holds the VBO Cache Keys + * @class VBOVertexIdxCacheKeysContainer */ -var ProcessQueue = function() +var VBOVertexIdxCacheKeysContainer = function() { - if (!(this instanceof ProcessQueue)) + if (!(this instanceof VBOVertexIdxCacheKeysContainer)) { throw new Error(Messages.CONSTRUCT_ERROR); } - this.nodesToDeleteMap = {}; - this.nodesToDeleteModelReferencesMap = {}; - this.nodesToDeleteLessThanLod3Map = {}; - this.nodesToDeleteLessThanLod4Map = {}; - this.nodesToDeleteLessThanLod5Map = {}; - this.nodesToDeleteLodMeshMap = {}; // no used.*** - this.tinTerrainsToDeleteMap = {}; + this.vboCacheKeysArray = []; //the container of vbo keys }; -ProcessQueue.prototype.putNodeToDeleteLodMesh = function(node, aValue) +/** + * Create the default VBO instance + * @returns {VBOVertexIdxCacheKey} vboVertexIdxCacheKey + */ +VBOVertexIdxCacheKeysContainer.prototype.newVBOVertexIdxCacheKey = function() { - // provisionally "aValue" can be anything. - if (aValue === undefined) - { aValue = 0; } - - if (node.data === undefined || node.data.neoBuilding === undefined) - { return; } - - var key = node.data.neoBuilding.buildingId; - this.nodesToDeleteLodMeshMap[key] = node; + if (this.vboCacheKeysArray === undefined) + { this.vboCacheKeysArray = []; } - //this.nodesToDeleteLodMeshMap.set(node, aValue); + var vboVertexIdxCacheKey = new VBOVertexIdxCacheKey(); + this.vboCacheKeysArray.push(vboVertexIdxCacheKey); + return vboVertexIdxCacheKey; }; -ProcessQueue.prototype.eraseNodeToDeleteLodMesh = function(node) +/** + * Clear the data of this instance + * @param gl + * @param {VBOMemoryManager} vboMemManager + */ +VBOVertexIdxCacheKeysContainer.prototype.deleteGlObjects = function(gl, vboMemManager) { - // this erases the node from the "nodesToDeleteLessThanLod3Map". - if (node.data === undefined || node.data.neoBuilding === undefined) + if (this.vboCacheKeysArray === undefined) { return; } - var key = node.data.neoBuilding.buildingId; - if (this.nodesToDeleteLodMeshMap.hasOwnProperty(key)) + var vboDatasCount = this.vboCacheKeysArray.length; + for (var j = 0; j < vboDatasCount; j++) { - delete this.nodesToDeleteLodMeshMap[key]; - return true; + this.vboCacheKeysArray[j].deleteGlObjects(gl, vboMemManager); + this.vboCacheKeysArray[j] = undefined; } - return false; - //return this.nodesToDeleteLodMeshMap.delete(node); + this.vboCacheKeysArray.length = 0; + this.vboCacheKeysArray = undefined; }; -ProcessQueue.prototype.putTinTerrainToDelete = function(tinTerrain, aValue) +/** + * + * @returns {Number} the number of the key that this instance holds + */ +VBOVertexIdxCacheKeysContainer.prototype.getVbosCount = function() { - // provisionally "aValue" can be anything. - if (aValue === undefined) - { aValue = 0; } - - if (tinTerrain === undefined) - { return; } + if (this.vboCacheKeysArray === undefined) { return 0; } - var key = tinTerrain.pathName; - this.tinTerrainsToDeleteMap[key] = tinTerrain; + return this.vboCacheKeysArray.length; }; -ProcessQueue.prototype.eraseTinTerrainToDelete = function(tinTerrain) +/** + * Get the VBO key by the index + * @param {Number} idx + * @returns {VBOVertexIdxCacheKey} + */ +VBOVertexIdxCacheKeysContainer.prototype.getVboKey = function(idx) { - // this erases the tinTerrain from the "tinTerrainsToDeleteMap". - if (tinTerrain === undefined) - { return; } + if (this.vboCacheKeysArray === undefined) + { return undefined; } - var key = tinTerrain.pathName; - if (this.tinTerrainsToDeleteMap.hasOwnProperty(key)) - { - delete this.tinTerrainsToDeleteMap[key]; - return true; - } - return false; + var vbo = this.vboCacheKeysArray[idx]; + return vbo; }; -ProcessQueue.prototype.putNodeToDeleteLessThanLod3 = function(node, aValue) -{ - // provisionally "aValue" can be anything. - if (aValue === undefined) - { aValue = 0; } - - if (node.data === undefined || node.data.neoBuilding === undefined) - { return; } - - var key = node.data.neoBuilding.buildingId; - this.nodesToDeleteLessThanLod3Map[key] = node; -}; +'use strict'; -ProcessQueue.prototype.eraseNodeToDeleteLessThanLod3 = function(node) +/** + * 어떤 일을 하고 있습니까? + * @class VisibleObjectsController + */ +var VisibleObjectsController = function() { - // this erases the node from the "nodesToDeleteLessThanLod3Map". - if (node.data === undefined || node.data.neoBuilding === undefined) - { return; } - - var key = node.data.neoBuilding.buildingId; - if (this.nodesToDeleteLessThanLod3Map.hasOwnProperty(key)) + if (!(this instanceof VisibleObjectsController)) { - delete this.nodesToDeleteLessThanLod3Map[key]; - return true; + throw new Error(Messages.CONSTRUCT_ERROR); } - return false; + // This object works with FrustumVolumeControl. + this.currentVisibles0 = []; //frustum 0 + this.currentVisibles1 = []; //frustum 1 + this.currentVisibles2 = []; //frustum 2 + this.currentVisibles3 = []; //frustum 3 + this.currentVisiblesAux = []; }; - -ProcessQueue.prototype.putNodeToDeleteLessThanLod4 = function(node, aValue) +VisibleObjectsController.prototype.initArrays = function() { - // provisionally "aValue" can be anything. - if (aValue === undefined) - { aValue = 0; } - - if (node.data === undefined || node.data.neoBuilding === undefined) - { return; } - - var key = node.data.neoBuilding.buildingId; - this.nodesToDeleteLessThanLod4Map[key] = node; + this.currentVisibles0 = []; + this.currentVisibles1 = []; + this.currentVisibles2 = []; + this.currentVisibles3 = []; + this.currentVisiblesAux = []; }; +/**Clear all of the volumn's data */ -ProcessQueue.prototype.eraseNodeToDeleteLessThanLod4 = function(node) +VisibleObjectsController.prototype.clear = function() { - // this erases the node from the "nodesToDeleteLessThanLod4Map". - if (node.data === undefined || node.data.neoBuilding === undefined) - { return; } - - var key = node.data.neoBuilding.buildingId; - if (this.nodesToDeleteLessThanLod4Map.hasOwnProperty(key)) - { - delete this.nodesToDeleteLessThanLod4Map[key]; - return true; - } - return false; + this.currentVisibles0.length = 0; + this.currentVisibles1.length = 0; + this.currentVisibles2.length = 0; + this.currentVisibles3.length = 0; + this.currentVisiblesAux.length = 0; }; -ProcessQueue.prototype.putNodeToDeleteLessThanLod5 = function(node, aValue) +/** + * Make all volumns visible + */ +VisibleObjectsController.prototype.getAllVisibles = function() { - // provisionally "aValue" can be anything. - if (aValue === undefined) - { aValue = 0; } - - if (node.data === undefined || node.data.neoBuilding === undefined) - { return; } - - var key = node.data.neoBuilding.buildingId; - this.nodesToDeleteLessThanLod5Map[key] = node; + var resultVisiblesArray = [].concat(this.currentVisibles0, this.currentVisibles1, this.currentVisibles2, this.currentVisibles3); + return resultVisiblesArray; }; -ProcessQueue.prototype.eraseNodeToDeleteLessThanLod5 = function(node) +/** + * Make two volumns : 0, 1 + */ +VisibleObjectsController.prototype.get01Visibles = function() { - // this erases the node from the "nodesToDeleteLessThanLod5Map". - if (node.data === undefined || node.data.neoBuilding === undefined) - { return; } - - var key = node.data.neoBuilding.buildingId; - if (this.nodesToDeleteLessThanLod5Map.hasOwnProperty(key)) - { - delete this.nodesToDeleteLessThanLod5Map[key]; - return true; - } - return false; + var resultVisiblesArray = [].concat(this.currentVisibles0, this.currentVisibles1); + return resultVisiblesArray; }; -ProcessQueue.prototype.putNodeToDeleteModelReferences = function(node, aValue) +/** + * + */ +VisibleObjectsController.prototype.getObjectIdxSortedByDist = function(objectsArray, startIdx, endIdx, object) { - // this puts the node to the "nodesToDeleteModelReferencesMap". - // provisionally "aValue" can be anything. - if (aValue === undefined) - { aValue = 0; } + // this do a dicotomic search of idx in a ordered table. + // 1rst, check the range. + var range = endIdx - startIdx; + if (range < 6) + { + // in this case do a lineal search. + var finished = false; + var i = startIdx; + var idx; - if (node.data === undefined || node.data.neoBuilding === undefined) - { return; } - - var key = node.data.neoBuilding.buildingId; - this.nodesToDeleteModelReferencesMap[key] = node; - //this.nodesToDeleteModelReferencesMap.set(node, aValue); + while (!finished && i<=endIdx) + { + var anObject = objectsArray[i]; + if (object.distToCamera < anObject.distToCamera) + { + idx = i; + finished = true; + } + i++; + } + + if (finished) + { return idx; } + else + { return endIdx+1; } + } + else + { + // in this case do the dicotomic search. + var middleIdx = startIdx + Math.floor(range/2); + var newStartIdx; + var newEndIdx; + var middleObject = objectsArray[middleIdx]; + if (middleObject.distToCamera > object.distToCamera) + { + newStartIdx = startIdx; + newEndIdx = middleIdx; + } + else + { + newStartIdx = middleIdx; + newEndIdx = endIdx; + } + return this.getObjectIdxSortedByDist(objectsArray, newStartIdx, newEndIdx, object); + } }; -ProcessQueue.prototype.eraseNodeToDeleteModelReferences = function(node) +/** + * Put the object by distance from camera + * @param {VisibleObjectsController}objectsArray + * @param {Octree}object + */ +VisibleObjectsController.prototype.putObjectToArraySortedByDist = function(objectsArray, object) { - // this erases the node from the "nodesToDeleteModelReferencesMap". - if (node.data === undefined || node.data.neoBuilding === undefined) - { return; } - - var key = node.data.neoBuilding.buildingId; - if (this.nodesToDeleteModelReferencesMap.hasOwnProperty(key)) + if (objectsArray.length > 0) { - delete this.nodesToDeleteModelReferencesMap[key]; - return true; + var startIdx = 0; + var endIdx = objectsArray.length - 1; + var idx = this.getObjectIdxSortedByDist(objectsArray, startIdx, endIdx, object); + + + objectsArray.splice(idx, 0, object); + } + else + { + objectsArray.push(object); } - return false; - //return this.nodesToDeleteModelReferencesMap.delete(node); }; -ProcessQueue.prototype.putNodeToDelete = function(node, aValue) +/** + * Get the index of the node which is in nodesArray + * @param nodesArray + * @param {Number} startIdx + * @param {Number} endIdx + * @param node + */ +VisibleObjectsController.prototype.getNodeIdxSortedByDist = function(nodesArray, startIdx, endIdx, node) { - // this puts the node to the "nodesToDeleteMap". - // provisionally "aValue" can be anything. - if (aValue === undefined) - { aValue = 0; } - - if (node.data === undefined || node.data.neoBuilding === undefined) - { return; } - - var key = node.data.neoBuilding.buildingId; - this.nodesToDeleteMap[key] = node; -}; + // Note: Function exclusive to use with Node class objects. + // this do a dicotomic search of idx in a ordered table. + // 1rst, check the range. + var neoBuilding = node.data.neoBuilding; + var range = endIdx - startIdx; + if (range < 6) + { + // in this case do a lineal search. + var finished = false; + var i = startIdx; + var idx; -ProcessQueue.prototype.putNodesArrayToDelete = function(nodesToDeleteArray, aValue) -{ - if (nodesToDeleteArray === undefined) - { return; } - - // this puts the nodesToDeleteArray to the "nodesToDeleteArray". - // provisionally "aValue" can be anything. - if (aValue === undefined) - { aValue = 0; } - - var nodesToDeleteCount = nodesToDeleteArray.length; - for (var i=0; i node.data.distToCam) + { + newStartIdx = startIdx; + newEndIdx = middleIdx; + } + else + { + newStartIdx = middleIdx; + newEndIdx = endIdx; + } + return this.getNodeIdxSortedByDist(nodesArray, newStartIdx, newEndIdx, node); } }; -ProcessQueue.prototype.eraseNodeToDelete = function(node) +/** + * Put the node to given node array + * @param nodesArray + * @param node + */ +VisibleObjectsController.prototype.putNodeToArraySortedByDist = function(nodesArray, node) { - // this erases the node from the "nodesToDeleteMap". - var key = node.data.neoBuilding.buildingId; - if (this.nodesToDeleteMap.hasOwnProperty(key)) + // Note: Function exclusive to use with Node class objects. + if (nodesArray.length > 0) { - delete this.nodesToDeleteMap[key]; - return true; + var startIdx = 0; + var endIdx = nodesArray.length - 1; + var idx = this.getNodeIdxSortedByDist(nodesArray, startIdx, endIdx, node); + + nodesArray.splice(idx, 0, node); } - return false; -}; - -ProcessQueue.prototype.eraseNodesArrayToDelete = function(nodesToEraseArray) -{ - // this erases the node from the "nodesToDeleteMap". - var key; - var nodesCount = nodesToEraseArray.length; - for (var i=0; i= 0 && idx < this.blocksArray.length) + { + return this.blocksArray[idx]; + } + return null; }; /** - * 버퍼에서 데이터를 읽어서 32비트 부호없는 정수값에 대한 배열의 0번째 값을 돌려줌 - * @param buffer 복사할 버퍼 - * @param start 시작 바이트 인덱스 - * @param end 끝 바이트 인덱스 - * @returns float16[0] + * 블록 리스트 초기화. gl에서 해당 블록 리스트의 블록 및 lego 삭제 + * + * @param {WebGLRenderingContext} gl + * @param {VboManager} vboMemManager */ -ReaderWriter.prototype.readFloat16 = function(buffer, start, end) +BlocksList.prototype.deleteGlObjects = function(gl, vboMemManager) { - var float16 = new Float32Array(buffer.slice(start, end)); - return float16[0]; + if (this.xhr !== undefined) + { + this.xhr.abort(); + this.xhr = undefined; + } + + if (this.blocksArray === undefined) { return; } + + for (var i = 0, blocksCount = this.blocksArray.length; i < blocksCount; i++ ) + { + var block = this.blocksArray[i]; + block.vBOVertexIdxCacheKeysContainer.deleteGlObjects(gl, vboMemManager); + block.vBOVertexIdxCacheKeysContainer = undefined; // Change this for "vbo_VertexIdx_CacheKeys_Container__idx". + block.mIFCEntityType = undefined; + block.isSmallObj = undefined; + block.radius = undefined; + block.vertexCount = undefined; // only for test. delete this. + if (block.lego) + { + block.lego.vbo_vicks_container.deleteGlObjects(gl, vboMemManager); + block.lego.vbo_vicks_container = undefined; + } + block.lego = undefined; // legoBlock. + this.blocksArray[i] = undefined; + } + this.blocksArray = undefined; + this.name = undefined; + this.fileLoadState = undefined; + this.dataArraybuffer = undefined; // file loaded data, that is no parsed yet. }; /** - * 버퍼에서 데이터를 읽어서 8비트 정수값에 대한 배열의 0번째 값을 돌려줌 - * @param buffer 복사할 버퍼 - * @param start 시작 바이트 인덱스 - * @param end 끝 바이트 인덱스 - * @returns int8[0] + * 사용하지 않는 부분들 계산하기 위한 파싱과정. stepOver + * 파싱을 위한 파싱.. + * 블록리스트 버퍼를 파싱(비대칭적)하는 과정. + * F4D 버전이 0.0.1일 경우 사용 + * This function parses the geometry data from binary arrayBuffer. + * + * @param {ArrayBuffer} arrayBuffer Binary data to parse. + * @param {Number} bytesReaded readed bytes. + * @param {ReaderWriter} readWriter Helper to read inside of the arrayBuffer. */ -ReaderWriter.prototype.readInt8 = function(buffer, start, end) +BlocksList.prototype.stepOverBlockVersioned = function(arrayBuffer, bytesReaded, readWriter) { - var int8 = new Int8Array(buffer.slice(start, end)); - return int8[0]; -}; - -/** - * 버퍼에서 데이터를 읽어서 8비트 부호없는 정수값에 대한 배열의 0번째 값을 돌려줌 - * @param buffer 복사할 버퍼 - * @param start 시작 바이트 인덱스 - * @param end 끝 바이트 인덱스 - * @returns uint8[0] - */ -ReaderWriter.prototype.readUInt8 = function(buffer, start, end) -{ - var uint8 = new Uint8Array(buffer.slice(start, end)); - return uint8[0]; -}; - -/** - * 어떤 일을 하고 있습니까? - * @param buffer 변수 - * @param start 변수 - * @param end 변수 - * @returns int8_value - */ -ReaderWriter.prototype.readInt8ByteColor = function(buffer, start, end) -{ - var int8 = new Int8Array(buffer.slice(start, end)); - var int8_value = int8[0]; - - if (int8_value > max_color_value) { int8_value = max_color_value; } - - if (int8_value < 0) { int8_value += 256; } - - return int8_value; -}; - -function loadWithXhr(fileName) -{ - // 1) 사용될 jQuery Deferred 객체를 생성한다. - var deferred = $.Deferred(); - - var xhr = new XMLHttpRequest(); - xhr.open("GET", fileName, true); - xhr.responseType = "arraybuffer";; - - // 이벤트 핸들러를 등록한다. - xhr.onload = function() - { - if (xhr.status < 200 || xhr.status >= 300) - { - deferred.reject(xhr.status); - return; - } - else - { - // 3.1) DEFERRED를 해결한다. (모든 done()...을 동작시킬 것이다.) - deferred.resolve(xhr.response); - } - }; + var vertexCount; + var verticesFloatValuesCount; + var normalByteValuesCount; + var shortIndicesValuesCount; + var sizeLevels; - xhr.onerror = function(e) + // Spec document Table 3-1 + // vboCount + var vboDatasCount = readWriter.readInt32(arrayBuffer, bytesReaded, bytesReaded+4); + bytesReaded += 4; + for ( var j = 0; j < vboDatasCount; j++ ) { - console.log("Invalid XMLHttpRequest response type."); - deferred.reject(xhr.status); - }; + // 1) Positions array. + // Spec document Table 3-2 + // vertexCount + vertexCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4);bytesReaded += 4; + verticesFloatValuesCount = vertexCount * 3; + startBuff = bytesReaded; + endBuff = bytesReaded + 4 * verticesFloatValuesCount; + bytesReaded = bytesReaded + 4 * verticesFloatValuesCount; // updating data. - // 작업을 수행한다. - xhr.send(null); + // 2) Normals. + // Spec document Table 3-2 + // normalCount + vertexCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4);bytesReaded += 4; + normalByteValuesCount = vertexCount * 3; + bytesReaded = bytesReaded + 1 * normalByteValuesCount; // updating data. + + // 3) Indices. + // Spec document Table 3-2 + // indexCount + shortIndicesValuesCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4);bytesReaded += 4; + sizeLevels = readWriter.readUInt8(arrayBuffer, bytesReaded, bytesReaded+1);bytesReaded += 1; + bytesReaded = bytesReaded + sizeLevels * 4; + bytesReaded = bytesReaded + sizeLevels * 4; + bytesReaded = bytesReaded + 2 * shortIndicesValuesCount; // updating data. + } - // 참고: jQuery.ajax를 사용할 수 있었고 해야할 수 있었다. - // 참고: jQuery.ajax는 Promise를 반환하지만 다른 Deferred/Promise를 사용하여 애플리케이션에 의미있는 구문으로 감싸는 것은 언제나 좋은 생각이다. - // ---- /AJAX 호출 ---- // - - // 2) 이 deferred의 promise를 반환한다. - return deferred.promise(); + return bytesReaded; }; -ReaderWriter.prototype.getNeoBlocksArraybuffer = function(fileName, lowestOctree, magoManager) +/** + * 블록리스트 버퍼를 파싱(비대칭적) + * vboData 파싱 부분 + * Spec document Table 3-1 + * This function parses the geometry data from binary arrayBuffer. + * + * @param {ArrayBuffer} arrayBuffer Binary data to parse. + * @param {Number} bytesReaded 지금까지 읽은 바이트 길이 + * @param {Block} block 정보를 담을 block. + * @param {ReaderWriter} readWriter + * @param {MagoManager} magoManager + * + * @see VBOVertexIdxCacheKey#readPosNorIdx + */ +BlocksList.prototype.parseBlockVersioned = function(arrayBuffer, bytesReaded, block, readWriter, magoManager) { - magoManager.fileRequestControler.modelRefFilesRequestedCount += 1; - var blocksList = lowestOctree.neoReferencesMotherAndIndices.blocksList; - blocksList.fileLoadState = CODE.fileLoadState.LOADING_STARTED; - - loadWithXhr(fileName).done(function(response) - { - var arrayBuffer = response; - if (arrayBuffer) - { - blocksList.dataArraybuffer = arrayBuffer; - blocksList.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; - arrayBuffer = null; - - - magoManager.parseQueue.putOctreeLod0ModelsToParse(lowestOctree); - } - else - { - blocksList.fileLoadState = 500; - } - }).fail(function(status) - { - console.log("Invalid XMLHttpRequest status = " + status); - if (status === 0) { blocksList.fileLoadState = 500; } - else { blocksList.fileLoadState = status; } - }).always(function() + var vboMemManager = magoManager.vboMemoryManager; + var vboDatasCount = readWriter.readInt32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; + for ( var j = 0; j < vboDatasCount; j++ ) { - magoManager.fileRequestControler.modelRefFilesRequestedCount -= 1; - if (magoManager.fileRequestControler.modelRefFilesRequestedCount < 0) { magoManager.fileRequestControler.modelRefFilesRequestedCount = 0; } - }); + var vboViCacheKey = block.vBOVertexIdxCacheKeysContainer.newVBOVertexIdxCacheKey(); + bytesReaded = vboViCacheKey.readPosNorIdx(arrayBuffer, readWriter, vboMemManager, bytesReaded); + block.vertexCount = vboViCacheKey.vertexCount; + } + + return bytesReaded; }; /** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param fileName 파일명 - * @param magoManager 변수 + * 블록리스트 버퍼를 파싱(비대칭적) + * F4D 버전이 0.0.1일 경우 사용 + * This function parses the geometry data from binary arrayBuffer. + * + * @param {ArrayBuffer} arrayBuffer Binary data to parse. + * @param {ReaderWriter} readWriter Helper to read inside of the arrayBuffer. + * @param {Array.} motherBlocksArray Global blocks array. + * @param {MagoManager} magoManager */ -ReaderWriter.prototype.getNeoReferencesArraybuffer = function(fileName, lowestOctree, magoManager) +BlocksList.prototype.parseBlocksListVersioned_v001 = function(arrayBuffer, readWriter, motherBlocksArray, magoManager) { - magoManager.fileRequestControler.modelRefFilesRequestedCount += 1; - lowestOctree.neoReferencesMotherAndIndices.fileLoadState = CODE.fileLoadState.LOADING_STARTED; + this.fileLoadState = CODE.fileLoadState.PARSE_STARTED; + var bytesReaded = 0; + var succesfullyGpuDataBinded = true; - loadWithXhr(fileName).done(function(response) + // read the version. + var versionLength = 5; + bytesReaded += versionLength; + + + // modelCount + var blocksCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded + 4); bytesReaded += 4; + for ( var i = 0; i< blocksCount; i++ ) { - var arrayBuffer = response; - if (arrayBuffer) + // modelIndex + var blockIdx = readWriter.readInt32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; + + // Check if block exist. + if (motherBlocksArray[blockIdx]) { - var neoRefsList = lowestOctree.neoReferencesMotherAndIndices; - if (neoRefsList) + // The block exists, then read data but no create a new block. + bytesReaded += 4 * 6; // boundingBox. + // step over vbo datas of the model. + bytesReaded = this.stepOverBlockVersioned(arrayBuffer, bytesReaded, readWriter) ; + + // read lego if exist. (note: lego is exactly same of a model, is a mesh). + var existLego = readWriter.readUInt8(arrayBuffer, bytesReaded, bytesReaded+1); bytesReaded += 1; + if (existLego) { - neoRefsList.dataArraybuffer = arrayBuffer; - neoRefsList.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; - magoManager.parseQueue.putOctreeLod0ReferencesToParse(lowestOctree); + bytesReaded = this.stepOverBlockVersioned(arrayBuffer, bytesReaded, readWriter) ; } - arrayBuffer = null; + continue; } - else + + // The block doesn't exist, so creates a new block and read data. + var block = new Block(); + block.idx = blockIdx; + motherBlocksArray[blockIdx] = block; + + // 1rst, read bbox. + var bbox = new BoundingBox(); + bbox.minX = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); bytesReaded += 4; + bbox.minY = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); bytesReaded += 4; + bbox.minZ = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); bytesReaded += 4; + + bbox.maxX = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); bytesReaded += 4; + bbox.maxY = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); bytesReaded += 4; + bbox.maxZ = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); bytesReaded += 4; + + var maxLength = bbox.getMaxLength(); + if (maxLength < 0.5) { block.isSmallObj = true; } + else { block.isSmallObj = false; } + + block.radius = maxLength/2.0; + + bytesReaded = this.parseBlockVersioned(arrayBuffer, bytesReaded, block, readWriter, magoManager) ; + + // parse lego if exist. + var existLego = readWriter.readUInt8(arrayBuffer, bytesReaded, bytesReaded+1); bytesReaded += 1; + if (existLego) { - lowestOctree.neoReferencesMotherAndIndices.fileLoadState = 500; + if (block.lego === undefined) + { + // TODO : this is no used. delete this. + block.lego = new Lego(); + } + bytesReaded = this.parseBlockVersioned(arrayBuffer, bytesReaded, block.lego, readWriter, magoManager) ; } - }).fail(function(status) - { - console.log("xhr status = " + status); - if (status === 0) { lowestOctree.neoReferencesMotherAndIndices.fileLoadState = 500; } - else { lowestOctree.neoReferencesMotherAndIndices.fileLoadState = status; } - }).always(function() - { - magoManager.fileRequestControler.modelRefFilesRequestedCount -= 1; - if (magoManager.fileRequestControler.modelRefFilesRequestedCount < 0) { magoManager.fileRequestControler.modelRefFilesRequestedCount = 0; } - }); + } + this.fileLoadState = CODE.fileLoadState.PARSE_FINISHED; + return succesfullyGpuDataBinded; }; /** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param fileName 파일명 - * @param magoManager 변수 + * 블록리스트 버퍼를 파싱(비대칭적) + * F4D 버전이 0.0.2일 경우 사용 + * 매개변수로 arrayBuffer 전달받지 않고 blocksArrayPartition에 있는 arrayBuffer를 이용. + * + * @param {ReaderWriter} readWriter Helper to read inside of the arrayBuffer. + * @param {Array.} motherBlocksArray Global blocks array. + * @param {MagoManager} magoManager */ -ReaderWriter.prototype.getOctreeLegoArraybuffer = function(fileName, lowestOctree, magoManager) +BlocksList.prototype.parseBlocksListVersioned_v002 = function(readWriter, motherBlocksArray, magoManager) { - if (lowestOctree.lego === undefined) + // 1rst, find the blocksArrayPartition to parse. + var blocksArrayPartitionsCount = this.blocksArrayPartitionsArray.length; + var blocksArrayPartition = this.blocksArrayPartitionsArray[blocksArrayPartitionsCount-1]; + if (blocksArrayPartition.fileLoadState !== CODE.fileLoadState.LOADING_FINISHED) { return; } - magoManager.fileRequestControler.filesRequestedCount += 1; - lowestOctree.lego.fileLoadState = CODE.fileLoadState.LOADING_STARTED; + var arrayBuffer = blocksArrayPartition.dataArraybuffer; + blocksArrayPartition.fileLoadState = CODE.fileLoadState.PARSE_STARTED; + var bytesReaded = 0; + var vboMemManager = magoManager.vboMemoryManager; + var succesfullyGpuDataBinded = true; - loadWithXhr(fileName).done(function(response) + var blocksCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded + 4); bytesReaded += 4; + for ( var i = 0; i< blocksCount; i++ ) { - var arrayBuffer = response; - if (arrayBuffer) + var blockIdx = readWriter.readInt32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; + var block; + + // Check if block exist. + if (motherBlocksArray[blockIdx]) { - if (lowestOctree.lego) - { - lowestOctree.lego.dataArrayBuffer = arrayBuffer; - lowestOctree.lego.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; - magoManager.parseQueue.putOctreeLod2LegosToParse(lowestOctree); - } - else - { - lowestOctree = undefined; - } - arrayBuffer = null; + block = motherBlocksArray[blockIdx]; } else { - lowestOctree.lego.fileLoadState = 500; + // The block doesn't exist, so creates a new block and read data. + block = new Block(); + block.idx = blockIdx; + motherBlocksArray[blockIdx] = block; } - }).fail(function(status) - { - console.log("xhr status = " + status); - if (status === 0) { lowestOctree.lego.fileLoadState = 500; } - else { lowestOctree.lego.fileLoadState = status; } - }).always(function() - { - magoManager.fileRequestControler.filesRequestedCount -= 1; - if (magoManager.fileRequestControler.filesRequestedCount < 0) { magoManager.fileRequestControler.filesRequestedCount = 0; } - }); -}; + + // Now, read the blocks vbo's idx. + var vboIdx = readWriter.readInt32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; + + if (vboIdx === 0) + { + // Only if the vboIdx = 0 -> read the bbox. + var bbox = new BoundingBox(); + bbox.minX = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); bytesReaded += 4; + bbox.minY = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); bytesReaded += 4; + bbox.minZ = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); bytesReaded += 4; -/** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param fileName 파일명 - * @param magoManager 변수 - */ -ReaderWriter.prototype.getOctreePCloudArraybuffer = function(fileName, lowestOctree, magoManager) -{ - if (lowestOctree.lego === undefined) - { return; } - - magoManager.fileRequestControler.filesRequestedCount += 1; - lowestOctree.lego.fileLoadState = CODE.fileLoadState.LOADING_STARTED; - - loadWithXhr(fileName).done(function(response) - { - var arrayBuffer = response; - if (arrayBuffer) + bbox.maxX = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); bytesReaded += 4; + bbox.maxY = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); bytesReaded += 4; + bbox.maxZ = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); bytesReaded += 4; + + var maxLength = bbox.getMaxLength(); + if (maxLength < 0.5) { block.isSmallObj = true; } + else { block.isSmallObj = false; } + + block.radius = maxLength/2.0; + } + + // check if the vbo exists. + var vboViCacheKey = block.vBOVertexIdxCacheKeysContainer.vboCacheKeysArray[vboIdx]; + if (vboViCacheKey === undefined) { - if (lowestOctree.lego) - { - lowestOctree.lego.dataArrayBuffer = arrayBuffer; - lowestOctree.lego.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; - magoManager.parseQueue.putOctreePCloudToParse(lowestOctree); - } - else - { - lowestOctree = undefined; - } - arrayBuffer = null; + // Now, read the vbo (Pos-Nor-Idx). + vboViCacheKey = new VBOVertexIdxCacheKey(); + block.vBOVertexIdxCacheKeysContainer.vboCacheKeysArray[vboIdx] = vboViCacheKey; + bytesReaded = vboViCacheKey.readPosNorIdx(arrayBuffer, readWriter, vboMemManager, bytesReaded); + block.vertexCount = vboViCacheKey.vertexCount; } else { - lowestOctree.lego.fileLoadState = 500; + // step over. + if (blocksCount > 1) + { bytesReaded = vboViCacheKey.stepOverPosNorIdx(arrayBuffer, readWriter, vboMemManager, bytesReaded); } } - }).fail(function(status) - { - console.log("xhr status = " + status); - if (status === 0) { lowestOctree.lego.fileLoadState = 500; } - else { lowestOctree.lego.fileLoadState = status; } - }).always(function() - { - magoManager.fileRequestControler.filesRequestedCount -= 1; - if (magoManager.fileRequestControler.filesRequestedCount < 0) { magoManager.fileRequestControler.filesRequestedCount = 0; } - }); + } + blocksArrayPartition.fileLoadState = CODE.fileLoadState.PARSE_FINISHED; + this.fileLoadState = CODE.fileLoadState.PARSE_FINISHED; // test. + return succesfullyGpuDataBinded; }; /** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param fileName 파일명 - * @param magoManager 변수 + * 블록리스트 버퍼를 파싱(비대칭적) + * This function parses the geometry data from binary arrayBuffer. + * @deprecated f4d 0.0.1 이전 버전에서 사용 + * + * @param {ArrayBuffer} arrayBuffer Binary data to parse. + * @param {ReaderWriter} readWriter Helper to read inside of the arrayBuffer. + * @param {Array.} motherBlocksArray Global blocks array. */ -ReaderWriter.prototype.getLegoArraybuffer = function(fileName, legoMesh, magoManager) +BlocksList.prototype.parseBlocksList = function(arrayBuffer, readWriter, motherBlocksArray, magoManager) { - //magoManager.fileRequestControler.filesRequestedCount += 1; - magoManager.fileRequestControler.lowLodDataRequestedCount += 1; - legoMesh.fileLoadState = CODE.fileLoadState.LOADING_STARTED; + this.fileLoadState = CODE.fileLoadState.PARSE_STARTED; + var bytesReaded = 0; + var blocksCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded + 4); bytesReaded += 4; - loadWithXhr(fileName).done(function(response) + var vboMemManager = magoManager.vboMemoryManager; + var succesfullyGpuDataBinded = true; + + for ( var i = 0; i< blocksCount; i++ ) { - var arrayBuffer = response; - if (arrayBuffer) + var blockIdx = readWriter.readInt32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; + + // Check if block exist. + if (motherBlocksArray[blockIdx]) { - if (legoMesh) + // The block exists, then read data but no create a new block. + bytesReaded += 4 * 6; // boundingBox. + // Read vbo datas (indices cannot superate 65535 value). + var vboDatasCount = readWriter.readInt32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; + + for ( var j = 0; j < vboDatasCount; j++ ) { - legoMesh.dataArrayBuffer = arrayBuffer; - legoMesh.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; - magoManager.parseQueue.putSkinLegosToParse(legoMesh); + // 1) Positions array. + var vertexCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; + var verticesFloatValuesCount = vertexCount * 3; + startBuff = bytesReaded; + endBuff = bytesReaded + 4 * verticesFloatValuesCount; + bytesReaded = bytesReaded + 4 * verticesFloatValuesCount; // updating data. + + // 2) Normals. + vertexCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; + var normalByteValuesCount = vertexCount * 3; + bytesReaded = bytesReaded + 1 * normalByteValuesCount; // updating data. + + // 3) Indices. + var shortIndicesValuesCount = readWriter.readUInt32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; + var sizeLevels = readWriter.readUInt8(arrayBuffer, bytesReaded, bytesReaded+1); bytesReaded += 1; + + bytesReaded = bytesReaded + sizeLevels * 4; + bytesReaded = bytesReaded + sizeLevels * 4; + bytesReaded = bytesReaded + 2 * shortIndicesValuesCount; // updating data. } - arrayBuffer = null; + // Pendent to load the block's lego. + continue; } - else + + // The block doesn't exist, so creates a new block and read data. + var block = new Block(); + block.idx = blockIdx; + motherBlocksArray[blockIdx] = block; + + // 1rst, read bbox. + var bbox = new BoundingBox(); + bbox.minX = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); + bytesReaded += 4; + bbox.minY = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); + bytesReaded += 4; + bbox.minZ = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); + bytesReaded += 4; + + bbox.maxX = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); + bytesReaded += 4; + bbox.maxY = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); + bytesReaded += 4; + bbox.maxZ = new Float32Array(arrayBuffer.slice(bytesReaded, bytesReaded+4)); + bytesReaded += 4; + + var maxLength = bbox.getMaxLength(); + if (maxLength < 0.5) { block.isSmallObj = true; } + else { block.isSmallObj = false; } + + block.radius = maxLength/2.0; + + bbox.deleteObjects(); + bbox = undefined; + + // New for read multiple vbo datas (indices cannot superate 65535 value). + var vboDatasCount = readWriter.readInt32(arrayBuffer, bytesReaded, bytesReaded+4); + bytesReaded += 4; + for ( var j = 0; j < vboDatasCount; j++ ) { - legoMesh.fileLoadState = 500; - } - }).fail(function(status) - { - console.log("xhr status = " + status); - if (status === 0) { legoMesh.fileLoadState = 500; } - //else { legoMesh.fileLoadState = status; } - else - { - legoMesh.fileLoadState = -1; + var vboViCacheKey = block.vBOVertexIdxCacheKeysContainer.newVBOVertexIdxCacheKey(); + bytesReaded = vboViCacheKey.readPosNorIdx(arrayBuffer, readWriter, vboMemManager, bytesReaded); + block.vertexCount = vboViCacheKey.vertexCount; } - }).always(function() - { - //magoManager.fileRequestControler.filesRequestedCount -= 1; - magoManager.fileRequestControler.lowLodDataRequestedCount -= 1; - //if (magoManager.fileRequestControler.filesRequestedCount < 0) { magoManager.fileRequestControler.filesRequestedCount = 0; } - if (magoManager.fileRequestControler.lowLodDataRequestedCount < 0) { magoManager.fileRequestControler.lowLodDataRequestedCount = 0; } - }); + // Pendent to load the block's lego. + } + this.fileLoadState = CODE.fileLoadState.PARSE_FINISHED; + return succesfullyGpuDataBinded; }; /** - * object index 파일을 읽어서 빌딩 개수, 포지션, 크기 정보를 배열에 저장 - * @param gl gl context - * @param fileName 파일명 - * @param readerWriter 파일 처리를 담당 - * @param neoBuildingsList object index 파일을 파싱한 정보를 저장할 배열 + * 블록리스트의 blocksArrayPartition정보를 할당 및 체크. + * F4D 버전이 0.0.2일 경우 사용 + * + * @param {MagoManager} magoManager + * @param {MagoManager} octreeOwner */ -ReaderWriter.prototype.getObjectIndexFileForSmartTile = function(fileName, magoManager, buildingSeedList, projectId) +BlocksList.prototype.prepareData = function(magoManager, octreeOwner) { - loadWithXhr(fileName).done(function(response) + if (this.version === "0.0.1") { - var arrayBuffer = response; - if (arrayBuffer) + // Provisionally this function is into octree.prepareModelReferencesListData(...). + } + else if (this.version === "0.0.2") + { + // Check the current loading state. + if (this.blocksArrayPartitionsArray === undefined) + { this.blocksArrayPartitionsArray = []; } + + var currPartitionsCount = this.blocksArrayPartitionsArray.length; + if (currPartitionsCount === 0) { - buildingSeedList.dataArrayBuffer = arrayBuffer; - buildingSeedList.parseBuildingSeedArrayBuffer(); - - magoManager.makeSmartTile(buildingSeedList, projectId); - arrayBuffer = null; - //MagoConfig.setObjectIndex("append", ); + // Proceed to load the 1rst partition. + var partitionIdx = 0; + var filePathInServer = this.blocksArrayPartitionsMasterPathName + partitionIdx.toString(); + var blocksArrayPartition = new BlocksArrayPartition(); + this.blocksArrayPartitionsArray.push(blocksArrayPartition); + magoManager.readerWriter.getNeoBlocksArraybuffer_partition(filePathInServer, octreeOwner, blocksArrayPartition, magoManager); } - else + else { - // blocksList.fileLoadState = 500; + // Check the last partition. + var lastBlocksArrayPartition = this.blocksArrayPartitionsArray[currPartitionsCount-1]; + if (lastBlocksArrayPartition.fileLoadState === CODE.fileLoadState.PARSE_FINISHED) + { + if (currPartitionsCount < this.blocksArrayPartitionsCount) + { + // Proceed to load another partition. + var partitionIdx = currPartitionsCount; + var filePathInServer = this.blocksArrayPartitionsMasterPathName + partitionIdx.toString(); + var blocksArrayPartition = new BlocksArrayPartition(); + this.blocksArrayPartitionsArray.push(blocksArrayPartition); + magoManager.readerWriter.getNeoBlocksArraybuffer_partition(filePathInServer, octreeOwner, blocksArrayPartition, magoManager); + } + } } - }).fail(function(status) - { - console.log("xhr status = " + status); - // if(status === 0) blocksList.fileLoadState = 500; - // else blocksList.fileLoadState = status; - }).always(function() - { - // magoManager.fileRequestControler.filesRequestedCount -= 1; - // if(magoManager.fileRequestControler.filesRequestedCount < 0) magoManager.fileRequestControler.filesRequestedCount = 0; - }); + + } }; - +'use strict'; /** - * object index 파일을 읽어서 빌딩 개수, 포지션, 크기 정보를 배열에 저장 - * @param gl gl context - * @param fileName 파일명 - * @param readerWriter 파일 처리를 담당 - * @param neoBuildingsList object index 파일을 파싱한 정보를 저장할 배열 + * 프로젝트와 노드 목록 관리 객체. + * 실질적으로 화면에 표출될 프로젝트와 노드들을 보관하고 있음. + * @exception {Error} Messages.CONSTRUCT_ERROR + * + * @class HierarchyManager */ -ReaderWriter.prototype.getObjectIndexFile = function(fileName, readerWriter, neoBuildingsList, magoManager) +var HierarchyManager = function() { - loadWithXhr(fileName).done(function(response) - { - var arrayBuffer = response; - if (arrayBuffer) - { - readerWriter.parseObjectIndexFile(arrayBuffer, neoBuildingsList); - arrayBuffer = null; - magoManager.createDeploymentGeoLocationsForHeavyIndustries(); - } - else - { - // blocksList.fileLoadState = 500; - } - }).fail(function(status) - { - console.log("xhr status = " + status); - // if(status === 0) blocksList.fileLoadState = 500; - // else blocksList.fileLoadState = status; - }).always(function() + if (!(this instanceof HierarchyManager)) { - // magoManager.fileRequestControler.filesRequestedCount -= 1; - // if(magoManager.fileRequestControler.filesRequestedCount < 0) magoManager.fileRequestControler.filesRequestedCount = 0; - }); + throw new Error(Messages.CONSTRUCT_ERROR); + } + + /** + * lowest nodes array. initial array to create tiles global distribution. + * @type {Array.} + */ + this.nodesArray = []; + + /** + * 프로젝트 보관 객체 + * @type {Object} + */ + this.projectsMap = {}; + + /** + * StaticModelManager + * @type {StaticModelManager} + */ + this.staticModelsManager; }; /** - * object index 파일을 읽어서 빌딩 개수, 포지션, 크기 정보를 배열에 저장 - * @param arrayBuffer object index file binary data - * @param neoBuildingsList object index 파일을 파싱한 정보를 저장할 배열 + * node array와 prjectMap을 초기화. gl Context에서 그려진 내용들 제거 */ -ReaderWriter.prototype.parseObjectIndexFile = function(arrayBuffer, neoBuildingsList) +HierarchyManager.prototype.deleteNodes = function(gl, vboMemoryManager) { - var bytesReaded = 0; - var buildingNameLength; - var longitude; - var latitude; - var altitude; - - var buildingsCount = this.readInt32(arrayBuffer, bytesReaded, bytesReaded+4); - bytesReaded += 4; - for (var i =0; i> 4) - { - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: - // 0xxxxxxx - out += String.fromCharCode(c); - break; - case 12: case 13: - // 110x xxxx 10xx xxxx - char2 = array[i++]; - out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F)); - break; - case 14: - // 1110 xxxx 10xx xxxx 10xx xxxx - char2 = array[i++]; - char3 = array[i++]; - out += String.fromCharCode(((c & 0x0F) << 12) | - ((char2 & 0x3F) << 6) | - ((char3 & 0x3F) << 0)); + var value = nodesMap[key]; + if (value.data !== undefined && value.data[dataName] === dataNameValue) + { + resultNode = value; break; } } + } + + return resultNode; +}; - return out; - }; - - //BR_Project._f4d_header_readed = true; - magoManager.fileRequestControler.headerFilesRequestedCount += 1; - neoBuilding.metaData.fileLoadState = CODE.fileLoadState.LOADING_STARTED; +/** + * projectId와 dataKey를 이용하여 nodesMap에 있는 Node를 반환. + * @param {String} projectId + * @param {String} dataKey + * + * @returns {Node|undefined} nodesMap이 선언되지 않았을 경우 undefined반환. + */ +HierarchyManager.prototype.getNodeByDataKey = function(projectId, dataKey) +{ + var nodesMap = this.getNodesMap(projectId); + + if (nodesMap === undefined) + { return undefined; } + + var resultNode = nodesMap[dataKey]; + + return resultNode; +}; - loadWithXhr(fileName).done(function(response) +/** + * node의 parent 속성이 비어있는 root node들을 반환. + * @param {Array.} resultRootNodesArray + * @returns {Array.} + */ +HierarchyManager.prototype.getRootNodes = function(resultRootNodesArray) +{ + if (resultRootNodesArray === undefined) + { resultRootNodesArray = []; } + + var nodesCount = this.nodesArray.length; + var node; + for (var i=0; i 0) - { - var texture = new Texture(); - texture.textureTypeName = textureTypeName; - texture.textureImageFileName = textureImageFileName; - - if (neoBuilding.texturesLoaded === undefined) - { neoBuilding.texturesLoaded = []; } - - neoBuilding.texturesLoaded.push(texture); - } - } - - // read geometry type data.*** - var lod; - var nameLength; - var lodBuildingDatasCount = (new Uint8Array(arrayBuffer.slice(bytesReaded, bytesReaded+ 1)))[0];bytesReaded += 1; - if (lodBuildingDatasCount !== undefined) - { - neoBuilding.lodBuildingDatasMap = {}; - - for (var i =0; i 0) - { - magoManager.backGround_imageReadings_count--; - } - }; - simpleBuildingImage.onerror = function() - { - // doesn't exist or error loading +/** + * 넘겨받은 projectId와 id, attribute로 Node를 생성 후 반환. Node 생성 후 nodesArray와 nodesMap에 등록 + * @param {String} id datakey + * @param {String} projectId + * @param {Object} attributes undefined가 아닐 경우 해당 nodesMap에 등록. + * @returns {Node} + */ +HierarchyManager.prototype.newNode = function(id, projectId, attributes) +{ + var nodesMap = this.getNodesMap(projectId, attributes); + + var node = new Node(); + node.data = {"nodeId": id}; + this.nodesArray.push(node); + nodesMap[id] = node; + return node; +}; - //BR_Project._f4d_lod0Image_readed_finished = false; - //BR_Project._f4d_lod0Image_exists = false; - //if(magoManager.backGround_fileReadings_count > 0 ) - // magoManager.backGround_fileReadings_count -=1; - return; - }; +'use strict'; - simpleBuildingImage.src = imagenUrl; +/** + * @deprecated 사용안함. + * + * @exception {Error} Messages.CONSTRUCT_ERROR + * + * @class InspectorBox + */ +var InspectorBox = function() +{ + if (!(this instanceof InspectorBox)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } }; +'use strict'; /** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param filePath_inServer 변수 - * @param BR_Project 변수 - * @param readerWriter 변수 - * @param magoManager 변수 - * @param imageLod 변수 + * F4D Lego 클래스 + * @exception {Error} Messages.CONSTRUCT_ERROR + * + * @alias Lego + * @class Lego + * + * 아래 문서의 Table 2 (Overall Structure of LOD2 file) 참조 + * @link https://github.com/Gaia3D/F4DConverter/blob/master/doc/F4D_SpecificationV1.pdf */ -ReaderWriter.prototype.readNailImage = function(gl, filePath_inServer, BR_Project, readerWriter, magoManager, imageLod) +var Lego = function() { - if (imageLod === undefined) { imageLod = 3; } // The lowest lod.*** + if (!(this instanceof Lego)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } - if (imageLod === 3) { BR_Project._f4d_nailImage_readed = true; } - else if (imageLod === 0) { BR_Project._f4d_lod0Image_readed = true; } + /** + * @type {VBOVertexIdxCacheKeysContainer} + */ + this.vbo_vicks_container = new VBOVertexIdxCacheKeysContainer(); - if (BR_Project._simpleBuilding_v1 === undefined) { BR_Project._simpleBuilding_v1 = new SimpleBuildingV1(); } + /** + * lego file load state. Default is 0(READY) + * "READY" : 0, + * "LOADING_STARTED" : 1, + * "LOADING_FINISHED" : 2, + * "PARSE_STARTED" : 3, + * "PARSE_FINISHED" : 4, + * "IN_QUEUE" : 5, + * "LOAD_FAILED" : 6 + * @type {Number} + */ + this.fileLoadState = CODE.fileLoadState.READY; - var simpBuildingV1 = BR_Project._simpleBuilding_v1; + /** + * lego bounding box + * @type {BoundingBox} + */ + this.bbox; - var simpleBuildingImage = new Image(); - simpleBuildingImage.onload = function() - { - /* - if(magoManager.render_time > 20)// for the moment is a test.*** - { - if(imageLod === 3) - BR_Project._f4d_nailImage_readed = false; - else if(imageLod === 0) - BR_Project._f4d_lod0Image_readed = false; + /** + * lego data array buffer. parse가 끝난 후 undefined. + * @type {ArrayBuffer} + */ + this.dataArrayBuffer; - if(magoManager.backGround_fileReadings_count > 0 ) - magoManager.backGround_fileReadings_count -=1; + /** + * lego data color. not used + * @deprecated + * @type {Color} + */ + this.selColor4; - return; - } - */ + /** + * 텍스쳐 coord 유무 + * @type {Boolean} + */ + this.hasTexCoords; - if (imageLod === 3) - { - handleTextureLoaded(gl, simpleBuildingImage, simpBuildingV1._simpleBuildingTexture); - BR_Project._f4d_nailImage_readed_finished = true; - } - else if (imageLod === 0) - { - if (simpBuildingV1._texture_0 === undefined) { simpBuildingV1._texture_0 = gl.createTexture(); } + /** + * 텍스쳐 + * @type {Texture} + */ + this.texture; - handleTextureLoaded(gl, simpleBuildingImage, simpBuildingV1._texture_0); - BR_Project._f4d_lod0Image_readed_finished = true; - } + /** + * 텍스쳐 이름 + * @type {String} + */ + this.textureName; - if (magoManager.backGround_fileReadings_count > 0 ) { magoManager.backGround_fileReadings_count -=1; } - }; + /** + * lego key + * @type {String} + */ + this.legoKey; + this.xhr; + + /** + * not use + * @deprecated + * @type {String} + */ + this.renderableType; // triangles, lines, points, etc. - simpleBuildingImage.onerror = function() - { - // doesn't exist or error loading - BR_Project._f4d_lod0Image_readed_finished = false; - BR_Project._f4d_lod0Image_exists = false; - if (magoManager.backGround_fileReadings_count > 0 ) { magoManager.backGround_fileReadings_count -=1; } - return; - }; + /** + * 칼라값 유무 + * @type {Boolean} + */ + this.hasColors; - var filePath_inServer_SimpleBuildingImage = filePath_inServer; - simpleBuildingImage.src = filePath_inServer_SimpleBuildingImage; + /** + * blendAlpha + * @type {Number} + */ + this.blendAlpha = 0.0; + + /** + * birthTime + * @type {Date} + */ + this.birthTime; + + /** + * not use + * @deprecated + * @type {Boolean} + */ + this.isAdult = false; }; /** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param filePath_inServer 변수 - * @param f4dTex 변수 - * @param magoManager 변수 + * F4D Lego 자료를 읽어서 가져온 ArrayBuffer를 파싱. + * + * @param {WebGLRenderingContext} gl WebGL Rendering Context. + * @param {ArrayBuffer} dataArraybuffer + * @param {MagoManager} magoManager */ -ReaderWriter.prototype.readTexture = function(gl, filePath_inServer, f4dTex, magoManager) +Lego.prototype.parseArrayBuffer = function(gl, dataArraybuffer, magoManager) { - f4dTex.loadStarted = true; - //f4dTex.fileLoadState = CODE.fileLoadState.LOADING_STARTED; - f4dTex.texImage = new Image(); - f4dTex.texImage.onload = function() - { - f4dTex.loadFinished = true; - //f4dTex.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; - - if (magoManager.backGround_fileReadings_count > 0 ) { magoManager.backGround_fileReadings_count -=1; } - }; - - f4dTex.texImage.onerror = function() - { - // doesn't exist or error loading - f4dTex.loadStarted = false; - if (magoManager.backGround_fileReadings_count > 0 ) { magoManager.backGround_fileReadings_count -=1; } - return; - }; - - f4dTex.texImage.src = filePath_inServer; + this.parseLegoData(dataArraybuffer, gl, magoManager); }; -ReaderWriter.prototype.decodeTGA = function(arrayBuffer) +/** + * BlendAlpha 반환 + * + * @param {Date} currTime not use + * @returns {Number} always return 1.0 + */ +Lego.prototype.getBlendAlpha = function(currTime) { - // code from toji.*** - var content = new Uint8Array(arrayBuffer), - contentOffset = 18 + content[0], - imagetype = content[2], // 2 = rgb, only supported format for now - width = content[12] + (content[13] << 8), - height = content[14] + (content[15] << 8), - bpp = content[16], // should be 8,16,24,32 - - bytesPerPixel = bpp / 8, - bytesPerRow = width * 4, - data, i, j, x, y; - - if (!width || !height) - { - console.error("Invalid dimensions"); - return null; - } - - if (imagetype !== 2) - { - console.error("Unsupported TGA format:", imagetype); - return null; - } - - data = new Uint8Array(width * height * 4); - i = contentOffset; - - // Oy, with the flipping of the rows... - for (y = height-1; y >= 0; --y) + return 1.0; + /* + if(!this.isAdult) { - for (x = 0; x < width; ++x, i += bytesPerPixel) + if(this.birthTime === undefined) + this.birthTime = currTime; + var increAlpha = (currTime - this.birthTime)*0.0001; + this.blendAlpha += increAlpha; + + if(this.blendAlpha >= 1.0) { - j = (x * 4) + (y * bytesPerRow); - data[j] = content[i+2]; - data[j+1] = content[i+1]; - data[j+2] = content[i+0]; - data[j+3] = (bpp === 32 ? content[i+3] : 255); + this.isAdult = true; } } + else + return 1.0; + + return this.blendAlpha; + */ +}; - return { - width : width, - height : height, - data : data - }; +/** + * render할 준비가 됬는지 체크 + * @returns {Boolean} this.fileLoadState가 CODE.fileLoadState.PARSE_FINISHED(4)이거나 this.texture, this.texture.texId가 존재할때 true 반환 + */ +Lego.prototype.isReadyToRender = function() +{ + if (this.fileLoadState !== CODE.fileLoadState.PARSE_FINISHED) + { return false; } + + if (this.texture === undefined || this.texture.texId === undefined) // In the future, a skin can has no texture. TODO: + { return false; } + + return true; }; /** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param filePath_inServer 변수 - * @param texture 변수 - * @param neoBuilding 변수 - * @param magoManager 변수 + * lego 초기화. gl에서 해당 lego 삭제 + * + * @param {WebGLRenderingContext} gl WebGL Rendering Context. + * @param {VboManager} vboMemManager */ -ReaderWriter.prototype.readNeoReferenceTexture = function(gl, filePath_inServer, texture, neoBuilding, magoManager) +Lego.prototype.deleteObjects = function(gl, vboMemManager) { - // Must know the fileExtension.*** - var extension = filePath_inServer.split('.').pop(); + /* + if(this.xhr !== undefined)// && this.fileLoadState === CODE.fileLoadState.LOADING_STARTED) + { + this.xhr.abort(); + this.xhr = undefined; + } + */ - if (extension === "tga" || extension === "TGA" || extension === "Tga") + if (this.vbo_vicks_container !== undefined) { - texture.fileLoadState = CODE.fileLoadState.LOADING_STARTED; - loadWithXhr(filePath_inServer).done(function(response) - { - var arrayBuffer = response; - if (arrayBuffer) - { - // decode tga.*** - // Test with tga decoder from https://github.com/schmittl/tgajs - var tga = new TGA(); - tga.load(arrayBuffer); - // End decoding.--------------------------------------------------- - - //var tga = magoManager.readerWriter.decodeTGA(arrayBuffer); // old code. - //if(tga) { - // gl.bindTexture(gl.TEXTURE_2D, texture.texId); - // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, tga.width, tga.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, tga.data); - // gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - // gl.generateMipmap(gl.TEXTURE_2D); - // texture.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; // file load finished.*** - //} - - // example values of tga.header - // alphaBits 0 - // bytePerPixel 3 - // colorMapDepth 0 - // colorMapIndex 0 - // colorMapLength 0 - // colorMapType 0 - // flags 32 - // hasColorMap false - // hasEncoding false - // height 2048 - // idLength 0 - // imageType 2 - // isGreyColor false - // offsetX 0 - // offsetY 0 - // origin 2 - // pixelDepth 24 - // width 2048 - - if (tga) - { - var rgbType; - if (tga.header.bytePerPixel === 3) - { - rgbType = gl.RGB; - - // test change rgb to bgr.*** - /* - var imageDataLength = tga.imageData.length; - var pixelsCount = imageDataLength/3; - var r, g, b; - for(var i=0; i 0 && texture.texId !== undefined) - { - gl.bindTexture(gl.TEXTURE_2D, texture.texId); - gl.texImage2D(gl.TEXTURE_2D, 0, rgbType, tga.header.width, tga.header.height, 0, rgbType, gl.UNSIGNED_BYTE, tga.imageData); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.generateMipmap(gl.TEXTURE_2D); - texture.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; // file load finished.*** - gl.bindTexture(gl.TEXTURE_2D, null); - } - else - { - var hola = 0; - - } - } - } - }).fail(function(status) - { - if (neoBuilding) - { - console.log("xhr status = " + status); - if (status === 0) { neoBuilding.metaData.fileLoadState = 500; } - else { neoBuilding.metaData.fileLoadState = status; } - } - }).always(function() - { - magoManager.backGround_fileReadings_count -= 1; - if (magoManager.backGround_fileReadings_count < 0) { magoManager.backGround_fileReadings_count = 0; } - }); + this.vbo_vicks_container.deleteGlObjects(gl, vboMemManager); + this.vbo_vicks_container = undefined; } - else + this.fileLoadState = undefined; + this.dataArrayBuffer = undefined; + if (this.selColor4 !== undefined) { - var neoRefImage = new Image(); - texture.fileLoadState = CODE.fileLoadState.LOADING_STARTED; // file load started.*** - - //magoManager.backGround_fileReadings_count ++; - neoRefImage.onload = function() - { - // is possible that during loading image the building was deleted. Then return. - if (texture.texId === undefined) - { - return; - } - - // if "texture.texId" exist then bind it. - handleTextureLoaded(gl, neoRefImage, texture.texId); - texture.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; // file load finished.*** - - if (magoManager.backGround_fileReadings_count > 0 ) - { magoManager.backGround_fileReadings_count -=1; } - }; - - neoRefImage.onerror = function() - { - // doesn't exist or error loading - return; - }; - neoRefImage.src = filePath_inServer; - } + this.selColor4.deleteObjects(); + this.selColor4 = undefined; + } + + this.textureName = undefined; + if (this.texture) + { + this.texture.deleteObjects(gl); + } + this.texture = undefined; + if (this.bbox) + { + this.bbox.deleteObjects(); + } + this.bbox = undefined; }; - /** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param filePath_inServer 변수 - * @param texture 변수 - * @param neoBuilding 변수 - * @param magoManager 변수 + * F4D Lego 자료(point cloude data)를 읽어서 가져온 ArrayBuffer를 파싱. + * vertex index cache key를 생성하여 담는다. + * LOADING_FINISHED 상태일때 실행. + * normal, texCoord는 없음 + * + * @param {ArrayBuffer} dataArraybuffer + * @param {WebGLRenderingContext} gl not use + * @param {MagoManager} magoManager */ -ReaderWriter.prototype.readLegoSimpleBuildingTexture = function(gl, filePath_inServer, texture, magoManager) +Lego.prototype.parsePointsCloudData = function(buffer, gl, magoManager) { - var neoRefImage = new Image(); - texture.fileLoadState == CODE.fileLoadState.LOADING_STARTED; - magoManager.fileRequestControler.lowLodImagesRequestedCount += 1; - - neoRefImage.onload = function() - { - if (texture.texId === undefined) - { texture.texId = gl.createTexture(); } - - handleTextureLoaded(gl, neoRefImage, texture.texId); - texture.fileLoadState == CODE.fileLoadState.LOADING_FINISHED; - - magoManager.fileRequestControler.lowLodImagesRequestedCount -= 1; + // Provisional. + if (this.fileLoadState !== CODE.fileLoadState.LOADING_FINISHED) { return; } + var stream = new DataStream(buffer, 0, DataStream.LITTLE_ENDIAN); + + var verticesCount = stream.readInt32(); + + var vboMemManager = magoManager.vboMemoryManager; + this.fileLoadState = CODE.fileLoadState.PARSE_STARTED; - if (magoManager.backGround_fileReadings_count > 0 ) { magoManager.backGround_fileReadings_count -=1; } - if (magoManager.fileRequestControler.lowLodImagesRequestedCount < 0) { magoManager.fileRequestControler.lowLodImagesRequestedCount = 0; } - }; + this.bbox = new BoundingBox(); + var bbox = this.bbox; + var vboCacheKey = this.vbo_vicks_container.newVBOVertexIdxCacheKey(); - neoRefImage.onerror = function() + // BoundingBox in float values. + bbox.minX = stream.readFloat32(); + bbox.minY = stream.readFloat32(); + bbox.minZ = stream.readFloat32(); + bbox.maxX = stream.readFloat32(); + bbox.maxY = stream.readFloat32(); + bbox.maxZ = stream.readFloat32(); + + // positionsBuffer. + // read bPositionsCompressed. If this var is true -> positions is in uShort). + this.bPositionsCompressed = stream.readInt8(); + var posByteSize = verticesCount * 3; + var positionBuffer; + + + if (this.bPositionsCompressed) { - if (texture.texId === undefined) - { - texture.texId = gl.createTexture(); - // Test wait for texture to load.******************************************** - gl.bindTexture(gl.TEXTURE_2D, texture.texId); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([200, 200, 200, 255])); // clear grey - gl.bindTexture(gl.TEXTURE_2D, null); - } - - texture.fileLoadState == CODE.fileLoadState.READY; - - magoManager.fileRequestControler.lowLodImagesRequestedCount -= 1; - if (magoManager.fileRequestControler.lowLodImagesRequestedCount < 0) { magoManager.fileRequestControler.lowLodImagesRequestedCount = 0; } - }; + vboCacheKey.setDataArrayPos(stream.readUint16Array(verticesCount * 3), vboMemManager); + } + else + { + vboCacheKey.setDataArrayPos(stream.readFloat32Array(verticesCount * 3), vboMemManager); + } - neoRefImage.src = filePath_inServer; + // normals. + this.hasNormals = stream.readInt8(); + if (this.hasNormals) + { + // todo: + } + + // colors. + this.hasColors = stream.readInt8(); + if (this.hasColors) + { + var numColors = verticesCount; + vboCacheKey.setDataArrayCol(stream.readUint8Array(numColors * 4), vboMemManager); + } + + // texCoords. + this.hasTexCoords = stream.readInt8(); + if (this.hasTexCoords) + { + // todo: + } + + // indices. + this.hasIndices = stream.readInt8(); + if (this.hasIndices) + { + // todo: + } + + this.fileLoadState = CODE.fileLoadState.PARSE_FINISHED; }; - /** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param fileName 변수 - * @param terranTile 변수 - * @param readerWriter 변수 - * @param magoManager 변수 + * F4D Lego 자료를 읽어서 가져온 ArrayBuffer를 파싱. + * vertex index cache key를 생성하여 담는다. + * LOADING_FINISHED 상태일때 실행. + * + * @param {ArrayBuffer} dataArraybuffer + * @param {WebGLRenderingContext} gl not use + * @param {MagoManager} magoManager */ -ReaderWriter.prototype.getTileArrayBuffer = function(gl, fileName, terranTile, readerWriter, magoManager) +Lego.prototype.parseLegoData = function(buffer, gl, magoManager) { - // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data - terranTile.fileReading_started = true; - // magoManager.fileRequestControler.backGround_fileReadings_count += 1; - // blocksList.fileLoadState = CODE.fileLoadState.LOADING_STARTED; + if (this.fileLoadState !== CODE.fileLoadState.LOADING_FINISHED) { return; } + + var vboMemManager = magoManager.vboMemoryManager; - loadWithXhr(fileName).done(function(response) + var stream = new DataStream(buffer, 0, DataStream.LITTLE_ENDIAN); + this.fileLoadState = CODE.fileLoadState.PARSE_STARTED; + + this.bbox = new BoundingBox(); + var bbox = this.bbox; + var vboCacheKey = this.vbo_vicks_container.newVBOVertexIdxCacheKey(); + + // BoundingBox + bbox.minX = stream.readFloat32(); + bbox.minY = stream.readFloat32(); + bbox.minZ = stream.readFloat32(); + bbox.maxX = stream.readFloat32(); + bbox.maxY = stream.readFloat32(); + bbox.maxZ = stream.readFloat32(); + + // VBO(Position Buffer) - x,y,z + var numPositions = stream.readUint32(); + var posDataArray = stream.readFloat32Array(numPositions * 3); + vboCacheKey.setDataArrayPos(posDataArray, vboMemManager); + + + // VBO(Normal Buffer) - i,j,k + var hasNormals = stream.readUint8(); + if (hasNormals) { - var arrayBuffer = response; - if (arrayBuffer) - { - //var BR_Project = new BRBuildingProject(); // Test.*** - //readerWriter.readF4D_Header(gl, arrayBuffer, BR_Project ); // Test.*** - terranTile.fileArrayBuffer = arrayBuffer; - terranTile.fileReading_finished = true; + var numNormals = stream.readUint32(); + var norDataArray = stream.readInt8Array(numNormals * 3); + vboCacheKey.setDataArrayNor(norDataArray, vboMemManager); + } - if (magoManager.backGround_fileReadings_count > 0 ) { magoManager.backGround_fileReadings_count -=1; } - // blocksList.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; - arrayBuffer = null; - } - else - { - // blocksList.fileLoadState = 500; - } - }).fail(function(status) + // VBO(Color Buffer) - r,g,b,a + var hasColors = stream.readUint8(); + if (hasColors) { - console.log("xhr status = " + status); - // if(status === 0) blocksList.fileLoadState = 500; - // else blocksList.fileLoadState = status; - }).always(function() + var numColors = stream.readUint32(); + var colDataArray = stream.readUint8Array(numColors * 4); + vboCacheKey.setDataArrayCol(colDataArray, vboMemManager); + } + + // VBO(TextureCoord Buffer) - u,v + this.hasTexCoords = stream.readUint8(); + if (this.hasTexCoords) { - // magoManager.fileRequestControler.filesRequestedCount -= 1; - // if(magoManager.fileRequestControler.filesRequestedCount < 0) magoManager.fileRequestControler.filesRequestedCount = 0; - }); + var dataType = stream.readUint16(); + var numCoords = stream.readUint32(); + var texCoordDataArray = stream.readFloat32Array(numCoords * 2); + vboCacheKey.setDataArrayTexCoord(texCoordDataArray, vboMemManager); + } + + this.fileLoadState = CODE.fileLoadState.PARSE_FINISHED; + + return true; }; /** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param filePath_inServer 변수 - * @param pCloud 변수 - * @param readerWriter 변수 - * @param magoManager 변수 + * F4D Lego 자료를 gl에 렌더 + * + * @param {MagoManager} magoManager + * @param {Number} renderType + * @param {Boolean} renderTexture + * @param {PostFxShader} shader */ -ReaderWriter.prototype.loadTINTerrain = function(gl, fileName, tinTerrain, magoManager) +Lego.prototype.render = function(magoManager, renderType, renderTexture, shader) { - //magoManager.fileRequestControler.modelRefFilesRequestedCount += 1; - tinTerrain.fileLoadState = CODE.fileLoadState.LOADING_STARTED; + var rendered = false; + var gl = magoManager.sceneState.gl; - loadWithXhr(fileName).done(function(response) + if (this.vbo_vicks_container.vboCacheKeysArray.length === 0) { - var arrayBuffer = response; - if (arrayBuffer) + return false; + } + gl.frontFace(gl.CCW); + + // renderType = 0 -> depth render. + // renderType = 1 -> normal render. + // renderType = 2 -> colorSelection render. + //-------------------------------------------- + + var vbo_vicky = this.vbo_vicks_container.vboCacheKeysArray[0]; // there are only one. + + var vertices_count = vbo_vicky.vertexCount; + if (vertices_count === 0) + { + return false; + } + + if (renderType === 0 || renderType === 2) // depth or colorSelection. + { + shader.disableVertexAttribArray(shader.texCoord2_loc); + shader.disableVertexAttribArray(shader.normal3_loc); + shader.disableVertexAttribArray(shader.color4_loc); + + // 1) Position. + if (!vbo_vicky.bindDataPosition(shader, magoManager.vboMemoryManager)) + { return false; } + + gl.drawArrays(gl.TRIANGLES, 0, vertices_count); + rendered = true; + + } + else if (renderType === 1) // color. + { + // Test external alpha. + if (magoManager.isTrailRender === undefined || magoManager.isTrailRender === false) // check if mago is not rendering special effects. { - tinTerrain.dataArrayBuffer = arrayBuffer; - tinTerrain.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; - //magoManager.parseQueue.putTinTerrainToParse(lowestOctree); // todo.*** - arrayBuffer = undefined; + var blendAlpha = this.getBlendAlpha(magoManager.currTime); + gl.uniform1f(shader.externalAlpha_loc, blendAlpha); + } + // End test.--- + + // 4) Texcoord. + if (renderTexture) + { + if (!vbo_vicky.bindDataTexCoord(shader, magoManager.vboMemoryManager)) + { return false; } } else { - tinTerrain.fileLoadState = 500; + gl.uniform1i(shader.bUse1Color_loc, false); + shader.disableVertexAttribArray(shader.texCoord2_loc); } - }).fail(function(status) - { - //console.log("xhr status = " + status); - //if (status === 0) { lowestOctree.neoReferencesMotherAndIndices.fileLoadState = 500; } - //else { lowestOctree.neoReferencesMotherAndIndices.fileLoadState = status; } - }).always(function() - { - //magoManager.fileRequestControler.modelRefFilesRequestedCount -= 1; - //if (magoManager.fileRequestControler.modelRefFilesRequestedCount < 0) { magoManager.fileRequestControler.modelRefFilesRequestedCount = 0; } - }); -}; + if (!vbo_vicky.bindDataPosition(shader, magoManager.vboMemoryManager)) + { return false; } + + if (!vbo_vicky.bindDataNormal(shader, magoManager.vboMemoryManager)) + { return false; } + + // TODO: + //if (vbo_vicky.meshColorCacheKey !== undefined ) + //{ + //if(shader.color4_loc != -1)shader.enableVertexAttribArray(shader.color4_loc); + //gl.bindBuffer(gl.ARRAY_BUFFER, vbo_vicky.meshColorCacheKey); + //gl.vertexAttribPointer(shader.color4_loc, 4, gl.UNSIGNED_BYTE, true, 0, 0); + //} + + if (renderTexture && vbo_vicky.vboBufferTCoord !== undefined) + { + // Provisionally flip tex coords here. + if (magoManager.configInformation.geo_view_library === Constant.CESIUM) + { gl.uniform1i(shader.textureFlipYAxis_loc, false); }//.ppp + else + { gl.uniform1i(shader.textureFlipYAxis_loc, true); }//.ppp + //--------------------------------------------------------------------------- + + shader.disableVertexAttribArray(shader.color4_loc); + + if (!vbo_vicky.bindDataTexCoord(shader, magoManager.vboMemoryManager)) + { return false; } + } -//load neoTextures -ReaderWriter.prototype.handleTextureLoaded = function(gl, image, texture) -{ - // https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL - //var gl = viewer.scene.context._gl; - gl.bindTexture(gl.TEXTURE_2D, texture); - //gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,true); // if need vertical mirror of the image.*** - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); // Original.*** - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); - gl.generateMipmap(gl.TEXTURE_2D); - gl.bindTexture(gl.TEXTURE_2D, null); + gl.drawArrays(gl.TRIANGLES, 0, vertices_count); + + + rendered = true; + shader.disableVertexAttribArray(shader.color4_loc); + } + + return rendered; }; + + + + + + + + + + + + + + + + + + + 'use strict'; /** - * @class TinTerrain + * LoadData + * @deprecated 삭제예정 + * @alias LoadData + * @class LoadData */ -var TinTerrain = function() +var LoadData = function() { - if (!(this instanceof TinTerrain)) + if (!(this instanceof LoadData)) { throw new Error(Messages.CONSTRUCT_ERROR); } - this.owner; // undefined if depth = 0.*** - this.geographicExtent; - this.fileLoadState = 0; - this.dataArrayBuffer; - this.vboKeyContainer; // class: VBOVertexIdxCacheKeysContainer.*** - this.terrainPositionHIGH; - this.terrainPositionLOW; - this.pathName; // example: "14//4567//516".*** + + // dataType: + // 1. referencesArray. + // 2. blocksArray. + // 3. skinData. (octree's skinData & lod3,4,5 skinData). + // 4. skinTexture. + + this.dataType; + this.distToCam; + this.lod; + this.filePath; + this.texFilePath; + this.skinMesh; + this.octree; this.texture; }; -TinTerrain.prototype.zigZagDecode = function(value) +LoadData.prototype.deleteObjects = function() { - return (value >> 1) ^ (-(value & 1)); + // here deletes deletable objects. + this.dataType = undefined; + this.distToCam = undefined; + this.lod = undefined; + this.filePath = undefined; + this.texFilePath = undefined; + this.skinMesh = undefined; + this.octree = undefined; + this.texture = undefined; }; -TinTerrain.prototype.makeVbo = function() +/** + * LoadQueue + * @deprecated 삭제예정 + * + * @alias LoadQueue + * @class LoadQueue + */ +var LoadQueue = function(magoManager) { - if (this.cartesiansArray === undefined) - { return; } - - // rest the CenterPosition to the this.cartesiansArray.*** - var coordsCount = this.cartesiansArray.length/3; - for (var i=0; i 65536 ) - { - this.indices = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4 * trianglesCount * 3)); bytes_readed += 4 * trianglesCount * 3; - } - else - { - this.indices = new Uint16Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 2 * trianglesCount * 3)); bytes_readed += 2 * trianglesCount * 3; + // Lod2 meshes, 1rst load texture.. + if (this.magoManager.fileRequestControler.isFullPlusLowLodImages()) + { + return; } - // decode indices.*** - var code; - var highest = 0; - var indicesCount = this.indices.length; - for (var i=0; i 4) + { + //this.lod2PCloudDataMap = {}; + remainLod2 = true; + break; + } } } - // 4. edges indices.*** - if (vertexCount > 65536 ) - { - this.westVertexCount = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4)); bytes_readed += 4; - this.westIndices = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4 * this.westVertexCount)); bytes_readed += 4 * this.westVertexCount; - - this.southVertexCount = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4)); bytes_readed += 4; - this.southIndices = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4 * this.southVertexCount)); bytes_readed += 4 * this.southVertexCount; - - this.eastVertexCount = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4)); bytes_readed += 4; - this.eastIndices = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4 * this.eastVertexCount)); bytes_readed += 4 * this.eastVertexCount; - - this.northVertexCount = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4)); bytes_readed += 4; - this.northIndices = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4 * this.northVertexCount)); bytes_readed += 4 * this.northVertexCount; - } - else + this.resetQueue(); +}; +'use strict'; + +/** + * F4D LodBuildingData 클래스 + * Node의 NeoBuilding안에서 사용. + * @exception {Error} Messages.CONSTRUCT_ERROR + * + * @alias LodBuildingData + * @class LodBuildingData + * + * 아래 문서의 Table 1-3 (lodInfo) 참조 + * @link https://github.com/Gaia3D/F4DConverter/blob/master/doc/F4D_SpecificationV1.pdf + */ +var LodBuildingData = function() +{ + if (!(this instanceof LodBuildingData)) { - this.westVertexCount = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4)); bytes_readed += 4; - this.westIndices = new Uint16Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 2 * this.westVertexCount)); bytes_readed += 2 * this.westVertexCount; - - this.southVertexCount = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4)); bytes_readed += 4; - this.southIndices = new Uint16Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 2 * this.southVertexCount)); bytes_readed += 2 * this.southVertexCount; - - this.eastVertexCount = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4)); bytes_readed += 4; - this.eastIndices = new Uint16Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 2 * this.eastVertexCount)); bytes_readed += 2 * this.eastVertexCount; - - this.northVertexCount = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4)); bytes_readed += 4; - this.northIndices = new Uint16Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 2 * this.northVertexCount)); bytes_readed += 2 * this.northVertexCount; + throw new Error(Messages.CONSTRUCT_ERROR); } - - // 5. extension header.*** - this.extensionId = new Uint8Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 1)); bytes_readed += 1; - this.extensionLength = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4)); bytes_readed += 4; - - this.fileLoadState = CODE.fileLoadState.PARSE_FINISHED; - - if (this.extensionId.length === 0) + + /** + * lod of this data. + * @type {Number} + */ + this.lod; + + /** + * 모델 레퍼런스 유무 0 : false, 1 : true + * @type {Number} + */ + this.isModelRef; + + /** + * geometry 파일명, isModelRef가 0일 경우 선언. + * @type {String} + * + * @example lod0, lod1 + */ + this.geometryFileName; + + /** + * texture 파일명 lod가 2일 경우 혹은 isModelRef가 0일 경우 선언 + * @type {String} + * + * @example mosaicTextureLod0.jpg + */ + this.textureFileName; + //this.dataType; // no used yet. +}; +'use strict'; + +/** + * F4D MetaData class. + * @exception {Error} Messages.CONSTRUCT_ERROR + * + * @alias MetaData + * @class MetaData + * + * 아래 문서의 Table 1 참조 + * @link https://github.com/Gaia3D/F4DConverter/blob/master/doc/F4D_SpecificationV1.pdf + */ +var MetaData = function() +{ + if (!(this instanceof MetaData)) { - dataArrayBuffer = undefined; - return; + throw new Error(Messages.CONSTRUCT_ERROR); } + + /** + * guid. must be undefined initially. + * @type {String} + */ + this.guid; + + /** + * f4d version + * @type {String} + */ + this.version = ""; + + /** + * f4d origin geographic coord. longitude, latitude, altitude. + * @type {GeographicCoord} + */ + this.geographicCoord; + + /** + * heading. unit is degree. + * @type {Number} + */ + this.heading; + + /** + * pitch. unit is degree. + * @type {Number} + */ + this.pitch; + + /** + * roll. unit is degree. + * @type {Number} + */ + this.roll; + + /** + * BoundingBox + * @type {BoundingBox} + */ + this.bbox; + + /** + * not used + * @deprecated + */ + this.imageLodCount; + + /** + * Project_data_type (new in version 002). + * 1 = 3d model data type (normal 3d with interior & exterior data). + * 2 = single building skin data type (as vWorld or googleEarth data). + * 3 = multi building skin data type (as Shibuya & Odaiba data). + * 4 = pointsCloud data type. + * 5 = pointsCloud data type pyramidOctree test. + * @type {Number} + */ + this.projectDataType; + //------------------------------------------------------------------------------- - dataArrayBuffer = undefined; -}; + /** + * offset x. Added since version 0.02 + * @type {Number} + */ + this.offSetX; + + /** + * offset y. Added since version 0.02 + * @type {Number} + */ + this.offSetY; + /** + * offset z. Added since version 0.02 + * @type {Number} + */ + this.offSetZ; + /** + * Buildings octree mother size. + * + * @see Octree#setBoxSize + * @see ReaderWriter#getNeoHeaderAsimetricVersion + */ + + /** + * octree min x. octree.centerPos.x - octree.half_dx + * @type {Number} + * @default 0.0 + */ + this.oct_min_x = 0.0; + /** + * octree max x. octree.centerPos.x + octree.half_dx + * @type {Number} + * @default 0.0 + */ + this.oct_max_x = 0.0; + /** + * octree min y. octree.centerPos.y - octree.half_dy + * @type {Number} + * @default 0.0 + */ + this.oct_min_y = 0.0; + /** + * octree min y. octree.centerPos.y + octree.half_dy + * @type {Number} + * @default 0.0 + */ + this.oct_max_y = 0.0; + /** + * octree min z. octree.centerPos.z - octree.half_dz + * @type {Number} + * @default 0.0 + */ + this.oct_min_z = 0.0; + /** + * octree max z. octree.centerPos.z + octree.half_dz + * @type {Number} + * @default 0.0 + */ + this.oct_max_z = 0.0; + /** + * small flag. + * + * when under condition, set true. + * bbox.maxX - bbox.minX < 40.0 && bbox.maxY - bbox.minY < 40.0 && bbox.maxZ - bbox.minZ < 30.0 + * @deprecated + * + * @type {Boolean} + * @default false + */ + this.isSmall = false; + /** + * lego file load state. Default is 0(READY) + * "READY" : 0, + * "LOADING_STARTED" : 1, + * "LOADING_FINISHED" : 2, + * "PARSE_STARTED" : 3, + * "PARSE_FINISHED" : 4, + * "IN_QUEUE" : 5, + * "LOAD_FAILED" : 6 + * @type {Number} + */ + this.fileLoadState = CODE.fileLoadState.READY; +}; +/** + * MetaData 초기화 + */ +MetaData.prototype.deleteObjects = function() +{ + this.guid = undefined; // must be undefined initially. + //this.version = undefined; + if (this.geographicCoord) + { this.geographicCoord.deleteObjects(); } + this.geographicCoord = undefined; // longitude, latitude, altitude. + this.heading = undefined; + this.pitch = undefined; + this.roll = undefined; + if (this.bbox) + { this.bbox.deleteObjects(); } + this.bbox = undefined; // BoundingBox. + this.imageLodCount = undefined; + // Buildings octree mother size. + this.oct_min_x = undefined; + this.oct_max_x = undefined; + this.oct_min_y = undefined; + this.oct_max_y = undefined; + this.oct_min_z = undefined; + this.oct_max_z = undefined; + this.isSmall = undefined; + this.fileLoadState = undefined; +}; +/** + * HeaderAsimetric.hed 파일을 불러와서 metadata 부분을 파싱. + * @param {ArrayBuffer} arrayBuffer + * @param {ReaderWriter} readWriter + */ +MetaData.prototype.parseFileHeaderAsimetricVersion = function(arrayBuffer, readWriter) +{ + var version_string_length = 5; + var intAux_scratch = 0; + var bytes_readed = 0; + if (readWriter === undefined) { readWriter = new ReaderWriter(); } + // 1) Version(5 chars). + this.version = ""; + for (var j=0; j 40.0 || this.bbox.maxY - this.bbox.minY > 40.0) + { + isLarge = true; + } + if (!isLarge && this.bbox.maxZ - this.bbox.minZ < 30.0) + { + this.isSmall = true; + } + + // if header version is "0.0.2", then must read extra parameters. + if (this.version === "0.0.2") + { + // parse dataType (unsigned short). + this.projectDataType = (new Uint16Array(arrayBuffer.slice(bytes_readed, bytes_readed+2)))[0]; bytes_readed += 2; + + // parse Project's offSet (double x 6). + this.offSetX = (new Float64Array(arrayBuffer.slice(bytes_readed, bytes_readed+8)))[0]; bytes_readed += 8; + this.offSetY = (new Float64Array(arrayBuffer.slice(bytes_readed, bytes_readed+8)))[0]; bytes_readed += 8; + this.offSetZ = (new Float64Array(arrayBuffer.slice(bytes_readed, bytes_readed+8)))[0]; bytes_readed += 8; + } + return bytes_readed; +}; @@ -37698,1052 +35391,1306 @@ TinTerrain.prototype.parseData = function(dataArrayBuffer) 'use strict'; /** - * @class TinTerrainManager + * 어떤 일을 하고 있습니까? + * @class ModelReferencedGroup */ -var TinTerrainManager = function() +var ModelReferencedGroup = function() { - if (!(this instanceof TinTerrainManager)) + if (!(this instanceof ModelReferencedGroup)) { throw new Error(Messages.CONSTRUCT_ERROR); } - - this.maxDepth = 15; - this.currentVisibles_terrName_geoCoords_map = {}; // current visible terrains map[terrainPathName, geographicCoords].*** - this.currentTerrainsMap = {}; // current terrains (that was created) map[terrainPathName, tinTerrain].*** + this.modelIdx; // there are only one model. + this.referencesIdxArray = []; // all references has the same model. }; -'use strict'; + /** * 어떤 일을 하고 있습니까? - * @class Arc + * @class ModelReferencedGroupsList */ -var Arc = function() +var ModelReferencedGroupsList = function() { - if (!(this instanceof Arc)) + if (!(this instanceof ModelReferencedGroupsList)) { throw new Error(Messages.CONSTRUCT_ERROR); } - // sweeping in CounterClockWise is positive.*** - // zero startAngle is in "X" axis positive.*** - this.centerPoint; // Point3D.*** - this.radius; - this.startAngleDeg; - this.sweepAngleDeg; - this.numPointsFor360Deg; // interpolation param.*** - // Alternative vars.*** - this.startPoint; // if no exist radius, then startPoint define the radius.*** - this.endPoint; - this.sweepSense; // 1=CCW, -1=CW.*** + this.modelReferencedGroupsMap = []; + this.modelReferencedGroupsArray = []; }; /** - * Set the center position of arc. - * @class Arc + * 어떤 일을 하고 있습니까? + * @param treeDepth 변수 */ -Arc.prototype.deleteObjects = function() +ModelReferencedGroupsList.prototype.getModelReferencedGroup = function(modelIdx) { - if (this.centerPoint !== undefined) - { this.centerPoint.deleteObjects(); } // Point3D.*** - this.centerPoint = undefined; - this.radius = undefined; - this.startAngleDeg = undefined; - this.sweepAngleDeg = undefined; - this.numPointsFor360Deg = undefined; - - if (this.startPoint !== undefined) - { this.startPoint.deleteObjects(); } - - this.startPoint = undefined; + var modelReferencedGroup = this.modelReferencedGroupsMap[modelIdx]; - if (this.endPoint !== undefined) - { this.endPoint.deleteObjects(); } + if (modelReferencedGroup === undefined) + { + modelReferencedGroup = new ModelReferencedGroup(); + modelReferencedGroup.modelIdx = modelIdx; + this.modelReferencedGroupsMap[modelIdx] = modelReferencedGroup; + } - this.endPoint = undefined; - this.sweepSense = undefined; // 1=CCW, -1=CW.*** + return modelReferencedGroup; }; /** - * Set the center position of arc. - * @class Arc + * 어떤 일을 하고 있습니까? + * @param treeDepth 변수 */ -Arc.prototype.setCenterPosition = function(cx, cy) +ModelReferencedGroupsList.prototype.makeModelReferencedGroupsArray = function() { - if (this.centerPoint === undefined) - { this.centerPoint = new Point2D(); } + this.modelReferencedGroupsArray.length = 0; + + var modelRefGroupsCount = this.modelReferencedGroupsMap.length; + for (var i=0; i=0) + // delete textures on the GPU.. + if (this.texturesLoaded) { - for (var currAngRad = 0.0; currAngRadsweepAngRad; currAngRad -= increAngRad) + if (Object.prototype.hasOwnProperty.call(this.lodMeshesMap, lodMeshKey)) { - x = cx + this.radius * Math.cos(currAngRad + startAngRad); - y = cy + this.radius * Math.sin(currAngRad + startAngRad); - point = new Point2D(x, y); - pointsArray.push(point); + var legoSkin = this.lodMeshesMap[lodMeshKey]; + if (legoSkin === undefined) + { return; } + + delete this.lodMeshesMap[lodMeshKey]; + legoSkin.deleteObjects(gl, vboMemoryManager); + legoSkin = undefined; } } +}; + +/** + * 어떤 일을 하고 있습니까? + * @param texture 변수 + * @returns texId + */ +NeoBuilding.prototype.deleteObjectsLod2 = function(gl, vboMemoryManager) +{ + if (this.octree !== undefined) + { + // deletes the geometry and the texture. + this.octree.deleteObjectsLego(gl, vboMemoryManager); + } - // once finished, mark the 1rst point and the last point as"important point".*** - var pointsCount = pointsArray.length; - if (pointsCount > 0) +}; + +/** + * 어떤 일을 하고 있습니까? + * @param texture 변수 + * @returns texId + */ +NeoBuilding.prototype.deleteObjects = function(gl, vboMemoryManager, deleteMetadata) +{ + if (deleteMetadata) { - pointsArray[0].pointType = 1; - pointsArray[pointsCount-1].pointType = 1; + this.metaData.deleteObjects(); + //this.metaData.fileLoadState = CODE.fileLoadState.READY; } - // now merge points into "resultPointsArray".*** - var errorDist = 0.0001; // 0.1mm.*** - var resultExistentPointsCount = resultPointsArray.length; - for (var i=0; i 0) - { - // check if the last point of "resultPointsArray" and the 1rst point of "this" is coincident.*** - var lastExistentPoint = resultPointsArray[resultExistentPointsCount-1]; - point = pointsArray[i]; - if (!lastExistentPoint.isCoincidentToPoint(point, errorDist)) - { - resultPointsArray.push(point); - } - } - else + if (this.texturesLoaded[i]) { - resultPointsArray.push(pointsArray[i]); + this.texturesLoaded[i].deleteObjects(gl); } + this.texturesLoaded[i] = undefined; } - else - { - resultPointsArray.push(pointsArray[i]); - } + this.texturesLoaded.length = 0; } + this.texturesLoaded = undefined; - // Last check: finally, in case of sweepAngle = 360 degrees, or is closed pointsArray, then pop the last insertedPoint.*** - resultExistentPointsCount = resultPointsArray.length; - if (resultExistentPointsCount > 0) + // delete lod3, lod4, lod5. + if (this.lodMeshesMap !== undefined) { - // check if the last point of "resultPointsArray" and the 1rst point of "this" is coincident.*** - var lastPoint = resultPointsArray[resultExistentPointsCount-1]; - var firstPoint = resultPointsArray[0]; - if (lastPoint.isCoincidentToPoint(firstPoint, errorDist)) + for (var key in this.lodMeshesMap) { - resultPointsArray.pop(); - lastPoint.deleteObjects(); + if (Object.prototype.hasOwnProperty.call(this.lodMeshesMap, key)) + { + var legoSkin = this.lodMeshesMap[key]; + if (legoSkin === undefined) + { continue; } + legoSkin.deleteObjects(gl, vboMemoryManager); + legoSkin = undefined; + } } + this.lodMeshesMap = undefined; } - - return resultPointsArray; }; - - - - - - - - - - - - - - - - - - - -'use strict'; - /** - * 선 - * @class AxisXYZ + * 어떤 일을 하고 있습니까? + * @param texture 변수 + * @returns texId */ -var AxisXYZ = function(length) +NeoBuilding.prototype.deleteLodMesh = function(gl, lod, vboMemoryManager) { - if (!(this instanceof AxisXYZ)) + if (this.lodMeshesMap !== undefined) { - throw new Error(Messages.CONSTRUCT_ERROR); + var legoSkin = this.lodMeshesMap[lod]; + if (legoSkin !== undefined) + { + legoSkin.deleteObjects(gl, vboMemoryManager); + legoSkin = undefined; + } } - - if (length === undefined) - { this.length = 60; } - else { this.length = length; } - - this.vbo_vicks_container = new VBOVertexIdxCacheKeysContainer(); - //this.vboKey = this.vbo_vicks_container.newVBOVertexIdxCacheKey(); }; -AxisXYZ.prototype.setDimension = function(length) +/** + * 어떤 일을 하고 있습니까? + * @param texture 변수 + * @returns texId + */ +NeoBuilding.prototype.getBBoxCenterPositionWorldCoord = function(geoLoc) { - this.length = length; + if (this.bboxAbsoluteCenterPos === undefined) + { + this.calculateBBoxCenterPositionWorldCoord(geoLoc); + } + + return this.bboxAbsoluteCenterPos; }; -AxisXYZ.prototype.makeMesh = function(length) +/** + * 어떤 일을 하고 있습니까? + * @param texture 변수 + * @returns texId + */ +NeoBuilding.prototype.calculateBBoxCenterPositionWorldCoord = function(geoLoc) { - if (length !== undefined) - { this.length = length; } - - var pMesh = new ParametricMesh(); - - pMesh.profile = new Profile(); - var profileAux = pMesh.profile; - - // create a halfArrow profile.*** - var outerRing = profileAux.newOuterRing(); - var arrowLength = this.length; - var arrowWidth = this.length*0.1; - var polyLine = outerRing.newElement("POLYLINE"); - var point3d = polyLine.newPoint2d(0, 0); // 0 - point3d = polyLine.newPoint2d(arrowWidth*0.25, arrowLength*0.25); // 1 - point3d = polyLine.newPoint2d(arrowWidth*0.25, arrowLength*0.75); // 2 - point3d = polyLine.newPoint2d(arrowWidth*0.5, arrowLength*0.75); // 3 - point3d = polyLine.newPoint2d(0, arrowLength); // 3 - //-------------------------------------------------------------------- - - var bIncludeBottomCap, bIncludeTopCap; - var revolveAngDeg, revolveSegmentsCount, revolveSegment2d; - revolveAngDeg = 360.0; - - // create a rotation axis by a segment.*** - revolveSegment2d = new Segment2D(); - var strPoint2d = new Point2D(0, -10); - var endPoint2d = new Point2D(0, 10); - revolveSegment2d.setPoints(strPoint2d, endPoint2d); - revolveSegmentsCount = 8; - - // rotate the profile and create the Y axis.*** - pMesh.revolve(profileAux, revolveAngDeg, revolveSegmentsCount, revolveSegment2d); - - bIncludeBottomCap = false; - bIncludeTopCap = false; - var mesh = pMesh.getSurfaceIndependentMesh(undefined, bIncludeBottomCap, bIncludeTopCap); - mesh.setColor(0.1, 1.0, 0.1, 1.0); // set the color.*** - mesh.reverseSense(); + var bboxCenterPoint; - // copy & rotate the mesh and create the X axis.*** - var tMatTest = new Matrix4(); - var mesh2 = mesh.getCopy(undefined); - tMatTest.rotationAxisAngDeg(-90.0, 0, 0, 1); - mesh2.transformByMatrix4(tMatTest); - mesh2.setColor(1.0, 0.1, 0.1, 1.0); // set the color.*** + bboxCenterPoint = this.bbox.getCenterPoint(bboxCenterPoint); // local bbox. + this.bboxAbsoluteCenterPos = geoLoc.tMatrix.transformPoint3D(bboxCenterPoint, this.bboxAbsoluteCenterPos); - // copy & rotate the mesh and create the Z axis.*** - var mesh3 = mesh.getCopy(undefined); - tMatTest.rotationAxisAngDeg(90.0, 1, 0, 0); - mesh3.transformByMatrix4(tMatTest); - mesh3.setColor(0.1, 0.1, 1.0, 1.0); // set the color.*** - - // Merge all meshes into a one mesh and make a unique vbo.*** - mesh.mergeMesh(mesh2); - mesh.mergeMesh(mesh3); - return mesh; + // Now, must applicate the aditional translation vector. Aditional translation is made when we translate the pivot point. + if (geoLoc.pivotPointTraslation) + { + var traslationVector; + traslationVector = geoLoc.tMatrix.rotatePoint3D(geoLoc.pivotPointTraslation, traslationVector ); + this.bboxAbsoluteCenterPos.add(traslationVector.x, traslationVector.y, traslationVector.z); + } }; -AxisXYZ.prototype.getVboKeysContainer = function() +/** + * 어떤 일을 하고 있습니까? + * @param texture 변수 + * @returns texId + */ +NeoBuilding.prototype.getTextureId = function(texture) { - return this.vbo_vicks_container; + var texId; + var texturesLoadedCount = this.texturesLoaded.length; + var find = false; + var i=0; + while (!find && i < texturesLoadedCount ) + { + if (this.texturesLoaded[i].textureImageFileName === texture.textureImageFileName) + { + find = true; + texId = this.texturesLoaded[i].texId; + } + i++; + } + + return texId; }; -'use strict'; /** -* 어떤 일을 하고 있습니까? -* @class BoundingRectangle -*/ -var BoundingRectangle = function(x, y) + * 어떤 일을 하고 있습니까? + * @param texture 변수 + * @returns texId + */ +NeoBuilding.prototype.getSameTexture = function(texture) { - if (!(this instanceof BoundingRectangle)) + var sameTexture; + var texturesLoadedCount = this.texturesLoaded.length; + var find = false; + var i=0; + while (!find && i < texturesLoadedCount ) { - throw new Error(Messages.CONSTRUCT_ERROR); + if (this.texturesLoaded[i].textureImageFileName === texture.textureImageFileName) + { + find = true; + sameTexture = this.texturesLoaded[i]; + } + i++; } - this.minX = 100000; - this.maxX = -100000; - this.minY = 100000; - this.maxY = -100000; + return sameTexture; }; -BoundingRectangle.prototype.setInit = function(point) +/** + * 어떤 일을 하고 있습니까? + * @param eyeX 변수 + * @param eyeY 변수 + * @param eyeZ 변수 + */ +NeoBuilding.prototype.updateCurrentVisibleIndicesExterior = function(eyeX, eyeY, eyeZ) { - if (point === undefined) - { return; } - - this.minX = point.x; - this.minY = point.y; - this.maxX = point.x; - this.maxY = point.y; + this._neoRefLists_Container.updateCurrentVisibleIndicesOfLists(eyeX, eyeY, eyeZ); }; -BoundingRectangle.prototype.setInitByRectangle = function(bRect) +/** + * 어떤 일을 하고 있습니까? + */ +NeoBuilding.prototype.updateCurrentAllIndicesExterior = function() { - if (bRect === undefined) - { return; } - - this.minX = bRect.minX; - this.minY = bRect.minY; - this.maxX = bRect.maxX; - this.maxY = bRect.maxY; + this._neoRefLists_Container.updateCurrentAllIndicesOfLists(); }; -BoundingRectangle.prototype.addPoint = function(point) +/** + * 어떤 일을 하고 있습니까? + * @returns metaData.bbox.isPoint3dInside(eyeX, eyeY, eyeZ); + */ +NeoBuilding.prototype.isCameraInsideOfBuilding = function(eyeX, eyeY, eyeZ) { - if (point === undefined) - { return; } - - if (point.x < this.minX) - { this.minX = point.x; } - else if (point.x > this.maxX) - { this.maxX = point.x; } - - if (point.y < this.minY) - { this.minY = point.y; } - else if (point.y > this.maxY) - { this.maxY = point.y; } + return this.metaData.bbox.isPoint3dInside(eyeX, eyeY, eyeZ); + /* + var intersectedOctree = this.octree.getIntersectedSubBoxByPoint3D(eyeX, eyeY, eyeZ); + if(intersectedOctree) + { + if(intersectedOctree.triPolyhedronsCount > 0) + return true; + else + return false; + } + else + return false; + */ }; -BoundingRectangle.prototype.addRectangle = function(bRect) +/** + * 어떤 일을 하고 있습니까? + * @param absoluteEyeX 변수 + * @param absoluteEyeY 변수 + * @param absoluteEyeZ 변수 + * @returns point3dScrath2 + */ +NeoBuilding.prototype.getTransformedRelativeEyePositionToBuilding = function(absoluteEyeX, absoluteEyeY, absoluteEyeZ, resultRelEyePosToBuilding) { - if (bRect === undefined) - { return; } + // 1rst, calculate the relative eye position. + var buildingPosition = this.buildingPosition; + var relativeEyePosX = absoluteEyeX - buildingPosition.x; + var relativeEyePosY = absoluteEyeY - buildingPosition.y; + var relativeEyePosZ = absoluteEyeZ - buildingPosition.z; + + if (this.buildingPosMatInv === undefined) + { + this.buildingPosMatInv = new Matrix4(); + this.buildingPosMatInv.setByFloat32Array(this.moveMatrixInv); + } + + var point3dScratch = new Point3D(); - if (bRect.minX < this.minX) - { this.minX = bRect.minX; } - if (bRect.maxX > this.maxX) - { this.maxX = bRect.maxX; } + if (resultRelEyePosToBuilding === undefined) + { resultRelEyePosToBuilding = new Point3D(); } - if (bRect.minY < this.minY) - { this.minY = bRect.minY; } - if (bRect.maxY > this.maxY) - { this.maxY = bRect.maxY; } + point3dScratch.set(relativeEyePosX, relativeEyePosY, relativeEyePosZ); + resultRelEyePosToBuilding = this.buildingPosMatInv.transformPoint3D(point3dScratch, resultRelEyePosToBuilding); + + return resultRelEyePosToBuilding; }; -BoundingRectangle.prototype.intersectsWithRectangle = function(bRect) +/** + * 어떤 일을 하고 있습니까? + * @param neoReference 변수 + */ +NeoBuilding.prototype.getHeaderVersion = function() { - if (bRect === undefined) - { return false; } - - if (bRect.minX > this.maxX) - { return false; } - else if (bRect.maxX < this.minX) - { return false; } - else if (bRect.minY > this.maxY) - { return false; } - else if (bRect.maxY < this.minY) - { return false; } - - return true; + if (this.metaData) + { return this.metaData.version; } + else + { return undefined; } }; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -'use strict'; - /** - * 영역 박스 - * @class BoxAux + * 어떤 일을 하고 있습니까? + * @param lod 변수 */ -var BoxAux = function() +NeoBuilding.prototype.getLodBuildingData = function(lod) { - if (!(this instanceof BoxAux)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - // vertex indices of the BoxAux.*** - // 3----------2 7----------6 - // | | | | - // | bottom | | top | - // | | | | - // 0----------1 4----------5 + if (this.lodBuildingDatasMap === undefined) + { return undefined; } - this.triPolyhedron = new TriPolyhedron(); - this.vbo_vicks_container = new VBOVertexIdxCacheKeysContainer(); - this.vBOVertexIdxCacheKey = this.vbo_vicks_container.newVBOVertexIdxCacheKey(); + return this.lodBuildingDatasMap[lod]; }; /** - * axis aligned bounding BoxAux - * @param xLength - * @param yLength - * @param zLength + * 어떤 일을 하고 있습니까? + * @param neoReference 변수 */ -BoxAux.prototype.getVboKeysContainer = function() +NeoBuilding.prototype.getCurrentLodString = function() { - return this.vbo_vicks_container; + var currentLodString = undefined; + var lodBuildingData = this.getLodBuildingData(this.currentLod); + currentLodString = lodBuildingData.geometryFileName; + return currentLodString; }; /** - * axis aligned bounding BoxAux - * @param xLength - * @param yLength - * @param zLength + * 어떤 일을 하고 있습니까? + * @param neoReference 변수 */ -BoxAux.prototype.makeAABB = function(xLength, yLength, zLength) +NeoBuilding.prototype.getLowerSkinLodToLoad = function(currentLod) { - // this makes a BoxAux centered on the center of the BoxAux.*** - var minX = -xLength/2.0; - var minY = -yLength/2.0; - var minZ = -zLength/2.0; - - var maxX = xLength/2.0; - var maxY = yLength/2.0; - var maxZ = zLength/2.0; - - // make 8 vertices and 6 triSurfaces.*** - var vertexList = this.triPolyhedron.vertexList; - - // Bottom.**** - var vertex = vertexList.newVertex(); // 0.*** - vertex.setPosition(minX, minY, minZ); - - vertex = vertexList.newVertex(); // 1.*** - vertex.setPosition(maxX, minY, minZ); - - vertex = vertexList.newVertex(); // 2.*** - vertex.setPosition(maxX, maxY, minZ); - - vertex = vertexList.newVertex(); // 3.*** - vertex.setPosition(minX, maxY, minZ); - - // Top.*** - vertex = vertexList.newVertex(); // 4.*** - vertex.setPosition(minX, minY, maxZ); - - vertex = vertexList.newVertex(); // 5.*** - vertex.setPosition(maxX, minY, maxZ); - - vertex = vertexList.newVertex(); // 6.*** - vertex.setPosition(maxX, maxY, maxZ); - - vertex = vertexList.newVertex(); // 7.*** - vertex.setPosition(minX, maxY, maxZ); - - - // now, create triSurfaces and triangles.*** - var triSurface; - var triangle; - // Bottom surface.*** - triSurface = this.triPolyhedron.newTriSurface(); - triangle = triSurface.newTriangle(); - triangle.setVertices(vertexList.getVertex(0), vertexList.getVertex(2), vertexList.getVertex(1)); - - triangle = triSurface.newTriangle(); - triangle.setVertices(vertexList.getVertex(0), vertexList.getVertex(3), vertexList.getVertex(2)); - - // Top surface.*** - triSurface = this.triPolyhedron.newTriSurface(); - triangle = triSurface.newTriangle(); - triangle.setVertices(vertexList.getVertex(4), vertexList.getVertex(5), vertexList.getVertex(6)); - - triangle = triSurface.newTriangle(); - triangle.setVertices(vertexList.getVertex(4), vertexList.getVertex(6), vertexList.getVertex(7)); - - // Front surface.*** - triSurface = this.triPolyhedron.newTriSurface(); - triangle = triSurface.newTriangle(); - triangle.setVertices(vertexList.getVertex(0), vertexList.getVertex(1), vertexList.getVertex(5)); - - triangle = triSurface.newTriangle(); - triangle.setVertices(vertexList.getVertex(0), vertexList.getVertex(5), vertexList.getVertex(4)); - - // Right surface.*** - triSurface = this.triPolyhedron.newTriSurface(); - triangle = triSurface.newTriangle(); - triangle.setVertices(vertexList.getVertex(1), vertexList.getVertex(2), vertexList.getVertex(6)); - - triangle = triSurface.newTriangle(); - triangle.setVertices(vertexList.getVertex(1), vertexList.getVertex(6), vertexList.getVertex(5)); - - // Rear surface.*** - triSurface = this.triPolyhedron.newTriSurface(); - triangle = triSurface.newTriangle(); - triangle.setVertices(vertexList.getVertex(2), vertexList.getVertex(3), vertexList.getVertex(7)); - - triangle = triSurface.newTriangle(); - triangle.setVertices(vertexList.getVertex(2), vertexList.getVertex(7), vertexList.getVertex(6)); + // When load buildingSkin, must load respecting the LOD-order. Load 1rst lowerLod. + // This function returns the lowerLod that is no loaded from currentLod. + var lodToLoad; - // Left surface.*** - triSurface = this.triPolyhedron.newTriSurface(); - triangle = triSurface.newTriangle(); - triangle.setVertices(vertexList.getVertex(3), vertexList.getVertex(0), vertexList.getVertex(4)); + for (var lod = 5; lod >= 0; lod--) + { + var lodBuildingDataAux = this.getLodBuildingData(lod); + + if (lodBuildingDataAux === undefined) + { continue; } - triangle = triSurface.newTriangle(); - triangle.setVertices(vertexList.getVertex(3), vertexList.getVertex(4), vertexList.getVertex(7)); + if (lodBuildingDataAux.isModelRef) + { continue; } + var lodStringAux = lodBuildingDataAux.geometryFileName; + var lowLodMeshAux = this.lodMeshesMap[lodStringAux]; + + // Check if lowLodMeshAux if finished loading data. + if (lowLodMeshAux === undefined || lowLodMeshAux.fileLoadState === CODE.fileLoadState.READY) + { + lodToLoad = lod; + break; + } + else if (lowLodMeshAux.vbo_vicks_container.vboCacheKeysArray === undefined) + { + lodToLoad = lod; + break; + } + if (lowLodMeshAux.vbo_vicks_container.vboCacheKeysArray[0] && lowLodMeshAux.vbo_vicks_container.vboCacheKeysArray[0].vboBufferTCoord) + { + // this is the new version. + if (lowLodMeshAux.texture === undefined) + { + lodToLoad = lod; + break; + } + } + } + + return lodToLoad; }; -'use strict'; /** * 어떤 일을 하고 있습니까? - * @class Circle + * @param neoReference 변수 */ -var Circle = function() +NeoBuilding.prototype.getCurrentSkin = function() { - if (!(this instanceof Circle)) + if (this.lodMeshesMap === undefined) + { return undefined; } + + var skinLego; + var lodBuildingData = this.getLodBuildingData(this.currentLod); + if (lodBuildingData === undefined) + { return; } + + //textureFileName = lodBuildingData.textureFileName; + var lodString = lodBuildingData.geometryFileName; + skinLego = this.lodMeshesMap[lodString]; + + if (skinLego !== undefined && skinLego.isReadyToRender()) + { return skinLego; } + + + if (this.currentLod === 0) { - throw new Error(Messages.CONSTRUCT_ERROR); + skinLego = this.lodMeshesMap.lod0; + + if (skinLego === undefined || !skinLego.isReadyToRender()) + { + skinLego = this.lodMeshesMap.lod1; + if (skinLego === undefined || !skinLego.isReadyToRender()) + { + skinLego = this.lodMeshesMap.lod2; + if (skinLego === undefined || !skinLego.isReadyToRender()) + { + skinLego = this.lodMeshesMap.lod3; + if (skinLego === undefined || !skinLego.isReadyToRender()) + { + skinLego = this.lodMeshesMap.lod4; + if (skinLego === undefined || !skinLego.isReadyToRender()) + { + skinLego = this.lodMeshesMap.lod5; + } + } + } + } + } + } - // sweeping in CounterClockWise is positive.*** - // zero startAngle is in "X" axis positive.*** - this.centerPoint; // Point3D.*** - this.radius; - this.numPointsFor360Deg; // interpolation param.*** + else if (this.currentLod === 1) + { + skinLego = this.lodMeshesMap.lod1; + + if (skinLego === undefined || !skinLego.isReadyToRender()) + { + skinLego = this.lodMeshesMap.lod2; + if (skinLego === undefined || !skinLego.isReadyToRender()) + { + skinLego = this.lodMeshesMap.lod3; + if (skinLego === undefined || !skinLego.isReadyToRender()) + { + skinLego = this.lodMeshesMap.lod4; + if (skinLego === undefined || !skinLego.isReadyToRender()) + { + skinLego = this.lodMeshesMap.lod5; + } + } + } + } + + } + else if (this.currentLod === 2) + { + skinLego = this.lodMeshesMap.lod2; + + if (skinLego === undefined || !skinLego.isReadyToRender()) + { + skinLego = this.lodMeshesMap.lod3; + if (skinLego === undefined || !skinLego.isReadyToRender()) + { + skinLego = this.lodMeshesMap.lod4; + if (skinLego === undefined || !skinLego.isReadyToRender()) + { + skinLego = this.lodMeshesMap.lod5; + } + } + } + + } + else if (this.currentLod === 3) + { + skinLego = this.lodMeshesMap.lod3; + + if (skinLego === undefined || !skinLego.isReadyToRender()) + { + skinLego = this.lodMeshesMap.lod4; + if (skinLego === undefined || !skinLego.isReadyToRender()) + { + skinLego = this.lodMeshesMap.lod5; + } + } + + } + else if (this.currentLod === 4) + { + skinLego = this.lodMeshesMap.lod4; + + if (skinLego === undefined || !skinLego.isReadyToRender()) + { + skinLego = this.lodMeshesMap.lod5; + if (skinLego === undefined || !skinLego.isReadyToRender()) + { + skinLego = this.lodMeshesMap.lod3; + } + } + + } + else if (this.currentLod === 5) + { + skinLego = this.lodMeshesMap.lod5; + + if (skinLego === undefined || !skinLego.isReadyToRender()) + { + skinLego = this.lodMeshesMap.lod4; + if (skinLego === undefined || !skinLego.isReadyToRender()) + { + skinLego = this.lodMeshesMap.lod3; + } + } + + } + + return skinLego; }; /** - * Set the center position of Circle. - * @class Circle + * 어떤 일을 하고 있습니까? + * @param neoReference 변수 */ -Circle.prototype.setCenterPosition = function(cx, cy) +NeoBuilding.prototype.manageNeoReferenceTexture = function(neoReference, magoManager) { - if (this.centerPoint === undefined) - { this.centerPoint = new Point2D(); } + var texture = undefined; + + if (this.metaData.version[0] === "v") + { + // this is the version beta. + if (neoReference.texture === undefined) + { return undefined; } + + if (neoReference.texture.texId === undefined && neoReference.texture.textureImageFileName !== "") + { + // 1rst, check if the texture is loaded. + if (this.texturesLoaded === undefined) + { this.texturesLoaded = []; } + + var sameTexture = this.getSameTexture(neoReference.texture); + if (sameTexture === undefined) + { + if (magoManager.backGround_fileReadings_count > 10) + { return; } + + if (neoReference.texture.fileLoadState === CODE.fileLoadState.READY) + { + var gl = magoManager.sceneState.gl; + neoReference.texture.texId = gl.createTexture(); + // Load the texture. + var projectFolderName = this.projectFolderName; + var geometryDataPath = magoManager.readerWriter.geometryDataPath; + var filePath_inServer = geometryDataPath + "/" + projectFolderName + "/" + this.buildingFileName + "/Images_Resized/" + neoReference.texture.textureImageFileName; + + this.texturesLoaded.push(neoReference.texture); + magoManager.readerWriter.readNeoReferenceTexture(gl, filePath_inServer, neoReference.texture, this, magoManager); + magoManager.backGround_fileReadings_count ++; + } + } + else + { + if (sameTexture.fileLoadState === CODE.fileLoadState.LOADING_FINISHED) + { + neoReference.texture = sameTexture; + } + } + } + + return neoReference.texture.fileLoadState; + } + else if (this.metaData.version[0] === '0' && this.metaData.version[2] === '0' && this.metaData.version[4] === '1' ) + { + if (neoReference.texture === undefined || neoReference.texture.fileLoadState === CODE.fileLoadState.READY) + { + // provisionally use materialId as textureId. + var textureId = neoReference.materialId; + texture = this.texturesLoaded[textureId]; + neoReference.texture = texture; + + if (texture.texId === undefined && texture.textureImageFileName !== "") + { + if (magoManager.backGround_fileReadings_count > 10) + { return undefined; } + + if (texture.fileLoadState === CODE.fileLoadState.READY) + { + var gl = magoManager.sceneState.gl; + texture.texId = gl.createTexture(); + // Load the texture. + var projectFolderName = this.projectFolderName; + var geometryDataPath = magoManager.readerWriter.getCurrentDataPath(); + var filePath_inServer = geometryDataPath + "/" + projectFolderName + "/" + this.buildingFileName + "/Images_Resized/" + texture.textureImageFileName; + + magoManager.readerWriter.readNeoReferenceTexture(gl, filePath_inServer, texture, this, magoManager); + magoManager.backGround_fileReadings_count ++; + } + } + } + + return neoReference.texture.fileLoadState; + } + else if (this.metaData.version[0] === '0' && this.metaData.version[2] === '0' && this.metaData.version[4] === '2' ) + { + // Project_data_type (new in version 002). + // 1 = 3d model data type (normal 3d with interior & exterior data). + // 2 = single building skin data type (as vWorld or googleEarth data). + // 3 = multi building skin data type (as Shibuya & Odaiba data). + // 4 = pointsCloud data type. + // 5 = pointsCloud data type pyramidOctree test. + if (this.metaData.projectDataType === undefined || this.metaData.projectDataType > 3) + { return neoReference.texture.fileLoadState; } + + if (neoReference.texture === undefined || neoReference.texture.fileLoadState === CODE.fileLoadState.READY) + { + // provisionally use materialId as textureId. + var textureId = neoReference.materialId; + texture = this.texturesLoaded[textureId]; + neoReference.texture = texture; + + if (texture.texId === undefined && texture.textureImageFileName !== "") + { + if (magoManager.backGround_fileReadings_count > 10) + { return undefined; } + + if (texture.fileLoadState === CODE.fileLoadState.READY) + { + var gl = magoManager.sceneState.gl; + texture.texId = gl.createTexture(); + // Load the texture. + var projectFolderName = this.projectFolderName; + var geometryDataPath = magoManager.readerWriter.getCurrentDataPath(); + var filePath_inServer = geometryDataPath + "/" + projectFolderName + "/" + this.buildingFileName + "/Images_Resized/" + texture.textureImageFileName; + + magoManager.readerWriter.readNeoReferenceTexture(gl, filePath_inServer, texture, this, magoManager); + magoManager.backGround_fileReadings_count ++; + } + } + } + + return neoReference.texture.fileLoadState; + } - this.centerPoint.set(cx, cy); }; /** - * Set the center position of Circle. - * @class Circle + * 어떤 일을 하고 있습니까? */ -Circle.prototype.setRadius = function(radius) +NeoBuilding.prototype.getShaderName = function(lod, projectType, renderType) { - this.radius = radius; + var shaderName; + + // renderType = 0 -> depth render. + // renderType = 1 -> normal render. + // renderType = 2 -> colorSelection render. + //-------------------------------------------- + + if (renderType === 0) + { + if (lod <= 1) + { + shaderName = "modelRefDepth"; + } + } + else if (renderType === 1) + { + if (lod <= 2) + { + shaderName = "modelRefSsao"; + } + } + else if (renderType === 2) + { + if (lod <= 1) + { + shaderName = "modelRefSsao"; + } + } + + return shaderName; }; /** - * Returns the points of the arc. - * @class Arc + * 어떤 일을 하고 있습니까? */ -Circle.prototype.getPoints = function(resultPointsArray, pointsCountFor360Deg) +NeoBuilding.prototype.prepareSkin = function(magoManager) { - if (pointsCountFor360Deg) - { this.numPointsFor360Deg = pointsCountFor360Deg; } + var headerVersion = this.getHeaderVersion(); + if (headerVersion === undefined) + { return false; } + + if (headerVersion[0] !== "0") + { + return false; + } - if (this.numPointsFor360Deg === undefined) - { this.numPointsFor360Deg = 36; } + if (this.lodMeshesMap === undefined) + { this.lodMeshesMap = {}; } - // use an arc to make points.*** - if (this.centerPoint === undefined || this.radius === undefined) - { return resultPointsArray; } + var projectFolderName = this.projectFolderName; + var buildingFolderName = this.buildingFileName; + var geometryDataPath = magoManager.readerWriter.geometryDataPath; - var arc = new Arc(); - arc.setCenterPosition(this.centerPoint.x, this.centerPoint.y); + // Must respect the lodLoading order: must load the lowerLod if is not loaded. + var lodToLoad; + lodToLoad = this.getLowerSkinLodToLoad(this.currentLod); + var lodBuildingData = this.getLodBuildingData(lodToLoad); + if (lodBuildingData === undefined) + { return false; } + + if (lodBuildingData.isModelRef) + { return false; } - arc.setRadius(this.radius); - arc.setStartAngleDegree(0); - arc.setSweepAngleDegree(360.0); - arc.setSense(1); + var textureFileName = lodBuildingData.textureFileName; + var lodString = lodBuildingData.geometryFileName; - if (resultPointsArray === undefined) - { resultPointsArray = []; } + ///lowLodMesh = this.lodMeshesMap.get(lodString); // code if "lodMeshesMap" is a map. + var lowLodMesh = this.lodMeshesMap[lodString]; + if (lowLodMesh === undefined) + { + lowLodMesh = new Lego(); + lowLodMesh.fileLoadState = CODE.fileLoadState.READY; + lowLodMesh.textureName = textureFileName; + lowLodMesh.legoKey = this.buildingId + "_" + lodString; + this.lodMeshesMap[lodString] = lowLodMesh; + } - resultPointsArray = arc.getPoints(resultPointsArray, this.numPointsFor360Deg); - return resultPointsArray; -}; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -'use strict'; - -/** - * 어떤 일을 하고 있습니까? - * @class Ellipsoid - */ -var Ellipsoid = function(radiusX, radiusY, radiusZ) -{ - if (!(this instanceof Ellipsoid)) + if (lowLodMesh.fileLoadState === -1) { - throw new Error(Messages.CONSTRUCT_ERROR); + // if a lodObject has "fileLoadState" = -1 means that there are no file in server. + return false; } - // Ellipsoid: x^2/a^2 + y^2/b^2 + z^2/c^2 = 1, (a, b, c) = (radiusX, radiusY, radiusZ).*** - - this.radiusX; - this.radiusY; - this.radiusZ; - if (radiusX !== undefined) - { this.radiusX = radiusX; } + if (lowLodMesh.fileLoadState === CODE.fileLoadState.READY) + { + // put it into fileLoadQueue. + var lodMeshFilePath = geometryDataPath + "/" + projectFolderName + "/" + buildingFolderName + "/" + lodString; + magoManager.readerWriter.getLegoArraybuffer(lodMeshFilePath, lowLodMesh, magoManager); + if (lowLodMesh.vbo_vicks_container.vboCacheKeysArray === undefined) + { lowLodMesh.vbo_vicks_container.vboCacheKeysArray = []; } + + } - if (radiusY !== undefined) - { this.radiusY = radiusY; } + if (lowLodMesh.vbo_vicks_container.vboCacheKeysArray[0] && lowLodMesh.vbo_vicks_container.vboCacheKeysArray[0].vboBufferTCoord) + { + // this is the new version. + if (lowLodMesh.texture === undefined) + { + lowLodMesh.texture = new Texture(); + var filePath_inServer = geometryDataPath + "/" + projectFolderName + "/" + buildingFolderName + "/" + textureFileName; + var gl = magoManager.sceneState.gl; + magoManager.readerWriter.readLegoSimpleBuildingTexture(gl, filePath_inServer, lowLodMesh.texture, magoManager); + } + } - if (radiusZ !== undefined) - { this.radiusZ = radiusZ; } - + return true; }; -'use strict'; /** * 어떤 일을 하고 있습니까? - * @class Face */ -var Face = function() +NeoBuilding.prototype.render = function(magoManager, shader, renderType, refMatrixIdxKey, flipYTexCoord, currentLod) { - if (!(this instanceof Face)) + var gl = magoManager.sceneState.gl; + //gl.uniform1f(shader.externalAlpha_loc, 1.0); + + if (currentLod !== undefined) + { this.currentLod = currentLod; } + + // Check metaData.projectDataType. + if (this.metaData.projectDataType === 5) { - throw new Error(Messages.CONSTRUCT_ERROR); + // Render pointsCloud pyramidMode. + return; } - - this.vertexArray; - this.hEdge; - this.planeNormal; - this.surfaceOwner; -}; - -Face.prototype.getVerticesCount = function() -{ - if (this.vertexArray === undefined) - { return 0; } - - return this.vertexArray.length; -}; - -Face.prototype.addVertex = function(vertex) -{ - if (this.vertexArray === undefined) - { this.vertexArray = []; } - this.vertexArray.push(vertex); + if (this.currentLod <= 2) + { + // There are buildings that are only skin, so check projectType of the building. + var lodBuildingData = this.getLodBuildingData(this.currentLod); + if (lodBuildingData && !lodBuildingData.isModelRef) + { + // This building is skinType data. + this.renderSkin(magoManager, shader, renderType); + } + else + { + // This building is octree divided type data. + var octreesRenderedCount = this.renderDetailed(magoManager, shader, renderType, refMatrixIdxKey, flipYTexCoord); + + if (this.currentVisibleOctreesControler === undefined) + { + this.renderSkin(magoManager, shader, renderType); + } + else + { + var lowestOctreesCount0 = this.currentVisibleOctreesControler.currentVisibles0.length; + var lowestOctreesCount1 = this.currentVisibleOctreesControler.currentVisibles1.length; + var lowestOctreesCount2 = this.currentVisibleOctreesControler.currentVisibles2.length; + + // If octreesRenderedsCount is minor than 60% of total of visibleOctrees, then render the buildingSkin. + if (octreesRenderedCount < (lowestOctreesCount0 + lowestOctreesCount1 + lowestOctreesCount2)*0.4) + { this.renderSkin(magoManager, shader, renderType); } + } + } + + // Now, check how many octrees are rendered. If rendered only a few, then render the buildingSkin. + + } + else if (this.currentLod > 2) + { + this.renderSkin(magoManager, shader, renderType); + } }; -Face.prototype.getVertex = function(idx) +/** + * 어떤 일을 하고 있습니까? + */ +NeoBuilding.prototype.renderSkin = function(magoManager, shader, renderType) { - if (this.vertexArray === undefined) - { return undefined; } + var skinLego = this.getCurrentSkin(); + + if (skinLego === undefined) + { return; } - return this.vertexArray[idx]; -}; + if (skinLego.fileLoadState !== CODE.fileLoadState.PARSE_FINISHED) + { return; } -Face.prototype.reverseSense = function() -{ - this.vertexArray.reverse(); -}; + var gl = magoManager.sceneState.gl; -Face.prototype.setColor = function(r, g, b, a) -{ - var vertex; - var verticesCount = this.getVerticesCount(); - for (var i=0; i0) { - resultHedgesArray.push(hedge); + renderTexture = true; + } + else { renderTexture = false; } + + if (magoManager.magoPolicy.getObjectMoveMode() === CODE.moveMode.ALL && magoManager.buildingSelected === this) + { + // active stencil buffer to draw silhouette. + magoManager.renderer.enableStencilBuffer(gl); } } - return resultHedgesArray; -}; - -Face.prototype.getHalfEdgesLoop = function(resultHedgesArray) -{ - if (this.hEdge === undefined) - { return resultHedgesArray; } + //else if (renderType === 2) // No need to do any function. - resultHedgesArray = HalfEdge.getHalfEdgesLoop(this.hEdge, resultHedgesArray); - return resultHedgesArray; -}; - -Face.prototype.setTwinFace = function(face) -{ - if (face === undefined) - { return false; } + // set the currentObjectsRendering. + magoManager.renderer.currentObjectsRendering.curBuilding = this; - if (this.hEdge === undefined || face.hEdge === undefined) - { return false; } + var lowestOctree; + var refMatrixIdxKey = 0; + var isInterior = false; // old var. - var hedgesArray = face.getHalfEdgesLoop(undefined); - var hedgesCount = hedgesArray.length; - var hedge; - var twined = false; - for (var i=0; i= 1.0) + { + this.isAdult = true; + } + } + else + { return 1.0; } - var hedge = new HalfEdge(); - this.hEdgesArray.push(hedge); - return hedge; + return this.blendAlpha; }; -HalfEdgesList.prototype.addHalfEdgesArray = function(hEdgesArray) -{ - if (hEdgesArray === undefined) - { return; } - - if (this.hEdgesArray === undefined) - { this.hEdgesArray = []; } - - Array.prototype.push.apply(this.hEdgesArray, hEdgesArray); -}; -'use strict'; /** -* 어떤 일을 하고 있습니까? -* @class IndexData -*/ -var IndexData = function() + * _originalMatrix4와 파라미터로 받은 matrix를 4차원 행렬의 곱셈을 계산한 결과를 _matrix4에 할당 + * + * @param {Matrix4} matrix + */ +NeoReference.prototype.multiplyTransformMatrix = function(matrix) { - if (!(this instanceof IndexData)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - this.owner; - this.idx; + this._matrix4 = this._originalMatrix4.getMultipliedByMatrix(matrix); // Original. }; -'use strict'; /** * 어떤 일을 하고 있습니까? - * @class IndexRange */ -var IndexRange = function() +NeoReference.prototype.multiplyKeyTransformMatrix = function(idxKey, matrix) { - if (!(this instanceof IndexRange)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - this.strIdx; - this.endIdx; -}; + // this function multiplies the originalMatrix by "matrix" and stores it in the "idxKey" position. + if (this.tMatrixAuxArray === undefined) + { this.tMatrixAuxArray = []; } -IndexRange.prototype.copyFrom = function(indexRange) -{ - if (indexRange === undefined) - { return; } + this.tMatrixAuxArray[idxKey] = this._originalMatrix4.getMultipliedByMatrix(matrix, this.tMatrixAuxArray[idxKey]); - this.strIdx = indexRange.strIdx; - this.endIdx = indexRange.endIdx; + if (this.moveVectorRelToBuilding) + { + this.moveVector = matrix.rotatePoint3D(this.moveVectorRelToBuilding, this.moveVector); + } }; -'use strict'; /** - * 선 - * @class Line + * 어떤 일을 하고 있습니까? */ -var Line = function() +NeoReference.prototype.hasKeyMatrix = function(idxKey) { - if (!(this instanceof Line)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - // (x,y,z) = (x0,y0,z0) + lambda * (u, v, w); - this.point = new Point3D(); - this.direction = new Point3D(); + if (this.tMatrixAuxArray === undefined) + { return false; } + + if (this.tMatrixAuxArray[idxKey] === undefined) + { return false; } + else + { return true; } }; -/** +/**{Boolean} * 어떤 일을 하고 있습니까? - * @param px 변수 - * @param py 변수 - * @param pz 변수 - * @param dx 변수 - * @param dy 변수 - * @param dz 변수 + * + * @returns {Boolean} returns if the neoReference is ready to render. */ -Line.prototype.setPointAndDir = function(px, py, pz, dx, dy, dz) +NeoReference.prototype.isReadyToRender = function() { - this.point.set(px, py, pz); - this.direction.set(dx, dy, dz); - this.direction.unitary(); + if (this.tMatrixAuxArray === undefined) + { + //this.multiplyKeyTransformMatrix(refMatrixIdxKey, neoBuilding.geoLocationDataAux.rotMatrix); + // we must collect all the neoReferences that has no tMatrixAuxArray and make it. + return false; + } + + return true; }; /** - * 어떤 일을 하고 있습니까? - * @param px 변수 + * Renders the content. */ -Line.prototype.getProjectedPoint = function(point, projectedPoint) +NeoReference.prototype.solveReferenceColorOrTexture = function(magoManager, neoBuilding, shader, currentObjectsRendering) { - if (projectedPoint === undefined) - { projectedPoint = new Point3D(); } + var gl = magoManager.sceneState.gl; - var plane = new Plane(); - plane.setPointAndNormal(point.x, point.y, point.z, this.direction.x, this.direction.y, this.direction.z); - projectedPoint = plane.intersectionLine(this, projectedPoint); + // Check if we are under a selected data structure. + var selectionManager = magoManager.selectionManager; + var referenceObjectIsSelected = false; + if (selectionManager.parentSelected && magoManager.objectSelected === this) + { + referenceObjectIsSelected = true; + + if (magoManager.magoPolicy.getObjectMoveMode() === CODE.moveMode.OBJECT) + { + // Active stencil if the object is selected. + magoManager.renderer.enableStencilBuffer(gl); + } + } - return projectedPoint; + // Check the color or texture of reference object. + if (neoBuilding.isHighLighted) + { + gl.uniform1i(shader.colorType_loc, 0); // 0= oneColor, 1= attribColor, 2= texture. + gl.uniform4fv(shader.oneColor4_loc, magoManager.highLightColor4); + } + else if (neoBuilding.isColorChanged) + { + gl.uniform1i(shader.colorType_loc, 0); // 0= oneColor, 1= attribColor, 2= texture. + if (referenceObjectIsSelected) + { + gl.uniform4fv(shader.oneColor4_loc, [255.0/255.0, 0/255.0, 0/255.0, 255.0/255.0]); + } + else + { + gl.uniform4fv(shader.oneColor4_loc, [neoBuilding.aditionalColor.r, neoBuilding.aditionalColor.g, neoBuilding.aditionalColor.b, neoBuilding.aditionalColor.a] ); + } + } + else if (this.aditionalColor) + { + gl.uniform1i(shader.colorType_loc, 0); // 0= oneColor, 1= attribColor, 2= texture. + if (referenceObjectIsSelected) + { + gl.uniform4fv(shader.oneColor4_loc, [255.0/255.0, 0/255.0, 0/255.0, 255.0/255.0]); + } + else + { + gl.uniform4fv(shader.oneColor4_loc, [this.aditionalColor.r, this.aditionalColor.g, this.aditionalColor.b, this.aditionalColor.a] ); + } + } + else + { + // Normal rendering. + if (magoManager.magoPolicy.getObjectMoveMode() === CODE.moveMode.OBJECT && referenceObjectIsSelected) + { + gl.uniform1i(shader.colorType_loc, 0); // 0= oneColor, 1= attribColor, 2= texture. + gl.uniform4fv(shader.oneColor4_loc, [255.0/255.0, 0/255.0, 0/255.0, 255.0/255.0]); + } + else if (magoManager.magoPolicy.colorChangedObjectId === this.objectId) + { + gl.uniform1i(shader.colorType_loc, 0); // 0= oneColor, 1= attribColor, 2= texture. + gl.uniform4fv(shader.oneColor4_loc, [magoManager.magoPolicy.color[0], magoManager.magoPolicy.color[1], magoManager.magoPolicy.color[2], 1.0]); + } + else + { + if (this.hasTexture) + { + if (this.texture !== undefined && this.texture.texId !== undefined) + { + gl.uniform1i(shader.colorType_loc, 2); // 0= oneColor, 1= attribColor, 2= texture. + if (shader.last_tex_id !== this.texture.texId) + { + gl.bindTexture(gl.TEXTURE_2D, this.texture.texId); + shader.last_tex_id = this.texture.texId; + } + } + else + { + gl.uniform1i(shader.colorType_loc, 0); // 0= oneColor, 1= attribColor, 2= texture. + gl.uniform4fv(shader.oneColor4_loc, [0.8, 0.0, 0.8, 1.0]); + } + } + else + { + // if no render texture, then use a color. + gl.uniform1i(shader.bUse1Color_loc, true); //. + if (this.color4) + { + gl.uniform1i(shader.colorType_loc, 0); // 0= oneColor, 1= attribColor, 2= texture. + gl.uniform4fv(shader.oneColor4_loc, [this.color4.r/255.0, this.color4.g/255.0, this.color4.b/255.0, this.color4.a/255.0]); + } + else + { + gl.uniform1i(shader.colorType_loc, 0); // 0= oneColor, 1= attribColor, 2= texture. + gl.uniform4fv(shader.oneColor4_loc, [0.8, 0.8, 0.8, 1.0]); + } + } + } + } }; /** * 어떤 일을 하고 있습니까? - * @param px 변수 + * + * @param mag{Boolean} + * @returns {Boolean} returns if the neoReference was rendered. */ -Line.prototype.isCoincidentPoint = function(point, error) +NeoReference.prototype.render = function(magoManager, neoBuilding, renderType, renderTexture, shader, refMatrixIdxKey, minSizeToRender) { - if (point === undefined) + var neoReference = this; + + if (!neoReference.isReadyToRender()) { return false; } + + // Check if the texture is loaded. + //if (neoReference.texture !== undefined || neoReference.materialId != -1) + if (neoReference.hasTexture)// && neoReference.texture !== undefined) + { + // note: in the future use only "neoReference.materialId". + var texFileLoadState = neoBuilding.manageNeoReferenceTexture(neoReference, magoManager); + if (texFileLoadState !== CODE.fileLoadState.LOADING_FINISHED) + { return false; } - var projectedPoint = this.getProjectedPoint(point); + if (neoReference.texture === undefined) + { return false; } - if (projectedPoint === undefined) - { return false; } + if (neoReference.texture.texId === undefined) + { return false; } + } - if (error === undefined) - { error = 10E-8; } + var currentObjectsRendering = magoManager.renderer.currentObjectsRendering; + var selectionManager; + var selectionColor; + var currentNode; + var currentOctree; - var squaredDist = projectedPoint.squareDistToPoint(point); + if (renderType === 2) + { + selectionManager = magoManager.selectionManager; + selectionColor = magoManager.selectionColor; + renderTexture = false; // reassign value for this var. + currentNode = currentObjectsRendering.curNode; + currentOctree = currentObjectsRendering.curOctree; + } - if (squaredDist < error*error) - { return true; } + var gl = magoManager.sceneState.gl; - return false; -}; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + var block_idx = neoReference._block_idx; + var block = neoBuilding.motherBlocksArray[block_idx]; + + if (block === undefined) + { return false; } + + if (magoManager.mouseLeftDown || magoManager.mouseMiddleDown) + { minSizeToRender = 0.5; } + + if (!block.isReadyToRender(neoReference, magoManager, minSizeToRender)) + { return false; } + // Check the color or texture of reference object. + if (renderType === 1) + { + neoReference.solveReferenceColorOrTexture(magoManager, neoBuilding, shader, currentObjectsRendering); + } + else if (renderType === 2) + { + neoReference.selColor4 = selectionColor.getAvailableColor(neoReference.selColor4); + var idxKey = selectionColor.decodeColor3(neoReference.selColor4.r, neoReference.selColor4.g, neoReference.selColor4.b); + selectionManager.setCandidates(idxKey, neoReference, currentOctree, neoBuilding, currentNode); + if (neoReference.selColor4) + { + gl.uniform4fv(shader.oneColor4_loc, [neoReference.selColor4.r/255.0, neoReference.selColor4.g/255.0, neoReference.selColor4.b/255.0, 1.0]); + } + } + // End check color or texture of reference object.----------------------------------------------------------------------------- + + //Now erase the aditional information (aditionalColor & moveVector). + this.aditionalColor = undefined; + + // Test external alpha. + if (magoManager.isTrailRender === undefined || magoManager.isTrailRender === false) // check if mago is not rendering special effects. + { + var blendAlpha = neoReference.getBlendAlpha(magoManager.currTime); + gl.uniform1f(shader.externalAlpha_loc, blendAlpha); + } + + // End test.--- + + var cacheKeys_count = block.vBOVertexIdxCacheKeysContainer.vboCacheKeysArray.length; + // Must applicate the transformMatrix of the reference object. + gl.uniform1i(shader.refMatrixType_loc, neoReference.refMatrixType); + if (neoReference.refMatrixType === 1) + { gl.uniform3fv(shader.refTranslationVec_loc, neoReference.refTranslationVec); } + else if (neoReference.refMatrixType === 2) + { gl.uniformMatrix4fv(shader.refMatrix_loc, false, neoReference.tMatrixAuxArray[refMatrixIdxKey]._floatArrays); } + + if (neoReference.moveVector !== undefined) + { + gl.uniform1i(shader.hasAditionalMov_loc, true); + gl.uniform3fv(shader.aditionalMov_loc, [neoReference.moveVector.x, neoReference.moveVector.y, neoReference.moveVector.z]); //. + shader.last_isAditionalMovedZero = false; + } + else + { + if (!shader.last_isAditionalMovedZero) + { + gl.uniform1i(shader.hasAditionalMov_loc, false); + gl.uniform3fv(shader.aditionalMov_loc, [0.0, 0.0, 0.0]); //. + shader.last_isAditionalMovedZero = true; + } + } + + var vboKey; + for (var n=0; n vboKey.indicesCount) + { indicesCount = vboKey.indicesCount; } + } + else + { + indicesCount = vboKey.indicesCount; + } + } + if (!vboKey.bindDataIndice(shader, magoManager.vboMemoryManager)) + { return false; } + gl.drawElements(gl.TRIANGLES, indicesCount, gl.UNSIGNED_SHORT, 0); // Fill. + } + + return true; +}; +/** + * 어떤 일을 하고 있습니까? + */ +NeoReference.prototype.deleteObjects = function(gl, vboMemManager) +{ + // 1) Object ID. + this._id = undefined; + // 2) Block Idx. + this._block_idx = undefined; + // 3) Transformation Matrix. + this._matrix4._floatArrays = undefined; + this._matrix4 = undefined; + this._originalMatrix4._floatArrays = undefined; + this._originalMatrix4 = undefined; // + // 5) The texture image. + this.hasTexture = undefined; + // no delete the texture, only break the referencing. + this.texture = undefined; // Texture + // 6) 1 color. + if (this.color4) + { this.color4.deleteObjects(); } + this.color4 = undefined; //new Color(); + // 7) selection color. + if (this.selColor4) + { this.selColor4.deleteObjects(); } + this.selColor4 = undefined; //new Color(); // use for selection only. + // 8) movement of the object. + if (this.moveVector) + { this.moveVector.deleteObjects(); } + this.moveVector = undefined; // Point3D. + this.bRendered = undefined; + + if (this.vBOVertexIdxCacheKeysContainer !== undefined) + { + this.vBOVertexIdxCacheKeysContainer.deleteGlObjects(gl, vboMemManager); + this.vBOVertexIdxCacheKeysContainer = undefined; + } +}; 'use strict'; /** - * 선 - * @class Line2D + * 어떤 일을 하고 있습니까? + * @class NeoReferencesMotherAndIndices */ -var Line2D = function() +var NeoReferencesMotherAndIndices = function() { - if (!(this instanceof Line2D)) + if (!(this instanceof NeoReferencesMotherAndIndices)) { throw new Error(Messages.CONSTRUCT_ERROR); } + + this.motherNeoRefsList; // this is a NeoReferencesList pointer. + this.neoRefsIndices = []; // All objects(references) of this class. + this.modelReferencedGroupsList; // (for new format. No used yet). + this.blocksList; + + this.fileLoadState = 0; // init as "READY". + this.dataArraybuffer; + this.succesfullyGpuDataBinded; + + this.exterior_ocCullOctree; // octree that contains the visible indices. + this.interior_ocCullOctree; // octree that contains the visible indices. - // (x,y) = (x0,y0) + lambda * (u, v); - this.point = new Point2D(); - this.direction = new Point2D(); + this.currentVisibleIndices = []; + this.currentVisibleMRG; // MRG = ModelReferencedGroup (for new format). + this.xhr; }; /** * 어떤 일을 하고 있습니까? - * @param px 변수 - * @param py 변수 - * @param dx 변수 - * @param dy 변수 + * @param matrix 변수 */ -Line2D.prototype.setPointAndDir = function(px, py, dx, dy) +NeoReferencesMotherAndIndices.prototype.multiplyKeyTransformMatrix = function(idxKey, matrix) { - this.point.set(px, py); - this.direction.set(dx, dy); - this.direction.unitary(); + var refIndicesCount = this.neoRefsIndices.length; + for (var i=0; i 0) + { thisHasOcCullData = true; } - if (point) - { perpendicular.point.set(point.x, point.y); } - else - { perpendicular.point.set(this.point.x, this.point.y); } + if (thisHasOcCullData && applyOcclusionCulling) + { + //if (this.currentVisibleMRG === undefined) + //{ this.currentVisibleMRG = new ModelReferencedGroupsList(); } + + var intersectedSubBox = this.interior_ocCullOctree.getIntersectedSubBoxByPoint3D(eye_x, eye_y, eye_z); + if (intersectedSubBox !== undefined && intersectedSubBox._indicesArray.length > 0) + { + this.currentVisibleIndices = intersectedSubBox._indicesArray; + //if (result_modelReferencedGroup) + //{ + // result_modelReferencedGroup = this.modelReferencedGroupsList; + //} + isExterior = false; + } + else + { + isExterior = true; + } + } + else + { + // In this case there are no occlusionCulling data. + this.currentVisibleIndices = this.neoRefsIndices; + this.currentVisibleMRG = this.modelReferencedGroupsList; + } + } - perpendicular.direction.set(this.direction.y, -this.direction.x); - return perpendicular; + if (isExterior) + { + if (this.exterior_ocCullOctree !== undefined) + { + var thisHasOcCullData = false; + if (this.exterior_ocCullOctree._subBoxesArray && this.exterior_ocCullOctree._subBoxesArray.length > 0) + { thisHasOcCullData = true; } + + if (thisHasOcCullData && applyOcclusionCulling) + { + if (this.currentVisibleMRG === undefined) + { this.currentVisibleMRG = new ModelReferencedGroupsList(); } + + this.currentVisibleIndices = this.exterior_ocCullOctree.getIndicesVisiblesForEye(eye_x, eye_y, eye_z, this.currentVisibleIndices, this.currentVisibleMRG); + } + else + { + // In this case there are no occlusionCulling data. + this.currentVisibleIndices = this.neoRefsIndices; + this.currentVisibleMRG = this.modelReferencedGroupsList; + } + } + } }; /** - * 어떤 일을 하고 있습니까? - * @param px 변수 + * Returns the neoReference + * @param matrix 변수 */ -Line2D.prototype.getPerpendicularLeft = function(point) +NeoReferencesMotherAndIndices.prototype.getNeoReference = function(idx) { - var perpendicular = new Line2D(); - - if (point) - { perpendicular.point.set(point.x, point.y); } - else - { perpendicular.point.set(this.point.x, this.point.y); } - - perpendicular.direction.set(-this.direction.y, this.direction.x); - return perpendicular; + return this.motherNeoRefsList[this.neoRefsIndices[idx]]; }; /** * 어떤 일을 하고 있습니까? - * @param px 변수 + * @param treeDepth 변수 */ -Line2D.prototype.getProjectedPoint = function(point, projectedPoint) +NeoReferencesMotherAndIndices.prototype.deleteObjects = function(gl, vboMemManager) { - if (point === undefined) - { return undefined; } - - if (projectedPoint === undefined) - { projectedPoint = new Point2D(); } + if (this.xhr !== undefined) + { + this.xhr.abort(); + this.xhr = undefined; + } - var perpendicular = this.getPerpendicularLeft(point); - projectedPoint = this.intersectionWithLine(perpendicular, projectedPoint); + this.motherNeoRefsList = undefined; // this is a NeoReferencesList pointer. + this.neoRefsIndices = undefined; - return projectedPoint; + if (this.blocksList !== undefined && this.blocksList.xhr !== undefined && this.fileLoadState !== CODE.fileLoadState.READY) + { + this.blocksList.xhr.abort(); + this.blocksList.xhr = undefined; + } + this.blocksList = undefined; + + this.fileLoadState = undefined; + this.dataArraybuffer = undefined; + + this.exterior_ocCullOctree = undefined; + this.interior_ocCullOctree = undefined; }; /** * 어떤 일을 하고 있습니까? - * @param px 변수 + * @returns {Boolean} returns if the neoReferencesMotherAndIndices is ready to render. */ -Line2D.prototype.isCoincidentPoint = function(point, error) +NeoReferencesMotherAndIndices.prototype.isReadyToRender = function() { - if (point === undefined) + if (this.neoRefsIndices === undefined || this.neoRefsIndices.length === 0) { return false; } - - if (error === undefined) - { error = 10E-8; } - - var projectedPoint = this.getProjectedPoint(point, projectedPoint); - var squaredDist = point.squareDistToPoint(projectedPoint); - - if (squaredDist < error*error) - { return true; } - return false; + if (this.blocksList === undefined) + { return false; } + + if (this.blocksList.fileLoadState !== CODE.fileLoadState.PARSE_FINISHED) + { return false; } + + return true; }; /** * 어떤 일을 하고 있습니까? - * @param px 변수 + * @param treeDepth 변수 */ -Line2D.prototype.isParallelToLine = function(line) +NeoReferencesMotherAndIndices.prototype.setRenderedFalseToAllReferences = function() { - if (line === undefined) - { return false; } - - var zero = 10E-10; - var angRad = this.direction.angleRadToVector(line.direction); - - // if angle is zero or 180 degree, then this is parallel to "line".*** - if (angRad < zero || Math.abs(angRad - Math.PI) < zero) - { return true; } - - return false; + var refIndicesCount = this.neoRefsIndices.length; + for (var i=0; i 0) + { + if (neoRef.vBOVertexIdxCacheKeysContainer === undefined) + { neoRef.vBOVertexIdxCacheKeysContainer = new VBOVertexIdxCacheKeysContainer(); } + } + + for (var j=0; j 0) + { + // Now, read the texture_type and texture_file_name. + var texture_type_nameLegth = readWriter.readUInt32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; + for (var j=0; j 0) + { + if (neoRef.vBOVertexIdxCacheKeysContainer === undefined) + { neoRef.vBOVertexIdxCacheKeysContainer = new VBOVertexIdxCacheKeysContainer(); } + } + + for (var j=0; j 0) + { + var textureTypeName = ""; + var textureImageFileName = ""; + // Now, read the texture_type and texture_file_name. + var texture_type_nameLegth = readWriter.readUInt32(arrayBuffer, bytes_readed, bytes_readed+4); bytes_readed += 4; + for (var j=0; j 0) + { + neoRef.texture = new Texture(); + neoRef.hasTexture = true; + neoRef.texture.textureTypeName = textureTypeName; + neoRef.texture.textureImageFileName = textureImageFileName; + } + /* + // 1pixel texture, wait for texture to load.** + if(neoRef.texture.texId === undefined) + neoRef.texture.texId = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, neoRef.texture.texId); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([90, 80, 85, 255])); // red + gl.bindTexture(gl.TEXTURE_2D, null); + */ + } + else + { + neoRef.hasTexture = false; + } + if (tMatrix4) + { + neoRef.multiplyTransformMatrix(tMatrix4); + } + } + } + + //this.createModelReferencedGroups(); // test for new format. + + // Now occlusion cullings. + // Occlusion culling octree data.** + if (this.exterior_ocCullOctree === undefined) + { this.exterior_ocCullOctree = new OcclusionCullingOctreeCell(); } + var infiniteOcCullBox = this.exterior_ocCullOctree; + //bytes_readed = this.readOcclusionCullingOctreeCell(arrayBuffer, bytes_readed, infiniteOcCullBox); // old. + bytes_readed = this.exterior_ocCullOctree.parseArrayBuffer(arrayBuffer, bytes_readed, readWriter); + infiniteOcCullBox.expandBox(1000); // Only for the infinite box. + infiniteOcCullBox.setSizesSubBoxes(); + infiniteOcCullBox.createModelReferencedGroups(this.motherNeoRefsList); + if (this.interior_ocCullOctree === undefined) + { this.interior_ocCullOctree = new OcclusionCullingOctreeCell(); } + var ocCullBox = this.interior_ocCullOctree; + //bytes_readed = this.readOcclusionCullingOctreeCell(arrayBuffer, bytes_readed, ocCullBox); // old. + bytes_readed = this.interior_ocCullOctree.parseArrayBuffer(arrayBuffer, bytes_readed, readWriter); + ocCullBox.setSizesSubBoxes(); + ocCullBox.createModelReferencedGroups(this.motherNeoRefsList); + this.fileLoadState = CODE.fileLoadState.PARSE_FINISHED; + return this.succesfullyGpuDataBinded; +}; +/** + * Renders the content. + */ +NeoReferencesMotherAndIndices.prototype.render = function(magoManager, neoBuilding, renderType, renderTexture, shader, maxSizeToRender, refMatrixIdxKey) +{ + var allRendered = true; + + if (!this.isReadyToRender()) + { return false; } + + if (renderType === 2) + { + renderTexture = false; // reassign value for this var. + } + + var gl = magoManager.sceneState.gl; + + if (renderType === 2) + { + shader.disableVertexAttribArray(shader.texCoord2_loc); + shader.disableVertexAttribArray(shader.normal3_loc); + } + if (renderType === 0) + { + shader.disableVertexAttribArray(shader.texCoord2_loc); + shader.disableVertexAttribArray(shader.normal3_loc); + shader.disableVertexAttribArray(shader.color4_loc); + } + + if (renderTexture) + { + gl.activeTexture(gl.TEXTURE2); // ... + if (renderType === 1) + { + gl.uniform1i(shader.colorType_loc, 2); // 0= oneColor, 1= attribColor, 2= texture. + } + } + var texturesManager = magoManager.texturesManager; + var textureAux1x1 = texturesManager.getTextureAux1x1(); + gl.bindTexture(gl.TEXTURE_2D, textureAux1x1); + shader.last_tex_id = textureAux1x1; + // New version. Use occlussion indices. + //var visibleIndices_count = this.neoRefsIndices.length; // no occludeCulling mode. + var visibleIndices_count = this.currentVisibleIndices.length; + var noRenderedsCount = 0; + for (var k=0; k 20000) - { - deltaA = camHeght*camHeght * 0.000000001; - deltaB = camHeght * 0.01; - } - if (camHeght > 16000) - { - deltaA = camHeght*camHeght * 0.000000001; - deltaB = camHeght * 0.001; - } - else if (camHeght > 14000) + var isReference = false; + if (this.data !== undefined) { - deltaA = camHeght*camHeght * 0.000000001; - deltaB = camHeght * 0.001; - } - else if (camHeght > 10000) - { - deltaA = camHeght*camHeght * 0.0000000001; - deltaB = camHeght * 0.0001; - } - else if (camHeght > 6000) - { - deltaA = camHeght*camHeght * 0.00000000001; - deltaB = camHeght * 0.0000001; - } - else - { - deltaA = camHeght*camHeght * 0.00000000001; - deltaB = camHeght * 0.00000001; + var attributes = this.data.attributes; + if (attributes !== undefined) + { + if (attributes.isReference !== undefined) + { isReference = attributes.isReference; } + } } - delta *= deltaA + deltaB + 1; - camPos.add(camDir.x * delta, camDir.y * delta, camDir.z * delta); - this.updateModelViewMatrixByCamera(camera); + return isReference; }; -MagoWorld.prototype.mousemove = function(event) +/** + * Deletes all datas and all datas of children. + */ +Node.prototype.deleteObjects = function(gl, vboMemoryManager) { - var mouseAction = this.magoManager.sceneState.mouseAction; - if (this.magoManager.sceneState.mouseButton === 0) + this.parent = undefined; + var data = this.data; + if (data !== undefined) { - // left button pressed.*** - var gl = this.magoManager.sceneState.gl; - var sceneState = this.magoManager.sceneState; - var curCamera = mouseAction.curCamera; - var camera = this.magoManager.sceneState.camera; + // Check if this is a reference node. + var isReference = this.isReferenceNode(); - // now, calculate the angle and the rotationAxis.*** - var curWorldPoint = mouseAction.curWorldPoint; - var currEarthRadius = curWorldPoint.getModul(); - var nowX = event.clientX; - var nowY = event.clientY; - if (nowX === mouseAction.curX && nowY === mouseAction.curY) + // No delete neoBuilding if this node is a reference node. + if (isReference) { return; } - - var nowPoint; - var camRay, camRayCamCoord; - - camRayCamCoord = this.magoManager.getRayCamSpace(nowX, nowY, camRayCamCoord); - - // now calculate rayWorldCoord.*** - if (this.pointSC === undefined) - { this.pointSC = new Point3D(); } - - this.pointSC.set(camRayCamCoord[0], camRayCamCoord[1], camRayCamCoord[2]); - // now, must transform this posCamCoord to world coord.*** - var mv_inv = mouseAction.curModelViewMatrixInv; - this.pointSC2 = mv_inv.rotatePoint3D(this.pointSC, this.pointSC2); // rayWorldSpace.*** - this.pointSC2.unitary(); // rayWorldSpace.*** - camRay = new Line(); - camRay.setPointAndDir(curCamera.position.x, curCamera.position.y, curCamera.position.z, this.pointSC2.x, this.pointSC2.y, this.pointSC2.z);// original.*** - // end calculate camRayWorldCoord.--------------- - - var nowWorldPoint; - nowWorldPoint = this.magoManager.globe.intersectionLineWgs84(camRay, nowWorldPoint, currEarthRadius); - - if (nowWorldPoint === undefined) + if (data.neoBuilding) { - return; + data.neoBuilding.deleteObjects(gl, vboMemoryManager); + data.neoBuilding = undefined; } - - var curPoint = new Point3D(curWorldPoint.x, curWorldPoint.y, curWorldPoint.z); - var nowPoint = new Point3D(nowWorldPoint[0], nowWorldPoint[1], nowWorldPoint[2]); - - var rotAxis; - rotAxis = curPoint.crossProduct(nowPoint, rotAxis); - rotAxis.unitary(); - if (rotAxis.isNAN()) - { return; } - - var angRad = curPoint.angleRadToVector(nowPoint); - if (angRad === 0 || isNaN(angRad)) - { return; } - // recalculate position and direction of the camera.*** + if (data.geographicCoord) + { + data.geographicCoord.deleteObjects(); + data.geographicCoord = undefined; + } - camera.copyPosDirUpFrom(curCamera); + if (data.rotationsDegree) + { + data.rotationsDegree.deleteObjects(); + data.rotationsDegree = undefined; + } - var matAux = mat4.create(); // create as identity.*** - matAux = mat4.rotate( matAux, matAux, -angRad, [rotAxis.x, rotAxis.y, rotAxis.z] ); - camera.transformByMatrix4(matAux); + if (data.bbox) + { + data.bbox.deleteObjects(); + data.bbox = undefined; + } - this.updateModelViewMatrixByCamera(camera); + // Delete geoLocationDataManager, etc. TODO. + this.data = undefined; } - else if (this.magoManager.sceneState.mouseButton === 1) + + if (this.children) { - // middle button pressed.*** - var curCamera = mouseAction.curCamera; - var camera = this.magoManager.sceneState.camera; - camera.copyPosDirUpFrom(curCamera); - var camPos = camera.position; - var camDir = camera.direction; - var camUp = camera.up; - - // 1rst, determine the point of rotation.*** - var rotPoint = mouseAction.curWorldPoint; - - // now determine the rotation axis.*** - // the rotation axis are the camRight & normalToSurface.*** - if (this.magoManager.globe === undefined) - { this.magoManager.globe = new Globe(); } - - var pivotPointNormal; - pivotPointNormal = this.magoManager.globe.normalAtCartesianPointWgs84(rotPoint.x, rotPoint.y, rotPoint.z, pivotPointNormal); - - var xAxis = camera.getCameraRight(); - - // now determine camZRot & camXRot angles.*** - var nowX = event.clientX; - var nowY = event.clientY; - var increX = nowX - mouseAction.curX; - var increY = nowY - mouseAction.curY; - - var zRotAngRad = increX * 0.003; - var xRotAngRad = increY * 0.003; - - if (zRotAngRad === 0 && xRotAngRad == 0) - { return; } - - if (this.rotMatX === undefined) - { this.rotMatX = mat4.create(); } - - if (this.rotMatZ === undefined) - { this.rotMatZ = mat4.create(); } - - if (this.rotMat === undefined) - { this.rotMat = mat4.create(); } - - this.rotMatX = mat4.identity(this.rotMatX); - this.rotMatZ = mat4.identity(this.rotMatZ); - this.rotMat = mat4.identity(this.rotMat); - - //ManagerUtils.calculateSplited3fv = function(point3fv, resultSplitPoint3fvHigh, resultSplitPoint3fvLow) - - this.rotMatX = mat4.fromRotation(this.rotMatX, -xRotAngRad, [xAxis.x, xAxis.y, xAxis.z]); - this.rotMatZ = mat4.fromRotation(this.rotMatZ, -zRotAngRad, pivotPointNormal); - this.rotMat = mat4.multiply(this.rotMat, this.rotMatZ, this.rotMatX); - var translateMat_1 = mat4.create(); - var translateMat_2 = mat4.create(); - translateMat_1 = mat4.fromTranslation(translateMat_1, [-rotPoint.x, -rotPoint.y, -rotPoint.z]); - translateMat_2 = mat4.fromTranslation(translateMat_2, [rotPoint.x, rotPoint.y, rotPoint.z]); - - var totalMatPrev = mat4.create(); - totalMatPrev = mat4.multiply(totalMatPrev, translateMat_2, this.rotMat); - - var totalMat = mat4.create(); - totalMat = mat4.multiply(totalMat, totalMatPrev, translateMat_2); - - camera.transformByMatrix4(translateMat_1); - camera.transformByMatrix4(this.rotMat); - camera.transformByMatrix4(translateMat_2); - - this.updateModelViewMatrixByCamera(camera); + var childrenCount = this.children.length; + for (var i=0; i depth render. + // renderType = 1 -> normal render. + // renderType = 2 -> colorSelection render. + //-------------------------------------------- + var data = this.data; + if (data === undefined) + { return; } - return this.surfacesArray.length; -}; + var neoBuilding = this.data.neoBuilding; + if (neoBuilding === undefined) + { return; } -Mesh.prototype.getCopySurfaceIndependentMesh = function(resultMesh) -{ - // In a surfaceIndependentMesh, the surfaces are disconex.*** - if (resultMesh === undefined) - { resultMesh = new Mesh(); } + // Check if we are under selected data structure.*** + var selectionManager = magoManager.selectionManager; + if (magoManager.nodeSelected === this) + { selectionManager.parentSelected = true; } + else + { selectionManager.parentSelected = false; } - var surface, surfaceCopy; - var surfacesCount = this.getSurfacesCount(); - for (var i=0; i0; i--) + for (var i=1; i 1) + { geoLocDataIdx = 1; } + else + { geoLocDataIdx = 0; } + var buildingGeoLocation = geoLocDataManager.getGeoLocationData(geoLocDataIdx); + buildingGeoLocation.bindGeoLocationUniforms(gl, shader); -/** - * 어떤 일을 하고 있습니까? - * @param idx 변수 - * @returns vertexArray[idx] - */ -Mesh.prototype.getNoRepeatedVerticesArray = function(resultVerticesArray) -{ - if (resultVerticesArray === undefined) - { resultVerticesArray = []; } + // magoManager.tempSettings.renderWithTopology === 0 -> render only Building. + // magoManager.tempSettings.renderWithTopology === 1 -> render only Topology. + // magoManager.tempSettings.renderWithTopology === 2 -> render both. + + // If this node is a referenceNode type, then, must render all references avoiding the renderingFase. + gl.uniform1f(shader.externalAlpha_loc, 1.0); + neoBuilding.currentLod = data.currentLod; // update currentLod. + neoBuilding.render(magoManager, shader, renderType, refMatrixIdxKey, flipYTexCoord, data.currentLod); - // 1rst, assign vertex-IdxInList for all used vertices.*** - var facesCount; - var face; - var surface; - var idxAux = 0; - var vtx; - var verticesCount; - var surfacesCount = this.getSurfacesCount(); - for (var i=0; i 1) + { geoLocDataManager.popGeoLocationData(); } + else + { + this.data.animationData = undefined; + } + } + + // Test. + /* + if (neoBuilding.network) + { + if(magoManager.tempSettings.renderWithTopology === 0 || magoManager.tempSettings.renderWithTopology === 2) { - face = surface.getFace(j); - verticesCount = face.getVerticesCount(); - for (var k=0; k 0) + return true; + } + var geoLocationData = geoLocDatamanager.getCurrentGeoLocationData(); + if (geoLocationData === undefined) { - resultTrianglesListsArray = this.getTrianglesListsArrayBy2ByteSize(rejectedTrianglesArray, resultTrianglesListsArray); + return true; } - - return resultTrianglesListsArray; -}; - -Mesh.prototype.getVbo = function(resultVboContainer) -{ - if (resultVboContainer === undefined) - { resultVboContainer = new VBOVertexIdxCacheKeysContainer(); } + var geographicCoord = geoLocationData.geographicCoord; - // make global triangles array.*** - var trianglesArray = this.getTrianglesConvex(undefined); - var trianglesCount = trianglesArray.length; - - // If vertices count > shortSize(65535), then must split the mesh.*** - var trianglesListsArray = this.getTrianglesListsArrayBy2ByteSize(trianglesArray, undefined); - var trianglesList; - var verticesArray; - var trianglesListsCount = trianglesListsArray.length; - for (var i=0; i animData.durationInSeconds) { - trianglesList = trianglesListsArray[i]; - verticesArray = trianglesList.getNoRepeatedVerticesArray(undefined); - var vbo = resultVboContainer.newVBOVertexIdxCacheKey(); - VertexList.setIdxInList(verticesArray); - VertexList.getVboDataArrays(verticesArray, vbo); - trianglesList.assignVerticesIdx(); - TrianglesList.getVboFaceDataArray(trianglesList.trianglesArray, vbo); + nextLongitude = animData.targetLongitude; + nextLatitude = animData.targetLatitude; + nextAltitude = animData.targetAltitude; + // finish the process. + finished = true; + this.data.animationData.finished = true; } - - return resultVboContainer; -}; - -Mesh.prototype.getVboEdges = function(resultVboContainer) -{ - // provisionally make edges by this.*** - var frontierHedgesArray = this.getFrontierHalfEdges(undefined); - var hedgesCount = frontierHedgesArray.length; - var hedge; - var vertexArray = []; - var indicesArray = []; - var strVertex, endVertex; - var index = 0; - for (var i=0; i X + // +-----+-----+ +-----+-----+ + + /** + * The octree's identifier. Accumulative number, starting from mother octree. + * @type {Number} + * @default 0 + */ + this.octree_number_name = 0; + + /** + * The octree's neoBuildingOwner identifier. + * @type {String} + * @default undefined + */ + this.neoBuildingOwnerId; + + /** + * The octree's neoBuildingOwner. + * @type {NeoBuilding} + * @default undefined + */ + this.neoBuildingOwner; + + /** + * The octree's global unique identifier. It is compost by neoBuildingOwnerId + octree_number_name. + * @type {String} + * @default undefined + */ + this.octreeKey; + + /** + * The octree's current LOD. Assigned by distance to camera when frustumCulling. + * @type {Number} + * @default undefined + */ + this.lod; + + /** + * The octree's current distance to camera. + * @type {Number} + * @default undefined + */ + this.distToCamera; + + /** + * The octree's meshes count. Readed when parsing. + * @type {Number} + * @default 0 + */ + this.triPolyhedronsCount = 0; + + /** + * The octree's current fileLoadState. + * @type {Number} + * @default 0 + */ + this.fileLoadState = CODE.fileLoadState.READY; -/** - * 포인트값 삭제 - * 어떤 일을 하고 있습니까? - */ -Point2D.prototype.setAssociated = function(associated) -{ - // aux test.*** - this.associated = associated; + /** + * The octree's children array. Array length must be 8. + * @type {Array} + * @default 0 + */ + this.subOctrees_array = []; + + /** + * The octree's meshes. The meshes of the octree are referenced by an indice. + * @type {NeoReferencesMotherAndIndices} + * @default undefined + */ + this.neoReferencesMotherAndIndices; + + /** + * Pre-extracted leaf octrees, to speedUp. + * @type {Array} + * @default undefined + */ + this.lowestOctrees_array; // pre extract lowestOctrees for speedUp, if this is motherOctree. + + /** + * Can be a mesh or poitsCloudPartition. Generally used to contain LOD2 meshes. + * @type {Lego} + * @default undefined + */ + this.lego; + + /** + * PointsCloudPartitions count. + * @type {Number} + * @default undefined + */ + this.pCloudPartitionsCount; // pointsCloud-pyramid-tree mode. + + /** + * PointsCloudPartitions. + * @type {Array} + * @default undefined + */ + this.pCloudPartitionsArray; + + // v002. + //this.blocksListsPartitionsCount; + //this.blocksListsPartitionsParsedCount; }; /** - * 포인트값 삭제 - * 어떤 일을 하고 있습니까? + * Creates a child octree. + * @returns {Octree} subOctree Returns the created child octree. */ -Point2D.prototype.getAssociated = function() +Octree.prototype.new_subOctree = function() { - // aux test.*** - return this.associated; + var subOctree = new Octree(this); + subOctree.octree_level = this.octree_level + 1; + this.subOctrees_array.push(subOctree); + return subOctree; }; /** - * 포인트값 삭제 * 어떤 일을 하고 있습니까? + * @param treeDepth 변수 */ -Point2D.prototype.copyFrom = function(point2d) +Octree.prototype.deleteObjectsModelReferences = function(gl, vboMemManager) { - this.x = point2d.x; - this.y = point2d.y; + if (this.neoReferencesMotherAndIndices) + { this.neoReferencesMotherAndIndices.deleteObjects(gl, vboMemManager); } + + this.neoReferencesMotherAndIndices = undefined; + + if (this.subOctrees_array !== undefined) + { + for (var i=0, subOctreesCount = this.subOctrees_array.length; i= 2) + { + // Must prepare skin data. + this.prepareSkinData(magoManager); } - - return coincident; }; /** * 어떤 일을 하고 있습니까? - * @param x 변수 - * @param y 변수 */ -Point2D.prototype.getVectorToPoint = function(targetPoint, resultVector) +Octree.prototype.prepareSkinData = function(magoManager) { - // this returns a vector that points to "targetPoint" from "this".*** - // the "resultVector" has the direction from "this" to "targetPoint", but is NOT normalized.*** - if (targetPoint === undefined) - { return undefined; } + if (this.octree_number_name === undefined) + { return; } - if (resultVector === undefined) - { resultVector = new Point2D(); } + if (this.lego === undefined) + { + this.lego = new Lego(); + this.lego.birthTime = magoManager.currTime; + this.lego.fileLoadState = CODE.fileLoadState.READY; + this.lego.legoKey = this.octreeKey + "_lego"; + } + + var neoBuilding = this.neoBuildingOwner; + if (neoBuilding === undefined) + { return; } - resultVector.set(targetPoint.x - this.x, targetPoint.y - this.y); + var gl = magoManager.sceneState.gl; + var geometryDataPath = magoManager.readerWriter.geometryDataPath; + var projectFolderName = neoBuilding.projectFolderName; + var buildingFolderName = neoBuilding.buildingFileName; - return resultVector; -}; + var headerVersion = neoBuilding.getHeaderVersion(); -/** - * nomal 계산 - * @param point 변수 - * @param resultPoint 변수 - * @returns resultPoint - */ -Point2D.prototype.crossProduct = function(point) -{ - return this.x * point.y - point.x * this.y; -}; + if (this.lego.fileLoadState === CODE.fileLoadState.READY) + { + // must load the legoStructure of the lowestOctree. + var subOctreeNumberName = this.octree_number_name.toString(); + var bricks_folderPath = geometryDataPath + "/" + projectFolderName + "/" + buildingFolderName + "/Bricks"; + var filePathInServer = bricks_folderPath + "/" + subOctreeNumberName + "_Brick"; -/** - * nomal 계산 - * @param point 변수 - * @param resultPoint 변수 - * @returns resultPoint - */ -Point2D.prototype.scalarProduct = function(point) -{ - var scalarProd = this.x*point.x + this.y*point.y; - return scalarProd; -}; + // finally check if there are legoSimpleBuildingTexture. + if (headerVersion[0] === "v") + { + if (this.lego.vbo_vicks_container.vboCacheKeysArray[0] && this.lego.vbo_vicks_container.vboCacheKeysArray[0].meshTexcoordsCacheKey) + { + // this is the old version. + if (neoBuilding.simpleBuilding3x3Texture === undefined) + { + neoBuilding.simpleBuilding3x3Texture = new Texture(); + var buildingFolderName = neoBuilding.buildingFileName; + var texFilePath = geometryDataPath + "/" + projectFolderName + "/" + buildingFolderName + "/SimpleBuildingTexture3x3.png"; + } + + // Direct loading. + if (neoBuilding.simpleBuilding3x3Texture !== undefined && neoBuilding.simpleBuilding3x3Texture.fileLoadState === CODE.fileLoadState.READY) + { + magoManager.readerWriter.readLegoSimpleBuildingTexture(gl, texFilePath, neoBuilding.simpleBuilding3x3Texture, magoManager); + } + + magoManager.readerWriter.getOctreeLegoArraybuffer(filePathInServer, this, magoManager); + + } + else + { + // there are no texture in this project. + magoManager.readerWriter.getOctreeLegoArraybuffer(filePathInServer, this, magoManager); + + } + } + else + { + // This is the version 001. + if (neoBuilding.simpleBuilding3x3Texture === undefined) + { + neoBuilding.simpleBuilding3x3Texture = new Texture(); + } -/** - * nomal 계산 - * @param vector 변수 - */ -Point2D.prototype.angleRadToVector = function(vector) -{ - if (vector === undefined) - { return undefined; } - - //****************************************************** - //var scalarProd = this.scalarProduct(vector); - var myModul = this.getModul(); - var vecModul = vector.getModul(); - - // calcule by cos.*** - //var cosAlfa = scalarProd / (myModul * vecModul); - //var angRad = Math.acos(cosAlfa); - //var angDeg = alfa * 180.0/Math.PI; - //------------------------------------------------------ - var error = 10E-10; - if (myModul < error || vecModul < error) - { return undefined; } - - return Math.acos(this.scalarProduct(vector) / (myModul * vecModul)); + var imageFilaName = neoBuilding.getImageFileNameForLOD(2); + var texFilePath = geometryDataPath + "/" + projectFolderName + "/" + buildingFolderName + "/" + imageFilaName; + + // Direct loading. + if (neoBuilding.simpleBuilding3x3Texture !== undefined && neoBuilding.simpleBuilding3x3Texture.fileLoadState === CODE.fileLoadState.READY) + { + magoManager.readerWriter.readLegoSimpleBuildingTexture(gl, texFilePath, neoBuilding.simpleBuilding3x3Texture, magoManager); + } + + magoManager.readerWriter.getOctreeLegoArraybuffer(filePathInServer, this, magoManager); + } + } }; /** - * nomal 계산 - * @param point 변수 - * @param resultPoint 변수 - * @returns resultPoint + * 어떤 일을 하고 있습니까? */ -Point2D.prototype.angleDegToVector = function(vector) +Octree.prototype.prepareModelReferencesListData = function(magoManager) { - if (vector === undefined) - { return undefined; } + var neoBuilding = this.neoBuildingOwner; + + // 1rst check possibles errors. + if (neoBuilding === undefined) + { return; } - var angRad = this.angleRadToVector(vector); + if (this.triPolyhedronsCount === 0) + { return; } - if (angRad === undefined) - { return undefined; } - - return angRad * 180.0/Math.PI; -}; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + if (this.octree_number_name === undefined) + { return; } -'use strict'; -/** -* 어떤 일을 하고 있습니까? -* @class Point2DList -*/ -var Point2DList = function(x, y) -{ - if (!(this instanceof Point2DList)) + // Check the version. + var version = neoBuilding.getHeaderVersion(); + if (version === "0.0.2") { - throw new Error(Messages.CONSTRUCT_ERROR); + this.prepareModelReferencesListData_v002(magoManager); + return; } - this.pointsArray; -}; + var geometryDataPath = magoManager.readerWriter.geometryDataPath; + var buildingFolderName = neoBuilding.buildingFileName; + var projectFolderName = neoBuilding.projectFolderName; + + if (this.neoReferencesMotherAndIndices === undefined) + { + this.neoReferencesMotherAndIndices = new NeoReferencesMotherAndIndices(); + this.neoReferencesMotherAndIndices.motherNeoRefsList = neoBuilding.motherNeoReferencesArray; + } + + if (this.neoReferencesMotherAndIndices.fileLoadState === CODE.fileLoadState.READY) + { + if (this.neoReferencesMotherAndIndices.blocksList === undefined) + { this.neoReferencesMotherAndIndices.blocksList = new BlocksList("0.0.1"); } -Point2DList.prototype.deleteObjects = function() -{ - if (this.pointsArray === undefined) - { return; } + var subOctreeNumberName = this.octree_number_name.toString(); + var references_folderPath = geometryDataPath + "/" + projectFolderName + "/" + buildingFolderName + "/References"; + var intRef_filePath = references_folderPath + "/" + subOctreeNumberName + "_Ref"; + magoManager.readerWriter.getNeoReferencesArraybuffer(intRef_filePath, this, magoManager); + } - var pointsCount = this.pointsArray.length; - for (var i=0; i pCloudSettings.maxPartitionsLod0) + { pCloudPartitionsCount = pCloudSettings.maxPartitionsLod0; } } - - return resultBRect; + else if (lod === 1) + { + var pCloudSettings = magoManager.magoPolicy.getPointsCloudSettings(); + pCloudPartitionsCount = Math.ceil(realPartitionsCount/4); + if (pCloudPartitionsCount > pCloudSettings.maxPartitionsLod1) + { pCloudPartitionsCount = pCloudSettings.maxPartitionsLod1; } + } + else if (lod > 1) + { pCloudPartitionsCount = 1; } + + return pCloudPartitionsCount; }; /** - * nomal 계산 - * @param point 변수 - * @param resultPoint 변수 - * @returns resultPoint + * 어떤 일을 하고 있습니까? + * @param {MagoManager} magoManager Main mago3d manager. + * @returns {Boolean} Returns if requested the points cloud data. */ -Point2DList.prototype.getNearestPointIdxToPoint = function(point) +Octree.prototype.preparePCloudData = function(magoManager) { - if (point === undefined) - { return undefined; } + if (this.pCloudPartitionsCount === undefined && this.pCloudPartitionsCount === 0) + { return false; } + + var neoBuilding = this.neoBuildingOwner; + if (neoBuilding === undefined) + { return false; } + + if (magoManager.processQueue.existOctreeToDeletePCloud(this)) + { return false; } - var currPoint, candidatePointIdx; - var currSquaredDist, candidateSquaredDist; - var pointsCount = this.getPointsCount(); - for (var i=0; i object.squaredDist) - { - newStartIdx = startIdx; - newEndIdx = middleIdx; - } - else + // Delete unnecessary objects if ditToCam is big. + if (distToCamera > 50.0) { - newStartIdx = middleIdx; - newEndIdx = endIdx; + // Put octree to delete pCloud, but before, delete from the parseQueue. + if (this.pCloudPartitionsArray !== undefined) + { + var pCloudPartitionsCount = this.pCloudPartitionsArray.length; + for (var i=0; i 0) { - throw new Error(Messages.CONSTRUCT_ERROR); + var numDigits = Math.floor(Math.log10(intNumber)+1); + return numDigits; + } + else + { + return 1; } - - if (x !== undefined) - { this.x = x; } - else - { this.x = 0.0; } - - if (y !== undefined) - { this.y = y; } - else - { this.y = 0.0; } - - if (z !== undefined) - { this.z = z; } - else - { this.z = 0.0; } - - this.pointType; // 1 = important point.*** }; /** - * 포인트값 삭제 * 어떤 일을 하고 있습니까? */ -Point3D.prototype.deleteObjects = function() +Octree.prototype.getMotherOctree = function() { - this.x = undefined; - this.y = undefined; - this.z = undefined; -}; + if (this.octree_owner === undefined) { return this; } -/** - * 포인트값 삭제 - * 어떤 일을 하고 있습니까? - */ -Point3D.prototype.copyFrom = function(point3d) -{ - this.x = point3d.x; - this.y = point3d.y; - this.z = point3d.z; + return this.octree_owner.getMotherOctree(); }; /** * 어떤 일을 하고 있습니까? - * @returns this.x*this.x + this.y*this.y + this.z*this.z; + * @param octreeNumberName 변수 + * @param numDigits 변수 + * @returns subOctrees_array[idx-1].getOctree(rest_octreeNumberName, numDigits-1) */ -Point3D.prototype.getSquaredModul = function() +Octree.prototype.getOctree = function(octreeNumberName, numDigits) { - return this.x*this.x + this.y*this.y + this.z*this.z; -}; + if (numDigits === 1) + { + if (octreeNumberName === 0) { return this.getMotherOctree(); } + else { return this.subOctrees_array[octreeNumberName-1]; } + } -/** - * 어떤 일을 하고 있습니까? - * @returns Math.sqrt(this.x*this.x + this.y*this.y + this.z*this.z ); - */ -Point3D.prototype.getModul = function() -{ - return Math.sqrt(this.getSquaredModul()); + // determine the next level octree. + var exp = numDigits-1; + var denominator = Math.pow(10, exp); + var idx = Math.floor(octreeNumberName /denominator) % 10; + var rest_octreeNumberName = octreeNumberName - idx * denominator; + return this.subOctrees_array[idx-1].getOctree(rest_octreeNumberName, numDigits-1); }; /** - * * 어떤 일을 하고 있습니까? + * @param octreeNumberName 변수 + * @returns motherOctree.subOctrees_array[idx-1].getOctree(rest_octreeNumberName, numDigits-1) */ -Point3D.prototype.unitary = function() +Octree.prototype.getOctreeByNumberName = function(octreeNumberName) { - var modul = this.getModul(); - this.x /= modul; - this.y /= modul; - this.z /= modul; + var motherOctree = this.getMotherOctree(); + var numDigits = this.getNumberOfDigits(octreeNumberName); + if (numDigits === 1) + { + if (octreeNumberName === 0) { return motherOctree; } + else { return motherOctree.subOctrees_array[octreeNumberName-1]; } + } + + if (motherOctree.subOctrees_array.length === 0) { return undefined; } + + // determine the next level octree. + var exp = numDigits-1; + var denominator = Math.pow(10, exp); + var idx = Math.floor(octreeNumberName /denominator) % 10; + var rest_octreeNumberName = octreeNumberName - idx * denominator; + return motherOctree.subOctrees_array[idx-1].getOctree(rest_octreeNumberName, numDigits-1); }; /** - * * 어떤 일을 하고 있습니까? */ -Point3D.prototype.isNAN = function() +Octree.prototype.setSizesSubBoxes = function() { - if (isNaN(this.x) || isNaN(this.y) || isNaN(this.z) ) - { return true; } - else - { return false; } -}; + // Octree number name.** + // Bottom Top + // |---------|---------| |---------|---------| + // | | | | | | Y + // | 3 | 2 | | 7 | 6 | ^ + // | | | | | | | + // |---------+---------| |---------+---------| | + // | | | | | | | + // | 0 | 1 | | 4 | 5 | | + // | | | | | | |-----------> X + // |---------|---------| |---------|---------| -/** - * nomal 계산 - * @param point 변수 - * @param resultPoint 변수 - * @returns resultPoint - */ -Point3D.prototype.crossProduct = function(point, resultPoint) -{ - if (resultPoint === undefined) { resultPoint = new Point3D(); } + if (this.subOctrees_array.length > 0) + { + var half_x = this.centerPos.x; + var half_y = this.centerPos.y; + var half_z = this.centerPos.z; - resultPoint.x = this.y * point.z - point.y * this.z; - resultPoint.y = point.x * this.z - this.x * point.z; - resultPoint.z = this.x * point.y - point.x * this.y; + var min_x = this.centerPos.x - this.half_dx; + var min_y = this.centerPos.y - this.half_dy; + var min_z = this.centerPos.z - this.half_dz; - return resultPoint; -}; + var max_x = this.centerPos.x + this.half_dx; + var max_y = this.centerPos.y + this.half_dy; + var max_z = this.centerPos.z + this.half_dz; -/** - * nomal 계산 - * @param point 변수 - * @param resultPoint 변수 - * @returns resultPoint - */ -Point3D.prototype.scalarProduct = function(point) -{ - var scalarProd = this.x*point.x + this.y*point.y + this.z*point.z; - return scalarProd; + this.subOctrees_array[0].setBoxSize(min_x, half_x, min_y, half_y, min_z, half_z); + this.subOctrees_array[1].setBoxSize(half_x, max_x, min_y, half_y, min_z, half_z); + this.subOctrees_array[2].setBoxSize(half_x, max_x, half_y, max_y, min_z, half_z); + this.subOctrees_array[3].setBoxSize(min_x, half_x, half_y, max_y, min_z, half_z); + + this.subOctrees_array[4].setBoxSize(min_x, half_x, min_y, half_y, half_z, max_z); + this.subOctrees_array[5].setBoxSize(half_x, max_x, min_y, half_y, half_z, max_z); + this.subOctrees_array[6].setBoxSize(half_x, max_x, half_y, max_y, half_z, max_z); + this.subOctrees_array[7].setBoxSize(min_x, half_x, half_y, max_y, half_z, max_z); + + for (var i=0; i<8; i++) + { + this.subOctrees_array[i].setSizesSubBoxes(); + } + } }; /** - * nomal 계산 - * @param point 변수 - * @param resultPoint 변수 - * @returns resultPoint + * 어떤 일을 하고 있습니까? + * @param Min_x 변수 + * @param Max_x 변수 + * @param Min_y 변수 + * @param Max_y 변수 + * @param Min_z 변수 + * @param Max_z 변수 */ -Point3D.prototype.angleRadToVector = function(vector) +Octree.prototype.setBoxSize = function(Min_X, Max_X, Min_Y, Max_Y, Min_Z, Max_Z) { - if (vector === undefined) - { return undefined; } - - //****************************************************** - //var scalarProd = this.scalarProd(vector); - var myModul = this.getModul(); - var vecModul = vector.getModul(); - - // calcule by cos.*** - //var cosAlfa = scalarProd / (myModul * vecModul); - //var angRad = Math.acos(cosAlfa); - //var angDeg = alfa * 180.0/Math.PI; - //------------------------------------------------------ - var error = 10E-10; - if (myModul < error || vecModul < error) - { return undefined; } - - return Math.acos(this.scalarProduct(vector) / (myModul * vecModul)); + this.centerPos.x = (Max_X + Min_X)/2.0; + this.centerPos.y = (Max_Y + Min_Y)/2.0; + this.centerPos.z = (Max_Z + Min_Z)/2.0; + + this.half_dx = (Max_X - Min_X)/2.0; // half width. + this.half_dy = (Max_Y - Min_Y)/2.0; // half length. + this.half_dz = (Max_Z - Min_Z)/2.0; // half height. }; /** - * nomal 계산 - * @param point 변수 - * @param resultPoint 변수 - * @returns resultPoint + * 어떤 일을 하고 있습니까? + * @returns centerPos */ -Point3D.prototype.angleDegToVector = function(vector) +Octree.prototype.getCenterPos = function() { - if (vector === undefined) - { return undefined; } - - var angRad = this.angleRadToVector(vector); - - if (angRad === undefined) - { return undefined; } - - return angRad * 180.0/Math.PI; + return this.centerPos; }; /** * 어떤 일을 하고 있습니까? - * @param px 변수 - * @returns dx*dx + dy*dy + dz*dz + * @returns Math.abs(this.half_dx*1.2); */ -Point3D.prototype.squareDistToPoint = function(point) +Octree.prototype.getRadiusAprox = function() { - var dx = this.x - point.x; - var dy = this.y - point.y; - var dz = this.z - point.z; - - return dx*dx + dy*dy + dz*dz; + return this.half_dx*1.7; }; /** * 어떤 일을 하고 있습니까? - * @param px 변수 - * @param py 변수 - * @param pz 변수 - * @returns dx*dx + dy*dy + dz*dz + * @param cullingVolume 변수 + * @param result_NeoRefListsArray 변수 + * @param boundingSphere_scratch 변수 + * @param eye_x 변수 + * @param eye_y 변수 + * @param eye_z 변수 */ -Point3D.prototype.isCoincidentToPoint = function(point, errorDist) +Octree.prototype.getFrustumVisibleLowestOctreesByLOD = function(cullingVolume, visibleObjControlerOctrees, globalVisibleObjControlerOctrees, + boundingSphere_scratch, cameraPosition, squaredDistLod0, squaredDistLod1, squaredDistLod2) { - var squareDist = this.distToPoint(point); - var coincident = false; - if (squareDist < errorDist*errorDist) + var visibleOctreesArray = []; + var find = false; + + //this.getAllSubOctrees(visibleOctreesArray); // Test. + visibleOctreesArray = this.getFrustumVisibleOctreesNeoBuildingAsimetricVersion(cullingVolume, visibleOctreesArray, boundingSphere_scratch); // Original. + + // Now, we must sort the subOctrees near->far from eye. + var visibleOctrees_count = visibleOctreesArray.length; + for (var i=0; i 0) + { + if (globalVisibleObjControlerOctrees) + { this.putOctreeInEyeDistanceSortedArray(globalVisibleObjControlerOctrees.currentVisibles0, visibleOctreesArray[i]); } + visibleObjControlerOctrees.currentVisibles0.push(visibleOctreesArray[i]); + visibleOctreesArray[i].lod = 0; + find = true; + } + } + else if (visibleOctreesArray[i].distToCamera < squaredDistLod1) + { + if (visibleOctreesArray[i].triPolyhedronsCount > 0) + { + if (globalVisibleObjControlerOctrees) + { this.putOctreeInEyeDistanceSortedArray(globalVisibleObjControlerOctrees.currentVisibles1, visibleOctreesArray[i]); } + visibleObjControlerOctrees.currentVisibles1.push(visibleOctreesArray[i]); + visibleOctreesArray[i].lod = 1; + find = true; + } + } + else if (visibleOctreesArray[i].distToCamera < squaredDistLod2) + { + if (visibleOctreesArray[i].triPolyhedronsCount > 0) + { + if (globalVisibleObjControlerOctrees) + { this.putOctreeInEyeDistanceSortedArray(globalVisibleObjControlerOctrees.currentVisibles2, visibleOctreesArray[i]); } + visibleObjControlerOctrees.currentVisibles2.push(visibleOctreesArray[i]); + visibleOctreesArray[i].lod = 2; + find = true; + } + } + else + { + if (visibleOctreesArray[i].triPolyhedronsCount > 0) + { + if (globalVisibleObjControlerOctrees) + { globalVisibleObjControlerOctrees.currentVisibles3.push(visibleOctreesArray[i]); } + visibleObjControlerOctrees.currentVisibles3.push(visibleOctreesArray[i]); + visibleOctreesArray[i].lod = 3; // must be 3!!! + find = true; + } + } + } + + visibleOctreesArray = undefined; + return find; }; /** * 어떤 일을 하고 있습니까? - * @param px 변수 - * @param py 변수 - * @param pz 변수 - * @returns dx*dx + dy*dy + dz*dz + * @param x 변수 + * @param y 변수 + * @param z 변수 + * @returns intersects */ -Point3D.prototype.squareDistTo = function(x, y, z) +Octree.prototype.intersectsWithPoint3D = function(x, y, z) { - var dx = this.x - x; - var dy = this.y - y; - var dz = this.z - z; - - return dx*dx + dy*dy + dz*dz; + //this.centerPos = new Point3D(); + //this.half_dx = 0.0; // half width. + //this.half_dy = 0.0; // half length. + //this.half_dz = 0.0; // half height. + var minX = this.centerPos.x - this.half_dx; + var minY = this.centerPos.y - this.half_dz; + var minZ = this.centerPos.z - this.half_dz; + var maxX = this.centerPos.x + this.half_dx; + var maxY = this.centerPos.y + this.half_dz; + var maxZ = this.centerPos.z + this.half_dz; + + var intersects = false; + if (x> minX && x minY && y minZ && z 0) + { + var center_x = this.centerPos.x; + var center_y = this.centerPos.y; + var center_z = this.centerPos.z; + + var intersectedSubBox_aux = undefined; + var intersectedSubBox_idx; + if (x difY) + // Now, we must sort the subOctrees near->far from eye. + var visibleOctrees_count = this.lowestOctrees_array.length; + for (var i=0; i difZ) + this.lowestOctrees_array[i].setDistToCamera(cameraPosition); + } + + for (var i=0; i 0) + { + if (globalVisibleObjControlerOctrees) + { this.putOctreeInEyeDistanceSortedArray(globalVisibleObjControlerOctrees.currentVisibles0, this.lowestOctrees_array[i]); } + visibleObjControlerOctrees.currentVisibles0.push(this.lowestOctrees_array[i]); + this.lowestOctrees_array[i].lod = 0; + find = true; + } + } + else if (this.lowestOctrees_array[i].distToCamera < squaredDistLod1) + { + if (this.lowestOctrees_array[i].triPolyhedronsCount > 0) + { + if (globalVisibleObjControlerOctrees) + { this.putOctreeInEyeDistanceSortedArray(globalVisibleObjControlerOctrees.currentVisibles1, this.lowestOctrees_array[i]); } + visibleObjControlerOctrees.currentVisibles1.push(this.lowestOctrees_array[i]); + this.lowestOctrees_array[i].lod = 1; + find = true; + } + } + else if (this.lowestOctrees_array[i].distToCamera < squaredDistLod2) + { + if (this.lowestOctrees_array[i].triPolyhedronsCount > 0) + { + if (globalVisibleObjControlerOctrees) + { this.putOctreeInEyeDistanceSortedArray(globalVisibleObjControlerOctrees.currentVisibles2, this.lowestOctrees_array[i]); } + visibleObjControlerOctrees.currentVisibles2.push(this.lowestOctrees_array[i]); + this.lowestOctrees_array[i].lod = 2; + find = true; + } } else { - maxValue = difZ; - value1 = difX/maxValue; - value1Idx = Math.floor(value1*10); - var middleDist = maxValue * sqrtTable[value1Idx]; - value2 = difY/middleDist; - value2Idx = Math.floor(value2*10); - return (middleDist * sqrtTable[value2Idx]); + if (this.lowestOctrees_array[i].triPolyhedronsCount > 0) + { + if (globalVisibleObjControlerOctrees) + { globalVisibleObjControlerOctrees.currentVisibles3.push(this.lowestOctrees_array[i]); } + visibleObjControlerOctrees.currentVisibles3.push(this.lowestOctrees_array[i]); + this.lowestOctrees_array[i].lod = 3; + find = true; + } } } - else + + return find; +}; + +/** + * 어떤 일을 하고 있습니까? + * @param cesium_cullingVolume 변수 + * @param result_octreesArray 변수 + * @param boundingSphere_scratch 변수 + */ +Octree.prototype.intersectionFrustum = function(cullingVolume, boundingSphere_scratch) +{ + if (boundingSphere_scratch === undefined) + { boundingSphere_scratch = new Sphere(); } + + boundingSphere_scratch.centerPoint.x = this.centerPos.x; + boundingSphere_scratch.centerPoint.y = this.centerPos.y; + boundingSphere_scratch.centerPoint.z = this.centerPos.z; + boundingSphere_scratch.r = this.getRadiusAprox(); + + return cullingVolume.intersectionSphere(boundingSphere_scratch); +}; + + +/** + * 어떤 일을 하고 있습니까? + * @param cesium_cullingVolume 변수 + * @param result_octreesArray 변수 + * @param boundingSphere_scratch 변수 + */ +Octree.prototype.getFrustumVisibleOctreesNeoBuildingAsimetricVersion = function(cullingVolume, result_octreesArray, boundingSphere_scratch) +{ + // cullingVolume: Frustum class. + if (this.subOctrees_array === undefined) { return; } + + if (this.subOctrees_array.length === 0 && this.triPolyhedronsCount === 0) + { return; } + + if (result_octreesArray === undefined) { result_octreesArray = []; } + + var frustumCull = this.intersectionFrustum(cullingVolume, boundingSphere_scratch); + if (frustumCull === Constant.INTERSECTION_INSIDE ) { - if (difY > difZ) + this.getAllSubOctreesIfHasRefLists(result_octreesArray); + } + else if (frustumCull === Constant.INTERSECTION_INTERSECT ) + { + if (this.subOctrees_array.length === 0) { - maxValue = difY; - value1 = difX/maxValue; - value1Idx = Math.floor(value1*10); - var middleDist = maxValue * sqrtTable[value1Idx]; - value2 = difZ/middleDist; - value2Idx = Math.floor(value2*10); - return (middleDist * sqrtTable[value2Idx]); + result_octreesArray.push(this); } else { - maxValue = difZ; - value1 = difX/maxValue; - value1Idx = Math.floor(value1*10); - var middleDist = maxValue * sqrtTable[value1Idx]; - value2 = difY/middleDist; - value2Idx = Math.floor(value2*10); - return (middleDist * sqrtTable[value2Idx]); + for (var i=0, subOctreesArrayLength = this.subOctrees_array.length; i octree.distToCamera) + { + newStartIdx = startIdx; + newEndIdx = middleIdx; + } + else + { + newStartIdx = middleIdx; + newEndIdx = endIdx; + } + return this.getIndexToInsertBySquaredDistToEye(octreesArray, octree, newStartIdx, newEndIdx); + } }; /** * 어떤 일을 하고 있습니까? - * @param x 변수 - * @param y 변수 - * @param z 변수 + * @param result_octreesArray 변수 + * @param octree 변수 */ -Point3D.prototype.addPoint = function(point) +Octree.prototype.putOctreeInEyeDistanceSortedArray = function(result_octreesArray, octree) { - this.x += point.x; this.y += point.y; this.z += point.z; + // sorting is from minDist to maxDist. + if (result_octreesArray.length > 0) + { + var startIdx = 0; + var endIdx = result_octreesArray.length - 1; + var insert_idx= this.getIndexToInsertBySquaredDistToEye(result_octreesArray, octree, startIdx, endIdx); + + result_octreesArray.splice(insert_idx, 0, octree); + } + else + { + result_octreesArray.push(octree); + } }; /** * 어떤 일을 하고 있습니까? - * @param x 변수 - * @param y 변수 - * @param z 변수 + * @param result_octreesArray 변수 */ -Point3D.prototype.scale = function(scaleFactor) +Octree.prototype.getAllSubOctreesIfHasRefLists = function(result_octreesArray) { - this.x *= scaleFactor; this.y *= scaleFactor; this.z *= scaleFactor; -}; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + if (this.subOctrees_array === undefined) { return; } + if (result_octreesArray === undefined) { result_octreesArray = []; } + if (this.subOctrees_array.length > 0) + { + for (var i=0, subOctreesArrayLength = this.subOctrees_array.length; i 0) { result_octreesArray.push(this); } // there are only 1. + } +}; +/** + * 어떤 일을 하고 있습니까? + * @param result_octreesArray 변수 + */ +Octree.prototype.getAllSubOctrees = function(result_octreesArray) +{ + if (result_octreesArray === undefined) { result_octreesArray = []; } -'use strict'; + if (this.subOctrees_array.length > 0) + { + for (var i=0, subOctreesArrayLength = this.subOctrees_array.length; i 0) { - throw new Error(Messages.CONSTRUCT_ERROR); + lowestOctreesArray.push(this); + } + else + { + for (var i=0; i CCW. (normal = -1) -> CW.*** - this.convexPolygonsArray; // tessellation result.*** - this.bRect; // boundary rectangle.*** }; -Polygon.prototype.deleteObjects = function() +/** + * 어떤 일을 하고 있습니까? + * @param result_octreesArray 변수 + */ +Octree.prototype.multiplyKeyTransformMatrix = function(idxKey, matrix) { - if (this.point2dList !== undefined) + var subOctreesCount = this.subOctrees_array.length; + + if (subOctreesCount === 0 && this.triPolyhedronsCount > 0) { - this.point2dList.deleteObjects(); - this.point2dList = undefined; + if (this.neoReferencesMotherAndIndices) + { this.neoReferencesMotherAndIndices.multiplyKeyTransformMatrix(idxKey, matrix); } + } + else + { + for (var i=0; i 0) + { this.neoBuildingOwner = neoBuildingOwner; } -Polygon.prototype.getCopy = function(resultCopyPolygon) -{ - if (this.point2dList === undefined) - { return resultCopyPolygon; } - - if (resultCopyPolygon === undefined) - { resultCopyPolygon = new Polygon(); } - - // copy the point2dList and the normal.*** - if (resultCopyPolygon.point2dList === undefined) - { resultCopyPolygon.point2dList = new Point2DList(); } - - resultCopyPolygon.point2dList = this.point2dList.getCopy(resultCopyPolygon.point2dList); - - if (this.normal) - { resultCopyPolygon.normal = this.normal; } - - return resultCopyPolygon; + if (version === "0.0.2") + { + // Read ModelLists partitions count. + this.blocksListsPartitionsCount = readerWriter.readInt32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; + } + + // 1rst, create the 8 subOctrees. + for (var i=0; i 0.0) - { - crossProd = 1; - } - // calcule by cos.*** - // cosAlfa = scalarProd / (strModul * endModul); (but strVecModul = 1 & endVecModul = 1), so: - var cosAlfa = scalarProd; - var alfa = Math.acos(cosAlfa); - this.normal += (crossProd * alfa); + // this is the mother octree, so read the mother octree's size. + var minX = readerWriter.readFloat32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; + var maxX = readerWriter.readFloat32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; + var minY = readerWriter.readFloat32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; + var maxY = readerWriter.readFloat32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; + var minZ = readerWriter.readFloat32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; + var maxZ = readerWriter.readFloat32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; + + this.setBoxSize(minX, maxX, minY, maxY, minZ, maxZ ); + this.octree_number_name = 0; } - - if (this.normal > 0 ) - { this.normal = 1; } - else - { this.normal = -1; } - - return resultConcavePointsIdxArray; -}; + var subOctreesCount = readerWriter.readUInt8(arrayBuffer, bytesReaded, bytesReaded+1); bytesReaded += 1; // this must be 0 or 8. + this.triPolyhedronsCount = readerWriter.readInt32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; + if (this.triPolyhedronsCount > 0) + { this.neoBuildingOwner = neoBuildingOwner; } -Polygon.prototype.tessellate = function(concaveVerticesIndices, convexPolygonsArray) -{ - var concaveVerticesCount = concaveVerticesIndices.length; - - if (concaveVerticesCount === 0) + // Now, read verticesArray partitions count. + this.pCloudPartitionsCount = readerWriter.readInt32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; + + // 1rst, create the 8 subOctrees. + for (var i=0; i octreesMaxSize -> down in tree. + var octreeSize = this.getRadiusAprox(); + var subOctreesCount = this.subOctrees_array.length; + var dist; + if (octreeSize > octreesMaxSize && subOctreesCount > 0) + { + // Calculate the nearest subOctree to camera. + var currDist; + var distCandidate; + var subOctreeCandidate; + for (var i=0; i 0) + { hasContent = true; } + if (subOctree.triPolyhedronsCount && subOctree.triPolyhedronsCount > 0) + { hasContent = true; } - var resultSplittedPolygons = this.splitPolygon(idx, idx_B); + if (!hasContent) + { continue; } - if (resultSplittedPolygons.length < 2) + //currDist = subOctree.getDistToCamera(cameraPosition, boundingSphere_Aux); // original. + currDist = subOctree.centerPos.squareDistToPoint(cameraPosition); // test. + if (distCandidate === undefined) { - j++; - continue; + distCandidate = currDist; + subOctreeCandidate = subOctree; } - - // now, compare splittedPolygon's normals with myNormal.*** - var polygon_A = resultSplittedPolygons[0]; - var polygon_B = resultSplittedPolygons[1]; - var concavePoints_A = polygon_A.calculateNormal(); - var concavePoints_B = polygon_B.calculateNormal(); - - var normal_A = polygon_A.normal; - var normal_B = polygon_B.normal; - if (normal_A === this.normal && normal_B === this.normal) + else { - find = true; - // polygon_A.*** - if (concavePoints_A.length > 0) - { - convexPolygonsArray = polygon_A.tessellate(concavePoints_A, convexPolygonsArray); - } - else - { - if (convexPolygonsArray === undefined) - { convexPolygonsArray = []; } - - convexPolygonsArray.push(polygon_A); - } - - // polygon_B.*** - if (concavePoints_B.length > 0) - { - convexPolygonsArray = polygon_B.tessellate(concavePoints_B, convexPolygonsArray); - } - else + if (currDist < distCandidate) { - if (convexPolygonsArray === undefined) - { convexPolygonsArray = []; } - - convexPolygonsArray.push(polygon_B); + distCandidate = currDist; + subOctreeCandidate = subOctree; } } - - j++; - } - i++; - } - - return convexPolygonsArray; -}; - -Polygon.prototype.intersectionWithSegment = function(segment) -{ - // "segment" cut a polygons edge.*** - // "segment" coincident with a polygons vertex.*** - if (this.bRect !== undefined) - { - // if exist boundary rectangle, check bRect intersection.*** - var segmentsBRect = segment.getBoundaryRectangle(segmentsBRect); - if (!this.bRect.intersectsWithRectangle(segmentsBRect)) - { return false; } - } - - // 1rst check if the segment is coincident with any polygons vertex.*** - var mySegment; - var intersectionType; - var error = 10E-8; - var pointsCount = this.point2dList.getPointsCount(); - for (var i=0; i idx2.*** - var polygon_A = new Polygon(); - polygon_A.point2dList = new Point2DList(); - polygon_A.point2dList.pointsArray = []; - - // 1rst, put vertex1 & vertex2 in to the polygon_A.*** - polygon_A.point2dList.pointsArray.push(this.point2dList.getPoint(idx1)); - polygon_A.point2dList.pointsArray.push(this.point2dList.getPoint(idx2)); - - var finished = false; - var currIdx = idx2; - var startIdx = idx1; - var i=0; - var totalPointsCount = this.point2dList.getPointsCount(); - while (!finished && i idx1.*** - var polygon_B = new Polygon(); - polygon_B.point2dList = new Point2DList(); - polygon_B.point2dList.pointsArray = []; - - // 1rst, put vertex2 & vertex1 in to the polygon_B.*** - polygon_B.point2dList.pointsArray.push(this.point2dList.getPoint(idx2)); - polygon_B.point2dList.pointsArray.push(this.point2dList.getPoint(idx1)); - - finished = false; - currIdx = idx1; - startIdx = idx2; - i=0; - while (!finished && i 0) - { normal = 1; } - else - { normal = -1; } - - var pointsCount = this.point2dList.getPointsCount(); - for (var i=0; i 0) - { normal = 1; } - else - { normal = -1; } - - var pointsCount = concavePolygon.point2dList.getPointsCount(); - for (var i=0; i 0) { - if (i===0) - { - if (resultExistentPointsCount > 0) - { - // check if the last point of "resultPointsArray" and the 1rst point of "this" is coincident.*** - var lastExistentPoint = resultPointsArray[resultExistentPointsCount-1]; - var point0 = this.point2dArray[i]; - if (!lastExistentPoint.isCoincidentToPoint(point0, errorDist)) - { - point = new Point2D(); - point.copyFrom(this.point2dArray[i]); - point.pointType = 1; // mark as "important point".*** - resultPointsArray.push(point); - } - } - else - { - point = new Point2D(); - point.copyFrom(this.point2dArray[i]); - point.pointType = 1; // mark as "important point".*** - resultPointsArray.push(point); - } - } - else + var node; + var skinLego; + var neoBuilding; + var skinsParsedCount = 0; + var maxParsesCount = this.maxNumParses; + var lod3buildingsCount = nodesArray.length; + for (var i=0; i maxParsesCount) + { break; } + } + /* + if (skinsParsedCount === 0) + { + for (var key in this.skinLegosToParseMap) + { + var node = this.skinLegosToParseMap[key]; + + if (node.data === undefined) + { continue; } + + neoBuilding = node.data.neoBuilding; + + if (neoBuilding === undefined) + { continue; } + + // check the current lod of the building.*** + var currentBuildingLod = neoBuilding.currentLod; + var lodIdx = currentBuildingLod - 3; + + if (lodIdx < 0) + { continue; } + + skinLego = neoBuilding.lodMeshesArray[lodIdx]; + if (skinLego === undefined) + { continue; } + if(this.eraseSkinLegosToParse(skinLego)) + { + skinLego.parseArrayBuffer(gl, skinLego.dataArrayBuffer, magoManager); + skinLego.dataArrayBuffer = undefined; + + skinsParsedCount++; + } + if (skinsParsedCount > maxParsesCount) + { break; } + + } + } + */ + + } +}; + +ParseQueue.prototype.parseArrayOctreesPCloud = function(gl, octreesArray, magoManager) +{ + // Test function.*** + if (Object.keys(this.octreesPCloudToParseMap).length > 0) + { + var maxParsesCount = this.maxNumParses; + var octreesParsedCount = 0; + var lowestOctree; + + var octreesLod0Count = octreesArray.length; + for (var i=0; i maxParsesCount) + { break; } + } + + if (octreesParsedCount === 0) + { + for (var key in this.octreesPCloudToParseMap) + { + if (Object.prototype.hasOwnProperty.call(this.octreesPCloudToParseMap, key)) + { + lowestOctree = this.octreesPCloudToParseMap[key]; + if (this.eraseOctreePCloudToParse(lowestOctree)) + { + if (lowestOctree.lego === undefined) + { continue; } + + lowestOctree.lego.parsePointsCloudData(lowestOctree.lego.dataArrayBuffer, gl, magoManager); + lowestOctree.lego.dataArrayBuffer = undefined; + + octreesParsedCount++; + } + if (octreesParsedCount > maxParsesCount) + { break; } + } + + } + } + + if (octreesParsedCount > 0) + { + if (this.selectionFbo) + { this.selectionFbo.dirty = true; } } } - - return resultPointsArray; }; +ParseQueue.prototype.parseArrayOctreesPCloudPartition = function(gl, octreesArray, magoManager) +{ + // Test function.*** + if (Object.keys(this.octreesPCloudPartitionToParseMap).length > 0) + { + var maxParsesCount = this.maxNumParses; + var octreesParsedCount = 0; + var lowestOctree; + + var octreesLod0Count = octreesArray.length; + for (var i=0; i maxParsesCount) + { break; } + } + + if (octreesParsedCount === 0) + { + for (var key in this.octreesPCloudPartitionToParseMap) + { + if (Object.prototype.hasOwnProperty.call(this.octreesPCloudPartitionToParseMap, key)) + { + lowestOctree = this.octreesPCloudPartitionToParseMap[key]; + if (this.eraseOctreePCloudPartitionToParse(lowestOctree)) + { + //if (lowestOctree.lego === undefined) + //{ continue; } + + pCloudPartition.parsePointsCloudData(gl, pCloudPartition.dataArrayBuffer, magoManager); + octreesParsedCount++; + + //octreesParsedCount++; + } + if (octreesParsedCount > maxParsesCount) + { break; } + } + } + } + + if (octreesParsedCount > 0) + { + if (this.selectionFbo) + { this.selectionFbo.dirty = true; } + } + } +}; +ParseQueue.prototype.parseArrayOctreesLod2Legos = function(gl, octreesArray, magoManager) +{ + if (Object.keys(this.octreesLod2LegosToParseMap).length > 0) + { + var maxParsesCount = this.maxNumParses; + var octreesParsedCount = 0; + var lowestOctree; + + var octreesLod0Count = octreesArray.length; + for (var i=0; i maxParsesCount) + { break; } + } + /* + if (octreesParsedCount === 0) + { + for (var key in this.octreesLod2LegosToParseMap) + { + var lowestOctree = this.octreesLod2LegosToParseMap[key]; + if(this.eraseOctreeLod2LegosToParse(lowestOctree)) + { + if (lowestOctree.lego === undefined) + { continue; } + + lowestOctree.lego.parseArrayBuffer(gl, lowestOctree.lego.dataArrayBuffer, magoManager); + lowestOctree.lego.dataArrayBuffer = undefined; + + octreesParsedCount++; + } + if (octreesParsedCount > maxParsesCount) + { break; } + } + } + */ + if (octreesParsedCount > 0) + { + if (magoManager.selectionFbo) + { magoManager.selectionFbo.dirty = true; } + } + } +}; +ParseQueue.prototype.parseArrayOctreesLod0Models = function(gl, octreesArray, magoManager) +{ + if (Object.keys(this.octreesLod0ModelsToParseMap).length > 0) + { + var maxParsesCount = this.maxNumParses; + var octreesParsedCount = 0; + // 1rst parse the currently closest lowestOctrees to camera. + var neoBuilding; + var headerVersion; + var lowestOctree; + + var octreesLod0Count = octreesArray.length; + for (var i=0; i maxParsesCount) + { break; } + } + /* + if (octreesParsedCount === 0) + { + for (var key in this.octreesLod0ModelsToParseMap) + { + var lowestOctree = this.octreesLod0ModelsToParseMap[key]; + if(this.eraseOctreeLod0ModelsToParse(lowestOctree)) + { + if (lowestOctree.neoReferencesMotherAndIndices === undefined) + { continue; } + + var blocksList = lowestOctree.neoReferencesMotherAndIndices.blocksList; + if (blocksList === undefined) + { continue; } + + if (blocksList.dataArraybuffer === undefined) + { continue; } + + if (blocksList.fileLoadState !== CODE.fileLoadState.LOADING_FINISHED) + { continue; } + + neoBuilding = lowestOctree.neoBuildingOwner; + headerVersion = neoBuilding.getHeaderVersion(); + + if (headerVersion[0] === "v") + { + // parse the beta version. + blocksList.parseBlocksList(blocksList.dataArraybuffer, magoManager.readerWriter, neoBuilding.motherBlocksArray, magoManager); + } + else + { + // parse versioned. + blocksList.parseBlocksListVersioned(blocksList.dataArraybuffer, magoManager.readerWriter, neoBuilding.motherBlocksArray, magoManager); + } + blocksList.dataArraybuffer = undefined; + octreesParsedCount++; + if (octreesParsedCount > maxParsesCount) + { break; } + } + + } + } + */ + + + if (octreesParsedCount > 0) + { + if (magoManager.selectionFbo) + { magoManager.selectionFbo.dirty = true; } + } + } +}; +ParseQueue.prototype.parseArrayOctreesLod0References = function(gl, octreesArray, magoManager) +{ + if (Object.keys(this.octreesLod0ReferencesToParseMap).length > 0) + { + var maxParsesCount = this.maxNumParses; + var octreesParsedCount = 0; + var lowestOctree; + + // 1rst parse the currently closest lowestOctrees to camera. + var octreesLod0Count = octreesArray.length; + for (var i=0; i maxParsesCount) + { break; } + } + /* + if (octreesParsedCount === 0) + { + for (var key in this.octreesLod0ReferencesToParseMap) + { + var lowestOctree = this.octreesLod0ReferencesToParseMap[key]; + if(this.parseOctreesLod0References(gl, lowestOctree, magoManager)) + { + octreesParsedCount++; + if (octreesParsedCount > maxParsesCount) + { break; } + } + } + } + */ + if (octreesParsedCount > 0) + { + if (magoManager.selectionFbo) + { magoManager.selectionFbo.dirty = true; } + } + } +}; +ParseQueue.prototype.parseOctreesLod0References = function(gl, lowestOctree, magoManager) +{ + var parsed = false; + if (this.eraseOctreeLod0ReferencesToParse(lowestOctree)) + { + if (lowestOctree.neoReferencesMotherAndIndices === undefined) + { return false; } + + if (lowestOctree.neoReferencesMotherAndIndices.dataArraybuffer === undefined) + { return false; } + + if (lowestOctree.neoReferencesMotherAndIndices.fileLoadState !== CODE.fileLoadState.LOADING_FINISHED) + { return false; } + + var neoBuilding = lowestOctree.neoBuildingOwner; + + var node = neoBuilding.nodeOwner; + var rootNode; + if (node) + { rootNode = node.getRoot(); } + else + { rootNode = undefined; } + + if (rootNode === undefined) + { return false; } + + if (rootNode.data === undefined) + { return false; } + + var geoLocDataManager = rootNode.data.geoLocDataManager; + + if (geoLocDataManager === undefined) + { return false; } + + if (this.matrix4SC === undefined) + { this.matrix4SC = new Matrix4(); } + + var buildingGeoLocation = geoLocDataManager.getCurrentGeoLocationData(); + var headerVersion = neoBuilding.getHeaderVersion(); + this.matrix4SC.setByFloat32Array(buildingGeoLocation.rotMatrix._floatArrays); + if (headerVersion[0] === "v") + { + // parse beta version. + lowestOctree.neoReferencesMotherAndIndices.parseArrayBufferReferences(gl, lowestOctree.neoReferencesMotherAndIndices.dataArraybuffer, + magoManager.readerWriter, neoBuilding, this.matrix4SC, magoManager); + } + else + { + // parse vesioned. + lowestOctree.neoReferencesMotherAndIndices.parseArrayBufferReferencesVersioned(gl, lowestOctree.neoReferencesMotherAndIndices.dataArraybuffer, + magoManager.readerWriter, neoBuilding, this.matrix4SC, magoManager); + } + lowestOctree.neoReferencesMotherAndIndices.multiplyKeyTransformMatrix(0, buildingGeoLocation.rotMatrix); + lowestOctree.neoReferencesMotherAndIndices.dataArraybuffer = undefined; + parsed = true; + } + + return parsed; +}; +ParseQueue.prototype.putOctreeLod0ReferencesToParse = function(octree, aValue) +{ + // provisionally "aValue" can be anything. + if (aValue === undefined) + { aValue = 0; } + + this.octreesLod0ReferencesToParseMap[octree.octreeKey] = octree; +}; +ParseQueue.prototype.eraseOctreeLod0ReferencesToParse = function(octree) +{ + var key = octree.octreeKey; + if (this.octreesLod0ReferencesToParseMap.hasOwnProperty(key)) + { + delete this.octreesLod0ReferencesToParseMap[key]; + return true; + } + return false; +}; +ParseQueue.prototype.putOctreeLod0ModelsToParse = function(octree, aValue) +{ + // provisionally "aValue" can be anything. + if (aValue === undefined) + { aValue = 0; } + + this.octreesLod0ModelsToParseMap[octree.octreeKey] = octree; +}; +ParseQueue.prototype.eraseOctreeLod0ModelsToParse = function(octree) +{ + var key = octree.octreeKey; + if (this.octreesLod0ModelsToParseMap.hasOwnProperty(key)) + { + delete this.octreesLod0ModelsToParseMap[key]; + return true; + } + return false; +}; +ParseQueue.prototype.putOctreeLod2LegosToParse = function(octree, aValue) +{ + // provisionally "aValue" can be anything. + if (aValue === undefined) + { aValue = 0; } + + this.octreesLod2LegosToParseMap[octree.octreeKey] = octree; +}; +ParseQueue.prototype.eraseOctreeLod2LegosToParse = function(octree) +{ + var key = octree.octreeKey; + if (this.octreesLod2LegosToParseMap.hasOwnProperty(key)) + { + delete this.octreesLod2LegosToParseMap[key]; + return true; + } + return false; +}; +ParseQueue.prototype.putOctreePCloudToParse = function(octree, aValue) +{ + // provisionally "aValue" can be anything. + if (aValue === undefined) + { aValue = 0; } + + this.octreesPCloudToParseMap[octree.octreeKey] = octree; +}; +ParseQueue.prototype.eraseOctreePCloudToParse = function(octree) +{ + if (octree === undefined) + { return false; } + + var key = octree.octreeKey; + if (this.octreesPCloudToParseMap.hasOwnProperty(key)) + { + delete this.octreesPCloudToParseMap[key]; + return true; + } + return false; +}; +ParseQueue.prototype.putOctreePCloudPartitionToParse = function(pCloudPartitionLego, aValue) +{ + // provisionally "aValue" can be anything. + if (aValue === undefined) + { aValue = 0; } + + this.octreesPCloudPartitionToParseMap[pCloudPartitionLego.legoKey] = pCloudPartitionLego; +}; +ParseQueue.prototype.eraseOctreePCloudPartitionToParse = function(pCloudPartitionLego) +{ + if (pCloudPartitionLego === undefined) + { return false; } + + var key = pCloudPartitionLego.legoKey; + if (this.octreesPCloudPartitionToParseMap.hasOwnProperty(key)) + { + delete this.octreesPCloudPartitionToParseMap[key]; + return true; + } + return false; +}; +ParseQueue.prototype.putSkinLegosToParse = function(skinLego, aValue) +{ + // provisionally "aValue" can be anything. + if (aValue === undefined) + { aValue = 0; } + + this.skinLegosToParseMap[skinLego.legoKey] = skinLego; +}; +ParseQueue.prototype.eraseSkinLegosToParse = function(skinLego) +{ + var key = skinLego.legoKey; + if (this.skinLegosToParseMap.hasOwnProperty(key)) + { + delete this.skinLegosToParseMap[key]; + return true; + } + return false; +}; +ParseQueue.prototype.clearAll = function() +{ + this.octreesLod0ReferencesToParseMap = {}; + this.octreesLod0ModelsToParseMap = {}; + this.octreesLod2LegosToParseMap = {}; +}; +ParseQueue.prototype.eraseAny = function(octree) +{ + this.eraseOctreeLod0ReferencesToParse(octree); + this.eraseOctreeLod0ModelsToParse(octree); + this.eraseOctreeLod2LegosToParse(octree); +}; +ParseQueue.prototype.initCounters = function() +{ + this.pCloudPartitionsParsed = 0; +}; @@ -42279,1782 +42148,3141 @@ PolyLine.prototype.getPoints = function(resultPointsArray) 'use strict'; /** - * 어떤 일을 하고 있습니까? - * @class Profile + * ProcessQueue + * + * @alias ProcessQueue + * @class ProcessQueue */ -var Profile = function() +var ProcessQueue = function() { - if (!(this instanceof Profile)) + if (!(this instanceof ProcessQueue)) { throw new Error(Messages.CONSTRUCT_ERROR); } - this.outerRing; // one Ring. - this.innerRingsList; // class: RingsList. + this.nodesToDeleteMap = {}; + this.nodesToDeleteModelReferencesMap = {}; + this.nodesToDeleteLessThanLod3Map = {}; + this.nodesToDeleteLessThanLod4Map = {}; + this.nodesToDeleteLessThanLod5Map = {}; + this.nodesToDeleteLodMeshMap = {}; // no used. + this.tinTerrainsToDeleteMap = {}; + + // Test. + this.octreeToDeletePCloudsMap = {}; }; -/** - * 어떤 일을 하고 있습니까? - * @returns vertexList - */ -Profile.prototype.newOuterRing = function() +ProcessQueue.prototype.putOctreeToDeletePCloud = function(octree, aValue) { - if (this.outerRing === undefined) - { this.outerRing = new Ring(); } - else - { - this.outerRing.deleteObjects(); - } + // provisionally "aValue" can be anything. + if (aValue === undefined) + { aValue = 0; } + + if (octree === undefined) + { return; } - return this.outerRing; + var key = octree.octreeKey; + this.octreeToDeletePCloudsMap[key] = octree; }; -/** - * 어떤 일을 하고 있습니까? - * @returns vertexList - */ -Profile.prototype.newInnerRing = function() +ProcessQueue.prototype.existOctreeToDeletePCloud = function(octree) { - if (this.innerRingsList === undefined) - { this.innerRingsList = new RingsList(); } - - var innerRing = this.innerRingsList.newRing(); + if (octree === undefined) + { return false; } - return innerRing; + var key = octree.octreeKey; + if (this.octreeToDeletePCloudsMap.hasOwnProperty(key)) + { + return true; + } + return false; }; -/** - * 어떤 일을 하고 있습니까? - * @returns vertexList - */ -Profile.prototype.deleteObjects = function() +ProcessQueue.prototype.eraseOctreeToDeletePCloud = function(octree) { - if (this.outerRing) + // this erases the octree from the "octreeToDeletePCloudsMap". + if (octree === undefined) + { return false; } + + var key = octree.octreeKey; + if (this.octreeToDeletePCloudsMap.hasOwnProperty(key)) { - this.outerRing.deleteObjects(); - this.outerRing = undefined; + delete this.octreeToDeletePCloudsMap[key]; + return true; } + return false; +}; - if (this.innerRingsList) +ProcessQueue.prototype.putNodeToDeleteLodMesh = function(node, aValue) +{ + if (node.isReferenceNode()) + { return; } + + // provisionally "aValue" can be anything. + if (aValue === undefined) + { aValue = 0; } + + if (node.data === undefined || node.data.neoBuilding === undefined) + { return; } + + var key = node.data.neoBuilding.buildingId; + this.nodesToDeleteLodMeshMap[key] = node; + + //this.nodesToDeleteLodMeshMap.set(node, aValue); +}; + +ProcessQueue.prototype.eraseNodeToDeleteLodMesh = function(node) +{ + // this erases the node from the "nodesToDeleteLessThanLod3Map". + if (node.data === undefined || node.data.neoBuilding === undefined) + { return; } + + var key = node.data.neoBuilding.buildingId; + if (this.nodesToDeleteLodMeshMap.hasOwnProperty(key)) { - this.innerRingsList.deleteObjects(); - this.innerRingsList = undefined; + delete this.nodesToDeleteLodMeshMap[key]; + return true; } + return false; + //return this.nodesToDeleteLodMeshMap.delete(node); }; -/** - * 어떤 일을 하고 있습니까? - * @returns vertexList - */ +ProcessQueue.prototype.putTinTerrainToDelete = function(tinTerrain, aValue) +{ + // provisionally "aValue" can be anything. + if (aValue === undefined) + { aValue = 0; } + + if (tinTerrain === undefined) + { return; } + + var key = tinTerrain.pathName; + this.tinTerrainsToDeleteMap[key] = tinTerrain; +}; -Profile.prototype.hasHoles = function() +ProcessQueue.prototype.eraseTinTerrainToDelete = function(tinTerrain) { - if (this.innerRingsList === undefined || this.innerRingsList.getRingsCount() === 0) + // this erases the tinTerrain from the "tinTerrainsToDeleteMap". + if (tinTerrain === undefined) { return false; } - return true; + var key = tinTerrain.pathName; + if (this.tinTerrainsToDeleteMap.hasOwnProperty(key)) + { + delete this.tinTerrainsToDeleteMap[key]; + return true; + } + return false; }; -/** - * 어떤 일을 하고 있습니까? - * @returns vertexList - */ - -Profile.prototype.getVBO = function(resultVbo) +ProcessQueue.prototype.putNodeToDeleteLessThanLod3 = function(node, aValue) { - if (this.outerRing === undefined) - { return resultVbo; } + if (node.isReferenceNode()) + { return; } - var generalPolygon = this.getGeneralPolygon(undefined); - generalPolygon.getVbo(resultVbo); + // provisionally "aValue" can be anything. + if (aValue === undefined) + { aValue = 0; } + + if (node.data === undefined || node.data.neoBuilding === undefined) + { return; } + + var key = node.data.neoBuilding.buildingId; + this.nodesToDeleteLessThanLod3Map[key] = node; }; -/** - * 어떤 일을 하고 있습니까? - * @returns vertexList - */ - -Profile.prototype.getConvexFacesIndicesData = function(resultGeneralIndicesData) +ProcessQueue.prototype.eraseNodeToDeleteLessThanLod3 = function(node) { - if (this.outerRing === undefined) - { return resultVbo; } + // this erases the node from the "nodesToDeleteLessThanLod3Map". + if (node.data === undefined || node.data.neoBuilding === undefined) + { return; } - var generalPolygon = this.getGeneralPolygon(undefined); + var key = node.data.neoBuilding.buildingId; + if (this.nodesToDeleteLessThanLod3Map.hasOwnProperty(key)) + { + delete this.nodesToDeleteLessThanLod3Map[key]; + return true; + } + return false; +}; + +ProcessQueue.prototype.putNodeToDeleteLessThanLod4 = function(node, aValue) +{ + if (node.isReferenceNode()) + { return; } - if (resultGeneralIndicesData === undefined) - { resultGeneralIndicesData = []; } + // provisionally "aValue" can be anything. + if (aValue === undefined) + { aValue = 0; } + + if (node.data === undefined || node.data.neoBuilding === undefined) + { return; } - // 1rst, set idxInList all points.*** - this.outerRing.polygon.point2dList.setIdxInList(); + var key = node.data.neoBuilding.buildingId; + this.nodesToDeleteLessThanLod4Map[key] = node; +}; + +ProcessQueue.prototype.eraseNodeToDeleteLessThanLod4 = function(node) +{ + // this erases the node from the "nodesToDeleteLessThanLod4Map". + if (node.data === undefined || node.data.neoBuilding === undefined) + { return; } - if (this.innerRingsList !== undefined) + var key = node.data.neoBuilding.buildingId; + if (this.nodesToDeleteLessThanLod4Map.hasOwnProperty(key)) { - var innerRingsCount = this.innerRingsList.getRingsCount(); - for (var i=0; i maxDeleteBuildingsCount) + // { break; } + //} + + + for (var key in this.nodesToDeleteMap) { - // calculate the most left-down innerRing.*** - innersBRect = RingsList.getBoundingRectangle(innerRingsArray, innersBRect); - innersBRectLeftDownPoint.set(innersBRect.minX, innersBRect.minY); + if (Object.prototype.hasOwnProperty.call(this.nodesToDeleteMap, key)) + { + //node = nodesToDeleteArray[i]; + node = this.nodesToDeleteMap[key]; + + if (node === undefined) + { continue; } + + neoBuilding = node.data.neoBuilding; + this.eraseNodeToDelete(node); + + if (neoBuilding === undefined) + { continue; } - objectsArray.length = 0; // init.*** - objectsArray = RingsList.getSortedRingsByDistToPoint(innersBRectLeftDownPoint, innerRingsArray, objectsArray); + var deleteMetaData = true; + if (key === 1) + { deleteMetaData = false; } + this.deleteNeoBuilding(gl, neoBuilding, magoManager); + } + } - objectAux = objectsArray[0]; - hole = objectAux.ring; - holeIdx = objectAux.ringIdx; - holePolygon = hole.polygon; - innerPointIdx = objectAux.pointIdx; - holePolygon.calculateNormal(); - - if (this.eliminateHolePolygon(computingPolygon, hole, innerPointIdx, resultPolygon)) + // now delete modelReferences of lod2Octrees. + var modelRefsDeletedCount = 0; + for (var key in this.nodesToDeleteModelReferencesMap) + { + if (Object.prototype.hasOwnProperty.call(this.nodesToDeleteModelReferencesMap, key)) { - computingPolygon = resultPolygon; + //node = nodesToDeleteModelReferencesArray[i]; + node = this.nodesToDeleteModelReferencesMap[key]; - if (innerRingsArray.length == 1) + if (node.data === undefined) + { continue; } + + neoBuilding = node.data.neoBuilding; + this.eraseNodeToDeleteModelReferences(neoBuilding); + if (neoBuilding === undefined) + { continue; } + + if (neoBuilding.octree) { - finished = true; - break; + neoBuilding.octree.deleteObjectsModelReferences(gl, magoManager.vboMemoryManager); + neoBuilding.octree.deletePCloudObjects(gl, magoManager.vboMemoryManager); } - // erase the hole from innerRingsArray.*** - innerRingsArray.splice(holeIdx, 1); - resultPolygon = new Polygon(); + if (neoBuilding.motherBlocksArray.length > 0 || neoBuilding.motherNeoReferencesArray.length > 0) + { + modelRefsDeletedCount ++; + } + neoBuilding.deleteObjectsModelReferences(gl, magoManager.vboMemoryManager); + + if (modelRefsDeletedCount > 10) + { break; } } - i++; } - resultHolesEliminatedPolygon = computingPolygon; - return resultHolesEliminatedPolygon; -}; - -/** - * 어떤 일을 하고 있습니까? - * @returns vertexList - */ -Profile.prototype.checkNormals = function() -{ - if (this.outerRing === undefined) - { return; } - - // 1rst, calculate the outerNormal.*** - var outerRing = this.outerRing; - if (outerRing.polygon === undefined) - { outerRing.makePolygon(); } - var outerPolygon = outerRing.polygon; - var concavePointsIndices = outerPolygon.calculateNormal(concavePointsIndices); - var outerNormal = outerPolygon.normal; - if (this.innerRingsList === undefined) - { return; } - // if there are inners, the innerNormals must be inverse of the outerNormal.*** - var innerRing; - var innerPolygon; - var innerNormal; - var innersCount = this.innerRingsList.getRingsCount(); - for (var i=0; i 0 || neoBuilding.motherNeoReferencesArray.length > 0) + { + modelRefsDeletedCount ++; + } + + neoBuilding.deleteObjectsModelReferences(gl, magoManager.vboMemoryManager); + neoBuilding.deleteObjectsLod2(gl, magoManager.vboMemoryManager); + deletedCount++; + + if (deletedCount > 10) + { break; } + } + } } -}; - -/** - * 어떤 일을 하고 있습니까? - * @returns vertexList - */ -Profile.prototype.TEST__setFigure_1 = function() -{ - // complicated polygon with multiple holes.*** - var polyLine; - var arc; - var circle; - var rect; - var point3d; - var star; - - // Outer ring.************************************** - var outerRing = this.newOuterRing(); - polyLine = outerRing.newElement("POLYLINE"); - point3d = polyLine.newPoint2d(7, 7); // 0 - point3d = polyLine.newPoint2d(0, 7); // 1 - point3d = polyLine.newPoint2d(0, 0); // 2 - point3d = polyLine.newPoint2d(7, 0); // 3 - - arc = outerRing.newElement("ARC"); - arc.setCenterPosition(7, 3.5); - arc.setRadius(3.5); - arc.setStartAngleDegree(-90.0); - arc.setSweepAngleDegree(180.0); - arc.numPointsFor360Deg = 24; - - // hole.*** - var innerRing = this.newInnerRing(); - rect = innerRing.newElement("RECTANGLE"); - rect.setCenterPosition(3, 3); - rect.setDimensions(2, 2); -}; - -/** - * 어떤 일을 하고 있습니까? - * @returns vertexList - */ -Profile.prototype.TEST__setFigureHole_2 = function() -{ - // complicated polygon with multiple holes.*** - var polyLine; - var arc; - var circle; - var rect; - var point3d; - var star; - - // Outer ring.************************************** - var outerRing = this.newOuterRing(); - - polyLine = outerRing.newElement("POLYLINE"); - point3d = polyLine.newPoint2d(-13, 3); // 0 - point3d = polyLine.newPoint2d(-13, -11); // 1 - - arc = outerRing.newElement("ARC"); - arc.setCenterPosition(-8, -11); - arc.setRadius(5); - arc.setStartAngleDegree(180.0); - arc.setSweepAngleDegree(90.0); - arc.numPointsFor360Deg = 24; - - polyLine = outerRing.newElement("POLYLINE"); - point3d = polyLine.newPoint2d(-8, -16); // 0 - point3d = polyLine.newPoint2d(-5, -16); // 1 - point3d = polyLine.newPoint2d(-3, -15); // 2 - point3d = polyLine.newPoint2d(-3, -14); // 3 - point3d = polyLine.newPoint2d(-5, -12); // 4 - point3d = polyLine.newPoint2d(-3, -11); // 5 - point3d = polyLine.newPoint2d(-2, -9); // 6 - point3d = polyLine.newPoint2d(3, -9); // 7 - - arc = outerRing.newElement("ARC"); - arc.setCenterPosition(9, -9); - arc.setRadius(6); - arc.setStartAngleDegree(180.0); - arc.setSweepAngleDegree(180.0); - arc.numPointsFor360Deg = 24; - - polyLine = outerRing.newElement("POLYLINE"); - point3d = polyLine.newPoint2d(15, -9); // 0 - point3d = polyLine.newPoint2d(16, -9); // 1 - point3d = polyLine.newPoint2d(16, 4); // 2 - - arc = outerRing.newElement("ARC"); - arc.setCenterPosition(11, 4); - arc.setRadius(5); - arc.setStartAngleDegree(0.0); - arc.setSweepAngleDegree(90.0); - arc.numPointsFor360Deg = 24; - - polyLine = outerRing.newElement("POLYLINE"); - point3d = polyLine.newPoint2d(11, 9); // 0 - point3d = polyLine.newPoint2d(4, 9); // 1 - - arc = outerRing.newElement("ARC"); - arc.setCenterPosition(4, 11); - arc.setRadius(2); - arc.setStartAngleDegree(-90.0); - arc.setSweepAngleDegree(-180.0); - arc.numPointsFor360Deg = 24; - - polyLine = outerRing.newElement("POLYLINE"); - point3d = polyLine.newPoint2d(4, 13); // 0 - point3d = polyLine.newPoint2d(9, 13); // 1 - - arc = outerRing.newElement("ARC"); - arc.setCenterPosition(9, 14.5); - arc.setRadius(1.5); - arc.setStartAngleDegree(-90.0); - arc.setSweepAngleDegree(180.0); - arc.numPointsFor360Deg = 24; - - polyLine = outerRing.newElement("POLYLINE"); - point3d = polyLine.newPoint2d(9, 16); // 0 - point3d = polyLine.newPoint2d(2, 16); // 1 - point3d = polyLine.newPoint2d(0, 14); // 2 - point3d = polyLine.newPoint2d(-4, 16); // 3 - point3d = polyLine.newPoint2d(-9, 16); // 4 - - arc = outerRing.newElement("ARC"); - arc.setCenterPosition(-9, 14); - arc.setRadius(2); - arc.setStartAngleDegree(90.0); - arc.setSweepAngleDegree(180.0); - arc.numPointsFor360Deg = 24; - - polyLine = outerRing.newElement("POLYLINE"); - point3d = polyLine.newPoint2d(-9, 12); // 0 - point3d = polyLine.newPoint2d(-6, 12); // 1 - - arc = outerRing.newElement("ARC"); - arc.setCenterPosition(-6, 10.5); - arc.setRadius(1.5); - arc.setStartAngleDegree(90.0); - arc.setSweepAngleDegree(-180.0); - arc.numPointsFor360Deg = 24; - - polyLine = outerRing.newElement("POLYLINE"); - point3d = polyLine.newPoint2d(-6, 9); // 0 - point3d = polyLine.newPoint2d(-7, 9); // 1 - - arc = outerRing.newElement("ARC"); - arc.setCenterPosition(-7, 3); - arc.setRadius(6); - arc.setStartAngleDegree(90.0); - arc.setSweepAngleDegree(90.0); - arc.numPointsFor360Deg = 24; - - // Holes.************************************************** - // Hole 1.************************************************* - var innerRing = this.newInnerRing(); - - polyLine = innerRing.newElement("POLYLINE"); - point3d = polyLine.newPoint2d(-9, 3); // 0 - point3d = polyLine.newPoint2d(-10, -4); // 1 - point3d = polyLine.newPoint2d(-10, -8); // 2 - point3d = polyLine.newPoint2d(-8, -11); // 3 - point3d = polyLine.newPoint2d(-3, -7); // 4 - point3d = polyLine.newPoint2d(4, -7); // 5 - - arc = innerRing.newElement("ARC"); - arc.setCenterPosition(8, -7); - arc.setRadius(4); - arc.setStartAngleDegree(180.0); - arc.setSweepAngleDegree(180.0); - arc.numPointsFor360Deg = 24; - - polyLine = innerRing.newElement("POLYLINE"); - point3d = polyLine.newPoint2d(12, -7); // 0 - point3d = polyLine.newPoint2d(12, -4); // 1 - point3d = polyLine.newPoint2d(8, -10); // 2 - point3d = polyLine.newPoint2d(4, -5); // 3 - point3d = polyLine.newPoint2d(-8, -5); // 4 - point3d = polyLine.newPoint2d(-7, 4); // 5 - point3d = polyLine.newPoint2d(9, 4); // 6 - point3d = polyLine.newPoint2d(9, -5); // 7 - point3d = polyLine.newPoint2d(14, 2); // 8 - point3d = polyLine.newPoint2d(13, 2); // 9 - point3d = polyLine.newPoint2d(11, 0); // 10 - point3d = polyLine.newPoint2d(11, 7); // 11 - point3d = polyLine.newPoint2d(13, 8); // 12 - point3d = polyLine.newPoint2d(5, 8); // 13 - point3d = polyLine.newPoint2d(9, 6); // 14 - point3d = polyLine.newPoint2d(-6, 6); // 15 - - arc = innerRing.newElement("ARC"); - arc.setCenterPosition(-6, 3); - arc.setRadius(3); - arc.setStartAngleDegree(90.0); - arc.setSweepAngleDegree(90.0); - arc.numPointsFor360Deg = 24; - + deletedCount = 0; + for (var key in this.nodesToDeleteLessThanLod4Map) + { + if (Object.prototype.hasOwnProperty.call(this.nodesToDeleteLessThanLod4Map, key)) + { + node = this.nodesToDeleteLessThanLod4Map[key]; + if (node.data === undefined) + { continue; } - // Hole 2.************************************************* - innerRing = this.newInnerRing(); - circle = innerRing.newElement("CIRCLE"); - circle.setCenterPosition(-10, -13); - circle.setRadius(1); - - // Hole 3.************************************************* - innerRing = this.newInnerRing(); - star = innerRing.newElement("STAR"); - star.setCenterPosition(-6.5, -14); - star.setRadiusCount(5); - star.setInteriorRadius(0.6); - star.setExteriorRadius(2); - - // Hole 4.************************************************* - innerRing = this.newInnerRing(); - star = innerRing.newElement("STAR"); - star.setCenterPosition(-9, 14); - star.setRadiusCount(6); - star.setInteriorRadius(0.5); - star.setExteriorRadius(1.5); - - // Hole 5.************************************************* - innerRing = this.newInnerRing(); - rect = innerRing.newElement("RECTANGLE"); - rect.setCenterPosition(-4.5, 1.5); - rect.setDimensions(3, 3); - - // Hole 6.************************************************* - innerRing = this.newInnerRing(); - circle = innerRing.newElement("CIRCLE"); - circle.setCenterPosition(-4.5, -2.5); - circle.setRadius(2); - - // Hole 7.************************************************* - innerRing = this.newInnerRing(); - star = innerRing.newElement("STAR"); - star.setCenterPosition(0, 0); - star.setRadiusCount(5); - star.setInteriorRadius(1); - star.setExteriorRadius(2.5); - - // Hole 8.************************************************* - innerRing = this.newInnerRing(); - circle = innerRing.newElement("CIRCLE"); - circle.setCenterPosition(-6, 14); - circle.setRadius(1.5); + if (this.eraseNodeToDeleteLessThanLod4(node)) + { + neoBuilding = node.data.neoBuilding; + if (neoBuilding === undefined) + { continue; } + + neoBuilding.deleteObjectsModelReferences(gl, magoManager.vboMemoryManager); + neoBuilding.deleteObjectsLod2(gl, magoManager.vboMemoryManager); + neoBuilding.deleteObjectsLodMesh(gl, magoManager.vboMemoryManager, "lod3"); + deletedCount++; + + if (deletedCount > 10) + { break; } + } + } + } - // Hole 9.************************************************* - innerRing = this.newInnerRing(); - star = innerRing.newElement("STAR"); - star.setCenterPosition(-1.5, 11); - star.setRadiusCount(12); - star.setInteriorRadius(0.6); - star.setExteriorRadius(2); + deletedCount = 0; + for (var key in this.nodesToDeleteLessThanLod5Map) + { + if (Object.prototype.hasOwnProperty.call(this.nodesToDeleteLessThanLod5Map, key)) + { + node = this.nodesToDeleteLessThanLod5Map[key]; + if (node.data === undefined) + { continue; } + + if (this.eraseNodeToDeleteLessThanLod5(node)) + { + neoBuilding = node.data.neoBuilding; + if (neoBuilding === undefined) + { continue; } + + neoBuilding.deleteObjectsModelReferences(gl, magoManager.vboMemoryManager); + neoBuilding.deleteObjectsLod2(gl, magoManager.vboMemoryManager); + neoBuilding.deleteObjectsLodMesh(gl, magoManager.vboMemoryManager, "lod3"); + neoBuilding.deleteObjectsLodMesh(gl, magoManager.vboMemoryManager, "lod4"); + deletedCount++; + + if (deletedCount > 10) + { break; } + } + } + } - // Hole 10.************************************************* - innerRing = this.newInnerRing(); - star = innerRing.newElement("STAR"); - star.setCenterPosition(13.5, 5); - star.setRadiusCount(25); - star.setInteriorRadius(0.4); - star.setExteriorRadius(1.5); - // Hole 11.************************************************* - innerRing = this.newInnerRing(); - star = innerRing.newElement("STAR"); - star.setCenterPosition(9, -13); - star.setRadiusCount(10); - star.setInteriorRadius(0.4); - star.setExteriorRadius(1.5); + // now, delete lod0, lod1, lod2. + // now, delete tinTerrains. + var deletedCount = 0; + for (var key in this.tinTerrainsToDeleteMap) + { + if (Object.prototype.hasOwnProperty.call(this.tinTerrainsToDeleteMap, key)) + { + var tinTerrain = this.tinTerrainsToDeleteMap[key]; + if (tinTerrain === undefined) + { continue; } + + if (this.eraseTinTerrainToDelete(tinTerrain)) + { + tinTerrain.deleteObjects(magoManager); + tinTerrain = undefined; + deletedCount++; + } + + if (deletedCount > 10) + { break; } + } + } - // Hole 12.************************************************* - innerRing = this.newInnerRing(); - star = innerRing.newElement("STAR"); - star.setCenterPosition(5.5, 1.5); - star.setRadiusCount(7); - star.setInteriorRadius(0.7); - star.setExteriorRadius(2); + // PointsCloud. + var deletedCount = 0; + for (var key in this.octreeToDeletePCloudsMap) + { + if (Object.prototype.hasOwnProperty.call(this.octreeToDeletePCloudsMap, key)) + { + var octree = this.octreeToDeletePCloudsMap[key]; + if (octree === undefined) + { continue; } + + if (this.eraseOctreeToDeletePCloud(octree)) + { + octree.deletePCloudObjects(gl, magoManager.vboMemoryManager); + octree = undefined; + deletedCount++; + } + + if (deletedCount > 10000) + { break; } + } + } }; - - - - - - - - - - - - - - - - - - - 'use strict'; /** - * 어떤 일을 하고 있습니까? - * @class ProfilesList + * @class ProjectTree */ -var ProfilesList = function() +var ProjectTree = function() { - if (!(this instanceof ProfilesList)) + if (!(this instanceof ProjectTree)) { throw new Error(Messages.CONSTRUCT_ERROR); } - this.profilesArray; - this.auxiliarAxis; -}; - -/** - * 어떤 일을 하고 있습니까? - * @returns vertexList - */ -ProfilesList.prototype.newProfile = function() -{ - if (this.profilesArray === undefined) - { this.profilesArray = []; } + this.root; - var profile = new Profile(); - this.profilesArray.push(profile); - return profile; + this.nodesArray = []; }; +'use strict'; + /** * 어떤 일을 하고 있습니까? - * @returns vertexList + * @class ReaderWriter */ -ProfilesList.prototype.deleteObjects = function() +var ReaderWriter = function() { - if (this.profilesArray) + if (!(this instanceof ReaderWriter)) { - var profilesCount = this.profilesArray.length; - for (var i=0; i 1) - { - // mark the last as pointType = 0 - resultPointsArray[totalPointsCount-1].pointType = 0; // delete this.*** - - var errorDist = 10E-8; - var firstPoint = resultPointsArray[0]; - var lastPoint = resultPointsArray[totalPointsCount-1]; - if (firstPoint.isCoincidentToPoint(lastPoint, errorDist)) - { - // delete the last point.*** - lastPoint = resultPointsArray.pop(); - lastPoint.deleteObjects(); - lastPoint = undefined; - } - } - - return resultPointsArray; -}; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -'use strict'; -/** -* 어떤 일을 하고 있습니까? -* @class RingsList -*/ -var RingsList = function() +ReaderWriter.prototype.readInt8 = function(buffer, start, end) { - if (!(this instanceof RingsList)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - this.ringsArray; - this.idxInList; + var int8 = new Int8Array(buffer.slice(start, end)); + return int8[0]; }; /** - * 어떤 일을 하고 있습니까? - * @returns vertexList + * 버퍼에서 데이터를 읽어서 8비트 부호없는 정수값에 대한 배열의 0번째 값을 돌려줌 + * @param buffer 복사할 버퍼 + * @param start 시작 바이트 인덱스 + * @param end 끝 바이트 인덱스 + * @returns uint8[0] */ -RingsList.prototype.newRing = function() +ReaderWriter.prototype.readUInt8 = function(buffer, start, end) { - if (this.ringsArray === undefined) - { this.ringsArray = []; } - - var ring = new Ring(); - this.ringsArray.push(ring); - - return ring; + var uint8 = new Uint8Array(buffer.slice(start, end)); + return uint8[0]; }; /** * 어떤 일을 하고 있습니까? - * @returns vertexList + * @param buffer 변수 + * @param start 변수 + * @param end 변수 + * @returns int8_value */ -RingsList.prototype.deleteObjects = function() +ReaderWriter.prototype.readInt8ByteColor = function(buffer, start, end) { - if (this.ringsArray) - { - var ringsCount = this.ringsArray.length; - for (var i=0; i max_color_value) { int8_value = max_color_value; } - return this.ringsArray.length; + if (int8_value < 0) { int8_value += 256; } + + return int8_value; }; -/** - * 어떤 일을 하고 있습니까? - * @returns vertexList - */ -RingsList.prototype.getRingIdx = function(ring) +function loadWithXhr(fileName, xhr, timeOut) { - if (ring === undefined) - { return undefined; } - - var ringIdx; - var ringsCount = this.getRingsCount(); - var find = false; - var i=0; - while (!find && i= 300) { - find = true; - ringIdx = i; + deferred.reject(xhr.status); + return; } - i++; - } + else + { + // 3.1) DEFERRED를 해결한다. (모든 done()...을 동작시킬 것이다.) + deferred.resolve(xhr.response); + } + }; - return ringIdx; -}; - -/** - * 어떤 일을 하고 있습니까? - * @returns vertexList - */ -RingsList.prototype.getRing = function(idx) -{ - if (this.ringsArray === undefined) - { return undefined; } + xhr.ontimeout = function (e) + { + // XMLHttpRequest timed out.*** + deferred.reject(-1); + }; + + xhr.onerror = function(e) + { + console.log("Invalid XMLHttpRequest response type."); + deferred.reject(xhr.status); + }; - return this.ringsArray[idx]; + // 작업을 수행한다. + xhr.send(null); + + // 참고: jQuery.ajax를 사용할 수 있었고 해야할 수 있었다. + // 참고: jQuery.ajax는 Promise를 반환하지만 다른 Deferred/Promise를 사용하여 애플리케이션에 의미있는 구문으로 감싸는 것은 언제나 좋은 생각이다. + // ---- /AJAX 호출 ---- // + + // 2) 이 deferred의 promise를 반환한다. + return deferred.promise(); }; -/** - * 어떤 일을 하고 있습니까? - * @returns vertexList - */ -RingsList.getBoundingRectangle = function(ringsArray, resultBRect) +ReaderWriter.prototype.getNeoBlocksArraybuffer = function(fileName, lowestOctree, magoManager) { - if (this.resultBRect === undefined) - { resultBRect = new BoundingRectangle(); } + magoManager.fileRequestControler.modelRefFilesRequestedCount += 1; + var blocksList = lowestOctree.neoReferencesMotherAndIndices.blocksList; + blocksList.fileLoadState = CODE.fileLoadState.LOADING_STARTED; + var xhr; + //xhr = new XMLHttpRequest(); + blocksList.xhr = xhr; // possibility to cancel.*** - var ring; - var currBRect; - var ringsCount = ringsArray.length; - for (var i=0; i> 4) + { + case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: + // 0xxxxxxx + out += String.fromCharCode(c); + break; + case 12: case 13: + // 110x xxxx 10xx xxxx + char2 = array[i++]; + out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F)); + break; + case 14: + // 1110 xxxx 10xx xxxx 10xx xxxx + char2 = array[i++]; + char3 = array[i++]; + out += String.fromCharCode(((c & 0x0F) << 12) | + ((char2 & 0x3F) << 6) | + ((char3 & 0x3F) << 0)); + break; + } + } + return out; + }; + //BR_Project._f4d_header_readed = true; + magoManager.fileRequestControler.headerFilesRequestedCount += 1; + neoBuilding.metaData.fileLoadState = CODE.fileLoadState.LOADING_STARTED; + loadWithXhr(fileName).done(function(response) + { + var arrayBuffer = response; + if (arrayBuffer) + { + if (neoBuilding.metaData === undefined) + { + neoBuilding.metaData = new MetaData(); + } + + var metaData = neoBuilding.metaData; + var bytesReaded = metaData.parseFileHeaderAsimetricVersion(arrayBuffer, readerWriter); + + // Now, make the neoBuilding's octree.*** + if (neoBuilding.octree === undefined) { neoBuilding.octree = new Octree(undefined); } + neoBuilding.octree.neoBuildingOwnerId = neoBuilding.buildingId; + neoBuilding.octree.octreeKey = neoBuilding.buildingId + "_" + neoBuilding.octree.octree_number_name; + + // now, parse octreeAsimetric or octreePyramid (check metadata.projectDataType).*** + if (metaData.projectDataType === 5) + { bytesReaded = neoBuilding.octree.parsePyramidVersion(arrayBuffer, readerWriter, bytesReaded, neoBuilding); } + else + { bytesReaded = neoBuilding.octree.parseAsimetricVersion(arrayBuffer, readerWriter, bytesReaded, neoBuilding); } + + metaData.oct_min_x = neoBuilding.octree.centerPos.x - neoBuilding.octree.half_dx; + metaData.oct_max_x = neoBuilding.octree.centerPos.x + neoBuilding.octree.half_dx; + metaData.oct_min_y = neoBuilding.octree.centerPos.y - neoBuilding.octree.half_dy; + metaData.oct_max_y = neoBuilding.octree.centerPos.y + neoBuilding.octree.half_dy; + metaData.oct_min_z = neoBuilding.octree.centerPos.z - neoBuilding.octree.half_dz; + metaData.oct_max_z = neoBuilding.octree.centerPos.z + neoBuilding.octree.half_dz; + + // now parse materialsList of the neoBuilding. + //var ver0 = neoBuilding.metaData.version[0]; + //var ver1 = neoBuilding.metaData.version[2]; + //var ver2 = neoBuilding.metaData.version[4]; + + if (metaData.version === "0.0.1" || metaData.version === "0.0.2") + { + // read materials list. + var materialsCount = readerWriter.readInt32(arrayBuffer, bytesReaded, bytesReaded+4); bytesReaded += 4; + for (var i=0; i 0) + { + var texture = new Texture(); + texture.textureTypeName = textureTypeName; + texture.textureImageFileName = textureImageFileName; + + if (neoBuilding.texturesLoaded === undefined) + { neoBuilding.texturesLoaded = []; } + + neoBuilding.texturesLoaded.push(texture); + } + } + + // read geometry type data.*** + var lod; + var nameLength; + var lodBuildingDatasCount = (new Uint8Array(arrayBuffer.slice(bytesReaded, bytesReaded+ 1)))[0];bytesReaded += 1; + if (lodBuildingDatasCount !== undefined) + { + neoBuilding.lodBuildingDatasMap = {}; + + for (var i =0; i= 0; --y) + { + for (x = 0; x < width; ++x, i += bytesPerPixel) + { + j = (x * 4) + (y * bytesPerRow); + data[j] = content[i+2]; + data[j+1] = content[i+1]; + data[j+2] = content[i+0]; + data[j+3] = (bpp === 32 ? content[i+3] : 255); + } + } + return { + width : width, + height : height, + data : data + }; +}; +/** + * 어떤 일을 하고 있습니까? + * @param gl 변수 + * @param filePath_inServer 변수 + * @param texture 변수 + * @param neoBuilding 변수 + * @param magoManager 변수 + */ +ReaderWriter.prototype.readNeoReferenceTexture = function(gl, filePath_inServer, texture, neoBuilding, magoManager) +{ + // Must know the fileExtension.*** + var extension = filePath_inServer.split('.').pop(); + + if (extension === "tga" || extension === "TGA" || extension === "Tga") + { + texture.fileLoadState = CODE.fileLoadState.LOADING_STARTED; + loadWithXhr(filePath_inServer).done(function(response) + { + var arrayBuffer = response; + if (arrayBuffer) + { + // decode tga.*** + // Test with tga decoder from https://github.com/schmittl/tgajs + var tga = new TGA(); + tga.load(arrayBuffer); + // End decoding.--------------------------------------------------- + + //var tga = magoManager.readerWriter.decodeTGA(arrayBuffer); // old code. + //if(tga) { + // gl.bindTexture(gl.TEXTURE_2D, texture.texId); + // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, tga.width, tga.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, tga.data); + // gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + // gl.generateMipmap(gl.TEXTURE_2D); + // texture.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; // file load finished.*** + //} + + // example values of tga.header + // alphaBits 0 + // bytePerPixel 3 + // colorMapDepth 0 + // colorMapIndex 0 + // colorMapLength 0 + // colorMapType 0 + // flags 32 + // hasColorMap false + // hasEncoding false + // height 2048 + // idLength 0 + // imageType 2 + // isGreyColor false + // offsetX 0 + // offsetY 0 + // origin 2 + // pixelDepth 24 + // width 2048 + + if (tga) + { + var rgbType; + if (tga.header.bytePerPixel === 3) + { + rgbType = gl.RGB; + + // test change rgb to bgr.*** + /* + var imageDataLength = tga.imageData.length; + var pixelsCount = imageDataLength/3; + var r, g, b; + for(var i=0; i 0 && texture.texId !== undefined) + { + gl.bindTexture(gl.TEXTURE_2D, texture.texId); + gl.texImage2D(gl.TEXTURE_2D, 0, rgbType, tga.header.width, tga.header.height, 0, rgbType, gl.UNSIGNED_BYTE, tga.imageData); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.generateMipmap(gl.TEXTURE_2D); + texture.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; // file load finished.*** + gl.bindTexture(gl.TEXTURE_2D, null); + } + } + } + }).fail(function(status) + { + if (neoBuilding) + { + console.log("xhr status = " + status); + if (status === 0) { neoBuilding.metaData.fileLoadState = 500; } + else { neoBuilding.metaData.fileLoadState = status; } + } + }).always(function() + { + magoManager.backGround_fileReadings_count -= 1; + if (magoManager.backGround_fileReadings_count < 0) { magoManager.backGround_fileReadings_count = 0; } + }); + } + else + { + var neoRefImage = new Image(); + texture.fileLoadState = CODE.fileLoadState.LOADING_STARTED; // file load started.*** + + //magoManager.backGround_fileReadings_count ++; + neoRefImage.onload = function() + { + // is possible that during loading image the building was deleted. Then return. + if (texture.texId === undefined) + { + return; + } + + // if "texture.texId" exist then bind it. + handleTextureLoaded(gl, neoRefImage, texture.texId); + texture.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; // file load finished.*** + + if (magoManager.backGround_fileReadings_count > 0 ) + { magoManager.backGround_fileReadings_count -=1; } + }; + + neoRefImage.onerror = function() + { + // doesn't exist or error loading + return; + }; + neoRefImage.src = filePath_inServer; + } +}; +ReaderWriter.loadBinaryData = function(fileName, dataContainer, weatherLayer) +{ + dataContainer.fileLoadState = CODE.fileLoadState.LOADING_STARTED; + + loadWithXhr(fileName).done(function(response) + { + var arrayBuffer = response; + if (arrayBuffer) + { + dataContainer.dataArraybuffer = arrayBuffer; + dataContainer.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; + arrayBuffer = null; + + weatherLayer.parseData(dataContainer); + } + else + { + dataContainer.fileLoadState = 500; + } + }).fail(function(status) + { + console.log("Invalid XMLHttpRequest status = " + status); + if (status === 0) { dataContainer.fileLoadState = 500; } + else { dataContainer.fileLoadState = status; } + }).always(function() + { + + }); +}; +/** + * 어떤 일을 하고 있습니까? + * @param gl 변수 + * @param filePath_inServer 변수 + * @param texture 변수 + * @param neoBuilding 변수 + * @param magoManager 변수 + */ +ReaderWriter.loadImage = function(gl, filePath_inServer, texture) +{ + // Must know the fileExtension.*** + //var extension = filePath_inServer.split('.').pop(); + + var image = new Image(); + texture.fileLoadState = CODE.fileLoadState.LOADING_STARTED; // file load started.*** + + image.onload = function() + { + // is possible that during loading image the building was deleted. Then return. + if (texture.texId === undefined) + { + return; + } + + function createTexture(_gl, filter, data, width, height) + { + var textureAux = _gl.createTexture(); + _gl.bindTexture(_gl.TEXTURE_2D, textureAux); + _gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + _gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE); + _gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE); + _gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, filter); + _gl.texParameteri(_gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, filter); + if (data instanceof Uint8Array) + { + _gl.texImage2D(_gl.TEXTURE_2D, 0, _gl.RGBA, width, height, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, data); + } + else + { + _gl.texImage2D(_gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, data); + } + _gl.bindTexture(_gl.TEXTURE_2D, null); + //gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); + return textureAux; + } + texture.texId = createTexture(gl, gl.LINEAR, image); + texture.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; // file load finished.*** + }; + image.onerror = function() + { + // doesn't exist or error loading + return; + }; + image.src = filePath_inServer; + +}; +/** + * 어떤 일을 하고 있습니까? + * @param gl 변수 + * @param filePath_inServer 변수 + * @param texture 변수 + * @param neoBuilding 변수 + * @param magoManager 변수 + */ +ReaderWriter.prototype.readLegoSimpleBuildingTexture = function(gl, filePath_inServer, texture, magoManager) +{ + var neoRefImage = new Image(); + texture.fileLoadState = CODE.fileLoadState.LOADING_STARTED; + magoManager.fileRequestControler.lowLodImagesRequestedCount += 1; + neoRefImage.onload = function() + { + if (texture.texId === undefined) + { texture.texId = gl.createTexture(); } + handleTextureLoaded(gl, neoRefImage, texture.texId); + texture.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; + + magoManager.fileRequestControler.lowLodImagesRequestedCount -= 1; + if (magoManager.backGround_fileReadings_count > 0 ) { magoManager.backGround_fileReadings_count -=1; } + if (magoManager.fileRequestControler.lowLodImagesRequestedCount < 0) { magoManager.fileRequestControler.lowLodImagesRequestedCount = 0; } + }; + neoRefImage.onerror = function() + { + if (texture.texId === undefined) + { + texture.texId = gl.createTexture(); + // Test wait for texture to load.******************************************** + gl.bindTexture(gl.TEXTURE_2D, texture.texId); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([200, 200, 200, 255])); // clear grey + gl.bindTexture(gl.TEXTURE_2D, null); + } + + texture.fileLoadState = CODE.fileLoadState.READY; + + magoManager.fileRequestControler.lowLodImagesRequestedCount -= 1; + if (magoManager.fileRequestControler.lowLodImagesRequestedCount < 0) { magoManager.fileRequestControler.lowLodImagesRequestedCount = 0; } + }; + neoRefImage.src = filePath_inServer; +}; - - -'use strict'; /** -* 어떤 일을 하고 있습니까? -* @class Segment2D -*/ -var Segment2D = function(strPoint2D, endPoint2D) + * 어떤 일을 하고 있습니까? + * @param gl 변수 + * @param fileName 변수 + * @param terranTile 변수 + * @param readerWriter 변수 + * @param magoManager 변수 + */ +ReaderWriter.prototype.getTileArrayBuffer = function(gl, fileName, terranTile, readerWriter, magoManager) { - if (!(this instanceof Segment2D)) + // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data + terranTile.fileReading_started = true; + // magoManager.fileRequestControler.backGround_fileReadings_count += 1; + // blocksList.fileLoadState = CODE.fileLoadState.LOADING_STARTED; + + loadWithXhr(fileName).done(function(response) { - throw new Error(Messages.CONSTRUCT_ERROR); - } + var arrayBuffer = response; + if (arrayBuffer) + { + //var BR_Project = new BRBuildingProject(); // Test.*** + //readerWriter.readF4D_Header(gl, arrayBuffer, BR_Project ); // Test.*** + terranTile.fileArrayBuffer = arrayBuffer; + terranTile.fileReading_finished = true; - this.startPoint2d; - this.endPoint2d; - - if (strPoint2D) - { this.startPoint2d = strPoint2D; } - - if (endPoint2D) - { this.endPoint2d = endPoint2D; } + if (magoManager.backGround_fileReadings_count > 0 ) { magoManager.backGround_fileReadings_count -=1; } + // blocksList.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; + arrayBuffer = null; + } + else + { + // blocksList.fileLoadState = 500; + } + }).fail(function(status) + { + console.log("xhr status = " + status); + // if(status === 0) blocksList.fileLoadState = 500; + // else blocksList.fileLoadState = status; + }).always(function() + { + // magoManager.fileRequestControler.filesRequestedCount -= 1; + // if(magoManager.fileRequestControler.filesRequestedCount < 0) magoManager.fileRequestControler.filesRequestedCount = 0; + }); }; -Segment2D.prototype.setPoints = function(strPoint2D, endPoint2D) +/** + * 어떤 일을 하고 있습니까? + * @param filePath_inServer 변수 + * @param pCloud 변수 + * @param readerWriter 변수 + * @param magoManager 변수 + */ +ReaderWriter.prototype.loadTINTerrain = function(fileName, tinTerrain, magoManager) { - if (strPoint2D) - { this.startPoint2d = strPoint2D; } + //magoManager.fileRequestControler.modelRefFilesRequestedCount += 1; + tinTerrain.fileLoadState = CODE.fileLoadState.LOADING_STARTED; - if (endPoint2D) - { this.endPoint2d = endPoint2D; } + loadWithXhr(fileName).done(function(response) + { + var arrayBuffer = response; + if (arrayBuffer) + { + tinTerrain.dataArrayBuffer = arrayBuffer; + tinTerrain.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; + //magoManager.parseQueue.putTinTerrainToParse(lowestOctree); // todo.*** + arrayBuffer = undefined; + } + else + { + tinTerrain.fileLoadState = 500; + } + }).fail(function(status) + { + tinTerrain.fileLoadState = CODE.fileLoadState.LOAD_FAILED; + //console.log("xhr status = " + status); + //if (status === 0) { lowestOctree.neoReferencesMotherAndIndices.fileLoadState = 500; } + //else { lowestOctree.neoReferencesMotherAndIndices.fileLoadState = status; } + }).always(function() + { + //magoManager.fileRequestControler.modelRefFilesRequestedCount -= 1; + //if (magoManager.fileRequestControler.modelRefFilesRequestedCount < 0) { magoManager.fileRequestControler.modelRefFilesRequestedCount = 0; } + }); }; -Segment2D.prototype.getVector = function(resultVector) +/** + * 어떤 일을 하고 있습니까? + * @param gl 변수 + * @param imageArrayBuffer 변수 + * @param magoManager 변수 + */ +ReaderWriter.prototype.imageFromArrayBuffer = function(gl, imageArrayBuffer, texture, magoManager, flip_y_texCoords) { - if (this.startPoint2d === undefined || this.endPoint2d === undefined) - { return undefined; } - - if (resultVector === undefined) - { resultVector = new Point2D(); } - - resultVector = this.startPoint2d.getVectorToPoint(this.endPoint2d, resultVector); - return resultVector; -}; + // example: allowedFileTypes = ["image/png", "image/jpeg", "image/gif"]; + var blob = new Blob( [ imageArrayBuffer ], { type: "image/png" } ); + var urlCreator = window.URL || window.webkitURL; + var imagenUrl = urlCreator.createObjectURL(blob); + var imageFromArray = new Image(); -Segment2D.prototype.getDirection = function(resultDir) -{ - if (resultDir === undefined) - { resultDir = new Point2D(); } - - resultDir = this.getVector(resultDir); - resultDir.unitary(); - - return resultDir; -}; + imageFromArray.onload = function () + { + if (flip_y_texCoords === undefined) + { flip_y_texCoords = false; } + + if (texture.texId === undefined) + { texture.texId = gl.createTexture(); } + handleTextureLoaded(gl, imageFromArray, texture.texId, flip_y_texCoords); + texture.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; + imageArrayBuffer = null; + }; -Segment2D.prototype.getBoundaryRectangle = function(resultBRect) -{ - if (resultBRect === undefined) - { resultBRect = new BoundaryRectangle(); } - - resultBRect.setInit(this.startPoint2d); - resultBRect.addPoint(this.endPoint2d); - - return resultBRect; + imageFromArray.onerror = function() + { + return; + }; + + imageFromArray.src = imagenUrl; }; -Segment2D.prototype.getLine = function(resultLine) +/** + * 어떤 일을 하고 있습니까? + * @param gl 변수 + * @param filePath_inServer 변수 + * @param texture 변수 + * @param magoManager 변수 + */ +ReaderWriter.prototype.loadWMSImage = function(gl, filePath_inServer, texture, magoManager, flip_y_texCoords) { - if (resultLine === undefined) - { resultLine = new Line2D(); } - - var dir = this.getDirection(); // unitary direction.*** - var strPoint = this.startPoint2d; - resultLine.setPointAndDir(strPoint.x, strPoint.y, dir.x, dir.y); - return resultLine; + texture.fileLoadState = CODE.fileLoadState.LOADING_STARTED; + var readWriter = this; + loadWithXhr(filePath_inServer).done(function(response) + { + var arrayBuffer = response; + if (arrayBuffer) + { + if (flip_y_texCoords === undefined) + { flip_y_texCoords = false; } + + readWriter.imageFromArrayBuffer(gl, arrayBuffer, texture, magoManager, flip_y_texCoords); + texture.fileLoadState = CODE.fileLoadState.LOADING_FINISHED; + } + }).fail(function(status) + { + console.log(status); + + }).always(function() + { + magoManager.backGround_fileReadings_count -= 1; + if (magoManager.backGround_fileReadings_count < 0) { magoManager.backGround_fileReadings_count = 0; } + }); + }; -Segment2D.prototype.getSquaredLength = function() + +ReaderWriter.prototype.handleTextureLoaded = function(gl, image, texture) { - return this.startPoint2d.squareDistToPoint(this.endPoint2d); + // https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL + //var gl = viewer.scene.context._gl; + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); // if need vertical mirror of the image.*** + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); // Original.*** + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); + gl.generateMipmap(gl.TEXTURE_2D); + gl.bindTexture(gl.TEXTURE_2D, null); }; -Segment2D.prototype.getLength = function() + +'use strict'; + +/** + * @class TinTerrain + */ +var TinTerrain = function(owner) { - return Math.sqrt(this.getSquaredLength()); + if (!(this instanceof TinTerrain)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + this.owner; // undefined if depth = 0. + this.depth; + if (owner) + { + this.owner = owner; + this.depth = owner.depth + 1; + } + else + { + this.depth = 0; + } + + this.childArray; // child array. + this.childMap; // example: this.childMap["LU"] = tinTerrainChild. + + // Data. + this.X; // tile index X. + this.Y; // tile index Y. + + // CencerPosition. + this.centerX; // Float64Array. + this.centerY; // Float64Array. + this.centerZ; // Float64Array. + + // positions(x, y, z), normals, texCoords, colors & indices array. + this.cartesiansArray; + this.normalsArray; + this.texCoordsArray; + this.colorsArray; + this.indices; + + // Tile extent. + this.geographicExtent; + this.sphereExtent; + + // Tile geometry data. + this.fileLoadState = 0; + this.dataArrayBuffer; + this.vboKeyContainer; // class: VBOVertexIdxCacheKeysContainer. + this.terrainPositionHIGH; + this.terrainPositionLOW; + + this.indexName; // example: "LU". + this.pathName; // example: "14//4567//516". + this.texture; + this.visible; + + // Test vars. Delete after test. + this.imageryGeoExtent; }; -Segment2D.prototype.intersectionWithPointByDistances = function(point, error) +TinTerrain.prototype.deleteObjects = function(magoManager) { - if (point === undefined) - { return undefined; } + var gl = magoManager.sceneState.gl; - if (error === undefined) - { error = 10E-8; } + // delete all tree under this tinTerrain. no delete tiles if depth < 2. + if (this.childMap !== undefined) + { + // subTile 0 (Left-Up). + var subTile_LU = this.childMap.LU; + if (subTile_LU !== undefined) + { + subTile_LU.deleteObjects(magoManager); + delete this.childMap.LU; + } + + // subTile 1 (Left-Down). + var subTile_LD = this.childMap.LD; + if (subTile_LD !== undefined) + { + subTile_LD.deleteObjects(magoManager); + delete this.childMap.LD; + } + + // subTile 2 (Right-Up). + var subTile_RU = this.childMap.RU; + if (subTile_RU !== undefined) + { + subTile_RU.deleteObjects(magoManager); + delete this.childMap.RU; + } + + // subTile 3 (Right-Down). + var subTile_RD = this.childMap.RD; + if (subTile_RD !== undefined) + { + subTile_RD.deleteObjects(magoManager); + delete this.childMap.RD; + } + + this.childMap = undefined; + } - // here no check line-point coincidance.*** + // no delete tiles if depth < 2. + if (this.depth < 2) + { return; } + + // now delete objects of this tinTerrain. + this.owner = undefined; + this.depth = undefined; + this.childArray = undefined; + this.childMap = undefined; - // now, check if is inside of the segment or if is coincident with any vertex of segment.*** - var distA = this.startPoint2d.distToPoint(point); - var distB = this.endPoint2d.distToPoint(point); - var distTotal = this.getLength(); + // Data. + this.X = undefined; // index X. + this.Y = undefined; // index Y. - if (distA < error) - { return Constant.INTERSECTION_POINT_A; } + // Tile extent. + if (this.geographicExtent !== undefined) + { + this.geographicExtent.deleteObjects(); + this.geographicExtent = undefined; + } - if (distB < error) - { return Constant.INTERSECTION_POINT_B; } + if (this.sphereExtent !== undefined) + { + this.sphereExtent.deleteObjects(); + this.sphereExtent = undefined; + } - if (distA> distTotal || distB> distTotal) + // Tile geometry data. + this.fileLoadState = 0; + this.dataArrayBuffer = undefined; + + if (this.vboKeyContainer !== undefined) { - return Constant.INTERSECTION_OUTSIDE; + this.vboKeyContainer.deleteGlObjects(gl, magoManager.vboMemoryManager); + this.vboKeyContainer = undefined; // class: VBOVertexIdxCacheKeysContainer. + } + this.terrainPositionHIGH = undefined; + this.terrainPositionLOW = undefined; - if (Math.abs(distA + distB - distTotal) < error) - { return Constant.INTERSECTION_INSIDE; } + this.indexName = undefined; + this.pathName = undefined; // example: "14//4567//516". + + if (this.texture !== undefined) + { + this.texture.deleteObjects(gl); + this.texture = undefined; + } + this.visible = undefined; }; -Segment2D.prototype.intersectionWithPoint = function(point, error) +TinTerrain.prototype.getPathName = function() { - if (point === undefined) - { return undefined; } + // this returns a string as: L//X//Y. + // example: "14//4567//516". + return this.depth.toString() + "\\" + this.X.toString() + "\\" + this.Y.toString(); +}; + +TinTerrain.prototype.setGeographicExtent = function(minLon, minLat, minAlt, maxLon, maxLat, maxAlt) +{ + if (this.geographicExtent === undefined) + { this.geographicExtent = new GeographicExtent(); } - if (error === undefined) - { error = 10E-8; } + var geoExtent = this.geographicExtent; - var line = this.getLine(); - if (!line.isCoincidentPoint(point, error)) - { return Constant.INTERSECTION_OUTSIDE; } // no intersection.*** + if (geoExtent.minGeographicCoord === undefined) + { geoExtent.minGeographicCoord = new GeographicCoord(); } - return this.intersectionWithPointByDistances(point, error); + if (geoExtent.maxGeographicCoord === undefined) + { geoExtent.maxGeographicCoord = new GeographicCoord(); } + + geoExtent.minGeographicCoord.setLonLatAlt(minLon, minLat, minAlt); + geoExtent.maxGeographicCoord.setLonLatAlt(maxLon, maxLat, maxAlt); }; -Segment2D.prototype.intersectionWithSegment = function(segment_B, error) +TinTerrain.prototype.isPrepared = function() { - if (segment_B === undefined) - { return undefined; } + // a tinTerrain is prepared if this is parsed and vbo maked and texture binded. - if (error === undefined) - { error = 10E-8; } + // Provisional solution.* + // Provisional solution.* + // Provisional solution.* + if (this.fileLoadState === CODE.fileLoadState.LOAD_FAILED) + { return true; } + // End provisional solution.------------------------------ + // End provisional solution.------------------------------ + // End provisional solution.------------------------------ - var myLine = this.getLine(); - var line = segment_B.getLine(); - var intersectionPoint = myLine.intersectionWithLine(line); + if (this.fileLoadState !== CODE.fileLoadState.PARSE_FINISHED) + { return false; } - if (intersectionPoint === undefined) - { return undefined; } // are parallels.*** + if (this.texture === undefined || this.texture.fileLoadState !== CODE.fileLoadState.LOADING_FINISHED) + { return false; } - // now use "intersectionWithPointByDistances" instead "intersectionWithPoint" bcos line-point intersection check is no necesary.*** - var intersectionType_A = this.intersectionWithPointByDistances(intersectionPoint); + if (this.vboKeyContainer === undefined || + this.vboKeyContainer.vboCacheKeysArray === undefined || + this.vboKeyContainer.vboCacheKeysArray.length === 0) + { return false; } - if (intersectionType_A === Constant.INTERSECTION_OUTSIDE) - { return Constant.INTERSECTION_OUTSIDE; } + return true; +}; + +TinTerrain.prototype.prepareTexture = function(magoManager, tinTerrainManager) +{ + var gl = magoManager.sceneState.gl; + this.texture = new Texture(); - var intersectionType_B = segment_B.intersectionWithPointByDistances(intersectionPoint); + // Provisionally test. + //var imagesDataPath = "\\images\\ko"; + //var textureFilePath = imagesDataPath + "\\funny_" + this.depth + ".jpg"; + //magoManager.readerWriter.readLegoSimpleBuildingTexture(gl, textureFilePath, this.texture, magoManager); + // End test.---------------------------------------------------------------------------------------------------- + + var geoServURL = tinTerrainManager.geoServURL; + var L = this.depth.toString(); + var X = this.X.toString(); + var Y = this.Y.toString(); - if (intersectionType_B === Constant.INTERSECTION_OUTSIDE) - { return Constant.INTERSECTION_OUTSIDE; } + X = (Math.floor(this.X/2)).toString(); + //L = (this.depth+1).toString(); - return Constant.INTERSECTION_INTERSECT; + + var tilePath = L + "&TileRow=" + Y + "&TileCol=" + X; + //var textureFilePath = geoServURL + "?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&Layer=mago3d:SejongBGM&Format=image/png&TileMatrixSet=EPSG:4326&TileMatrix=EPSG:4326:" + tilePath; + //https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}' + + var textureFilePath = "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/" + L + "/" + Y + "/" + X + ".png"; + + magoManager.readerWriter.loadWMSImage(gl, textureFilePath, this.texture, magoManager, false); + + // For elevation3D data. + //http://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer/tile/0/0/0 }; -Segment2D.prototype.hasPoint = function(point) +TinTerrain.prototype.prepareTinTerrainPlain = function(magoManager, tinTerrainManager) { - // returns if this segment has "point" as startPoint or endPoint.*** - if (point === undefined) - { return false; } - - if (point === this.startPoint2d || point === this.endPoint2d) - { return true; } + // This is a test function.!!! + // This function 1- loads file & 2- parses file & 3- makes vbo. + // 1rst, check if the parent is prepared. If parent is not prepared, then prepare the parent. - return false; + if (this.owner === undefined || this.owner.isPrepared()) + { + // 1rst, try to erase from procesQueue_deleting if exist. + magoManager.processQueue.eraseTinTerrainToDelete(this); + + // Prepare this tinTerrain. + this.fileLoadState = CODE.fileLoadState.PARSE_FINISHED; // Test code.!!! + if (this.fileLoadState === CODE.fileLoadState.READY) + { + //var pathName = this.getPathName(); + //var fileName = "CesiumTerrain/" + pathName + ".terrain"; + //magoManager.readerWriter.loadTINTerrain(fileName, this, magoManager); + + } + else if (this.fileLoadState === CODE.fileLoadState.LOADING_FINISHED) + { + // put the terrain into parseQueue. + //magoManager.parseQueue.putTinTerrainToParse(this, 0); + } + else if (this.fileLoadState === CODE.fileLoadState.PARSE_FINISHED && this.vboKeyContainer === undefined) + { + //this.decodeData(); + //this.makeVbo(magoManager.vboMemoryManager); + this.calculateCenterPosition(); + this.makeMeshVirtually(20, 20, undefined, undefined); + this.makeVbo(magoManager.vboMemoryManager); + } + else if (this.texture === undefined) + { + this.prepareTexture(magoManager, tinTerrainManager); + } + + return; + } + else + { + // Prepare ownerTinTerrain. + this.owner.prepareTinTerrainPlain(magoManager, tinTerrainManager); + return; + } }; -Segment2D.prototype.sharesPointsWithSegment = function(segment) +TinTerrain.prototype.prepareTinTerrain = function(magoManager, tinTerrainManager) { - if (segment === undefined) - { return false; } + // This function 1- loads file & 2- parses file & 3- makes vbo. + // 1rst, check if the parent is prepared. If parent is not prepared, then prepare the parent. - if (this.hasPoint(segment.startPoint2d) || this.hasPoint(segment.endPoint2d)) + if (this.owner === undefined || this.owner.isPrepared()) + { + // 1rst, try to erase from procesQueue_deleting if exist. + magoManager.processQueue.eraseTinTerrainToDelete(this); + + // Prepare this tinTerrain. + if (this.fileLoadState === CODE.fileLoadState.READY) + { + var pathName = this.getPathName(); + var fileName = "CesiumTerrain/" + pathName + ".terrain"; + magoManager.readerWriter.loadTINTerrain(fileName, this, magoManager); + + } + else if (this.fileLoadState === CODE.fileLoadState.LOADING_FINISHED) + { + // put the terrain into parseQueue. + magoManager.parseQueue.putTinTerrainToParse(this, 0); + } + else if (this.fileLoadState === CODE.fileLoadState.PARSE_FINISHED && this.vboKeyContainer === undefined) + { + this.decodeData(); + this.makeVbo(magoManager.vboMemoryManager); + } + else if (this.texture === undefined) + { + this.prepareTexture(magoManager, tinTerrainManager); + } + + return; + } + else + { + // Prepare ownerTinTerrain. + this.owner.prepareTinTerrain(magoManager, tinTerrainManager); + return; + } +}; + +TinTerrain.prototype.hasChildren = function() +{ + if (this.childMap !== undefined && this.childMap.length > 0) { return true; } return false; }; +TinTerrain.prototype.deleteTinTerrain = function(magoManager) +{ + // The quadTree must be deleted lowest-quads first. + // Check if this has child. If this has child, then, 1rst delete child. + if (this.hasChildren()) + { + // Delete children 1rst. + for (var key in this.childMap) + { + if (Object.prototype.hasOwnProperty.call(this.childMap, key)) + { + var child = this.childMap[key]; + child.deleteTinTerrain(magoManager); + } + } + + return false; + } + else + { + // 1rst, delete from parse-queue if exist. + magoManager.parseQueue.eraseTinTerrainToParse(this); + // put this tinTerrain into deleteQueue. + magoManager.processQueue.putTinTerrainToDelete(this, 0); + + // now, must erase from myOwner-childrenMap. + delete this.owner.childMap[this.indexName]; + + if (this.owner.childMap.length === 0) + { this.owner.childMap = undefined; } + + return true; + } +}; +TinTerrain.prototype.render = function(currentShader, magoManager, bDepth) +{ + if (this.owner === undefined || this.owner.isPrepared()) + { + if (this.isPrepared()) + { + if (this.fileLoadState === CODE.fileLoadState.LOAD_FAILED) // provisional solution. + { return; } + + // render this tinTerrain. + var gl = magoManager.sceneState.gl; + var renderWireframe = false; + + gl.bindTexture(gl.TEXTURE_2D, this.texture.texId); + + gl.uniform3fv(currentShader.buildingPosHIGH_loc, this.terrainPositionHIGH); + gl.uniform3fv(currentShader.buildingPosLOW_loc, this.terrainPositionLOW); + + var vboKey = this.vboKeyContainer.vboCacheKeysArray[0]; + + // Positions. + if (!vboKey.bindDataPosition(currentShader, magoManager.vboMemoryManager)) + { return false; } + + // TexCoords. + if (!bDepth) + { + if (!vboKey.bindDataTexCoord(currentShader, magoManager.vboMemoryManager)) + { return false; } + } + + // Normals. + // todo: + + // Colors. + // todo: + + // Indices. + if (!vboKey.bindDataIndice(currentShader, magoManager.vboMemoryManager)) + { return false; } + + var indicesCount = vboKey.indicesCount; + + if (renderWireframe) + { + var trianglesCount = indicesCount; + for (var i=0; i 5000)// && this.depth > 1) + { + // finish the process. + this.visible = true; + visibleTilesArray.push(this); + return; + } + + var currDepth = this.depth; + if (currDepth < maxDepth) + { + // must descend. + var curX = this.X; + var curY = this.Y; + var minLon = currMinGeographicCoords.longitude; + var minLat = currMinGeographicCoords.latitude; + var minAlt = currMinGeographicCoords.altitude; + var maxLon = currMaxGeographicCoords.longitude; + var maxLat = currMaxGeographicCoords.latitude; + var maxAlt = currMaxGeographicCoords.altitude; + var midLon = (minLon + maxLon)/ 2; + var midLat = (minLat + maxLat)/ 2; + + // create children if no exist. + // +--------------+--------------+ + // | subTile 0(LU)| subTile 2(RU)| + // | X = curX*2 | X = curX*2+1 | + // | Y = curY*2 | Y = curY*2 | + // | | | + // +--------------+--------------+ + // | subTile 1(LD)| subTile 3(RD)| + // | X = curX*2 | X = curX*2+1 | + // | Y = curY*2+1 | Y = curY*2+1 | + // | | | + // +--------------+--------------+ + + // Test imagery textures extent.** + var imageryMercatorMinX = this.imageryGeoExtent.minGeographicCoord.longitude; + var imageryMercatorMinY = this.imageryGeoExtent.minGeographicCoord.latitude; + var imageryMercatorMaxX = this.imageryGeoExtent.maxGeographicCoord.longitude; + var imageryMercatorMaxY = this.imageryGeoExtent.maxGeographicCoord.latitude; + var imageryMercatorMidX = (imageryMercatorMinX + imageryMercatorMaxX)/2; + var imageryMercatorMidY = (imageryMercatorMinY + imageryMercatorMaxY)/2; + // End test.------------------------------------------------------------------- + + if (this.childMap === undefined) + { this.childMap = {}; } + + // subTile 0 (Left-Up). + var subTile_LU = this.childMap.LU; + if (subTile_LU === undefined) + { + // if no exist -> create it. + subTile_LU = new TinTerrain(this); + subTile_LU.X = curX*2; + subTile_LU.Y = curY*2; + subTile_LU.setGeographicExtent(minLon, midLat, minAlt, midLon, maxLat, maxAlt); + subTile_LU.indexName = "LU"; + this.childMap.LU = subTile_LU; + + // Test imagery textures extent.** + if (subTile_LU.imageryGeoExtent === undefined) + { subTile_LU.imageryGeoExtent = new GeographicExtent(); } + subTile_LU.imageryGeoExtent.setExtent(imageryMercatorMinX, imageryMercatorMidY, 0.0, imageryMercatorMidX, imageryMercatorMaxY, 0.0); + // End test.------------------------------------------------------------------- + } + + // subTile 1 (Left-Down). + var subTile_LD = this.childMap.LD; + if (subTile_LD === undefined) + { + // if no exist -> create it. + subTile_LD = new TinTerrain(this); + subTile_LD.X = curX*2; + subTile_LD.Y = curY*2+1; + subTile_LD.setGeographicExtent(minLon, minLat, minAlt, midLon, midLat, maxAlt); + subTile_LD.indexName = "LD"; + this.childMap.LD = subTile_LD; + + // Test imagery textures extent.** + if (subTile_LD.imageryGeoExtent === undefined) + { subTile_LD.imageryGeoExtent = new GeographicExtent(); } + subTile_LD.imageryGeoExtent.setExtent(imageryMercatorMinX, imageryMercatorMinY, 0.0, imageryMercatorMidX, imageryMercatorMidY, 0.0); + // End test.------------------------------------------------------------------- + } + + // subTile 2 (Right-Up). + var subTile_RU = this.childMap.RU; + if (subTile_RU === undefined) + { + subTile_RU = new TinTerrain(this); + subTile_RU.X = curX*2+1; + subTile_RU.Y = curY*2; + subTile_RU.setGeographicExtent(midLon, midLat, minAlt, maxLon, maxLat, maxAlt); + subTile_RU.indexName = "RU"; + this.childMap.RU = subTile_RU; + + // Test imagery textures extent.** + if (subTile_RU.imageryGeoExtent === undefined) + { subTile_RU.imageryGeoExtent = new GeographicExtent(); } + subTile_RU.imageryGeoExtent.setExtent(imageryMercatorMidX, imageryMercatorMidY, 0.0, imageryMercatorMaxX, imageryMercatorMaxY, 0.0); + // End test.------------------------------------------------------------------- + } + + // subTile 3 (Right-Down). + var subTile_RD = this.childMap.RD; + if (subTile_RD === undefined) + { + subTile_RD = new TinTerrain(this); + subTile_RD.X = curX*2+1; + subTile_RD.Y = curY*2+1; + subTile_RD.setGeographicExtent(midLon, minLat, minAlt, maxLon, midLat, maxAlt); + subTile_RD.indexName = "RD"; + this.childMap.RD = subTile_RD; + + // Test imagery textures extent.** + if (subTile_RD.imageryGeoExtent === undefined) + { subTile_RD.imageryGeoExtent = new GeographicExtent(); } + subTile_RD.imageryGeoExtent.setExtent(imageryMercatorMidX, imageryMercatorMinY, 0.0, imageryMercatorMaxX, imageryMercatorMidY, 0.0); + // End test.------------------------------------------------------------------- + } + + // now, do frustumCulling for each childTiles. + subTile_LU.getFrustumIntersectedTinTerrainsQuadTree(frustum, maxDepth, camPos, magoManager, visibleTilesArray, noVisibleTilesArray); + subTile_LD.getFrustumIntersectedTinTerrainsQuadTree(frustum, maxDepth, camPos, magoManager, visibleTilesArray, noVisibleTilesArray); + subTile_RU.getFrustumIntersectedTinTerrainsQuadTree(frustum, maxDepth, camPos, magoManager, visibleTilesArray, noVisibleTilesArray); + subTile_RD.getFrustumIntersectedTinTerrainsQuadTree(frustum, maxDepth, camPos, magoManager, visibleTilesArray, noVisibleTilesArray); + } + else + { + // finish the process. + this.visible = true; + visibleTilesArray.push(this); + return; + } + } +}; +TinTerrain.prototype.calculateCenterPosition = function() +{ + // Note: The centerPosition is Float64Array type. + // The centerPosition of tiles are calculate with "altitude" = 0;. + var altitude = 0.0; + var resultGeographicCoord; + resultGeographicCoord = this.geographicExtent.getMidPoint(resultGeographicCoord); + + var centerLon = resultGeographicCoord.longitude; + var centerLat = resultGeographicCoord.latitude; + + var resultCartesian; + resultCartesian = Globe.geographicToCartesianWgs84(centerLon, centerLat, altitude, resultCartesian); + + // Float64Array. + this.centerX = new Float64Array([resultCartesian[0]]); + this.centerY = new Float64Array([resultCartesian[1]]); + this.centerZ = new Float64Array([resultCartesian[2]]); +}; + +/** + * Calculate the translation and scale for a particular {@link TileImagery} attached to a + * particular terrain tile. + * + * @private + * + * @param {Tile} tile The terrain tile. + * @param {TileImagery} tileImagery The imagery tile mapping. + * @returns {Cartesian4} The translation and scale where X and Y are the translation and Z and W + * are the scale. + */ + /* +ImageryLayer.prototype._calculateTextureTranslationAndScale = function(tile, tileImagery) { + var imageryRectangle = tileImagery.readyImagery.rectangle; + var terrainRectangle = tile.rectangle; + + if (tileImagery.useWebMercatorT) { + var tilingScheme = tileImagery.readyImagery.imageryLayer.imageryProvider.tilingScheme; + imageryRectangle = tilingScheme.rectangleToNativeRectangle(imageryRectangle, imageryBoundsScratch); + terrainRectangle = tilingScheme.rectangleToNativeRectangle(terrainRectangle, terrainRectangleScratch); + } + + var terrainWidth = terrainRectangle.width; + var terrainHeight = terrainRectangle.height; + + var scaleX = terrainWidth / imageryRectangle.width; + var scaleY = terrainHeight / imageryRectangle.height; + return new Cartesian4( + scaleX * (terrainRectangle.west - imageryRectangle.west) / terrainWidth, + scaleY * (terrainRectangle.south - imageryRectangle.south) / terrainHeight, + scaleX, + scaleY); +}; +*/ +TinTerrain.prototype.calculateTextureCoordinateTranslationAndScale = function() +{ + // In construction function. + // Tile Images from World Imagery has different extent to the tiles obtained by CRS84 rules. + // To match image texture on to the tile, must calculate texture's coordinates translation & scale. + // The calculation must to do onto mercator projection. + + // Calculate terrain mercator extension. + var terrainMercatorMinPoint2d, terrainMercatorMaxPoint2d; + terrainMercatorMinPoint2d = this.geographicExtent.minGeographicCoord.getMercatorProjection(terrainMercatorMinPoint2d); + terrainMercatorMaxPoint2d = this.geographicExtent.maxGeographicCoord.getMercatorProjection(terrainMercatorMaxPoint2d); + + // Calculate imagery mercator extension. + var imageryMercatorMinPoint2d, imageryMercatorMaxPoint2d; + // Imagery coords are just mercator. + imageryMercatorMinPoint2d = new Point2D(this.imageryGeoExtent.minGeographicCoord.longitude, this.imageryGeoExtent.minGeographicCoord.latitude); + imageryMercatorMaxPoint2d = new Point2D(this.imageryGeoExtent.maxGeographicCoord.longitude, this.imageryGeoExtent.maxGeographicCoord.latitude); + + var terrainWidth = terrainMercatorMaxPoint2d.x - terrainMercatorMinPoint2d.x; + var terrainHeight = terrainMercatorMaxPoint2d.y - terrainMercatorMinPoint2d.y; + var imageryWidth = imageryMercatorMaxPoint2d.x - imageryMercatorMinPoint2d.x; + var imageryHeight = imageryMercatorMaxPoint2d.y - imageryMercatorMinPoint2d.y; + + var scaleX = terrainWidth / imageryWidth; + var scaleY = terrainHeight / imageryHeight; + var translateX = scaleX *(terrainMercatorMinPoint2d.x - imageryMercatorMinPoint2d.x)/ terrainWidth; + var translateY = scaleY *(terrainMercatorMinPoint2d.y - imageryMercatorMinPoint2d.y)/ terrainHeight; + + this.textureTranslateAndScale = new Point4D(translateX, translateY, scaleX, scaleY); +}; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -'use strict'; - -/** - * 어떤 일을 하고 있습니까? - * @class Star - */ -var Star = function() +TinTerrain.prototype.makeMeshVirtually = function(lonSegments, latSegments, altitude, altitudesSlice) { - if (!(this instanceof Star)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } + // This function makes an ellipsoidal mesh for tiles that has no elevation data. + // note: "altitude" & "altitudesSlice" are optionals. + var degToRadFactor = Math.PI/180.0; + var minLon = this.geographicExtent.minGeographicCoord.longitude * degToRadFactor; + var minLat = this.geographicExtent.minGeographicCoord.latitude * degToRadFactor; + var maxLon = this.geographicExtent.maxGeographicCoord.longitude * degToRadFactor; + var maxLat = this.geographicExtent.maxGeographicCoord.latitude * degToRadFactor; + var lonRange = maxLon - minLon; + var latRange = maxLat - minLat; + + var lonIncreDeg = lonRange/lonSegments; + var latIncreDeg = latRange/latSegments; + + // use a vertexMatrix to make the regular net. + var vertexMatrix; + + // calculate total verticesCount. + var vertexCount = (lonSegments + 1)*(latSegments + 1); + var lonArray = new Float32Array(vertexCount); + var latArray = new Float32Array(vertexCount); + var altArray = new Float32Array(vertexCount); + this.texCoordsArray = new Float32Array(vertexCount*2); + + var currLon = minLon; // init startLon. + var currLat = minLat; // init startLat. + var idx = 0; + var s, t; + + // check if exist altitude. + var alt = 0; + if (altitude) + { alt = altitude; } - // this is a closed element.*** - this.centerPoint; // Point3D.*** - this.interiorRadius; - this.exteriorRadius; - this.radiusCount; + // Note: If exist "altitudesSlice", then use it. + + // Test.** + // _calculateTextureTranslationAndScale + var minMercator, maxMercator; + minMercator = Globe.geographicRadianToMercatorProjection(minLon, minLat, minMercator); + maxMercator = Globe.geographicRadianToMercatorProjection(maxLon, maxLat, maxMercator); + this.calculateTextureCoordinateTranslationAndScale(); + // End test.------------------------------------------------------------------------------- + + for (var currLatSeg = 0; currLatSeg> 1) ^ (-(value & 1)); }; -/** - * @class Star - */ -Star.prototype.setExteriorRadius = function(radius) +TinTerrain.prototype.makeVbo = function(vboMemManager) { - this.exteriorRadius = radius; + if (this.cartesiansArray === undefined) + { return; } + + // rest the CenterPosition to the this.cartesiansArray. + var coordsCount = this.cartesiansArray.length/3; + for (var i=0; i 65536 ) + { + this.indices = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4 * trianglesCount * 3)); bytes_readed += 4 * trianglesCount * 3; + } + else + { + this.indices = new Uint16Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 2 * trianglesCount * 3)); bytes_readed += 2 * trianglesCount * 3; + } + + // decode indices. + var code; + var highest = 0; + var indicesCount = this.indices.length; + for (var i=0; i 65536 ) + { + this.westVertexCount = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4)); bytes_readed += 4; + this.westIndices = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4 * this.westVertexCount)); bytes_readed += 4 * this.westVertexCount; - currAngRad += increAngRad; + this.southVertexCount = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4)); bytes_readed += 4; + this.southIndices = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4 * this.southVertexCount)); bytes_readed += 4 * this.southVertexCount; + + this.eastVertexCount = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4)); bytes_readed += 4; + this.eastIndices = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4 * this.eastVertexCount)); bytes_readed += 4 * this.eastVertexCount; + + this.northVertexCount = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4)); bytes_readed += 4; + this.northIndices = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4 * this.northVertexCount)); bytes_readed += 4 * this.northVertexCount; + } + else + { + this.westVertexCount = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4)); bytes_readed += 4; + this.westIndices = new Uint16Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 2 * this.westVertexCount)); bytes_readed += 2 * this.westVertexCount; + + this.southVertexCount = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4)); bytes_readed += 4; + this.southIndices = new Uint16Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 2 * this.southVertexCount)); bytes_readed += 2 * this.southVertexCount; + + this.eastVertexCount = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4)); bytes_readed += 4; + this.eastIndices = new Uint16Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 2 * this.eastVertexCount)); bytes_readed += 2 * this.eastVertexCount; + + this.northVertexCount = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4)); bytes_readed += 4; + this.northIndices = new Uint16Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 2 * this.northVertexCount)); bytes_readed += 2 * this.northVertexCount; } - return resultPointsArray; + // 5. extension header. + this.extensionId = new Uint8Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 1)); bytes_readed += 1; + this.extensionLength = new Uint32Array(dataArrayBuffer.slice(bytes_readed, bytes_readed + 4)); bytes_readed += 4; + + this.fileLoadState = CODE.fileLoadState.PARSE_FINISHED; + + if (this.extensionId.length === 0) + { + dataArrayBuffer = undefined; + return; + } + + dataArrayBuffer = undefined; }; @@ -44106,280 +45334,252 @@ Star.prototype.getPoints = function(resultPointsArray) -'use strict'; -/** - * 어떤 일을 하고 있습니까? - * @class Surface - */ -var Surface = function() -{ - if (!(this instanceof Surface)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - this.facesArray; - this.localVertexList; // vertices used only for this surface.*** -}; - -Surface.prototype.newFace = function() -{ - if (this.facesArray === undefined) - { this.facesArray = []; } - - var face = new Face(); - this.facesArray.push(face); - return face; -}; -Surface.prototype.getFacesCount = function() -{ - if (this.facesArray === undefined) - { return 0; } - return this.facesArray.length; -}; -Surface.prototype.getFace = function(idx) -{ - if (this.facesArray === undefined) - { return undefined; } - return this.facesArray[idx]; -}; +'use strict'; -Surface.prototype.setColor = function(r, g, b, a) +/** + * @class TinTerrainManager + */ +var TinTerrainManager = function() { - var face; - var facesCount = this.getFacesCount(); - for (var i=0; i terrainPlainModel. + // terrainType = 1 -> terrainElevationModel. + this.terrainType = 0; + + this.init(); }; -Surface.prototype.getHalfEdges = function(resultHedgesArray) +TinTerrainManager.prototype.init = function() { - if (this.facesArray === undefined) - { return resultHedgesArray; } + this.tinTerrainsQuadTreeAsia = new TinTerrain(undefined); // Main object. + this.tinTerrainsQuadTreeAmerica = new TinTerrain(undefined); // Main object. + //1.4844222297453322 + //var latDeg = 1.4844222297453322 *180/Math.PI; + // Asia side. + var minLon = 0; + var minLat = -90; + var minAlt = 0; + var maxLon = 180; + var maxLat = 90; + var maxAlt = 0; + this.tinTerrainsQuadTreeAsia.setGeographicExtent(minLon, minLat, minAlt, maxLon, maxLat, maxAlt); + this.tinTerrainsQuadTreeAsia.X = 1; + this.tinTerrainsQuadTreeAsia.Y = 0; - if (resultHedgesArray === undefined) - { resultHedgesArray = []; } + // America side. + minLon = -180; + minLat = -90; + minAlt = 0; + maxLon = 0; + maxLat = 90; + maxAlt = 0; + this.tinTerrainsQuadTreeAmerica.setGeographicExtent(minLon, minLat, minAlt, maxLon, maxLat, maxAlt); + this.tinTerrainsQuadTreeAmerica.X = 0; + this.tinTerrainsQuadTreeAmerica.Y = 0; + + // do imagery test. + // set imagery initial geoExtent (in mercator coords). + /* + // https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer + Initial Extent: + XMin: -2.7680880158351306E7 + YMin: -195164.8424795773 // error. + XMax: 2.7680880158351306E7 + YMax: 1.9971868880408563E7 + Spatial Reference: 102100 + + Full Extent: + XMin: -2.003750722959434E7 + YMin: -1.997186888040859E7 + XMax: 2.003750722959434E7 + YMax: 1.9971868880408563E7 + Spatial Reference: 102100 + + //https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/0 + Level 0 Extent: + XMin: -2.0028669624423463E7 + YMin: -7679113.797548824 + XMax: 2.001627433615794E7 + YMax: 1.7924177384518914E7 + Spatial Reference: 102100 (3857) + + */ - var facesCount = this.getFacesCount(); - var face; - for (var i=0; i 2) + { + tinTerrain.deleteTinTerrain(magoManager); + deletedCount++; + } + } + + if (deletedCount > 5) + { break; } } - return resultVerticesArray; }; -Surface.prototype.getTrianglesConvex = function(resultTrianglesArray) +TinTerrainManager.prototype.render = function(magoManager, bDepth) { - // To call this method, the faces must be convex.*** - if (this.facesArray === undefined || this.facesArray.length ===0) - { return resultTrianglesArray; } - if (resultTrianglesArray === undefined) - { resultTrianglesArray = []; } + var gl = magoManager.sceneState.gl; + var currentShader = magoManager.postFxShadersManager.getShader("tinTerrain"); + var shaderProgram = currentShader.program; - var face; - var facesCount = this.getFacesCount(); - for (var i=0; i 0) + { + if (!vbo_vicky.bindDataIndice(shader, magoManager.vboMemoryManager)) + { return false; } - return resultCrossProduct; + gl.drawElements(gl.TRIANGLES, vbo_vicky.indicesCount, gl.UNSIGNED_SHORT, 0); // Fill. + } + else + { + gl.drawArrays(gl.TRIANGLES, 0, vertices_count); + } + } + else + { + gl.drawArrays(gl.LINE_STRIP, 0, vertices_count); + //gl.drawArrays(gl.TRIANGLES, 0, vertices_count); + } + } }; +/** + * This function renders provisional ParametricMesh objects that has no self render function. + * @param {WebGLRenderingContext} gl WebGL Rendering Context. + * @param {Number} renderType If renderType = 0 (depth render), renderType = 1 (color render), renderType = 2 (colorCoding render). + * @param {VisibleObjectsController} visibleObjControlerNodes This object contains visible objects for the camera frustum. + */ +Renderer.prototype.renderGeometryDepth = function(gl, renderType, visibleObjControlerNodes) +{ + var currentShader; + var shaderProgram; + var renderTexture = false; + + var magoManager = this.magoManager; + + // Test Modeler Rendering.******************************************************************** + // Test Modeler Rendering.******************************************************************** + // Test Modeler Rendering.******************************************************************** + if (magoManager.modeler !== undefined) + { + currentShader = magoManager.postFxShadersManager.getShader("modelRefDepth"); + currentShader.resetLastBuffersBinded(); + shaderProgram = currentShader.program; + + currentShader.useProgram(); + currentShader.enableVertexAttribArray(currentShader.position3_loc); + currentShader.disableVertexAttribArray(currentShader.texCoord2_loc); + currentShader.disableVertexAttribArray(currentShader.normal3_loc); + currentShader.disableVertexAttribArray(currentShader.color4_loc); + + currentShader.bindUniformGenerals(); + var refTMatrixIdxKey = 0; + var minSizeToRender = 0.0; + var renderType = 0; + var refMatrixIdxKey =0; // provisionally set this var here.*** + magoManager.modeler.render(magoManager, currentShader, renderType); + currentShader.disableVertexAttribArrayAll(); + gl.useProgram(null); + } + + var nodesLOD0Count = visibleObjControlerNodes.currentVisibles0.length; + var nodesLOD2Count = visibleObjControlerNodes.currentVisibles2.length; + var nodesLOD3Count = visibleObjControlerNodes.currentVisibles3.length; + if (nodesLOD0Count > 0 || nodesLOD2Count > 0 || nodesLOD3Count > 0) + { + currentShader = magoManager.postFxShadersManager.getShader("modelRefDepth"); + currentShader.resetLastBuffersBinded(); + shaderProgram = currentShader.program; + currentShader.useProgram(); + currentShader.enableVertexAttribArray(currentShader.position3_loc); + currentShader.disableVertexAttribArray(currentShader.texCoord2_loc); + currentShader.disableVertexAttribArray(currentShader.normal3_loc); + currentShader.disableVertexAttribArray(currentShader.color4_loc); + currentShader.bindUniformGenerals(); + // RenderDepth for all buildings.*** + var refTMatrixIdxKey = 0; + var minSize = 0.0; + magoManager.renderer.renderNodes(gl, visibleObjControlerNodes.currentVisibles0, magoManager, currentShader, renderTexture, renderType, minSize, 0, refTMatrixIdxKey); + //magoManager.renderer.renderNodes(gl, visibleObjControlerNodes.currentVisibles2, magoManager, currentShader, renderTexture, renderType, minSize, 0, refTMatrixIdxKey); + //magoManager.renderer.renderNodes(gl, visibleObjControlerNodes.currentVisibles3, magoManager, currentShader, renderTexture, renderType, minSize, 0, refTMatrixIdxKey); + + currentShader.disableVertexAttribArray(currentShader.position3_loc); + gl.useProgram(null); + } + + // PointsCloud.**************************************************************************************** + // PointsCloud.**************************************************************************************** + var nodesPCloudCount = magoManager.visibleObjControlerNodes.currentVisiblesAux.length; + if (nodesPCloudCount > 0) + { + currentShader = magoManager.postFxShadersManager.getShader("pointsCloudDepth"); + currentShader.useProgram(); + + currentShader.resetLastBuffersBinded(); + currentShader.enableVertexAttribArray(currentShader.position3_loc); + currentShader.disableVertexAttribArray(currentShader.color4_loc); + currentShader.disableVertexAttribArray(currentShader.normal3_loc); // provisionally has no normals.*** + currentShader.disableVertexAttribArray(currentShader.texCoord2_loc); // provisionally has no texCoords.*** + + currentShader.bindUniformGenerals(); + + // Test to load pCloud.*** + if (magoManager.visibleObjControlerPCloudOctrees === undefined) + { magoManager.visibleObjControlerPCloudOctrees = new VisibleObjectsController(); } + magoManager.visibleObjControlerPCloudOctrees.clear(); + magoManager.renderer.renderNeoBuildingsPCloud(gl, magoManager.visibleObjControlerNodes.currentVisiblesAux, magoManager, currentShader, renderTexture, renderType); + currentShader.disableVertexAttribArrayAll(); + + gl.useProgram(null); + + // Load pCloud data.*** + var visiblesSortedOctreesArray = magoManager.visibleObjControlerPCloudOctrees.currentVisibles0; + var octreesCount = visiblesSortedOctreesArray.length; + var loadCount = 0; + if (!magoManager.isCameraMoving && !magoManager.mouseLeftDown && !magoManager.mouseMiddleDown) + { + for (var i=0; i 1) + { break; } + } + } + } + + // Render cuttingPlanes of temperaturalayers if exist.*** + if (magoManager.weatherStation) + { magoManager.weatherStation.test_renderCuttingPlanes(magoManager, renderType); } + + // tin terrain.*** + if (magoManager.tinTerrainManager !== undefined) + { + var bDepth = true; + magoManager.tinTerrainManager.render(magoManager, bDepth); + gl.useProgram(null); + } + + // Test.*** + var selGeneralObjects = magoManager.selectionManager.getSelectionCandidatesFamily("general"); + if (selGeneralObjects) + { + var currObjectSelected = selGeneralObjects.currentSelected; + if (currObjectSelected) + { + // check if is a cuttingPlane.*** + if (currObjectSelected instanceof CuttingPlane) + { + // Test. Render depth only for the selected object.*************************** + magoManager.test_renderDepth_objectSelected(currObjectSelected); + } + } + } +}; +/** + * This function renders provisional ParametricMesh objects that has no self render function. + * @param {WebGLRenderingContext} gl WebGL Rendering Context. + * @param {Number} renderType If renderType = 0 (depth render), renderType = 1 (color render), renderType = 2 (colorCoding render). + * @param {VisibleObjectsController} visibleObjControlerNodes This object contains visible objects for the camera frustum. + */ +Renderer.prototype.renderGeometry = function(gl, renderType, visibleObjControlerNodes) +{ + gl.frontFace(gl.CCW); + gl.enable(gl.DEPTH_TEST); + gl.depthFunc(gl.LEQUAL); + gl.enable(gl.CULL_FACE); + + var currentShader; + var shaderProgram; + var neoBuilding; + var node; + var rootNode; + var geoLocDataManager; + var magoManager = this.magoManager; + var renderTexture = false; + + if (renderType === 0 ) + { + gl.disable(gl.BLEND); + magoManager.renderer.renderGeometryDepth(gl, renderType, visibleObjControlerNodes); + + // Draw the axis.*** + if (magoManager.magoPolicy.getShowOrigin() && magoManager.nodeSelected !== undefined) + { + node = magoManager.nodeSelected; + var nodes = [node]; + + this.renderAxisNodes(nodes, renderType); + } + } + if (renderType === 1) + { + var textureAux1x1 = magoManager.texturesManager.getTextureAux1x1(); + var noiseTexture = magoManager.texturesManager.getNoiseTexture4x4(); + + // Test Modeler Rendering.******************************************************************** + // Test Modeler Rendering.******************************************************************** + // Test Modeler Rendering.******************************************************************** + if (magoManager.modeler !== undefined) + { + currentShader = magoManager.postFxShadersManager.getShader("modelRefSsao"); + currentShader.useProgram(); + gl.uniform1i(currentShader.bApplySsao_loc, false); // apply ssao default.*** + + gl.uniform1i(currentShader.bApplySpecularLighting_loc, true); + gl.enableVertexAttribArray(currentShader.texCoord2_loc); + gl.enableVertexAttribArray(currentShader.position3_loc); + gl.enableVertexAttribArray(currentShader.normal3_loc); + if (currentShader.color4_loc !== -1){ gl.disableVertexAttribArray(currentShader.color4_loc); } + + currentShader.bindUniformGenerals(); + gl.uniform1i(currentShader.textureFlipYAxis_loc, magoManager.sceneState.textureFlipYAxis); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, magoManager.depthFboNeo.colorBuffer); // original.*** + gl.activeTexture(gl.TEXTURE1); + gl.bindTexture(gl.TEXTURE_2D, noiseTexture); + gl.activeTexture(gl.TEXTURE2); + gl.bindTexture(gl.TEXTURE_2D, textureAux1x1); + currentShader.last_tex_id = textureAux1x1; + + + var refTMatrixIdxKey = 0; + var minSizeToRender = 0.0; + var renderType = 1; + var refMatrixIdxKey =0; // provisionally set magoManager var here.*** + magoManager.modeler.render(magoManager, currentShader, renderType); + + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, null); // original.*** + gl.activeTexture(gl.TEXTURE1); + gl.bindTexture(gl.TEXTURE_2D, null); + gl.activeTexture(gl.TEXTURE2); + gl.bindTexture(gl.TEXTURE_2D, null); + + currentShader.disableVertexAttribArrayAll(); + gl.useProgram(null); + } + + // check changesHistory. + magoManager.checkChangesHistoryMovements(visibleObjControlerNodes.currentVisibles0); + magoManager.checkChangesHistoryColors(visibleObjControlerNodes.currentVisibles0); + + magoManager.checkChangesHistoryMovements(visibleObjControlerNodes.currentVisibles2); + magoManager.checkChangesHistoryColors(visibleObjControlerNodes.currentVisibles2); + + magoManager.checkChangesHistoryMovements(visibleObjControlerNodes.currentVisibles3); + magoManager.checkChangesHistoryColors(visibleObjControlerNodes.currentVisibles3); + + // ssao render.************************************************************************************************************ + var nodesLOD0Count = visibleObjControlerNodes.currentVisibles0.length; + var nodesLOD2Count = visibleObjControlerNodes.currentVisibles2.length; + var nodesLOD3Count = visibleObjControlerNodes.currentVisibles3.length; + if (nodesLOD0Count > 0 || nodesLOD2Count > 0 || nodesLOD3Count > 0) + { + gl.enable(gl.BLEND); + currentShader = magoManager.postFxShadersManager.getShader("modelRefSsao"); + currentShader.useProgram(); + var bApplySsao = true; + gl.uniform1i(currentShader.bApplySsao_loc, bApplySsao); // apply ssao default.*** + + gl.uniform1i(currentShader.bApplySpecularLighting_loc, true); + gl.enableVertexAttribArray(currentShader.texCoord2_loc); + gl.enableVertexAttribArray(currentShader.position3_loc); + gl.enableVertexAttribArray(currentShader.normal3_loc); + if (currentShader.color4_loc !== -1){ gl.disableVertexAttribArray(currentShader.color4_loc); } + + currentShader.bindUniformGenerals(); + gl.uniform1f(currentShader.externalAlpha_loc, 1.0); + gl.uniform1i(currentShader.textureFlipYAxis_loc, magoManager.sceneState.textureFlipYAxis); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, magoManager.depthFboNeo.colorBuffer); // original.*** + gl.activeTexture(gl.TEXTURE1); + gl.bindTexture(gl.TEXTURE_2D, noiseTexture); + gl.activeTexture(gl.TEXTURE2); + gl.bindTexture(gl.TEXTURE_2D, textureAux1x1); + currentShader.last_tex_id = textureAux1x1; + + + var refTMatrixIdxKey = 0; + var minSizeToRender = 0.0; + var renderType = 1; + var refMatrixIdxKey =0; // provisionally set magoManager var here.*** + magoManager.renderer.renderNodes(gl, visibleObjControlerNodes.currentVisibles0, magoManager, currentShader, renderTexture, renderType, minSizeToRender, refTMatrixIdxKey); + + bApplySsao = false; + gl.uniform1i(currentShader.bApplySsao_loc, bApplySsao); + magoManager.renderer.renderNodes(gl, visibleObjControlerNodes.currentVisibles2, magoManager, currentShader, renderTexture, renderType, minSizeToRender, refTMatrixIdxKey); + magoManager.renderer.renderNodes(gl, visibleObjControlerNodes.currentVisibles3, magoManager, currentShader, renderTexture, renderType, minSizeToRender, refTMatrixIdxKey); + + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, null); // original.*** + gl.activeTexture(gl.TEXTURE1); + gl.bindTexture(gl.TEXTURE_2D, null); + gl.activeTexture(gl.TEXTURE2); + gl.bindTexture(gl.TEXTURE_2D, null); + + currentShader.disableVertexAttribArrayAll(); + gl.useProgram(null); + } + + // If there are an object selected, then there are a stencilBuffer.****************************************** + if (magoManager.nodeSelected) // if there are an object selected then there are a building selected.*** + { + if (magoManager.magoPolicy.getObjectMoveMode() === CODE.moveMode.OBJECT && magoManager.objectSelected) + { + node = magoManager.nodeSelected; + var geoLocDataManager = node.getNodeGeoLocDataManager(); + neoBuilding = magoManager.buildingSelected; + var buildingGeoLocation = geoLocDataManager.getCurrentGeoLocationData(); + var neoReferencesMotherAndIndices = magoManager.octreeSelected.neoReferencesMotherAndIndices; + var glPrimitive = gl.POINTS; + glPrimitive = gl.TRIANGLES; + var maxSizeToRender = 0.0; + var refMatrixIdxKey = 0; + + // do as the "getSelectedObjectPicking".********************************************************** + currentShader = magoManager.postFxShadersManager.getModelRefSilhouetteShader(); // silhouette shader.*** + currentShader.useProgram(); + + currentShader.enableVertexAttribArray(currentShader.position3_loc); + currentShader.disableVertexAttribArray(currentShader.texCoord2_loc); + currentShader.disableVertexAttribArray(currentShader.normal3_loc); + currentShader.disableVertexAttribArray(currentShader.color4_loc); + + buildingGeoLocation.bindGeoLocationUniforms(gl, currentShader); + gl.uniformMatrix4fv(currentShader.modelViewProjectionMatrix4RelToEye_loc, false, magoManager.sceneState.modelViewProjRelToEyeMatrix._floatArrays); + gl.uniformMatrix4fv(currentShader.ModelViewMatrixRelToEye_loc, false, magoManager.sceneState.modelViewRelToEyeMatrix._floatArrays); + gl.uniform3fv(currentShader.cameraPosHIGH_loc, magoManager.sceneState.encodedCamPosHigh); + gl.uniform3fv(currentShader.cameraPosLOW_loc, magoManager.sceneState.encodedCamPosLow); + + // do the colorCoding render.*** + + gl.uniform4fv(currentShader.color4Aux_loc, [0.0, 1.0, 0.0, 1.0]); + gl.uniform2fv(currentShader.screenSize_loc, [magoManager.sceneState.drawingBufferWidth, magoManager.sceneState.drawingBufferHeight]); + gl.uniformMatrix4fv(currentShader.ProjectionMatrix_loc, false, magoManager.sceneState.projectionMatrix._floatArrays); + + gl.enable(gl.STENCIL_TEST); + gl.disable(gl.POLYGON_OFFSET_FILL); + gl.disable(gl.CULL_FACE); + gl.disable(gl.DEPTH_TEST); + gl.depthRange(0, 0); + + gl.stencilFunc(gl.EQUAL, 0, 1); + gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE); + + //glPrimitive = gl.POINTS; + glPrimitive = gl.TRIANGLES; + //gl.polygonMode( gl.FRONT_AND_BACK, gl.LINE ); + var localRenderType = 0; // only need positions.*** + var minSizeToRender = 0.0; + var offsetSize = 3/1000; + + gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [offsetSize, offsetSize]); + magoManager.objectSelected.render(magoManager, neoBuilding, localRenderType, renderTexture, currentShader, refMatrixIdxKey, minSizeToRender); + gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [-offsetSize, offsetSize]); + magoManager.objectSelected.render(magoManager, neoBuilding, localRenderType, renderTexture, currentShader, refMatrixIdxKey, minSizeToRender); + gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [offsetSize, -offsetSize]); + magoManager.objectSelected.render(magoManager, neoBuilding, localRenderType, renderTexture, currentShader, refMatrixIdxKey, minSizeToRender); + gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [-offsetSize, -offsetSize]); + magoManager.objectSelected.render(magoManager, neoBuilding, localRenderType, renderTexture, currentShader, refMatrixIdxKey, minSizeToRender); + + gl.enable(gl.DEPTH_TEST);// return to the normal state.*** + gl.disable(gl.STENCIL_TEST); + gl.depthRange(0, 1);// return to the normal value.*** + //gl.disableVertexAttribArray(currentShader.position3_loc); + currentShader.disableVertexAttribArrayAll(); + + gl.useProgram(null); + } + + // new. Render the silhouette by lod3 or lod4 or lod5 mesh*** + if (magoManager.magoPolicy.getObjectMoveMode() === CODE.moveMode.ALL && magoManager.buildingSelected) + { + node = magoManager.nodeSelected; + + if (node !== undefined) // test code.*** + { + var geoLocDataManager = node.getNodeGeoLocDataManager(); + neoBuilding = magoManager.buildingSelected; + var buildingGeoLocation = geoLocDataManager.getCurrentGeoLocationData(); + + currentShader = magoManager.postFxShadersManager.getModelRefSilhouetteShader(); // silhouette shader.*** + currentShader.useProgram(); + gl.enableVertexAttribArray(currentShader.position3_loc); + + buildingGeoLocation.bindGeoLocationUniforms(gl, currentShader); + gl.uniformMatrix4fv(currentShader.modelViewProjectionMatrix4RelToEye_loc, false, magoManager.sceneState.modelViewProjRelToEyeMatrix._floatArrays); + gl.uniformMatrix4fv(currentShader.ModelViewMatrixRelToEye_loc, false, magoManager.sceneState.modelViewRelToEyeMatrix._floatArrays); + gl.uniform3fv(currentShader.cameraPosHIGH_loc, magoManager.sceneState.encodedCamPosHigh); + gl.uniform3fv(currentShader.cameraPosLOW_loc, magoManager.sceneState.encodedCamPosLow); + + // do the colorCoding render.*** + + gl.uniform4fv(currentShader.color4Aux_loc, [0.0, 1.0, 0.0, 1.0]); + gl.uniform2fv(currentShader.screenSize_loc, [magoManager.sceneState.drawingBufferWidth, magoManager.sceneState.drawingBufferHeight]); + gl.uniformMatrix4fv(currentShader.ProjectionMatrix_loc, false, magoManager.sceneState.projectionMatrix._floatArrays); + + gl.uniform3fv(currentShader.aditionalMov_loc, [0.0, 0.0, 0.0]); //.*** + + gl.enable(gl.STENCIL_TEST); + gl.disable(gl.POLYGON_OFFSET_FILL); + gl.disable(gl.CULL_FACE); + gl.disable(gl.DEPTH_TEST); + gl.depthRange(0, 0); + + gl.stencilFunc(gl.EQUAL, 0, 1); + gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE); + //gl.stencilOp(gl.KEEP, gl.REPLACE, gl.REPLACE); + + //glPrimitive = gl.POINTS; + glPrimitive = gl.TRIANGLES; + gl.uniform1i(currentShader.refMatrixType_loc, 0); // 0 = identity matrix, there are not referencesMatrix.*** + //gl.polygonMode( gl.FRONT_AND_BACK, gl.LINE ); + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + var refTMatrixIdxKey = 0; + var minSizeToRender = 0.0; + var renderType = 0; + var refMatrixIdxKey =0; // provisionally set magoManager var here.*** + var offsetSize = 4/1000; + gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [offsetSize, offsetSize]); + magoManager.renderer.renderNodes(gl, [node], magoManager, currentShader, renderTexture, renderType, minSizeToRender, refTMatrixIdxKey); + gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [-offsetSize, offsetSize]); + magoManager.renderer.renderNodes(gl, [node], magoManager, currentShader, renderTexture, renderType, minSizeToRender, refTMatrixIdxKey); + gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [offsetSize, -offsetSize]); + magoManager.renderer.renderNodes(gl, [node], magoManager, currentShader, renderTexture, renderType, minSizeToRender, refTMatrixIdxKey); + gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [-offsetSize, -offsetSize]); + magoManager.renderer.renderNodes(gl, [node], magoManager, currentShader, renderTexture, renderType, minSizeToRender, refTMatrixIdxKey); + + currentShader.disableVertexAttribArrayAll(); + } + /* + var geoLocDataManager = node.getNodeGeoLocDataManager(); + neoBuilding = magoManager.buildingSelected; + var buildingGeoLocation = geoLocDataManager.getCurrentGeoLocationData(); + //var neoReferencesMotherAndIndices = magoManager.octreeSelected.neoReferencesMotherAndIndices; + var glPrimitive = gl.POINTS; + glPrimitive = gl.TRIANGLES; + var maxSizeToRender = 0.0; + var refMatrixIdxKey = 0; + var skinLego = neoBuilding.getCurrentSkin(); + if (skinLego !== undefined) + { + // do as the "getSelectedObjectPicking".********************************************************** + currentShader = magoManager.postFxShadersManager.getModelRefSilhouetteShader(); // silhouette shader.*** + currentShader.useProgram(); + gl.enableVertexAttribArray(currentShader.position3_loc); + + buildingGeoLocation.bindGeoLocationUniforms(gl, currentShader); + gl.uniformMatrix4fv(currentShader.modelViewProjectionMatrix4RelToEye_loc, false, magoManager.sceneState.modelViewProjRelToEyeMatrix._floatArrays); + gl.uniformMatrix4fv(currentShader.ModelViewMatrixRelToEye_loc, false, magoManager.sceneState.modelViewRelToEyeMatrix._floatArrays); + gl.uniform3fv(currentShader.cameraPosHIGH_loc, magoManager.sceneState.encodedCamPosHigh); + gl.uniform3fv(currentShader.cameraPosLOW_loc, magoManager.sceneState.encodedCamPosLow); + + // do the colorCoding render.*** + + gl.uniform4fv(currentShader.color4Aux_loc, [0.0, 1.0, 0.0, 1.0]); + gl.uniform2fv(currentShader.screenSize_loc, [magoManager.sceneState.drawingBufferWidth, magoManager.sceneState.drawingBufferHeight]); + gl.uniformMatrix4fv(currentShader.ProjectionMatrix_loc, false, magoManager.sceneState.projectionMatrix._floatArrays); + + gl.uniform3fv(currentShader.aditionalMov_loc, [0.0, 0.0, 0.0]); //.*** + + gl.enable(gl.STENCIL_TEST); + gl.disable(gl.POLYGON_OFFSET_FILL); + gl.disable(gl.CULL_FACE); + gl.disable(gl.DEPTH_TEST); + gl.depthRange(0, 0); + + gl.stencilFunc(gl.EQUAL, 0, 1); + gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE); + //gl.stencilOp(gl.KEEP, gl.REPLACE, gl.REPLACE); + + //glPrimitive = gl.POINTS; + glPrimitive = gl.TRIANGLES; + gl.uniform1i(currentShader.refMatrixType_loc, 0); // 0 = identity matrix, there are not referencesMatrix.*** + //gl.polygonMode( gl.FRONT_AND_BACK, gl.LINE ); + var offsetSize = 4/1000; + var localRenderType = 0; // only need positions.*** + gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [offsetSize, offsetSize]); + skinLego.render(magoManager, localRenderType, renderTexture, currentShader); + gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [-offsetSize, offsetSize]); + skinLego.render(magoManager, localRenderType, renderTexture, currentShader); + gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [offsetSize, -offsetSize]); + skinLego.render(magoManager, localRenderType, renderTexture, currentShader); + gl.uniform2fv(currentShader.camSpacePixelTranslation_loc, [-offsetSize, -offsetSize]); + skinLego.render(magoManager, localRenderType, renderTexture, currentShader); + gl.enable(gl.DEPTH_TEST);// return to the normal state.*** + gl.disable(gl.STENCIL_TEST); + gl.depthRange(0, 1);// return to the normal value.*** + gl.disableVertexAttribArray(currentShader.position3_loc); + + currentShader.disableVertexAttribArrayAll(); + } + */ + } + + // draw the axis.*** + if (magoManager.magoPolicy.getShowOrigin()) + { + node = magoManager.nodeSelected; + //var geoLocDataManager = node.getNodeGeoLocDataManager(); + var nodes = [node]; + + this.renderAxisNodes(nodes, renderType); + } + } + + + // 3) now render bboxes.******************************************************************************************************************* + if (magoManager.magoPolicy.getShowBoundingBox()) + { + var bRenderLines = true; + this.renderBoundingBoxesNodes(magoManager.visibleObjControlerNodes.currentVisibles0, undefined, bRenderLines); + this.renderBoundingBoxesNodes(magoManager.visibleObjControlerNodes.currentVisibles2, undefined, bRenderLines); + this.renderBoundingBoxesNodes(magoManager.visibleObjControlerNodes.currentVisibles3, undefined, bRenderLines); + } + + // 4) Render ObjectMarkers.******************************************************************************************************** + // 4) Render ObjectMarkers.******************************************************************************************************** + // 4) Render ObjectMarkers.******************************************************************************************************** + var objectsMarkersCount = magoManager.objMarkerManager.objectMarkerArray.length; + if (objectsMarkersCount > 0) + { + // now repeat the objects markers for png images.*** + // Png for pin image 128x128.******************************************************************** + if (magoManager.pin.positionBuffer === undefined) + { magoManager.pin.createPinCenterBottom(gl); } + + currentShader = magoManager.postFxShadersManager.pngImageShader; // png image shader.*** + currentShader.resetLastBuffersBinded(); + + shaderProgram = currentShader.program; + + gl.useProgram(shaderProgram); + gl.uniformMatrix4fv(currentShader.modelViewProjectionMatrix4RelToEye_loc, false, magoManager.sceneState.modelViewProjRelToEyeMatrix._floatArrays); + gl.uniform3fv(currentShader.cameraPosHIGH_loc, magoManager.sceneState.encodedCamPosHigh); + gl.uniform3fv(currentShader.cameraPosLOW_loc, magoManager.sceneState.encodedCamPosLow); + gl.uniformMatrix4fv(currentShader.buildingRotMatrix_loc, false, magoManager.sceneState.modelViewRelToEyeMatrixInv._floatArrays); + + gl.uniform1i(currentShader.textureFlipYAxis_loc, magoManager.sceneState.textureFlipYAxis); + // Tell the shader to get the texture from texture unit 0 + gl.uniform1i(currentShader.texture_loc, 0); + gl.enableVertexAttribArray(currentShader.texCoord2_loc); + gl.enableVertexAttribArray(currentShader.position3_loc); + gl.activeTexture(gl.TEXTURE0); + + gl.depthRange(0, 0); + //var context = document.getElementById('canvas2').getContext("2d"); + //var canvas = document.getElementById("magoContainer"); + + gl.bindBuffer(gl.ARRAY_BUFFER, magoManager.pin.positionBuffer); + gl.vertexAttribPointer(currentShader.position3_loc, 3, gl.FLOAT, false, 0, 0); + gl.bindBuffer(gl.ARRAY_BUFFER, magoManager.pin.texcoordBuffer); + gl.vertexAttribPointer(currentShader.texCoord2_loc, 2, gl.FLOAT, false, 0, 0); + var j=0; + for (var i=0; i= magoManager.pin.texturesArray.length) + { j=0; } + + var currentTexture = magoManager.pin.texturesArray[j]; + var objMarker = magoManager.objMarkerManager.objectMarkerArray[i]; + var objMarkerGeoLocation = objMarker.geoLocationData; + gl.bindTexture(gl.TEXTURE_2D, currentTexture.texId); + gl.uniform3fv(currentShader.buildingPosHIGH_loc, objMarkerGeoLocation.positionHIGH); + gl.uniform3fv(currentShader.buildingPosLOW_loc, objMarkerGeoLocation.positionLOW); + gl.drawArrays(gl.TRIANGLES, 0, 6); + + j++; + } + gl.depthRange(0, 1); + gl.useProgram(null); + gl.bindTexture(gl.TEXTURE_2D, null); + currentShader.disableVertexAttribArrayAll(); + + } + + // test renders.*** + // render cctv.*** + /* + magoManager.test_cctv(); + var cctvsCount = 0; + if (magoManager.cctvList !== undefined) + { + cctvsCount = magoManager.cctvList.getCCTVCount(); + } + if (cctvsCount > 0) + { + currentShader = magoManager.postFxShadersManager.getShader("modelRefSsao"); + magoManager.cctvList.render(magoManager, currentShader ); + } + */ + + // PointsCloud.**************************************************************************************** + // PointsCloud.**************************************************************************************** + var nodesPCloudCount = magoManager.visibleObjControlerNodes.currentVisiblesAux.length; + if (nodesPCloudCount > 0) + { + magoManager.sceneState.camera.setCurrentFrustum(0); + var frustumIdx = magoManager.currentFrustumIdx; + magoManager.sceneState.camera.frustum.near[0] = magoManager.sceneState.camera.frustumsArray[frustumIdx].near[0]; + magoManager.sceneState.camera.frustum.far[0] = magoManager.sceneState.camera.frustumsArray[frustumIdx].far[0]; + + if (magoManager.pointsCloudSsao === undefined) + { magoManager.pointsCloudSsao = true; } + + if (magoManager.pointsCloudSsao) + { currentShader = magoManager.postFxShadersManager.getShader("pointsCloudSsao"); } + else + { currentShader = magoManager.postFxShadersManager.getShader("pointsCloud"); } + currentShader.useProgram(); + currentShader.resetLastBuffersBinded(); + currentShader.enableVertexAttribArray(currentShader.position3_loc); + currentShader.enableVertexAttribArray(currentShader.color4_loc); + currentShader.bindUniformGenerals(); + + gl.uniform1f(currentShader.externalAlpha_loc, 1.0); + var bApplySsao = true; + gl.uniform1i(currentShader.bApplySsao_loc, bApplySsao); // apply ssao default.*** + + if (magoManager.pointsCloudWhite !== undefined && magoManager.pointsCloudWhite) + { + gl.uniform1i(currentShader.bUse1Color_loc, true); + gl.uniform4fv(currentShader.oneColor4_loc, [0.99, 0.99, 0.99, 1.0]); //.*** + } + else + { + gl.uniform1i(currentShader.bUse1Color_loc, false); + } + + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, magoManager.depthFboNeo.colorBuffer); + + // Test to load pCloud.*** + if (magoManager.visibleObjControlerPCloudOctrees === undefined) + { magoManager.visibleObjControlerPCloudOctrees = new VisibleObjectsController(); } + + magoManager.visibleObjControlerPCloudOctrees.clear(); + magoManager.renderer.renderNeoBuildingsPCloud(gl, magoManager.visibleObjControlerNodes.currentVisiblesAux, magoManager, currentShader, renderTexture, renderType); // lod0.*** + currentShader.disableVertexAttribArrayAll(); + + gl.useProgram(null); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + currentShader = magoManager.postFxShadersManager.getShader("modelRefSsao"); + currentShader.disableVertexAttribArrayAll(); + + currentShader = magoManager.postFxShadersManager.getShader("modelRefColorCoding"); // color selection shader.*** + currentShader.disableVertexAttribArrayAll(); + + currentShader = magoManager.postFxShadersManager.getModelRefSilhouetteShader(); // silhouette shader.*** + currentShader.disableVertexAttribArrayAll(); + + // Test TinTerrain.************************************************************************** + // Test TinTerrain.************************************************************************** + // render tiles, rendertiles.*** + + if (magoManager.tinTerrainManager !== undefined) + { + var bDepthRender = false; // magoManager is no depth render.*** + magoManager.tinTerrainManager.render(magoManager, bDepthRender); + } + + + } + + currentShader = magoManager.postFxShadersManager.getShader("modelRefSsao"); + currentShader.disableVertexAttribArrayAll(); + + currentShader = magoManager.postFxShadersManager.getShader("modelRefColorCoding"); // color selection shader.*** + currentShader.disableVertexAttribArrayAll(); + + currentShader = magoManager.postFxShadersManager.getModelRefSilhouetteShader(); // silhouette shader.*** + currentShader.disableVertexAttribArrayAll(); + + gl.disable(gl.BLEND); + gl.depthRange(0.0, 1.0); +}; -'use strict'; /** - * 어떤 일을 하고 있습니까? - * @class TrianglesList + * This function renders the axis coordinates of the nodes. + * @param {Array} nodesArray Nodes that render the axis. + * @param {Number} renderType If renderType = 0 (depth render), renderType = 1 (color render), renderType = 2 (colorCoding render). */ -var TrianglesList = function() +Renderer.prototype.renderAxisNodes = function(nodesArray, renderType) { - if (!(this instanceof TrianglesList)) + var magoManager = this.magoManager; + + if (magoManager.axisXYZ.vbo_vicks_container.vboCacheKeysArray.length === 0) + { + var mesh = magoManager.axisXYZ.makeMesh(30); + mesh.getVboTrianglesConvex(magoManager.axisXYZ.vbo_vicks_container, magoManager.vboMemoryManager); + } + + var gl = magoManager.getGl(); + var color; + var node; + var currentShader; + if (renderType === 0) { - throw new Error(Messages.CONSTRUCT_ERROR); + currentShader = magoManager.postFxShadersManager.getShader("modelRefDepth"); + gl.disable(gl.BLEND); } + if (renderType === 1) + { + currentShader = magoManager.postFxShadersManager.getShader("modelRefSsao"); + gl.enable(gl.BLEND); + } + + var noiseTexture = magoManager.texturesManager.getNoiseTexture4x4(); + + // Test rendering by modelRefShader.**** + currentShader.useProgram(); + gl.uniform1i(currentShader.bApplySsao_loc, true); // apply ssao.*** + gl.uniform1i(currentShader.refMatrixType_loc, 0); // in magoManager case, there are not referencesMatrix.*** + gl.uniform1i(currentShader.colorType_loc, 1); // 0= oneColor, 1= attribColor, 2= texture.*** + + // ------------------------------------- + + currentShader.disableVertexAttribArray(currentShader.texCoord2_loc); + + var shaderProgram = currentShader.program; + currentShader.bindUniformGenerals(); + gl.enableVertexAttribArray(currentShader.position3_loc); + + if (renderType === 1) + { + var textureAux1x1 = magoManager.texturesManager.getTextureAux1x1(); + + // provisionally render all native projects.*** + gl.enableVertexAttribArray(currentShader.normal3_loc); + gl.enableVertexAttribArray(currentShader.color4_loc); - this.trianglesArray; -}; + gl.uniform1i(currentShader.bUse1Color_loc, false); + if (color) + { + gl.uniform4fv(currentShader.oneColor4_loc, [color.r, color.g, color.b, 1.0]); //.*** + } + else + { + gl.uniform4fv(currentShader.oneColor4_loc, [1.0, 0.1, 0.1, 1.0]); //.*** + } + + gl.uniform1i(currentShader.bUseNormal_loc, true); -/** - * 어떤 일을 하고 있습니까? - * @param idx 변수 - * @returns vertexArray[idx] - */ -TrianglesList.prototype.newTriangle = function(vertex0, vertex1, vertex2) -{ - if (this.trianglesArray === undefined) - { this.trianglesArray = []; } + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, magoManager.depthFboNeo.colorBuffer); // original.*** + gl.activeTexture(gl.TEXTURE1); + gl.bindTexture(gl.TEXTURE_2D, noiseTexture); + gl.activeTexture(gl.TEXTURE2); + gl.bindTexture(gl.TEXTURE_2D, textureAux1x1); + } - var triangle = new Triangle(vertex0, vertex1, vertex2); - this.trianglesArray.push(triangle); - return triangle; -}; + var neoBuilding; + var natProject, mesh; + var geoLocDataManager; + var buildingGeoLocation; + var nodesCount = nodesArray.length; + for (var b=0; b verticesCount-1) - { return undefined; } - var prevIdx; + this.centerPoint; // Point2D. + this.radius; + this.startAngleDeg; // zero startAngle is in "X" axis positive. + this.sweepAngleDeg; // sweeping in CounterClockWise is positive. + this.numPointsFor360Deg; // interpolation param. - if (idx === 0) - { prevIdx = verticesCount - 1; } - else - { prevIdx = idx - 1; } - - return prevIdx; + // Alternative vars. + this.startPoint; // if no exist radius, then startPoint define the radius. + this.endPoint; + this.sweepSense; // 1=CCW, -1=CW. }; -VertexList.getNextIdx = function(idx, vertexArray) +/** + * Set the center position of Arc2D. + * @class Arc2D + */ +Arc2D.prototype.deleteObjects = function() { - var verticesCount = vertexArray.length; + if (this.centerPoint !== undefined) + { this.centerPoint.deleteObjects(); } // Point3D. + this.centerPoint = undefined; + this.radius = undefined; + this.startAngleDeg = undefined; + this.sweepAngleDeg = undefined; + this.numPointsFor360Deg = undefined; - if (idx < 0 || idx > verticesCount-1) - { return undefined; } + if (this.startPoint !== undefined) + { this.startPoint.deleteObjects(); } - var nextIdx; + this.startPoint = undefined; - if (idx === verticesCount - 1) - { nextIdx = 0; } - else - { nextIdx = idx + 1; } - - return nextIdx; -}; - -VertexList.getVtxSegment = function(idx, vertexArray, resultVtxSegment) -{ - var currVertex = vertexArray[idx]; - var nextIdx = VertexList.getNextIdx(idx, vertexArray); - var nextVertex = vertexArray[nextIdx]; + if (this.endPoint !== undefined) + { this.endPoint.deleteObjects(); } - if (resultVtxSegment === undefined) - { resultVtxSegment = new VtxSegment(currVertex, nextVertex); } - else - { - resultVtxSegment.setVertices(currVertex, nextVertex); - } - - return resultVtxSegment; + this.endPoint = undefined; + this.sweepSense = undefined; // 1=CCW, -1=CW. }; -VertexList.getVector = function(idx, vertexArray, resultVector) +/** + * Set the center position of Arc + * @param {Number} cx the x coordi of the center + * @param {Number} cy the y coordi of the center + */ +Arc2D.prototype.setCenterPosition = function(cx, cy) { - var currVertex = vertexArray[idx]; - var nextIdx = VertexList.getNextIdx(idx, vertexArray); - var nextVertex = vertexArray[nextIdx]; - - var currPoint = currVertex.point3d; - var nextPoint = nextVertex.point3d; + if (this.centerPoint === undefined) + { this.centerPoint = new Point2D(); } - if (resultVector === undefined) - { resultVector = new Point3D(nextPoint.x - currPoint.x, nextPoint.y - currPoint.y, nextPoint.z - currPoint.z); } - else - { - resultVector.setVertices(nextPoint.x - currPoint.x, nextPoint.y - currPoint.y, nextPoint.z - currPoint.z); - } - - return resultVector; -}; - -VertexList.getCrossProduct = function(idx, vertexArray, resultCrossProduct) -{ - var currVector = VertexList.getVector(idx, vertexArray, undefined); - var prevIdx = VertexList.getPrevIdx(idx, vertexArray); - var prevVector = VertexList.getVector(prevIdx, vertexArray, undefined); - resultCrossProduct = prevVector.crossProduct(currVector, resultCrossProduct); - - return resultCrossProduct; + this.centerPoint.set(cx, cy); }; /** - * 어떤 일을 하고 있습니까? - * @returns vertex + * Set the radius value + * @param {Number} radius */ -VertexList.prototype.deleteObjects = function() +Arc2D.prototype.setRadius = function(radius) { - for (var i = 0, vertexCount = this.vertexArray.length; i < vertexCount; i++) - { - this.vertexArray[i].deleteObjects(); - this.vertexArray[i] = undefined; - } - this.vertexArray = undefined; + this.radius = radius; }; /** - * 어떤 일을 하고 있습니까? - * @returns vertex + * Set the start angle of the arc. + * @param startAngleDegree */ -VertexList.prototype.copyFrom = function(vertexList) +Arc2D.prototype.setStartAngleDegree = function(startAngleDegree) { - // first reset vertexArray. - this.deleteObjects(); - this.vertexArray = []; - - var vertex; - var myVertex; - var vertexCount = vertexList.getVertexCount(); - for (var i=0; i=0) + { + for (var currAngRad = 0.0; currAngRadsweepAngRad; currAngRad -= increAngRad) + { + x = cx + this.radius * Math.cos(currAngRad + startAngRad); + y = cy + this.radius * Math.sin(currAngRad + startAngRad); + point = new Point2D(x, y); + pointsArray.push(point); + } + } + + // once finished, mark the 1rst point and the last point as"important point". + var pointsCount = pointsArray.length; + if (pointsCount > 0) + { + pointsArray[0].pointType = 1; + pointsArray[pointsCount-1].pointType = 1; + } + + // now merge points into "resultPointsArray". + var errorDist = 0.0001; // 0.1mm. + var resultExistentPointsCount = resultPointsArray.length; + for (var i=0; i 0) + { + // check if the last point of "resultPointsArray" and the 1rst point of "this" is coincident. + var lastExistentPoint = resultPointsArray[resultExistentPointsCount-1]; + point = pointsArray[i]; + if (!lastExistentPoint.isCoincidentToPoint(point, errorDist)) + { + resultPointsArray.push(point); + } + } + else + { + resultPointsArray.push(pointsArray[i]); + } + } + else + { + resultPointsArray.push(pointsArray[i]); + } + } + + // Last check: finally, in case of sweepAngle = 360 degrees, or is closed pointsArray, then pop the last insertedPoint. + resultExistentPointsCount = resultPointsArray.length; + if (resultExistentPointsCount > 0) + { + // check if the last point of "resultPointsArray" and the 1rst point of "this" is coincident. + var lastPoint = resultPointsArray[resultExistentPointsCount-1]; + var firstPoint = resultPointsArray[0]; + if (lastPoint.isCoincidentToPoint(firstPoint, errorDist)) + { + resultPointsArray.pop(); + lastPoint.deleteObjects(); + } + } + + return resultPointsArray; }; + + + + + + + + + + + + + + + + + + + +'use strict'; + /** - * 어떤 일을 하고 있습니까? - * @param transformMatrix 변수 + * This show x, y ,z axises of the given feature to visualize them + * @class AxisXYZ + * + * @param {number} length */ -VertexList.prototype.transformPointsByMatrix4 = function(transformMatrix) +var AxisXYZ = function(length) { - for (var i = 0, vertexCount = this.vertexArray.length; i < vertexCount; i++) + if (!(this instanceof AxisXYZ)) { - var vertex = this.vertexArray[i]; - transformMatrix.transformPoint3D(vertex.point3d, vertex.point3d); + throw new Error(Messages.CONSTRUCT_ERROR); } + + if (length === undefined) + { this.length = 60; } + else { this.length = length; } + + /** + * Container which holds the VBO Cache Keys + * @type {VBOVertexIdxCacheKeysContainer} + */ + this.vbo_vicks_container = new VBOVertexIdxCacheKeysContainer(); + //this.vboKey = this.vbo_vicks_container.newVBOVertexIdxCacheKey(); }; -VertexList.prototype.setIdxInList = function() +/** + * Set the length of the axises + * @param {Number} length the length of the axis + */ +AxisXYZ.prototype.setDimension = function(length) { - VertexList.setIdxInList(this.vertexArray); - /* - for (var i = 0, vertexCount = this.vertexArray.length; i < vertexCount; i++) - { - this.vertexArray[i].idxInList = i; - } - */ + this.length = length; }; -VertexList.setIdxInList = function(vertexArray) +/** + * Visualize the axises at the feature + * @param {Number} length the length of the axis to set the length of the axises + * @returns {Mesh} mesh + */ +AxisXYZ.prototype.makeMesh = function(length) { - if (vertexArray === undefined) - { return; } + if (length !== undefined) + { this.length = length; } - for (var i = 0, vertexCount = vertexArray.length; i < vertexCount; i++) + var pMesh = new ParametricMesh(); + + pMesh.profile = new Profile2D(); + var profileAux = pMesh.profile; + + // create a halfArrow profile. + var outerRing = profileAux.newOuterRing(); + var arrowLength = this.length; + var arrowWidth = this.length*0.1; + var polyLine = outerRing.newElement("POLYLINE"); + var point3d = polyLine.newPoint2d(0, 0); // 0 + point3d = polyLine.newPoint2d(arrowWidth*0.25, arrowLength*0.25); // 1 + point3d = polyLine.newPoint2d(arrowWidth*0.25, arrowLength*0.75); // 2 + point3d = polyLine.newPoint2d(arrowWidth*0.5, arrowLength*0.75); // 3 + point3d = polyLine.newPoint2d(0, arrowLength); // 3 + //-------------------------------------------------------------------- + + var bIncludeBottomCap, bIncludeTopCap; + var revolveAngDeg, revolveSegmentsCount, revolveSegment2d; + revolveAngDeg = 360.0; + + // create a rotation axis by a segment. + revolveSegment2d = new Segment2D(); + var strPoint2d = new Point2D(0, -10); + var endPoint2d = new Point2D(0, 10); + revolveSegment2d.setPoints(strPoint2d, endPoint2d); + revolveSegmentsCount = 8; + + // rotate the profile and create the Y axis. + pMesh.revolve(profileAux, revolveAngDeg, revolveSegmentsCount, revolveSegment2d); + + bIncludeBottomCap = false; + bIncludeTopCap = false; + var mesh = pMesh.getSurfaceIndependentMesh(undefined, bIncludeBottomCap, bIncludeTopCap); + mesh.setColor(0.1, 1.0, 0.1, 1.0); // set the color. + mesh.reverseSense(); + + // copy & rotate the mesh and create the X axis. + var tMatTest = new Matrix4(); + var mesh2 = mesh.getCopy(undefined); + tMatTest.rotationAxisAngDeg(-90.0, 0, 0, 1); + mesh2.transformByMatrix4(tMatTest); + mesh2.setColor(1.0, 0.1, 0.1, 1.0); // set the color. + + // copy & rotate the mesh and create the Z axis. + var mesh3 = mesh.getCopy(undefined); + tMatTest.rotationAxisAngDeg(90.0, 1, 0, 0); + mesh3.transformByMatrix4(tMatTest); + mesh3.setColor(0.1, 0.1, 1.0, 1.0); // set the color. + + // Merge all meshes into a one mesh and make a unique vbo. + mesh.mergeMesh(mesh2); + mesh.mergeMesh(mesh3); + return mesh; +}; + +/** + * Get the container which holds the VBO Cache Keys + * @returns {VBOVertexIdxCacheKeysContainer} vbo_vicks_container + */ +AxisXYZ.prototype.getVboKeysContainer = function() +{ + return this.vbo_vicks_container; +}; + +'use strict'; +/** +* This class represent the bounding box of the other feature in 2D +* @class BoundingRectangle +*/ +var BoundingRectangle = function(x, y) +{ + if (!(this instanceof BoundingRectangle)) { - vertexArray[i].idxInList = i; + throw new Error(Messages.CONSTRUCT_ERROR); } + + this.minX = Number.MAX_VALUE; + this.maxX = Number.MIN_VALUE; + this.minY = Number.MAX_VALUE; + this.maxY = Number.MIN_VALUE; }; +BoundingRectangle.prototype.setInit = function(point) +{ + if (point === undefined) + { return; } + + this.minX = point.x; + this.minY = point.y; + this.maxX = point.x; + this.maxY = point.y; +}; /** - * 어떤 일을 하고 있습니까? - * @param transformMatrix 변수 + * Initiation bounding rectangle by the other bounding rectangle + * @param {BoundingRectangle} bRect The other bounding rectangle */ -VertexList.prototype.getVboDataArrays = function(resultVbo) +BoundingRectangle.prototype.setInitByRectangle = function(bRect) { - VertexList.getVboDataArrays(this.vertexArray, resultVbo) ; - return resultVbo; + if (bRect === undefined) + { return; } + + this.minX = bRect.minX; + this.minY = bRect.minY; + this.maxX = bRect.maxX; + this.maxY = bRect.maxY; }; /** - * 어떤 일을 하고 있습니까? - * @param transformMatrix 변수 + * Change the range of this bounding rectangle if a point is added + * @param {Point2D} point */ -VertexList.getVboDataArrays = function(vertexArray, resultVbo) +BoundingRectangle.prototype.addPoint = function(point) { - // returns positions, and if exist, normals, colors, texCoords.*** - var verticesCount = vertexArray.length; - if (verticesCount === 0) - { return resultVbo; } - - if (resultVbo === undefined) - { resultVbo = new VBOVertexIdxCacheKey(); } - - var posArray = []; - var norArray; - var colArray; - var texCoordArray; + if (point === undefined) + { return; } - var vertex, position, normal, color, texCoord; + if (point.x < this.minX) + { this.minX = point.x; } + else if (point.x > this.maxX) + { this.maxX = point.x; } - for (var i = 0; i < verticesCount; i++) - { - vertex = vertexArray[i]; - if (vertex.point3d === undefined) - { continue; } - - position = vertex.point3d; - posArray.push(position.x); - posArray.push(position.y); - posArray.push(position.z); - - normal = vertex.normal; - if (normal) - { - if (norArray === undefined) - { norArray = []; } - - norArray.push(normal.x*127); - norArray.push(normal.y*127); - norArray.push(normal.z*127); - } - - color = vertex.color4; - if (color) - { - if (colArray === undefined) - { colArray = []; } - - colArray.push(color.r*255); - colArray.push(color.g*255); - colArray.push(color.b*255); - colArray.push(color.a*255); - } - - texCoord = vertex.texCoord; - if (texCoord) - { - if (texCoordArray === undefined) - { texCoordArray = []; } - - texCoordArray.push(texCoord.x); - texCoordArray.push(texCoord.y); - } - } + if (point.y < this.minY) + { this.minY = point.y; } + else if (point.y > this.maxY) + { this.maxY = point.y; } +}; +/** + * Change the range of this bounding rectangle if a rectangle is added + * @param {BoundingRectangle} bRect + */ +BoundingRectangle.prototype.addRectangle = function(bRect) +{ + if (bRect === undefined) + { return; } - resultVbo.posVboDataArray = Float32Array.from(posArray); - if (normal) - { resultVbo.norVboDataArray = Int8Array.from(norArray); } + if (bRect.minX < this.minX) + { this.minX = bRect.minX; } + if (bRect.maxX > this.maxX) + { this.maxX = bRect.maxX; } - if (color) - { resultVbo.colVboDataArray = Uint8Array.from(colArray); } + if (bRect.minY < this.minY) + { this.minY = bRect.minY; } + if (bRect.maxY > this.maxY) + { this.maxY = bRect.maxY; } +}; +/** + * Check whether this rectangle is intersected with the given bounding rectangle + * @param {BoundingRectangle} bRect + * @returns {Boolean} + */ +BoundingRectangle.prototype.intersectsWithRectangle = function(bRect) +{ + if (bRect === undefined) + { return false; } - if (texCoord) - { resultVbo.tcoordVboDataArray = Float32Array.from(texCoordArray); } + if (bRect.minX > this.maxX) + { return false; } + else if (bRect.maxX < this.minX) + { return false; } + else if (bRect.minY > this.maxY) + { return false; } + else if (bRect.maxY < this.minY) + { return false; } - return resultVbo; + return true; }; @@ -45774,446 +48296,859 @@ VertexList.getVboDataArrays = function(vertexArray, resultVbo) -'use strict'; + + + + + + + +'use strict'; /** - * 어떤 일을 하고 있습니까? - * @class VertexMatrix + * This is similar with the 3D version of the Bounding Rectangle but this is slighthly different. + * 꼭지점을 가지고 한붓 그리기로 3차원 버전의 BB를 그립니다. + * @class BoxAux */ -var VertexMatrix = function() +var BoxAux = function() { - if (!(this instanceof VertexMatrix)) + if (!(this instanceof BoxAux)) { throw new Error(Messages.CONSTRUCT_ERROR); } - this.vertexListsArray = []; - // SCTRATXH.****************** - this.totalVertexArraySC = []; + // vertex indices of the BoxAux. + // 3----------2 7----------6 + // | | | | + // | bottom | | top | + // | | | | + // 0----------1 4----------5 + + this.triPolyhedron = new TriPolyhedron(); + this.vbo_vicks_container = new VBOVertexIdxCacheKeysContainer(); + this.vBOVertexIdxCacheKey = this.vbo_vicks_container.newVBOVertexIdxCacheKey(); }; /** - * 어떤 일을 하고 있습니까? - * @returns vertexList + * get the Vbo keys container of this feature */ -VertexMatrix.prototype.deleteObjects = function() +BoxAux.prototype.getVboKeysContainer = function() { - for (var i = 0, vertexListsCount = this.vertexListsArray.length; i < vertexListsCount; i++) - { - this.vertexListsArray[i].deleteObjects(); - this.vertexListsArray[i] = undefined; - } - this.vertexListsArray = undefined; + return this.vbo_vicks_container; }; /** - * 어떤 일을 하고 있습니까? - * @returns vertexList + * make Axis Aligned Bounding Box(Aux) + * @param {Number} xLength + * @param {Number} yLength + * @param {Number} zLength */ -VertexMatrix.prototype.newVertexList = function() +BoxAux.prototype.makeAABB = function(xLength, yLength, zLength) { - var vertexList = new VertexList(); - this.vertexListsArray.push(vertexList); - return vertexList; + // this makes a BoxAux centered on the center of the BoxAux. + var minX = -xLength/2.0; + var minY = -yLength/2.0; + var minZ = -zLength/2.0; + + var maxX = xLength/2.0; + var maxY = yLength/2.0; + var maxZ = zLength/2.0; + + // make 8 vertices and 6 triSurfaces. + var vertexList = this.triPolyhedron.vertexList; + + // Bottom.* + var vertex = vertexList.newVertex(); // 0. + vertex.setPosition(minX, minY, minZ); + + vertex = vertexList.newVertex(); // 1. + vertex.setPosition(maxX, minY, minZ); + + vertex = vertexList.newVertex(); // 2. + vertex.setPosition(maxX, maxY, minZ); + + vertex = vertexList.newVertex(); // 3. + vertex.setPosition(minX, maxY, minZ); + + // Top. + vertex = vertexList.newVertex(); // 4. + vertex.setPosition(minX, minY, maxZ); + + vertex = vertexList.newVertex(); // 5. + vertex.setPosition(maxX, minY, maxZ); + + vertex = vertexList.newVertex(); // 6. + vertex.setPosition(maxX, maxY, maxZ); + + vertex = vertexList.newVertex(); // 7. + vertex.setPosition(minX, maxY, maxZ); + + + // now, create triSurfaces and triangles. + var triSurface; + var triangle; + // Bottom surface. + triSurface = this.triPolyhedron.newTriSurface(); + triangle = triSurface.newTriangle(); + triangle.setVertices(vertexList.getVertex(0), vertexList.getVertex(2), vertexList.getVertex(1)); + + triangle = triSurface.newTriangle(); + triangle.setVertices(vertexList.getVertex(0), vertexList.getVertex(3), vertexList.getVertex(2)); + + // Top surface. + triSurface = this.triPolyhedron.newTriSurface(); + triangle = triSurface.newTriangle(); + triangle.setVertices(vertexList.getVertex(4), vertexList.getVertex(5), vertexList.getVertex(6)); + + triangle = triSurface.newTriangle(); + triangle.setVertices(vertexList.getVertex(4), vertexList.getVertex(6), vertexList.getVertex(7)); + + // Front surface. + triSurface = this.triPolyhedron.newTriSurface(); + triangle = triSurface.newTriangle(); + triangle.setVertices(vertexList.getVertex(0), vertexList.getVertex(1), vertexList.getVertex(5)); + + triangle = triSurface.newTriangle(); + triangle.setVertices(vertexList.getVertex(0), vertexList.getVertex(5), vertexList.getVertex(4)); + + // Right surface. + triSurface = this.triPolyhedron.newTriSurface(); + triangle = triSurface.newTriangle(); + triangle.setVertices(vertexList.getVertex(1), vertexList.getVertex(2), vertexList.getVertex(6)); + + triangle = triSurface.newTriangle(); + triangle.setVertices(vertexList.getVertex(1), vertexList.getVertex(6), vertexList.getVertex(5)); + + // Rear surface. + triSurface = this.triPolyhedron.newTriSurface(); + triangle = triSurface.newTriangle(); + triangle.setVertices(vertexList.getVertex(2), vertexList.getVertex(3), vertexList.getVertex(7)); + + triangle = triSurface.newTriangle(); + triangle.setVertices(vertexList.getVertex(2), vertexList.getVertex(7), vertexList.getVertex(6)); + + // Left surface. + triSurface = this.triPolyhedron.newTriSurface(); + triangle = triSurface.newTriangle(); + triangle.setVertices(vertexList.getVertex(3), vertexList.getVertex(0), vertexList.getVertex(4)); + + triangle = triSurface.newTriangle(); + triangle.setVertices(vertexList.getVertex(3), vertexList.getVertex(4), vertexList.getVertex(7)); + }; +'use strict'; /** - * 어떤 일을 하고 있습니까? - * @param idx 변수 - * @returns vertexListArray[idx] + * This represent the circle feature drawn in 2D. + * @class Circle2D */ -VertexMatrix.prototype.getVertexList = function(idx) +var Circle2D = function() { - if (idx >= 0 && idx < this.vertexListsArray.length) - { - return this.vertexListsArray[idx]; - } - else + if (!(this instanceof Circle2D)) { - return undefined; + throw new Error(Messages.CONSTRUCT_ERROR); } + // sweeping in CounterClockWise is positive. + // zero startAngle is in "X" axis positive. + this.centerPoint; // Point2D. + this.radius; + this.numPointsFor360Deg; // interpolation param. }; /** - * 어떤 일을 하고 있습니까? - * @param vertexMatrix 변수 + * Set the center position of Circle. + * @param {Number} cx the x coordi of the center + * @param {Number} cy the y coordi of the center */ -VertexMatrix.prototype.copyFrom = function(vertexMatrix) +Circle2D.prototype.setCenterPosition = function(cx, cy) { - if (vertexMatrix === undefined) - { return; } + if (this.centerPoint === undefined) + { this.centerPoint = new Point2D(); } - var vertexList, myVertexList; - var vertexListsCount = vertexMatrix.vertexListsArray.length; - for (var i=0; i} + */ + this.vertexArray; + /** + * 페이스의 임의의 버텍스의 hEdge. + * @type {HalfEdge} + */ + this.hEdge; + /** + * 페이스의 플레인 노말 포인트. + * @type {Point3D} + */ + this.planeNormal; + /** + * @deprecated not used + */ + this.surfaceOwner; +}; - - - - - -'use strict'; /** -* 어떤 일을 하고 있습니까? -* @class VtxProfilesList -*/ -var VtxProfilesList = function(x, y) + * delete all member. + * Note: "Face" is NO-Owner of vertices, so, don't delete vertices. Only set as "undefined". + * Note: "Face" is NO-Owner of hEdge, so, don't delete hEdge. Only set as "undefined". + */ +Face.prototype.deleteObjects = function() { - if (!(this instanceof VtxProfilesList)) + this.vertexArray = undefined; + this.hEdge = undefined; + + if (this.planeNormal !== undefined) { - throw new Error(Messages.CONSTRUCT_ERROR); + this.planeNormal.deleteObjects(); + this.planeNormal = undefined; } + + this.surfaceOwner = undefined; +}; +/** + * get vertex array length + * @returns {number} length of this vertexArray. + */ +Face.prototype.getVerticesCount = function() +{ + if (this.vertexArray === undefined) + { return 0; } - this.vtxProfilesArray; - this.convexFacesIndicesData; + return this.vertexArray.length; }; -VtxProfilesList.getLateralFaces = function(bottomVtxRing, topVtxRing, resultFacesArray, resultMesh, elemIndexRange) +/** + * add vertex to this vertexArray + * @param {Vertex} vertex + */ +Face.prototype.addVertex = function(vertex) { - // This returns a lateral surface between "bottomVtxRing" & "topVtxRing" limited by "elemIndexRange".*** - if (resultFacesArray === undefined) - { resultFacesArray = []; } - - if (resultMesh.hedgesList === undefined) - { resultMesh.hedgesList = new HalfEdgesList(); } - - var hedgesList = resultMesh.hedgesList; + if (this.vertexArray === undefined) + { this.vertexArray = []; } - var strIdx, currIdx, endIdx, nextIdx; - var vtx0, vtx1, vtx2, vtx3; - var face, prevFace; - var hedgesArray = []; - currIdx = elemIndexRange.strIdx; - while (currIdx !== elemIndexRange.endIdx) + this.vertexArray.push(vertex); +}; + +/** + * add vertex array to this vertexArray + * @param {Array.} vertex + */ +Face.prototype.addVerticesArray = function(verticesArray) +{ + if (this.vertexArray === undefined) + { this.vertexArray = []; } + + Array.prototype.push.apply(this.vertexArray, verticesArray); +}; + +/** + * get vertex + * @param {number} idx array index. + * @returns {Vertex|undefined} + */ +Face.prototype.getVertex = function(idx) +{ + if (this.vertexArray === undefined) + { return undefined; } + + return this.vertexArray[idx]; +}; + +/** + * reverse this vertex array. + */ +Face.prototype.reverseSense = function() +{ + this.vertexArray.reverse(); +}; + +/** + * set color all vertex in vertexArray. + * @param {number} r + * @param {number} g + * @param {number} b + * @param {number} a + */ +Face.prototype.setColor = function(r, g, b, a) +{ + var vertex; + var verticesCount = this.getVerticesCount(); + for (var i=0; i} vertexArray + * @param {Point3D} resultPlaneNormal if this is undefined, set new Point3D instance. + * @returns {Point3D} + */ +Face.calculatePlaneNormal = function(vertexArray, resultPlaneNormal) +{ + // Note: the vertexArray must be planar. + if (resultPlaneNormal === undefined) + { resultPlaneNormal = new Point3D(); } + + resultPlaneNormal.set(0, 0, 0); + var verticesCount = vertexArray.length; + for (var i=0; i 1.0) + { cosAlfa = 1.0; } + else if (cosAlfa < -1.0) + { cosAlfa = -1.0; } + var alfa = Math.acos(cosAlfa); + + resultPlaneNormal.add(crossProd.x*alfa, crossProd.y*alfa, crossProd.z*alfa); } + resultPlaneNormal.unitary(); - return resultFacesArray; + return resultPlaneNormal; }; -VtxProfilesList.prototype.newVtxProfile = function() +/** + * calculate plane normal and set this plane normal. + * @returns {Point3D} this plane normal point. + * + * @see Face#calculatePlaneNormal + */ +Face.prototype.calculatePlaneNormal = function() { - if (this.vtxProfilesArray === undefined) - { this.vtxProfilesArray = []; } - - var vtxProfile = new VtxProfile(); - this.vtxProfilesArray.push(vtxProfile); - return vtxProfile; + // Note: face must be planar. + this.planeNormal = Face.calculatePlaneNormal(this.vertexArray, this.planeNormal); + return this.planeNormal; }; -VtxProfilesList.prototype.getVtxProfilesCount = function() +/** + * 각 버텍스들의 normal point를 face의 plane normal로 일괄 적용. + * @param {Boolean} bForceRecalculatePlaneNormal if true, force execute calculatePlaneNormal. + * + * @see Face#calculatePlaneNormal + */ +Face.prototype.calculateVerticesNormals = function(bForceRecalculatePlaneNormal) { - if (this.vtxProfilesArray === undefined) - { return 0; } + // This function calculates normals for concave faces. + // Provisionally calculate the plane normal and assign to the vertices. + var verticesCount = this.vertexArray.length; + + if (bForceRecalculatePlaneNormal !== undefined && bForceRecalculatePlaneNormal) + { this.calculatePlaneNormal(); } - return this.vtxProfilesArray.length; + if (this.planeNormal === undefined) + { this.calculatePlaneNormal(); } + + var normal; + var verticesCount = this.getVerticesCount(); + for (var i=0; i nx && nz >= ny ) + { + best_plane = 0; //"xy"; + } + else if ( nx >= ny && nx >= nz ) + { + best_plane = 1; //"yz"; + } + else if ( ny > nx && ny >= nz ) + { + best_plane = 2; //"xz"; } - - return resultVerticesArray; + + return best_plane; }; -VtxProfilesList.prototype.getMesh = function(resultMesh, bIncludeBottomCap, bIncludeTopCap) +/** + * 버텍스 배열을 plane normal에 따라 polygon2d 형식으로 변환 후 반환. + * @static + * @param {Array.} vertexArray + * @param {Point3D} normal + * @param {Polygon2D} resultProjectedPolygon2d + * @returns {Polygon2D} + */ +Face.getProjectedPolygon2D = function(vertexArray, normal, resultProjectedPolygon2d) { - // face's vertex order.*** - // 3-------2 - // | | - // | | - // | | - // 0-------1 + // Create a temp polygon2d. + if (resultProjectedPolygon2d === undefined) + { resultProjectedPolygon2d = new Polygon2D(); } - if (this.vtxProfilesArray === undefined) - { return resultTriangleMatrix; } + if (resultProjectedPolygon2d.point2dList === undefined) + { resultProjectedPolygon2d.point2dList = new Point2DList(); } + + var point2dList = resultProjectedPolygon2d.point2dList; + point2dList.pointsArray = VertexList.getProjectedPoints2DArray(vertexArray, normal, point2dList.pointsArray); + + return resultProjectedPolygon2d; +}; + +/** + * 오목 폴리곤들을 볼록 폴리곤들로 분리 후 반환. + * concave to convex list. + * @param {Array.} resultTrianglesArray + * @returns {Array.} + */ +Face.prototype.getTessellatedTriangles = function(resultTrianglesArray) +{ + if (resultTrianglesArray === undefined) + { resultTrianglesArray = []; } + + var verticesCount = this.getVerticesCount(); + if (verticesCount <= 3) + { + // This is a triangle, so no need to tessellate. + resultTrianglesArray = this.getTrianglesConvex(resultTrianglesArray); + return resultTrianglesArray; + } + + // 1rst, must project the face to a plane and process to tessellate in 2d. + var normal = this.getPlaneNormal(); - // outerLateral.*************************************************** - var vtxProfilesCount = this.getVtxProfilesCount(); + var bestPlaneToProject = Face.getBestFacePlaneToProject(normal); - if (vtxProfilesCount < 2) - { return resultTriangleMatrix; } + // Create a temp polygon2d. + var polygon2d = Face.getProjectedPolygon2D(this.vertexArray, normal, undefined); - if (resultMesh === undefined) - { resultMesh = new Mesh(); } + // Now, tessellate the polygon2D. + // Before tessellate, we must know if there are concavePoints. + var resultConcavePointsIdxArray; + resultConcavePointsIdxArray = polygon2d.calculateNormal(resultConcavePointsIdxArray); - if (resultMesh.vertexList === undefined) - { resultMesh.vertexList = new VertexList(); } + var convexPolygonsArray = []; + polygon2d.tessellate(resultConcavePointsIdxArray, convexPolygonsArray); - // 1rst, get all vertices and put it into the resultMesh.*** - resultMesh.vertexList.vertexArray = this.getAllVertices(resultMesh.vertexList.vertexArray); - - var bottomVtxProfile, topVtxProfile; + // inside of "convexPolygonsArray" there are 1 or more convexPolygons result of tessellation of the polygon2d. - bottomVtxProfile = this.getVtxProfile(0); - var outerVtxRing = bottomVtxProfile.outerVtxRing; - var elemIndexRange; - var bottomVtxRing, topVtxRing; - var elemIndicesCount; - var strIdx, currIdx, endIdx, nextIdx; - var vtx0, vtx1, vtx2, vtx3; - var face, surface; - var k; - var facesArray = []; - var prevFacesArray; - var elemsCount = outerVtxRing.elemsIndexRangesArray.length; - - for (var i=0; i 0) - { - // set twins between "prevFacesArray" & "facesArray".*** - var currFace, prevFace; - var facesCount = facesArray.length; - for (var k=0; k} resultTrianglesArray undefined일 때, 배열로 초기화. + * @returns {Array.|undefined} 기존 버텍스 배열이 undefined거나 비어있으면 매개변수 resultTrianglesArray 상태 그대로 반환. + */ +Face.prototype.getTrianglesConvex = function(resultTrianglesArray) +{ + // To call this method, the face MUST be convex. + if (this.vertexArray === undefined || this.vertexArray.length === 0) + { return resultTrianglesArray; } - // Inner laterals.************************************************************************ - var innerVtxRing; - var innerRinsCount = bottomVtxProfile.getInnerVtxRingsCount(); - for (var k=0; k0) - { - // set twins between "prevFacesArray" & "facesArray".*** - var currFace, prevFace; - var facesCount = facesArray.length; - for (var a=0; a} resultHedgesArray + * @returns {Array.} + * + * @see HalfEdge#getHalfEdgesLoop + * @see HalfEdge#isFrontier + */ +Face.prototype.getFrontierHalfEdges = function(resultHedgesArray) +{ + var hedgesArray = this.getHalfEdgesLoop(undefined); + if (hedgesArray === undefined) + { return resultHedgesArray; } - // Top profile.*********************************************************************** - // in this case, there are a surface with multiple convex faces.*** - if (bIncludeTopCap === undefined || bIncludeTopCap === true) + if (resultHedgesArray === undefined) + { resultHedgesArray = []; } + + var hedgesCount = hedgesArray.length; + var hedge; + for (var i=0; i} resultHedgesArray + * @returns {Array.} + * + * @see HalfEdge#getHalfEdgesLoop + */ +Face.prototype.getHalfEdgesLoop = function(resultHedgesArray) +{ + if (this.hEdge === undefined) + { return resultHedgesArray; } + + resultHedgesArray = HalfEdge.getHalfEdgesLoop(this.hEdge, resultHedgesArray); + return resultHedgesArray; +}; + +/** + * 현재 Face와 매개변수 Face의 각각 hedge를 이용하여 twin hedge를 찾아서 twin 유무 반환 + * @param {Face} face Required. Must contain hEdge. + * @returns {Boolean} is twin face. + */ +Face.prototype.setTwinFace = function(face) +{ + if (face === undefined) + { return false; } + + if (this.hEdge === undefined || face.hEdge === undefined) + { return false; } + + var hedgesArray = face.getHalfEdgesLoop(undefined); + var hedgesCount = hedgesArray.length; + var hedge; + var twined = false; + for (var i=0; i|undefined} resultHalfEdgesArray + * @returns {Array.} + */ +Face.prototype.createHalfEdges = function(resultHalfEdgesArray) { - if (resultSurface === undefined) - { resultSurface = new Surface(); } - - var currRing; - var currVtxRing; - var faceIndicesData; - var indexData; - var ringIdx, vertexIdx; - var indicesCount; - var face; + if (this.vertexArray === undefined || this.vertexArray.length === 0) + { return resultHalfEdgesArray; } + + if (resultHalfEdgesArray === undefined) + { resultHalfEdgesArray = []; } + var vertex; - var convexFacesCount = convexFacesIndicesData.length; - for (var i=0; i} + */ +HalfEdge.getHalfEdgesLoop = function(hedge, resultHedgesArray) +{ + if (hedge === undefined) + { return resultHedgesArray; } + + if (resultHedgesArray === undefined) + { resultHedgesArray = []; } + + resultHedgesArray.length = 0; // init the array. + + var startHedge = hedge; + var currHedge = hedge; + var finished = false; + while (!finished) + { + resultHedgesArray.push(currHedge); + currHedge = currHedge.next; + if (currHedge === startHedge || currHedge === undefined) + { finished = true; } + } + + return resultHedgesArray; +}; + +'use strict'; + +/** + * HalfEdge객체의 리스트 + * @exception {Error} Messages.CONSTRUCT_ERROR + * + * @class HalfEdgesList + */ +var HalfEdgesList = function() +{ + if (!(this instanceof HalfEdgesList)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + + /** + * @type {Array.} + */ + this.hEdgesArray; +}; + +/** + * hEdgesArray 초기화 + */ +HalfEdgesList.prototype.deleteObjects = function() +{ + if (this.hEdgesArray !== undefined) + { + var hedgesCount = this.hEdgesArray.length; + for (var i=0; i} HalfEdge Required. HalfEdge들의 배열 + */ +HalfEdgesList.prototype.addHalfEdgesArray = function(hEdgesArray) +{ + if (hEdgesArray === undefined) + { return; } + + if (this.hEdgesArray === undefined) + { this.hEdgesArray = []; } + + Array.prototype.push.apply(this.hEdgesArray, hEdgesArray); +}; +'use strict'; +/** +* 폴리곤을 구성하는 포인트의 인덱스데이터 객체 +* Rind2D의 getPolygon 수행 시 인스턴스를 생성하여 각 포인트에 설정함. +* owner는 Ring2D instance로 설정. +* +* @exception {Error} Messages.CONSTRUCT_ERROR +* @class IndexData +* +* @see Ring2D#getPolygon +*/ +var IndexData = function() +{ + if (!(this instanceof IndexData)) { - this.vertexList.translateVertices(x, y, z); + throw new Error(Messages.CONSTRUCT_ERROR); } + + /** + * 포인트를 포함하는 Ring2D 객체 + * @type {Ring2D} + */ + this.owner; + + /** + * 포인트의 idxInList + * @deprecated idx 대신 idxInList로 사용되고 있음. 변경 필요 + * @type {Number} + */ + this.idx; }; -VtxRing.prototype.transformPointsByMatrix4 = function(tMat4) +/** + * delete the value of owner and idx. + */ +IndexData.prototype.deleteObjects = function() { - if (this.vertexList !== undefined) + // Don't delete objects. Only assign as undefined. + this.owner = undefined; + this.idx = undefined; +}; +'use strict'; + +/** + * index range. consist of two vertex index. start and end. + * 특정 geometry의 시작vertex와 끝vertex의 index를 저장 + * @exception {Error} Messages.CONSTRUCT_ERROR + * + * @class IndexRange + */ +var IndexRange = function() +{ + if (!(this instanceof IndexRange)) { - this.vertexList.transformPointsByMatrix4(tMat4); + throw new Error(Messages.CONSTRUCT_ERROR); } + + /** + * start index + * @type {Number} + */ + this.strIdx; + + /** + * last index + * @type {Number} + */ + this.endIdx; }; -VtxRing.prototype.makeByPoint2DList = function(point2dList, z) +/** + * make indexRange copy from another indexRange. + * @param {IndexRange} indexRange + */ +IndexRange.prototype.copyFrom = function(indexRange) { - if (point2dList === undefined) + if (indexRange === undefined) { return; } - if (z === undefined) - { z = 0; } + this.strIdx = indexRange.strIdx; + this.endIdx = indexRange.endIdx; +}; + +/** + * indexRange init. + * all member set undifined; + */ +IndexRange.prototype.deleteObjects = function() +{ + this.strIdx = undefined; + this.endIdx = undefined; +}; +'use strict'; +/** + * 교차 판단값 + * 한 객체가 다른 한 객체에 완전히 안쪽에 포함된 경우: INSIDE + * 한 객체가 다른 한 객체에 일부는 안쪽에 포함되고 일부는 바깥쪽에 포함된 경우: INTERSECT + * 한 객체가 다른 한 객체에 완전히 바깥쪽에 있는 경우: OUTSIDE + * A 지점에 포함된 경우: POINT_A + * B 지점에 포함된 경우: POINT_B + * + * @enum + */ +var Intersect = { + /** + * 한 객체가 다른 한 객체에 완전히 바깥쪽에 존재함 + * @type {Number} + * @constant + */ + OUTSIDE: 0, + + /** + * 한 객체가 다른 한 객체의 일부분만 포함 + * @type {Number} + * @constant + */ + INTERSECT: 1, + + /** + * 한 객체가 다른 한 객체를 완전히 포함 + * @type {Number} + * @constant + */ + INSIDE: 2, + + /** + * A 지점에 포함 + * @type {Number} + * @constant + */ + POINT_A: 3, + + /** + * B 지점에 포함 + * @type {Number} + * @constant + */ + POINT_B: 4 +}; +'use strict'; + +/** + * This represents a line which can be shown as linear equation + * @class Line + * @param {Point3D} point the point which decides line + * @param {Point3D} direction the vector of the direction which decides line + */ +var Line = function(point, direction) +{ + if (!(this instanceof Line)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } - if (this.vertexList === undefined) - { this.vertexList = new VertexList(); } + // (x,y,z) = (x0,y0,z0) + lambda * (u, v, w); + if (point !== undefined) + { this.point = point; } + else + { this.point = new Point3D(); } - this.vertexList.copyFromPoint2DList(point2dList, z); - this.calculateElementsIndicesRange(); + if (direction !== undefined) + { this.direction = direction; } + else + { this.direction = new Point3D(); } }; -VtxRing.prototype.calculateElementsIndicesRange = function() +/** + * Set a point and a direction of a linear equation + * @param px 변수 the value of x coordi of the point + * @param py 변수 the value of y coordi of the point + * @param pz 변수 the value of z coordi of the point + * @param dx 변수 the value of x coordi of the point which represents direction + * @param dy 변수 the value of y coordi of the point which represents direction + * @param dz 변수 the value of z coordi of the point which represents direction + */ +Line.prototype.setPointAndDir = function(px, py, pz, dx, dy, dz) { - if (this.vertexList === undefined) + // Note: dx, dy, dz must be unitary. + this.point.set(px, py, pz); + this.direction.set(dx, dy, dz); + this.direction.unitary(); +}; + +/** + * get the point which is projected as 2d plane(the plane which is represented by using x,y axis) + * @param point the target point + * @param projectedPoint the projected point of the target point + * @returns projetedPoint + */ +Line.prototype.getProjectedPoint = function(point, projectedPoint) +{ + if (projectedPoint === undefined) + { projectedPoint = new Point3D(); } + + var plane = new Plane(); + plane.setPointAndNormal(point.x, point.y, point.z, this.direction.x, this.direction.y, this.direction.z); + projectedPoint = plane.intersectionLine(this, projectedPoint); + + return projectedPoint; +}; + +/** + * Check whether the given point is on this line or not + * @param {Point3D} point the given point + * @param {Number} error the error rate which can be handdled + * @returns {Boolean} + */ +Line.prototype.isCoincidentPoint = function(point, error) +{ + if (point === undefined) { return false; } - var vertex; - var idxRange = undefined; - var vertexType; - var vertexCount = this.vertexList.getVertexCount(); - for (var i=0; i distTotal || distB> distTotal) - { - return Constant.INTERSECTION_OUTSIDE; - } - - if (Math.abs(distA + distB - distTotal) < error) - { return Constant.INTERSECTION_INSIDE; } + if (this.meshesArray === undefined) + { return undefined; } + return this.meshesArray[idx]; }; @@ -47130,1639 +50724,1696 @@ VtxSegment.prototype.intersectionWithPoint = function(point, error) -'use strict'; +'use strict'; /** - * 어떤 일을 하고 있습니까? - * @class UniformMatrix4fvDataPair - * @param gl 변수 + * Under implementation + * Top class on Mago3D. + * Handling mouse event and send it to MouseAction + * @class MagoWorld + * @param {MagoManager} magoManager */ -var UniformMatrix4fvDataPair = function(gl, uniformName) +var MagoWorld = function(magoManager) { - if (!(this instanceof UniformMatrix4fvDataPair)) + if (!(this instanceof MagoWorld)) { throw new Error(Messages.CONSTRUCT_ERROR); } - this.gl = gl; - this.name = uniformName; - this.uniformLocation; - this.matrix4fv; + + this.magoManager = magoManager; }; /** - * 어떤 일을 하고 있습니까? - * @param gl 변수 + * 시각화 준비 함수 */ -UniformMatrix4fvDataPair.prototype.bindUniform = function() +MagoWorld.prototype.prepareVisibles = function() { - this.gl.uniformMatrix4fv(this.uniformLocation, false, this.matrix4fv); + // 1rst, do terrain frustum culling. + // TODO: }; /** - * 어떤 일을 하고 있습니까? - * @class UniformVec2fvDataPair - * @param gl 변수 + * 첫 번째 시야를 그릴 준비 */ -var UniformVec2fvDataPair = function(gl, uniformName) +MagoWorld.prototype.renderScene = function() { - if (!(this instanceof UniformVec2fvDataPair)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - this.gl = gl; - this.name = uniformName; - this.uniformLocation; - this.vec2fv; + //this.renderTest(); + var gl = this.magoManager.sceneState.gl; + gl.clearColor(0.0, 0.0, 0.0, 1.0); + gl.enable(gl.DEPTH_TEST); + gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + + this.magoManager.start(undefined, true, 0, 1); }; /** - * 어떤 일을 하고 있습니까? - * @param gl 변수 + * 첫 번째 시야를 그릴 준비 + * @TODO : 리팩토링 필요 */ -UniformVec2fvDataPair.prototype.bindUniform = function() +MagoWorld.prototype.renderTest = function() { - this.gl.uniform2fv(this.uniformLocation, this.vec2fv); + var gl = this.magoManager.sceneState.gl; + gl.clearColor(0.0, 0.0, 0.0, 1.0); + gl.enable(gl.DEPTH_TEST); + gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + + this.magoManager.start(undefined, true, 0, 1); + }; /** - * 어떤 일을 하고 있습니까? - * @class UniformVec3fvDataPair - * @param gl 변수 + * 카메라를 지구의 특정 위치에 위치시키는 함수 + * @param {Number} longitude + * @param {Number} latitude + * @param {Number} altitude */ -var UniformVec3fvDataPair = function(gl, uniformName) +MagoWorld.prototype.goto = function(longitude, latitude, altitude) { - if (!(this instanceof UniformVec3fvDataPair)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - this.gl = gl; - this.name = uniformName; - this.uniformLocation; - this.vec3fv; + var resultCartesian; + resultCartesian = Globe.geographicToCartesianWgs84(longitude, latitude, altitude, resultCartesian); + + var camera = this.magoManager.sceneState.camera; + var camPos = camera.position; + var camDir = camera.direction; + var camUp = camera.up; + + var matrixAux; + matrixAux = this.magoManager.globe.transformMatrixAtCartesianPointWgs84(resultCartesian[0], resultCartesian[1], resultCartesian[2], matrixAux); + + camPos.set(resultCartesian[0], resultCartesian[1], resultCartesian[2]); + + // calculate camDir & camUp. + camDir.set(-matrixAux[8], -matrixAux[9], -matrixAux[10]); + camUp.set(matrixAux[4], matrixAux[5], matrixAux[6]); // tangent north direction. + + this.updateModelViewMatrixByCamera(camera); }; /** - * 어떤 일을 하고 있습니까? - * @param gl 변수 + * 마우스 꾹 누르는 동작을 핸들링 + * @param {type}event */ -UniformVec3fvDataPair.prototype.bindUniform = function() +MagoWorld.prototype.mousedown = function(event) { - this.gl.uniform3fv(this.uniformLocation, this.vec3fv); + this.magoManager.sceneState.mouseButton = event.button; + MagoWorld.updateMouseStartClick(event.clientX, event.clientY, this.magoManager); + this.magoManager.isCameraMoving = true; + }; /** - * 어떤 일을 하고 있습니까? - * @class UniformVec4fvDataPair - * @param gl 변수 + * 마우스 클릭 위치를 최신으로 갱신 + * @param {Number} mouseX 최신 마우스 클릭 위치의 x 좌표 + * @param {Number} mouseY 최신 마우스 클릭 위치의 y 좌표 + * @param {MagoManager} magoManager + * */ -var UniformVec4fvDataPair = function(gl, uniformName) + +MagoWorld.updateMouseClick = function(mouseX, mouseY, magoManager) { - if (!(this instanceof UniformVec4fvDataPair)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - this.gl = gl; - this.name = uniformName; - this.uniformLocation; - this.vec4fv; + var mouseAction = magoManager.sceneState.mouseAction; + mouseAction.curX = mouseX; + mouseAction.curY = mouseY; }; /** - * 어떤 일을 하고 있습니까? - * @param gl 변수 + * 마우스를 드래그하기 시작하는 시점을 저장 + * @param {Number} mouseX the x coordi of the start point + * @param {Number} mouseY the y coordi of the start point + * @param {MagoManager} magoManager */ -UniformVec4fvDataPair.prototype.bindUniform = function() +MagoWorld.updateMouseStartClick = function(mouseX, mouseY, magoManager) { - this.gl.uniform4fv(this.uniformLocation, this.vec4fv); + var gl = magoManager.sceneState.gl; + var mouseAction = magoManager.sceneState.mouseAction; + + MagoWorld.updateMouseClick(mouseX, mouseY, magoManager); + + // if button = 1 (middleButton), then rotate camera. + mouseAction.strX = mouseX; + mouseAction.strY = mouseY; + if (magoManager.sceneState.mouseButton === 0) + { + magoManager.bPicking = true; + } + + // determine world position of the X,Y. + mouseAction.strLinealDepth = ManagerUtils.calculatePixelLinearDepth(gl, mouseAction.strX, mouseAction.strY, magoManager.depthFboAux, magoManager); + mouseAction.strCamCoordPoint = ManagerUtils.calculatePixelPositionCamCoord(gl, mouseAction.strX, mouseAction.strY, mouseAction.strCamCoordPoint, magoManager.depthFboAux, undefined, magoManager); + mouseAction.strWorldPoint = ManagerUtils.cameraCoordPositionToWorldCoord(mouseAction.strCamCoordPoint, mouseAction.strWorldPoint, magoManager); + + // now, copy camera to curCamera. + var camera = magoManager.sceneState.camera; + var strCamera = mouseAction.strCamera; + + strCamera.copyPosDirUpFrom(camera); + + // copy modelViewMatrix. + var modelViewMatrix = magoManager.sceneState.modelViewMatrix; + var modelViewMatrixInv = magoManager.sceneState.modelViewMatrixInv; + mouseAction.strModelViewMatrix._floatArrays = glMatrix.mat4.copy(mouseAction.strModelViewMatrix._floatArrays, modelViewMatrix._floatArrays); + mouseAction.strModelViewMatrixInv._floatArrays = glMatrix.mat4.copy(mouseAction.strModelViewMatrixInv._floatArrays, modelViewMatrixInv._floatArrays); + + // save the sphere pick. + if (magoManager.globe !== undefined) + { + var camRay; + camRay = ManagerUtils.getRayWorldSpace(gl, mouseX, mouseY, camRay, magoManager); // rayWorldSpace. + mouseAction.strWorldPoint2 = magoManager.globe.intersectionLineWgs84(camRay, mouseAction.strWorldPoint2); + } }; /** - * 어떤 일을 하고 있습니까? - * @class Uniform1fDataPair - * @param gl 변수 + * 만약 마우스 핸들링으로 화면이 바뀌었을 경우, 다음 함수가 활성화 된다 + * @param {Camera} camera */ -var Uniform1fDataPair = function(gl, uniformName) +MagoWorld.prototype.updateModelViewMatrixByCamera = function(camera) { - if (!(this instanceof Uniform1fDataPair)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - this.gl = gl; - this.name = uniformName; - this.uniformLocation; - this.floatValue; + var camera = this.magoManager.sceneState.camera; + var camPos = camera.position; + var camDir = camera.direction; + var camUp = camera.up; + var far = camera.frustum.far[0]; + + var tergetX = camPos.x + camDir.x * far; + var tergetY = camPos.y + camDir.y * far; + var tergetZ = camPos.z + camDir.z * far; + + var modelViewMatrix = this.magoManager.sceneState.modelViewMatrix; + modelViewMatrix._floatArrays = Matrix4.lookAt(modelViewMatrix._floatArrays, [camPos.x, camPos.y, camPos.z], + [tergetX, tergetY, tergetZ], + [camUp.x, camUp.y, camUp.z]); + }; /** - * 어떤 일을 하고 있습니까? - * @param gl 변수 + * 마우스를 꾹 눌렀다가 땔 때의 동작을 감지 + * @param {type}event + * */ -Uniform1fDataPair.prototype.bindUniform = function() +MagoWorld.prototype.mouseup = function(event) { - this.gl.uniform1f(this.uniformLocation, this.floatValue); + this.magoManager.sceneState.mouseButton = -1; + this.magoManager.bPicking = false; + this.magoManager.isCameraMoving = false; }; - /** - * 어떤 일을 하고 있습니까? - * @class Uniform1iDataPair - * @param gl 변수 + * 마우스 클릭 동작을 감지 + * @param {type}event */ -var Uniform1iDataPair = function(gl, uniformName) +MagoWorld.prototype.mouseclick = function(event) { - if (!(this instanceof Uniform1iDataPair)) + if (event.button === 0) { - throw new Error(Messages.CONSTRUCT_ERROR); + var mouseX = event.clientX; + var mouseY = event.clientY; + this.magoManager.mouseActionLeftClick(mouseX, mouseY); } - this.gl = gl; - this.name = uniformName; - this.uniformLocation; - this.intValue; }; /** - * 어떤 일을 하고 있습니까? - * @param gl 변수 + * 마우스 휠 동작을 감지 + * @param {type}event */ -Uniform1iDataPair.prototype.bindUniform = function() +MagoWorld.prototype.mousewheel = function(event) { - this.gl.uniform1i(this.uniformLocation, this.intValue); -}; + var delta = event.wheelDelta / 10; + + var mouseAction = this.magoManager.sceneState.mouseAction; + + // move camera. + var camera = this.magoManager.sceneState.camera; + var camPos = camera.position; + var camDir = camera.direction; + var camUp = camera.up; + + var camHeght = camera.getCameraElevation(); + if (isNaN(camHeght)) + { return; } + // Lineal increment. + //delta *= camHeght * 0.003; + + // Squared increment. + delta *= (camHeght*camHeght) * 0.00001 + camHeght * 0.001; + delta += 1; + + var maxDelta = 200000; + if (delta < -maxDelta) + { delta = -maxDelta; } + + if (delta > maxDelta) + { delta = maxDelta; } + + camPos.add(camDir.x * delta, camDir.y * delta, camDir.z * delta); + + this.updateModelViewMatrixByCamera(camera); +}; /** - * 어떤 일을 하고 있습니까? - * @class PostFxShader - * @param gl 변수 + * 어떻게 화면을 변화시키는지를 처리할 수 있다. 마우스 왼쪽 또는 마우스 휠로 회전 가능. */ -var PostFxShader = function(gl) +MagoWorld.prototype.mousemove = function(event) { - if (!(this instanceof PostFxShader)) + var mouseAction = this.magoManager.sceneState.mouseAction; + if (this.magoManager.sceneState.mouseButton === 0) { - throw new Error(Messages.CONSTRUCT_ERROR); - } - this.gl = gl; - this.name; - this.attribLocationCacheObj = {}; - this.uniformsArrayGeneral = []; // this array has the same uniforms that "uniformsCacheObj".*** - this.uniformsMapGeneral = {}; // this object has the same uniforms that "uniformsArray".*** - - this.uniformsArrayLocal = []; // this array has the same uniforms that "uniformsCacheObj".*** - this.uniformsMapLocal = {}; // this object has the same uniforms that "uniformsArray".*** + // left button pressed. + var gl = this.magoManager.sceneState.gl; + var sceneState = this.magoManager.sceneState; + var strCamera = mouseAction.strCamera; // camera of onMouseDown. + var camera = this.magoManager.sceneState.camera; + + // now, calculate the angle and the rotationAxis. + var strWorldPoint = mouseAction.strWorldPoint; + var strEarthRadius = strWorldPoint.getModul(); + var nowX = event.clientX; + var nowY = event.clientY; + if (nowX === mouseAction.strX && nowY === mouseAction.strY) + { return; } + + var nowPoint; + var camRay, camRayCamCoord; + + camRayCamCoord = ManagerUtils.getRayCamSpace(nowX, nowY, camRayCamCoord, this.magoManager); + + // Now calculate rayWorldCoord. + if (this.pointSC === undefined) + { this.pointSC = new Point3D(); } + + this.pointSC.set(camRayCamCoord[0], camRayCamCoord[1], camRayCamCoord[2]); + + // Now, must transform this posCamCoord to world coord, but with the "mouseAction.strModelViewMatrixInv". + var mv_inv = mouseAction.strModelViewMatrixInv; + this.pointSC2 = mv_inv.rotatePoint3D(this.pointSC, this.pointSC2); // rayWorldSpace. + this.pointSC2.unitary(); // rayWorldSpace. + camRay = new Line(); + camRay.setPointAndDir(strCamera.position.x, strCamera.position.y, strCamera.position.z, this.pointSC2.x, this.pointSC2.y, this.pointSC2.z);// original. + // end calculate camRayWorldCoord.--------------- + + var nowWorldPoint; + nowWorldPoint = this.magoManager.globe.intersectionLineWgs84(camRay, nowWorldPoint, strEarthRadius); + + if (nowWorldPoint === undefined) + { return; } + + var strPoint = new Point3D(strWorldPoint.x, strWorldPoint.y, strWorldPoint.z); // copy point3d. + var nowPoint = new Point3D(nowWorldPoint[0], nowWorldPoint[1], nowWorldPoint[2]); + + var rotAxis; + rotAxis = strPoint.crossProduct(nowPoint, rotAxis); + rotAxis.unitary(); + if (rotAxis.isNAN()) + { return; } + + var angRad = strPoint.angleRadToVector(nowPoint); + if (angRad === 0 || isNaN(angRad)) + { return; } + + // recalculate position and direction of the camera. + camera.copyPosDirUpFrom(strCamera); - // shader program.*** - this.program; - this.shader_vertex; - this.shader_fragment; + var rotMat = new Matrix4(); + rotMat.rotationAxisAngRad(-angRad, rotAxis.x, rotAxis.y, rotAxis.z); + camera.transformByMatrix4(rotMat); + + this.updateModelViewMatrixByCamera(camera); + } + else if (this.magoManager.sceneState.mouseButton === 1) + { + // middle button pressed. + var strCamera = mouseAction.strCamera; + var camera = this.magoManager.sceneState.camera; + camera.copyPosDirUpFrom(strCamera); + var camPos = camera.position; + var camDir = camera.direction; + var camUp = camera.up; + + // 1rst, determine the point of rotation. + var rotPoint = mouseAction.strWorldPoint; + + // now determine the rotation axis. + // the rotation axis are the camRight & normalToSurface. + if (this.magoManager.globe === undefined) + { this.magoManager.globe = new Globe(); } + + var pivotPointNormal; + pivotPointNormal = this.magoManager.globe.normalAtCartesianPointWgs84(rotPoint.x, rotPoint.y, rotPoint.z, pivotPointNormal); + + var xAxis = camera.getCameraRight(); + + // now determine camZRot & camXRot angles. + var nowX = event.clientX; + var nowY = event.clientY; + var increX = nowX - mouseAction.strX; + var increY = nowY - mouseAction.strY; + + var zRotAngRad = increX * 0.003; + var xRotAngRad = increY * 0.003; + + if (zRotAngRad === 0 && xRotAngRad === 0) + { return; } + + if (this.rotMatX === undefined) + { this.rotMatX = new Matrix4(); } + + if (this.rotMatZ === undefined) + { this.rotMatZ = new Matrix4(); } + + if (this.rotMat === undefined) + { this.rotMat = new Matrix4(); } + this.rotMatX.rotationAxisAngRad(-xRotAngRad, xAxis.x, xAxis.y, xAxis.z); + this.rotMatZ.rotationAxisAngRad(-zRotAngRad, pivotPointNormal[0], pivotPointNormal[1], pivotPointNormal[2]); + this.rotMat = this.rotMatX.getMultipliedByMatrix(this.rotMatZ, this.rotMat); + + var translationVec_1 = new Point3D(-rotPoint.x, -rotPoint.y, -rotPoint.z); + var translationVec_2 = new Point3D(rotPoint.x, rotPoint.y, rotPoint.z); + + camera.translate(translationVec_1); + camera.transformByMatrix4(this.rotMat); + camera.translate(translationVec_2); + + this.updateModelViewMatrixByCamera(camera); + } }; /** - * 어떤 일을 하고 있습니까? - * @param shaderName 변수 - * @returns shader + * + * + * @param {*} event */ -PostFxShader.prototype.bindUniformGenerals = function() +MagoWorld.prototype.keydown = function(event) { - if (this.uniformsArrayGeneral === undefined) - { return; } - - var uniformsDataPairsCount = this.uniformsArrayGeneral.length; - for (var i=0; i 0) { - uniformDataPair = shader.newUniformDataPair("1f", "diffuseReflectionCoef"); - uniformDataPair.uniformLocation = uniformLocation; - uniformDataPair.floatValue = sceneState.diffuseReflectionCoef; + resultTrianglesListsArray = this.getTrianglesListsArrayBy2ByteSize(rejectedTrianglesArray, resultTrianglesListsArray); } - // 21. specularReflectionCoef.*** - uniformLocation = gl.getUniformLocation(shader.program, "specularReflectionCoef"); - if (uniformLocation !== null && uniformLocation !== undefined) + return resultTrianglesListsArray; +}; + +Mesh.prototype.render = function(magoManager, shader, renderType, glPrimitive) +{ + var vboMemManager = magoManager.vboMemoryManager; + + if (this.vboKeysContainer === undefined) { - uniformDataPair = shader.newUniformDataPair("1f", "specularReflectionCoef"); - uniformDataPair.uniformLocation = uniformLocation; - uniformDataPair.floatValue = sceneState.specularReflectionCoef; + this.vboKeysContainer = this.getVbo(this.vboKeysContainer, vboMemManager); + return; } - // 22. shininessValue.*** - uniformLocation = gl.getUniformLocation(shader.program, "shininessValue"); - if (uniformLocation !== null && uniformLocation !== undefined) + var gl = magoManager.sceneState.gl; + var primitive; + + var vboKeysCount = this.vboKeysContainer.vboCacheKeysArray.length; + for (var i=0; i shortSize(65535), then must split the mesh. + var trianglesListsArray = this.getTrianglesListsArrayBy2ByteSize(trianglesArray, undefined); + var trianglesList; + var verticesArray; + var trianglesListsCount = trianglesListsArray.length; + for (var i=0; i shortSize(65535), then must split the mesh. + var trianglesListsArray = this.getTrianglesListsArrayBy2ByteSize(trianglesArray, undefined); + var trianglesList; + var verticesArray; + var trianglesListsCount = trianglesListsArray.length; + for (var i=0; i= 0 && idx < this.shaders_array.length) - { - shader = this.shaders_array[idx]; - } - - return shader; + // aux test. + this.associated.x = associated.x; + this.associated.y = associated.y; }; /** - * 어떤 일을 하고 있습니까? + * get the value of the property 'associated' + * @returns {Point2D} this.associated */ -ShadersManager.prototype.getShader = function(gl, source, type, typeString) +Point2D.prototype.getAssociated = function() { - // Source from internet.*** - var shader = gl.createShader(type); - gl.shaderSource(shader, source); - gl.compileShader(shader); - if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) - { - alert("ERROR IN "+typeString+ " SHADER : " + gl.getShaderInfoLog(shader)); - return false; - } - return shader; + // aux test. + return this.associated; }; /** - * 어떤 일을 하고 있습니까? + * copy the value of other point + * @param {Point2D} point2d */ -ShadersManager.prototype.createDefaultShader = function(gl) +Point2D.prototype.copyFrom = function(point2d) { - this.createStandardShader(gl); // 0.*** - this.createTextureSimpleObjectShader(gl); // 1.*** - this.createColorSelectionShader(gl); // 2.*** - this.createTextureSimpleObjectA1Shader(gl); // 3.*** - this.createCloudShader(gl); // 4.*** - this.createBlendingCubeShader(gl); // 5.*** - this.createPCloudShader(gl); // 6.*** - this.createSimpleObjectTexNormalShader(gl); // 7.*** + this.x = point2d.x; + this.y = point2d.y; }; /** - * 어떤 일을 하고 있습니까? + * change the sign of the values of point inversely */ -ShadersManager.prototype.createColorSelectionShader = function(gl) +Point2D.prototype.inverse = function() { - var shader = new Shader(); - this.shaders_array.push(shader); - - shader.shader_vertex_source = ShaderSource.ColorVS; - //http://www.lighthouse3d.com/tutorials/opengl-selection-tutorial/ + this.x = -this.x; + this.y = -this.y; +}; - shader.shader_fragment_source = ShaderSource.ColorFS; +/** + * set the value of x,y coordi of the point + * @param {Number} x + * @param {Number} y + */ +Point2D.prototype.set = function(x, y) +{ + this.x = x; + this.y = y; +}; - // https://www.khronos.org/files/webgl/webgl-reference-card-1_0.pdf - shader.SHADER_PROGRAM = gl.createProgram(); - shader.shader_vertex = this.getShader(gl, shader.shader_vertex_source, gl.VERTEX_SHADER, "VERTEX"); - shader.shader_fragment = this.getShader(gl, shader.shader_fragment_source, gl.FRAGMENT_SHADER, "FRAGMENT"); - gl.attachShader(shader.SHADER_PROGRAM, shader.shader_vertex); - gl.attachShader(shader.SHADER_PROGRAM, shader.shader_fragment); - gl.linkProgram(shader.SHADER_PROGRAM); +/** + * return the result of calculating (this.x*this.x + this.y*this.y) + * @returns this.x*this.x + this.y*this.y; + */ +Point2D.prototype.getSquaredModul = function() +{ + return this.x*this.x + this.y*this.y; +}; - shader._ModelViewProjectionMatrixRelToEye = gl.getUniformLocation(shader.SHADER_PROGRAM, "ModelViewProjectionMatrixRelToEye"); - shader._encodedCamPosHIGH = gl.getUniformLocation(shader.SHADER_PROGRAM, "encodedCameraPositionMCHigh"); - shader._encodedCamPosLOW = gl.getUniformLocation(shader.SHADER_PROGRAM, "encodedCameraPositionMCLow"); - shader._BuildingPosHIGH = gl.getUniformLocation(shader.SHADER_PROGRAM, "buildingPosHIGH"); - shader._BuildingPosLOW = gl.getUniformLocation(shader.SHADER_PROGRAM, "buildingPosLOW"); - shader._RefTransfMatrix = gl.getUniformLocation(shader.SHADER_PROGRAM, "RefTransfMatrix"); +/** + * return the result of calculating Math.sqrt(this.x*this.x + this.y*this.y); + * @returns Math.sqrt(this.x*this.x + this.y*this.y); + */ +Point2D.prototype.getModul = function() +{ + return Math.sqrt(this.getSquaredModul()); +}; - shader._position = gl.getAttribLocation(shader.SHADER_PROGRAM, "position"); +/** + * + * make unitary of the point + */ +Point2D.prototype.unitary = function() +{ + var modul = this.getModul(); + this.x /= modul; + this.y /= modul; }; /** - * 어떤 일을 하고 있습니까? + * prepare to calculate the Euclidean distance between this point and the other point. + * @param {Number} point + * @returns dx*dx + dy*dy */ -ShadersManager.prototype.createTextureSimpleObjectShader = function(gl) +Point2D.prototype.squareDistToPoint = function(point) { - var shader = new Shader(); - this.shaders_array.push(shader); + var dx = this.x - point.x; + var dy = this.y - point.y; - shader.shader_vertex_source = ShaderSource.TextureVS; - shader.shader_fragment_source = ShaderSource.TextureFS; + return dx*dx + dy*dy; +}; - //http://learningwebgl.com/blog/?p=507 - //https://gist.github.com/elnaqah/5070979 - shader.SHADER_PROGRAM = gl.createProgram(); - shader.shader_vertex = this.getShader(gl, shader.shader_vertex_source, gl.VERTEX_SHADER, "VERTEX"); - shader.shader_fragment = this.getShader(gl, shader.shader_fragment_source, gl.FRAGMENT_SHADER, "FRAGMENT"); - gl.attachShader(shader.SHADER_PROGRAM, shader.shader_vertex); - gl.attachShader(shader.SHADER_PROGRAM, shader.shader_fragment); - gl.linkProgram(shader.SHADER_PROGRAM); +/** + * calculate the Euclidean distance between this point and the other point. + * @param {Point2D} point the target + * @returns the calculated Euclidan distance + */ +Point2D.prototype.distToPoint = function(point) +{ + return Math.sqrt(this.squareDistToPoint(point)); +}; - shader._encodedCamPosHIGH = gl.getUniformLocation(shader.SHADER_PROGRAM, "encodedCameraPositionMCHigh"); - shader._encodedCamPosLOW = gl.getUniformLocation(shader.SHADER_PROGRAM, "encodedCameraPositionMCLow"); - shader._BuildingPosHIGH = gl.getUniformLocation(shader.SHADER_PROGRAM, "buildingPosHIGH"); - shader._BuildingPosLOW = gl.getUniformLocation(shader.SHADER_PROGRAM, "buildingPosLOW"); - shader._Mmatrix = gl.getUniformLocation(shader.SHADER_PROGRAM, "Mmatrix"); - shader._ModelViewProjectionMatrixRelToEye = gl.getUniformLocation(shader.SHADER_PROGRAM, "ModelViewProjectionMatrixRelToEye"); - shader.SHADER_PROGRAM.samplerUniform = gl.getUniformLocation(shader.SHADER_PROGRAM, "uSampler"); +/** + * Check whether this point and the other point are overlapped(coincident) or not + * @param {Point2D} point the point which will be checked whether the two points are coincident or not + * @param {Number} errorDist allowed error range value of calculating distance. It can be from 0.1mm to 10E-8 + * @returns {Boolean} the flag which let us know whether they are coincident or not + */ +Point2D.prototype.isCoincidentToPoint = function(point, errorDist) +{ + var squareDist = this.distToPoint(point); + var coincident = false; + if (squareDist < errorDist*errorDist) + { + coincident = true; + } - shader._position = gl.getAttribLocation(shader.SHADER_PROGRAM, "position"); - shader._texcoord = gl.getAttribLocation(shader.SHADER_PROGRAM, "aTextureCoord"); + return coincident; }; /** - * 어떤 일을 하고 있습니까? + * @param {Point2D} targetPoint this returns a vector that points to "targetPoint" from "this" + * @param {Point3D} resultVector the "resultVector" has the direction from "this" to "targetPoint", but is NOT normalized. + * @returns {Point3D} resultVector */ -ShadersManager.prototype.createTextureSimpleObjectA1Shader = function(gl) +Point2D.prototype.getVectorToPoint = function(targetPoint, resultVector) { - var shader = new Shader(); - this.shaders_array.push(shader); - - shader.shader_vertex_source = ShaderSource.TextureA1VS; - shader.shader_fragment_source = ShaderSource.TextureA1FS; + if (targetPoint === undefined) + { return undefined; } + + if (resultVector === undefined) + { resultVector = new Point2D(); } + + resultVector.set(targetPoint.x - this.x, targetPoint.y - this.y); + + return resultVector; +}; - //http://learningwebgl.com/blog/?p=507 - //https://gist.github.com/elnaqah/5070979 - shader.SHADER_PROGRAM = gl.createProgram(); - shader.shader_vertex = this.getShader(gl, shader.shader_vertex_source, gl.VERTEX_SHADER, "VERTEX"); - shader.shader_fragment = this.getShader(gl, shader.shader_fragment_source, gl.FRAGMENT_SHADER, "FRAGMENT"); - gl.attachShader(shader.SHADER_PROGRAM, shader.shader_vertex); - gl.attachShader(shader.SHADER_PROGRAM, shader.shader_fragment); - gl.linkProgram(shader.SHADER_PROGRAM); +/** + * Calculate vector product + * @param {Point2D} point the point which will be used at this calculate. + * @returns {Number} calculated result + */ +Point2D.prototype.crossProduct = function(point) +{ + return this.x * point.y - point.x * this.y; +}; - shader._encodedCamPosHIGH = gl.getUniformLocation(shader.SHADER_PROGRAM, "encodedCameraPositionMCHigh"); - shader._encodedCamPosLOW = gl.getUniformLocation(shader.SHADER_PROGRAM, "encodedCameraPositionMCLow"); - shader._BuildingPosHIGH = gl.getUniformLocation(shader.SHADER_PROGRAM, "buildingPosHIGH"); - shader._BuildingPosLOW = gl.getUniformLocation(shader.SHADER_PROGRAM, "buildingPosLOW"); - shader._ModelViewProjectionMatrixRelToEye = gl.getUniformLocation(shader.SHADER_PROGRAM, "ModelViewProjectionMatrixRelToEye"); - shader.SHADER_PROGRAM.samplerUniform = gl.getUniformLocation(shader.SHADER_PROGRAM, "uSampler"); +/** + * Calculate scalar production of vector + * @param {Point2D} point the point which will be used at this calculate. + * @returns {Number} calculated result + */ +Point2D.prototype.scalarProduct = function(point) +{ + var scalarProd = this.x*point.x + this.y*point.y; + return scalarProd; +}; - shader._position = gl.getAttribLocation(shader.SHADER_PROGRAM, "position"); - shader._texcoord = gl.getAttribLocation(shader.SHADER_PROGRAM, "aTextureCoord"); +/** + * Calculate the radian value of the angle of the two vectors + * @param vector the target vector + * @returns the angle of two vector + */ +Point2D.prototype.angleRadToVector = function(vector) +{ + if (vector === undefined) + { return undefined; } + + // + //var scalarProd = this.scalarProduct(vector); + var myModul = this.getModul(); + var vecModul = vector.getModul(); + + // calcule by cos. + //var cosAlfa = scalarProd / (myModul * vecModul); + //var angRad = Math.acos(cosAlfa); + //var angDeg = alfa * 180.0/Math.PI; + //------------------------------------------------------ + var error = 10E-10; + if (myModul < error || vecModul < error) + { return undefined; } + + return Math.acos(this.scalarProduct(vector) / (myModul * vecModul)); }; /** - * 어떤 일을 하고 있습니까? + * Calculate the degree value of the angle of the two vectors + * @param point 변수 + * @param resultPoint 변수 + * @returns resultPoint */ -ShadersManager.prototype.createStandardShader = function(gl) +Point2D.prototype.angleDegToVector = function(vector) { - // This shader renders the normal f4d geometry.*** - var standard_shader = new Shader(); - this.shaders_array.push(standard_shader); + if (vector === undefined) + { return undefined; } + + var angRad = this.angleRadToVector(vector); + + if (angRad === undefined) + { return undefined; } + + return angRad * 180.0/Math.PI; +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + - standard_shader.shader_vertex_source = ShaderSource.StandardVS; - standard_shader.shader_fragment_source = ShaderSource.StandardFS; - // Default ShaderProgram.******************************************************************** - standard_shader.SHADER_PROGRAM = gl.createProgram(); - standard_shader.shader_vertex = this.getShader(gl, standard_shader.shader_vertex_source, gl.VERTEX_SHADER, "VERTEX"); - standard_shader.shader_fragment = this.getShader(gl, standard_shader.shader_fragment_source, gl.FRAGMENT_SHADER, "FRAGMENT"); - gl.attachShader(standard_shader.SHADER_PROGRAM, standard_shader.shader_vertex); - gl.attachShader(standard_shader.SHADER_PROGRAM, standard_shader.shader_fragment); - gl.linkProgram(standard_shader.SHADER_PROGRAM); - standard_shader._ModelViewProjectionMatrixRelToEye = gl.getUniformLocation(standard_shader.SHADER_PROGRAM, "ModelViewProjectionMatrixRelToEye"); - standard_shader._RefTransfMatrix = gl.getUniformLocation(standard_shader.SHADER_PROGRAM, "RefTransfMatrix"); - standard_shader._encodedCamPosHIGH = gl.getUniformLocation(standard_shader.SHADER_PROGRAM, "encodedCameraPositionMCHigh"); - standard_shader._encodedCamPosLOW = gl.getUniformLocation(standard_shader.SHADER_PROGRAM, "encodedCameraPositionMCLow"); - standard_shader._BuildingPosHIGH = gl.getUniformLocation(standard_shader.SHADER_PROGRAM, "buildingPosHIGH"); - standard_shader._BuildingPosLOW = gl.getUniformLocation(standard_shader.SHADER_PROGRAM, "buildingPosLOW"); - standard_shader._color = gl.getAttribLocation(standard_shader.SHADER_PROGRAM, "color"); - standard_shader._position = gl.getAttribLocation(standard_shader.SHADER_PROGRAM, "position"); + + + + + + + + + + + + + + + + + +'use strict'; +/** +* Contain the list of the features of Point2D +* @class Point2DList +*/ +var Point2DList = function() +{ + if (!(this instanceof Point2DList)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + + this.pointsArray; }; /** - * 어떤 일을 하고 있습니까? + * Clear this.pointsArray of this feature */ -ShadersManager.prototype.createCloudShader = function(gl) +Point2DList.prototype.deleteObjects = function() { - // This shader renders the f4d clouds.*** - var standard_shader = new Shader(); - this.shaders_array.push(standard_shader); + if (this.pointsArray === undefined) + { return; } + + var pointsCount = this.pointsArray.length; + for (var i=0; i object.squaredDist) + { + newStartIdx = startIdx; + newEndIdx = middleIdx; + } + else + { + newStartIdx = middleIdx; + newEndIdx = endIdx; + } + return this.getIndexToInsertBySquaredDist(objectsArray, object, newStartIdx, newEndIdx); + } +}; - //http://learningwebgl.com/blog/?p=507 - //https://gist.github.com/elnaqah/5070979 - //https://dannywoodz.wordpress.com/2014/12/14/webgl-from-scratch-directional-lighting-part-1/ - //http://learningwebgl.com/blog/?p=684 // good.*** - shader.SHADER_PROGRAM = gl.createProgram(); - shader.shader_vertex = this.getShader(gl, shader.shader_vertex_source, gl.VERTEX_SHADER, "VERTEX"); - shader.shader_fragment = this.getShader(gl, shader.shader_fragment_source, gl.FRAGMENT_SHADER, "FRAGMENT"); - gl.attachShader(shader.SHADER_PROGRAM, shader.shader_vertex); - gl.attachShader(shader.SHADER_PROGRAM, shader.shader_fragment); - gl.linkProgram(shader.SHADER_PROGRAM); - shader._encodedCamPosHIGH = gl.getUniformLocation(shader.SHADER_PROGRAM, "encodedCameraPositionMCHigh"); - shader._encodedCamPosLOW = gl.getUniformLocation(shader.SHADER_PROGRAM, "encodedCameraPositionMCLow"); - shader._BuildingPosHIGH = gl.getUniformLocation(shader.SHADER_PROGRAM, "buildingPosHIGH"); - shader._BuildingPosLOW = gl.getUniformLocation(shader.SHADER_PROGRAM, "buildingPosLOW"); - shader._ModelViewProjectionMatrixRelToEye = gl.getUniformLocation(shader.SHADER_PROGRAM, "ModelViewProjectionMatrixRelToEye"); - shader._NormalMatrix = gl.getUniformLocation(shader.SHADER_PROGRAM, "uNMatrix"); - //shader.SHADER_PROGRAM.samplerUniform = gl.getUniformLocation(shader.SHADER_PROGRAM, "uSampler"); - shader.samplerUniform = gl.getUniformLocation(shader.SHADER_PROGRAM, "uSampler"); - shader._lightDirection = gl.getUniformLocation(shader.SHADER_PROGRAM, "uLightingDirection"); - shader._position = gl.getAttribLocation(shader.SHADER_PROGRAM, "position"); - shader._texcoord = gl.getAttribLocation(shader.SHADER_PROGRAM, "aTextureCoord"); - shader._normal = gl.getAttribLocation(shader.SHADER_PROGRAM, "aVertexNormal"); -}; -//# sourceURL=Shader.js -'use strict'; -var ShaderSource = {}; -ShaderSource.BlendingCubeFS = " precision lowp float;\n\ - varying vec4 vColor;\n\ -\n\ - void main()\n\ - {\n\ - gl_FragColor = vColor;\n\ - }"; -ShaderSource.BlendingCubeVS = "attribute vec3 position;\n\ -uniform mat4 ModelViewProjectionMatrixRelToEye;\n\ -uniform vec3 encodedCameraPositionMCHigh;\n\ -uniform vec3 encodedCameraPositionMCLow;\n\ -attribute vec4 color;\n\ -varying vec4 vColor;\n\ -\n\ -void main()\n\ -{\n\ - vec3 highDifference = -encodedCameraPositionMCHigh.xyz;\n\ - vec3 lowDifference = position.xyz - encodedCameraPositionMCLow.xyz;\n\ - vec4 pos = vec4(position.xyz, 1.0);\n\ -\n\ - vColor=color;\n\ -\n\ - gl_Position = ModelViewProjectionMatrixRelToEye * pos;\n\ -}"; -ShaderSource.BlurFS = "#ifdef GL_ES\n\ - precision highp float;\n\ - #endif\n\ -uniform sampler2D colorTex;\n\ -uniform vec2 texelSize;\n\ -varying vec2 vTexCoord; \n\ -\n\ -void main()\n\ -{\n\ - vec3 result = vec3(0.0);\n\ - for (int i = 0; i < 4; ++i) {\n\ - for (int j = 0; j < 4; ++j) {\n\ - vec2 offset = vec2(texelSize.x * float(j), texelSize.y * float(i));\n\ - result += texture2D(colorTex, vTexCoord + offset).rgb;\n\ - }\n\ - }\n\ - \n\ - gl_FragColor.rgb = vec3(result * 0.0625); \n\ - gl_FragColor.a = 1.0;\n\ -}\n\ -"; -ShaderSource.BlurVS = "attribute vec4 position;\n\ -attribute vec2 texCoord;\n\ -\n\ -uniform mat4 projectionMatrix;\n\ -uniform mat4 modelViewMatrix; \n\ -\n\ -varying vec2 vTexCoord;\n\ -\n\ -void main()\n\ -{ \n\ - vTexCoord = texCoord;\n\ - \n\ - gl_Position = projectionMatrix * modelViewMatrix * position;\n\ -}\n\ -"; -ShaderSource.BoxDepthFS = "#ifdef GL_ES\n\ - precision highp float;\n\ -#endif\n\ -uniform float near;\n\ -uniform float far;\n\ -\n\ -varying float depth; \n\ -\n\ -vec4 packDepth(const in float depth)\n\ -{\n\ - const vec4 bit_shift = vec4(16777216.0, 65536.0, 256.0, 1.0);\n\ - const vec4 bit_mask = vec4(0.0, 0.00390625, 0.00390625, 0.00390625); \n\ - vec4 res = fract(depth * bit_shift);\n\ - res -= res.xxyz * bit_mask;\n\ - return res; \n\ -}\n\ -\n\ -void main()\n\ -{ \n\ - gl_FragData[0] = packDepth(-depth);\n\ -}\n\ -"; -ShaderSource.BoxDepthVS = "attribute vec3 position;\n\ -\n\ -uniform mat4 modelViewMatrixRelToEye; \n\ -uniform mat4 ModelViewProjectionMatrixRelToEye;\n\ -uniform mat4 buildingRotMatrix; \n\ -uniform vec3 buildingPosHIGH;\n\ -uniform vec3 buildingPosLOW;\n\ -uniform vec3 encodedCameraPositionMCHigh;\n\ -uniform vec3 encodedCameraPositionMCLow;\n\ -uniform float near;\n\ -uniform float far;\n\ -uniform vec3 aditionalPosition;\n\ -\n\ -varying float depth; \n\ -void main()\n\ -{ \n\ - vec4 rotatedPos = buildingRotMatrix * vec4(position.xyz + aditionalPosition.xyz, 1.0);\n\ - vec3 objPosHigh = buildingPosHIGH;\n\ - vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n\ - vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\ - vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\ - vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ - \n\ - //linear depth in camera space (0..far)\n\ - depth = (modelViewMatrixRelToEye * pos4).z/far;\n\ -\n\ - gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\ -}\n\ -"; -ShaderSource.BoxSsaoFS = "#ifdef GL_ES\n\ - precision highp float;\n\ -#endif\n\ -uniform sampler2D depthTex;\n\ -uniform sampler2D noiseTex; \n\ -uniform sampler2D diffuseTex;\n\ -uniform bool hasTexture;\n\ -varying vec3 vNormal;\n\ -uniform mat4 projectionMatrix;\n\ -uniform mat4 m;\n\ -uniform vec2 noiseScale;\n\ -uniform float near;\n\ -uniform float far; \n\ -uniform float fov;\n\ -uniform float aspectRatio; \n\ -uniform float screenWidth; \n\ -uniform float screenHeight; \n\ -uniform vec3 kernel[16]; \n\ -uniform vec4 vColor4Aux;\n\ -uniform bool bUseNormal;\n\ -uniform bool bApplySsao;\n\ -\n\ -varying vec2 vTexCoord; \n\ -varying vec3 vLightWeighting;\n\ -varying vec4 vcolor4;\n\ -\n\ -const int kernelSize = 16; \n\ -const float radius = 0.5; \n\ -\n\ -float unpackDepth(const in vec4 rgba_depth)\n\ -{\n\ - const vec4 bit_shift = vec4(0.000000059605, 0.000015258789, 0.00390625, 1.0);\n\ - float depth = dot(rgba_depth, bit_shift);\n\ - return depth;\n\ -} \n\ -\n\ -vec3 getViewRay(vec2 tc)\n\ -{\n\ - float hfar = 2.0 * tan(fov/2.0) * far;\n\ - float wfar = hfar * aspectRatio; \n\ - vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n\ - return ray; \n\ -} \n\ - \n\ -//linear view space depth\n\ -float getDepth(vec2 coord)\n\ -{ \n\ - return unpackDepth(texture2D(depthTex, coord.xy));\n\ -} \n\ -\n\ -void main()\n\ -{ \n\ - vec4 textureColor;\n\ - textureColor = vcolor4; \n\ - if(bUseNormal)\n\ - {\n\ - if(bApplySsao)\n\ - {\n\ - vec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight); \n\ - float linearDepth = getDepth(screenPos); \n\ - vec3 origin = getViewRay(screenPos) * linearDepth; \n\ - vec3 normal2 = vNormal; \n\ - \n\ - vec3 rvec = texture2D(noiseTex, screenPos.xy * noiseScale).xyz * 2.0 - 1.0;\n\ - vec3 tangent = normalize(rvec - normal2 * dot(rvec, normal2));\n\ - vec3 bitangent = cross(normal2, tangent);\n\ - mat3 tbn = mat3(tangent, bitangent, normal2); \n\ - \n\ - float occlusion = 0.0;\n\ - for(int i = 0; i < kernelSize; ++i)\n\ - { \n\ - vec3 sample = origin + (tbn * kernel[i]) * radius;\n\ - vec4 offset = projectionMatrix * vec4(sample, 1.0); \n\ - offset.xy /= offset.w;\n\ - offset.xy = offset.xy * 0.5 + 0.5; \n\ - float sampleDepth = -sample.z/far;\n\ - float depthBufferValue = getDepth(offset.xy); \n\ - float range_check = abs(linearDepth - depthBufferValue)+radius*0.998;\n\ - if (range_check < radius*1.001 && depthBufferValue <= sampleDepth)\n\ - {\n\ - occlusion += 1.0;\n\ - }\n\ - \n\ - } \n\ - \n\ - occlusion = 1.0 - occlusion / float(kernelSize);\n\ - \n\ - vec3 lightPos = vec3(10.0, 10.0, 10.0);\n\ - vec3 L = normalize(lightPos);\n\ - float DiffuseFactor = dot(normal2, L);\n\ - float NdotL = abs(DiffuseFactor);\n\ - vec3 diffuse = vec3(NdotL);\n\ - vec3 ambient = vec3(1.0);\n\ - gl_FragColor.rgb = vec3((textureColor.xyz)*vLightWeighting * occlusion); \n\ - gl_FragColor.a = 1.0; \n\ - }\n\ - else{\n\ - gl_FragColor.rgb = vec3((textureColor.xyz)*vLightWeighting); \n\ - gl_FragColor.a = 1.0; \n\ - }\n\ - }\n\ - else\n\ - {\n\ - gl_FragColor.rgb = vec3(textureColor.xyz); \n\ - gl_FragColor.a = 1.0; \n\ - } \n\ -}\n\ -"; -ShaderSource.BoxSsaoVS = "attribute vec3 position;\n\ -attribute vec3 normal;\n\ -attribute vec4 color4;\n\ -\n\ -uniform mat4 projectionMatrix; \n\ -uniform mat4 modelViewMatrix;\n\ -uniform mat4 modelViewMatrixRelToEye; \n\ -uniform mat4 ModelViewProjectionMatrixRelToEye;\n\ -uniform mat4 normalMatrix4;\n\ -uniform mat4 buildingRotMatrix; \n\ -uniform vec3 buildingPosHIGH;\n\ -uniform vec3 buildingPosLOW;\n\ -uniform vec3 encodedCameraPositionMCHigh;\n\ -uniform vec3 encodedCameraPositionMCLow;\n\ -uniform vec3 aditionalPosition;\n\ -uniform vec4 oneColor4;\n\ -uniform bool bUse1Color;\n\ -uniform bool bUseNormal;\n\ -uniform vec3 scale;\n\ -uniform bool bScale;\n\ -\n\ -varying vec3 vNormal;\n\ -varying vec2 vTexCoord; \n\ -varying vec3 uAmbientColor;\n\ -varying vec3 vLightWeighting;\n\ -varying vec4 vcolor4;\n\ -\n\ -void main()\n\ -{ \n\ - vec4 position2 = vec4(position.xyz, 1.0);\n\ - if(bScale)\n\ - {\n\ - position2.x *= scale.x;\n\ - position2.y *= scale.y;\n\ - position2.z *= scale.z;\n\ - }\n\ - vec4 rotatedPos = buildingRotMatrix * vec4(position2.xyz + aditionalPosition.xyz, 1.0);\n\ - vec3 objPosHigh = buildingPosHIGH;\n\ - vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n\ - vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\ - vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\ - vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ - if(bUseNormal)\n\ - {\n\ - vec4 rotatedNormal = buildingRotMatrix * vec4(normal.xyz, 1.0);\n\ - vLightWeighting = vec3(1.0, 1.0, 1.0);\n\ - uAmbientColor = vec3(0.8, 0.8, 0.8);\n\ - vec3 uLightingDirection = vec3(0.5, 0.5, 0.5);\n\ - vec3 directionalLightColor = vec3(0.6, 0.6, 0.6);\n\ - vNormal = (normalMatrix4 * vec4(rotatedNormal.x, rotatedNormal.y, rotatedNormal.z, 1.0)).xyz;\n\ - float directionalLightWeighting = max(dot(vNormal, uLightingDirection), 0.0);\n\ - vLightWeighting = uAmbientColor + directionalLightColor * directionalLightWeighting;\n\ - }\n\ - if(bUse1Color)\n\ - {\n\ - vcolor4 = oneColor4;\n\ - }\n\ - else\n\ - {\n\ - vcolor4 = color4;\n\ - }\n\ -\n\ - gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\ -}\n\ -"; -ShaderSource.CloudFS = "precision lowp float;\n\ -varying vec3 vColor;\n\ -\n\ -void main()\n\ -{\n\ - gl_FragColor = vec4(vColor, 1.);\n\ -}"; -ShaderSource.CloudVS = "attribute vec3 position;\n\ -uniform mat4 ModelViewProjectionMatrixRelToEye;\n\ -uniform vec3 cloudPosHIGH;\n\ -uniform vec3 cloudPosLOW;\n\ -uniform vec3 encodedCameraPositionMCHigh;\n\ -uniform vec3 encodedCameraPositionMCLow;\n\ -attribute vec3 color;\n\ -varying vec3 vColor;\n\ -\n\ -void main()\n\ -{\n\ - vec3 objPosHigh = cloudPosHIGH;\n\ - vec3 objPosLow = cloudPosLOW.xyz + position.xyz;\n\ - vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\ - vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\ - vec4 pos = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ -\n\ - vColor=color;\n\ -\n\ - gl_Position = ModelViewProjectionMatrixRelToEye * pos;\n\ -}"; -ShaderSource.ColorFS = "precision mediump float;\n\ -uniform int byteColor_r;\n\ -uniform int byteColor_g;\n\ -uniform int byteColor_b;\n\ -\n\ -void main()\n\ -{\n\ - float byteMaxValue = 255.0;\n\ -\n\ - gl_FragColor = vec4(float(byteColor_r)/byteMaxValue, float(byteColor_g)/byteMaxValue, float(byteColor_b)/byteMaxValue, 1);\n\ -}\n\ -"; -ShaderSource.ColorSelectionSsaoFS = "precision highp float;\n\ -uniform vec4 vColor4Aux;\n\ -\n\ -void main()\n\ -{ \n\ - gl_FragColor = vColor4Aux;\n\ -}\n\ -"; -ShaderSource.ColorSelectionSsaoVS = "attribute vec3 position;\n\ -\n\ -uniform mat4 buildingRotMatrix;\n\ -uniform mat4 ModelViewProjectionMatrixRelToEye;\n\ -uniform mat4 RefTransfMatrix;\n\ -uniform vec3 buildingPosHIGH;\n\ -uniform vec3 buildingPosLOW;\n\ -uniform vec3 encodedCameraPositionMCHigh;\n\ -uniform vec3 encodedCameraPositionMCLow;\n\ -uniform vec3 aditionalPosition;\n\ -uniform vec3 refTranslationVec;\n\ -uniform int refMatrixType; // 0= identity, 1= translate, 2= transform\n\ -\n\ -void main()\n\ -{\n\ - vec4 rotatedPos;\n\ - if(refMatrixType == 0)\n\ - {\n\ - rotatedPos = buildingRotMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\ - }\n\ - else if(refMatrixType == 1)\n\ - {\n\ - rotatedPos = buildingRotMatrix * vec4(position.xyz + refTranslationVec.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\ - }\n\ - else if(refMatrixType == 2)\n\ - {\n\ - rotatedPos = RefTransfMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\ - }\n\ -\n\ - vec3 objPosHigh = buildingPosHIGH;\n\ - vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n\ - vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\ - vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\ - vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ - \n\ - gl_PointSize = 10.0;\n\ - gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\ -}\n\ -"; -ShaderSource.ColorVS = "attribute vec3 position;\n\ -uniform mat4 ModelViewProjectionMatrixRelToEye;\n\ -uniform vec3 buildingPosHIGH;\n\ -uniform vec3 buildingPosLOW;\n\ -uniform vec3 encodedCameraPositionMCHigh;\n\ -uniform vec3 encodedCameraPositionMCLow;\n\ -uniform mat4 RefTransfMatrix;\n\ -\n\ -void main()\n\ -{\n\ - vec4 rotatedPos = RefTransfMatrix * vec4(position.xyz, 1.0);\n\ - vec3 objPosHigh = buildingPosHIGH;\n\ - vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n\ - vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\ - vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\ - vec4 pos = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ - \n\ - gl_Position = ModelViewProjectionMatrixRelToEye * pos;\n\ -}\n\ -"; -ShaderSource.InvertedBoxFS = "#ifdef GL_ES\n\ - precision highp float;\n\ -#endif\n\ -\n\ -uniform sampler2D depthTex;\n\ -uniform sampler2D noiseTex; \n\ -uniform sampler2D diffuseTex;\n\ -uniform bool hasTexture;\n\ -uniform bool textureFlipYAxis;\n\ -varying vec3 vNormal;\n\ -uniform mat4 projectionMatrix;\n\ -uniform mat4 m;\n\ -uniform vec2 noiseScale;\n\ -uniform float near;\n\ -uniform float far; \n\ -uniform float fov;\n\ -uniform float aspectRatio; \n\ -uniform float screenWidth; \n\ -uniform float screenHeight; \n\ -uniform float shininessValue;\n\ -uniform vec3 kernel[16]; \n\ -uniform vec4 vColor4Aux;\n\ -\n\ -varying vec2 vTexCoord; \n\ -varying vec3 vLightWeighting;\n\ -\n\ -varying vec3 diffuseColor;\n\ -uniform vec3 specularColor;\n\ -varying vec3 vertexPos;\n\ -\n\ -const int kernelSize = 16; \n\ -uniform float radius; \n\ -\n\ -uniform float ambientReflectionCoef;\n\ -uniform float diffuseReflectionCoef; \n\ -uniform float specularReflectionCoef; \n\ -\n\ -float unpackDepth(const in vec4 rgba_depth)\n\ -{\n\ - const vec4 bit_shift = vec4(0.000000059605, 0.000015258789, 0.00390625, 1.0);\n\ - float depth = dot(rgba_depth, bit_shift);\n\ - return depth;\n\ -} \n\ -\n\ -vec3 getViewRay(vec2 tc)\n\ -{\n\ - float hfar = 2.0 * tan(fov/2.0) * far;\n\ - float wfar = hfar * aspectRatio; \n\ - vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n\ - return ray; \n\ -} \n\ - \n\ -//linear view space depth\n\ -float getDepth(vec2 coord)\n\ -{\n\ - return unpackDepth(texture2D(depthTex, coord.xy));\n\ -} \n\ -\n\ -void main()\n\ -{ \n\ - vec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight); \n\ - float linearDepth = getDepth(screenPos); \n\ - vec3 origin = getViewRay(screenPos) * linearDepth; \n\ -\n\ - vec3 normal2 = vNormal;\n\ - \n\ - vec3 rvec = texture2D(noiseTex, screenPos.xy * noiseScale).xyz * 2.0 - 1.0;\n\ - vec3 tangent = normalize(rvec - normal2 * dot(rvec, normal2));\n\ - vec3 bitangent = cross(normal2, tangent);\n\ - mat3 tbn = mat3(tangent, bitangent, normal2); \n\ - \n\ - float occlusion = 0.0;\n\ - for(int i = 0; i < kernelSize; ++i)\n\ - { \n\ - vec3 sample = origin + (tbn * kernel[i]) * radius;\n\ - vec4 offset = projectionMatrix * vec4(sample, 1.0); \n\ - offset.xy /= offset.w;\n\ - offset.xy = offset.xy * 0.5 + 0.5; \n\ - float sampleDepth = -sample.z/far;\n\ - if(sampleDepth > 0.49)\n\ - continue;\n\ - float depthBufferValue = getDepth(offset.xy); \n\ - float range_check = abs(linearDepth - depthBufferValue)+radius*0.998;\n\ - if (range_check < radius*1.001 && depthBufferValue <= sampleDepth)\n\ - {\n\ - occlusion += 1.0;\n\ - }\n\ - } \n\ - \n\ - occlusion = 1.0 - occlusion / float(kernelSize);\n\ -\n\ - vec3 lightPos = vec3(20.0, 60.0, 20.0);\n\ - vec3 L = normalize(lightPos - vertexPos);\n\ - float lambertian = max(dot(normal2, L), 0.0);\n\ - float specular = 0.0;\n\ - if(lambertian > 0.0)\n\ - {\n\ - vec3 R = reflect(-L, normal2); // Reflected light vector\n\ - vec3 V = normalize(-vertexPos); // Vector to viewer\n\ - \n\ - // Compute the specular term\n\ - float specAngle = max(dot(R, V), 0.0);\n\ - specular = pow(specAngle, shininessValue);\n\ - }\n\ - \n\ - if(lambertian < 0.5)\n\ - {\n\ - lambertian = 0.5;\n\ - }\n\ -\n\ - vec4 textureColor;\n\ - if(hasTexture)\n\ - {\n\ - if(textureFlipYAxis)\n\ - {\n\ - textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, 1.0 - vTexCoord.t));\n\ - }\n\ - else{\n\ - textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, vTexCoord.t));\n\ - }\n\ - \n\ - if(textureColor.w == 0.0)\n\ - {\n\ - discard;\n\ - }\n\ - }\n\ - else{\n\ - textureColor = vColor4Aux;\n\ - }\n\ - \n\ - vec3 ambientColor = vec3(textureColor.x, textureColor.y, textureColor.z);\n\ -\n\ - gl_FragColor = vec4((ambientReflectionCoef * ambientColor + diffuseReflectionCoef * lambertian * textureColor.xyz + specularReflectionCoef * specular * specularColor)*vLightWeighting * occlusion, 1.0); \n\ -}\n\ -"; -ShaderSource.InvertedBoxVS = " attribute vec3 position;\n\ - attribute vec3 normal;\n\ - attribute vec2 texCoord;\n\ - \n\ - uniform mat4 buildingRotMatrix; \n\ - uniform mat4 projectionMatrix; \n\ - uniform mat4 modelViewMatrix;\n\ - uniform mat4 modelViewMatrixRelToEye; \n\ - uniform mat4 ModelViewProjectionMatrixRelToEye;\n\ - uniform mat4 RefTransfMatrix;\n\ - uniform mat4 normalMatrix4;\n\ - uniform vec3 buildingPosHIGH;\n\ - uniform vec3 buildingPosLOW;\n\ - uniform vec3 encodedCameraPositionMCHigh;\n\ - uniform vec3 encodedCameraPositionMCLow;\n\ - uniform vec3 aditionalPosition;\n\ - uniform vec3 refTranslationVec;\n\ - uniform int refMatrixType; // 0= identity, 1= translate, 2= transform\n\ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +'use strict'; + +/** + * a point feature which will be used at three degree world + * @class Point3D + * @param {Number} x + * @param {Number} y + * @param {Number} z + */ + +var Point3D = function(x, y, z) +{ + if (!(this instanceof Point3D)) + { + // throw new Error(Messages.CONSTRUCT_ERROR); + throw new Error(i18next.t('error.construct.create')); + } + + if (x !== undefined) + { this.x = x; } + else + { this.x = 0.0; } + + if (y !== undefined) + { this.y = y; } + else + { this.y = 0.0; } + + if (z !== undefined) + { this.z = z; } + else + { this.z = 0.0; } + + this.pointType; // 1 = important point. +}; + +/** + * delete the value of x,y,z coordi + */ +Point3D.prototype.deleteObjects = function() +{ + this.x = undefined; + this.y = undefined; + this.z = undefined; +}; + +/** + * copy the value of other point + * @param {Point3D} point3d + */ +Point3D.prototype.copyFrom = function(point3d) +{ + this.x = point3d.x; + this.y = point3d.y; + this.z = point3d.z; +}; + +/** + * Calculate [this.x*this.x + this.y*this.y + this.z*this.z] to prepare squared module + * @returns {Number} + */ +Point3D.prototype.getSquaredModul = function() +{ + return this.x*this.x + this.y*this.y + this.z*this.z; +}; + +/** + * Math.sqrt(this.x*this.x + this.y*this.y + this.z*this.z ); + * @returns {Number} + */ +Point3D.prototype.getModul = function() +{ + return Math.sqrt(this.getSquaredModul()); +}; + +/** + * + * get the unitary value + */ +Point3D.prototype.unitary = function() +{ + var modul = this.getModul(); + this.x /= modul; + this.y /= modul; + this.z /= modul; +}; + +/** + * + * check whether each value of the coordi is null or not + * @returns {Boolean} + */ +Point3D.prototype.isNAN = function() +{ + if (isNaN(this.x) || isNaN(this.y) || isNaN(this.z) ) + { return true; } + else + { return false; } +}; + +/** + * Calculate vector product + * @param {Point3D} point the point which will be used at this calculate. + * @param {Point3D} resultPoint the point which will save the calculated value. + * @returns {Number} calculated result + */ +Point3D.prototype.crossProduct = function(point, resultPoint) +{ + if (resultPoint === undefined) { resultPoint = new Point3D(); } + + resultPoint.x = this.y * point.z - point.y * this.z; + resultPoint.y = point.x * this.z - this.x * point.z; + resultPoint.z = this.x * point.y - point.x * this.y; + + return resultPoint; +}; + +/** + * Calculate scalar production of vector + * @param {Point3D} point the point which will be used at this calculate. + * @returns {Number} calculated result + */ +Point3D.prototype.scalarProduct = function(point) +{ + var scalarProd = this.x*point.x + this.y*point.y + this.z*point.z; + return scalarProd; +}; + +/** + * get the spherical coordinates + * @param {GeographicCoord}resultGeographicCoords the target that will be canged + * @returns {GeographicCoord} resultGeographicCoords + */ +Point3D.prototype.getSphericalCoords = function(resultGeographicCoords) +{ + if (resultGeographicCoords === undefined) + { resultGeographicCoords = new GeographicCoord(); } + + // heading. + var xyProjectedPoint = new Point2D(this.x, this.y); + var longitudeVectorRef = new Point2D(1.0, 0.0); + var headingDeg = xyProjectedPoint.angleDegToVector(longitudeVectorRef); + + if (this.y < 0.0) + { + headingDeg = 360.0 - headingDeg; + } + + // azimutal.meridian angle + var projectedModul = xyProjectedPoint.getModul(); + var azimutRad = Math.atan(this.z/projectedModul); + var azimutDeg = azimutRad * 180.0 / Math.PI; + + if (this.z < 0.0) + { + azimutDeg *= -1.0; + } + + resultGeographicCoords.longitude = headingDeg; + resultGeographicCoords.latitude = azimutDeg; + + return resultGeographicCoords; +}; + +/** + * Check whether those of two vectors are parallel or not + * If parallel then check whether the direction sense is same or not + */ +Point3D.prototype.getRelativeOrientationToVector = function(vector, radError) +{ + var angRad = this.angleRadToVector(vector); + if (angRad < radError) + { return 0; } // there are parallel & the same direction sense. + else if (Math.abs(Math.PI - angRad) < radError) + { return 1; } // there are parallel & opposite direction sense. + else + { return 2; } // there are NO parallels. +}; + +/** + * Calculate the radian value of the angle of the two vectors + * @param vector the target vector + * @returns the angle of two vector + */ +Point3D.prototype.angleRadToVector = function(vector) +{ + if (vector === undefined) + { return undefined; } + + // + //var scalarProd = this.scalarProd(vector); + var myModul = this.getModul(); + var vecModul = vector.getModul(); + + // calculate by cos. + //var cosAlfa = scalarProd / (myModul * vecModul); + //var angRad = Math.acos(cosAlfa); + //var angDeg = alfa * 180.0/Math.PI; + //------------------------------------------------------ + var error = 10E-10; + if (myModul < error || vecModul < error) + { return undefined; } + + return Math.acos(this.scalarProduct(vector) / (myModul * vecModul)); +}; + +/** + * Calculate the degree value of the angle of the two vectors + * @param point 변수 + * @param resultPoint 변수 + * @returns resultPoint + */ +Point3D.prototype.angleDegToVector = function(vector) +{ + if (vector === undefined) + { return undefined; } + + var angRad = this.angleRadToVector(vector); + + if (angRad === undefined) + { return undefined; } + + return angRad * 180.0/Math.PI; +}; + +/** + * 어떤 일을 하고 있습니까? + * @param px 변수 + * @returns dx*dx + dy*dy + dz*dz + */ +Point3D.prototype.squareDistToPoint = function(point) +{ + var dx = this.x - point.x; + var dy = this.y - point.y; + var dz = this.z - point.z; + + return dx*dx + dy*dy + dz*dz; +}; + +/** + * 어떤 일을 하고 있습니까? + * @param px 변수 + * @param py 변수 + * @param pz 변수 + * @returns dx*dx + dy*dy + dz*dz + */ +Point3D.prototype.isCoincidentToPoint = function(point, errorDist) +{ + var squareDist = this.distToPoint(point); + var coincident = false; + if (squareDist < errorDist*errorDist) + { + coincident = true; + } + + return coincident; +}; + +/** + * 어떤 일을 하고 있습니까? + * @param px 변수 + * @param py 변수 + * @param pz 변수 + * @returns dx*dx + dy*dy + dz*dz + */ +Point3D.prototype.squareDistTo = function(x, y, z) +{ + var dx = this.x - x; + var dy = this.y - y; + var dz = this.z - z; + + return dx*dx + dy*dy + dz*dz; +}; + +/** + * 어떤 일을 하고 있습니까? + * @param px 변수 + * @param py 변수 + * @param pz 변수 + * @returns dx*dx + dy*dy + dz*dz + */ +Point3D.prototype.distTo = function(x, y, z) +{ + return Math.sqrt(this.squareDistTo(x, y, z)); +}; + +/** + * 어떤 일을 하고 있습니까? + * @param px 변수 + * @param py 변수 + * @param pz 변수 + * @returns dx*dx + dy*dy + dz*dz + */ +Point3D.prototype.distToPoint = function(point) +{ + return Math.sqrt(this.squareDistToPoint(point)); +}; + +/** + * 어떤 일을 하고 있습니까? + * @param px 변수 + * @param py 변수 + * @param pz 변수 + * @returns dx*dx + dy*dy + dz*dz + */ +Point3D.prototype.distToSphere = function(sphere) +{ + return Math.sqrt(this.squareDistToPoint(sphere.centerPoint)) - sphere.r; +}; + +/** + * 어떤 일을 하고 있습니까? + * @param px 변수 + * @param py 변수 + * @param pz 변수 + * @returns dx*dx + dy*dy + dz*dz + */ +Point3D.prototype.aproxDistTo = function(pointB, sqrtTable) +{ + var difX = Math.abs(this.x - pointB.x); + var difY = Math.abs(this.y - pointB.y); + var difZ = Math.abs(this.z - pointB.z); + + // find the big value. + var maxValue, value1, value2; + var value1Idx, value2Idx; + + if (difX > difY) + { + if (difX > difZ) + { + maxValue = difX; + value1 = difY/maxValue; + value1Idx = Math.floor(value1*10); + var middleDist = maxValue * sqrtTable[value1Idx]; + value2 = difZ/middleDist; + value2Idx = Math.floor(value2*10); + return (middleDist * sqrtTable[value2Idx]); + } + else + { + maxValue = difZ; + value1 = difX/maxValue; + value1Idx = Math.floor(value1*10); + var middleDist = maxValue * sqrtTable[value1Idx]; + value2 = difY/middleDist; + value2Idx = Math.floor(value2*10); + return (middleDist * sqrtTable[value2Idx]); + } + } + else + { + if (difY > difZ) + { + maxValue = difY; + value1 = difX/maxValue; + value1Idx = Math.floor(value1*10); + var middleDist = maxValue * sqrtTable[value1Idx]; + value2 = difZ/middleDist; + value2Idx = Math.floor(value2*10); + return (middleDist * sqrtTable[value2Idx]); + } + else + { + maxValue = difZ; + value1 = difX/maxValue; + value1Idx = Math.floor(value1*10); + var middleDist = maxValue * sqrtTable[value1Idx]; + value2 = difY/middleDist; + value2Idx = Math.floor(value2*10); + return (middleDist * sqrtTable[value2Idx]); + } + } +}; + +/** + * 어떤 일을 하고 있습니까? + * @param x 변수 + * @param y 변수 + * @param z 변수 + */ +Point3D.prototype.getVectorToPoint = function(targetPoint, resultVector) +{ + // this returns a vector that points to "targetPoint" from "this". + // the "resultVector" has the direction from "this" to "targetPoint", but is NOT normalized. + if (targetPoint === undefined) + { return undefined; } + + if (resultVector === undefined) + { resultVector = new Point3D(); } + + resultVector.set(targetPoint.x - this.x, targetPoint.y - this.y, targetPoint.z - this.z); + + return resultVector; +}; + +/** + * 어떤 일을 하고 있습니까? + * @param x 변수 + * @param y 변수 + * @param z 변수 + */ +Point3D.prototype.set = function(x, y, z) +{ + this.x = x; this.y = y; this.z = z; +}; + +/** + * 어떤 일을 하고 있습니까? + * @param x 변수 + * @param y 변수 + * @param z 변수 + */ +Point3D.prototype.add = function(x, y, z) +{ + this.x += x; this.y += y; this.z += z; +}; + +/** + * 어떤 일을 하고 있습니까? + * @param x 변수 + * @param y 변수 + * @param z 변수 + */ +Point3D.prototype.addPoint = function(point) +{ + this.x += point.x; this.y += point.y; this.z += point.z; +}; + +/** + * 어떤 일을 하고 있습니까? + * @param x 변수 + * @param y 변수 + * @param z 변수 + */ +Point3D.prototype.scale = function(scaleFactor) +{ + this.x *= scaleFactor; this.y *= scaleFactor; this.z *= scaleFactor; +}; + + +/** + * 3차원 정보 + * @class Point3DList + */ +var Point3DList = function() +{ + if (!(this instanceof Point3DList)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + + this.points3dArray; +}; + +/** + * 어떤 일을 하고 있습니까? + */ +Point3DList.prototype.newPoint3D = function(x, y, z) +{ + if (this.points3dArray === undefined) + { this.points3dArray = []; } + + var point3d = new Point3D(x, y, z); + this.points3dArray.push(point3d); + return point3d; +}; + +/** + * 어떤 일을 하고 있습니까? + */ +Point3DList.prototype.addPoint3D = function(point3d) +{ + if (this.points3dArray === undefined) + { this.points3dArray = []; } + + this.points3dArray.push(point3d); +}; + +/** + * 어떤 일을 하고 있습니까? + */ +Point3DList.calculateBBox = function(points3DArray, resultBBox) +{ + if (points3DArray === undefined) + { return undefined; } + + var pointCount = points3DArray.length; + if (pointCount === 0) + { return undefined; } + + if (resultBBox === undefined) + { resultBBox = new BoundingBox(); } + + resultBBox.init(points3DArray[0]); // init the box. + for (var i=1; i CCW. (normal = -1) -> CW. + this.convexPolygonsArray; // tessellation result. + this.bRect; // boundary rectangle. +}; + +Polygon2D.prototype.deleteObjects = function() +{ + if (this.point2dList !== undefined) + { + this.point2dList.deleteObjects(); + this.point2dList = undefined; + } + + this.normal = undefined; +}; + +Polygon2D.prototype.getBoundingRectangle = function(resultBRect) +{ + if (this.point2dList === undefined) + { return resultBRect; } + + resultBRect = this.point2dList.getBoundingRectangle(resultBRect); + return resultBRect; +}; +/** + * get the direction of the specific line segment of the edge + * @param {Number} idx the index of the specific line segment + * @returns direction + */ +Polygon2D.prototype.getEdgeDirection = function(idx) +{ + // the direction is unitary vector. + var segment = this.point2dList.getSegment(idx); + var direction = segment.getDirection(undefined); + return direction; +}; + +/** + * get the vector of the specigic line segement of the edge + * @param {Number} index the index of the specific line segment + * @returns vector + */ +Polygon2D.prototype.getEdgeVector = function(idx) +{ + var segment = this.point2dList.getSegment(idx); + var vector = segment.getVector(undefined); + return vector; +}; + +/** + * reverse the direction sense of this polygon + */ +Polygon2D.prototype.reverseSense = function() +{ + if (this.point2dList !== undefined) + { this.point2dList.reverse(); } +}; + +/** + * copy the information of the other polygon to this polygon + * @param {Polygon2D} resultCopyPolygon + * @returns {Polygon2D} resultCopyPolygon + */ +Polygon2D.prototype.getCopy = function(resultCopyPolygon) +{ + if (this.point2dList === undefined) + { return resultCopyPolygon; } + + if (resultCopyPolygon === undefined) + { resultCopyPolygon = new Polygon2D(); } + + // copy the point2dList and the normal. + if (resultCopyPolygon.point2dList === undefined) + { resultCopyPolygon.point2dList = new Point2DList(); } + + resultCopyPolygon.point2dList = this.point2dList.getCopy(resultCopyPolygon.point2dList); + + if (this.normal) + { resultCopyPolygon.normal = this.normal; } + + return resultCopyPolygon; +}; + +/** + * Calculate the normal vector of this polygon + * @param resultConcavePointsIdxArray save the index of the points which make concave at the border + * @returns resultFConcavePointsIdxArray the list of the index which make concave at the border + */ +Polygon2D.prototype.calculateNormal = function(resultConcavePointsIdxArray) +{ + // must check if the verticesCount is 3. Then is a convex polygon. + + // A & B are vectors. + // A*B is scalarProduct. + // A*B = |A|*|B|*cos(alfa) + var point; + var crossProd; + + if (resultConcavePointsIdxArray === undefined) + { resultConcavePointsIdxArray = []; } + + //var candidate_1 = {}; // normal candidate 1. + //var candidate_2 = {}; // normal candidate 2. + + this.normal = 0; // unknown sense. + var pointsCount = this.point2dList.getPointsCount(); + for (var i=0; i 0.0) + { + crossProd = 1; + } + else + { continue; } + // calcule by cos. + // cosAlfa = scalarProd / (strModul * endModul); (but strVecModul = 1 & endVecModul = 1), so: + var cosAlfa = scalarProd; + var alfa = Math.acos(cosAlfa); + this.normal += (crossProd * alfa); + } + + if (this.normal > 0 ) + { this.normal = 1; } + else + { this.normal = -1; } + + return resultConcavePointsIdxArray; +}; + +/** + * Make the tessellate of the triangles which originally make up single Polygon2D feature (like a patchwork with triangle) + * To call this function, before must call "calculateNormal" that returns "concaveVerticesIndices" + * In 2D, "normal" is -1=(cw) or 1=(ccw). + * @param concaveVerticesIndices the index of the points which make concave + * @param convexPolygonsArray the index of the points which make convex + */ +Polygon2D.prototype.tessellate = function(concaveVerticesIndices, convexPolygonsArray) +{ + + var concaveVerticesCount = concaveVerticesIndices.length; + + if (concaveVerticesCount === 0) + { + convexPolygonsArray.push(this); + return convexPolygonsArray; + } + + // now, for any concave vertex, find the closest vertex to split the polygon. + var find = false; + var idx_B; + var i=0; + + while (!find && i 0) + { + convexPolygonsArray = polygon_A.tessellate(concavePoints_A, convexPolygonsArray); + } + else + { + if (convexPolygonsArray === undefined) + { convexPolygonsArray = []; } + + convexPolygonsArray.push(polygon_A); + } + + // polygon_B. + if (concavePoints_B.length > 0) + { + convexPolygonsArray = polygon_B.tessellate(concavePoints_B, convexPolygonsArray); + } + else + { + if (convexPolygonsArray === undefined) + { convexPolygonsArray = []; } + + convexPolygonsArray.push(polygon_B); + } + } + + j++; + } + i++; + } + + return convexPolygonsArray; +}; +/** + * Check whether the given segment cut a polygon edges or is coincident with a polygon's vertex + * @param segment the target segement + * */ +Polygon2D.prototype.intersectionWithSegment = function(segment) +{ + if (this.bRect !== undefined) + { + // if exist boundary rectangle, check bRect intersection. + var segmentsBRect = segment.getBoundaryRectangle(segmentsBRect); + if (!this.bRect.intersectsWithRectangle(segmentsBRect)) + { return false; } + } + + // 1rst check if the segment is coincident with any polygons vertex. + var mySegment; + var intersectionType; + var error = 10E-8; + var pointsCount = this.point2dList.getPointsCount(); + for (var i=0; i idx2. + var polygon_A = new Polygon2D(); + polygon_A.point2dList = new Point2DList(); + polygon_A.point2dList.pointsArray = []; + + // 1rst, put vertex1 & vertex2 in to the polygon_A. + polygon_A.point2dList.pointsArray.push(this.point2dList.getPoint(idx1)); + polygon_A.point2dList.pointsArray.push(this.point2dList.getPoint(idx2)); + + var finished = false; + var currIdx = idx2; + var startIdx = idx1; + var i=0; + var totalPointsCount = this.point2dList.getPointsCount(); + while (!finished && i idx1. + var polygon_B = new Polygon2D(); + polygon_B.point2dList = new Point2DList(); + polygon_B.point2dList.pointsArray = []; + + // 1rst, put vertex2 & vertex1 in to the polygon_B. + polygon_B.point2dList.pointsArray.push(this.point2dList.getPoint(idx2)); + polygon_B.point2dList.pointsArray.push(this.point2dList.getPoint(idx1)); + + finished = false; + currIdx = idx1; + startIdx = idx2; + i=0; + while (!finished && i 0) + { normal = 1; } + else + { normal = -1; } + + var pointsCount = this.point2dList.getPointsCount(); + for (var i=0; i 0) + { normal = 1; } + else + { normal = -1; } + + var pointsCount = concavePolygon.point2dList.getPointsCount(); + for (var i=0; i 0) + { + // check if the last point of "resultPointsArray" and the 1rst point of "this" is coincident. + var lastExistentPoint = resultPointsArray[resultExistentPointsCount-1]; + var point0 = this.point2dArray[i]; + if (!lastExistentPoint.isCoincidentToPoint(point0, errorDist)) + { + point = new Point2D(); + point.copyFrom(this.point2dArray[i]); + point.pointType = 1; // mark as "important point". + resultPointsArray.push(point); + } + } + else + { + point = new Point2D(); + point.copyFrom(this.point2dArray[i]); + point.pointType = 1; // mark as "important point". + resultPointsArray.push(point); + } + } + else + { + point = new Point2D(); + point.copyFrom(this.point2dArray[i]); + point.pointType = 1; // mark as "important point". + resultPointsArray.push(point); + } + } + + return resultPointsArray; +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +'use strict'; + +/** + * This is similar with Point23List, but this one represents real polyline geometry feature. + * @class PolyLine3D + */ +var PolyLine3D = function() +{ + if (!(this instanceof PolyLine3D)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + + this.point3dArray; + this.geoLocDataManager; + this.vboKeysContainer; +}; + +/** + * Creates a new Point3D. + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @returns point3d + */ +PolyLine3D.prototype.newPoint3d = function(x, y, z) +{ + if (this.point3dArray === undefined) + { this.point3dArray = []; } + + var point3d = new Point3D(x, y, z); + this.point3dArray.push(point3d); + return point3d; +}; + +/** + * Add a list of Point3D at the last of this.pointsArray + * @param point3dArray the point that will be pushed at this.pointsArray + */ +PolyLine3D.prototype.addPoint3dArray = function(points3dArray) +{ + if (points3dArray === undefined) + { return; } + + if (this.point3dArray === undefined) + { this.point3dArray = []; } + + this.point3dArray.push.apply(this.point3dArray, points3dArray); +}; + +/** + * Return the coordinate contained at geoLocDataManager + * @returns geoLoc + */ +PolyLine3D.prototype.getGeographicLocation = function() +{ + if (this.geoLocDataManager === undefined) + { this.geoLocDataManager = new GeoLocationDataManager(); } + + var geoLoc = this.geoLocDataManager.getCurrentGeoLocationData(); + if (geoLoc === undefined) + { + geoLoc = this.geoLocDataManager.newGeoLocationData("default"); + } + + return geoLoc; +}; + +/** + * Make the vbo of this point3DList + * @param magoManager + */ +PolyLine3D.prototype.makeVbo = function(magoManager) +{ + if (this.vboKeysContainer === undefined) + { this.vboKeysContainer = new VBOVertexIdxCacheKeysContainer(); } + + var pointsCount = this.point3dArray.length; + var posByteSize = pointsCount * 3; + var posVboDataArray = new Float32Array(posByteSize); + var point3d; + for (var i=0; i|undefined} resultPointsArray if this undefined, set new Array. [] + * @returns {Array.} resultPointsArray rectangle의 꼭지점 반환, 중심점으로부터 가로,세로의 절반 만큼 떨어진 4점을 반환 + */ +Rectangle2D.prototype.getPoints = function(resultPointsArray) +{ + if (this.centerPoint === undefined || this.width === undefined || this.height === undefined) + { return resultPointsArray; } + + if (resultPointsArray === undefined) + { resultPointsArray = []; } + + var point; + var halfWidth = this.width / 2; + var halfHeight = this.height / 2; + + // starting in left-down corner, go in CCW. + point = new Point2D(this.centerPoint.x - halfWidth, this.centerPoint.y - halfHeight); + point.pointType = 1; // mark as "important point". + resultPointsArray.push(point); + + point = new Point2D(this.centerPoint.x + halfWidth, this.centerPoint.y - halfHeight); + point.pointType = 1; // mark as "important point". + resultPointsArray.push(point); + + point = new Point2D(this.centerPoint.x + halfWidth, this.centerPoint.y + halfHeight); + point.pointType = 1; // mark as "important point". + resultPointsArray.push(point); + + point = new Point2D(this.centerPoint.x - halfWidth, this.centerPoint.y + halfHeight); + point.pointType = 1; // mark as "important point". + resultPointsArray.push(point); + + return resultPointsArray; +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +'use strict'; + +/** + * 링형태의 폴리곤 객체를 생성하기 위한 클래스 + * + * @class + */ +var Ring2D = function() +{ + if (!(this instanceof Ring2D)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + /** + * 다양한 폴리곤을 갖고 있는 배열 + * @type {Obecjt[]} + */ + this.elemsArray = []; + + /** + * 폴리곤 + * @type {Polygon2D} + */ + this.polygon = undefined; +}; + +/** + * 생성된 객체가 있다면 삭제하고 초기화 한다. + */ +Ring2D.prototype.deleteObjects = function() +{ + for (var i=0, len = this.elemsArray.length; i 1) + { + + var errorDist = 10E-8; + var firstPoint = resultPointsArray[0]; + var lastPoint = resultPointsArray[totalPointsCount-1]; + + // mark the last as pointType = 1 + lastPoint.pointType = 1; + + if (firstPoint.isCoincidentToPoint(lastPoint, errorDist)) + { + // delete the last point. + lastPoint = resultPointsArray.pop(); + lastPoint.deleteObjects(); + lastPoint = undefined; + } + } + + return resultPointsArray; +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +'use strict'; +/** + * Ring2D 의 리스트 {@link Ring2D} + */ +var Ring2DList = function() +{ + if (!(this instanceof Ring2DList)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + + /** + * 폴리곤 배열 + * @type {Ring2D[]} + */ + this.ringsArray = []; + + /** + * 인덱스 리스트 + * @type {Number[]} + */ + this.idxInList; +}; + +/** + * Ring2D 를 생성하고 배열에 추가한다. + * + * @returns {Ring2D} 생성된 Ring2D 의 객체 + */ +Ring2DList.prototype.newRing = function() +{ + var ring = new Ring2D(); + this.ringsArray.push(ring); + + return ring; +}; + +/** + * 주어진 Ring2D 를 배열에 추가한다. + * + * @param {Ring2D} ring 추가할 Ring2D 객체 + */ +Ring2DList.prototype.addRing = function(ring) +{ + this.ringsArray.push(ring); +}; + +/** + * 생성된 객체가 있다면 삭제하고 초기화 한다. + */ +Ring2DList.prototype.deleteObjects = function() +{ + for (var i=0, len = this.ringsArray.length; iindex 위치의 Ring2D 객체 + * + * @see Ring2DList#getRingsCount + */ +Ring2DList.prototype.getRing = function(index) +{ + return this.ringsArray[index]; +}; + +/** + * 주어진 Ring2D 배열의 각 폴리곤을 포함하는 경계 사각형을 구한다. + * + * @param {Ring2D[]} ringsArray Ring2D 배열 + * @param {BoundingRectangle} resultBRect 폴리곤들을 포함하는 경계 사각형 + * @returns {BoundingRectangle} 폴리곤들을 포함하는 경계 사각형 결과값 + */ +Ring2DList.getBoundingRectangle = function(ringsArray, resultBRect) +{ + if (resultBRect === undefined) + { + resultBRect = new BoundingRectangle(); + } + + var ring; + var currBRect; + for (var i=0, len = ringsArray.length; i object.squaredDist) + { + newStartIdx = startIdx; + newEndIdx = middleIdx; + } + else + { + newStartIdx = middleIdx; + newEndIdx = endIdx; + } + return this.getIndexToInsertBySquaredDist(objectsArray, object, newStartIdx, newEndIdx); + } +}; + +/** + * 이진 탐색 방법을 통해 해당 객체가 추가될 인덱스 값을 찾는다. + * - 탐색의 대상인 배열은 이미 정렬되어있어야 한다. + * + * @param {Object[]} arr 탐색하기 위한 배열 + * @param {Object} x 탐색 대상 + * @param {Function} func 탐색 비교값 + * @returns {Number} 탐색 결과 인덱스 + */ +Ring2DList.getBinarySearchIndex = function (arr, x, func) +{ + var start = 0; + var end = arr.length - 1; + + func = func || function (value) { return value; }; + + // Iterate while start not meets end + while (start <= end) + { + // Find the mid index + var mid = Math.floor((start + end) / 2); + + if (func(arr[mid]) < func(x)) + { + start = mid + 1; + } + else + { + end = mid - 1; + } + } + + return start; +}; + +"use strict"; + +/** + * 링폴리곤의 형태를 정의 + */ +var RingType = { + /** + * 아치형태의 폴리곤 {@link Arc2D} + * @type {Number} + * @constant + */ + ARC: 0, + + /** + * 원형태의 폴리곤 {@link Circle2D} + * @type {Number} + * @constant + */ + CIRCLE: 1, + + /** + * 폴리라인형태의 폴리곤 {@link PolyLine2D} + * @type {Number} + * @constant + */ + POLYLINE: 2, + + /** + * 사각형형태의 폴리곤 {@link Rectangle2D} + * @type {Number} + * @constant + */ + RECTANGLE: 3, + + /** + * 별형태의 폴리곤 {@link Star2D} + * @type {Number} + * @constant + */ + Star2D: 4, + + /** + * @private + */ + NUMBER_OF_RING_TYPE: 5 +}; +'use strict'; +/** + * 선분 생성을 위한 클래스 + * + * @param {Point2D} strPoint2D 시작 포인트 + * @param {Point2D} endPoint2D 종료 포인트 + */ +var Segment2D = function(strPoint2D, endPoint2D) +{ + if (!(this instanceof Segment2D)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + + this.startPoint2d; + this.endPoint2d; + + if (strPoint2D) + { + this.startPoint2d = strPoint2D; + } + + if (endPoint2D) + { + this.endPoint2d = endPoint2D; + } +}; + + +/** + * 선분에 포인트를 설정한다. + * + * @param {Point2D} strPoint2D 시작 포인트 + * @param {Point2D} endPoint2D 종료 포인트 + */ +Segment2D.prototype.setPoints = function(strPoint2D, endPoint2D) +{ + if (strPoint2D !== undefined) + { + this.startPoint2d = strPoint2D; + } + if (endPoint2D !== undefined) + { + this.endPoint2d = endPoint2D; + } +}; + +/** + * 시작 포인트에서 종료 포인트까지의 벡터를 구한다. + * + * @param {Point2D} result 벡터 결과값 + * @returns {Point2D} 벡터 결과값 + */ +Segment2D.prototype.getVector = function(result) +{ + if (this.startPoint2d === undefined || this.endPoint2d === undefined) + { + return undefined; + } + + if (result === undefined) + { + result = new Point2D(); + } + + result = this.startPoint2d.getVectorToPoint(this.endPoint2d, result); + return result; +}; + + +/** + * 선분의 방향값을 계산한다. + * + * @param {Point2D} result 선분이 나타내는 방향값 + * @returns {Point2D} 선분이 나타내는 방향값 + */ +Segment2D.prototype.getDirection = function(result) +{ + if (result === undefined) + { + result = new Point2D(); + } + + result = this.getVector(result); + result.unitary(); + + return result; +}; + + +/** + * 선분의 경계 사각형을 구한다. + * + * @param {BoundaryRectangle} result 선분을 포함하는 경계 사각형 + * @returns {BoundaryRectangle} 선분을 포함하는 경계 사각형 + */ +Segment2D.prototype.getBoundaryRectangle = function(result) +{ + if (result === undefined) + { + result = new BoundaryRectangle(); + } + + result.setInit(this.startPoint2d); + result.addPoint(this.endPoint2d); + + return result; +}; + + +/** + * 선분을 지나는 직선을 구한다. + * + * @param {Line2D} result 주어진 선분을 지나는 직선 + * @returns {Line2D} 주어진 선분을 지나는 직선 + */ +Segment2D.prototype.getLine = function(result) +{ + if (result === undefined) + { + result = new Line2D(); + } + // unitary direction. + var dir = this.getDirection(); + var strPoint = this.startPoint2d; + result.setPointAndDir(strPoint.x, strPoint.y, dir.x, dir.y); + return result; +}; + + +/** + * 선분의 제곱된 길이를 구한다. + * + * @returns {Number} 선분의 제곱된 길이 + */ +Segment2D.prototype.getSquaredLength = function() +{ + return this.startPoint2d.squareDistToPoint(this.endPoint2d); +}; + + +/** + * 선분의 길이를 구한다. + * + * @returns {Number} 선분의 길이 + */ +Segment2D.prototype.getLength = function() +{ + return Math.sqrt(this.getSquaredLength()); +}; + + +/** + * 오차율에 따라 주어진 포인트와 선분의 교차를 판단한다. + * + * @param {Point2D} point 포인트 + * @param {Number} error 오차율 + * @returns 교차 판단 결과값 + */ +Segment2D.prototype.intersectionWithPointByDistances = function(point, error) +{ + if (point === undefined) + { + return undefined; + } + + if (error === undefined) + { + error = 10E-8; + } + + // here no check line-point coincidance. + // now, check if is inside of the segment or if is coincident with any vertex of segment. + var distA = this.startPoint2d.distToPoint(point); + var distB = this.endPoint2d.distToPoint(point); + var distTotal = this.getLength(); + + if (distA < error) + { + return Constant.INTERSECTION_POINT_A; + } + + if (distB < error) + { + return Constant.INTERSECTION_POINT_B; + } + + if (distA> distTotal || distB> distTotal) + { + return Constant.INTERSECTION_OUTSIDE; + } + + if (Math.abs(distA + distB - distTotal) < error) + { + return Constant.INTERSECTION_INSIDE; + } +}; + + +/** + * 오차율에 따라 주어진 포인트와 선분의 교차를 판단한다. + * + * @param {Point2D} point 포인트 + * @param {Number} error 오차율 + * @returns 교차 판단 결과값 + */ +Segment2D.prototype.intersectionWithPoint = function(point, error) +{ + if (point === undefined) + { + return undefined; + } + + if (error === undefined) + { + error = 10E-8; + } + + var line = this.getLine(); + if (!line.isCoincidentPoint(point, error)) + { + // no intersection + return Constant.INTERSECTION_OUTSIDE; + } + + return this.intersectionWithPointByDistances(point, error); +}; + +/** + * 오차율에 따라 주어진 선분과 선분의 교차를 판단한다. + * + * @param {Segment2D} segment 선분 + * @param {Number} error 오차율 + * @returns 교차 판단 결과값 + */ +Segment2D.prototype.intersectionWithSegment = function(segment, error) +{ + if (segment === undefined) + { + return undefined; + } + + if (error === undefined) + { + error = 10E-8; + } + + var lineA = this.getLine(); + var lineB = segment.getLine(); + var intersectionPoint = lineA.intersectionWithLine(lineB); + + // 두 선분이 평행한 경우 + if (intersectionPoint === undefined) + { + return undefined; + } + + var intersectionTypeA = this.intersectionWithPointByDistances(intersectionPoint); + var intersectionTypeB = segment.intersectionWithPointByDistances(intersectionPoint); + + if (intersectionTypeA === Constant.INTERSECTION_OUTSIDE) + { + return Constant.INTERSECTION_OUTSIDE; + } + if (intersectionTypeB === Constant.INTERSECTION_OUTSIDE) + { + return Constant.INTERSECTION_OUTSIDE; + } + + return Constant.INTERSECTION_INTERSECT; +}; + + +/** + * 주어진 포인트가 시작 포인트 또는 종료 포인트를 갖는지 판단한다. + * returns if this segment has "point" as startPoint or endPoint. + * + * @param {Point2D} point 포인트 + * @returns {Boolean} 시작/종료 포인트 존재 여부 + */ +Segment2D.prototype.hasPoint = function(point) +{ + if (point === undefined) + { + return false; + } + + if (point === this.startPoint2d || point === this.endPoint2d) + { + return true; + } + + return false; +}; + + +/** + * 주어진 선분이 해당 선분과 공유 포인트를 갖는지 판단한다. + * + * @param {Segment2D} segment 선분 + * @returns {Boolean} 공유 포인트 존재 여부 + */ +Segment2D.prototype.sharesPointsWithSegment = function(segment) +{ + if (segment === undefined) + { + return false; + } + + if (this.hasPoint(segment.startPoint2d) || this.hasPoint(segment.endPoint2d)) + { + return true; + } + + return false; +}; +'use strict'; +/** + * 선분 생성을 위한 클래스 + * + * @param {Point3D} strPoint2D 시작 포인트 + * @param {Point3D} endPoint2D 종료 포인트 + */ +var Segment3D = function(strPoint3D, endPoint3D) +{ + if (!(this instanceof Segment3D)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + + this.startPoint3d; + this.endPoint3d; + + if (strPoint3D) + { + this.startPoint3d = strPoint3D; + } + + if (endPoint3D) + { + this.endPoint3d = endPoint3D; + } +}; + +/** + * 선분에 포인트를 설정한다. + * + * @param {Point3D} strPoint3D 시작 포인트 + * @param {Point3D} endPoint3D 종료 포인트 + */ +Segment3D.prototype.setPoints = function(strPoint3D, endPoint3D) +{ + if (strPoint3D) + { + this.startPoint3d = strPoint3D; + } + + if (endPoint3D) + { + this.endPoint3d = endPoint3D; + } +}; + +/** + * 시작 포인트에서 종료 포인트까지의 벡터를 구한다. + * + * @param {Point3D} result 벡터 결과값 + * @returns {Point3D} 벡터 결과값 + */ +Segment3D.prototype.getVector = function(result) +{ + if (this.startPoint3d === undefined || this.endPoint3d === undefined) + { + return undefined; + } + + if (result === undefined) + { + result = new Point3D(); + } + + result = this.startPoint3d.getVectorToPoint(this.endPoint3d, result); + return result; +}; + +/** + * 선분의 방향값을 계산한다. + * + * @param {Point3D} result 선분이 나타내는 방향값 + * @returns {Point3D} 선분이 나타내는 방향값 + */ +Segment3D.prototype.getDirection = function(result) +{ + if (result === undefined) + { + result = new Point3D(); + } + + result = this.getVector(result); + result.unitary(); + + return result; +}; + +/** + * 시작 포인트와 종료 포인트를 맞바꾼다. + * interchange strPoint & endPoint. + */ +Segment3D.prototype.invertSense = function() +{ + var point3dAux = this.startPoint3d; + this.startPoint3d = this.endPoint3d; + this.endPoint3d = point3dAux; +}; +'use strict'; + +/** + * '별(star)'모양 폴리곤 객체 + * @exception {Error} Messages.CONSTRUCT_ERROR + * + * @class Star2D + */ +var Star2D = function() +{ + if (!(this instanceof Star2D)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + + // this is a closed element. + /** + * center of star + * @type {Point2D} + */ + this.centerPoint; // Point3D. + + /** + * interior radius + * @type {Number} + */ + this.interiorRadius; + /** + * exterior radius + * @type {Number} + */ + this.exteriorRadius; + + /** + * 별꼭지점 갯수 + * @type {Number} + */ + this.radiusCount; +}; + +/** + * star의 중심점 설정 + * @param {number} cx + * @param {number} cy + */ +Star2D.prototype.setCenterPosition = function(cx, cy) +{ + if (this.centerPoint === undefined) + { this.centerPoint = new Point2D(); } + + this.centerPoint.set(cx, cy); +}; + +/** + * star의 interior radius 설정 + * @param {number} radius + */ +Star2D.prototype.setInteriorRadius = function(radius) +{ + this.interiorRadius = radius; +}; + +/** + * star의 exterior radius 설정 + * @param {number} radius + */ +Star2D.prototype.setExteriorRadius = function(radius) +{ + this.exteriorRadius = radius; +}; + +/** + * star의 꼭지점 갯수 설정 + * @param {number} radiusCount + */ +Star2D.prototype.setRadiusCount = function(radiusCount) +{ + this.radiusCount = radiusCount; +}; + +/** + * star의 꼭지점 배열 반환 + * @param {Array.} resultPointsArray + * @returns {Array.} + */ +Star2D.prototype.getPoints = function(resultPointsArray) +{ + // star has an arrow to up. + var increAngDeg = 360 / this.radiusCount; + var increAngRad = increAngDeg * Math.PI/180; + var halfIncreAngRad = increAngRad / 2; + var startAngRad = 90 * Math.PI/180; + var currAngRad = startAngRad; + var point; + var x, y; + + if (resultPointsArray === undefined) + { resultPointsArray = []; } + + for (var i=0; itrue + * 동일한 Face 가 존재하지 않으면 false + */ +Surface.setTwinsFacesBetweenFaceAndFacesArrays = function(face, facesArray, bIsRegularQuadGrid) +{ + // if the faces pertains a regular-quad-grid, + // then there are only ONE twin between the "face" & the "facesArray". + if (facesArray === undefined) + { + return false; + } + + var twined = false; + for (var i=0, len=facesArray.length; itrue + * 동일한 Face 가 존재하지 않으면 false + */ +Surface.setTwinsFacesBetweenFacesArrays_regularQuadGrid = function(facesA, facesB) +{ + // Faces are rectangles in a rectangle grid. + if (facesA === undefined || facesB === undefined) + { + return false; + } + + var faceA, faceB; + for (var i=0, len=facesA.length-1; itrue Plane 노말을 사용한다. + * false Plane 노말을 사용하지 않는다. + */ +Surface.prototype.calculateVerticesNormals = function(bForceRecalculatePlaneNormal) +{ + var face; + var facesCount = this.getFacesCount(); + for (var i=0; i} + */ + this.vertexArray = []; +}; + +/** + * get previus index of vertexArray + * @static + * @param {Number} idx index must bigger than 0, less than vertexArray length. + * @param {Array.} vertexArray + * @returns {Number} prevIdx. if idx is 0, return vertexArray.length - 1. + */ +VertexList.getPrevIdx = function(idx, vertexArray) +{ + var verticesCount = vertexArray.length; + + if (idx < 0 || idx > verticesCount-1) + { return undefined; } + + var prevIdx; + + if (idx === 0) + { prevIdx = verticesCount - 1; } + else + { prevIdx = idx - 1; } + + return prevIdx; +}; + +/** + * get next index of vertexArray + * @static + * @param {Number} idx index must bigger than 0, less than vertexArray length. + * @param {Array.} vertexArray + * @returns {Number} nextIdx. if idx is equal vertexArray.length - 1, return 0. + */ +VertexList.getNextIdx = function(idx, vertexArray) +{ + var verticesCount = vertexArray.length; + + if (idx < 0 || idx > verticesCount-1) + { return undefined; } + + var nextIdx; + + if (idx === verticesCount - 1) + { nextIdx = 0; } + else + { nextIdx = idx + 1; } + + return nextIdx; +}; + +/** + * get vertex segment. This segment is consist of indexed vertex and next vertex + * @static + * @param {Number} idx index + * @param {Array.} vertexArray + * @param {VtxSegment} resultVtxSegment if resultVtxSegment is undefined, resultVtxSegment set new VtxSegemnt instance. + * @returns {VtxSegment} resultVtxSegment + */ +VertexList.getVtxSegment = function(idx, vertexArray, resultVtxSegment) +{ + var currVertex = vertexArray[idx]; + var nextIdx = VertexList.getNextIdx(idx, vertexArray); + var nextVertex = vertexArray[nextIdx]; + + if (resultVtxSegment === undefined) + { resultVtxSegment = new VtxSegment(currVertex, nextVertex); } + else + { + resultVtxSegment.setVertices(currVertex, nextVertex); + } + + return resultVtxSegment; +}; + +/** + * get vertex vector. This vector is consist of indexed vertex and next vertex + * @static + * @param {Number} idx index + * @param {Array.} vertexArray + * @param {Point3D} resultVector if resultVector is undefined, resultVector set new Point3D instance. + * @returns {Point3D} resultVector + */ +VertexList.getVector = function(idx, vertexArray, resultVector) +{ + var currVertex = vertexArray[idx]; + var nextIdx = VertexList.getNextIdx(idx, vertexArray); + var nextVertex = vertexArray[nextIdx]; + + var currPoint = currVertex.point3d; + var nextPoint = nextVertex.point3d; + + if (resultVector === undefined) + { resultVector = new Point3D(nextPoint.x - currPoint.x, nextPoint.y - currPoint.y, nextPoint.z - currPoint.z); } + else + { + resultVector.setVertices(nextPoint.x - currPoint.x, nextPoint.y - currPoint.y, nextPoint.z - currPoint.z); + } + + return resultVector; +}; + +/** + * get vertex direction. vertex vector's unitary. + * @static + * @param {Number} idx index + * @param {Array.} vertexArray + * @param {Point3D} resultDir point3d unitary. + * @returns {Point3D} + */ +VertexList.getDirection = function(idx, vertexArray, resultDir) +{ + resultDir = VertexList.getVector(idx, vertexArray, resultDir); + resultDir.unitary(); + return resultDir; +}; + +/** + * get crossproduct. This crossproduct is consist of indexed vertex and prev vertex + * @deprecated + * @static + * @param {Number} idx index + * @param {Array.} vertexArray + * @param {Point3D} resultCrossProduct + * @returns {Point3D} + */ +VertexList.getCrossProduct = function(idx, vertexArray, resultCrossProduct) +{ + var currVector = VertexList.getVector(idx, vertexArray, undefined); + var prevIdx = VertexList.getPrevIdx(idx, vertexArray); + var prevVector = VertexList.getVector(prevIdx, vertexArray, undefined); + resultCrossProduct = prevVector.crossProduct(currVector, resultCrossProduct); + + return resultCrossProduct; +}; + +/** + * get vertex list. this vertex is projected onto plane. + * @static + * @param {Array.} vertexArray if vertexArray is undefined, return resultVertexList + * @param {Plane} plane. + * @param {Point3D} projectionDirection projectionDirection must be unitary. + * @param {VertexList} resultVertexList if resultVertexList is undefined, resultVector set new VertexList instance. + * @returns {VertexList} + * + * @see Vertex#getProjectedOntoPlane + */ +VertexList.getProjectedOntoPlane = function(vertexList, plane, projectionDirection, resultVertexList) +{ + if (vertexList === undefined) + { return resultVertexList; } + + if (resultVertexList === undefined) + { resultVertexList = new VertexList(); } + + var vertex, projectedVertex; + var vertexCount = vertexList.getVertexCount(); + for (var i=0; i} vertexArray if vertexArray is undefined, return resultPoints2dArray + * @param {Point3D} normal. + * @param {Array.} resultPoints2dArray array. + * @returns {Array.} resultPoints2dArray + */ +VertexList.getProjectedPoints2DArray = function(vertexArray, normal, resultPoints2dArray) +{ + // This function projects the vertices on to planes xy, yz or xz. + if (vertexArray === undefined) + { return resultPoints2dArray; } + + if (resultPoints2dArray === undefined) + { resultPoints2dArray = []; } + + var bestPlaneToProject = Face.getBestFacePlaneToProject(normal); + + var point2d; + var verticesCount = vertexArray.length; + // Project this face into the bestPlane. + if (bestPlaneToProject === 0) // plane-xy. + { + // project this face into a xy plane. + for (var i=0; i 0) + { point2d = new Point2D(point3d.x, point3d.y); } + else + { point2d = new Point2D(point3d.x, -point3d.y); } + point2d.ownerVertex3d = vertex; // with this we can reconvert polygon2D to face3D. + resultPoints2dArray.push(point2d); + } + } + else if (bestPlaneToProject === 1) // plane-yz. + { + // project this face into a yz plane. + for (var i=0; i 0) + { point2d = new Point2D(point3d.y, point3d.z); } + else + { point2d = new Point2D(-point3d.y, point3d.z); } + point2d.ownerVertex3d = vertex; // with this we can reconvert polygon2D to face3D. + resultPoints2dArray.push(point2d); + } + } + else if (bestPlaneToProject === 2) // plane-xz. + { + // project this face into a xz plane. + for (var i=0; i 0) + { point2d = new Point2D(-point3d.x, point3d.z); } + else + { point2d = new Point2D(point3d.x, point3d.z); } + point2d.ownerVertex3d = vertex; // with this we can reconvert polygon2D to face3D. + resultPoints2dArray.push(point2d); + } + } + + return resultPoints2dArray; +}; + +/** + * delete all vertex. + */ +VertexList.prototype.deleteObjects = function() +{ + for (var i = 0, vertexCount = this.vertexArray.length; i < vertexCount; i++) + { + this.vertexArray[i].deleteObjects(); + this.vertexArray[i] = undefined; + } + this.vertexArray = undefined; +}; + +/** + * Copy vertex list from another vertexList. + * @param {VertexList} vertexList + */ +VertexList.prototype.copyFrom = function(vertexList) +{ + // first reset vertexArray. + this.deleteObjects(); + this.vertexArray = []; + + var vertex; + var myVertex; + var vertexCount = vertexList.getVertexCount(); + for (var i=0; i} point3dArray Required. + */ +VertexList.prototype.copyFromPoint3DArray = function(point3dArray) +{ + if (point3dArray === undefined) + { return; } + + // first reset vertexArray. + this.deleteObjects(); + this.vertexArray = []; + + var point3d; + var vertex; + + var pointsCount = point3dArray.length; + for (var i=0; i} + */ + this.vertexListsArray = []; + // SCTRATXH. + + /** + * All Vertex array + * @instance + * @type {Array.} + */ + this.totalVertexArraySC = []; +}; + +/** + * delete all vertex. + */ +VertexMatrix.prototype.deleteObjects = function() +{ + for (var i = 0, vertexListsCount = this.vertexListsArray.length; i < vertexListsCount; i++) + { + this.vertexListsArray[i].deleteObjects(); + this.vertexListsArray[i] = undefined; + } + this.vertexListsArray = undefined; +}; + +/** + * add vertex list and return. + * @returns {VertexList}} + */ +VertexMatrix.prototype.newVertexList = function() +{ + var vertexList = new VertexList(); + this.vertexListsArray.push(vertexList); + return vertexList; +}; + +/** + * get vertex list + * @param {Number }idx + * @returns {VertextList|undefined} if invalid idx, return undefined + */ +VertexMatrix.prototype.getVertexList = function(idx) +{ + if (idx >= 0 && idx < this.vertexListsArray.length) + { + return this.vertexListsArray[idx]; + } + else + { + return undefined; + } +}; + +/** + * copy from another vertex matrix. + * @param {VertexMatrix} vertexMatrix Required. + */ +VertexMatrix.prototype.copyFrom = function(vertexMatrix) +{ + if (vertexMatrix === undefined) + { return; } + + var vertexList, myVertexList; + var vertexListsCount = vertexMatrix.vertexListsArray.length; + for (var i=0; i} + */ +VertexMatrix.prototype.getTotalVertexArray = function(resultTotalVertexArray) +{ + for (var i = 0, vertexListsCount = this.vertexListsArray.length; i < vertexListsCount; i++) + { + var vtxList = this.vertexListsArray[i]; + for (var j = 0, vertexCount = vtxList.vertexArray.length; j < vertexCount; j++) + { + var vertex = vtxList.getVertex(j); + resultTotalVertexArray.push(vertex); + } + } + + return resultTotalVertexArray; +}; + +/** + * get vertex color float array. + * @param {Float32Array} resultFloatArray if this is undefined, set new Float32Array instance. length = this.totalVertexArraySC.length*6 + * @returns {Float32Array} + */ +VertexMatrix.prototype.getVBOVertexColorFloatArray = function(resultFloatArray) +{ + this.totalVertexArraySC.length = 0; + this.totalVertexArraySC = this.getTotalVertexArray(this.totalVertexArraySC); + + var totalVertexCount = this.totalVertexArraySC.length; + if (resultFloatArray === undefined) { resultFloatArray = new Float32Array(totalVertexCount * 6); } + + for (var i = 0; i < totalVertexCount; i++) + { + var vertex = this.totalVertexArraySC[i]; + resultFloatArray[i*6] = vertex.point3d.x; + resultFloatArray[i*6+1] = vertex.point3d.y; + resultFloatArray[i*6+2] = vertex.point3d.z; + + resultFloatArray[i*6+3] = vertex.color4.r; + resultFloatArray[i*6+4] = vertex.color4.g; + resultFloatArray[i*6+5] = vertex.color4.b; + } + + return resultFloatArray; +}; + +/** + * get vertex color with alpha float array. + * @param {Float32Array} resultFloatArray if this is undefined, set new Float32Array instance. length = this.totalVertexArraySC.length*7 + * @returns {Float32Array} + */ +VertexMatrix.prototype.getVBOVertexColorRGBAFloatArray = function(resultFloatArray) +{ + this.totalVertexArraySC.length = 0; + this.totalVertexArraySC = this.getTotalVertexArray(this.totalVertexArraySC); + + var totalVertexCount = this.totalVertexArraySC.length; + if (resultFloatArray === undefined) { resultFloatArray = new Float32Array(totalVertexCount * 7); } + + for (var i = 0; i < totalVertexCount; i++) + { + var vertex = this.totalVertexArraySC[i]; + resultFloatArray[i*7] = vertex.point3d.x; + resultFloatArray[i*7+1] = vertex.point3d.y; + resultFloatArray[i*7+2] = vertex.point3d.z; + + resultFloatArray[i*7+3] = vertex.color4.r; + resultFloatArray[i*7+4] = vertex.color4.g; + resultFloatArray[i*7+5] = vertex.color4.b; + resultFloatArray[i*7+6] = vertex.color4.a; + } + + return resultFloatArray; +}; + +/** + * get vertex basic float array. + * @param {Float32Array} resultFloatArray if this is undefined, set new Float32Array instance. length = this.totalVertexArraySC.length*3 + * @returns {Float32Array} + */ +VertexMatrix.prototype.getVBOVertexFloatArray = function(resultFloatArray) +{ + this.totalVertexArraySC.length = 0; + this.totalVertexArraySC = this.getTotalVertexArray(this.totalVertexArraySC); + + var totalVertexCount = this.totalVertexArraySC.length; + if (resultFloatArray === undefined) { resultFloatArray = new Float32Array(totalVertexCount * 3); } + + for (var i = 0; i < totalVertexCount; i++) + { + var vertex = this.totalVertexArraySC[i]; + resultFloatArray[i*3] = vertex.point3d.x; + resultFloatArray[i*3+1] = vertex.point3d.y; + resultFloatArray[i*3+2] = vertex.point3d.z; + } + + return resultFloatArray; +}; + +/** + * translate vertex in vertex matrix + * @param {Number} dx + * @param {Number} dy + * @param {Number} dz + */ +VertexMatrix.prototype.translateVertices = function(dx, dy, dz) +{ + for (var i = 0, vertexListsCount = this.vertexListsArray.length; i < vertexListsCount; i++) + { + this.vertexListsArray[i].translateVertices(dx, dy, dz); + } +}; + +/** + * set TTrianglesMatrix using vertexMatrix. + * OLD function. Used for shadow blending cube. OLD. + * TTriangles provisional is in geometryUtils. + * condition: all the vertex lists must have the same number of vertex. + * @param {TTrianglesMatrix} tTrianglesMatrix + */ +VertexMatrix.prototype.makeTTrianglesLateralSidesLOOP = function(tTrianglesMatrix) +{ + // + var vtxList1; + var vtxList2; + var tTrianglesList; + var tTriangle1; + var tTriangle2; + var vertexCount = 0; + for (var i = 0, vertexListsCount = this.vertexListsArray.length; i < vertexListsCount-1; i++) + { + vtxList1 = this.vertexListsArray[i]; + vtxList2 = this.vertexListsArray[i+1]; + tTrianglesList = tTrianglesMatrix.newTTrianglesList(); + + vertexCount = vtxList1.vertexArray.length; + for (var j = 0; j < vertexCount; j++) + { + tTriangle1 = tTrianglesList.newTTriangle(); + tTriangle2 = tTrianglesList.newTTriangle(); + + if (j === vertexCount-1) + { + tTriangle1.setVertices(vtxList1.getVertex(j), vtxList2.getVertex(j), vtxList2.getVertex(0)); + tTriangle2.setVertices(vtxList1.getVertex(j), vtxList2.getVertex(0), vtxList1.getVertex(0)); + } + else + { + tTriangle1.setVertices(vtxList1.getVertex(j), vtxList2.getVertex(j), vtxList2.getVertex(j+1)); + tTriangle2.setVertices(vtxList1.getVertex(j), vtxList2.getVertex(j+1), vtxList1.getVertex(j+1)); + } + } + } +}; + +/** + * get vertex matrix. using data array. + * @deprecated + * @static + * @param {Array.} positions3Array Required. + * @param {Array.} normals3Array + * @param {Array.} texCoords2Array + * @param {Array.} colors4Array + * @param {Number} numCols + * @param {Number} numRows + * @param {VertexMatrix} resultVertexMatrix if undefined, set new VertexMatrix instance. + * @returns {VertexMatrix} + */ +VertexMatrix.makeMatrixByDataArray = function(positions3Array, normals3Array, texCoords2Array, colors4Array, numCols, numRows, resultVertexMatrix) +{ + if (positions3Array === undefined) + { return; } + + if (resultVertexMatrix === undefined) + { resultVertexMatrix = new VertexMatrix(); } + + var vertexList; + var vertex; + var px, py, pz; + var nx, ny, nz; + var tx, ty; + var r, g, b, a; + for (var r=0; r} resultFacesArray + * @param {Boolean} bLoop + * @param {Boolean} bClockWise + * @returns {VertexMatrix} + */ +VertexMatrix.makeFacesBetweenVertexLists = function(vertexListDown, vertexListUp, resultFacesArray, bLoop, bClockWise) +{ + if (resultFacesArray === undefined) + { resultFacesArray = []; } + + var face_A, face_B; + var hedge_A, hedge_B; + var faceLast_B; + var vertexCount = vertexListDown.vertexArray.length; + var vertex_0, vertex_1, vertex_2, vertex_3; + if (bClockWise === undefined) + { bClockWise = false; } + + var resultHalfEdgesArray_A = []; + var resultHalfEdgesArray_B = []; + var vtx0_idx, vtx1_idx, vtx2_idx, vtx3_idx; + + if (bClockWise) + { + for (var j = 0; j < vertexCount; j++) + { + resultHalfEdgesArray_A.length = 0; + resultHalfEdgesArray_B.length = 0; + if (j < vertexCount-1) + { + vertex_0 = vertexListDown.getVertex(j); + vertex_1 = vertexListDown.getVertex(j+1); + vertex_2 = vertexListUp.getVertex(j+1); + vertex_3 = vertexListUp.getVertex(j); + + face_A = new Face(); + face_B = new Face(); + + face_A.addVerticesArray([vertex_0, vertex_3, vertex_1]); + //resultHalfEdgesArray_A = face_A.createHalfEdges(resultHalfEdgesArray_A); + //hedge_A = resultHalfEdgesArray_A[1]; // Diagonal hedge of face_A. + + face_B.addVerticesArray([vertex_1, vertex_3, vertex_2]); + //resultHalfEdgesArray_B = face_B.createHalfEdges(resultHalfEdgesArray_B); + //hedge_B = resultHalfEdgesArray_B[2]; // Diagonal hedge of face_B. + + // Now, set twins between face_A & face_B. + //hedge_A.setTwin(hedge_B); + resultFacesArray.push(face_A); + resultFacesArray.push(face_B); + } + else + { + if (bLoop !== undefined && bLoop === true) + { + vertex_0 = vertexListDown.getVertex(j); + vertex_1 = vertexListDown.getVertex(0); + vertex_2 = vertexListUp.getVertex(0); + vertex_3 = vertexListUp.getVertex(j); + + face_A = new Face(); + face_B = new Face(); + + face_A.addVerticesArray([vertex_0, vertex_3, vertex_1]); + //resultHalfEdgesArray_A = face_A.createHalfEdges(resultHalfEdgesArray_A); + //hedge_A = resultHalfEdgesArray_A[1]; // Diagonal hedge of face_A. + + face_B.addVerticesArray([vertex_1, vertex_3, vertex_2]); + //resultHalfEdgesArray_B = face_B.createHalfEdges(resultHalfEdgesArray_B); + //hedge_B = resultHalfEdgesArray_B[2]; // Diagonal hedge of face_B. + + // Now, set twins between face_A & face_B. + //hedge_A.setTwin(hedge_B); + resultFacesArray.push(face_A); + resultFacesArray.push(face_B); + } + } + + if (faceLast_B === undefined) + { faceLast_B = face_B; } + else + { + //face_A.setTwinFace(faceLast_B); + faceLast_B = face_B; + } + + + } + } + else + { + for (var j = 0; j < vertexCount; j++) + { + resultHalfEdgesArray_A.length = 0; + resultHalfEdgesArray_B.length = 0; + + if (j < vertexCount - 1) + { + vertex_0 = vertexListDown.getVertex(j); + vertex_1 = vertexListDown.getVertex(j+1); + vertex_2 = vertexListUp.getVertex(j+1); + vertex_3 = vertexListUp.getVertex(j); + + face_A = new Face(); + face_B = new Face(); + + face_A.addVerticesArray([vertex_0, vertex_1, vertex_3]); + //resultHalfEdgesArray_A = face_A.createHalfEdges(resultHalfEdgesArray_A); + //hedge_A = resultHalfEdgesArray_A[1]; // Diagonal hedge of face_A. + + face_B.addVerticesArray([vertex_1, vertex_2, vertex_3]); + //resultHalfEdgesArray_B = face_B.createHalfEdges(resultHalfEdgesArray_B); + //hedge_B = resultHalfEdgesArray_B[2]; // Diagonal hedge of face_B. + + // Now, set twins between face_A & face_B. + //hedge_A.setTwin(hedge_B); + + resultFacesArray.push(face_A); + resultFacesArray.push(face_B); + } + else + { + if (bLoop !== undefined && bLoop === true) + { + vertex_0 = vertexListDown.getVertex(j); + vertex_1 = vertexListDown.getVertex(0); + vertex_2 = vertexListUp.getVertex(0); + vertex_3 = vertexListUp.getVertex(j); + + face_A = new Face(); + face_B = new Face(); + + face_A.addVerticesArray([vertex_0, vertex_1, vertex_3]); + //resultHalfEdgesArray_A = face_A.createHalfEdges(resultHalfEdgesArray_A); + //hedge_A = resultHalfEdgesArray_A[1]; // Diagonal hedge of face_A. + + face_B.addVerticesArray([vertex_1, vertex_2, vertex_3]); + //resultHalfEdgesArray_B = face_B.createHalfEdges(resultHalfEdgesArray_B); + //hedge_B = resultHalfEdgesArray_B[2]; // Diagonal hedge of face_B. + + // Now, set twins between face_A & face_B. + //hedge_A.setTwin(hedge_B); + + resultFacesArray.push(face_A); + resultFacesArray.push(face_B); + } + + } + + if (faceLast_B === undefined) + { faceLast_B = face_B; } + else + { + //face_A.setTwinFace(faceLast_B); + faceLast_B = face_B; + } + + + } + } + + return resultFacesArray; +}; + +/** +* make Surface +* condition: all the vertex lists must have the same number of vertex. +* @deprecated +* @static +* @param {VertexMatrix} vertexMatrix +* @param {Surface} resultSurface if undefined, set new Surface instance. +* @param {Boolean} bLoop +* @param {Boolean} bClockWise +* @returns {Surface} +*/ +VertexMatrix.makeSurface = function(vertexMatrix, resultSurface, bLoop, bClockWise) +{ + if (resultSurface === undefined) + { resultSurface = new Surface(); } + + var vtxList1; + var vtxList2; + var vertexListDown, vertexListUp; + var resultFacesArray = []; + var resultFacesArrayLast; + var vertexCount = 0; + var vertexListsCount = vertexMatrix.vertexListsArray.length; + for (var i = 0; i 0) + { + innerRingsList = resultProfile2d.getInnerRingsList(); + } + + for (var i=0; i} outerPoints3dArray Required. + * @param {Array.>} innerPoints3dArrayArray deprecated. + * + * @see VtxRing#makeByPoints3DArray + */ +VtxProfile.prototype.makeByPoints3DArray = function(outerPoints3dArray, innerPoints3dArrayArray) +{ + if (outerPoints3dArray === undefined) + { return; } + + // outer. + if (this.outerVtxRing === undefined) + { this.outerVtxRing = new VtxRing(); } + + this.outerVtxRing.makeByPoints3DArray(outerPoints3dArray); + + // inners. + // todo: +}; + +/** + * use point3d array, update outerVtxRing's vertex list. + * @param {Array.} point3dArray Required. + * @param {Array.>} innerPoints3dArrayArray deprecated. + * + * @see VtxRing#makeByPoints3DArray + */ +VtxProfile.prototype.updateByPoints3DArray = function(outerPoints3dArray, innerPoints3dArrayArray) +{ + if (outerPoints3dArray === undefined) + { return; } + + // outer. + if (this.outerVtxRing === undefined) + { return; } + + this.outerVtxRing.updateByPoints3DArray(outerPoints3dArray); + + // inners. + // todo: +}; + +/** + * use Profile2D, make VtxProfile's outer vertex ring and inner vertex ring list. + * z is always 0. + * @param {Profile2D} profile2d Required. + * + * @see VtxRing#makeByPoint2DList + */ +VtxProfile.prototype.makeByProfile2D = function(profile2d) +{ + if (profile2d === undefined || profile2d.outerRing === undefined) + { return undefined; } + + var outerRing = profile2d.outerRing; + if (outerRing.polygon === undefined) + { outerRing.makePolygon(); } + + // outer. + if (this.outerVtxRing === undefined) + { this.outerVtxRing = new VtxRing(); } + + var z = 0; + var outerPolygon = outerRing.polygon; + var point2dList = outerPolygon.point2dList; + this.outerVtxRing.makeByPoint2DList(point2dList, z); + + // inners. + if (profile2d.innerRingsList === undefined) + { return; } + + var innerRingsList = profile2d.innerRingsList; + var innerRingsCount = innerRingsList.getRingsCount(); + + if (innerRingsCount === 0) + { return; } + + if (this.innerVtxRingsList === undefined) + { this.innerVtxRingsList = new VtxRingsList(); } + + var innerRing; + var innerPolygon; + var innerVtxRing; + + for (var i=0; i|undefined} + */ +VtxProfile.prototype.getAllVertices = function(resultVerticesArray) +{ + if (this.outerVtxRing !== undefined) + { this.outerVtxRing.getAllVertices(resultVerticesArray); } + + if (this.innerVtxRingsList !== undefined) + { this.innerVtxRingsList.getAllVertices(resultVerticesArray); } + + return resultVerticesArray; +}; + +/** + * get vertex intersected with plane. + * @static + * @param {VtxProfile} vtxProfile if vtxProfile.outerVtxRing undefined, return resultvtxProfile. + * @param {Plane} plane. + * @param {Point3D} projectionDirection projectionDirection must be unitary. + * @param {VtxProfile} resultvtxProfile Optional. if undefined, set new VtxProfile instance. + * @returns {VtxProfile} resultvtxProfile + */ +VtxProfile.getProjectedOntoPlane = function(vtxProfile, plane, projectionDirection, resultvtxProfile) +{ + if (vtxProfile.outerVtxRing === undefined) + { return resultvtxProfile; } + + if (resultvtxProfile === undefined) + { resultvtxProfile = new VtxProfile(); } + + // OuterVtxRing. + resultvtxProfile.outerVtxRing = VtxRing.getProjectedOntoPlane(vtxProfile.outerVtxRing, plane, projectionDirection, resultvtxProfile.outerVtxRing); + + // InnerVtxRings. + if (vtxProfile.innerVtxRingsList !== undefined) + { + resultvtxProfile.innerVtxRingsList = VtxRingsList.getProjectedOntoPlane(vtxProfile.innerVtxRingsList, plane, projectionDirection, resultvtxProfile.innerVtxRingsList); + } + + return resultvtxProfile; +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +'use strict'; +/** +* Vertex Profile List +* @exception {Error} Messages.CONSTRUCT_ERROR + +* @class VtxProfilesList + +* @param {number} x not used +* @param {number} y not used +* +* @see VtxProfile +*/ +var VtxProfilesList = function(x, y) +{ + if (!(this instanceof VtxProfilesList)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + + /** + * VtxProfile Array + * @type {Array.} + */ + this.vtxProfilesArray; + + + /** + * convex index data array + * @type {Array.>} + */ + this.convexFacesIndicesData; +}; + + +/** + * delete vertex profile and convex array. + */ +VtxProfilesList.prototype.deleteObjects = function() +{ + if (this.vtxProfilesArray !== undefined) + { + var vtxProfilesCount = this.vtxProfilesArray.length; + for (var i=0; i} resultFacesArray + * @param {Mesh} resultMesh + * @param {IndexRange} elemIndexRange + * + * @see VtxProfilesList#getMesh + * @see Mesh#getHalfEdgesList + * @see Face#createHalfEdges + * @see Face#setTwinFace + * @see HalfEdgesList#addHalfEdgesArray + */ +VtxProfilesList.getLateralFaces = function(bottomVtxRing, topVtxRing, resultFacesArray, resultMesh, elemIndexRange) +{ + // This returns a lateral surface between "bottomVtxRing" & "topVtxRing" limited by "elemIndexRange". + if (resultFacesArray === undefined) + { resultFacesArray = []; } + + var hedgesList = resultMesh.getHalfEdgesList(); + + var strIdx, currIdx, endIdx, nextIdx; + var vtx0, vtx1, vtx2, vtx3; + var face, prevFace; + var hedgesArray = []; + currIdx = elemIndexRange.strIdx; + while (currIdx !== elemIndexRange.endIdx) + { + nextIdx = bottomVtxRing.vertexList.getNextIdx(currIdx); + + face = new Face(); + resultFacesArray.push(face); + face.vertexArray = []; + + vtx0 = bottomVtxRing.vertexList.getVertex(currIdx); + vtx1 = bottomVtxRing.vertexList.getVertex(nextIdx); + vtx2 = topVtxRing.vertexList.getVertex(nextIdx); + vtx3 = topVtxRing.vertexList.getVertex(currIdx); + Array.prototype.push.apply(face.vertexArray, [vtx0, vtx1, vtx2, vtx3]); + + // now create hedges of the face. + hedgesArray.length = 0; + hedgesArray = face.createHalfEdges(hedgesArray); + hedgesList.addHalfEdgesArray(hedgesArray); + + if (prevFace !== undefined) + { + // set twins between face and prevFace. + face.setTwinFace(prevFace); + } + prevFace = face; + + currIdx = nextIdx; + } + + return resultFacesArray; +}; + +/** + * VtxProfile 추가 + * @param {VtxProfile} vtxProfile + */ +VtxProfilesList.prototype.addVtxProfile = function(vtxProfile) +{ + if (this.vtxProfilesArray === undefined) + { this.vtxProfilesArray = []; } + + this.vtxProfilesArray.push(vtxProfile); +}; + +/** + * VtxProfile 생성하여 vtxProfileArray에 추가 후 반환. + * @returns {VtxProfile} vtxProfile + */ +VtxProfilesList.prototype.newVtxProfile = function() +{ + if (this.vtxProfilesArray === undefined) + { this.vtxProfilesArray = []; } + + var vtxProfile = new VtxProfile(); + this.vtxProfilesArray.push(vtxProfile); + return vtxProfile; +}; + +/** + * vtxProfileArray length 반환. + * @returns {Number} + */ +VtxProfilesList.prototype.getVtxProfilesCount = function() +{ + if (this.vtxProfilesArray === undefined) + { return 0; } + + return this.vtxProfilesArray.length; +}; + +/** + * 인덱스에 해당하는 vtxProfile 반환 + * @returns {VtxProfile} + */ +VtxProfilesList.prototype.getVtxProfile = function(idx) +{ + if (this.vtxProfilesArray === undefined) + { return undefined; } + + return this.vtxProfilesArray[idx]; +}; + +/** + * vtxProfileArray에 있는 모든 vertex를 배열에 담아 반환 + * @param {Array.|undefined} resultVerticesArray 비어있을 시 배열 초기화. + * @returns {Array.} + */ +VtxProfilesList.prototype.getAllVertices = function(resultVerticesArray) +{ + // collect all vertices of all vtxProfiles. + if (resultVerticesArray === undefined) + { resultVerticesArray = []; } + + var vtxProfile; + var vtxProfilesCount = this.getVtxProfilesCount(); + for (var i=0; i 0) + { + // set twins between "prevFacesArray" & "facesArray". + var currFace, prevFace; + var facesCount = facesArray.length; + for (var k=0; k0) + { + // set twins between "prevFacesArray" & "facesArray". + var currFace, prevFace; + var facesCount = facesArray.length; + for (var a=0; a} convexFacesIndicesData + * @param {Surface} resultSurface 비어있을 시 Surface 인스턴스 선언. + * @returns {Surface} + */ +VtxProfilesList.getTransversalSurface = function(vtxProfile, convexFacesIndicesData, resultSurface) +{ + if (resultSurface === undefined) + { resultSurface = new Surface(); } + + var currRing; + var currVtxRing; + var faceIndicesData; + var indexData; + var ringIdx, vertexIdx; + var indicesCount; + var face; + var vertex; + var convexFacesCount = convexFacesIndicesData.length; + for (var i=0; i} + */ + this.elemsIndexRangesArray; +}; + +/** + * delete all vertex and element index ranges. + */ +VtxRing.prototype.deleteObjects = function() +{ + if (this.vertexList !== undefined) + { + this.vertexList.deleteObjects(); + this.vertexList = undefined; + } + + if (this.elemsIndexRangesArray !== undefined) + { + this.deleteElementIndexRanges(); + } +}; + +/** + * delete all element index ranges. + */ +VtxRing.prototype.deleteElementIndexRanges = function() +{ + if (this.elemsIndexRangesArray === undefined) + { return; } + + var indexRangesCount = this.elemsIndexRangesArray.length; + for (var i=0; i|undefined} if this.vertexList is undefined or this.vertexList.vertexArray is undefined, return resultVerticesArray. + */ +VtxRing.prototype.getAllVertices = function(resultVerticesArray) +{ + if (this.vertexList === undefined || this.vertexList.vertexArray === undefined) + { return resultVerticesArray; } + + if (resultVerticesArray === undefined) + { resultVerticesArray = []; } + + resultVerticesArray.push.apply(resultVerticesArray, this.vertexList.vertexArray); + + return resultVerticesArray; +}; + +/** + * vertex ring copy from another vertex ring. + * @param {VtxRing} vtxRing + */ +VtxRing.prototype.copyFrom = function(vtxRing) +{ + if (vtxRing.vertexList !== undefined) + { + if (this.vertexList === undefined) + { this.vertexList = new VertexList(); } + + this.vertexList.copyFrom(vtxRing.vertexList); + } + + if (vtxRing.elemsIndexRangesArray !== undefined) + { + if (this.elemsIndexRangesArray === undefined) + { this.elemsIndexRangesArray = []; } + + var indexRange, myIndexRange; + var indexRangesCount = vtxRing.elemsIndexRangesArray.length; + for (var i=0; i} point3dArray Required. + * + * @see VertexList#copyFromPoint3DArray + */ +VtxRing.prototype.makeByPoints3DArray = function(point3dArray) +{ + if (point3dArray === undefined) + { return; } + + if (this.vertexList === undefined) + { this.vertexList = new VertexList(); } + + this.vertexList.copyFromPoint3DArray(point3dArray); + this.calculateElementsIndicesRange(); +}; + +/** + * use point3d array, update VtxRing's vertex list. + * @param {Array.} point3dArray Required. + * + * @see VertexList#copyFromPoint3DArray + */ +VtxRing.prototype.updateByPoints3DArray = function(point3dArray) +{ + // Note: point3dCount must be equal to this.verticesCount. + if (point3dArray === undefined) + { return; } + + if (this.vertexList === undefined) + { this.vertexList = new VertexList(); } + + var vertex; + var point3d; + var position; + var points3dCount = point3dArray.length; + for (var i=0; i} + */ + this.vtxRingsArray; +}; + +/** + * delete all vertex and element index ranges. + */ +VtxRingsList.prototype.deleteObjects = function() +{ + if (this.vtxRingsArray !== undefined) + { + var vtxRingsCount = this.vtxRingsArray.length; + for (var i=0; i|undefined} if this.vtxRingsArray is undefined, return resultVerticesArray. + */ +VtxRingsList.prototype.getAllVertices = function(resultVerticesArray) +{ + if (this.vtxRingsArray === undefined) + { return resultVerticesArray; } + + var vtxRingsCount = this.getVtxRingsCount(); + for (var i=0; i distTotal || distB> distTotal) + { + return Constant.INTERSECTION_OUTSIDE; + } + + if (Math.abs(distA + distB - distTotal) < error) + { return Constant.INTERSECTION_INSIDE; } +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +'use strict'; + +/** + * 메세지 + * + * @class + */ +var Message = function(i18next, message) +{ + this.handle = i18next; + this.message = message || MessageSource; +}; + +/** + * 메세지 클래스 초기화 + * + * @param {Function} callback + */ +Message.prototype.init = function (callback) +{ + var h = this.handle; + this.handle.use(i18nextXHRBackend) + .use(i18nextBrowserLanguageDetector) + .init({ + // Useful for debuging, displays which key is missing + debug: false, + + detection: { + // keys or params to lookup language from + lookupQuerystring : 'lang', + lookupCookie : 'i18nextLang', + lookupLocalStorage : 'i18nextLang', + }, + + // If translation key is missing, which lang use instead + fallbackLng: 'en', + + resources: this.message, + + // all, languageOnly + load: "languageOnly", + + ns : ['common'], + // Namespace to use by default, when not indicated + defaultNS : 'common', + + keySeparator : ".", + nsSeparator : ":", + pluralSeparator : "_", + contextSeparator : "_" + + }, function(err, t) + { + console.log("detected user language: " + h.language); + console.log("loaded languages: " + h.languages.join(', ')); + h.changeLanguage(h.languages[0]); + callback(err, t); + }); +}; + +/** + * 메세지 핸들러를 가져온다. + * + * @returns {i18next} message handler + */ +Message.prototype.getHandle = function () +{ + return this.handle; +}; + +/** + * 메세지를 가져온다. + * + * @returns {Object} message + */ +Message.prototype.getMessage = function () +{ + return this.message; +}; + +'use strict'; +var MessageSource = {}; +MessageSource.en = { + "common": { + "welcome" : "Welcome", + "error": { + "title" : "Error", + "construct" : { + "create" : "This object should be created using new." + } + } + } +}; +MessageSource.ko = { + "common": { + "welcome" : "환영합니다.", + "error": { + "title" : "오류", + "construct" : { + "create" : "이 객체는 new 를 사용하여 생성해야 합니다." + } + } + } + }; + +'use strict'; + +/** + * 어떤 일을 하고 있습니까? + * @class AttribLocationState + */ +var AttribLocationState = function() +{ + if (!(this instanceof AttribLocationState)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + + this.attribLocationEnabled = false; +}; +'use strict'; + +/** + * 어떤 일을 하고 있습니까? + * @class PostFxShader + * @param gl 변수 + */ +var PostFxShader = function(gl) +{ + if (!(this instanceof PostFxShader)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + this.gl = gl; + this.name; + this.attribLocationCacheObj = {}; // old. + this.uniformsArrayGeneral = []; // this array has the same uniforms that "uniformsCacheObj". + this.uniformsMapGeneral = {}; // this object has the same uniforms that "uniformsArray". + + this.uniformsArrayLocal = []; // this array has the same uniforms that "uniformsCacheObj". + this.uniformsMapLocal = {}; // this object has the same uniforms that "uniformsArray". + + // No general objects. + this.camera; + + // shader program. + this.program; + this.shader_vertex; + this.shader_fragment; + + // current buffers binded. + this.last_vboPos_binded; + this.last_vboNor_binded; + this.last_vboCol_binded; + this.last_vboIdx_binded; + this.last_tex_id; + this.last_isAditionalMovedZero = false; + this.last_vboTexCoord_binded; + + // attribLocations state management. + this.attribLocationStateArray = []; +}; + +/** + * 어떤 일을 하고 있습니까? + * @param shaderName 변수 + * @returns shader + */ +PostFxShader.prototype.resetLastBuffersBinded = function() +{ + this.last_vboPos_binded = undefined; + this.last_vboNor_binded = undefined; + this.last_vboIdx_binded = undefined; + this.last_vboTexCoord_binded = undefined; // no used. + this.last_tex_id = undefined; // todo: must distinguish by channel. + this.last_isAditionalMovedZero = false; + + this.disableVertexAttribArrayAll(); + + if (this.attribLocationStateArray) + { + var attribLocsCount = this.attribLocationStateArray.length; + for (var i=0; i 0.49)\n\ - continue;\n\ - float depthBufferValue = getDepth(offset.xy); \n\ - float range_check = abs(linearDepth - depthBufferValue)+radius*0.998;\n\ - if (range_check < radius*1.001 && depthBufferValue <= sampleDepth)\n\ - {\n\ - occlusion += 1.0;\n\ - }\n\ - } \n\ - \n\ - occlusion = 1.0 - occlusion / float(kernelSize);\n\ -\n\ - vec4 textureColor;\n\ - if(hasTexture)\n\ +{ \n\ + vec4 textureColor;\n\ + textureColor = vcolor4; \n\ + if(bUseNormal)\n\ {\n\ - if(textureFlipYAxis)\n\ - {\n\ - textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, 1.0 - vTexCoord.t));\n\ - }\n\ - else{\n\ - textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, vTexCoord.t));\n\ - }\n\ + vec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight); \n\ + float linearDepth = getDepth(screenPos); \n\ + vec3 origin = getViewRay(screenPos) * linearDepth; \n\ + vec3 normal2 = vNormal; \n\ + \n\ + vec3 rvec = texture2D(noiseTex, screenPos.xy * noiseScale).xyz * 2.0 - 1.0;\n\ + vec3 tangent = normalize(rvec - normal2 * dot(rvec, normal2));\n\ + vec3 bitangent = cross(normal2, tangent);\n\ + mat3 tbn = mat3(tangent, bitangent, normal2); \n\ \n\ - if(textureColor.w == 0.0)\n\ - {\n\ - discard;\n\ - }\n\ - }\n\ - else{\n\ - textureColor = vcolor4;\n\ - }\n\ -\n\ - gl_FragColor = vec4((textureColor.xyz) * occlusion, 1.0); \n\ + float occlusion = 0.0;\n\ + for(int i = 0; i < kernelSize; ++i)\n\ + { \n\ + vec3 sample = origin + (tbn * kernel[i]) * radius;\n\ + vec4 offset = projectionMatrix * vec4(sample, 1.0); \n\ + offset.xy /= offset.w;\n\ + offset.xy = offset.xy * 0.5 + 0.5; \n\ + float sampleDepth = -sample.z/far;\n\ + float depthBufferValue = getDepth(offset.xy); \n\ + float range_check = abs(linearDepth - depthBufferValue)+radius*0.998;\n\ + if (range_check < radius*1.001 && depthBufferValue <= sampleDepth)\n\ + {\n\ + occlusion += 1.0;\n\ + }\n\ + \n\ + } \n\ + \n\ + occlusion = 1.0 - occlusion / float(kernelSize);\n\ + \n\ + vec3 lightPos = vec3(10.0, 10.0, 10.0);\n\ + vec3 L = normalize(lightPos);\n\ + float DiffuseFactor = dot(normal2, L);\n\ + float NdotL = abs(DiffuseFactor);\n\ + vec3 diffuse = vec3(NdotL);\n\ + vec3 ambient = vec3(1.0);\n\ + gl_FragColor.rgb = vec3((textureColor.xyz)*vLightWeighting * occlusion); \n\ + gl_FragColor.a = 1.0; \n\ + }\n\ + else\n\ + {\n\ + gl_FragColor.rgb = vec3(textureColor.xyz); \n\ + gl_FragColor.a = 1.0; \n\ + } \n\ }\n\ "; -ShaderSource.LodBuildingSsaoSimpleCompressVS = "attribute vec3 position;\n\ +ShaderSource.BoxSsaoVS = "attribute vec3 position;\n\ attribute vec3 normal;\n\ attribute vec4 color4;\n\ -attribute vec2 texCoord;\n\ \n\ -uniform sampler2D diffuseTex;\n\ uniform mat4 projectionMatrix; \n\ uniform mat4 modelViewMatrix;\n\ uniform mat4 modelViewMatrixRelToEye; \n\ @@ -50308,46 +63527,42 @@ uniform vec3 encodedCameraPositionMCLow;\n\ uniform vec3 aditionalPosition;\n\ uniform vec4 oneColor4;\n\ uniform bool bUse1Color;\n\ -uniform bool hasTexture;\n\ -\n\ -uniform int posDataByteSize;\n\ -uniform int texCoordByteSize;\n\ -uniform vec3 compressionMaxPoint;\n\ -uniform vec3 compressionMinPoint;\n\ +uniform bool bUseNormal;\n\ +uniform vec3 scale;\n\ +uniform bool bScale;\n\ \n\ varying vec3 vNormal;\n\ -varying vec2 vTexCoord; \n\ +varying vec2 vTexCoord; \n\ +varying vec3 uAmbientColor;\n\ varying vec3 vLightWeighting;\n\ varying vec4 vcolor4;\n\ \n\ void main()\n\ { \n\ - vec3 finalPos;\n\ - vec2 finalTexCoord;\n\ - if(posDataByteSize == 2)\n\ - {\n\ - // Decompress the position.*** \n\ - float rangeX = compressionMaxPoint.x - compressionMinPoint.x;\n\ - float rangeY = compressionMaxPoint.y - compressionMinPoint.y;\n\ - float rangeZ = compressionMaxPoint.z - compressionMinPoint.z;\n\ - float shortMax = 65535.0;\n\ - finalPos.x = (float(position.x) * rangeX / shortMax) + compressionMinPoint.x;\n\ - finalPos.y = (float(position.y) * rangeY / shortMax) + compressionMinPoint.y;\n\ - finalPos.z = (float(position.z) * rangeZ / shortMax) + compressionMinPoint.z;\n\ - }\n\ - else{\n\ - finalPos = position;\n\ - }\n\ - vec4 rotatedPos = buildingRotMatrix * vec4(finalPos.xyz + aditionalPosition.xyz, 1.0);\n\ + vec4 position2 = vec4(position.xyz, 1.0);\n\ + if(bScale)\n\ + {\n\ + position2.x *= scale.x;\n\ + position2.y *= scale.y;\n\ + position2.z *= scale.z;\n\ + }\n\ + vec4 rotatedPos = buildingRotMatrix * vec4(position2.xyz + aditionalPosition.xyz, 1.0);\n\ vec3 objPosHigh = buildingPosHIGH;\n\ vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n\ vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\ vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\ vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ - \n\ - vec4 rotatedNormal = buildingRotMatrix * vec4(normal.xyz, 1.0);\n\ - vNormal = (normalMatrix4 * vec4(rotatedNormal.x, rotatedNormal.y, rotatedNormal.z, 1.0)).xyz;\n\ -\n\ + if(bUseNormal)\n\ + {\n\ + vec4 rotatedNormal = buildingRotMatrix * vec4(normal.xyz, 1.0);\n\ + vLightWeighting = vec3(1.0, 1.0, 1.0);\n\ + uAmbientColor = vec3(0.8, 0.8, 0.8);\n\ + vec3 uLightingDirection = vec3(0.5, 0.5, 0.5);\n\ + vec3 directionalLightColor = vec3(0.6, 0.6, 0.6);\n\ + vNormal = (normalMatrix4 * vec4(rotatedNormal.x, rotatedNormal.y, rotatedNormal.z, 1.0)).xyz;\n\ + float directionalLightWeighting = max(dot(vNormal, uLightingDirection), 0.0);\n\ + vLightWeighting = uAmbientColor + directionalLightColor * directionalLightWeighting;\n\ + }\n\ if(bUse1Color)\n\ {\n\ vcolor4 = oneColor4;\n\ @@ -50356,252 +63571,253 @@ void main()\n\ {\n\ vcolor4 = color4;\n\ }\n\ - \n\ - if(texCoordByteSize == 2)\n\ - {\n\ - // Decompress the texCoord.***\n\ - float shortMax = 65535.0;\n\ - finalTexCoord.x = float(texCoord.x) / shortMax;\n\ - finalTexCoord.y = float(texCoord.y) / shortMax;\n\ - }\n\ - else\n\ - {\n\ - finalTexCoord = texCoord;\n\ - }\n\ - vTexCoord = finalTexCoord;\n\ \n\ gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\ }\n\ "; -ShaderSource.LodBuildingSsaoSimpleFS = "#ifdef GL_ES\n\ - precision highp float;\n\ -#endif\n\ -uniform sampler2D depthTex;\n\ -uniform sampler2D noiseTex; \n\ -uniform sampler2D diffuseTex;\n\ -uniform bool hasTexture;\n\ -uniform bool textureFlipYAxis;\n\ -varying vec3 vNormal;\n\ -uniform mat4 projectionMatrix;\n\ -uniform mat4 m;\n\ -uniform vec2 noiseScale;\n\ -uniform float near;\n\ -uniform float far; \n\ -uniform float fov;\n\ -uniform float aspectRatio; \n\ -uniform float screenWidth; \n\ -uniform float screenHeight; \n\ -uniform vec3 kernel[16]; \n\ -uniform vec4 vColor4Aux;\n\ -\n\ -varying vec2 vTexCoord; \n\ -varying vec4 vcolor4;\n\ -uniform vec3 specularColor;\n\ -\n\ -const int kernelSize = 16; \n\ -uniform float radius; \n\ +ShaderSource.CloudFS = "precision lowp float;\n\ +varying vec3 vColor;\n\ \n\ -float unpackDepth(const in vec4 rgba_depth)\n\ +void main()\n\ {\n\ - const vec4 bit_shift = vec4(0.000000059605, 0.000015258789, 0.00390625, 1.0);\n\ - float depth = dot(rgba_depth, bit_shift);\n\ - return depth;\n\ -} \n\ + gl_FragColor = vec4(vColor, 1.);\n\ +}"; +ShaderSource.CloudVS = "attribute vec3 position;\n\ +uniform mat4 ModelViewProjectionMatrixRelToEye;\n\ +uniform vec3 cloudPosHIGH;\n\ +uniform vec3 cloudPosLOW;\n\ +uniform vec3 encodedCameraPositionMCHigh;\n\ +uniform vec3 encodedCameraPositionMCLow;\n\ +attribute vec3 color;\n\ +varying vec3 vColor;\n\ \n\ -vec3 getViewRay(vec2 tc)\n\ +void main()\n\ {\n\ - float hfar = 2.0 * tan(fov/2.0) * far;\n\ - float wfar = hfar * aspectRatio; \n\ - vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n\ - return ray; \n\ -} \n\ - \n\ -//linear view space depth\n\ -float getDepth(vec2 coord)\n\ -{ \n\ - return unpackDepth(texture2D(depthTex, coord.xy));\n\ -} \n\ + vec3 objPosHigh = cloudPosHIGH;\n\ + vec3 objPosLow = cloudPosLOW.xyz + position.xyz;\n\ + vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\ + vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\ + vec4 pos = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ \n\ -void main()\n\ -{ \n\ - vec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight); \n\ - float linearDepth = getDepth(screenPos); \n\ - vec3 origin = getViewRay(screenPos) * linearDepth; \n\ + vColor=color;\n\ \n\ - vec3 normal2 = vNormal; \n\ - \n\ - vec3 rvec = texture2D(noiseTex, screenPos.xy * noiseScale).xyz * 2.0 - 1.0;\n\ - vec3 tangent = normalize(rvec - normal2 * dot(rvec, normal2));\n\ - vec3 bitangent = cross(normal2, tangent);\n\ - mat3 tbn = mat3(tangent, bitangent, normal2); \n\ - \n\ - float occlusion = 0.0;\n\ - for(int i = 0; i < kernelSize; ++i)\n\ - { \n\ - vec3 sample = origin + (tbn * kernel[i]) * radius;\n\ - vec4 offset = projectionMatrix * vec4(sample, 1.0); \n\ - offset.xy /= offset.w;\n\ - offset.xy = offset.xy * 0.5 + 0.5; \n\ - float sampleDepth = -sample.z/far;\n\ - if(sampleDepth > 0.49)\n\ - continue;\n\ - float depthBufferValue = getDepth(offset.xy); \n\ - float range_check = abs(linearDepth - depthBufferValue)+radius*0.998;\n\ - if (range_check < radius*1.001 && depthBufferValue <= sampleDepth)\n\ - {\n\ - occlusion += 1.0;\n\ - }\n\ - } \n\ - \n\ - occlusion = 1.0 - occlusion / float(kernelSize);\n\ + gl_Position = ModelViewProjectionMatrixRelToEye * pos;\n\ +}"; +ShaderSource.ColorFS = "precision mediump float;\n\ +uniform int byteColor_r;\n\ +uniform int byteColor_g;\n\ +uniform int byteColor_b;\n\ \n\ - vec4 textureColor;\n\ - if(hasTexture)\n\ - {\n\ - if(textureFlipYAxis)\n\ - {\n\ - textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, 1.0 - vTexCoord.t));\n\ - }\n\ - else{\n\ - textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, vTexCoord.t));\n\ - }\n\ - \n\ - if(textureColor.w == 0.0)\n\ - {\n\ - discard;\n\ - }\n\ - }\n\ - else{\n\ - textureColor = vcolor4;\n\ - }\n\ +void main()\n\ +{\n\ + float byteMaxValue = 255.0;\n\ +\n\ + gl_FragColor = vec4(float(byteColor_r)/byteMaxValue, float(byteColor_g)/byteMaxValue, float(byteColor_b)/byteMaxValue, 1);\n\ +}\n\ +"; +ShaderSource.ColorSelectionSsaoFS = "precision highp float;\n\ +uniform vec4 oneColor4;\n\ \n\ - gl_FragColor = vec4((textureColor.xyz) * occlusion, 1.0); \n\ +void main()\n\ +{ \n\ + gl_FragColor = oneColor4;\n\ }\n\ "; -ShaderSource.LodBuildingSsaoSimpleVS = "attribute vec3 position;\n\ -attribute vec3 normal;\n\ -attribute vec4 color4;\n\ -attribute vec2 texCoord;\n\ +ShaderSource.ColorSelectionSsaoVS = "attribute vec3 position;\n\ \n\ -uniform sampler2D diffuseTex;\n\ -uniform mat4 projectionMatrix; \n\ -uniform mat4 modelViewMatrix;\n\ -uniform mat4 modelViewMatrixRelToEye; \n\ +uniform mat4 buildingRotMatrix;\n\ uniform mat4 ModelViewProjectionMatrixRelToEye;\n\ -uniform mat4 normalMatrix4;\n\ -uniform mat4 buildingRotMatrix; \n\ +uniform mat4 RefTransfMatrix;\n\ uniform vec3 buildingPosHIGH;\n\ uniform vec3 buildingPosLOW;\n\ uniform vec3 encodedCameraPositionMCHigh;\n\ uniform vec3 encodedCameraPositionMCLow;\n\ uniform vec3 aditionalPosition;\n\ -uniform vec4 oneColor4;\n\ -uniform bool bUse1Color;\n\ -uniform bool hasTexture;\n\ -\n\ -varying vec2 vTexCoord; \n\ -varying vec4 vcolor4;\n\ +uniform vec3 refTranslationVec;\n\ +uniform int refMatrixType; // 0= identity, 1= translate, 2= transform\n\ \n\ void main()\n\ -{ \n\ - vec4 rotatedPos = buildingRotMatrix * vec4(position.xyz + aditionalPosition.xyz, 1.0);\n\ +{\n\ + vec4 rotatedPos;\n\ + if(refMatrixType == 0)\n\ + {\n\ + rotatedPos = buildingRotMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\ + }\n\ + else if(refMatrixType == 1)\n\ + {\n\ + rotatedPos = buildingRotMatrix * vec4(position.xyz + refTranslationVec.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\ + }\n\ + else if(refMatrixType == 2)\n\ + {\n\ + rotatedPos = RefTransfMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\ + }\n\ +\n\ vec3 objPosHigh = buildingPosHIGH;\n\ vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n\ vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\ vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\ vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ -\n\ - if(bUse1Color)\n\ - {\n\ - vcolor4 = oneColor4;\n\ - }\n\ - else\n\ - {\n\ - vcolor4 = color4;\n\ - }\n\ - vTexCoord = texCoord;\n\ -\n\ + \n\ + gl_PointSize = 10.0;\n\ gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\ -}"; -ShaderSource.LodBuildingSsaoVS = "attribute vec3 position;\n\ -attribute vec3 normal;\n\ -attribute vec4 color4;\n\ -attribute vec2 texCoord;\n\ -\n\ -uniform sampler2D diffuseTex;\n\ -uniform mat4 projectionMatrix; \n\ -uniform mat4 modelViewMatrix;\n\ -uniform mat4 modelViewMatrixRelToEye; \n\ +}\n\ +"; +ShaderSource.ColorVS = "attribute vec3 position;\n\ uniform mat4 ModelViewProjectionMatrixRelToEye;\n\ -uniform mat4 normalMatrix4;\n\ -uniform mat4 buildingRotMatrix; \n\ uniform vec3 buildingPosHIGH;\n\ uniform vec3 buildingPosLOW;\n\ uniform vec3 encodedCameraPositionMCHigh;\n\ uniform vec3 encodedCameraPositionMCLow;\n\ -uniform vec3 aditionalPosition;\n\ -uniform vec4 oneColor4;\n\ -uniform bool bUse1Color;\n\ -uniform bool hasTexture;\n\ -uniform bool bApplySpecularLighting;\n\ -\n\ -varying vec3 vNormal;\n\ -varying vec2 vTexCoord; \n\ -varying vec3 uAmbientColor;\n\ -varying vec3 vLightWeighting;\n\ -varying vec4 vcolor4;\n\ -varying vec3 vertexPos;\n\ -varying float applySpecLighting;\n\ +uniform mat4 RefTransfMatrix;\n\ \n\ void main()\n\ -{ \n\ - vec4 rotatedPos = buildingRotMatrix * vec4(position.xyz + aditionalPosition.xyz, 1.0);\n\ +{\n\ + vec4 rotatedPos = RefTransfMatrix * vec4(position.xyz, 1.0);\n\ vec3 objPosHigh = buildingPosHIGH;\n\ vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n\ vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\ vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\ - vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ - \n\ - vertexPos = vec3(modelViewMatrixRelToEye * pos4);\n\ - vec4 rotatedNormal = buildingRotMatrix * vec4(normal.xyz, 1.0);\n\ - vLightWeighting = vec3(1.0, 1.0, 1.0);\n\ - uAmbientColor = vec3(0.8, 0.8, 0.8);\n\ - vec3 uLightingDirection = vec3(0.6, 0.6, 0.6);\n\ - vec3 directionalLightColor = vec3(0.7, 0.7, 0.7);\n\ - vNormal = (normalMatrix4 * vec4(rotatedNormal.x, rotatedNormal.y, rotatedNormal.z, 1.0)).xyz;\n\ - float directionalLightWeighting = max(dot(vNormal, uLightingDirection), 0.0);\n\ - vLightWeighting = uAmbientColor + directionalLightColor * directionalLightWeighting;\n\ + vec4 pos = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ + \n\ + gl_Position = ModelViewProjectionMatrixRelToEye * pos;\n\ +}\n\ +"; +ShaderSource.draw_frag = "precision mediump float;\n\ +\n\ +uniform sampler2D u_wind;\n\ +uniform vec2 u_wind_min;\n\ +uniform vec2 u_wind_max;\n\ +uniform bool u_flipTexCoordY_windMap;\n\ +uniform bool u_colorScale;\n\ +\n\ +varying vec2 v_particle_pos;\n\ +\n\ +void main() {\n\ + vec2 windMapTexCoord = v_particle_pos;\n\ + if(u_flipTexCoordY_windMap)\n\ + {\n\ + windMapTexCoord.y = 1.0 - windMapTexCoord.y;\n\ + }\n\ + vec2 velocity = mix(u_wind_min, u_wind_max, texture2D(u_wind, windMapTexCoord).rg);\n\ + float speed_t = length(velocity) / length(u_wind_max);\n\ +\n\ \n\ - if(bApplySpecularLighting)\n\ - applySpecLighting = 1.0;\n\ - else\n\ - applySpecLighting = -1.0;\n\ + if(u_colorScale)\n\ + {\n\ + speed_t *= 1.5;\n\ + if(speed_t > 1.0)speed_t = 1.0;\n\ + float b = 1.0 - speed_t;\n\ + float g;\n\ + if(speed_t > 0.5)\n\ + {\n\ + g = 2.0-2.0*speed_t;\n\ + }\n\ + else{\n\ + g = 2.0*speed_t;\n\ + }\n\ + float r = speed_t;\n\ + gl_FragColor = vec4(r,g,b,1.0);\n\ + }\n\ + else{\n\ + float intensity = speed_t*3.0;\n\ + if(intensity > 1.0)\n\ + intensity = 1.0;\n\ + gl_FragColor = vec4(intensity,intensity,intensity,1.0);\n\ + }\n\ +}\n\ +"; +ShaderSource.draw_vert = "precision mediump float;\n\ \n\ - if(bUse1Color)\n\ - {\n\ - vcolor4 = oneColor4;\n\ - }\n\ - else\n\ - {\n\ - vcolor4 = color4;\n\ - }\n\ - vTexCoord = texCoord;\n\ +attribute float a_index;\n\ \n\ - gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\ +uniform sampler2D u_particles;\n\ +uniform float u_particles_res;\n\ +\n\ +varying vec2 v_particle_pos;\n\ +\n\ +void main() {\n\ + vec4 color = texture2D(u_particles, vec2(\n\ + fract(a_index / u_particles_res),\n\ + floor(a_index / u_particles_res) / u_particles_res));\n\ +\n\ + // decode current particle position from the pixel's RGBA value\n\ + v_particle_pos = vec2(\n\ + color.r / 255.0 + color.b,\n\ + color.g / 255.0 + color.a);\n\ +\n\ + gl_PointSize = 1.0;\n\ + gl_Position = vec4(2.0 * v_particle_pos.x - 1.0, 1.0 - 2.0 * v_particle_pos.y, 0, 1);\n\ }\n\ "; -ShaderSource.ModelRefSsaoFS = "#ifdef GL_ES\n\ - precision highp float;\n\ -#endif\n\ +ShaderSource.draw_vert3D = "precision mediump float;\n\ +\n\ + // This shader draws windParticles in 3d directly from positions on u_particles image.***\n\ +attribute float a_index;\n\ +\n\ +uniform sampler2D u_particles;\n\ +uniform float u_particles_res;\n\ +uniform mat4 ModelViewProjectionMatrix;\n\ +\n\ +varying vec2 v_particle_pos;\n\ +\n\ +#define M_PI 3.1415926535897932384626433832795\n\ +vec4 geographicToWorldCoord(float lonDeg, float latDeg, float alt)\n\ +{\n\ + // defined in the LINZ standard LINZS25000 (Standard for New Zealand Geodetic Datum 2000)\n\ + // https://www.linz.govt.nz/data/geodetic-system/coordinate-conversion/geodetic-datum-conversions/equations-used-datum\n\ + // a = semi-major axis.\n\ + // e2 = firstEccentricitySquared.\n\ + // v = a / sqrt(1 - e2 * sin2(lat)).\n\ + // x = (v+h)*cos(lat)*cos(lon).\n\ + // y = (v+h)*cos(lat)*sin(lon).\n\ + // z = [v*(1-e2)+h]*sin(lat).\n\ + float degToRadFactor = M_PI/180.0;\n\ + float equatorialRadius = 6378137.0; // meters.\n\ + float firstEccentricitySquared = 6.69437999014E-3;\n\ + float lonRad = lonDeg * degToRadFactor;\n\ + float latRad = latDeg * degToRadFactor;\n\ + float cosLon = cos(lonRad);\n\ + float cosLat = cos(latRad);\n\ + float sinLon = sin(lonRad);\n\ + float sinLat = sin(latRad);\n\ + float a = equatorialRadius;\n\ + float e2 = firstEccentricitySquared;\n\ + float v = a/sqrt(1.0 - e2 * sinLat * sinLat);\n\ + float h = alt;\n\ + \n\ + vec4 resultCartesian = vec4((v+h)*cosLat*cosLon, (v+h)*cosLat*sinLon, (v*(1.0-e2)+h)*sinLat, 1.0);\n\ + return resultCartesian;\n\ +}\n\ +\n\ +void main() {\n\ + vec4 color = texture2D(u_particles, vec2(\n\ + fract(a_index / u_particles_res),\n\ + floor(a_index / u_particles_res) / u_particles_res));\n\ +\n\ + // decode current particle position from the pixel's RGBA value\n\ + v_particle_pos = vec2(\n\ + color.r / 255.0 + color.b,\n\ + color.g / 255.0 + color.a);\n\ +\n\ + gl_PointSize = 1.0;\n\ + vec4 pos2d = vec4(2.0 * v_particle_pos.x - 1.0, 1.0 - 2.0 * v_particle_pos.y, 0, 1);\n\ + \n\ + // Now, must calculate geographic coords of the pos2d.***\n\ + float longitudeDeg = -180.0 + pos2d.x * 360.0;\n\ + float latitudeDeg = 90.0 - pos2d.y * 180.0;\n\ + float altitude = 0.0;\n\ + // Now, calculate worldPosition of the geographicCoords (lon, lat, alt).***\n\ + vec4 worldPos = geographicToWorldCoord(longitudeDeg, latitudeDeg, altitude);\n\ + \n\ + // Now calculate the position on camCoord.***\n\ + \n\ + gl_Position = ModelViewProjectionMatrix * worldPos;\n\ +}"; +ShaderSource.filterSilhouetteFS = "precision mediump float;\n\ \n\ uniform sampler2D depthTex;\n\ uniform sampler2D noiseTex; \n\ -uniform sampler2D diffuseTex;\n\ -uniform bool hasTexture;\n\ -uniform bool textureFlipYAxis;\n\ -varying vec3 vNormal;\n\ uniform mat4 projectionMatrix;\n\ -uniform mat4 m;\n\ uniform vec2 noiseScale;\n\ uniform float near;\n\ uniform float far; \n\ @@ -50609,25 +63825,13 @@ uniform float fov;\n\ uniform float aspectRatio; \n\ uniform float screenWidth; \n\ uniform float screenHeight; \n\ -uniform float shininessValue;\n\ uniform vec3 kernel[16]; \n\ -uniform vec4 oneColor4;\n\ -uniform bool bApplyScpecularLighting;\n\ -\n\ -varying vec2 vTexCoord; \n\ -varying vec3 vLightWeighting;\n\ \n\ -varying vec3 diffuseColor;\n\ -uniform vec3 specularColor;\n\ -varying vec3 vertexPos;\n\ \n\ const int kernelSize = 16; \n\ uniform float radius; \n\ \n\ -uniform float ambientReflectionCoef;\n\ -uniform float diffuseReflectionCoef; \n\ -uniform float specularReflectionCoef; \n\ -varying float applySpecLighting;\n\ +uniform bool bApplySsao;\n\ \n\ float unpackDepth(const in vec4 rgba_depth)\n\ {\n\ @@ -50638,112 +63842,71 @@ float unpackDepth(const in vec4 rgba_depth)\n\ \n\ vec3 getViewRay(vec2 tc)\n\ {\n\ - float hfar = 2.0 * tan(fov/2.0) * far;\n\ - float wfar = hfar * aspectRatio; \n\ - vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n\ - return ray; \n\ -} \n\ - \n\ -//linear view space depth\n\ -float getDepth(vec2 coord)\n\ -{\n\ - return unpackDepth(texture2D(depthTex, coord.xy));\n\ -} \n\ -\n\ -void main()\n\ -{ \n\ - vec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight); \n\ - float linearDepth = getDepth(screenPos); \n\ - vec3 origin = getViewRay(screenPos) * linearDepth; \n\ -\n\ - vec3 normal2 = vNormal;\n\ - \n\ - vec3 rvec = texture2D(noiseTex, screenPos.xy * noiseScale).xyz * 2.0 - 1.0;\n\ - vec3 tangent = normalize(rvec - normal2 * dot(rvec, normal2));\n\ - vec3 bitangent = cross(normal2, tangent);\n\ - mat3 tbn = mat3(tangent, bitangent, normal2); \n\ - \n\ - float occlusion = 0.0;\n\ - for(int i = 0; i < kernelSize; ++i)\n\ - { \n\ - vec3 sample = origin + (tbn * kernel[i]) * radius;\n\ - vec4 offset = projectionMatrix * vec4(sample, 1.0); \n\ - offset.xy /= offset.w;\n\ - offset.xy = offset.xy * 0.5 + 0.5; \n\ - float sampleDepth = -sample.z/far;\n\ - if(sampleDepth > 0.49)\n\ - continue;\n\ - float depthBufferValue = getDepth(offset.xy); \n\ - float range_check = abs(linearDepth - depthBufferValue)+radius*0.998;\n\ - if (range_check < radius*1.001 && depthBufferValue <= sampleDepth)\n\ - {\n\ - occlusion += 1.0;\n\ - }\n\ - } \n\ - \n\ - occlusion = 1.0 - occlusion / float(kernelSize);\n\ -\n\ - // Do specular lighting.***\n\ - float lambertian;\n\ - float specular;\n\ - \n\ - if(applySpecLighting> 0.0)\n\ - {\n\ - vec3 lightPos = vec3(20.0, 60.0, 20.0);\n\ - vec3 L = normalize(lightPos - vertexPos);\n\ - lambertian = max(dot(normal2, L), 0.0);\n\ - specular = 0.0;\n\ - if(lambertian > 0.0)\n\ - {\n\ - vec3 R = reflect(-L, normal2); // Reflected light vector\n\ - vec3 V = normalize(-vertexPos); // Vector to viewer\n\ - \n\ - // Compute the specular term\n\ - float specAngle = max(dot(R, V), 0.0);\n\ - specular = pow(specAngle, shininessValue);\n\ - }\n\ - \n\ - if(lambertian < 0.5)\n\ - {\n\ - lambertian = 0.5;\n\ - }\n\ - }\n\ -\n\ - vec4 textureColor;\n\ - if(hasTexture)\n\ - {\n\ - if(textureFlipYAxis)\n\ - {\n\ - textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, 1.0 - vTexCoord.t));\n\ - }\n\ - else{\n\ - textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, vTexCoord.t));\n\ - }\n\ - \n\ - if(textureColor.w == 0.0)\n\ - {\n\ - discard;\n\ - }\n\ - }\n\ - else{\n\ - textureColor = oneColor4;\n\ - }\n\ - \n\ - vec3 ambientColor = vec3(textureColor.x, textureColor.y, textureColor.z);\n\ - float alfa = textureColor.w;\n\ + float hfar = 2.0 * tan(fov/2.0) * far;\n\ + float wfar = hfar * aspectRatio; \n\ + vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n\ + return ray; \n\ +} \n\ + \n\ +//linear view space depth\n\ +float getDepth(vec2 coord)\n\ +{\n\ + return unpackDepth(texture2D(depthTex, coord.xy));\n\ +} \n\ \n\ - vec4 finalColor;\n\ - if(applySpecLighting> 0.0)\n\ - {\n\ - finalColor = vec4((ambientReflectionCoef * ambientColor + diffuseReflectionCoef * lambertian * textureColor.xyz + specularReflectionCoef * specular * specularColor)*vLightWeighting * occlusion, alfa); \n\ +void main()\n\ +{\n\ + float occlusion = 0.0;\n\ + vec3 normal2 = vec3(0.0, 0.0, 1.0);\n\ + float radiusAux = radius * 5.0;\n\ + if(bApplySsao)\n\ + { \n\ + vec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight); \n\ + float linearDepth = getDepth(screenPos); \n\ + vec3 origin = getViewRay(screenPos) * linearDepth; \n\ +\n\ + vec3 rvec = texture2D(noiseTex, screenPos.xy * noiseScale).xyz * 2.0 - 1.0;\n\ + vec3 tangent = normalize(rvec - normal2 * dot(rvec, normal2));\n\ + vec3 bitangent = cross(normal2, tangent);\n\ + mat3 tbn = mat3(tangent, bitangent, normal2); \n\ + \n\ + for(int i = 0; i < kernelSize; ++i)\n\ + { \n\ + //vec3 sample = origin + (tbn * kernel[i]) * radiusAux;\n\ + vec3 sample = origin + (kernel[i]) * radiusAux;\n\ + vec4 offset = projectionMatrix * vec4(sample, 1.0); \n\ + offset.xy /= offset.w;\n\ + offset.xy = offset.xy * 0.5 + 0.5; \n\ + float sampleDepth = -sample.z/far;\n\ + if(sampleDepth > 0.49)\n\ + continue;\n\ + float depthBufferValue = getDepth(offset.xy);\n\ + float range_check = abs(linearDepth - depthBufferValue)+radiusAux*0.998;\n\ + if (range_check > radius*1.001 && depthBufferValue <= sampleDepth)\n\ + {\n\ + occlusion += 1.0;\n\ + }\n\ + } \n\ + \n\ + if(occlusion > float(kernelSize)*0.4)\n\ + {\n\ + occlusion = occlusion / float(kernelSize);\n\ + }\n\ + else{\n\ + occlusion = 0.0;\n\ + }\n\ + //occlusion = 1.0 - occlusion / float(kernelSize);\n\ }\n\ else{\n\ - finalColor = vec4((textureColor.xyz) * occlusion, alfa);\n\ + occlusion = 0.0;\n\ }\n\ +\n\ + vec4 finalColor;\n\ + finalColor = vec4(1.0, 1.0, 1.0, occlusion*0.9);\n\ gl_FragColor = finalColor; \n\ }\n\ "; -ShaderSource.ModelRefSsaoSimpleFS = "#ifdef GL_ES\n\ +ShaderSource.InvertedBoxFS = "#ifdef GL_ES\n\ precision highp float;\n\ #endif\n\ \n\ @@ -50764,7 +63927,7 @@ uniform float screenWidth; \n\ uniform float screenHeight; \n\ uniform float shininessValue;\n\ uniform vec3 kernel[16]; \n\ -uniform vec4 oneColor4;\n\ +uniform vec4 vColor4Aux;\n\ \n\ varying vec2 vTexCoord; \n\ varying vec3 vLightWeighting;\n\ @@ -50833,6 +63996,25 @@ void main()\n\ } \n\ \n\ occlusion = 1.0 - occlusion / float(kernelSize);\n\ +\n\ + vec3 lightPos = vec3(20.0, 60.0, 20.0);\n\ + vec3 L = normalize(lightPos - vertexPos);\n\ + float lambertian = max(dot(normal2, L), 0.0);\n\ + float specular = 0.0;\n\ + if(lambertian > 0.0)\n\ + {\n\ + vec3 R = reflect(-L, normal2); // Reflected light vector\n\ + vec3 V = normalize(-vertexPos); // Vector to viewer\n\ + \n\ + // Compute the specular term\n\ + float specAngle = max(dot(R, V), 0.0);\n\ + specular = pow(specAngle, shininessValue);\n\ + }\n\ + \n\ + if(lambertian < 0.5)\n\ + {\n\ + lambertian = 0.5;\n\ + }\n\ \n\ vec4 textureColor;\n\ if(hasTexture)\n\ @@ -50851,13 +64033,15 @@ void main()\n\ }\n\ }\n\ else{\n\ - textureColor = oneColor4;\n\ + textureColor = vColor4Aux;\n\ }\n\ \n\ - gl_FragColor = vec4((textureColor.xyz) * occlusion, 1.0); \n\ + vec3 ambientColor = vec3(textureColor.x, textureColor.y, textureColor.z);\n\ +\n\ + gl_FragColor = vec4((ambientReflectionCoef * ambientColor + diffuseReflectionCoef * lambertian * textureColor.xyz + specularReflectionCoef * specular * specularColor)*vLightWeighting * occlusion, 1.0); \n\ }\n\ "; -ShaderSource.ModelRefSsaoSimpleVS = " attribute vec3 position;\n\ +ShaderSource.InvertedBoxVS = " attribute vec3 position;\n\ attribute vec3 normal;\n\ attribute vec2 texCoord;\n\ \n\ @@ -50922,9 +64106,175 @@ ShaderSource.ModelRefSsaoSimpleVS = " attribute vec3 position;\n\ gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\ }\n\ "; +ShaderSource.ModelRefSsaoFS = "#ifdef GL_ES\n\ + precision highp float;\n\ +#endif\n\ +\n\ +uniform sampler2D depthTex;\n\ +uniform sampler2D noiseTex; \n\ +uniform sampler2D diffuseTex;\n\ +uniform bool textureFlipYAxis;\n\ +varying vec3 vNormal;\n\ +uniform mat4 projectionMatrix;\n\ +uniform mat4 m;\n\ +uniform vec2 noiseScale;\n\ +uniform float near;\n\ +uniform float far; \n\ +uniform float fov;\n\ +uniform float aspectRatio; \n\ +uniform float screenWidth; \n\ +uniform float screenHeight; \n\ +uniform float shininessValue;\n\ +uniform vec3 kernel[16]; \n\ +uniform vec4 oneColor4;\n\ +varying vec4 aColor4; // color from attributes\n\ +uniform bool bApplyScpecularLighting;\n\ +uniform highp int colorType; // 0= oneColor, 1= attribColor, 2= texture.\n\ +\n\ +varying vec2 vTexCoord; \n\ +varying vec3 vLightWeighting;\n\ +\n\ +varying vec3 diffuseColor;\n\ +uniform vec3 specularColor;\n\ +varying vec3 vertexPos;\n\ +\n\ +const int kernelSize = 16; \n\ +uniform float radius; \n\ +\n\ +uniform float ambientReflectionCoef;\n\ +uniform float diffuseReflectionCoef; \n\ +uniform float specularReflectionCoef; \n\ +varying float applySpecLighting;\n\ +uniform bool bApplySsao;\n\ +uniform float externalAlpha;\n\ +\n\ +float unpackDepth(const in vec4 rgba_depth)\n\ +{\n\ + const vec4 bit_shift = vec4(0.000000059605, 0.000015258789, 0.00390625, 1.0);\n\ + float depth = dot(rgba_depth, bit_shift);\n\ + return depth;\n\ +} \n\ +\n\ +vec3 getViewRay(vec2 tc)\n\ +{\n\ + float hfar = 2.0 * tan(fov/2.0) * far;\n\ + float wfar = hfar * aspectRatio; \n\ + vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n\ + return ray; \n\ +} \n\ + \n\ +//linear view space depth\n\ +float getDepth(vec2 coord)\n\ +{\n\ + return unpackDepth(texture2D(depthTex, coord.xy));\n\ +} \n\ +\n\ +void main()\n\ +{\n\ + float occlusion = 0.0;\n\ + vec3 normal2 = vNormal;\n\ + if(bApplySsao)\n\ + { \n\ + vec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight); \n\ + float linearDepth = getDepth(screenPos); \n\ + vec3 origin = getViewRay(screenPos) * linearDepth; \n\ +\n\ + vec3 rvec = texture2D(noiseTex, screenPos.xy * noiseScale).xyz * 2.0 - 1.0;\n\ + vec3 tangent = normalize(rvec - normal2 * dot(rvec, normal2));\n\ + vec3 bitangent = cross(normal2, tangent);\n\ + mat3 tbn = mat3(tangent, bitangent, normal2); \n\ + \n\ + for(int i = 0; i < kernelSize; ++i)\n\ + { \n\ + vec3 sample = origin + (tbn * kernel[i]) * radius;\n\ + vec4 offset = projectionMatrix * vec4(sample, 1.0); \n\ + offset.xy /= offset.w;\n\ + offset.xy = offset.xy * 0.5 + 0.5; \n\ + float sampleDepth = -sample.z/far;\n\ + if(sampleDepth > 0.49)\n\ + continue;\n\ + float depthBufferValue = getDepth(offset.xy); \n\ + float range_check = abs(linearDepth - depthBufferValue)+radius*0.998;\n\ + if (range_check < radius*1.001 && depthBufferValue <= sampleDepth)\n\ + {\n\ + occlusion += 1.0;\n\ + }\n\ + } \n\ + \n\ + occlusion = 1.0 - occlusion / float(kernelSize);\n\ + }\n\ + else{\n\ + occlusion = 1.0;\n\ + }\n\ +\n\ + // Do specular lighting.***\n\ + float lambertian;\n\ + float specular;\n\ + \n\ + if(applySpecLighting> 0.0)\n\ + {\n\ + vec3 lightPos = vec3(20.0, 60.0, 200.0);\n\ + vec3 L = normalize(lightPos - vertexPos);\n\ + lambertian = max(dot(normal2, L), 0.0);\n\ + specular = 0.0;\n\ + if(lambertian > 0.0)\n\ + {\n\ + vec3 R = reflect(-L, normal2); // Reflected light vector\n\ + vec3 V = normalize(-vertexPos); // Vector to viewer\n\ + \n\ + // Compute the specular term\n\ + float specAngle = max(dot(R, V), 0.0);\n\ + specular = pow(specAngle, shininessValue);\n\ + }\n\ + \n\ + if(lambertian < 0.5)\n\ + {\n\ + lambertian = 0.5;\n\ + }\n\ + }\n\ +\n\ + vec4 textureColor;\n\ + if(colorType == 2)\n\ + {\n\ + if(textureFlipYAxis)\n\ + {\n\ + textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, 1.0 - vTexCoord.t));\n\ + }\n\ + else{\n\ + textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, vTexCoord.t));\n\ + }\n\ + \n\ + if(textureColor.w == 0.0)\n\ + {\n\ + discard;\n\ + }\n\ + }\n\ + else if(colorType == 0)\n\ + {\n\ + textureColor = oneColor4;\n\ + }\n\ + else if(colorType == 1)\n\ + {\n\ + textureColor = aColor4;\n\ + }\n\ + \n\ + vec3 ambientColor = vec3(textureColor.x, textureColor.y, textureColor.z);\n\ + float alfa = textureColor.w * externalAlpha;\n\ +\n\ + vec4 finalColor;\n\ + if(applySpecLighting> 0.0)\n\ + {\n\ + finalColor = vec4((ambientReflectionCoef * ambientColor + diffuseReflectionCoef * lambertian * textureColor.xyz + specularReflectionCoef * specular * specularColor)*vLightWeighting * occlusion, alfa); \n\ + }\n\ + else{\n\ + finalColor = vec4((textureColor.xyz) * occlusion, alfa);\n\ + }\n\ + gl_FragColor = finalColor; \n\ +}"; ShaderSource.ModelRefSsaoVS = " attribute vec3 position;\n\ attribute vec3 normal;\n\ attribute vec2 texCoord;\n\ + attribute vec4 color4;\n\ \n\ uniform mat4 buildingRotMatrix; \n\ uniform mat4 projectionMatrix; \n\ @@ -50941,6 +64291,7 @@ ShaderSource.ModelRefSsaoVS = " attribute vec3 position;\n\ uniform vec3 refTranslationVec;\n\ uniform int refMatrixType; // 0= identity, 1= translate, 2= transform\n\ uniform bool bApplySpecularLighting;\n\ + uniform highp int colorType; // 0= oneColor, 1= attribColor, 2= texture.\n\ \n\ varying vec3 vNormal;\n\ varying vec2 vTexCoord; \n\ @@ -50948,6 +64299,7 @@ ShaderSource.ModelRefSsaoVS = " attribute vec3 position;\n\ varying vec3 vLightWeighting;\n\ varying vec3 vertexPos;\n\ varying float applySpecLighting;\n\ + varying vec4 aColor4; // color from attributes\n\ \n\ void main()\n\ { \n\ @@ -50975,7 +64327,7 @@ ShaderSource.ModelRefSsaoVS = " attribute vec3 position;\n\ vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\ vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ \n\ - vertexPos = vec3(modelViewMatrixRelToEye * pos4);\n\ + //vertexPos = vec3(modelViewMatrixRelToEye * pos4);\n\ vec3 rotatedNormal = currentTMat * normal;\n\ vLightWeighting = vec3(1.0, 1.0, 1.0);\n\ uAmbientColor = vec3(0.8);\n\ @@ -50992,8 +64344,10 @@ ShaderSource.ModelRefSsaoVS = " attribute vec3 position;\n\ applySpecLighting = -1.0;\n\ \n\ gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\ - }\n\ -"; + \n\ + if(colorType == 1)\n\ + aColor4 = color4;\n\ + }"; ShaderSource.PngImageFS = "precision mediump float;\n\ varying vec2 v_texcoord;\n\ uniform bool textureFlipYAxis;\n\ @@ -51042,25 +64396,27 @@ void main()\n\ gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\ }\n\ "; -ShaderSource.PointCloudFS = " precision lowp float;\n\ - varying vec4 vColor;\n\ -\n\ - void main()\n\ - {\n\ - gl_FragColor = vColor;\n\ - }"; -ShaderSource.PointCloudVS = "attribute vec3 position;\n\ +ShaderSource.PointCloudDepthVS = "attribute vec3 position;\n\ uniform mat4 ModelViewProjectionMatrixRelToEye;\n\ +uniform mat4 modelViewMatrixRelToEye; \n\ uniform vec3 buildingPosHIGH;\n\ uniform vec3 buildingPosLOW;\n\ uniform mat4 buildingRotMatrix;\n\ uniform vec3 encodedCameraPositionMCHigh;\n\ uniform vec3 encodedCameraPositionMCLow;\n\ +uniform float near;\n\ +uniform float far;\n\ uniform bool bPositionCompressed;\n\ uniform vec3 minPosition;\n\ uniform vec3 bboxSize;\n\ attribute vec4 color4;\n\ +uniform bool bUse1Color;\n\ +uniform vec4 oneColor4;\n\ +uniform float fixPointSize;\n\ +uniform bool bUseFixPointSize;\n\ varying vec4 vColor;\n\ +//varying float glPointSize;\n\ +varying float depth; \n\ \n\ void main()\n\ {\n\ @@ -51081,174 +64437,248 @@ void main()\n\ vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\ vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\ vec4 pos = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ -\n\ - vColor=color4;\n\ + \n\ + if(bUse1Color)\n\ + {\n\ + vColor=oneColor4;\n\ + }\n\ + else\n\ + vColor=color4;\n\ \n\ gl_Position = ModelViewProjectionMatrixRelToEye * pos;\n\ - gl_PointSize = 1.0 + 50.0/gl_Position.z;\n\ + float z_b = gl_Position.z/gl_Position.w;\n\ + float z_n = 2.0 * z_b - 1.0;\n\ + float z_e = 2.0 * near * far / (far + near - z_n * (far - near));\n\ + gl_PointSize = 1.0 + 40.0/z_e; // Original.***\n\ if(gl_PointSize > 10.0)\n\ gl_PointSize = 10.0;\n\ + if(gl_PointSize < 2.0)\n\ + gl_PointSize = 2.0;\n\ + \n\ + depth = (modelViewMatrixRelToEye * pos).z/far; // original.***\n\ }"; -ShaderSource.RenderShowDepthFS = "#ifdef GL_ES\n\ -precision highp float;\n\ +ShaderSource.PointCloudFS = " precision lowp float;\n\ + varying vec4 vColor;\n\ +\n\ + void main()\n\ + {\n\ + gl_FragColor = vColor;\n\ + }"; +ShaderSource.PointCloudSsaoFS = "#ifdef GL_ES\n\ + precision highp float;\n\ #endif\n\ +\n\ +uniform sampler2D depthTex;\n\ +uniform mat4 projectionMatrix;\n\ uniform float near;\n\ -uniform float far;\n\ +uniform float far; \n\ +uniform float fov;\n\ +uniform float aspectRatio; \n\ +uniform float screenWidth; \n\ +uniform float screenHeight; \n\ +uniform vec3 kernel[16]; \n\ +uniform vec4 oneColor4;\n\ +varying vec4 aColor4; // color from attributes\n\ +varying vec4 vColor;\n\ +varying float glPointSize;\n\ \n\ -varying float depth; \n\ +const int kernelSize = 16; \n\ +uniform float radius; \n\ \n\ -vec4 packDepth(const in float depth)\n\ +uniform bool bApplySsao;\n\ +uniform float externalAlpha;\n\ +\n\ +float unpackDepth(const in vec4 rgba_depth)\n\ {\n\ - const vec4 bit_shift = vec4(16777216.0, 65536.0, 256.0, 1.0);\n\ - const vec4 bit_mask = vec4(0.0, 0.00390625, 0.00390625, 0.00390625); \n\ - vec4 res = fract(depth * bit_shift);\n\ - res -= res.xxyz * bit_mask;\n\ - return res; \n\ -}\n\ + const vec4 bit_shift = vec4(0.000000059605, 0.000015258789, 0.00390625, 1.0);\n\ + float depth = dot(rgba_depth, bit_shift);\n\ + return depth;\n\ +} \n\ +\n\ +vec3 getViewRay(vec2 tc)\n\ +{\n\ + float hfar = 2.0 * tan(fov/2.0) * far;\n\ + float wfar = hfar * aspectRatio; \n\ + vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n\ + return ray; \n\ +} \n\ + \n\ +//linear view space depth\n\ +float getDepth(vec2 coord)\n\ +{\n\ + return unpackDepth(texture2D(depthTex, coord.xy));\n\ +} \n\ \n\ void main()\n\ -{ \n\ - gl_FragData[0] = packDepth(-depth);\n\ -}\n\ -"; -ShaderSource.RenderShowDepthVS = "attribute vec3 position;\n\ +{\n\ + float occlusion = 0.0;\n\ + if(bApplySsao)\n\ + { \n\ + vec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight);\n\ + float linearDepth = getDepth(screenPos);\n\ + vec3 origin = getViewRay(screenPos) * linearDepth;\n\ + float radiusAux = glPointSize/1.9;\n\ + radiusAux = 1.5;\n\ + vec2 screenPosAdjacent;\n\ + \n\ + for(int j = 0; j < 1; ++j)\n\ + {\n\ + radiusAux = 1.5 *(float(j)+1.0);\n\ + for(int i = 0; i < 8; ++i)\n\ + { \n\ + if(i == 0)\n\ + screenPosAdjacent = vec2((gl_FragCoord.x - radiusAux)/ screenWidth, (gl_FragCoord.y - radiusAux) / screenHeight);\n\ + else if(i == 1)\n\ + screenPosAdjacent = vec2((gl_FragCoord.x)/ screenWidth, (gl_FragCoord.y - radiusAux) / screenHeight);\n\ + else if(i == 2)\n\ + screenPosAdjacent = vec2((gl_FragCoord.x + radiusAux)/ screenWidth, (gl_FragCoord.y - radiusAux) / screenHeight);\n\ + else if(i == 3)\n\ + screenPosAdjacent = vec2((gl_FragCoord.x + radiusAux)/ screenWidth, (gl_FragCoord.y) / screenHeight);\n\ + else if(i == 4)\n\ + screenPosAdjacent = vec2((gl_FragCoord.x + radiusAux)/ screenWidth, (gl_FragCoord.y + radiusAux) / screenHeight);\n\ + else if(i == 5)\n\ + screenPosAdjacent = vec2((gl_FragCoord.x)/ screenWidth, (gl_FragCoord.y + radiusAux) / screenHeight);\n\ + else if(i == 6)\n\ + screenPosAdjacent = vec2((gl_FragCoord.x - radiusAux)/ screenWidth, (gl_FragCoord.y + radiusAux) / screenHeight);\n\ + else if(i == 7)\n\ + screenPosAdjacent = vec2((gl_FragCoord.x - radiusAux)/ screenWidth, (gl_FragCoord.y) / screenHeight);\n\ + float depthBufferValue = getDepth(screenPosAdjacent);\n\ + float range_check = abs(linearDepth - depthBufferValue)*far;\n\ + if (range_check > 1.5 && depthBufferValue > linearDepth)\n\ + {\n\ + if (range_check < 20.0)\n\ + occlusion += 1.0;\n\ + }\n\ + } \n\ + } \n\ + \n\ + if(occlusion > 6.0)\n\ + occlusion = 8.0;\n\ + //else occlusion = 0.0;\n\ + occlusion = 1.0 - occlusion / 8.0;\n\ + }\n\ + else{\n\ + occlusion = 1.0;\n\ + }\n\ \n\ -uniform mat4 buildingRotMatrix; \n\ -uniform mat4 modelViewMatrixRelToEye; \n\ -uniform mat4 RefTransfMatrix;\n\ + vec4 finalColor;\n\ + finalColor = vec4((vColor.xyz) * occlusion, externalAlpha);\n\ + //finalColor = vec4(vec3(0.8, 0.8, 0.8) * occlusion, externalAlpha);\n\ + gl_FragColor = finalColor; \n\ +}"; +ShaderSource.PointCloudVS = "attribute vec3 position;\n\ uniform mat4 ModelViewProjectionMatrixRelToEye;\n\ uniform vec3 buildingPosHIGH;\n\ uniform vec3 buildingPosLOW;\n\ +uniform mat4 buildingRotMatrix;\n\ uniform vec3 encodedCameraPositionMCHigh;\n\ uniform vec3 encodedCameraPositionMCLow;\n\ uniform float near;\n\ uniform float far;\n\ -uniform vec3 aditionalPosition;\n\ -uniform vec3 refTranslationVec;\n\ -uniform int refMatrixType; // 0= identity, 1= translate, 2= transform\n\ +uniform bool bPositionCompressed;\n\ +uniform vec3 minPosition;\n\ +uniform vec3 bboxSize;\n\ +attribute vec4 color4;\n\ +uniform bool bUse1Color;\n\ +uniform vec4 oneColor4;\n\ +uniform float fixPointSize;\n\ +uniform bool bUseFixPointSize;\n\ +varying vec4 vColor;\n\ +varying float glPointSize;\n\ \n\ -varying float depth;\n\ - \n\ void main()\n\ -{ \n\ +{\n\ + vec3 realPos;\n\ vec4 rotatedPos;\n\ -\n\ - if(refMatrixType == 0)\n\ - {\n\ - rotatedPos = buildingRotMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\ - }\n\ - else if(refMatrixType == 1)\n\ + if(bPositionCompressed)\n\ {\n\ - rotatedPos = buildingRotMatrix * vec4(position.xyz + refTranslationVec.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\ + float maxShort = 65535.0;\n\ + realPos = vec3(float(position.x)/maxShort*bboxSize.x + minPosition.x, float(position.y)/maxShort*bboxSize.y + minPosition.y, float(position.z)/maxShort*bboxSize.z + minPosition.z);\n\ }\n\ - else if(refMatrixType == 2)\n\ + else\n\ {\n\ - rotatedPos = RefTransfMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\ + realPos = position;\n\ }\n\ -\n\ + rotatedPos = buildingRotMatrix * vec4(realPos.xyz, 1.0);\n\ vec3 objPosHigh = buildingPosHIGH;\n\ vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n\ vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\ vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\ - vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ - \n\ - //linear depth in camera space (0..far)\n\ - depth = (modelViewMatrixRelToEye * pos4).z/far;\n\ + vec4 pos = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ + \n\ + if(bUse1Color)\n\ + {\n\ + vColor=oneColor4;\n\ + }\n\ + else\n\ + vColor=color4;\n\ + \n\ + gl_Position = ModelViewProjectionMatrixRelToEye * pos;\n\ + float z_b = gl_Position.z/gl_Position.w;\n\ + float z_n = 2.0 * z_b - 1.0;\n\ + float z_e = 2.0 * near * far / (far + near - z_n * (far - near));\n\ + gl_PointSize = 1.0 + 40.0/z_e; // Original.***\n\ + if(gl_PointSize > 10.0)\n\ + gl_PointSize = 10.0;\n\ + if(gl_PointSize < 2.0)\n\ + gl_PointSize = 2.0;\n\ + \n\ + glPointSize = gl_PointSize;\n\ +}"; +ShaderSource.quad_vert = "precision mediump float;\n\ \n\ - gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\ - gl_PointSize = 2.0;\n\ +attribute vec2 a_pos;\n\ +\n\ +varying vec2 v_tex_pos;\n\ +\n\ +void main() {\n\ + v_tex_pos = a_pos;\n\ + gl_Position = vec4(1.0 - 2.0 * a_pos, 0, 1);\n\ }\n\ "; -ShaderSource.ShowDepthFS = "#ifdef GL_ES\n\ - precision highp float;\n\ +ShaderSource.RenderShowDepthFS = "#ifdef GL_ES\n\ +precision highp float;\n\ #endif\n\ uniform float near;\n\ uniform float far;\n\ \n\ varying float depth; \n\ -varying vec3 vN; \n\ -varying vec4 vVSPos;\n\ \n\ -// from http://spidergl.org/example.php?id=6\n\ vec4 packDepth(const in float depth)\n\ {\n\ const vec4 bit_shift = vec4(16777216.0, 65536.0, 256.0, 1.0);\n\ const vec4 bit_mask = vec4(0.0, 0.00390625, 0.00390625, 0.00390625); \n\ vec4 res = fract(depth * bit_shift);\n\ res -= res.xxyz * bit_mask;\n\ -\n\ return res; \n\ }\n\ \n\ void main()\n\ -{\n\ +{ \n\ gl_FragData[0] = packDepth(-depth);\n\ - gl_FragData[0].r = -depth/far;\n\ -}\n\ -"; -ShaderSource.ShowDepthVS = "attribute vec3 position;\n\ -attribute vec3 normal;\n\ +}"; +ShaderSource.RenderShowDepthVS = "attribute vec3 position;\n\ \n\ +uniform mat4 buildingRotMatrix; \n\ uniform mat4 modelViewMatrixRelToEye; \n\ +uniform mat4 RefTransfMatrix;\n\ uniform mat4 ModelViewProjectionMatrixRelToEye;\n\ -uniform mat4 normalMatrix3;\n\ -uniform mat4 normalMatrix4;\n\ uniform vec3 buildingPosHIGH;\n\ uniform vec3 buildingPosLOW;\n\ uniform vec3 encodedCameraPositionMCHigh;\n\ uniform vec3 encodedCameraPositionMCLow;\n\ uniform float near;\n\ uniform float far;\n\ -\n\ -varying vec3 vN;\n\ -varying float depth; \n\ -varying vec4 vVSPos;\n\ -\n\ -void main()\n\ -{ \n\ - vec3 objPosHigh = buildingPosHIGH;\n\ - vec3 objPosLow = buildingPosLOW.xyz + position.xyz;\n\ - vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\ - vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\ - vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ -\n\ - vN = normalize((normalMatrix4 * vec4(normal, 1.0)).xyz);\n\ - \n\ - //linear depth in camera space (0..far)\n\ - depth = (modelViewMatrixRelToEye * pos4).z/far;\n\ - vVSPos = modelViewMatrixRelToEye * pos4;\n\ -\n\ - gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\ -}\n\ -"; -ShaderSource.SilhouetteFS = "precision highp float;\n\ -uniform vec4 vColor4Aux;\n\ -\n\ -void main()\n\ -{ \n\ - gl_FragColor = vColor4Aux;\n\ -}"; -ShaderSource.SilhouetteVS = "attribute vec3 position;\n\ -\n\ -uniform mat4 buildingRotMatrix; \n\ -uniform mat4 ModelViewProjectionMatrixRelToEye;\n\ -uniform mat4 ModelViewMatrixRelToEye;\n\ -uniform mat4 ProjectionMatrix;\n\ -uniform mat4 RefTransfMatrix;\n\ -uniform vec3 buildingPosHIGH;\n\ -uniform vec3 buildingPosLOW;\n\ -uniform vec3 encodedCameraPositionMCHigh;\n\ -uniform vec3 encodedCameraPositionMCLow;\n\ uniform vec3 aditionalPosition;\n\ uniform vec3 refTranslationVec;\n\ uniform int refMatrixType; // 0= identity, 1= translate, 2= transform\n\ -uniform vec2 camSpacePixelTranslation;\n\ -uniform vec2 screenSize; \n\ -varying vec2 camSpaceTranslation;\n\ \n\ +varying float depth;\n\ + \n\ void main()\n\ -{ \n\ - vec4 rotatedPos;\n\ +{ \n\ + vec4 rotatedPos;\n\ +\n\ if(refMatrixType == 0)\n\ {\n\ rotatedPos = buildingRotMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\ @@ -51267,174 +64697,77 @@ void main()\n\ vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\ vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\ vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ - vec4 camSpacePos = ModelViewMatrixRelToEye * pos4;\n\ - vec4 translationVec = ProjectionMatrix * vec4(camSpacePixelTranslation.x*(-camSpacePos.z), camSpacePixelTranslation.y*(-camSpacePos.z), 0.0, 1.0);\n\ + \n\ + //linear depth in camera space (0..far)\n\ + depth = (modelViewMatrixRelToEye * pos4).z/far; // original.***\n\ \n\ gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\ - gl_Position += translationVec; \n\ + gl_PointSize = 2.0;\n\ }"; -ShaderSource.SimpleDepthSsaoFS = "precision highp float;\n\ -const vec4 bitEnc = vec4(1.0,255.0,65025.0,16581375.0);\n\ -const vec4 bitDec = 1.0/bitEnc;\n\ -varying float zDepth;\n\ -\n\ -vec4 EncodeFloatRGBA (float v)\n\ -{\n\ - vec4 enc = bitEnc * v;\n\ - enc = fract(enc);\n\ - enc -= enc.yzww * vec2(1.0/255.0, 0.0).xxxy;\n\ - return enc;\n\ -}\n\ -\n\ -void main()\n\ -{ \n\ - vec4 encodedZ = EncodeFloatRGBA(zDepth);\n\ - gl_FragData[0] = encodedZ;\n\ -}\n\ -"; -ShaderSource.SimpleDepthSsaoVS = "attribute vec3 position;\n\ +ShaderSource.screen_frag = "precision mediump float;\n\ \n\ -uniform mat4 modelViewMatrixRelToEye; \n\ -uniform mat4 ModelViewProjectionMatrixRelToEye;\n\ -uniform mat4 RefTransfMatrix;\n\ -uniform vec3 buildingPosHIGH;\n\ -uniform vec3 buildingPosLOW;\n\ -uniform vec3 encodedCameraPositionMCHigh;\n\ -uniform vec3 encodedCameraPositionMCLow;\n\ -varying float zDepth;\n\ -uniform float far;\n\ +uniform sampler2D u_screen;\n\ +uniform float u_opacity;\n\ \n\ -void main()\n\ -{ \n\ - vec4 rotatedPos = RefTransfMatrix * vec4(position.xyz, 1.0);\n\ - vec3 objPosHigh = buildingPosHIGH;\n\ - vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n\ - vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\ - vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\ - vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ - \n\ - zDepth = (modelViewMatrixRelToEye * pos4).z/far;\n\ +varying vec2 v_tex_pos;\n\ \n\ - gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\ +void main() {\n\ + vec4 color = texture2D(u_screen, 1.0 - v_tex_pos);\n\ + // a hack to guarantee opacity fade out even with a value close to 1.0\n\ + gl_FragColor = vec4(floor(255.0 * color * u_opacity) / 255.0);\n\ }\n\ "; -ShaderSource.SsaoFS = "#ifdef GL_ES\n\ - precision highp float;\n\ -#endif\n\ -uniform sampler2D depthTex;\n\ -uniform sampler2D noiseTex; \n\ -uniform sampler2D diffuseTex;\n\ -varying vec3 vNormal;\n\ -uniform mat4 projectionMatrix;\n\ -uniform mat4 m;\n\ -uniform vec2 noiseScale;\n\ -uniform float near;\n\ -uniform float far; \n\ -uniform float fov;\n\ -uniform float aspectRatio; \n\ -uniform float screenWidth; \n\ -uniform float screenHeight; \n\ -uniform vec3 kernel[16]; \n\ -\n\ -varying vec2 vTexCoord; \n\ -\n\ -const int kernelSize = 16; \n\ -const float radius = 1.0; \n\ -\n\ -float unpackDepth(const in vec4 rgba_depth)\n\ -{\n\ - const vec4 bit_shift = vec4(0.000000059605, 0.000015258789, 0.00390625, 1.0);\n\ - float depth = dot(rgba_depth, bit_shift);\n\ - return depth;\n\ -} \n\ -\n\ -vec3 getViewRay(vec2 tc)\n\ -{\n\ - float hfar = 2.0 * tan(fov/2.0) * far;\n\ - float wfar = hfar * aspectRatio; \n\ - vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n\ - return ray; \n\ -} \n\ - \n\ -//linear view space depth\n\ -float getDepth(vec2 coord)\n\ -{ \n\ - return unpackDepth(texture2D(depthTex, coord.xy));\n\ -} \n\ +ShaderSource.SilhouetteFS = "precision highp float;\n\ +uniform vec4 vColor4Aux;\n\ \n\ void main()\n\ { \n\ - vec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight); \n\ - float linearDepth = getDepth(screenPos); \n\ - vec3 origin = getViewRay(screenPos) * linearDepth; \n\ - \n\ - vec3 normal2 = vNormal; \n\ - \n\ - vec3 rvec = texture2D(noiseTex, screenPos.xy * noiseScale).xyz * 2.0 - 1.0;\n\ - vec3 tangent = normalize(rvec - normal2 * dot(rvec, normal2));\n\ - vec3 bitangent = cross(normal2, tangent);\n\ - mat3 tbn = mat3(tangent, bitangent, normal2); \n\ - \n\ - float occlusion = 0.0;\n\ - for(int i = 0; i < kernelSize; ++i)\n\ - { \n\ - vec3 sample = origin + (tbn * kernel[i]) * radius;\n\ - vec4 offset = projectionMatrix * vec4(sample, 1.0); \n\ - offset.xy /= offset.w;\n\ - offset.xy = offset.xy * 0.5 + 0.5; \n\ - float sampleDepth = -sample.z/far;\n\ - float depthBufferValue = getDepth(offset.xy); \n\ -\n\ - float range_check = abs(linearDepth - depthBufferValue)+radius*0.998;\n\ - if (range_check < radius && depthBufferValue <= sampleDepth)\n\ - {\n\ - occlusion += 1.0;\n\ - }\n\ - \n\ - } \n\ - \n\ - occlusion = 1.0 - (occlusion) / float(kernelSize);\n\ - \n\ - vec3 lightPos = vec3(10.0, 10.0, 10.0);\n\ - vec3 L = normalize(lightPos);\n\ - float NdotL = abs(dot(normal2, L));\n\ - vec3 diffuse = vec3(NdotL);\n\ - vec3 ambient = vec3(1.0);\n\ - vec4 textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, vTexCoord.t));\n\ -\n\ - gl_FragColor.rgb = vec3((textureColor.xyz*0.2 + textureColor.xyz*0.8) * occlusion); // with texture.***\n\ - gl_FragColor.a = 1.0; \n\ -}\n\ -"; -ShaderSource.SsaoVS = "attribute vec3 position;\n\ -attribute vec3 normal;\n\ -attribute vec2 texCoord;\n\ + gl_FragColor = vColor4Aux;\n\ +}"; +ShaderSource.SilhouetteVS = "attribute vec3 position;\n\ \n\ -uniform mat4 projectionMatrix; \n\ -uniform mat4 modelViewMatrix;\n\ -uniform mat4 modelViewMatrixRelToEye; \n\ +uniform mat4 buildingRotMatrix; \n\ uniform mat4 ModelViewProjectionMatrixRelToEye;\n\ -uniform mat4 normalMatrix4;\n\ +uniform mat4 ModelViewMatrixRelToEye;\n\ +uniform mat4 ProjectionMatrix;\n\ +uniform mat4 RefTransfMatrix;\n\ uniform vec3 buildingPosHIGH;\n\ uniform vec3 buildingPosLOW;\n\ uniform vec3 encodedCameraPositionMCHigh;\n\ uniform vec3 encodedCameraPositionMCLow;\n\ -\n\ -varying vec3 vNormal;\n\ -varying vec2 vTexCoord; \n\ +uniform vec3 aditionalPosition;\n\ +uniform vec3 refTranslationVec;\n\ +uniform int refMatrixType; // 0= identity, 1= translate, 2= transform\n\ +uniform vec2 camSpacePixelTranslation;\n\ +uniform vec2 screenSize; \n\ +varying vec2 camSpaceTranslation;\n\ \n\ void main()\n\ -{ \n\ +{ \n\ + vec4 rotatedPos;\n\ + if(refMatrixType == 0)\n\ + {\n\ + rotatedPos = buildingRotMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\ + }\n\ + else if(refMatrixType == 1)\n\ + {\n\ + rotatedPos = buildingRotMatrix * vec4(position.xyz + refTranslationVec.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\ + }\n\ + else if(refMatrixType == 2)\n\ + {\n\ + rotatedPos = RefTransfMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\ + }\n\ +\n\ vec3 objPosHigh = buildingPosHIGH;\n\ - vec3 objPosLow = buildingPosLOW.xyz + position.xyz;\n\ + vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n\ vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\ vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\ vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ -\n\ - vNormal = (normalMatrix4 * vec4(-normal.x, -normal.y, -normal.z, 1.0)).xyz;\n\ - vTexCoord = texCoord;\n\ + vec4 camSpacePos = ModelViewMatrixRelToEye * pos4;\n\ + vec4 translationVec = ProjectionMatrix * vec4(camSpacePixelTranslation.x*(-camSpacePos.z), camSpacePixelTranslation.y*(-camSpacePos.z), 0.0, 1.0);\n\ \n\ gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\ + gl_Position += translationVec; \n\ }"; ShaderSource.StandardFS = "precision lowp float;\n\ varying vec3 vColor;\n\ @@ -51466,6 +64799,50 @@ void main()\n\ \n\ gl_Position = ModelViewProjectionMatrixRelToEye * pos;\n\ }"; +ShaderSource.Test_QuadFS = "#ifdef GL_ES\n\ + precision highp float;\n\ +#endif\n\ + \n\ +uniform sampler2D diffuseTex; \n\ +varying vec2 vTexCoord; \n\ +void main()\n\ +{ \n\ + vec4 textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, vTexCoord.t));\n\ + gl_FragColor = textureColor; \n\ +}\n\ +"; +ShaderSource.Test_QuadVS = "attribute vec3 position;\n\ +attribute vec2 texCoord;\n\ +\n\ +uniform sampler2D diffuseTex;\n\ +uniform mat4 projectionMatrix; \n\ +uniform mat4 modelViewMatrix;\n\ +uniform mat4 modelViewMatrixRelToEye; \n\ +uniform mat4 ModelViewProjectionMatrixRelToEye;\n\ +uniform mat4 normalMatrix4;\n\ +uniform mat4 buildingRotMatrix; \n\ +uniform vec3 buildingPosHIGH;\n\ +uniform vec3 buildingPosLOW;\n\ +uniform vec3 encodedCameraPositionMCHigh;\n\ +uniform vec3 encodedCameraPositionMCLow;\n\ +\n\ +varying vec3 vNormal;\n\ +varying vec2 vTexCoord; \n\ +\n\ +void main()\n\ +{ \n\ + vec4 rotatedPos = buildingRotMatrix * vec4(position.xyz, 1.0);\n\ + vec3 objPosHigh = buildingPosHIGH;\n\ + vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n\ + vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\ + vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\ + vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ + \n\ + vTexCoord = texCoord;\n\ +\n\ + gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\ +}\n\ +"; ShaderSource.TextureA1FS = "precision mediump float;\n\ varying vec4 vColor;\n\ varying vec2 vTextureCoord;\n\ @@ -51647,8 +65024,8 @@ vec3 getViewRay(vec2 tc)\n\ float wfar = hfar * aspectRatio; \n\ vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n\ return ray; \n\ -} \n\ - \n\ +}\n\ +\n\ //linear view space depth\n\ float getDepth(vec2 coord)\n\ {\n\ @@ -51737,1710 +65114,2360 @@ void main()\n\ gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\ \n\ }"; +ShaderSource.update_frag = "precision highp float;\n\ +\n\ +uniform sampler2D u_particles;\n\ +uniform sampler2D u_wind;\n\ +uniform vec2 u_wind_res;\n\ +uniform vec2 u_wind_min;\n\ +uniform vec2 u_wind_max;\n\ +uniform float u_rand_seed;\n\ +uniform float u_speed_factor;\n\ +uniform float u_drop_rate;\n\ +uniform float u_drop_rate_bump;\n\ +uniform bool u_flipTexCoordY_windMap;\n\ +\n\ +varying vec2 v_tex_pos;\n\ +\n\ +// pseudo-random generator\n\ +const vec3 rand_constants = vec3(12.9898, 78.233, 4375.85453);\n\ +float rand(const vec2 co) {\n\ + float t = dot(rand_constants.xy, co);\n\ + return fract(sin(t) * (rand_constants.z + t));\n\ +}\n\ +\n\ +// wind speed lookup; use manual bilinear filtering based on 4 adjacent pixels for smooth interpolation\n\ +vec2 lookup_wind(const vec2 uv) {\n\ + // return texture2D(u_wind, uv).rg; // lower-res hardware filtering\n\ + vec2 px = 1.0 / u_wind_res;\n\ + vec2 vc = (floor(uv * u_wind_res)) * px;\n\ + vec2 f = fract(uv * u_wind_res);\n\ + vec2 tl = texture2D(u_wind, vc).rg;\n\ + vec2 tr = texture2D(u_wind, vc + vec2(px.x, 0)).rg;\n\ + vec2 bl = texture2D(u_wind, vc + vec2(0, px.y)).rg;\n\ + vec2 br = texture2D(u_wind, vc + px).rg;\n\ + return mix(mix(tl, tr, f.x), mix(bl, br, f.x), f.y);\n\ +}\n\ +\n\ +void main() {\n\ + vec4 color = texture2D(u_particles, v_tex_pos);\n\ + vec2 pos = vec2(\n\ + color.r / 255.0 + color.b,\n\ + color.g / 255.0 + color.a); // decode particle position from pixel RGBA\n\ + vec2 windMapTexCoord = pos;\n\ + if(u_flipTexCoordY_windMap)\n\ + {\n\ + windMapTexCoord.y = 1.0 - windMapTexCoord.y;\n\ + }\n\ + vec2 velocity = mix(u_wind_min, u_wind_max, lookup_wind(windMapTexCoord));\n\ + float speed_t = length(velocity) / length(u_wind_max);\n\ +\n\ + // take EPSG:4236 distortion into account for calculating where the particle moved\n\ + float distortion = cos(radians(pos.y * 180.0 - 90.0));\n\ + vec2 offset = vec2(velocity.x / distortion, -velocity.y) * 0.0001 * u_speed_factor;\n\ +\n\ + // update particle position, wrapping around the date line\n\ + pos = fract(1.0 + pos + offset);\n\ +\n\ + // a random seed to use for the particle drop\n\ + vec2 seed = (pos + v_tex_pos) * u_rand_seed;\n\ +\n\ + // drop rate is a chance a particle will restart at random position, to avoid degeneration\n\ + float drop_rate = u_drop_rate + speed_t * u_drop_rate_bump;\n\ + float drop = step(1.0 - drop_rate, rand(seed));\n\ +\n\ + vec2 random_pos = vec2(\n\ + rand(seed + 1.3),\n\ + rand(seed + 2.1));\n\ + pos = mix(pos, random_pos, drop);\n\ +\n\ + // encode the new particle position back into RGBA\n\ + gl_FragColor = vec4(\n\ + fract(pos * 255.0),\n\ + floor(pos * 255.0) / 255.0);\n\ +}"; +ShaderSource.vol_fs = "#ifdef GL_ES\n\ +precision highp float;\n\ +#endif\n\ +\n\ +//---------------------------------------------------------\n\ +// MACROS\n\ +//---------------------------------------------------------\n\ +\n\ +#define EPS 0.0001\n\ +#define PI 3.14159265\n\ +#define HALFPI 1.57079633\n\ +#define ROOTTHREE 1.73205081\n\ +\n\ +#define EQUALS(A,B) ( abs((A)-(B)) < EPS )\n\ +#define EQUALSZERO(A) ( ((A)-EPS) )\n\ +\n\ +\n\ +//---------------------------------------------------------\n\ +// CONSTANTS\n\ +//---------------------------------------------------------\n\ +\n\ +// 32 48 64 96 128\n\ +#define MAX_STEPS 64\n\ +\n\ +#define LIGHT_NUM 2\n\ +//#define uTMK 20.0\n\ +#define TM_MIN 0.05\n\ +\n\ +\n\ +//---------------------------------------------------------\n\ +// SHADER VARS\n\ +//---------------------------------------------------------\n\ +\n\ +varying vec2 vUv;\n\ +varying vec3 vPos0; // position in world coords\n\ +varying vec3 vPos1; // position in object coords\n\ +varying vec3 vPos1n; // normalized 0 to 1, for texture lookup\n\ +\n\ +uniform vec3 uOffset; // TESTDEBUG\n\ +\n\ +uniform vec3 uCamPos;\n\ +\n\ +uniform vec3 uLightP[LIGHT_NUM]; // point lights\n\ +uniform vec3 uLightC[LIGHT_NUM];\n\ +\n\ +uniform vec3 uColor; // color of volume\n\ +uniform sampler2D uTex; // 3D(2D) volume texture\n\ +uniform vec3 uTexDim; // dimensions of texture\n\ +\n\ +uniform float uTMK;\n\ +\n\ +float gStepSize;\n\ +float gStepFactor;\n\ +\n\ +\n\ +//---------------------------------------------------------\n\ +// PROGRAM\n\ +//---------------------------------------------------------\n\ +\n\ +// TODO: convert world to local volume space\n\ +vec3 toLocal(vec3 p) {\n\ + return p + vec3(0.5);\n\ +}\n\ +\n\ +float sampleVolTex(vec3 pos) {\n\ + pos = pos + uOffset; // TESTDEBUG\n\ + \n\ + // note: z is up in 3D tex coords, pos.z is tex.y, pos.y is zSlice\n\ + float zSlice = (1.0-pos.y)*(uTexDim.z-1.0); // float value of slice number, slice 0th to 63rd\n\ + \n\ + // calc pixels from top of texture\n\ + float fromTopPixels =\n\ + floor(zSlice)*uTexDim.y + // offset pix from top of tex, from upper slice \n\ + pos.z*(uTexDim.y-1.0) + // y pos in pixels, range 0th to 63rd pix\n\ + 0.5; // offset to center of cell\n\ + \n\ + // calc y tex coords of two slices\n\ + float y0 = min( (fromTopPixels)/(uTexDim.y*uTexDim.z), 1.0);\n\ + float y1 = min( (fromTopPixels+uTexDim.y)/(uTexDim.y*uTexDim.z), 1.0);\n\ + \n\ + // get (bi)linear interped texture reads at two slices\n\ + float z0 = texture2D(uTex, vec2(pos.x, y0)).g;\n\ + float z1 = texture2D(uTex, vec2(pos.x, y1)).g;\n\ + \n\ + // lerp them again (thus trilinear), using remaining fraction of zSlice\n\ + return mix(z0, z1, fract(zSlice));\n\ +}\n\ +\n\ +// accumulate density by ray marching\n\ +float getDensity(vec3 ro, vec3 rd) {\n\ + vec3 step = rd*gStepSize;\n\ + vec3 pos = ro;\n\ + \n\ + float density = 0.0;\n\ + \n\ + for (int i=0; i 0.95 ||\n\ + pos.x > 1.0 || pos.x < 0.0 ||\n\ + pos.y > 1.0 || pos.y < 0.0 ||\n\ + pos.z > 1.0 || pos.z < 0.0)\n\ + break;\n\ + }\n\ + \n\ + return density;\n\ +}\n\ +\n\ +// calc transmittance\n\ +float getTransmittance(vec3 ro, vec3 rd) {\n\ + vec3 step = rd*gStepSize;\n\ + vec3 pos = ro;\n\ + \n\ + float tm = 1.0;\n\ + \n\ + for (int i=0; i 1.0 || pos.x < 0.0 ||\n\ + pos.y > 1.0 || pos.y < 0.0 ||\n\ + pos.z > 1.0 || pos.z < 0.0)\n\ + break;\n\ + }\n\ + \n\ + return tm;\n\ +}\n\ +\n\ +vec4 raymarchNoLight(vec3 ro, vec3 rd) {\n\ + vec3 step = rd*gStepSize;\n\ + vec3 pos = ro;\n\ + \n\ + vec3 col = vec3(0.0);\n\ + float tm = 1.0;\n\ + \n\ + for (int i=0; i 1.0 || pos.x < 0.0 ||\n\ + pos.y > 1.0 || pos.y < 0.0 ||\n\ + pos.z > 1.0 || pos.z < 0.0)\n\ + break;\n\ + }\n\ + \n\ + float alpha = 1.0-tm;\n\ + return vec4(col/alpha, alpha);\n\ +}\n\ +\n\ +vec4 raymarchLight(vec3 ro, vec3 rd) {\n\ + vec3 step = rd*gStepSize;\n\ + vec3 pos = ro;\n\ + \n\ + \n\ + vec3 col = vec3(0.0); // accumulated color\n\ + float tm = 1.0; // accumulated transmittance\n\ + \n\ + for (int i=0; i 1.0 || pos.x < 0.0 ||\n\ + pos.y > 1.0 || pos.y < 0.0 ||\n\ + pos.z > 1.0 || pos.z < 0.0)\n\ + break;\n\ + }\n\ + \n\ + float alpha = 1.0-tm;\n\ + return vec4(col/alpha, alpha);\n\ +}\n\ +\n\ +void main() {\n\ + // in world coords, just for now\n\ + vec3 ro = vPos1n;\n\ + vec3 rd = normalize( ro - toLocal(uCamPos) );\n\ + //vec3 rd = normalize(ro-uCamPos);\n\ + \n\ + // step_size = root_three / max_steps ; to get through diagonal \n\ + gStepSize = ROOTTHREE / float(MAX_STEPS);\n\ + gStepFactor = 32.0 * gStepSize;\n\ + \n\ + gl_FragColor = raymarchLight(ro, rd);\n\ + //gl_FragColor = vec4(uColor, getDensity(ro,rd));\n\ + //gl_FragColor = vec4(vec3(sampleVolTex(pos)), 1.0);\n\ + //gl_FragColor = vec4(vPos1n, 1.0);\n\ + //gl_FragColor = vec4(uLightP[0], 1.0);\n\ +}"; +ShaderSource.vol_vs = "attribute vec3 aPosition;\n\ +\n\ +uniform sampler2D diffuseTex;\n\ +uniform mat4 projectionMatrix; \n\ +uniform mat4 modelViewMatrix;\n\ +uniform mat4 modelViewMatrixRelToEye; \n\ +uniform mat4 ModelViewProjectionMatrixRelToEye;\n\ +uniform vec3 encodedCameraPositionMCHigh;\n\ +uniform vec3 encodedCameraPositionMCLow;\n\ +\n\ +varying vec3 vNormal;\n\ +varying vec3 vPosObjectCoord;\n\ +varying vec3 vPosCameraCoord;\n\ +varying vec3 vPosWorldCoord;\n\ +\n\ +// Render a fullScreen quad (2 triangles).***\n\ +void main()\n\ +{\n\ + vec4 rotatedPos = buildingRotMatrix * vec4(position.xyz + aditionalPosition.xyz, 1.0);\n\ + vec3 objPosHigh = buildingPosHIGH;\n\ + vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n\ + vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\ + vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\ + vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\ + \n\ + gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\ +}"; +ShaderSource.wgs84_volumFS = "precision mediump float;\n\ +\n\ +#define M_PI 3.1415926535897932384626433832795\n\ +\n\ +uniform sampler2D volumeTex;\n\ +uniform mat4 projectionMatrix; \n\ +uniform mat4 modelViewMatrix;\n\ +uniform mat4 modelViewMatrixInv;\n\ +uniform mat4 modelViewMatrixRelToEye; \n\ +uniform mat4 ModelViewProjectionMatrixRelToEye;\n\ +uniform vec3 encodedCameraPositionMCHigh;\n\ +uniform vec3 encodedCameraPositionMCLow;\n\ +\n\ +uniform float screenWidth; \n\ +uniform float screenHeight;\n\ +uniform float aspectRatio;\n\ +uniform float far;\n\ +uniform float fovyRad;\n\ +uniform float tanHalfFovy;\n\ +\n\ +// volume tex definition.***\n\ +uniform int texNumCols;\n\ +uniform int texNumRows;\n\ +uniform int texNumSlices;\n\ +uniform int numSlicesPerStacks;\n\ +uniform int slicesNumCols;\n\ +uniform int slicesNumRows;\n\ +uniform float maxLon;\n\ +uniform float minLon;\n\ +uniform float maxLat;\n\ +uniform float minLat;\n\ +uniform float maxAlt;\n\ +uniform float minAlt;\n\ +uniform vec4 cuttingPlanes[6]; \n\ +uniform int cuttingPlanesCount;\n\ +\n\ +uniform float maxValue;\n\ +uniform float minValue;\n\ +\n\ +vec3 getViewRay(vec2 tc)\n\ +{\n\ + float hfar = 2.0 * tanHalfFovy * far;\n\ + float wfar = hfar * aspectRatio; \n\ + vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n\ + return ray; \n\ +} \n\ +\n\ +float squaredLength(vec3 point1, vec3 point2)\n\ +{\n\ + float a = point1.x - point2.x;\n\ + float b = point1.y - point2.y;\n\ + float c = point1.z - point2.z;\n\ + \n\ + float sqDist = a*a + b*b + c*c;\n\ + return sqDist;\n\ +}\n\ +\n\ +void intersectionLineSphere(float radius, vec3 rayPos, vec3 rayDir, out int intersectType, out vec3 nearIntersectPos, out vec3 farIntersectPos)\n\ +{\n\ + // line: (x, y, z) = x1 + t(x2 - x1), y1 + t(y2 - y1), z1 + t(z2 - z1)\n\ + // sphere: (x - x3)^2 + (y - y3)^2 + (z - z3)^2 = r^2, where x3, y3, z3 is the center of the sphere.\n\ + \n\ + // line:\n\ + vec3 p1 = rayPos;\n\ + vec3 lineDir = rayDir;\n\ + float dist = 1000.0;// any value is ok.***\n\ + vec3 p2 = vec3(p1.x + lineDir.x * dist, p1.y + lineDir.y * dist, p1.z + lineDir.z * dist);\n\ + float x1 = p1.x;\n\ + float y1 = p1.y;\n\ + float z1 = p1.z;\n\ + float x2 = p2.x;\n\ + float y2 = p2.y;\n\ + float z2 = p2.z;\n\ +\n\ + // sphere:\n\ + float x3 = 0.0;\n\ + float y3 = 0.0;\n\ + float z3 = 0.0;\n\ + float r = radius;\n\ + \n\ + // resolve:\n\ + float x21 = (x2-x1);\n\ + float y21 = (y2-y1);\n\ + float z21 = (z2-z1);\n\ + \n\ + float a = x21*x21 + y21*y21 + z21*z21;\n\ + \n\ + float x13 = (x1-x3);\n\ + float y13 = (y1-y3);\n\ + float z13 = (z1-z3);\n\ + \n\ + float b = 2.0*(x21 * x13 + y21 * y13 + z21 * z13);\n\ + \n\ + float c = x3*x3 + y3*y3 + z3*z3 + x1*x1 + y1*y1 + z1*z1 - 2.0*(x3*x1 + y3*y1+ z3*z1) - r*r;\n\ + \n\ + float discriminant = b*b - 4.0*a*c;\n\ + \n\ + if (discriminant < 0.0)\n\ + {\n\ + // no intersection.***\n\ + intersectType = 0;\n\ + }\n\ + else if (discriminant == 0.0)\n\ + {\n\ + // this is tangent.***\n\ + intersectType = 1;\n\ + \n\ + float t1 = (-b)/(2.0*a);\n\ + nearIntersectPos = vec3(x1 + (x2 - x1)*t1, y1 + (y2 - y1)*t1, z1 + (z2 - z1)*t1);\n\ + }\n\ + else\n\ + {\n\ + intersectType = 2;\n\ + \n\ + // find the nearest to p1.***\n\ + float sqrtDiscriminant = sqrt(discriminant);\n\ + float t1 = (-b + sqrtDiscriminant)/(2.0*a);\n\ + float t2 = (-b - sqrtDiscriminant)/(2.0*a);\n\ + \n\ + // solution 1.***\n\ + vec3 intersectPoint1 = vec3(x1 + (x2 - x1)*t1, y1 + (y2 - y1)*t1, z1 + (z2 - z1)*t1);\n\ + vec3 intersectPoint2 = vec3(x1 + (x2 - x1)*t2, y1 + (y2 - y1)*t2, z1 + (z2 - z1)*t2);\n\ + \n\ + float dist1 = squaredLength(p1,intersectPoint1);\n\ + float dist2 = squaredLength(p1,intersectPoint2);\n\ + \n\ + // nearIntersectPos, out vec3 farIntersectPos\n\ + if (dist1 < dist2)\n\ + {\n\ + nearIntersectPos = intersectPoint1;\n\ + farIntersectPos = intersectPoint2;\n\ + }\n\ + else\n\ + {\n\ + nearIntersectPos = intersectPoint2;\n\ + farIntersectPos = intersectPoint1;\n\ + }\n\ + }\n\ +}\n\ +\n\ +float atan2(float y, float x) \n\ +{\n\ + if(x > 0.0)\n\ + {\n\ + return atan(y/x);\n\ + }\n\ + else if(x < 0.0)\n\ + {\n\ + if(y >= 0.0)\n\ + {\n\ + return atan(y/x) + M_PI;\n\ + }\n\ + else{\n\ + return atan(y/x) - M_PI;\n\ + }\n\ + }\n\ + else if(x == 0.0)\n\ + {\n\ + if(y>0.0)\n\ + {\n\ + return M_PI/2.0;\n\ + }\n\ + else if(y<0.0)\n\ + {\n\ + return -M_PI/2.0;\n\ + }\n\ + else{\n\ + return 0.0; // return undefined.***\n\ + }\n\ + }\n\ +}\n\ +\n\ +void cartesianToGeographicWgs84(vec3 point, out vec3 result) \n\ +{\n\ + // From WebWorldWind.***\n\ + // According to H. Vermeille, An analytical method to transform geocentric into geodetic coordinates\n\ + // http://www.springerlink.com/content/3t6837t27t351227/fulltext.pdf\n\ + \n\ + float firstEccentricitySquared = 6.69437999014E-3;\n\ + float equatorialRadius = 6378137.0;\n\ +\n\ + // wwwind coord type.***\n\ + // X = point.z;\n\ + // Y = point.x;\n\ + // Z = point.y;\n\ +\n\ + // magoWorld coord type.***\n\ + float X = point.x;\n\ + float Y = point.y;\n\ + float Z = point.z;\n\ + float XXpYY = X * X + Y * Y;\n\ + float sqrtXXpYY = sqrt(XXpYY);\n\ + float a = equatorialRadius;\n\ + float ra2 = 1.0 / (a * a);\n\ + float e2 = firstEccentricitySquared;\n\ + float e4 = e2 * e2;\n\ + float p = XXpYY * ra2;\n\ + float q = Z * Z * (1.0 - e2) * ra2;\n\ + float r = (p + q - e4) / 6.0;\n\ + float h;\n\ + float phi;\n\ + float u;\n\ + float evoluteBorderTest = 8.0 * r * r * r + e4 * p * q;\n\ + float rad1;\n\ + float rad2;\n\ + float rad3;\n\ + float atanAux;\n\ + float v;\n\ + float w;\n\ + float k;\n\ + float D;\n\ + float sqrtDDpZZ;\n\ + float e;\n\ + float lambda;\n\ + float s2;\n\ + float cbrtFac = 1.0/3.0;\n\ +\n\ + if (evoluteBorderTest > 0.0 || q != 0.0) \n\ + {\n\ + if (evoluteBorderTest > 0.0) \n\ + {\n\ + // Step 2: general case\n\ + rad1 = sqrt(evoluteBorderTest);\n\ + rad2 = sqrt(e4 * p * q);\n\ +\n\ + // 10*e2 is my arbitrary decision of what Vermeille means by near... the cusps of the evolute.\n\ + if (evoluteBorderTest > 10.0 * e2) \n\ + {\n\ + rad3 = pow((rad1 + rad2) * (rad1 + rad2), cbrtFac);\n\ + u = r + 0.5 * rad3 + 2.0 * r * r / rad3;\n\ + }\n\ + else \n\ + {\n\ + u = r + 0.5 * pow((rad1 + rad2) * (rad1 + rad2), cbrtFac)\n\ + + 0.5 * pow((rad1 - rad2) * (rad1 - rad2), cbrtFac);\n\ + }\n\ + }\n\ + else \n\ + {\n\ + // Step 3: near evolute\n\ + rad1 = sqrt(-evoluteBorderTest);\n\ + rad2 = sqrt(-8.0 * r * r * r);\n\ + rad3 = sqrt(e4 * p * q);\n\ + atanAux = 2.0 * atan2(rad3, rad1 + rad2) / 3.0;\n\ +\n\ + u = -4.0 * r * sin(atanAux) * cos(M_PI / 6.0 + atanAux);\n\ + }\n\ +\n\ + v = sqrt(u * u + e4 * q);\n\ + w = e2 * (u + v - q) / (2.0 * v);\n\ + k = (u + v) / (sqrt(w * w + u + v) + w);\n\ + D = k * sqrtXXpYY / (k + e2);\n\ + sqrtDDpZZ = sqrt(D * D + Z * Z);\n\ +\n\ + h = (k + e2 - 1.0) * sqrtDDpZZ / k;\n\ + phi = 2.0 * atan2(Z, sqrtDDpZZ + D);\n\ + }\n\ + else \n\ + {\n\ + // Step 4: singular disk\n\ + rad1 = sqrt(1.0 - e2);\n\ + rad2 = sqrt(e2 - p);\n\ + e = sqrt(e2);\n\ +\n\ + h = -a * rad1 * rad2 / e;\n\ + phi = rad2 / (e * rad2 + rad1 * sqrt(p));\n\ + }\n\ +\n\ + // Compute lambda\n\ + s2 = sqrt(2.0);\n\ + if ((s2 - 1.0) * Y < sqrtXXpYY + X) \n\ + {\n\ + // case 1 - -135deg < lambda < 135deg\n\ + lambda = 2.0 * atan2(Y, sqrtXXpYY + X);\n\ + }\n\ + else if (sqrtXXpYY + Y < (s2 + 1.0) * X) \n\ + {\n\ + // case 2 - -225deg < lambda < 45deg\n\ + lambda = -M_PI * 0.5 + 2.0 * atan2(X, sqrtXXpYY - Y);\n\ + }\n\ + else \n\ + {\n\ + // if (sqrtXXpYY-Y<(s2=1)*X) { // is the test, if needed, but it's not\n\ + // case 3: - -45deg < lambda < 225deg\n\ + lambda = M_PI * 0.5 - 2.0 * atan2(X, sqrtXXpYY + Y);\n\ + }\n\ +\n\ + float factor = 180.0 / M_PI;\n\ + result = vec3(factor * lambda, factor * phi, h); // (longitude, latitude, altitude).***\n\ +}\n\ +\n\ +bool isPointRearCamera(vec3 point, vec3 camPos, vec3 camDir)\n\ +{\n\ + bool isRear = false;\n\ + float lambdaX = 10.0;\n\ + float lambdaY = 10.0;\n\ + float lambdaZ = 10.0;\n\ + if(abs(camDir.x) > 0.0000001)\n\ + {\n\ + float lambdaX = (point.x - camPos.x)/camDir.x;\n\ + }\n\ + else if(abs(camDir.y) > 0.0000001)\n\ + {\n\ + float lambdaY = (point.y - camPos.y)/camDir.y;\n\ + }\n\ + else if(abs(camDir.z) > 0.0000001)\n\ + {\n\ + float lambdaZ = (point.z - camPos.z)/camDir.z;\n\ + }\n\ + \n\ + if(lambdaZ < 0.0 || lambdaY < 0.0 || lambdaX < 0.0)\n\ + isRear = true;\n\ + else\n\ + isRear = false;\n\ + return isRear;\n\ +}\n\ +\n\ +float distPointToPlane(vec3 point, vec4 plane)\n\ +{\n\ + return (point.x*plane.x + point.y*plane.y + point.z*plane.z + plane.w);\n\ +}\n\ +\n\ +bool getValue(vec3 geoLoc, out vec4 value)\n\ +{\n\ + // geoLoc = (longitude, latitude, altitude).***\n\ + float lon = geoLoc.x;\n\ + float lat = geoLoc.y;\n\ + float alt = geoLoc.z;\n\ + \n\ + // 1rst, check if geoLoc intersects the volume.***\n\ + // Note: minLon, maxLon, minLat, maxLat, minAlt & maxAlt are uniforms.***\n\ + if(lon < minLon || lon > maxLon)\n\ + return false;\n\ + else if(lat < minLat || lat > maxLat)\n\ + return false;\n\ + else if(alt < minAlt || alt > maxAlt)\n\ + return false;\n\ + \n\ + float lonRange = maxLon - minLon;\n\ + float latRange = maxLat - minLat;\n\ + float altRange = maxAlt - minAlt;\n\ + float col = (lon - minLon)/lonRange * float(slicesNumCols); \n\ + float row = (lat - minLat)/latRange * float(slicesNumRows); \n\ + float slice = (alt - minAlt)/altRange * float(texNumSlices); // slice if texture has only one stack.***\n\ + float sliceDown = floor(slice);\n\ + float sliceUp = ceil(slice);\n\ + float sliceDownDist = slice - sliceDown;\n\ + //slice = 18.0; // test. force slice to nearest to ground.***\n\ + \n\ + float stackDown = floor(sliceDown/float(numSlicesPerStacks));\n\ + float realSliceDown = sliceDown - stackDown * float(numSlicesPerStacks);\n\ + float tx = stackDown * float(slicesNumCols) + col;\n\ + float ty = realSliceDown * float(slicesNumRows) + row;\n\ + vec2 texCoord = vec2(tx/float(texNumCols), ty/float(texNumRows));\n\ + vec4 valueDown = texture2D(volumeTex, texCoord);\n\ + \n\ + if(sliceDown < float(texNumSlices-1))\n\ + {\n\ + float stackUp = floor(sliceUp/float(numSlicesPerStacks));\n\ + float realSliceUp = sliceUp - stackUp * float(numSlicesPerStacks);\n\ + float tx2 = stackUp * float(slicesNumCols) + col;\n\ + float ty2 = realSliceUp * float(slicesNumRows) + row;\n\ + vec2 texCoord2 = vec2(tx2/float(texNumCols), ty2/float(texNumRows));\n\ + vec4 valueUp = texture2D(volumeTex, texCoord2);\n\ + value = valueDown*(1.0-sliceDownDist)+valueUp*(sliceDownDist);\n\ + }\n\ + else{\n\ + value = valueDown;\n\ + }\n\ + //if((value.r * (maxValue - minValue)) > maxValue * 0.3)\n\ + // return true;\n\ + //else return false;\n\ + return true;\n\ +}\n\ +\n\ +void main() {\n\ + vec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight);\n\ + float linearDepth = 1.0; // the quad is 1m of dist of the camera.*** \n\ + vec3 rayCamCoord = getViewRay(screenPos) * linearDepth; \n\ + rayCamCoord = normalize(rayCamCoord);\n\ + \n\ + vec3 camTarget = rayCamCoord * 10000.0;\n\ + vec4 camPosWorld = vec4(encodedCameraPositionMCHigh + encodedCameraPositionMCLow, 1.0);\n\ + vec4 camTargetWorld = modelViewMatrixInv * vec4(camTarget.xyz, 1.0);\n\ + vec3 camDirWorld = camTargetWorld.xyz - camPosWorld.xyz;\n\ + camDirWorld = normalize(camDirWorld);\n\ +\n\ + // now, must find sampling points.***\n\ + int intersectType = 0;\n\ + vec3 nearP;\n\ + vec3 farP;\n\ + float radius = 6378137.0 + maxAlt; // equatorial radius.***\n\ + //radius = 6250000.0 + maxAlt; // test radius.***\n\ + \n\ + intersectionLineSphere(radius, camPosWorld.xyz, camDirWorld, intersectType, nearP, farP);\n\ + \n\ + if(intersectType == 0)\n\ + {\n\ + discard;\n\ + }\n\ + \n\ + if(intersectType == 1)\n\ + {\n\ + // provisionally discard.***\n\ + discard; \n\ + }\n\ + \n\ + // check if nearP is rear of the camera.***\n\ + if(isPointRearCamera(nearP, camPosWorld.xyz, camDirWorld.xyz))\n\ + {\n\ + nearP = vec3(camPosWorld.xyz);\n\ + }\n\ + float dist = distance(nearP, farP);\n\ + float testDist = dist;\n\ + if(dist > 1500000.0)\n\ + testDist = 1500000.0;\n\ + \n\ + // now calculate the geographicCoords of 2 points.***\n\ + // now, depending the dist(nearP, endPoint), determine numSmples.***\n\ + // provisionally take 16 samples.***\n\ + float numSamples = 512.0;\n\ + vec4 color = vec4(0.0, 0.0, 0.0, 0.0);\n\ + float alpha = 0.8/numSamples;\n\ + float tempRange = maxValue - minValue;\n\ + vec4 value;\n\ + float totalValue = 0.0;\n\ + int sampledsCount = 0;\n\ + int intAux = 0;\n\ + float increDist = testDist / numSamples;\n\ + int c = 0;\n\ + bool isPointRearPlane = true;\n\ + for(int i=0; i<512; i++)\n\ + {\n\ + vec3 currGeoLoc;\n\ + vec3 currPosWorld = vec3(nearP.x + camDirWorld.x * increDist*float(c), nearP.y + camDirWorld.y * increDist*float(c), nearP.z + camDirWorld.z * increDist*float(c));\n\ + // Check if the currPosWorld is in front or rear of planes (if exist planes).***\n\ + int planesCounter = 0;\n\ + for(int j=0; j<6; j++)\n\ + {\n\ + if(planesCounter == cuttingPlanesCount)\n\ + break;\n\ + \n\ + vec4 plane = cuttingPlanes[j];\n\ + float dist = distPointToPlane(currPosWorld, plane);\n\ + if(dist > 0.0)\n\ + {\n\ + isPointRearPlane = false;\n\ + break;\n\ + }\n\ + else{\n\ + isPointRearPlane = true;\n\ + }\n\ + planesCounter++;\n\ + }\n\ + \n\ + \n\ + if(isPointRearPlane)\n\ + {\n\ + cartesianToGeographicWgs84(currPosWorld, currGeoLoc);\n\ + if(getValue(currGeoLoc, value))\n\ + {\n\ + float realValue = value.r * tempRange + minValue*255.0;\n\ + totalValue += (value.r);\n\ + sampledsCount += 1;\n\ + }\n\ + }\n\ + if(sampledsCount >= 1)\n\ + {\n\ + break;\n\ + }\n\ + c++;\n\ + }\n\ + if(sampledsCount == 0)\n\ + {\n\ + discard;\n\ + }\n\ + float fValue = totalValue/numSamples;\n\ + fValue = totalValue;\n\ + if(fValue > 1.0)\n\ + {\n\ + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n\ + return;\n\ + }\n\ + float b = 1.0 - fValue;\n\ + float g;\n\ + if(fValue > 0.5)\n\ + {\n\ + g = 2.0-2.0*fValue;\n\ + }\n\ + else{\n\ + g = 2.0*fValue;\n\ + }\n\ + float r = fValue;\n\ + color += vec4(r,g,b,0.8);\n\ + gl_FragColor = color;\n\ +}"; +ShaderSource.wgs84_volumVS = "precision mediump float;\n\ +\n\ +attribute vec3 position;\n\ +uniform mat4 projectionMatrix;\n\ +\n\ +void main()\n\ +{ \n\ + vec4 pos = projectionMatrix * vec4(position.xyz, 1.0);\n\ + gl_Position = pos;\n\ +}"; + +'use strict'; + +/** + * 어떤 일을 하고 있습니까? + * @class Uniform1fDataPair + * @param gl 변수 + */ +var Uniform1fDataPair = function(gl, uniformName) +{ + if (!(this instanceof Uniform1fDataPair)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + this.gl = gl; + this.name = uniformName; + this.uniformLocation; + this.floatValue; +}; + +/** + * 어떤 일을 하고 있습니까? + * @param gl 변수 + */ +Uniform1fDataPair.prototype.bindUniform = function() +{ + this.gl.uniform1f(this.uniformLocation, this.floatValue[0]); +}; +'use strict'; +/** + * 어떤 일을 하고 있습니까? + * @class Uniform1iDataPair + * @param gl 변수 + */ +var Uniform1iDataPair = function(gl, uniformName) +{ + if (!(this instanceof Uniform1iDataPair)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + this.gl = gl; + this.name = uniformName; + this.uniformLocation; + this.intValue; +}; + +/** + * 어떤 일을 하고 있습니까? + * @param gl 변수 + */ +Uniform1iDataPair.prototype.bindUniform = function() +{ + this.gl.uniform1i(this.uniformLocation, this.intValue); +}; +'use strict'; + + +/** + * 어떤 일을 하고 있습니까? + * @class UniformMatrix4fvDataPair + * @param gl 변수 + */ +var UniformMatrix4fvDataPair = function(gl, uniformName) +{ + if (!(this instanceof UniformMatrix4fvDataPair)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + this.gl = gl; + this.name = uniformName; + this.uniformLocation; + this.matrix4fv; +}; + +/** + * 어떤 일을 하고 있습니까? + * @param gl 변수 + */ +UniformMatrix4fvDataPair.prototype.bindUniform = function() +{ + this.gl.uniformMatrix4fv(this.uniformLocation, false, this.matrix4fv); +}; +'use strict'; + +/** + * 어떤 일을 하고 있습니까? + * @class UniformVec2fvDataPair + * @param gl 변수 + */ +var UniformVec2fvDataPair = function(gl, uniformName) +{ + if (!(this instanceof UniformVec2fvDataPair)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + this.gl = gl; + this.name = uniformName; + this.uniformLocation; + this.vec2fv; +}; + +/** + * 어떤 일을 하고 있습니까? + * @param gl 변수 + */ +UniformVec2fvDataPair.prototype.bindUniform = function() +{ + this.gl.uniform2fv(this.uniformLocation, this.vec2fv); +}; +'use strict'; + +/** + * 어떤 일을 하고 있습니까? + * @class UniformVec3fvDataPair + * @param gl 변수 + */ +var UniformVec3fvDataPair = function(gl, uniformName) +{ + if (!(this instanceof UniformVec3fvDataPair)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + this.gl = gl; + this.name = uniformName; + this.uniformLocation; + this.vec3fv; +}; + +/** + * 어떤 일을 하고 있습니까? + * @param gl 변수 + */ +UniformVec3fvDataPair.prototype.bindUniform = function() +{ + this.gl.uniform3fv(this.uniformLocation, this.vec3fv); +}; 'use strict'; -var MAGO3DJS_MESSAGE = new Object(); +/** + * 어떤 일을 하고 있습니까? + * @class UniformVec4fvDataPair + * @param gl 변수 + */ +var UniformVec4fvDataPair = function(gl, uniformName) +{ + if (!(this instanceof UniformVec4fvDataPair)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + this.gl = gl; + this.name = uniformName; + this.uniformLocation; + this.vec4fv; +}; +/** + * 어떤 일을 하고 있습니까? + * @param gl 변수 + */ +UniformVec4fvDataPair.prototype.bindUniform = function() +{ + this.gl.uniform4fv(this.uniformLocation, this.vec4fv); +}; 'use strict'; /** - * 어떤 일을 하고 있습니까? - * @class Renderer + * Network. + * + * @alias Network + * @class Network */ -var Renderer = function() +var Network = function(owner) { - if (!(this instanceof Renderer)) + if (!(this instanceof Network)) { throw new Error(Messages.CONSTRUCT_ERROR); } - this.renderNormals = true; - this.renderTexture = true; + this.nodeOwner; + if (owner) + { this.nodeOwner = owner; } + + this.id; // network id. + this.nodesArray; + this.edgesArray; + this.spacesArray; + this.attributes; + this.edgesVboKeysContainer; // to draw edges with an unique vbo. + this.nodesVboKeysContainer; // to draw nodes with an unique vbo. + + this.renderSpaces = true; + this.spacesAlpha = 0.2; +}; - this.vbo_vi_cacheKey_aux; - this.byteColorAux = new ByteColor(); +/** + * + */ +Network.prototype.newNode = function() +{ + if (this.nodesArray === undefined) + { this.nodesArray = []; } + + var networkNode = new NetworkNode(this); + this.nodesArray.push(networkNode); + return networkNode; +}; - // SCRATCH.*** SCRATCH.*** SCRATCH.*** SCRATCH.*** SCRATCH.*** SCRATCH.*** SCRATCH.*** SCRATCH.*** SCRATCH.*** SCRATCH.*** SCRATCH.*** SCRATCH.*** +/** + * + */ +Network.prototype.newEdge = function() +{ + if (this.edgesArray === undefined) + { this.edgesArray = []; } + + var networkEdge = new NetworkEdge(this); + this.edgesArray.push(networkEdge); + return networkEdge; +}; - this.currentTimeSC; - this.dateSC; - this.startTimeSC; - this.simpObj_scratch; +/** + * + */ +Network.prototype.newSpace = function() +{ + if (this.spacesArray === undefined) + { this.spacesArray = []; } + + var networkSpace = new NetworkSpace(this); + this.spacesArray.push(networkSpace); + return networkSpace; }; /** - * 어떤 일을 하고 있습니까? - * @param gl 변수 + * */ -Renderer.prototype.renderRenderables = function(gl, renderables, magoManager, shader, renderTexture, ssao_idx, maxSizeToRender, refMatrixIdxKey) +Network.prototype.test__makeVbos = function(magoManager) { - var node; - var neoBuilding; - var lod; - var renderablesCount = renderables.length; - for (var i=0; i 0 )//&& !magoManager.isCameraMoving) + { + var refMatrixType = 1; // translation-type. + gl.uniform1i(shader.refMatrixType_loc, refMatrixType); + //gl.uniform4fv(shader.oneColor4_loc, [0.3, 0.3, 0.9, 1.0]); + var nodeMaster = this.nodesArray[0]; // render all with an unique box. + for (var i=0; i0) - { - renderTexture = true; - } - else { renderTexture = false; } + } + + // Edges.** + // Render with a unique vbo. + if (this.edgesVboKeysContainer) + { + var vboKey = this.edgesVboKeysContainer.vboCacheKeysArray[0]; + if (vboKey.isReadyPositions(gl, vboMemManager)) + { + shader.disableVertexAttribArray(shader.texCoord2_loc); + shader.disableVertexAttribArray(shader.normal3_loc); + refMatrixType = 0; + gl.uniform1i(shader.refMatrixType_loc, refMatrixType); - if (magoManager.magoPolicy.getObjectMoveMode() === CODE.moveMode.ALL && magoManager.buildingSelected === neoBuilding) + // Positions. + if (vboKey.meshVertexCacheKey !== shader.last_vboPos_binded) { - // active stencil buffer to draw silhouette.*** - this.enableStencilBuffer(gl); + gl.bindBuffer(gl.ARRAY_BUFFER, vboKey.meshVertexCacheKey); + gl.vertexAttribPointer(shader.position3_loc, 3, gl.FLOAT, false, 0, 0); + shader.last_vboPos_binded = vboKey.meshVertexCacheKey; } - - } - - // LOD0.*** - minSize = 0.0; - lowestOctreesCount = neoBuilding.currentVisibleOctreesControler.currentVisibles0.length; - for (var j=0; j 0 )//&& !magoManager.isCameraMoving) + { + gl.uniform1i(shader.colorType_loc, 0); // 0= oneColor, 1= attribColor, 2= texture. + var refMatrixType = 1; // translation-type. + gl.uniform1i(shader.refMatrixType_loc, refMatrixType); + gl.uniform4fv(shader.oneColor4_loc, [0.3, 0.3, 0.9, 1.0]); + var nodeMaster = this.nodesArray[0]; // render all with an unique box. + for (var i=0; i pickingMode.*** - // ssao_idx = 0 -> depth.*** - // ssao_idx = 1 -> ssao.*** + this.networkOwner = owner; + this.id; + this.strNode; + this.endNode; + this.sense; + this.attributes; + + // provisionally: + this.strNodeId; + this.endNodeId; +}; +'use strict'; - if (ssao_idx === 0) // depth.*** +/** + * NetworkNode. + * + * @alias NetworkNode + * @class NetworkNode + */ +var NetworkNode = function(owner) +{ + if (!(this instanceof NetworkNode)) { - // 1) Position.********************************************* - var vbo_vicky = pCloud.vbo_vicks_container.vboCacheKeysArray[0]; // there are only one.*** - if (!vbo_vicky.isReadyPositions(gl, magoManager.vboMemoryManager)) - { return; } - - var vertices_count = vbo_vicky.vertexCount; - if (vertices_count === 0) - { - return; - } - - gl.disableVertexAttribArray(shader.color4_loc); - - gl.bindBuffer(gl.ARRAY_BUFFER, vbo_vicky.meshVertexCacheKey); - gl.vertexAttribPointer(shader.position3_loc, 3, gl.UNSIGNED_SHORT, false, 0, 0); - gl.drawArrays(gl.POINTS, 0, vertices_count); + throw new Error(Messages.CONSTRUCT_ERROR); } - else if (ssao_idx === 1) // ssao.*** - { - var vbo_vicky = pCloud.vbo_vicks_container.vboCacheKeysArray[0]; // there are only one.*** - var vertices_count = vbo_vicky.vertexCount; + this.networkOwner = owner; + this.id; + this.edgesArray; + this.attributes; + this.box; + //this.mesh; // if display as a box, cilinder, etc. +}; +'use strict'; - if (vertices_count === 0) - { - return; - } - - if (!vbo_vicky.isReadyPositions(gl, magoManager.vboMemoryManager)) - { return; } - - //if (!vbo_vicky.isReadyNormals(gl, magoManager.vboMemoryManager)) - //{ return; } - - if (!vbo_vicky.isReadyColors(gl, magoManager.vboMemoryManager)) - { return; } - - // 4) Texcoord.********************************************* - /* - if (renderTexture) - { - if (!vbo_vicky.isReadyTexCoords(gl, magoManager.vboMemoryManager)) - { return; } - } - else - { - gl.uniform1i(shader.bUse1Color_loc, false); - gl.disableVertexAttribArray(shader.texCoord2_loc); - } - */ - - gl.bindBuffer(gl.ARRAY_BUFFER, vbo_vicky.meshVertexCacheKey); - if (posCompressed) - { - gl.vertexAttribPointer(shader.position3_loc, 3, gl.UNSIGNED_SHORT, false, 0, 0); - } - else - { - gl.vertexAttribPointer(shader.position3_loc, 3, gl.FLOAT, false, 0, 0); - } +/** + * NetworkSpace. + * + * @alias NetworkSpace + * @class NetworkSpace + */ +var NetworkSpace = function(owner) +{ + if (!(this instanceof NetworkSpace)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } + this.networkOwner = owner; + this.id; + this.mesh; + this.attributes; + +}; +'use strict'; - //gl.bindBuffer(gl.ARRAY_BUFFER, vbo_vicky.meshNormalCacheKey); - //gl.vertexAttribPointer(shader.normal3_loc, 3, gl.BYTE, true, 0, 0); +/** + * 어떤 일을 하고 있습니까? + * @class ByteColor + */ +var ByteColor = function() +{ + if (!(this instanceof ByteColor)) + { + throw new Error(Messages.CONSTRUCT_ERROR); + } - if (vbo_vicky.meshColorCacheKey !== undefined ) - { - gl.enableVertexAttribArray(shader.color4_loc); - gl.bindBuffer(gl.ARRAY_BUFFER, vbo_vicky.meshColorCacheKey); - gl.vertexAttribPointer(shader.color4_loc, 4, gl.UNSIGNED_BYTE, true, 0, 0); - } - - //if (renderTexture && vbo_vicky.meshTexcoordsCacheKey) - //{ - // gl.disableVertexAttribArray(shader.color4_loc); - // gl.bindBuffer(gl.ARRAY_BUFFER, vbo_vicky.meshTexcoordsCacheKey); - // gl.vertexAttribPointer(shader.texCoord2_loc, 2, gl.FLOAT, false, 0, 0); - //} - if (magoManager.isCameraMoving)// && !isInterior && magoManager.isCameraInsideBuilding) - { - vertices_count = Math.floor(vertices_count/5); - if (vertices_count === 0) - { return; } - } - - if (distToCam < 100) - { - // do nothing.*** - } - else if (distToCam < 200) - { - vertices_count = Math.floor(vertices_count/2); - if (vertices_count === 0) - { return; } - } - else if (distToCam < 400) - { - vertices_count = Math.floor(vertices_count/4); - if (vertices_count === 0) - { return; } - } - else if (distToCam < 800) - { - vertices_count = Math.floor(vertices_count/8); - if (vertices_count === 0) - { return; } - } - else if (distToCam < 1600) - { - vertices_count = Math.floor(vertices_count/16); - if (vertices_count === 0) - { return; } - } - else - { - vertices_count = Math.floor(vertices_count/32); - if (vertices_count === 0) - { return; } - } + this.ByteR = 0; + this.ByteG = 0; + this.ByteB = 0; + this.ByteAlfa = 255; +}; - gl.drawArrays(gl.POINTS, 0, vertices_count); - gl.disableVertexAttribArray(shader.color4_loc); - } +/** + * 어떤 일을 하고 있습니까? + */ +ByteColor.prototype.destroy = function() +{ + this.ByteR = null; + this.ByteG = null; + this.ByteB = null; + this.ByteAlfa = null; }; /** * 어떤 일을 하고 있습니까? - * @param gl 변수 + * @param byteRed 변수 + * @param byteGreen 변수 + * @param byteBlue 변수 */ -Renderer.prototype.renderNeoBuildingsPCloud = function(gl, visibleNodesArray, magoManager, shader, renderTexture, ssao_idx) +ByteColor.prototype.set = function(byteRed, byteGreen, byteBlue) { - var node; - var rootNode; - var geoLocDataManager; - var neoBuilding; - var lowestOctreesCount; - var lowestOctree; - var lastExtureId; - - var nodesCount = visibleNodesArray.length; - for (var i=0; i this.vbo_vi_cacheKey_aux.indicesCount) - { indicesCount = this.vbo_vi_cacheKey_aux.indicesCount; } - } - } - else - { - if (magoManager.thereAreUrgentOctrees) - { - indicesCount = this.vbo_vi_cacheKey_aux.bigTrianglesIndicesCount; - if (indicesCount > this.vbo_vi_cacheKey_aux.indicesCount) - { indicesCount = this.vbo_vi_cacheKey_aux.indicesCount; } - } - else - { - indicesCount = this.vbo_vi_cacheKey_aux.indicesCount; - } - } + if (heading !== undefined) + { resultGeoLocationData.heading = heading; } - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.vbo_vi_cacheKey_aux.meshFacesCacheKey); - gl.drawElements(gl.TRIANGLES, indicesCount, gl.UNSIGNED_SHORT, 0); // Fill.*** - //gl.drawElements(gl.LINES, this.vbo_vi_cacheKey_aux.indicesCount, gl.UNSIGNED_SHORT, 0); // Wireframe.*** - } + if (pitch !== undefined) + { resultGeoLocationData.pitch = pitch; } - neoReference.swapRenderingFase(); - if (magoManager.magoPolicy.getObjectMoveMode() === CODE.moveMode.OBJECT && magoManager.objectSelected === neoReference) - { - this.disableStencilBuffer(gl); - gl.disable(gl.POLYGON_OFFSET_FILL); - } - } -}; + if (roll !== undefined) + { resultGeoLocationData.roll = roll; } -/** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param neoRefList_array 변수 - * @param neoBuilding 변수 - * @param magoManager 변수 - * @param isInterior 변수 - * @param standardShader 변수 - * @param renderTexture 변수 - * @param ssao_idx 변수 - */ -Renderer.prototype.depthRenderNeoRefListsAsimetricVersion = function(gl, neoReferencesMotherAndIndices, neoBuilding, magoManager, - isInterior, standardShader, renderTexture, ssao_idx, maxSizeToRender, lod, refMatrixIdxKey) -{ - if (!this.isReadyNeoRefList(neoReferencesMotherAndIndices)) + if (resultGeoLocationData.geographicCoord.longitude === undefined || resultGeoLocationData.geographicCoord.latitude === undefined) + { return; } + + if (magoManager.configInformation === undefined) { return; } - var cacheKeys_count; - //var reference; - var block_idx; - var block; - - // New version. Use occlussion indices.*** - //var visibleIndices_count = neoReferencesMotherAndIndices.neoRefsIndices.length; // no occludeCulling mode.*** - var visibleIndices_count = neoReferencesMotherAndIndices.currentVisibleIndices.length; - - for (var k=0; k this.vbo_vi_cacheKey_aux.indicesCount) - { indicesCount = this.vbo_vi_cacheKey_aux.indicesCount; } - - //if(indicesCount === 0) - // indicesCount = this.vbo_vi_cacheKey_aux.indicesCount; - } - } - else - { - indicesCount = this.vbo_vi_cacheKey_aux.indicesCount; - } + // Set inverseMatrices as undefined. + resultGeoLocationData.tMatrixInv = undefined; // reset. is calculated when necessary. + resultGeoLocationData.rotMatrixInv = undefined; // reset. is calculated when necessary. + resultGeoLocationData.geoLocMatrixInv = undefined; // reset. is calculated when necessary. - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.vbo_vi_cacheKey_aux.meshFacesCacheKey); - gl.drawElements(gl.TRIANGLES, indicesCount, gl.UNSIGNED_SHORT, 0); // Fill.*** - //gl.drawElements(gl.LINES, this.vbo_vi_cacheKey_aux.indicesCount, gl.UNSIGNED_SHORT, 0); // Wireframe.*** - } + // 1rst, calculate the transformation matrix for the location. + resultGeoLocationData.tMatrix = ManagerUtils.calculateTransformMatrixAtWorldPosition(resultGeoLocationData.position, resultGeoLocationData.heading, resultGeoLocationData.pitch, resultGeoLocationData.roll, + resultGeoLocationData.geoLocMatrix, resultGeoLocationData.tMatrix, magoManager); + resultGeoLocationData.rotMatrix.copyFromMatrix4(resultGeoLocationData.tMatrix); + resultGeoLocationData.rotMatrix._floatArrays[12] = 0; + resultGeoLocationData.rotMatrix._floatArrays[13] = 0; + resultGeoLocationData.rotMatrix._floatArrays[14] = 0; + + // finally assing the pivotPoint. + if (resultGeoLocationData.pivotPoint === undefined) + { resultGeoLocationData.pivotPoint = new Point3D(); } - neoReference.swapRenderingFase(); - } + resultGeoLocationData.pivotPoint.set(resultGeoLocationData.position.x, resultGeoLocationData.position.y, resultGeoLocationData.position.z); + resultGeoLocationData.doEffectivePivotPointTranslation(); + return resultGeoLocationData; }; - /** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param neoRefList_array 변수 - * @param neoBuilding 변수 - * @param magoManager 변수 - * @param isInterior 변수 - * @param standardShader 변수 + * This function calculates geolocation data use pixel point(calculated world point). + * When use Object Marker, this function called. + * @param {number} absoluteX absoluteX. + * @param {number} absoluteY absoluteY. + * @param {number} absoluteZ absoluteZ. + * @param {GeoLocationData|undefined} resultGeoLocationData Optional. result geolocation matrix. if undefined, create GeoLocationData instance. + * @param {MagoManager} magoManager + * @returns {GeoLocationData} resultGeoLocationData. */ -Renderer.prototype.renderNeoRefListsAsimetricVersionColorSelection = function(gl, lowestOctree, node, magoManager, isInterior, standardShader, maxSizeToRender, refMatrixIdxKey, glPrimitive) +ManagerUtils.calculateGeoLocationDataByAbsolutePoint = function(absoluteX, absoluteY, absoluteZ, resultGeoLocationData, magoManager) { - var neoBuilding = node.data.neoBuilding; - // render_neoRef - var neoReferencesMotherAndIndices = lowestOctree.neoReferencesMotherAndIndices; + if (resultGeoLocationData === undefined) + { resultGeoLocationData = new GeoLocationData(); } - if (!this.isReadyNeoRefList(neoReferencesMotherAndIndices)) + // 0) Position.** + if (resultGeoLocationData.geographicCoord === undefined) + { resultGeoLocationData.geographicCoord = new GeographicCoord(); } + + if (magoManager.configInformation === undefined) { return; } - - // New version. Use occlussion indices.*** - var visibleIndices_count = neoReferencesMotherAndIndices.currentVisibleIndices.length; - var selCandidates = magoManager.selectionCandidates; - var idxKey; - - for (var k=0; kExample usage of calculateSplitedValues + * ManagerUtils.calculateSplitedValues(4049653.5985745606, new SplitValue()); + * resultSplitValue.high = 3997696; // Math.floor(4049653.5985745606 / 65536.0) * 65536.0; + * resultSplitValue.low = 51957.5985745606 // 4049653.5985745606 - 3997696; + * @param {number} value Required. coordinate x or y or z. + * @param {SplitValue} resultSplitValue Optional. result split value. if undefined, create SplitValue instance. + * @returns {SplitValue} resultSplitValue. */ -Renderer.prototype.renderLodBuilding = function(gl, lodBuilding, magoManager, shader, ssao_idx, renderTexture) +ManagerUtils.calculateSplitedValues = function(value, resultSplitValue) { - if (lodBuilding.vbo_vicks_container.vboCacheKeysArray.length === 0) - { - return; - } - gl.frontFace(gl.CCW); - // ssao_idx = -1 -> pickingMode.*** - // ssao_idx = 0 -> depth.*** - // ssao_idx = 1 -> ssao.*** + if (resultSplitValue === undefined) + { resultSplitValue = new SplitValue(); } - if (ssao_idx === 0) // depth.*** + var doubleHigh; + if (value >= 0.0) { - // 1) Position.********************************************* - var vbo_vicky = lodBuilding.vbo_vicks_container.vboCacheKeysArray[0]; // there are only one.*** - if (!vbo_vicky.isReadyPositions(gl, magoManager.vboMemoryManager)) - { return; } - - var vertices_count = vbo_vicky.vertexCount; - if (vertices_count === 0) - { - return; - } - - gl.bindBuffer(gl.ARRAY_BUFFER, vbo_vicky.meshVertexCacheKey); - gl.vertexAttribPointer(shader.position3_loc, 3, gl.FLOAT, false, 0, 0); - gl.drawArrays(gl.TRIANGLES, 0, vertices_count); + doubleHigh = Math.floor(value / 65536.0) * 65536.0; //unsigned short max + resultSplitValue.high = doubleHigh; + resultSplitValue.low = value - doubleHigh; } - else if (ssao_idx === 1) // ssao.*** + else { - var vbo_vicky = lodBuilding.vbo_vicks_container.vboCacheKeysArray[0]; // there are only one.*** - var vertices_count = vbo_vicky.vertexCount; + doubleHigh = Math.floor(-value / 65536.0) * 65536.0; + resultSplitValue.high = -doubleHigh; + resultSplitValue.low = value + doubleHigh; + } - if (vertices_count === 0) - { - return; - } - - if (!vbo_vicky.isReadyPositions(gl, magoManager.vboMemoryManager)) - { return; } - - if (!vbo_vicky.isReadyNormals(gl, magoManager.vboMemoryManager)) - { return; } - - if (!renderTexture && !vbo_vicky.isReadyColors(gl, magoManager.vboMemoryManager)) - { return; } - - // 4) Texcoord.********************************************* - if (renderTexture) - { - if (!vbo_vicky.isReadyTexCoords(gl, magoManager.vboMemoryManager)) - { return; } - } - else - { - gl.uniform1i(shader.bUse1Color_loc, false); - gl.disableVertexAttribArray(shader.texCoord2_loc); - } + return resultSplitValue; +}; - +/** + * 자릿수가 긴 숫자를 나머지(low)와 몫(high)으로 분리한 결과를 각각 배열로 생성. gl에서는 float형밖에 처리 불가. + * @param {Point3D} point3fv Required. + * @param {Float32Array} resultSplitPoint3fvHigh Optional. result split high value array. if undefined, set new Float32Array(3). + * @param {Float32Array} resultSplitPoint3fvLow Optional. result split low value array. if undefined, set new Float32Array(3). + * + * @see ManagerUtils#calculateSplitedValues + */ +ManagerUtils.calculateSplited3fv = function(point3fv, resultSplitPoint3fvHigh, resultSplitPoint3fvLow) +{ + if (point3fv === undefined) + { return undefined; } - gl.bindBuffer(gl.ARRAY_BUFFER, vbo_vicky.meshVertexCacheKey); - gl.vertexAttribPointer(shader.position3_loc, 3, gl.FLOAT, false, 0, 0); + if (resultSplitPoint3fvHigh === undefined) // delete unnecesary. agree + { resultSplitPoint3fvHigh = new Float32Array(3); }// delete unnecesary. agree - gl.bindBuffer(gl.ARRAY_BUFFER, vbo_vicky.meshNormalCacheKey); - gl.vertexAttribPointer(shader.normal3_loc, 3, gl.BYTE, true, 0, 0); + if (resultSplitPoint3fvLow === undefined)// delete unnecesary. agree + { resultSplitPoint3fvLow = new Float32Array(3); }// delete unnecesary. agree - if (vbo_vicky.meshColorCacheKey !== undefined ) - { - gl.enableVertexAttribArray(shader.color4_loc); - gl.bindBuffer(gl.ARRAY_BUFFER, vbo_vicky.meshColorCacheKey); - gl.vertexAttribPointer(shader.color4_loc, 4, gl.UNSIGNED_BYTE, true, 0, 0); - } - - if (renderTexture && vbo_vicky.meshTexcoordsCacheKey) - { - gl.disableVertexAttribArray(shader.color4_loc); - gl.bindBuffer(gl.ARRAY_BUFFER, vbo_vicky.meshTexcoordsCacheKey); - gl.vertexAttribPointer(shader.texCoord2_loc, 2, gl.FLOAT, false, 0, 0); - } + var posSplitX = new SplitValue(); + posSplitX = this.calculateSplitedValues(point3fv[0], posSplitX); + var posSplitY = new SplitValue(); + posSplitY = this.calculateSplitedValues(point3fv[1], posSplitY); + var posSplitZ = new SplitValue(); + posSplitZ = this.calculateSplitedValues(point3fv[2], posSplitZ); - gl.drawArrays(gl.TRIANGLES, 0, vertices_count); - /* - gl.uniform1i(shader.bUse1Color_loc, true); - gl.uniform4fv(shader.oneColor4_loc, [1.0, 1.0, 1.0, 1.0]); //.*** - gl.disableVertexAttribArray(shader.texCoord2_loc); - gl.uniform1i(shader.hasTexture_loc, false); - gl.drawArrays(gl.LINES, 0, vertices_count); - gl.enableVertexAttribArray(shader.texCoord2_loc); - */ - - gl.disableVertexAttribArray(shader.color4_loc); - } + resultSplitPoint3fvHigh[0] = posSplitX.high; + resultSplitPoint3fvHigh[1] = posSplitY.high; + resultSplitPoint3fvHigh[2] = posSplitZ.high; + + resultSplitPoint3fvLow[0] = posSplitX.low; + resultSplitPoint3fvLow[1] = posSplitY.low; + resultSplitPoint3fvLow[2] = posSplitZ.low; }; /** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param neoRefList_array 변수 - * @param neoBuilding 변수 - * @param magoManager 변수 - * @param isInterior 변수 - * @param standardShader 변수 - * @param renderTexture 변수 - * @param ssao_idx 변수 + * Calculates the pixel linear depth value. + * @param {WebGLRenderingContext} gl WebGL Rendering Context. + * @param {Number} pixelX Screen x position of the pixel. + * @param {Number} pixelY Screen y position of the pixel. + * @param {FBO} depthFbo Depth frameBuffer object. + * @param {MagoManager} magoManager Mago3D main manager. + * @returns {Number} linearDepth Returns the linear depth [0.0, 1.0] ranged value. */ -Renderer.prototype.renderLodBuildingColorSelection = function(gl, lodBuilding, magoManager, shader) +ManagerUtils.calculatePixelLinearDepth = function(gl, pixelX, pixelY, depthFbo, magoManager) { - if (lodBuilding.vbo_vicks_container.vboCacheKeysArray.length === 0) + if (depthFbo === undefined) + { depthFbo = magoManager.depthFboNeo; } + + if (depthFbo) { - return; + depthFbo.bind(); } - gl.frontFace(gl.CCW); - // 1) Position.********************************************* - var vbo_vicky = lodBuilding.vbo_vicks_container.vboCacheKeysArray[0]; // there are only one.*** - if (!vbo_vicky.isReadyPositions(gl, magoManager.vboMemoryManager)) - { return; } + // Now, read the pixel and find the pixel position. + var depthPixels = new Uint8Array(4 * 1 * 1); // 4 x 1x1 pixel. + gl.readPixels(pixelX, magoManager.sceneState.drawingBufferHeight - pixelY, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, depthPixels); + + var zDepth = depthPixels[0]/(256.0*256.0*256.0) + depthPixels[1]/(256.0*256.0) + depthPixels[2]/256.0 + depthPixels[3]; // 0 to 256 range depth. + var linearDepth = zDepth / 256.0; // LinearDepth. Convert to [0.0, 1.0] range depth. + return linearDepth; +}; - var vertices_count = vbo_vicky.vertexCount; - if (vertices_count === 0) - { - return; - } +/** + * Calculates the pixel position in camera coordinates. + * @param {WebGLRenderingContext} gl WebGL Rendering Context. + * @param {Number} pixelX Screen x position of the pixel. + * @param {Number} pixelY Screen y position of the pixel. + * @param {Point3D} resultPixelPos The result of the calculation. + * @param {MagoManager} magoManager Mago3D main manager. + * @returns {Point3D} resultPixelPos The result of the calculation. + */ +ManagerUtils.calculatePixelPositionCamCoord = function(gl, pixelX, pixelY, resultPixelPos, depthFbo, frustumFar, magoManager) +{ + if (frustumFar === undefined) + { frustumFar = magoManager.sceneState.camera.frustum.far; } + + var linearDepth = ManagerUtils.calculatePixelLinearDepth(gl, pixelX, pixelY, depthFbo, magoManager); + var realZDepth = linearDepth*frustumFar; // original. - gl.bindBuffer(gl.ARRAY_BUFFER, vbo_vicky.meshVertexCacheKey); - gl.vertexAttribPointer(shader.position3_loc, 3, gl.FLOAT, false, 0, 0); - gl.drawArrays(gl.TRIANGLES, 0, vertices_count); + // now, find the 3d position of the pixel in camCoord.* + magoManager.resultRaySC = ManagerUtils.getRayCamSpace(pixelX, pixelY, magoManager.resultRaySC, magoManager); + if (resultPixelPos === undefined) + { resultPixelPos = new Point3D(); } + + resultPixelPos.set(magoManager.resultRaySC[0] * realZDepth, magoManager.resultRaySC[1] * realZDepth, magoManager.resultRaySC[2] * realZDepth); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + return resultPixelPos; }; /** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param neoRefList_array 변수 - * @param magoManager 변수 - * @param shader 변수 - * @param renderTexture 변수 - * @param ssao_idx 변수 + * Calculates the cameraCoord position in world coordinates. + * @param {Point3D} cameraCoord Camera coordinate position. + * @param {MagoManager} magoManager Mago3D main manager. + * @returns {Point3D} resultPixelPos The result of the calculation. */ -Renderer.prototype.renderObject = function(gl, renderable, magoManager, shader, ssao_idx, bRenderLines, primitiveType) +ManagerUtils.cameraCoordPositionToWorldCoord = function(camCoordPos, resultWorldPos, magoManager) { - var vbo_vicks_container = renderable.getVboKeysContainer(); - - if (vbo_vicks_container === undefined) - { return; } + // now, must transform this pixelCamCoord to world coord. + var mv_inv = magoManager.sceneState.getModelViewMatrixInv(); + if (resultWorldPos === undefined) + { var resultWorldPos = new Point3D(); } + resultWorldPos = mv_inv.transformPoint3D(camCoordPos, resultWorldPos); + return resultWorldPos; +}; + +/** + * Calculates the pixel position in world coordinates. + * @param {WebGLRenderingContext} gl WebGL Rendering Context. + * @param {Number} pixelX Screen x position of the pixel. + * @param {Number} pixelY Screen y position of the pixel. + * @param {Point3D} resultPixelPos The result of the calculation. + * @param {MagoManager} magoManager Mago3D main manager. + * @returns {Point3D} resultPixelPos The result of the calculation. + */ +ManagerUtils.calculatePixelPositionWorldCoord = function(gl, pixelX, pixelY, resultPixelPos, depthFbo, frustumFar, magoManager) +{ + var pixelPosCamCoord = new Point3D(); - if (vbo_vicks_container.vboCacheKeysArray.length === 0) - { return; } + if (frustumFar === undefined) + { frustumFar = magoManager.sceneState.camera.frustum.far; } - // ssao_idx = -1 -> pickingMode.*** - // ssao_idx = 0 -> depth.*** - // ssao_idx = 1 -> ssao.*** - if (bRenderLines === undefined) - { bRenderLines = false; } + if (depthFbo === undefined) + { depthFbo = magoManager.depthFboNeo; } - var vbosCount = vbo_vicks_container.getVbosCount(); - for (var i=0; i 0) - { - if (!vbo_vicky.isReadyFaces(gl, magoManager.vboMemoryManager)) - { return; } - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vbo_vicky.meshFacesCacheKey); - gl.drawElements(gl.TRIANGLES, vbo_vicky.indicesCount, gl.UNSIGNED_SHORT, 0); // Fill.*** - } - else - { - gl.drawArrays(gl.TRIANGLES, 0, vertices_count); - } - } - else - { - /* - if (!vbo_vicky.isReadyFaces(gl, magoManager.vboMemoryManager)) - { return; } - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vbo_vicky.meshFacesCacheKey); - gl.drawElements(gl.LINE_STRIP, vbo_vicky.indicesCount, gl.UNSIGNED_SHORT, 0); // Fill.*** - */ - gl.drawArrays(gl.LINE_STRIP, 0, vertices_count); - } - } + resultPixelPos = ManagerUtils.cameraCoordPositionToWorldCoord(pixelPosCamCoord, resultPixelPos, magoManager); + return resultPixelPos; }; - - - - - - - - - - - - - - - - - - - - - - - -'use strict'; - /** - * ?? - * @class SceneState + * Calculates a world coordinate point to screen coordinate. + * @param {WebGLRenderingContext} gl WebGL Rendering Context. + * @param {Number} worldCoordX x value of the point in world coordinate. + * @param {Number} worldCoordY y value of the point in world coordinate. + * @param {Number} worldCoordZ z value of the point in world coordinate. + * @param {Point3D} resultPixelPos The result of the calculation. + * @param {MagoManager} magoManager Mago3D main manager. + * @returns {Point3D} resultPixelPos The result of the calculation. */ -var SceneState = function() +ManagerUtils.calculateWorldPositionToScreenCoord = function(gl, worldCoordX, worldCoordY, worldCoordZ, resultScreenCoord, magoManager) { - if (!(this instanceof SceneState)) + if (resultScreenCoord === undefined) + { resultScreenCoord = new Point3D(); } + + if (magoManager.pointSC === undefined) + { magoManager.pointSC = new Point3D(); } + + if (magoManager.pointSC2 === undefined) + { magoManager.pointSC2 = new Point3D(); } + + magoManager.pointSC.set(worldCoordX, worldCoordY, worldCoordZ); + + // calculate the position in camera coords. + var pointSC2 = magoManager.pointSC2; + var sceneState = magoManager.sceneState; + pointSC2 = sceneState.modelViewMatrix.transformPoint3D(magoManager.pointSC, pointSC2); + + // now calculate the position in screen coords. + var zDist = pointSC2.z; + if (zDist > 0) { - throw new Error(Messages.CONSTRUCT_ERROR); + // the worldPoint is rear the camera. + resultScreenCoord.set(-1, -1, 0); + return resultScreenCoord; } - this.gl; - - // this contains the model matrices and camera position.*** - this.modelViewProjRelToEyeMatrix = new Matrix4(); // created as identity matrix.*** - this.modelViewRelToEyeMatrix = new Matrix4(); // created as identity matrix.*** - this.modelViewRelToEyeMatrixInv = new Matrix4(); // created as identity matrix.*** - this.modelViewMatrix = new Matrix4(); // created as identity matrix.*** - this.modelViewMatrixInv = new Matrix4(); // created as identity matrix.*** - this.projectionMatrix = new Matrix4(); // created as identity matrix.*** - this.modelViewProjMatrix = new Matrix4(); // created as identity matrix.*** - this.normalMatrix4 = new Matrix4(); // created as identity matrix.*** - this.identityMatrix4 = new Matrix4(); // created as identity matrix.*** - - this.encodedCamPosHigh = new Float32Array([0.0, 0.0, 0.0]); - this.encodedCamPosLow = new Float32Array([0.0, 0.0, 0.0]); + // now calculate the width and height of the plane in zDist. + //var fovyRad = sceneState.camera.frustum.fovyRad; - this.camera = new Camera(); - this.drawingBufferWidth = new Int32Array([1000]); - this.drawingBufferHeight = new Int32Array([1000]); - this.mouseAction = new MouseAction(); + var planeHeight = sceneState.camera.frustum.tangentOfHalfFovy*zDist*2; + var planeWidth = planeHeight * sceneState.camera.frustum.aspectRatio; + var pixelX = -pointSC2.x * sceneState.drawingBufferWidth / planeWidth; + var pixelY = -(pointSC2.y) * sceneState.drawingBufferHeight / planeHeight; + + pixelX += sceneState.drawingBufferWidth / 2; + pixelY += sceneState.drawingBufferHeight / 2; + pixelY = sceneState.drawingBufferHeight - pixelY; + resultScreenCoord.set(pixelX, pixelY, 0); - // lighting & ssao.*** - this.ambientReflectionCoef = 0.45; // 0.2. - this.diffuseReflectionCoef = 0.75; // 1.0 - this.specularReflectionCoef = 0.6; // 0.7 - this.specularColor = new Float32Array([0.7, 0.7, 0.7]); - this.ssaoRadius = 0.15; - this.shininessValue = 40.0; - this.ssaoNoiseScale2 = new Float32Array([1.0, 1.0]); // [this.depthFboNeo.width[0]/this.noiseTexture.width, this.depthFboNeo.height[0]/this.noiseTexture.height] - this.ssaoKernel16 = [ 0.33, 0.0, 0.85, - 0.25, 0.3, 0.5, - 0.1, 0.3, 0.85, - -0.15, 0.2, 0.85, - -0.33, 0.05, 0.6, - -0.1, -0.15, 0.85, - -0.05, -0.32, 0.25, - 0.2, -0.15, 0.85, - 0.6, 0.0, 0.55, - 0.5, 0.6, 0.45, - -0.01, 0.7, 0.35, - -0.33, 0.5, 0.45, - -0.45, 0.0, 0.55, - -0.65, -0.5, 0.7, - 0.0, -0.5, 0.55, - 0.33, 0.3, 0.35]; - - this.ssaoSphereKernel32 = [ 0.33, 0.0, 0.85, - 0.25, 0.3, 0.5, - 0.1, 0.3, 0.85, - -0.15, 0.2, 0.85, - -0.33, 0.05, 0.6, - -0.1, -0.15, 0.85, - -0.05, -0.32, 0.25, - 0.2, -0.15, 0.85, - 0.6, 0.0, 0.55, - 0.5, 0.6, 0.45, - -0.01, 0.7, 0.35, - -0.33, 0.5, 0.45, - -0.45, 0.0, 0.55, - -0.65, -0.5, 0.7, - 0.0, -0.5, 0.55, - 0.33, 0.3, 0.35, - - 0.33, 0.0, -0.85, - 0.25, 0.3, -0.5, - 0.1, 0.3, -0.85, - -0.15, 0.2, -0.85, - -0.33, 0.05, -0.6, - -0.1, -0.15, -0.85, - -0.05, -0.32, -0.25, - 0.2, -0.15, -0.85, - 0.6, 0.0, -0.55, - 0.5, 0.6, -0.45, - -0.01, 0.7, -0.35, - -0.33, 0.5, -0.45, - -0.45, 0.0, -0.55, - -0.65, -0.5, -0.7, - 0.0, -0.5, -0.55, - 0.33, 0.3, -0.35]; - - this.bMust = false; + return resultScreenCoord; +}; + +/** + * Calculates the direction vector of a ray that starts in the camera position and + * continues to the pixel position in camera space. + * @param {Number} pixelX Screen x position of the pixel. + * @param {Number} pixelY Screen y position of the pixel. + * @param {Float32Array(3)} resultRay Result of the calculation. + * @returns {Float32Array(3)} resultRay Result of the calculation. + */ +ManagerUtils.getRayCamSpace = function(pixelX, pixelY, resultRay, magoManager) +{ + // in this function "ray" is a vector. + var sceneState = magoManager.sceneState; + var frustum_far = 1.0; // unitary frustum far. + var frustum = sceneState.camera.frustum; + var aspectRatio = frustum.aspectRatio; + var tangentOfHalfFovy = frustum.tangentOfHalfFovy; - // webWorldWind vars.*** - this.dc; + var hfar = 2.0 * tangentOfHalfFovy * frustum_far; //var hfar = 2.0 * Math.tan(fovy/2.0) * frustum_far; + var wfar = hfar * aspectRatio; + var mouseX = pixelX; + var mouseY = sceneState.drawingBufferHeight - pixelY; + if (resultRay === undefined) + { resultRay = new Float32Array(3); } + resultRay[0] = wfar*((mouseX/sceneState.drawingBufferWidth) - 0.5); + resultRay[1] = hfar*((mouseY/sceneState.drawingBufferHeight) - 0.5); + resultRay[2] = - frustum_far; + return resultRay; +}; + +/** + * Calculates the direction vector of a ray that starts in the camera position and + * continues to the pixel position in world space. + * @param {WebGLRenderingContext} gl WebGL Rendering Context. + * @param {Number} pixelX Screen x position of the pixel. + * @param {Number} pixelY Screen y position of the pixel. + * @returns {Line} resultRay + */ +ManagerUtils.getRayWorldSpace = function(gl, pixelX, pixelY, resultRay, magoManager) +{ + // in this function the "ray" is a line. + if (resultRay === undefined) + { resultRay = new Line(); } - // insertIssue states.*** - this.insertIssueState = 0; // 0 = no started. 1 = started.*** + // world ray = camPos + lambda*camDir. + var camPos = magoManager.sceneState.camera.position; + var rayCamSpace = new Float32Array(3); + rayCamSpace = ManagerUtils.getRayCamSpace(pixelX, pixelY, rayCamSpace, magoManager); - // provisionally.*** - this.textureFlipYAxis = false; + if (magoManager.pointSC === undefined) + { magoManager.pointSC = new Point3D(); } - // mouse.*** - this.mouseButton = -1; + var pointSC = magoManager.pointSC; + var pointSC2 = magoManager.pointSC2; + pointSC.set(rayCamSpace[0], rayCamSpace[1], rayCamSpace[2]); + + // now, must transform this posCamCoord to world coord. + pointSC2 = magoManager.sceneState.modelViewMatrixInv.rotatePoint3D(pointSC, pointSC2); // rayWorldSpace. + pointSC2.unitary(); // rayWorldSpace. + resultRay.setPointAndDir(camPos.x, camPos.y, camPos.z, pointSC2.x, pointSC2.y, pointSC2.z);// original. + + return resultRay; }; @@ -53475,247 +67502,36 @@ var SceneState = function() -'use strict'; -// NO USED. -/** - * 어떤 일을 하고 있습니까? - * @class Selection - */ -var Selection = function() -{ - if (!(this instanceof Selection)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - - this.drawing_height; - this.drawing_width; - this.GAIA_selectFrameBuffer; - this.GAIA_selectRenderBuffer; - this.GAIA_selectRttTexture; - - this.currentByteColorPicked = new Uint8Array(4); - this.currentSelectedObj_idx = -1; -}; -/** - * 어떤 일을 하고 있습니까? - * @param gl 변수 - * @param drawingBufferWidth 변수 - * @param drawingBufferHeight 변수 - */ -Selection.prototype.init = function(gl, drawingBufferWidth, drawingBufferHeight) -{ - // http://www.webglacademy.com/courses.php?courses=0|1|20|2|3|4|23|5|6|7|10#10 - this.drawing_height = drawingBufferHeight; - this.drawing_width = drawingBufferWidth; - //this.lastCapturedColourMap = new Uint8Array(this.drawing_width * this.drawing_height * 4); - this.GAIA_selectFrameBuffer = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.GAIA_selectFrameBuffer); - - this.GAIA_selectRenderBuffer = gl.createRenderbuffer(); - gl.bindRenderbuffer(gl.RENDERBUFFER, this.GAIA_selectRenderBuffer); - gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.drawing_width, this.drawing_height); - this.GAIA_selectRttTexture = gl.createTexture(); - gl.bindTexture(gl.TEXTURE_2D, this.GAIA_selectRttTexture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.drawing_width, this.drawing_height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.GAIA_selectRttTexture, 0); - gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.GAIA_selectRenderBuffer); - - // Finally... - gl.bindTexture(gl.TEXTURE_2D, null); - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, null); -}; -'use strict'; -/** - * SelectionCandidates - * - * @alias SelectionCandidates - * @class SelectionCandidates - */ -var SelectionCandidates = function() -{ - if (!(this instanceof SelectionCandidates)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - this.referencesMap = {}; - this.octreesMap = {}; - this.buildingsMap = {}; - this.nodesMap = {}; - - this.currentReferenceSelected; - this.currentOctreeSelected; - this.currentBuildingSelected; - this.currentNodeSelected; -}; -/** - * SelectionCandidates - * - * @alias SelectionCandidates - * @class SelectionCandidates - */ -SelectionCandidates.prototype.setCandidates = function(idxKey, reference, octree, building, node) -{ - if (reference) - { - this.referencesMap[idxKey] = reference; - } - - if (octree) - { - this.octreesMap[idxKey] = octree; - } - - if (building) - { - this.buildingsMap[idxKey] = building; - } - - if (node) - { - this.nodesMap[idxKey] = node; - } -}; -/** - * SelectionCandidates - * - * @alias SelectionCandidates - * @class SelectionCandidates - */ -SelectionCandidates.prototype.clearCandidates = function() -{ - this.referencesMap = {}; - this.octreesMap = {}; - this.buildingsMap = {}; - this.nodesMap = {}; -}; -/** - * SelectionCandidates - * - * @alias SelectionCandidates - * @class SelectionCandidates - */ -SelectionCandidates.prototype.selectObjects = function(idxKey) -{ - this.currentReferenceSelected = this.referencesMap[idxKey]; - this.currentOctreeSelected = this.octreesMap[idxKey]; - this.currentBuildingSelected = this.buildingsMap[idxKey]; - this.currentNodeSelected = this.nodesMap[idxKey]; -}; -/** - * SelectionCandidates - * - * @alias SelectionCandidates - * @class SelectionCandidates - */ -SelectionCandidates.prototype.clearCurrents = function(idxKey) -{ - this.currentReferenceSelected = undefined; - this.currentOctreeSelected = undefined; - this.currentBuildingSelected = undefined; - this.currentNodeSelected = undefined; -}; -'use strict'; -/** - * Returns the first parameter if not undefined, otherwise the second parameter. - * Useful for setting a default value for a parameter. - * - * @exports defaultValue - * - * @param {*} a - * @param {*} b - * @returns {*} Returns the first parameter if not undefined, otherwise the second parameter. - * - * @example - * param = defaultValue(param, 'default'); - * - * @copyright https://github.com/AnalyticalGraphicsInc/cesium - */ -function defaultValue(a, b) -{ - if (a !== undefined) - { - return a; - } - return b; -} -'use strict'; -/** - * 어떤 일을 하고 있습니까? - * @class ByteColor - */ -var ByteColor = function() -{ - if (!(this instanceof ByteColor)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - this.ByteR = 0; - this.ByteG = 0; - this.ByteB = 0; - this.ByteAlfa = 255; -}; -/** - * 어떤 일을 하고 있습니까? - */ -ByteColor.prototype.destroy = function() -{ - this.ByteR = null; - this.ByteG = null; - this.ByteB = null; - this.ByteAlfa = null; -}; -/** - * 어떤 일을 하고 있습니까? - * @param byteRed 변수 - * @param byteGreen 변수 - * @param byteBlue 변수 - */ -ByteColor.prototype.set = function(byteRed, byteGreen, byteBlue) -{ - this.ByteR = byteRed; - this.ByteG = byteGreen; - this.ByteB = byteBlue; -}; -/** - * 어떤 일을 하고 있습니까? - * @class Point3DAux - */ -var Point3DAux = function() -{ - if (!(this instanceof Point3DAux)) - { - throw new Error(Messages.CONSTRUCT_ERROR); - } - this.x = 0.0; - this.y = 0.0; - this.z = 0.0; - //this.IdxInIist; -}; + + + + + + + + +'use strict'; /** * 어떤 일을 하고 있습니까? * @class TTriangle @@ -53754,7 +67570,7 @@ TTriangle.prototype.invert = function() this.mVertex2 = this.mVertex3; this.mVertex3 = vertexAux; }; - +'use strict'; /** * 어떤 일을 하고 있습니까? * @class TTrianglesList @@ -53808,6 +67624,8 @@ TTrianglesList.prototype.getTTriangle = function(idx) } }; + +'use strict'; /** * 어떤 일을 하고 있습니까? * @class TTrianglesMatrix @@ -53820,7 +67638,7 @@ var TTrianglesMatrix = function() } this.tTrianglesListsArray = []; - // SCRATX.********************* + // SCRATX. this.totalTTrianglesArraySC = []; }; @@ -53890,1056 +67708,1472 @@ TTrianglesMatrix.prototype.getVBOIndicesShortArray = function() -'use strict'; +/** + * A module containing Data from IndoorGML.
+ * This module contains the variables required to navigate in 3D buildings built in DisplayHelper and + * the functions required for parsing that variables from json object.
+ * Unlike existing maps, the indoor space viewer is restricted due to the spatial factor of the wall.
+ * With this in mind, this module ensures that the user moves only on the network defined in the GML file + * to limit unusual behavior such as user penetration through the wall.
+ * @module GMLDataContainer + */ -var ManagerUtils = function() -{ - // sqrtTable. - this.sqrtTable = []; - // make 100 values. - var increValue = 0.01; - for (var i=0; i<101; i++) - { - this.sqrtTable[i] = Math.sqrt(1+(increValue*i)*(increValue*i)); - } - -}; + 'use strict'; -ManagerUtils.pointToGeographicCoord = function(point, resultGeographicCoord, magoManager) -{ - if (resultGeographicCoord === undefined) - { resultGeographicCoord = new GeographicCoord(); } - - if (magoManager.configInformation.geo_view_library === Constant.WORLDWIND) - { - var globe = magoManager.wwd.globe; - var origin = new WorldWind.Position(); - origin = globe.computePositionFromPoint(point.x, point.y, point.z, origin); - resultGeographicCoord.setLonLatAlt(origin.longitude, origin.latitude, origin.altitude); - } - else if (magoManager.configInformation.geo_view_library === Constant.CESIUM) - { - var cartographic = Cesium.Cartographic.fromCartesian(new Cesium.Cartesian3(point.x, point.y, point.z)); - resultGeographicCoord.setLonLatAlt(cartographic.longitude * (180.0/Math.PI), cartographic.latitude * (180.0/Math.PI), cartographic.height); - } - else if (magoManager.configInformation.geo_view_library === Constant.MAGOWORLD) - { - var cartographic = Globe.CartesianToGeographicWgs84(point.x, point.y, point.z, cartographic); - resultGeographicCoord.setLonLatAlt(cartographic.longitude, cartographic.latitude, cartographic.height); - } - - return resultGeographicCoord; -}; -ManagerUtils.geographicCoordToWorldPoint = function(longitude, latitude, altitude, resultWorldPoint, magoManager) -{ - if (resultWorldPoint === undefined) - { resultWorldPoint = new Point3D(); } + /** + * Create new GMLDataContainer + * @alias module:GMLDataContainer + * @param {Object} jsonresponse JSON object parsed from inputed json data file + */ + function GMLDataContainer(jsonresponse, gmlVersion) { + + /** + * JSON object parsed from inputed json data file.
+ * Inputed json data file is converted from IndoorGML file.
+ * You can convert IndoorGML to json through 'gmlToJson' in our git hub project. + */ + this.jsonresponse = jsonresponse; + + /** + * This value appears in the IndoorGML document .
+ * Within the topographic space layer, a state can be associated with a room, corridor, door, etc.
+ * And this may be an isolated node, i.e. not connected to another State. + */ + this.nodes = []; + + /** + * This value appears in the IndoorGML document .
+ * And Transition is an edge that represents the adjacency or connectivity relationships among nodes representing space objects in primal space.
+ * Transition always connects two States. + */ + this.edges = []; + + /** + * In IndoorGML, CellSpaceis a base class for representing the indoor space.
+ * Each CellSpace is associated with a geometry object which can be represented as several geometry primitive types such as 2D and 3D.
+ * In short, and are responsible for the relationship between the spaces, and is about the geometry that constitutes the space. + */ + this.cellSpaceMembers = []; + + /** + * CellSpaceBoundary is used to semantically describe the boundary of each geographical feature in space.
+ * You can notice that if you visualize geometry of this it look like door or something connecting one space to other.
+ * In this project we don't need to use this value because we can distinguish door from description of cellSpaceMembers. + */ + this.cellSpaceBoundaryMembers = []; + + /** + * The maximum x coordinate. This value will used for calculating center x coordinate of building. + */ + this.max_X = 0; + + /** + * The maximum y coordinate. This value will used for calculating center y coordinate of building. + */ + this.max_Y = 0; + + /** + * The maximum z coordinate. This value will used for calculating center z coordinate of building. + */ + this.max_Z = 0; + + + + /** + * The maximum x coordinate. This value will used for calculating center x coordinate of building. + */ + this.min_X = 0; + + /** + * The maximum y coordinate. This value will used for calculating center y coordinate of building. + */ + this.min_Y = 0; + + /** + * The maximum z coordinate. This value will used for calculating center z coordinate of building. + */ + this.min_Z = 0; + + + + /** + * The Center X coordinate of building. + */ + this.center_X = 0; + + /** + * The Center Y coordinate of building. + */ + this.center_Y = 0; + + + /** The object onto which to store the transformation result. */ + this.ENU = new Cesium.Matrix4(); + + this.jsonParsor; + + this.parsingJson(jsonresponse, gmlVersion); + this.setCenter(); + } - var cartesian = Globe.geographicToCartesianWgs84(longitude, latitude, altitude, undefined); - - if (magoManager.configInformation !== undefined && magoManager.configInformation.geo_view_library === Constant.WORLDWIND) - { - resultWorldPoint.set(cartesian[1], cartesian[2], cartesian[0]); - return resultWorldPoint; - } - - resultWorldPoint.set(cartesian[0], cartesian[1], cartesian[2]); - - return resultWorldPoint; -}; -ManagerUtils.getTransformationMatrixInPoint = function(point, resultTMatrix, resultMatrixInv, magoManager) -{ - if (magoManager.configInformation.geo_view_library === Constant.WORLDWIND) - { - ;// - } - else if (magoManager.configInformation.geo_view_library === Constant.CESIUM) - { - if (resultTMatrix === undefined) - { resultTMatrix = new Matrix4(); } - - Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3(point.x, point.y, point.z), undefined, resultTMatrix._floatArrays); - - if (resultMatrixInv) - { - Cesium.Matrix4.inverseTransformation(resultTMatrix._floatArrays, resultMatrixInv._floatArrays); - } - } - - return resultTMatrix; -}; -ManagerUtils.translatePivotPointGeoLocationData = function(geoLocationData, newPivotPoint) -{ - // this function NO modifies the geographic coords.*** - // "newPivotPoint" is in buildingCoords.*** - // "newPivotPoint" is the desired position of the new origen of coords, for example: - // in a building you can desire the center of the bbox as the origin of the coords.*** - if (geoLocationData === undefined) - { return; } + /** + * Parse the data(nodes, edges, cellSpace, cellSpaceBoundary ) required to produce the viewer in the JSON object. + * @param {Object} jsonresponse JSON object parsed from inputed json data file + */ + GMLDataContainer.prototype.parsingJson = function(jsonresponse, gmlVersion) { - var rawTranslation = new Point3D(); - rawTranslation.set(-newPivotPoint.x, -newPivotPoint.y, -newPivotPoint.z); + if(gmlVersion == "1.0.1"){ + this.jsonParsor = new JsonParsor_1_0_1(jsonresponse); + } + else if(gmlVersion == "1.0.3"){ + this.jsonParsor = new JsonParsor_1_0_3(jsonresponse); + } + else{ + alert(gmlVersion + " is not a vailid version!"); + } - geoLocationData.pivotPointTraslation = rawTranslation; - geoLocationData.doEffectivePivotPointTranslation(); -}; + this.nodes = this.jsonParsor.parsingNodeData(jsonresponse); + this.edges = this.jsonParsor.parsingEdgeData(jsonresponse); + this.cellSpaceMembers = this.jsonParsor.parsingCellSpaceMember(jsonresponse); -ManagerUtils.calculateGeoLocationMatrixAtWorldPosition = function(worldPosition, resultGeoLocMatrix, magoManager) -{ - // this function calculates the transformation matrix for (x, y, z) coordinate, that has NO heading, pitch or roll rotations. - if (resultGeoLocMatrix === undefined) - { resultGeoLocMatrix = new Matrix4(); } + this.max_X = this.jsonParsor.getMaxX(); + this.max_Y = this.jsonParsor.getMaxY(); + this.max_Z = this.jsonParsor.getMaxZ(); + this.min_X = this.jsonParsor.getMinX(); + this.min_Y = this.jsonParsor.getMinY(); + this.min_Z = this.jsonParsor.getMinZ(); + // this.cellSpaceBoundaryMembers = this.parsingCellSpaceBoundaryMember(jsonresponse); - if (magoManager.configInformation.geo_view_library === Constant.WORLDWIND) - { - // * if this in webWorldWind: - var xAxis = new WorldWind.Vec3(0, 0, 0), - yAxis = new WorldWind.Vec3(0, 0, 0), - zAxis = new WorldWind.Vec3(0, 0, 0); - var tMatrix = WorldWind.Matrix.fromIdentity(); - - WorldWind.WWMath.localCoordinateAxesAtPoint([worldPosition.x, worldPosition.y, worldPosition.z], magoManager.wwd.globe, xAxis, yAxis, zAxis); - - tMatrix.set( - xAxis[0], yAxis[0], zAxis[0], worldPosition.x, - xAxis[1], yAxis[1], zAxis[1], worldPosition.y, - xAxis[2], yAxis[2], zAxis[2], worldPosition.z, - 0, 0, 0, 1); - - var tMatrixColMajorArray = WorldWind.Matrix.fromIdentity(); - tMatrixColMajorArray = tMatrix.columnMajorComponents(tMatrixColMajorArray); - resultGeoLocMatrix.setByFloat32Array(tMatrixColMajorArray); - return resultGeoLocMatrix; - } + }; - if (magoManager.globe === undefined) - { magoManager.globe = new Globe(); } - magoManager.globe.transformMatrixAtCartesianPointWgs84(worldPosition.x, worldPosition.y, worldPosition.z, resultGeoLocMatrix._floatArrays); - - return resultGeoLocMatrix; -}; -ManagerUtils.calculateGeoLocationMatrixAtLonLatAlt = function(longitude, latitude, altitude, resultGeoLocMatrix, magoManager) -{ - // this function calculates the transformation matrix for (longitude, latitude, altitude) coordinate, that has NO heading, pitch or roll rotations. - if (resultGeoLocMatrix === undefined) - { resultGeoLocMatrix = new Matrix4(); } - - var worldPosition; - worldPosition = this.geographicCoordToWorldPoint(longitude, latitude, altitude, worldPosition, magoManager); - resultGeoLocMatrix = ManagerUtils.calculateGeoLocationMatrixAtWorldPosition(worldPosition, resultGeoLocMatrix, magoManager); - - return resultGeoLocMatrix; -}; + /** + * Calculate the central coordinates of the building. + */ + GMLDataContainer.prototype.setCenter = function() { + this.center_X = (this.min_X + this.max_X) / 2; + this.center_Y = (this.min_Y + this.max_Y) / 2; + } -ManagerUtils.calculateTransformMatrixAtWorldPosition = function(worldPosition, heading, pitch, roll, resultGeoLocMatrix, resultTransformMatrix, magoManager) -{ - // This function calculates the "resultGeoLocMatrix" & "resultTransformMatrix". - // note: "resultGeoLocMatrix" is the transformMatrix without the heading, pitch, roll rotations. - // note: "resultTransformMatrix" is the transformMatrix including the heading, pitch, roll rotations. - var xRotMatrix = new Matrix4(); // created as identity matrix. - var yRotMatrix = new Matrix4(); // created as identity matrix. - var zRotMatrix = new Matrix4(); // created as identity matrix. - - if (heading !== undefined && heading !== 0) - { zRotMatrix.rotationAxisAngDeg(heading, 0.0, 0.0, 1.0); } - if (pitch !== undefined && pitch !== 0) - { xRotMatrix.rotationAxisAngDeg(pitch, 1.0, 0.0, 0.0); } - if (roll !== undefined && roll !== 0) - { yRotMatrix.rotationAxisAngDeg(roll, 0.0, 1.0, 0.0); } + /** + * When the inputted coordinates differs from the actual world, this tries to rotate the building to reduce the gap. + * @param {Cesium.Viewer} viewer + * @param {Cesium.Cartesian3} position position on actual world + * @param {number} angle angle for rotate + */ + GMLDataContainer.prototype.rotateBuilding = function(viewer, position, angle) { + + var ellipsoid = viewer.scene.globe.ellipsoid; + + /** Rotation matrix */ + var orientation = new Cesium.Matrix4(Math.cos(angle), -Math.sin(angle), 0, 0, + Math.sin(angle), Math.cos(angle), 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + + + this.rotateCellSpaceMember(orientation, position, ellipsoid); + this.rotateCellSpaceBoundaryMembers(orientation, position, ellipsoid); + this.rotateNodes(orientation); + this.rotateEdges(orientation); + + } + + + + /** + * Rotate nodes + * @param {Cesium.Matrix4} orientation rotation matrix for rotation + */ + GMLDataContainer.prototype.rotateNodes = function(orientation) { + + var nodesLen = this.nodes.length; + + /** Applying translation and rotation to the nodes */ + for (var i = 0; i < nodesLen; i++) { + + /** Translating coordinates + converting the result to Cartesian3 */ + var offset = new Cesium.Cartesian3(this.nodes[i].coordinates[0] - this.center_X, + this.nodes[i].coordinates[1] - this.center_Y, + this.nodes[i].coordinates[2] - this.min_Z); + + /** Applying rotation to the offset */ + var finalPos = Cesium.Matrix4.multiplyByPoint(orientation, offset, new Cesium.Cartesian3()); + + /** Report offset to the actual position of LWM */ + var new_coord = Cesium.Matrix4.multiplyByPoint(this.ENU, finalPos, finalPos); + + /** Replacing the old coordinates by the new ones */ + this.nodes[i].coordinates[0] = new_coord.x; + this.nodes[i].coordinates[1] = new_coord.y; + this.nodes[i].coordinates[2] = new_coord.z; + } + } + + + + /** + * Rotate edges + * @param {Cesium.Matrix4} orientation rotation matrix for rotation + */ + GMLDataContainer.prototype.rotateEdges = function(orientation) { + + /** Applying translation and rotation to the edges */ + for (var i = 0; i < this.edges.length; i++) { + + for (var j = 0; j < this.edges[i].stateMembers.length; j++) { + + var offset = new Cesium.Cartesian3(this.edges[i].stateMembers[j].coordinates[0] - this.center_X, + this.edges[i].stateMembers[j].coordinates[1] - this.center_Y, + this.edges[i].stateMembers[j].coordinates[2] - this.min_Z); + + var finalPos = Cesium.Matrix4.multiplyByPoint(orientation, offset, new Cesium.Cartesian3()); + + var new_coord = Cesium.Matrix4.multiplyByPoint(this.ENU, finalPos, finalPos); + + this.edges[i].stateMembers[j].coordinates[0] = new_coord.x; + this.edges[i].stateMembers[j].coordinates[1] = new_coord.y; + this.edges[i].stateMembers[j].coordinates[2] = new_coord.z; + } + } + } + + + + /** + * Rotate cellSpaceMembers + * @param {Cesium.Matrix4} orientation rotation matrix for rotation + * @param {Cesium.Cartesian3} position position on actual world + * @param {Cesium.Ellipsoid} ellipsoid + */ + GMLDataContainer.prototype.rotateCellSpaceMember = function(orientation, position, ellipsoid) { + + Cesium.Transforms.eastNorthUpToFixedFrame(position, ellipsoid, this.ENU); + + /** Applying translation and rotation to coordinates */ + for (var i = 0; i < this.cellSpaceMembers.length; i++) { + + var csmLen = this.cellSpaceMembers[i].surfaceMember.length; + + for (var j = 0; j < csmLen; j++) { + var smLen = this.cellSpaceMembers[i].surfaceMember[j].coordinates.length; + + for (var k = 0; k < smLen; k += 3) { + + /** Translating coordinates + converting the result to Cartesian3 */ + var offset = new Cesium.Cartesian3(this.cellSpaceMembers[i].surfaceMember[j].coordinates[k] - this.center_X, + this.cellSpaceMembers[i].surfaceMember[j].coordinates[k + 1] - this.center_Y, + this.cellSpaceMembers[i].surfaceMember[j].coordinates[k + 2] - this.min_Z); + + /** Applying rotation to the offset */ + var finalPos = Cesium.Matrix4.multiplyByPoint(orientation, offset, new Cesium.Cartesian3()); + + /** Report offset to the actual position of LWM */ + var new_coord = Cesium.Matrix4.multiplyByPoint(this.ENU, finalPos, finalPos); + + /** Replacing the old coordinates by the new ones */ + this.cellSpaceMembers[i].surfaceMember[j].coordinates[k] = new_coord.x; + this.cellSpaceMembers[i].surfaceMember[j].coordinates[k + 1] = new_coord.y; + this.cellSpaceMembers[i].surfaceMember[j].coordinates[k + 2] = new_coord.z; + } + } + } + } + + + + /** + * Rotate cellSpaceBoundaryMembers + * @param {Cesium.Matrix4} orientation rotation matrix for rotation + * @param {Cesium.Cartesian3} position position on actual world + * @param {Cesium.Ellipsoid} ellipsoid + */ + GMLDataContainer.prototype.rotateCellSpaceBoundaryMembers = function(orientation, position, ellipsoid) { + + Cesium.Transforms.eastNorthUpToFixedFrame(position, ellipsoid, this.ENU); + + /** Applying translation and rotation to coordinates */ + for (var i = 0; i < this.cellSpaceBoundaryMembers.length; i++) { + + var csmLen = this.cellSpaceBoundaryMembers[i].surfaceMember.length; + + for (var j = 0; j < csmLen; j++) { + var smLen = this.cellSpaceBoundaryMembers[i].surfaceMember[j].coordinates.length; + + for (var k = 0; k < smLen; k += 3) { + + /** Translating coordinates + converting the result to Cartesian3 */ + var offset = new Cesium.Cartesian3(this.cellSpaceBoundaryMembers[i].surfaceMember[j].coordinates[k] - this.center_X, + this.cellSpaceBoundaryMembers[i].surfaceMember[j].coordinates[k + 1] - this.center_Y, + this.cellSpaceBoundaryMembers[i].surfaceMember[j].coordinates[k + 2] - this.min_Z); + + /** Applying rotation to the offset */ + var finalPos = Cesium.Matrix4.multiplyByPoint(orientation, offset, new Cesium.Cartesian3()); + + /** Report offset to the actual position of LWM */ + var new_coord = Cesium.Matrix4.multiplyByPoint(this.ENU, finalPos, finalPos); + + /** Replacing the old coordinates by the new ones */ + this.cellSpaceBoundaryMembers[i].surfaceMember[j].coordinates[k] = new_coord.x; + this.cellSpaceBoundaryMembers[i].surfaceMember[j].coordinates[k + 1] = new_coord.y; + this.cellSpaceBoundaryMembers[i].surfaceMember[j].coordinates[k + 2] = new_coord.z; + } + } + } + } + + + + +/** + * @module JsonParsor_1_0_1 + */ + + 'use strict'; + + + /** + * @alias module:JsonParsor_1_0_1 + * @param {Object} jsonresponse JSON object parsed from inputed json data file + */ + function JsonParsor_1_0_1(jsonresponse) { + + /** + * JSON object parsed from inputed json data file.
+ * Inputed json data file is converted from IndoorGML file.
+ * You can convert IndoorGML to json through 'gmlToJson' in our git hub project. + */ + this.jsonresponse = jsonresponse; + + /** + * The maximum x coordinate. This value will used for calculating center x coordinate of building. + */ + this.max_X = 0; + + /** + * The maximum y coordinate. This value will used for calculating center y coordinate of building. + */ + this.max_Y = 0; + + /** + * The maximum z coordinate. This value will used for calculating center z coordinate of building. + */ + this.max_Z = 0; + + + + /** + * The maximum x coordinate. This value will used for calculating center x coordinate of building. + */ + this.min_X = 0; + + /** + * The maximum y coordinate. This value will used for calculating center y coordinate of building. + */ + this.min_Y = 0; + + /** + * The maximum z coordinate. This value will used for calculating center z coordinate of building. + */ + this.min_Z = 0; + + } + + + /** + * @param {Object} jsonresponse JSON object parsed from inputed json data file + */ + JsonParsor_1_0_1.prototype.parsingNodeData = function(jsonresponse) { + + var nodes = []; + + /** Extracting state members */ + var sm = jsonresponse.value.multiLayeredGraph.spaceLayers["0"].spaceLayerMember["0"].spaceLayer.nodes["0"].stateMember; + var smLen = sm.length; + + for (var j = 0; j < smLen; j++) { + + var coordinates = sm[j].state.geometry.point.pos.value; + var stateMemberObject = new StateMember(coordinates); + + /** Adding the state member to the nodes array */ + nodes.push(stateMemberObject); + } + + return nodes; + }; + + + + /** + * @param {Object} jsonresponse JSON object parsed from inputed json data file + */ + JsonParsor_1_0_1.prototype.parsingEdgeData = function(jsonresponse) { + + var edges = []; + + /** Extracting transition members */ + var tm = jsonresponse.value.multiLayeredGraph.spaceLayers["0"].spaceLayerMember["0"].spaceLayer.edges["0"].transitionMember; + + /** Loop through transition Members and extracting connection, description and state members of each transition member */ + for (var i = 0; i < tm.length; i++) { + + /** Array of connections of a transition member */ + var connects = []; + + /** Getting the href of each connection */ + for (var j = 0; j < tm[i].transition.connects.length; j++) { + connects.push(tm[i].transition.connects[j].href); + } + + /** Description of a transition member */ + var description; + if (tm[i].transition.description != null) { + description = tm[i].transition.description.value; + } + + + /** Array of state members */ + var stateMembers = []; + + /** Getting coordinates of each state member */ + for (var k = 0; k < tm[i].transition.geometry.abstractCurve.value.posOrPointPropertyOrPointRep.length; k++) { + /** Creating a state member instance*/ + + var coordinates = tm[i].transition.geometry.abstractCurve.value.posOrPointPropertyOrPointRep[k].value.value; + var smObject = new StateMember(coordinates); + + + // smObject.coordinates.push(coordinates[0], coordinates[1], coordinates[2]); + stateMembers.push(smObject); + } + + + /** Creating a transition member instance */ + var transitionMemberObject = new TransitionMember(connects, description, stateMembers); + + + /** Adding the transition member to edges array */ + edges.push(transitionMemberObject); + } + + return edges; + }; + + + + /** + * Abstract cellSpaceMember data from JSON object and save it as cellSpaceMembers + * @param {Object} jsonresponse JSON object parsed from inputed json data file + */ + JsonParsor_1_0_1.prototype.parsingCellSpaceMember = function(jsonresponse) { + + var cellSpaceMembers = []; + + var cellSpaceMemberLen = jsonresponse.value.primalSpaceFeatures.primalSpaceFeatures.cellSpaceMember.length; + + for (var i = 0; i < cellSpaceMemberLen; i++) { + + /** Cell space member */ + var csm = jsonresponse.value.primalSpaceFeatures.primalSpaceFeatures.cellSpaceMember[i]; + + /** Extracting the description of the cell space member */ + var description = ""; + if (csm.abstractFeature.value.description != null) { + description = csm.abstractFeature.value.description.value; + } + + var id = ""; + if (csm.abstractFeature.value.id != null) { + id = csm.abstractFeature.value.id; + } + + /** Extracting the href of the cell space member */ + var href = ""; + if (csm.abstractFeature.value.duality.href != null) { + href = csm.abstractFeature.value.duality.href; + } + + + /** Creating an instance of the cell space member */ + var csmObject = new CellSpaceMember(description, href, id, []); + + /** Number of surface members */ + if (csm.abstractFeature.value.geometry3D != null) { + csmObject.surfaceMember = this.getCsmSurfaceMemberFromGeometry3D(csm); + } else if (csm.abstractFeature.value.geometry2D != null) { + csmObject.surfaceMember = this.getCsmSurfaceMemberFromGeometry2D(csm); + } + + + /** Filling the array with the cell space member instancesBut the problem with outline has not been solved yet. */ + cellSpaceMembers.push(csmObject); + } + + return cellSpaceMembers; + }; + + + + /** + * @param {Object} jsonresponse JSON object parsed from inputed json data file + */ + JsonParsor_1_0_1.prototype.parsingCellSpaceBoundaryMember = function(jsonresponse) { + var cellSpaceBoundaryMembers = []; + var cellSpaceBoundaryMemberLen = jsonresponse.value.primalSpaceFeatures.primalSpaceFeatures.cellSpaceBoundaryMember.length; + + for (var i = 0; i < cellSpaceBoundaryMemberLen; i++) { + + var csbm = jsonresponse.value.primalSpaceFeatures.primalSpaceFeatures.cellSpaceBoundaryMember[i]; + + var description = ""; + if (csbm.abstractFeature.value.description != null) { + description = csbm.abstractFeature.value.description.value; + } + + var id = ""; + if (csbm.abstractFeature.value.id != null) { + id = csbm.abstractFeature.value.id; + } + + /** Extracting the href of the cell space member */ + var href = ""; + if (csbm.abstractFeature.value.duality != null) { + href = csbm.abstractFeature.value.duality.href; + } + + /** Creating an instance of the cell space member */ + var csbmObject = new CellSpaceMember(description, href, id, []); + + /** Number of surface members */ + if (csbm.abstractFeature.value.geometry3D != null) { + csbmObject.surfaceMember = this.getCsbmSurfaceMemberFromGeometry3D(csbm); + } + + cellSpaceBoundaryMembers.push(csbmObject); + } + + return cellSpaceBoundaryMembers; + }; + + + + /** + * Extract surfaceMember of cellSpaceMember from the JSON object when the surface of the given GML file is configured with geometry3D. + * @param {Object} csm CellSpaceMember, cellSpaceMember part of jsonresponse. + * @returns {array} array of {@link SurfaceMember} + */ + JsonParsor_1_0_1.prototype.getCsmSurfaceMemberFromGeometry3D = function(csm) { + /** get surface MemberLen */ + var surfaceMemberLen = csm.abstractFeature.value.geometry3D.abstractSolid.value.exterior.shell.surfaceMember.length; + + var surfaceMembers = []; + + /** Loop through the surface members and creating instances */ + for (var j = 0; j < surfaceMemberLen; j++) { + + /** Surface member */ + var sm = csm.abstractFeature.value.geometry3D.abstractSolid.value.exterior.shell.surfaceMember[j]; + + /** Creating an instance of the surface member */ + var smObject = new SurfaceMember([]); + + /** Number of coordinates of the surface member */ + var coordLen = sm.abstractSurface.value.exterior.abstractRing.value.posOrPointPropertyOrPointRep.length; + + var value = sm.abstractSurface.value.exterior.abstractRing.value.posOrPointPropertyOrPointRep; + + /** Loop through the coordinates of a surfaceMember */ + for (var k = 0; k < coordLen; k++) { + smObject = this.abstractCoordinate(value[k].value.value, smObject); + } + + /** Adding the surface member to the corresponding cell space member */ + surfaceMembers.push(smObject); + } + return surfaceMembers; + } + + + + /** + * Extract surfaceMember of cellSpaceMember from the JSON object when the surface of the given GML file is configured with geometry2D. + * @param {Object} csm CellSpaceMember, cellSpaceMember part of jsonresponse. + * @returns {array} array of {@link SurfaceMember} + */ + JsonParsor_1_0_1.prototype.getCsmSurfaceMemberFromGeometry2D = function(csm) { + + var surfaceMembers = []; + + /** abstractRing */ + var ar = csm.abstractFeature.value.geometry2D.abstractSurface.value.exterior.abstractRing; + + /** Creating an instance of abstractRing */ + var arObject = new SurfaceMember([]); + + /** Number of coordinates of the surface member */ + var coordLen = ar.value.posOrPointPropertyOrPointRep.length; + + /** Loop through the coordinates of a surfaceMember */ + for (var i = 0; i < coordLen; i++) { + arObject = this.abstractCoordinate(ar.value.posOrPointPropertyOrPointRep[i].value.value, arObject); + } + + surfaceMembers.push(arObject); + + return surfaceMembers; + } + + + + /** + * Extract surfaceMember of cellSpaceBoundaryMember from the JSON object when the surface of the given GML file is configured with geometry3D. + * @param {Object} csm cellSpaceBoundaryMember, cellSpaceBoundaryMember part of jsonresponse. + * @returns {array} array of {@link SurfaceMember} + */ + JsonParsor_1_0_1.prototype.getCsbmSurfaceMemberFromGeometry3D = function(csbm) { + + var smObject = new SurfaceMember([]); + + var surfaceMembers = []; + + if (csbm.abstractFeature.value.geometry3D.abstractSurface.value.exterior != null) { + + var coordLen = csbm.abstractFeature.value.geometry3D.abstractSurface.value.exterior.abstractRing.value.posOrPointPropertyOrPointRep.length; + for (var k = 0; k < coordLen; k++) { + smObject = this.abstractCoordinate(csbm.abstractFeature.value.geometry3D.abstractSurface.value.exterior.abstractRing.value.posOrPointPropertyOrPointRep[k].value.value, smObject); + } + } + + surfaceMembers.push(smObject); + + return surfaceMembers; + } + + + + /** + * Abstract coordinates from value and save it in object.coordinates + * @param {Array} value array of coordinates. + * @param {SurfaceMember} object The coordinates obtained from value are stored in object.coordinates. + * @returns {array} array of {@link SurfaceMember} + */ + JsonParsor_1_0_1.prototype.abstractCoordinate = function(value, object) { + + /** Extracting X */ + var X = value[0]; + object.coordinates.push(X); + + + /** Test if X is maximum or minimum */ + if (X > this.max_X) { + this.max_X = X; + } else if (X < this.min_X) { + this.min_X = X; + } + + /** Extracting Y */ + var Y = value[1]; + object.coordinates.push(Y); + + if (Y > this.max_Y) { + this.max_Y = Y; + } else if (Y < this.min_Y) { + this.min_Y = Y; + } + + /** Extracting Z */ + var Z = value[2]; + object.coordinates.push(Z); + + if (Z > this.max_Z) { + this.max_Z = Z; + } else if (Z < this.min_Z) { + this.min_Z = Z; + } + + return object; + } + + JsonParsor_1_0_1.prototype.getMaxX = function(){ + return this.max_X; + } + + JsonParsor_1_0_1.prototype.getMaxY = function(){ + return this.max_Y; + } + + JsonParsor_1_0_1.prototype.getMaxZ = function(){ + return this.max_Z; + } + + JsonParsor_1_0_1.prototype.getMinX = function(){ + return this.min_X; + } + + JsonParsor_1_0_1.prototype.getMinY = function(){ + return this.min_Y; + } + + JsonParsor_1_0_1.prototype.getMinZ = function(){ + return this.min_Z; + } + + + +/** + * @module JsonParsor_1_0_3 + */ + + 'use strict'; + + + /** + * @alias module:JsonParsor_1_0_3 + * @param {Object} jsonresponse JSON object parsed from inputed json data file + */ + function JsonParsor_1_0_3(jsonresponse) { + + /** + * JSON object parsed from inputed json data file.
+ * Inputed json data file is converted from IndoorGML file.
+ * You can convert IndoorGML to json through 'gmlToJson' in our git hub project. + */ + this.jsonresponse = jsonresponse; + + /** + * The maximum x coordinate. This value will used for calculating center x coordinate of building. + */ + this.max_X = 0; + + /** + * The maximum y coordinate. This value will used for calculating center y coordinate of building. + */ + this.max_Y = 0; + + /** + * The maximum z coordinate. This value will used for calculating center z coordinate of building. + */ + this.max_Z = 0; + + + + /** + * The maximum x coordinate. This value will used for calculating center x coordinate of building. + */ + this.min_X = 0; + + /** + * The maximum y coordinate. This value will used for calculating center y coordinate of building. + */ + this.min_Y = 0; + + /** + * The maximum z coordinate. This value will used for calculating center z coordinate of building. + */ + this.min_Z = 0; + + } + + + /** + * @param {Object} jsonresponse JSON object parsed from inputed json data file + */ + JsonParsor_1_0_3.prototype.parsingNodeData = function(jsonresponse) { + + var nodes = []; + + /** Extracting state members */ + var sm = jsonresponse.value.multiLayeredGraph.multiLayeredGraph.spaceLayers["0"].spaceLayerMember["0"].spaceLayer.nodes["0"].stateMember; + var smLen = sm.length; + + for (var j = 0; j < smLen; j++) { + + var coordinates = sm[j].state.geometry.point.pos.value; + var stateMemberObject = new StateMember(coordinates); + + // Son 20181121.******************************************* + stateMemberObject.id = sm[j].state.id; + // End Son 20181121.--------------------------------------- + + /** Adding the state member to the nodes array */ + nodes.push(stateMemberObject); + } + + return nodes; + }; + + + + /** + * @param {Object} jsonresponse JSON object parsed from inputed json data file + */ + JsonParsor_1_0_3.prototype.parsingEdgeData = function(jsonresponse) { + + var edges = []; + + /** Extracting transition members */ + var tm = jsonresponse.value.multiLayeredGraph.multiLayeredGraph.spaceLayers["0"].spaceLayerMember["0"].spaceLayer.edges["0"].transitionMember; + + /** Loop through transition Members and extracting connection, description and state members of each transition member */ + for (var i = 0; i < tm.length; i++) { + + /** Array of connections of a transition member */ + var connects = []; + + /** Getting the href of each connection */ + for (var j = 0; j < tm[i].transition.connects.length; j++) { + connects.push(tm[i].transition.connects[j].href); + } + + /** Description of a transition member */ + var description; + if (tm[i].transition.description != null) { + description = tm[i].transition.description.value; + } + + + /** Array of state members */ + var stateMembers = []; + + /** Getting coordinates of each state member */ + for (var k = 0; k < tm[i].transition.geometry.abstractCurve.value.posOrPointPropertyOrPointRep.length; k++) { + /** Creating a state member instance*/ + + var coordinates = tm[i].transition.geometry.abstractCurve.value.posOrPointPropertyOrPointRep[k].value.value; + var smObject = new StateMember(coordinates); + + // Son 20181121.******************************************* + //smObject.id = tm[i].transition.id; + // End Son 20181121.--------------------------------------- + + // smObject.coordinates.push(coordinates[0], coordinates[1], coordinates[2]); + stateMembers.push(smObject); + } + + + /** Creating a transition member instance */ + var transitionMemberObject = new TransitionMember(connects, description, stateMembers); + + + /** Adding the transition member to edges array */ + edges.push(transitionMemberObject); + } + + return edges; + }; + + + + /** + * Abstract cellSpaceMember data from JSON object and save it as cellSpaceMembers + * @param {Object} jsonresponse JSON object parsed from inputed json data file + */ + JsonParsor_1_0_3.prototype.parsingCellSpaceMember = function(jsonresponse) { + + var cellSpaceMembers = []; + + var cellSpaceMemberLen = jsonresponse.value.primalSpaceFeatures.primalSpaceFeatures.cellSpaceMember.length; + + for (var i = 0; i < cellSpaceMemberLen; i++) { + + /** Cell space member */ + var csm = jsonresponse.value.primalSpaceFeatures.primalSpaceFeatures.cellSpaceMember[i]; + + /** Extracting the description of the cell space member */ + var description = ""; + if (csm.cellSpace.description != null) { + description = csm.cellSpace.description.value; + } + + var id = ""; + if (csm.cellSpace.id != null) { + id = csm.cellSpace.id; + } + + /** Extracting the href of the cell space member */ + var href = ""; + if (csm.cellSpace.duality.href != null) { + href = csm.cellSpace.duality.href; + } + + + /** Creating an instance of the cell space member */ + var csmObject = new CellSpaceMember(description, href, id, []); + + /** Number of surface members */ + if (csm.cellSpace.cellSpaceGeometry.geometry3D != null) { + csmObject.surfaceMember = this.getCsmSurfaceMemberFromGeometry3D(csm); + } else if (csm.cellSpace.cellSpaceGeometry.geometry2D != null) { + csmObject.surfaceMember = this.getCsmSurfaceMemberFromGeometry2D(csm); + } + + + /** Filling the array with the cell space member instancesBut the problem with outline has not been solved yet. */ + cellSpaceMembers.push(csmObject); + } + + return cellSpaceMembers; + }; + + + + /** + * @param {Object} jsonresponse JSON object parsed from inputed json data file + */ + JsonParsor_1_0_3.prototype.parsingCellSpaceBoundaryMember = function(jsonresponse) { + var cellSpaceBoundaryMembers = []; + var cellSpaceBoundaryMemberLen = jsonresponse.value.primalSpaceFeatures.primalSpaceFeatures.cellSpaceBoundaryMember.length; + + for (var i = 0; i < cellSpaceBoundaryMemberLen; i++) { + + var csbm = jsonresponse.value.primalSpaceFeatures.primalSpaceFeatures.cellSpaceBoundaryMember[i]; - /* - if (heading !== undefined && heading !== 0) - { zRotMatrix.rotationAxisAngDeg(heading, 0.0, 0.0, -1.0); } + var description = ""; + if (csbm.cellSpaceBoundary.description != null) { + description = csbm.cellSpaceBoundary.description.value; + } - if (pitch !== undefined && pitch !== 0) - { xRotMatrix.rotationAxisAngDeg(pitch, -1.0, 0.0, 0.0); } + var id = ""; + if (csbm.cellSpaceBoundary.id != null) { + id = csbm.cellSpaceBoundary.id; + } - if (roll !== undefined && roll !== 0) - { yRotMatrix.rotationAxisAngDeg(roll, 0.0, -1.0, 0.0); } - */ + /** Extracting the href of the cell space member */ + var href = ""; + if (csbm.cellSpaceBoundary.duality != null) { + href = csbm.cellSpaceBoundary.duality.href; + } - if (resultGeoLocMatrix === undefined) - { resultGeoLocMatrix = new Matrix4(); } // created as identity matrix. - - if (resultTransformMatrix === undefined) - { resultTransformMatrix = new Matrix4(); } // created as identity matrix. + /** Creating an instance of the cell space member */ + var csbmObject = new CellSpaceMember(description, href, id, []); - // 1rst, calculate the transformation matrix for the location. - resultGeoLocMatrix = ManagerUtils.calculateGeoLocationMatrixAtWorldPosition(worldPosition, resultGeoLocMatrix, magoManager); - - resultTransformMatrix.copyFromMatrix4(resultGeoLocMatrix); - var zRotatedTMatrix; - var zxRotatedTMatrix; - var zxyRotatedTMatrix; + /** Number of surface members */ + if (csbm.cellSpaceBoundary.cellSpaceBoundaryGeometry.geometry3D != null) { + csbmObject.surfaceMember = this.getCsbmSurfaceMemberFromGeometry3D(csbm); + } - zRotatedTMatrix = zRotMatrix.getMultipliedByMatrix(resultTransformMatrix, zRotatedTMatrix); - zxRotatedTMatrix = xRotMatrix.getMultipliedByMatrix(zRotatedTMatrix, zxRotatedTMatrix); - zxyRotatedTMatrix = yRotMatrix.getMultipliedByMatrix(zxRotatedTMatrix, zxyRotatedTMatrix); - - resultTransformMatrix = zxyRotatedTMatrix; - return resultTransformMatrix; -}; + cellSpaceBoundaryMembers.push(csbmObject); + } -ManagerUtils.calculateGeoLocationData = function(longitude, latitude, altitude, heading, pitch, roll, resultGeoLocationData, magoManager) -{ - // This function calculates all data and matrices for the location(longitude, latitude, altitude) and rotation(heading, pitch, roll). - if (resultGeoLocationData === undefined) - { resultGeoLocationData = new GeoLocationData(); } + return cellSpaceBoundaryMembers; + }; - // 0) Position.******************************************************************************************** - if (resultGeoLocationData.geographicCoord === undefined) - { resultGeoLocationData.geographicCoord = new GeographicCoord(); } - if (longitude !== undefined) - { resultGeoLocationData.geographicCoord.longitude = longitude; } - else - { longitude = resultGeoLocationData.geographicCoord.longitude; } - if (latitude !== undefined) - { resultGeoLocationData.geographicCoord.latitude = latitude; } - else - { latitude = resultGeoLocationData.geographicCoord.latitude; } + /** + * Extract surfaceMember of cellSpaceMember from the JSON object when the surface of the given GML file is configured with geometry3D. + * @param {Object} csm CellSpaceMember, cellSpaceMember part of jsonresponse. + * @returns {array} array of {@link SurfaceMember} + */ + JsonParsor_1_0_3.prototype.getCsmSurfaceMemberFromGeometry3D = function(csm) { + /** get surface MemberLen */ + var surfaceMemberLen = csm.cellSpace.cellSpaceGeometry.geometry3D.abstractSolid.value.exterior.shell.surfaceMember.length; - if (altitude !== undefined) - { resultGeoLocationData.geographicCoord.altitude = altitude; } - else - { altitude = resultGeoLocationData.geographicCoord.altitude; } + var surfaceMembers = []; - if (heading !== undefined) - { resultGeoLocationData.heading = heading; } + /** Loop through the surface members and creating instances */ + for (var j = 0; j < surfaceMemberLen; j++) { - if (pitch !== undefined) - { resultGeoLocationData.pitch = pitch; } + /** Surface member */ + var sm = csm.cellSpace.cellSpaceGeometry.geometry3D.abstractSolid.value.exterior.shell.surfaceMember[j]; - if (roll !== undefined) - { resultGeoLocationData.roll = roll; } + /** Creating an instance of the surface member */ + var smObject = new SurfaceMember([]); - if (resultGeoLocationData.geographicCoord.longitude === undefined || resultGeoLocationData.geographicCoord.latitude === undefined) - { return; } - - if (magoManager.configInformation === undefined) - { return; } + /** Number of coordinates of the surface member */ + var coordLen = sm.abstractSurface.value.exterior.abstractRing.value.posOrPointPropertyOrPointRep.length; - resultGeoLocationData.position = this.geographicCoordToWorldPoint(longitude, latitude, altitude, resultGeoLocationData.position, magoManager); - - // High and Low values of the position.******************************************************************** - if (resultGeoLocationData.positionHIGH === undefined) - { resultGeoLocationData.positionHIGH = new Float32Array([0.0, 0.0, 0.0]); } - if (resultGeoLocationData.positionLOW === undefined) - { resultGeoLocationData.positionLOW = new Float32Array([0.0, 0.0, 0.0]); } - this.calculateSplited3fv([resultGeoLocationData.position.x, resultGeoLocationData.position.y, resultGeoLocationData.position.z], resultGeoLocationData.positionHIGH, resultGeoLocationData.positionLOW); + var value = sm.abstractSurface.value.exterior.abstractRing.value.posOrPointPropertyOrPointRep; - // Determine the elevation of the position.*********************************************************** - //var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position); - //var height = cartographic.height; - // End Determine the elevation of the position.------------------------------------------------------- - if (resultGeoLocationData.tMatrix === undefined) - { resultGeoLocationData.tMatrix = new Matrix4(); } - else - { resultGeoLocationData.tMatrix.Identity(); } + /** Loop through the coordinates of a surfaceMember */ + for (var k = 0; k < coordLen; k++) { + smObject = this.abstractCoordinate(value[k].value.value, smObject); + } - if (resultGeoLocationData.geoLocMatrix === undefined) - { resultGeoLocationData.geoLocMatrix = new Matrix4(); } - else - { resultGeoLocationData.geoLocMatrix.Identity(); } + /** Adding the surface member to the corresponding cell space member */ + surfaceMembers.push(smObject); + } + return surfaceMembers; + } - if (resultGeoLocationData.geoLocMatrixInv === undefined) - { resultGeoLocationData.geoLocMatrixInv = new Matrix4(); } - else - { resultGeoLocationData.geoLocMatrixInv.Identity(); } - //--------------------------------------------------------- - if (resultGeoLocationData.tMatrixInv === undefined) - { resultGeoLocationData.tMatrixInv = new Matrix4(); } - else - { resultGeoLocationData.tMatrixInv.Identity(); } + /** + * Extract surfaceMember of cellSpaceMember from the JSON object when the surface of the given GML file is configured with geometry2D. + * @param {Object} csm CellSpaceMember, cellSpaceMember part of jsonresponse. + * @returns {array} array of {@link SurfaceMember} + */ + JsonParsor_1_0_3.prototype.getCsmSurfaceMemberFromGeometry2D = function(csm) { - if (resultGeoLocationData.rotMatrix === undefined) - { resultGeoLocationData.rotMatrix = new Matrix4(); } - else - { resultGeoLocationData.rotMatrix.Identity(); } + var surfaceMembers = []; - if (resultGeoLocationData.rotMatrixInv === undefined) - { resultGeoLocationData.rotMatrixInv = new Matrix4(); } - else - { resultGeoLocationData.rotMatrixInv.Identity(); } + /** abstractRing */ + var ar = csm.cellSpace.cellSpaceGeometry.geometry2D.abstractSurface.value.exterior.abstractRing; - // 1rst, calculate the transformation matrix for the location. - resultGeoLocationData.tMatrix = ManagerUtils.calculateTransformMatrixAtWorldPosition(resultGeoLocationData.position, resultGeoLocationData.heading, resultGeoLocationData.pitch, resultGeoLocationData.roll, - resultGeoLocationData.geoLocMatrix, resultGeoLocationData.tMatrix, magoManager); - resultGeoLocationData.rotMatrix.copyFromMatrix4(resultGeoLocationData.tMatrix); - resultGeoLocationData.rotMatrix._floatArrays[12] = 0; - resultGeoLocationData.rotMatrix._floatArrays[13] = 0; - resultGeoLocationData.rotMatrix._floatArrays[14] = 0; - - // now calculate the inverse matrices. - if (magoManager.configInformation.geo_view_library === Constant.WORLDWIND) - { - // * if this in webWorldWind: - var tMatrixInv = WorldWind.Matrix.fromIdentity(); - tMatrixInv.invertMatrix(resultGeoLocationData.tMatrix._floatArrays); - resultGeoLocationData.tMatrixInv.setByFloat32Array(tMatrixInv); - - var rotMatrixInv = WorldWind.Matrix.fromIdentity(); - rotMatrixInv.invertMatrix(resultGeoLocationData.rotMatrix._floatArrays); - resultGeoLocationData.rotMatrixInv.setByFloat32Array(rotMatrixInv); - - var geoLocMatrixInv = WorldWind.Matrix.fromIdentity(); - geoLocMatrixInv.invertMatrix(resultGeoLocationData.geoLocMatrix._floatArrays); - resultGeoLocationData.geoLocMatrixInv.setByFloat32Array(geoLocMatrixInv); - } - else if (magoManager.configInformation.geo_view_library === Constant.CESIUM) - { - // *if this in Cesium: - Cesium.Matrix4.inverseTransformation(resultGeoLocationData.tMatrix._floatArrays, resultGeoLocationData.tMatrixInv._floatArrays); - Cesium.Matrix4.inverseTransformation(resultGeoLocationData.rotMatrix._floatArrays, resultGeoLocationData.rotMatrixInv._floatArrays); - Cesium.Matrix4.inverseTransformation(resultGeoLocationData.geoLocMatrix._floatArrays, resultGeoLocationData.geoLocMatrixInv._floatArrays); - } + /** Creating an instance of abstractRing */ + var arObject = new SurfaceMember([]); - // finally assing the pivotPoint.*** - if (resultGeoLocationData.pivotPoint === undefined) - { resultGeoLocationData.pivotPoint = new Point3D(); } + /** Number of coordinates of the surface member */ + var coordLen = ar.value.posOrPointPropertyOrPointRep.length; - resultGeoLocationData.pivotPoint.set(resultGeoLocationData.position.x, resultGeoLocationData.position.y, resultGeoLocationData.position.z); - resultGeoLocationData.doEffectivePivotPointTranslation(); - - return resultGeoLocationData; -}; + /** Loop through the coordinates of a surfaceMember */ + for (var i = 0; i < coordLen; i++) { + arObject = this.abstractCoordinate(ar.value.posOrPointPropertyOrPointRep[i].value.value, arObject); + } -ManagerUtils.calculateGeoLocationDataByAbsolutePoint = function(absoluteX, absoluteY, absoluteZ, resultGeoLocationData, magoManager) -{ + surfaceMembers.push(arObject); - if (resultGeoLocationData === undefined) - { resultGeoLocationData = new GeoLocationData(); } + return surfaceMembers; + } - // 0) Position.******************************************************************************************** - if (resultGeoLocationData.geographicCoord === undefined) - { resultGeoLocationData.geographicCoord = new GeographicCoord(); } - - if (magoManager.configInformation === undefined) - { return; } - - if (resultGeoLocationData.position === undefined) - { resultGeoLocationData.position = new Point3D(); } - - resultGeoLocationData.position.x = absoluteX; - resultGeoLocationData.position.y = absoluteY; - resultGeoLocationData.position.z = absoluteZ; - - if (magoManager.configInformation.geo_view_library === Constant.WORLDWIND) - { - var globe = magoManager.wwd.globe; - var resultCartographic = new WorldWind.Vec3(0, 0, 0); - resultCartographic = globe.computePositionFromPoint(absoluteX, absoluteY, absoluteZ, resultCartographic); - resultGeoLocationData.geographicCoord.longitude = resultCartographic.longitude; - resultGeoLocationData.geographicCoord.latitude = resultCartographic.latitude; - resultGeoLocationData.geographicCoord.altitude = resultCartographic.altitude; - } - else if (magoManager.configInformation.geo_view_library === Constant.CESIUM) - { - // *if this in Cesium: - //resultGeoLocationData.position = Cesium.Cartesian3.fromDegrees(resultGeoLocationData.geographicCoord.longitude, resultGeoLocationData.geographicCoord.latitude, resultGeoLocationData.geographicCoord.altitude); - // must find cartographic data.*** - var cartographic = new Cesium.Cartographic(); - var cartesian = new Cesium.Cartesian3(); - cartesian.x = absoluteX; - cartesian.y = absoluteY; - cartesian.z = absoluteZ; - cartographic = Cesium.Cartographic.fromCartesian(cartesian, magoManager.scene._globe._ellipsoid, cartographic); - resultGeoLocationData.geographicCoord.longitude = cartographic.longitude * 180.0/Math.PI; - resultGeoLocationData.geographicCoord.latitude = cartographic.latitude * 180.0/Math.PI; - resultGeoLocationData.geographicCoord.altitude = cartographic.height; - } - // High and Low values of the position.******************************************************************** - if (resultGeoLocationData.positionHIGH === undefined) - { resultGeoLocationData.positionHIGH = new Float32Array([0.0, 0.0, 0.0]); } - if (resultGeoLocationData.positionLOW === undefined) - { resultGeoLocationData.positionLOW = new Float32Array([0.0, 0.0, 0.0]); } - this.calculateSplited3fv([resultGeoLocationData.position.x, resultGeoLocationData.position.y, resultGeoLocationData.position.z], resultGeoLocationData.positionHIGH, resultGeoLocationData.positionLOW); - // Determine the elevation of the position.*********************************************************** - //var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position); - //var height = cartographic.height; - // End Determine the elevation of the position.------------------------------------------------------- - if (resultGeoLocationData.tMatrix === undefined) - { resultGeoLocationData.tMatrix = new Matrix4(); } - else - { resultGeoLocationData.tMatrix.Identity(); } + /** + * Extract surfaceMember of cellSpaceBoundaryMember from the JSON object when the surface of the given GML file is configured with geometry3D. + * @param {Object} csm cellSpaceBoundaryMember, cellSpaceBoundaryMember part of jsonresponse. + * @returns {array} array of {@link SurfaceMember} + */ + JsonParsor_1_0_3.prototype.getCsbmSurfaceMemberFromGeometry3D = function(csbm) { - if (resultGeoLocationData.geoLocMatrix === undefined) - { resultGeoLocationData.geoLocMatrix = new Matrix4(); } - else - { resultGeoLocationData.geoLocMatrix.Identity(); } + var smObject = new SurfaceMember([]); - if (resultGeoLocationData.geoLocMatrixInv === undefined) - { resultGeoLocationData.geoLocMatrixInv = new Matrix4(); } - else - { resultGeoLocationData.geoLocMatrixInv.Identity(); } + var surfaceMembers = []; - //--------------------------------------------------------- + if (csbm.cellSpaceBoundary.cellSpaceBoundaryGeometry.geometry3D.abstractSurface.value.exterior != null) { - if (resultGeoLocationData.tMatrixInv === undefined) - { resultGeoLocationData.tMatrixInv = new Matrix4(); } - else - { resultGeoLocationData.tMatrixInv.Identity(); } + var coordLen = csbm.cellSpaceBoundary.cellSpaceBoundaryGeometry.geometry3D.abstractSurface.value.exterior.abstractRing.value.posOrPointPropertyOrPointRep.length; + for (var k = 0; k < coordLen; k++) { + smObject = this.abstractCoordinate(csbm.cellSpaceBoundary.cellSpaceBoundaryGeometry.geometry3D.abstractSurface.value.exterior.abstractRing.value.posOrPointPropertyOrPointRep[k].value.value, smObject); + } + } - if (resultGeoLocationData.rotMatrix === undefined) - { resultGeoLocationData.rotMatrix = new Matrix4(); } - else - { resultGeoLocationData.rotMatrix.Identity(); } + surfaceMembers.push(smObject); - if (resultGeoLocationData.rotMatrixInv === undefined) - { resultGeoLocationData.rotMatrixInv = new Matrix4(); } - else - { resultGeoLocationData.rotMatrixInv.Identity(); } + return surfaceMembers; + } - var xRotMatrix = new Matrix4(); // created as identity matrix.*** - var yRotMatrix = new Matrix4(); // created as identity matrix.*** - var zRotMatrix = new Matrix4(); // created as identity matrix.*** - if (resultGeoLocationData.heading !== undefined && resultGeoLocationData.heading !== 0) - { - zRotMatrix.rotationAxisAngDeg(resultGeoLocationData.heading, 0.0, 0.0, -1.0); - } - if (resultGeoLocationData.pitch !== undefined && resultGeoLocationData.pitch !== 0) - { - xRotMatrix.rotationAxisAngDeg(resultGeoLocationData.pitch, -1.0, 0.0, 0.0); - } + /** + * Abstract coordinates from value and save it in object.coordinates + * @param {Array} value array of coordinates. + * @param {SurfaceMember} object The coordinates obtained from value are stored in object.coordinates. + * @returns {array} array of {@link SurfaceMember} + */ + JsonParsor_1_0_3.prototype.abstractCoordinate = function(value, object) { - if (resultGeoLocationData.roll !== undefined && resultGeoLocationData.roll !== 0) - { - yRotMatrix.rotationAxisAngDeg(resultGeoLocationData.roll, 0.0, -1.0, 0.0); - } - - if (magoManager.configInformation.geo_view_library === Constant.WORLDWIND) - { - // * if this in webWorldWind: - var xAxis = new WorldWind.Vec3(0, 0, 0), - yAxis = new WorldWind.Vec3(0, 0, 0), - zAxis = new WorldWind.Vec3(0, 0, 0); - var rotMatrix = WorldWind.Matrix.fromIdentity(); - var tMatrix = WorldWind.Matrix.fromIdentity(); - - WorldWind.WWMath.localCoordinateAxesAtPoint([resultGeoLocationData.position.x, resultGeoLocationData.position.y, resultGeoLocationData.position.z], magoManager.wwd.globe, xAxis, yAxis, zAxis); + /** Extracting X */ + var X = value[0]; + object.coordinates.push(X); - rotMatrix.set( - xAxis[0], yAxis[0], zAxis[0], 0, - xAxis[1], yAxis[1], zAxis[1], 0, - xAxis[2], yAxis[2], zAxis[2], 0, - 0, 0, 0, 1); - - tMatrix.set( - xAxis[0], yAxis[0], zAxis[0], resultGeoLocationData.position.x, - xAxis[1], yAxis[1], zAxis[1], resultGeoLocationData.position.y, - xAxis[2], yAxis[2], zAxis[2], resultGeoLocationData.position.z, - 0, 0, 0, 1); - - var columnMajorArray = WorldWind.Matrix.fromIdentity(); - columnMajorArray = rotMatrix.columnMajorComponents(columnMajorArray); // no used.*** - - var matrixInv = WorldWind.Matrix.fromIdentity(); - matrixInv.invertMatrix(rotMatrix); - var columnMajorArrayAux_inv = WorldWind.Matrix.fromIdentity(); - var columnMajorArray_inv = matrixInv.columnMajorComponents(columnMajorArrayAux_inv); - - var tMatrixColMajorArray = WorldWind.Matrix.fromIdentity(); - tMatrixColMajorArray = tMatrix.columnMajorComponents(tMatrixColMajorArray); - resultGeoLocationData.tMatrix.setByFloat32Array(tMatrixColMajorArray); - - resultGeoLocationData.geoLocMatrix.copyFromMatrix4(resultGeoLocationData.tMatrix); // "geoLocMatrix" is the pure transformation matrix, without heading or pitch or roll.*** - var zRotatedTMatrix = zRotMatrix.getMultipliedByMatrix(resultGeoLocationData.tMatrix, zRotatedTMatrix); - var zxRotatedTMatrix = xRotMatrix.getMultipliedByMatrix(zRotatedTMatrix, zxRotatedTMatrix); - var zxyRotatedTMatrix = yRotMatrix.getMultipliedByMatrix(zxRotatedTMatrix, zxyRotatedTMatrix); - resultGeoLocationData.tMatrix = zxyRotatedTMatrix; + /** Test if X is maximum or minimum */ + if (X > this.max_X) { + this.max_X = X; + } else if (X < this.min_X) { + this.min_X = X; + } - resultGeoLocationData.rotMatrix.copyFromMatrix4(resultGeoLocationData.tMatrix); - resultGeoLocationData.rotMatrix._floatArrays[12] = 0; - resultGeoLocationData.rotMatrix._floatArrays[13] = 0; - resultGeoLocationData.rotMatrix._floatArrays[14] = 0; - - // now calculate the inverses of the matrices.*** - var tMatrixInv = WorldWind.Matrix.fromIdentity(); - tMatrixInv.invertMatrix(resultGeoLocationData.tMatrix._floatArrays); - resultGeoLocationData.tMatrixInv.setByFloat32Array(tMatrixInv); - - var rotMatrixInv = WorldWind.Matrix.fromIdentity(); - rotMatrixInv.invertMatrix(resultGeoLocationData.rotMatrix._floatArrays); - resultGeoLocationData.rotMatrixInv.setByFloat32Array(rotMatrixInv); - - var geoLocMatrixInv = WorldWind.Matrix.fromIdentity(); - geoLocMatrixInv.invertMatrix(resultGeoLocationData.geoLocMatrix._floatArrays); - resultGeoLocationData.geoLocMatrixInv.setByFloat32Array(geoLocMatrixInv); - } - else if (magoManager.configInformation.geo_view_library === Constant.CESIUM) - { - // *if this in Cesium: - Cesium.Transforms.eastNorthUpToFixedFrame(resultGeoLocationData.position, undefined, resultGeoLocationData.tMatrix._floatArrays); - resultGeoLocationData.geoLocMatrix.copyFromMatrix4(resultGeoLocationData.tMatrix);// "geoLocMatrix" is the pure transformation matrix, without heading or pitch or roll.*** + /** Extracting Y */ + var Y = value[1]; + object.coordinates.push(Y); - var zRotatedTMatrix = zRotMatrix.getMultipliedByMatrix(resultGeoLocationData.tMatrix, zRotatedTMatrix); - var zxRotatedTMatrix = xRotMatrix.getMultipliedByMatrix(zRotatedTMatrix, zxRotatedTMatrix); - var zxyRotatedTMatrix = yRotMatrix.getMultipliedByMatrix(zxRotatedTMatrix, zxyRotatedTMatrix); - resultGeoLocationData.tMatrix = zxyRotatedTMatrix; - - // test.*** - //var yRotatedTMatrix = yRotMatrix.getMultipliedByMatrix(resultGeoLocationData.tMatrix, yRotatedTMatrix); - //var yxRotatedTMatrix = xRotMatrix.getMultipliedByMatrix(yRotatedTMatrix, yxRotatedTMatrix); - //var yxzRotatedTMatrix = zRotMatrix.getMultipliedByMatrix(yxRotatedTMatrix, yxzRotatedTMatrix); - //resultGeoLocationData.tMatrix = yxzRotatedTMatrix; - // end test.--- + if (Y > this.max_Y) { + this.max_Y = Y; + } else if (Y < this.min_Y) { + this.min_Y = Y; + } - resultGeoLocationData.rotMatrix.copyFromMatrix4(resultGeoLocationData.tMatrix); - resultGeoLocationData.rotMatrix._floatArrays[12] = 0; - resultGeoLocationData.rotMatrix._floatArrays[13] = 0; - resultGeoLocationData.rotMatrix._floatArrays[14] = 0; + /** Extracting Z */ + var Z = value[2]; + object.coordinates.push(Z); - // now, calculates the inverses.*** - Cesium.Matrix4.inverse(resultGeoLocationData.tMatrix._floatArrays, resultGeoLocationData.tMatrixInv._floatArrays); - Cesium.Matrix4.inverse(resultGeoLocationData.rotMatrix._floatArrays, resultGeoLocationData.rotMatrixInv._floatArrays); - Cesium.Matrix4.inverse(resultGeoLocationData.geoLocMatrix._floatArrays, resultGeoLocationData.geoLocMatrixInv._floatArrays); - } + if (Z > this.max_Z) { + this.max_Z = Z; + } else if (Z < this.min_Z) { + this.min_Z = Z; + } - // finally assing the pivotPoint.*** - if (resultGeoLocationData.pivotPoint === undefined) - { resultGeoLocationData.pivotPoint = new Point3D(); } + return object; + } - resultGeoLocationData.pivotPoint.set(resultGeoLocationData.position.x, resultGeoLocationData.position.y, resultGeoLocationData.position.z); + JsonParsor_1_0_3.prototype.getMaxX = function(){ + return this.max_X; + } - return resultGeoLocationData; -}; + JsonParsor_1_0_3.prototype.getMaxY = function(){ + return this.max_Y; + } -ManagerUtils.calculateSplitedValues = function(value, resultSplitValue) -{ - if (resultSplitValue === undefined) - { resultSplitValue = new SplitValue(); } + JsonParsor_1_0_3.prototype.getMaxZ = function(){ + return this.max_Z; + } - var doubleHigh; - if (value >= 0.0) - { - doubleHigh = Math.floor(value / 65536.0) * 65536.0; - resultSplitValue.high = doubleHigh; - resultSplitValue.low = value - doubleHigh; - } - else - { - doubleHigh = Math.floor(-value / 65536.0) * 65536.0; - resultSplitValue.high = -doubleHigh; - resultSplitValue.low = value + doubleHigh; - } + JsonParsor_1_0_3.prototype.getMinX = function(){ + return this.min_X; + } - return resultSplitValue; -}; + JsonParsor_1_0_3.prototype.getMinY = function(){ + return this.min_Y; + } -ManagerUtils.calculateSplited3fv = function(point3fv, resultSplitPoint3fvHigh, resultSplitPoint3fvLow) -{ - if (point3fv === undefined) - { return undefined; } + JsonParsor_1_0_3.prototype.getMinZ = function(){ + return this.min_Z; + } - if (resultSplitPoint3fvHigh === undefined) // delete unnecesary. - { resultSplitPoint3fvHigh = new Float32Array(3); }// delete unnecesary. - if (resultSplitPoint3fvLow === undefined)// delete unnecesary. - { resultSplitPoint3fvLow = new Float32Array(3); }// delete unnecesary. - var posSplitX = new SplitValue(); - posSplitX = this.calculateSplitedValues(point3fv[0], posSplitX); - var posSplitY = new SplitValue(); - posSplitY = this.calculateSplitedValues(point3fv[1], posSplitY); - var posSplitZ = new SplitValue(); - posSplitZ = this.calculateSplitedValues(point3fv[2], posSplitZ); - resultSplitPoint3fvHigh[0] = posSplitX.high; - resultSplitPoint3fvHigh[1] = posSplitY.high; - resultSplitPoint3fvHigh[2] = posSplitZ.high; - resultSplitPoint3fvLow[0] = posSplitX.low; - resultSplitPoint3fvLow[1] = posSplitY.low; - resultSplitPoint3fvLow[2] = posSplitZ.low; -}; + 'use strict'; -ManagerUtils.calculateAproxDist2D = function(pointA, pointB, sqrtTable) -{ - // test function. - var difX = Math.abs(pointA.x - pointB.x); - var difY = Math.abs(pointA.y - pointB.y); - - // find the big value. - var maxValue, value1; - - if (difX > difY) - { - maxValue = difX; - value1 = difY/maxValue; - } - else - { - maxValue = difY; - value1 = difX/maxValue; - } - - var value1Idx = Math.floor(value1*100); - var aproxDist = maxValue * sqrtTable[value1Idx]; - return aproxDist; -}; + /** + * Objects storing CellSpaceMember in IndoorGML + * @exports CellSpaceMember + * @constructor + * @param {string} description description of CellSpaceMember + * @param {string} href href of CellSpaceMember + * @param {string} id id of CellSpaceMember + * @param {Array} surfaceMember Array of {@link SurfaceMember} + */ + function CellSpaceMember(description, href, id, surfaceMember) { -var sqrtTable = new Float32Array(11); -// make 10 values. -var increValue = 0.1; -for (var i=0; i<11; i++) -{ - sqrtTable[i] = Math.sqrt(1+(increValue*i)*(increValue*i)); -} - -ManagerUtils.calculateAproxDist3D = function(pointA, pointB) -{ - var difX = Math.abs(pointA.x - pointB.x); - var difY = Math.abs(pointA.y - pointB.y); - var difZ = Math.abs(pointA.z - pointB.z); - - // find the big value. - var maxValue, value1, value2; - var value1Idx, value2Idx; - var aproxDist; - - if (difX > difY) - { - if (difX > difZ) - { - maxValue = difX; - value1 = difY/maxValue; - value1Idx = Math.floor(value1*100); - var middleDist = maxValue * sqrtTable[value1Idx]; - value2 = difZ/middleDist; - value2Idx = Math.floor(value2*100); - return (middleDist * sqrtTable[value2Idx]); - } - else - { - maxValue = difZ; - value1 = difX/maxValue; - value1Idx = Math.floor(value1*100); - var middleDist = maxValue * sqrtTable[value1Idx]; - value2 = difY/middleDist; - value2Idx = Math.floor(value2*100); - return (middleDist * sqrtTable[value2Idx]); - } - } - else - { - if (difY > difZ) - { - maxValue = difY; - value1 = difX/maxValue; - value1Idx = Math.floor(value1*100); - var middleDist = maxValue * sqrtTable[value1Idx]; - value2 = difZ/middleDist; - value2Idx = Math.floor(value2*100); - return (middleDist * sqrtTable[value2Idx]); - } - else - { - maxValue = difZ; - value1 = difX/maxValue; - value1Idx = Math.floor(value1*100); - var middleDist = maxValue * sqrtTable[value1Idx]; - value2 = difY/middleDist; - value2Idx = Math.floor(value2*100); - return (middleDist * sqrtTable[value2Idx]); - } - } - -}; -/* -ManagerUtils.getBuildingCurrentPosition = function(renderingMode, neoBuilding) -{ - // renderingMode = 0 => assembled.*** - // renderingMode = 1 => dispersed.*** + /** Description contains information about section and floor ... etc */ + this.description = description; - if (neoBuilding === undefined) { return undefined; } + /** Duality.
This will work as a key of cell that distinguse one cell to this other. */ + this.href = href; - var realBuildingPos; + this.id = id; - // 0 = assembled mode. 1 = dispersed mode.*** - if (renderingMode === 1) - { - if (neoBuilding.geoLocationDataAux === undefined) - { - var realTimeLocBlocksList = MagoConfig.getData().alldata; - var newLocation = realTimeLocBlocksList[neoBuilding.buildingId]; - // must calculate the realBuildingPosition (bbox_center_position).*** + /** Array of surface members */ + this.surfaceMember = surfaceMember; - if (newLocation) - { - neoBuilding.geoLocationDataAux = ManagerUtils.calculateGeoLocationData(newLocation.LONGITUDE, newLocation.LATITUDE, newLocation.ELEVATION, neoBuilding.geoLocationDataAux); + /** + * This means what role it plays.
+ * This value will be parsed from description.
+ * If description doesn't mention usage, this remains empty. + */ + this.usage = ""; + if(description.indexOf("Usage=") != -1){ + var usageStart = description.indexOf("Usage=") + 6; + this.usage = description.substring(usageStart, description.indexOf(":", usageStart)); + } - //this.pointSC = neoBuilding.bbox.getCenterPoint(this.pointSC); - neoBuilding.point3dScratch.set(0.0, 0.0, 50.0); - realBuildingPos = neoBuilding.geoLocationDataAux.tMatrix.transformPoint3D(neoBuilding.point3dScratch, realBuildingPos ); - } - else - { - // use the normal data.*** - neoBuilding.point3dScratch = neoBuilding.bbox.getCenterPoint(neoBuilding.point3dScratch); - realBuildingPos = neoBuilding.transfMat.transformPoint3D(neoBuilding.point3dScratch, realBuildingPos ); - } - } - else - { - //this.pointSC = neoBuilding.bbox.getCenterPoint(this.pointSC); - neoBuilding.point3dScratch.set(0.0, 0.0, 50.0); - realBuildingPos = neoBuilding.geoLocationDataAux.tMatrix.transformPoint3D(neoBuilding.point3dScratch, realBuildingPos ); - } - } - else - { - neoBuilding.point3dScratch = neoBuilding.bbox.getCenterPoint(neoBuilding.point3dScratch); - realBuildingPos = neoBuilding.transfMat.transformPoint3D(neoBuilding.point3dScratch, realBuildingPos ); - } + /** + * This is the section value to which the current cell belongs.
+ * This value will be parsed from description.
+ * If description doesn't mention section, this remains empty.
+ * You can change this value to information about the cells that your IndoorGML file contains. + */ + this.section = ""; + if(description.indexOf("Section=") != -1){ + var sectionStart = description.indexOf("Section=") + 8; + this.section = description.substring(sectionStart, description.indexOf(":", sectionStart)); + } - return realBuildingPos; -}; -*/ -'use strict'; + /** + * This is the floor value to which the current cell belongs.
+ * This value will be parsed from description.
+ * If description doesn't mention floor, this remains empty.
+ * You can change this value to information about the cells that your IndoorGML file contains. + */ + this.floor = ""; + if(description.indexOf("Floor=") != -1){ + var floorStart = description.indexOf("Floor=") + 6; + this.floor = description.substring(floorStart); + } + } -/** - * 사용하지 않음 - */ -!(function() -{ - var URL = window.URL || window.webkitURL; - if (!URL) - { - throw new Error('This browser does not support Blob URLs'); - } - if (!window.Worker) - { - throw new Error('This browser does not support Web Workers'); - } + 'use strict'; - function Multithread(threads) - { - this.threads = Math.max(2, threads | 0); - this._queue = []; - this._queueSize = 0; - this._activeThreads = 0; - this._debug = { - start : 0, - end : 0, - time : 0 - }; - } + /** + * State Member Class. This can be thought of as simply a node. + * @exports StateMember + * @constructor + */ + function StateMember(coordinates) { - Multithread.prototype._worker = { - JSON: function() - { - var /**/name/**/ = (/**/func/**/); - self.addEventListener('message', function(e) - { - var data = e.data; - var view = new DataView(data); - var len = data.byteLength; - var str = Array(len); - for (var i=0;i + * This means two nodes constituting an edge. + */ + this.connects = connects; - }; + /** + * information about section and floor...etc + */ + this.description = description; - Multithread.prototype.processInt32 = function(fn, callback) - { + /** Array of state members, each state member has X,Y,Z coordinates */ + this.stateMembers = coordinates; - var resource = this._prepare(fn, 'Int32'); - var self = this; + if(description != null){ - return function() - { - self._execute(resource, [].slice.call(arguments), 'Int32', callback); - }; + /** + * This means what role it plays.
+ * This value will be parsed from description.
+ * If description doesn't mention usage, this remains empty. + */ + this.usage = ""; + if(description.indexOf("Usage=") != -1){ + var usageStart = description.indexOf("Usage=") + 6; + this.usage = description.substring(usageStart, description.indexOf(":", usageStart)); + } - }; - Multithread.prototype.processFloat64 = function(fn, callback) - { + /** + * This is the section value to which the current cell belongs.
+ * This value will be parsed from description.
+ * If description doesn't mention section, this remains empty.
+ * You can change this value to information about the cells that your IndoorGML file contains. + */ + this.section = ""; + if(description.indexOf("Section=") != -1){ + var sectionStart = description.indexOf("Section=") + 8; + this.section = description.substring(sectionStart, description.indexOf(":", sectionStart)); + } - var resource = this._prepare(fn, 'Float64'); - var self = this; - return function() - { - self._execute(resource, [].slice.call(arguments), 'Float64', callback); - }; + /** + * This is the floor value to which the current cell belongs.
+ * This value will be parsed from description.
+ * If description doesn't mention floor, this remains empty.
+ * You can change this value to information about the cells that your IndoorGML file contains. + */ + this.floor = ""; + if(description.indexOf("Floor=") != -1){ + var floorStart = description.indexOf("Floor=") + 6; + this.floor = description.substring(floorStart); + } - }; + } + } - window.Multithread = Multithread; -})(); \ No newline at end of file + + var _mago3d = { + VERSION: '2.0', + }; + _mago3d['ColorAPI'] = ColorAPI; + _mago3d['DrawAPI'] = DrawAPI; + _mago3d['LocationAndRotationAPI'] = LocationAndRotationAPI; + _mago3d['LodAPI'] = LodAPI; + _mago3d['AnimationData'] = AnimationData; + _mago3d['AnimationManager'] = AnimationManager; + _mago3d['Atmosphere'] = Atmosphere; + _mago3d['BoundingBox'] = BoundingBox; + _mago3d['BoundingSphere'] = BoundingSphere; + _mago3d['Box'] = Box; + _mago3d['BuildingSeed'] = BuildingSeed; + _mago3d['BuildingSeedList'] = BuildingSeedList; + _mago3d['Camera'] = Camera; + _mago3d['CCTV'] = CCTV; + _mago3d['CCTVList'] = CCTVList; + _mago3d['Color'] = Color; + _mago3d['FBO'] = FBO; + _mago3d['FileRequestControler'] = FileRequestControler; + _mago3d['FirstPersonView'] = FirstPersonView; + _mago3d['Frustum'] = Frustum; + _mago3d['FrustumVolumeControl'] = FrustumVolumeControl; + _mago3d['GeographicCoord'] = GeographicCoord; + _mago3d['GeographicCoordsList'] = GeographicCoordsList; + _mago3d['GeographicExtent'] = GeographicExtent; + _mago3d['GeoLocationData'] = GeoLocationData; + _mago3d['GeoLocationDataManager'] = GeoLocationDataManager; + _mago3d['Globe'] = Globe; + _mago3d['MagoManager'] = MagoManager; + _mago3d['ManagerFactory'] = ManagerFactory; + _mago3d['Matrix4'] = Matrix4; + _mago3d['Message'] = Message; + _mago3d['MouseAction'] = MouseAction; + _mago3d['ObjectMarker'] = ObjectMarker; + _mago3d['OcclusionCullingOctree'] = OcclusionCullingOctree; + _mago3d['OcclusionCullingOctreeCell'] = OcclusionCullingOctreeCell; + _mago3d['Pin'] = Pin; + _mago3d['Plane'] = Plane; + _mago3d['Quaternion'] = Quaternion; + _mago3d['SelectionColor'] = SelectionColor; + _mago3d['SmartTile'] = SmartTile; + _mago3d['SmartTileManager'] = SmartTileManager; + _mago3d['Sphere'] = Sphere; + _mago3d['SplitValue'] = SplitValue; + _mago3d['TerranTile'] = TerranTile; + _mago3d['Texture'] = Texture; + _mago3d['TexturesManager'] = TexturesManager; + _mago3d['TriPolyhedron'] = TriPolyhedron; + _mago3d['TriSurface'] = TriSurface; + _mago3d['VboBuffer'] = VboBuffer; + _mago3d['VBOKeysNation'] = VBOKeysNation; + _mago3d['VBOKeysStore'] = VBOKeysStore; + _mago3d['VBOKeysWorld'] = VBOKeysWorld; + _mago3d['VBOMemoryManager'] = VBOMemoryManager; + _mago3d['VBOVertexIdxCacheKey'] = VBOVertexIdxCacheKey; + _mago3d['VBOVertexIdxCacheKeysContainer'] = VBOVertexIdxCacheKeysContainer; + _mago3d['VisibleObjectsController'] = VisibleObjectsController; + _mago3d['API'] = API; + _mago3d['ChangeHistory'] = ChangeHistory; + _mago3d['CODE'] = CODE; + _mago3d['Constant'] = Constant; + _mago3d['MagoConfig'] = MagoConfig; + _mago3d['Policy'] = Policy; + _mago3d['Accessor'] = Accessor; + _mago3d['Block'] = Block; + _mago3d['BlocksArrayPartition'] = BlocksArrayPartition; + _mago3d['BlocksList'] = BlocksList; + _mago3d['HierarchyManager'] = HierarchyManager; + _mago3d['InspectorBox'] = InspectorBox; + _mago3d['Lego'] = Lego; + _mago3d['LoadQueue'] = LoadQueue; + _mago3d['LodBuildingData'] = LodBuildingData; + _mago3d['MetaData'] = MetaData; + _mago3d['ModelReferencedGroup'] = ModelReferencedGroup; + _mago3d['NeoBuilding'] = NeoBuilding; + _mago3d['NeoBuildingsList'] = NeoBuildingsList; + _mago3d['NeoReference'] = NeoReference; + _mago3d['NeoReferencesMotherAndIndices'] = NeoReferencesMotherAndIndices; + _mago3d['NeoSimpleBuilding'] = NeoSimpleBuilding; + _mago3d['NeoTexture'] = NeoTexture; + _mago3d['Node'] = Node; + _mago3d['Octree'] = Octree; + _mago3d['ParseQueue'] = ParseQueue; + _mago3d['ProcessQueue'] = ProcessQueue; + _mago3d['ProjectTree'] = ProjectTree; + _mago3d['ReaderWriter'] = ReaderWriter; + _mago3d['TinTerrain'] = TinTerrain; + _mago3d['TinTerrainManager'] = TinTerrainManager; + _mago3d['Arc2D'] = Arc2D; + _mago3d['AxisXYZ'] = AxisXYZ; + _mago3d['BoundingRectangle'] = BoundingRectangle; + _mago3d['BoxAux'] = BoxAux; + _mago3d['Circle2D'] = Circle2D; + _mago3d['CuttingPlane'] = CuttingPlane; + _mago3d['Ellipsoid'] = Ellipsoid; + _mago3d['Excavation'] = Excavation; + _mago3d['Face'] = Face; + _mago3d['HalfEdge'] = HalfEdge; + _mago3d['HalfEdgesList'] = HalfEdgesList; + _mago3d['IndexData'] = IndexData; + _mago3d['IndexRange'] = IndexRange; + _mago3d['Intersect'] = Intersect; + _mago3d['Line'] = Line; + _mago3d['Line2D'] = Line2D; + _mago3d['MagoNativeProject'] = MagoNativeProject; + _mago3d['MagoWorld'] = MagoWorld; + _mago3d['Mesh'] = Mesh; + _mago3d['Modeler'] = Modeler; + _mago3d['ParametricMesh'] = ParametricMesh; + _mago3d['PlaneGrid'] = PlaneGrid; + _mago3d['Point2D'] = Point2D; + _mago3d['Point2DList'] = Point2DList; + _mago3d['Point3D'] = Point3D; + _mago3d['Point3DList'] = Point3DList; + _mago3d['Point4D'] = Point4D; + _mago3d['Polygon2D'] = Polygon2D; + _mago3d['PolyLine2D'] = PolyLine2D; + _mago3d['PolyLine3D'] = PolyLine3D; + _mago3d['Profile2D'] = Profile2D; + _mago3d['Profiles2DList'] = Profiles2DList; + _mago3d['Rectangle2D'] = Rectangle2D; + _mago3d['Ring2D'] = Ring2D; + _mago3d['Ring2DList'] = Ring2DList; + _mago3d['RingType'] = RingType; + _mago3d['Segment2D'] = Segment2D; + _mago3d['Segment3D'] = Segment3D; + _mago3d['Star2D'] = Star2D; + _mago3d['StaticModel'] = StaticModel; + _mago3d['Surface'] = Surface; + _mago3d['Triangle'] = Triangle; + _mago3d['TrianglesList'] = TrianglesList; + _mago3d['TrianglesMatrix'] = TrianglesMatrix; + _mago3d['Tunnel'] = Tunnel; + _mago3d['Vertex'] = Vertex; + _mago3d['VertexList'] = VertexList; + _mago3d['VertexMatrix'] = VertexMatrix; + _mago3d['VtxProfile'] = VtxProfile; + _mago3d['VtxProfilesList'] = VtxProfilesList; + _mago3d['VtxRing'] = VtxRing; + _mago3d['VtxRingsList'] = VtxRingsList; + _mago3d['VtxSegment'] = VtxSegment; + _mago3d['Message'] = Message; + _mago3d['MessageSource'] = MessageSource; + _mago3d['Renderer'] = Renderer; + _mago3d['SceneState'] = SceneState; + _mago3d['Selection'] = Selection; + _mago3d['SelectionCandidateFamily'] = SelectionCandidateFamily; + _mago3d['SelectionManager'] = SelectionManager; + _mago3d['AttribLocationState'] = AttribLocationState; + _mago3d['PostFxShader'] = PostFxShader; + _mago3d['PostFxShadersManager'] = PostFxShadersManager; + _mago3d['ShaderSource'] = ShaderSource; + _mago3d['Uniform1fDataPair'] = Uniform1fDataPair; + _mago3d['Uniform1iDataPair'] = Uniform1iDataPair; + _mago3d['UniformMatrix4fvDataPair'] = UniformMatrix4fvDataPair; + _mago3d['UniformVec2fvDataPair'] = UniformVec2fvDataPair; + _mago3d['UniformVec3fvDataPair'] = UniformVec3fvDataPair; + _mago3d['UniformVec4fvDataPair'] = UniformVec4fvDataPair; + _mago3d['Network'] = Network; + _mago3d['NetworkEdge'] = NetworkEdge; + _mago3d['NetworkNode'] = NetworkNode; + _mago3d['NetworkSpace'] = NetworkSpace; + _mago3d['ByteColor'] = ByteColor; + _mago3d['defaultValue'] = defaultValue; + _mago3d['defined'] = defined; + _mago3d['ManagerUtils'] = ManagerUtils; + _mago3d['TTriangle'] = TTriangle; + _mago3d['TTrianglesList'] = TTrianglesList; + _mago3d['TTrianglesMatrix'] = TTrianglesMatrix; + _mago3d['GMLDataContainer'] = GMLDataContainer; + _mago3d['JsonParsor_1_0_1'] = JsonParsor_1_0_1; + _mago3d['JsonParsor_1_0_3'] = JsonParsor_1_0_3; + _mago3d['CellSpaceMember'] = CellSpaceMember; + _mago3d['StateMember'] = StateMember; + _mago3d['SurfaceMember'] = SurfaceMember; + _mago3d['TransitionMember'] = TransitionMember; + return _mago3d; +})(); diff --git a/dist/mago3d.min.js b/dist/mago3d.min.js index ef3b636c..3b143e9b 100644 --- a/dist/mago3d.min.js +++ b/dist/mago3d.min.js @@ -1 +1 @@ -"use strict";var Atmosphere=function(){if(!(this instanceof Atmosphere))throw new Error(Messages.CONSTRUCT_ERROR);this.cloudsManager=new CloudsManager,this.shadowBlendingCube=new ShadowBlendingCube},ShadowBlendingCube=function(){if(!(this instanceof ShadowBlendingCube))throw new Error(Messages.CONSTRUCT_ERROR);this.vertexMatrix=new VertexMatrix,this.tTrianglesMatrix=new TTrianglesMatrix,this.init(this.vertexMatrix,this.tTrianglesMatrix),this.vboVertexCacheKey,this.vboIndexCacheKey,this.indicesCount=0};ShadowBlendingCube.prototype.init=function(e,t){var i=.1,o=.1,r=.1,n=e.newVertexList(),a=n.newVertex();a.setPosition(0,0,-150.5),a.setColorRGBA(i,o,r,.6),(a=n.newVertex()).setPosition(0,0,-150.5),a.setColorRGBA(i,o,r,.6),(a=n.newVertex()).setPosition(0,0,-150.5),a.setColorRGBA(i,o,r,.6),(a=n.newVertex()).setPosition(0,0,-150.5),a.setColorRGBA(i,o,r,.6),(a=(n=e.newVertexList()).newVertex()).setPosition(-150.5,-150.5,-150.5),a.setColorRGBA(i,o,r,.6),(a=n.newVertex()).setPosition(150.5,-150.5,-150.5),a.setColorRGBA(i,o,r,.6),(a=n.newVertex()).setPosition(150.5,150.5,-150.5),a.setColorRGBA(i,o,r,.6),(a=n.newVertex()).setPosition(-150.5,150.5,-150.5),a.setColorRGBA(i,o,r,.6),(a=(n=e.newVertexList()).newVertex()).setPosition(-150.5,-150.5,150.5),a.setColorRGBA(i,o,r,.6),(a=n.newVertex()).setPosition(150.5,-150.5,150.5),a.setColorRGBA(i,o,r,.6),(a=n.newVertex()).setPosition(150.5,150.5,150.5),a.setColorRGBA(i,o,r,.6),(a=n.newVertex()).setPosition(-150.5,150.5,150.5),a.setColorRGBA(i,o,r,.6),(a=(n=e.newVertexList()).newVertex()).setPosition(0,0,150.5),a.setColorRGBA(i,o,r,.6),(a=n.newVertex()).setPosition(0,0,150.5),a.setColorRGBA(i,o,r,.6),(a=n.newVertex()).setPosition(0,0,150.5),a.setColorRGBA(i,o,r,.6),(a=n.newVertex()).setPosition(0,0,150.5),a.setColorRGBA(i,o,r,.6),e.makeTTrianglesLateralSidesLOOP(t)},ShadowBlendingCube.prototype.getVBOVertexColorRGBAFloatArray=function(){return this.vertexMatrix.getVBOVertexColorRGBAFloatArray()},ShadowBlendingCube.prototype.getVBOIndicesShortArray=function(){this.vertexMatrix.setVertexIdxInList();var e=this.tTrianglesMatrix.getVBOIndicesShortArray();return this.indicesCount=e.length,e};var CloudsManager=function(){if(!(this instanceof CloudsManager))throw new Error(Messages.CONSTRUCT_ERROR);this.circularCloudsArray=[]};CloudsManager.prototype.newCircularCloud=function(){var e=new CircularCloud;return this.circularCloudsArray.push(e),e};var CircularCloud=function(){if(!(this instanceof CircularCloud))throw new Error(Messages.CONSTRUCT_ERROR);this.radius=200,this.depth=150,this.numPointsForCicle=8,this.vertexMatrix=new VertexMatrix,this.tTrianglesMatrix=new TTrianglesMatrix,this.shadowVertexMatrix=new VertexMatrix,this.shadowTTrianglesMatrix=new TTrianglesMatrix,this.sunLightDirection=new Point3D,this.sunLightDirection.set(1,1,-5),this.sunLightDirection.unitary(),this.longitude,this.latitude,this.altitude,this.position,this.positionHIGH,this.positionLOW,this.bbox=new BoundingBox,this.cullingPosition,this.cullingRadius,this.vboVertexCacheKey,this.vboIndexCacheKey,this.vboShadowVertexCacheKey,this.vboShadowIndexCacheKey,this.indicesCount=0,this.rendered=!1,this.point3dSC=new Point3D,this.vertexSC=new Vertex};CircularCloud.prototype.getVBOVertexColorFloatArray=function(){var e;return e=this.vertexMatrix.getVBOVertexColorFloatArray(e)},CircularCloud.prototype.getVBOIndicesShortArray=function(){this.vertexMatrix.setVertexIdxInList();var e=this.tTrianglesMatrix.getVBOIndicesShortArray();return this.indicesCount=e.length,e},CircularCloud.prototype.getVBOShadowVertexFloatArray=function(){var e;return e=this.shadowVertexMatrix.getVBOVertexFloatArray(e)},CircularCloud.prototype.getVBOShadowIndicesShortArray=function(){this.shadowVertexMatrix.setVertexIdxInList();var e=this.shadowTTrianglesMatrix.getVBOIndicesShortArray();return this.indicesCount=e.length,e},CircularCloud.prototype.rotateMeshByLocation=function(e){var t=new Matrix4;t.rotationAxisAngDeg(-this.longitude,0,0,1),e.transformPointsByMatrix4(t);var i,o=this.longitude*Math.PI/180,r=new Point3D,n=new Point3D;r.set(Math.cos(o),Math.sin(o),0),n.set(0,0,1),(i=r.crossProduct(n,i)).unitary(),t.rotationAxisAngDeg(90-this.latitude,i.x,i.y,0),e.transformPointsByMatrix4(t)},CircularCloud.prototype.doShadowMeshWithSunDirection=function(){var e=this.shadowVertexMatrix.getVertexList(5);e.translateVertices(this.sunLightDirection.x,this.sunLightDirection.y,this.sunLightDirection.z,3e3),(e=this.shadowVertexMatrix.getVertexList(4)).translateVertices(this.sunLightDirection.x,this.sunLightDirection.y,this.sunLightDirection.z,3e3),(e=this.shadowVertexMatrix.getVertexList(3)).translateVertices(this.sunLightDirection.x,this.sunLightDirection.y,this.sunLightDirection.z,3e3)},CircularCloud.prototype.createCloud=function(e,t,i,o,r,n){this.longitude=e,this.latitude=t,this.altitude=i,this.radius=o,this.depth=r,this.numPointsForCicle=n,this.makeMesh(this.vertexMatrix,this.tTrianglesMatrix,this.shadowVertexMatrix,this.shadowTTrianglesMatrix),this.doShadowMeshWithSunDirection(),this.rotateMeshByLocation(this.vertexMatrix),this.rotateMeshByLocation(this.shadowVertexMatrix);var a=Cesium.Cartesian3.fromDegrees(this.longitude,this.latitude,this.altitude);this.position=a;var s,l=Cesium.EncodedCartesian3.encode(a.x),c=Cesium.EncodedCartesian3.encode(a.y),h=Cesium.EncodedCartesian3.encode(a.z);this.positionHIGH=new Float32Array([l.high,c.high,h.high]),this.positionLOW=new Float32Array([l.low,c.low,h.low]),this.bbox=this.shadowVertexMatrix.getBoundingBox(this.bbox),s=this.bbox.getCenterPoint(s),this.cullingPosition=new Cesium.Cartesian3(s.x+this.position.x,s.y+this.position.y,s.z+this.position.z),this.cullingRadius=this.bbox.getMaxLength()/2},CircularCloud.prototype.makeMesh=function(e,t,i,o){var r,n,a=2*Math.PI/16,s=0,l=this.depth/2,c=0,h=0,d=0,u=e.newVertexList(),f=i.newVertexList();d=.9+.3*Math.random();for(var g=0;g<16;g++)(r=u.newVertex()).setPosition(c,h,l),(n=f.newVertex()).setPosition(c,h,1.2*-l),r.setColorRGB(d,d,d);s=0;var p=.7*this.radius;u=e.newVertexList(),f=i.newVertexList();for(g=0;g<16;g++)d=(2+Math.random())/2,r=u.newVertex(),n=f.newVertex(),c=p*Math.cos(s)*d,h=p*Math.sin(s)*d,n.setPosition(c,h,2*-l),r.setPosition(c,h,.8*l),d=.9+.3*Math.random(),r.setColorRGB(d,d,d),s+=a;s=0,u=e.newVertexList(),f=i.newVertexList();for(g=0;g<16;g++)d=(2+Math.random())/2,r=u.newVertex(),n=f.newVertex(),c=this.radius*Math.cos(s)*d,h=this.radius*Math.sin(s)*d,n.setPosition(c,h,2*-l),r.setPosition(c,h,.4*l),d=.9+.3*Math.random(),r.setColorRGB(d,d,d),s+=a;s=0,u=e.newVertexList(),f=i.newVertexList();for(g=0;g<16;g++)d=(2+Math.random())/2,r=u.newVertex(),n=f.newVertex(),c=this.radius*Math.cos(s)*d,h=this.radius*Math.sin(s)*d,n.setPosition(c,h,2*-l),r.setPosition(c,h,.4*-l),d=.8+.3*Math.random(),r.setColorRGB(d,d,d),s+=a;s=0,p=.7*this.radius,u=e.newVertexList(),f=i.newVertexList();for(g=0;g<16;g++)d=(2+Math.random())/2,r=u.newVertex(),n=f.newVertex(),c=p*Math.cos(s)*d,h=p*Math.sin(s)*d,r.setPosition(c,h,.8*-l),n.setPosition(c,h,1.2*-l),d=.6+.3*Math.random(),r.setColorRGB(d,d,d),s+=a;u=e.newVertexList(),f=i.newVertexList(),d=.6+.3*Math.random();for(g=0;g<16;g++)r=u.newVertex(),n=f.newVertex(),r.setPosition(0,0,-l),n.setPosition(0,0,-l),r.setColorRGB(d,d,d);e.makeTTrianglesLateralSidesLOOP(t),i.makeTTrianglesLateralSidesLOOP(o)};var AuxiliarSegment=function(){if(!(this instanceof AuxiliarSegment))throw new Error(Messages.CONSTRUCT_ERROR);this.point1,this.point2};AuxiliarSegment.prototype.setPoints=function(e,t,i,o,r,n){this.point1[0]=e,this.point1[1]=t,this.point1[2]=i,this.point2[0]=o,this.point2[1]=r,this.point2[2]=n};var BoundingBox=function(){if(!(this instanceof BoundingBox))throw new Error(Messages.CONSTRUCT_ERROR);this.minX=1e6,this.minY=1e6,this.minZ=1e6,this.maxX=-1e6,this.maxY=-1e6,this.maxZ=-1e6};BoundingBox.prototype.init=function(e){e=e||new Point3D,this.minX=e.x,this.minY=e.y,this.minZ=e.z,this.maxX=e.x,this.maxY=e.y,this.maxZ=e.z},BoundingBox.prototype.deleteObjects=function(){this.minX=void 0,this.minY=void 0,this.minZ=void 0,this.maxX=void 0,this.maxY=void 0,this.maxZ=void 0},BoundingBox.prototype.copyFrom=function(e){this.minX=e.minX,this.minY=e.minY,this.minZ=e.minZ,this.maxX=e.maxX,this.maxY=e.maxY,this.maxZ=e.maxZ},BoundingBox.prototype.translateToOrigin=function(){var e=this.getXLength()/2,t=this.getYLength()/2,i=this.getZLength()/2;this.minX=-e,this.minY=-t,this.minZ=-i,this.maxX=e,this.maxY=t,this.maxZ=i},BoundingBox.prototype.expand=function(e){e=e||0,e=Math.abs(e),this.minX-=e,this.minY-=e,this.minZ-=e,this.maxX+=e,this.maxY+=e,this.maxZ+=e},BoundingBox.prototype.addPoint=function(e){void 0!==e&&(e.xthis.maxX&&(this.maxX=e.x),e.ythis.maxY&&(this.maxY=e.y),e.zthis.maxZ&&(this.maxZ=e.z))},BoundingBox.prototype.addBox=function(e){void 0!==e&&(e.minXthis.maxX&&(this.maxX=e.maxX),e.minYthis.maxY&&(this.maxY=e.maxY),e.minZthis.maxZ&&(this.maxZ=e.maxZ))},BoundingBox.prototype.getMinLength=function(){return Math.min(this.maxX-this.minX,this.maxY-this.minY,this.maxZ-this.minZ)},BoundingBox.prototype.getMaxLength=function(){return Math.max(this.maxX-this.minX,this.maxY-this.minY,this.maxZ-this.minZ)},BoundingBox.prototype.getXLength=function(){return this.maxX-this.minX},BoundingBox.prototype.getYLength=function(){return this.maxY-this.minY},BoundingBox.prototype.getZLength=function(){return this.maxZ-this.minZ},BoundingBox.prototype.getCenterPoint=function(e){return void 0===e&&(e=new Point3D),e.set((this.maxX+this.minX)/2,(this.maxY+this.minY)/2,(this.maxZ+this.minZ)/2),e},BoundingBox.prototype.getRadiusAprox=function(){return this.getMaxLength()/1.5},BoundingBox.prototype.intersectWithPoint=function(e){return void 0!==e&&!(e.xthis.maxX||e.ythis.maxY||e.zthis.maxZ)},BoundingBox.prototype.isPoint3dInside=function(e,t,i){return!(ethis.maxX)&&(!(tthis.maxY)&&!(ithis.maxZ))},BoundingBox.prototype.intersectWithBox=function(e){return void 0!==e&&!(e.minX>this.maxX||e.maxXthis.maxY||e.maxYthis.maxZ||e.maxZe.maxX?t=!1:this.maxYe.maxY?t=!1:this.maxZe.maxZ&&(t=!1),t};var BoundingSphere=function(){if(!(this instanceof BoundingSphere))throw new Error(Messages.CONSTRUCT_ERROR);this.center=new Point3D,this.radius=0},Box=function(){if(!(this instanceof Box))throw new Error(Messages.CONSTRUCT_ERROR);this.vbo_vicks_container=new VBOVertexIdxCacheKeysContainer,this.vbo_vicks_containerEdges,this.centerPoint,this.width,this.length,this.height};Box.prototype.getVboKeysContainer=function(){return this.vbo_vicks_container},Box.prototype.makeMesh=function(e,t,i){void 0!==e&&(this.width=e),void 0!==t&&(this.length=t),void 0!==i&&(this.height=i),void 0===this.width&&(this.width=1),void 0===this.length&&(this.length=1),void 0===this.height&&(this.height=1),void 0===this.centerPoint&&(this.centerPoint=new Point3D(0,0,0)),void 0===this.vbo_vicks_container&&(this.vbo_vicks_container=new VBOVertexIdxCacheKeysContainer),void 0===this.vbo_vicks_containerEdges&&(this.vbo_vicks_containerEdges=new VBOVertexIdxCacheKeysContainer);var o=new ParametricMesh;o.profile=new Profile;var r=o.profile,n=r.newOuterRing().newElement("RECTANGLE");n.setCenterPosition(this.centerPoint.x,this.centerPoint.y),n.setDimensions(this.width,this.length);o.extrude(r,this.height,1,void 0);var a=o.getSurfaceIndependentMesh(void 0,!0,!0);return a.translate(0,0,-this.height/2),a};var BuildingSeed=function(){if(!(this instanceof BuildingSeed))throw new Error(Messages.CONSTRUCT_ERROR);this.fisrtName,this.name="",this.buildingId,this.buildingFileName,this.geographicCoord,this.rotationsDegree,this.bBox,this.geographicCoordOfBBox};BuildingSeed.prototype.deleteObjects=function(){this.fisrtName=void 0,this.name=void 0,this.buildingId=void 0,this.buildingFileName=void 0,this.geographicCoord.deleteObjects(),this.rotationsDegree.deleteObjects(),this.bBox.deleteObjects(),this.geographicCoordOfBBox.deleteObjects(),this.geographicCoord=void 0,this.rotationsDegree=void 0,this.bBox=void 0,this.geographicCoordOfBBox=void 0};var BuildingSeedList=function(){if(!(this instanceof BuildingSeedList))throw new Error(Messages.CONSTRUCT_ERROR);this.buildingSeedArray=[],this.minGeographicCoord,this.maxGeographicCoord,this.dataArrayBuffer};BuildingSeedList.prototype.deleteObjects=function(){if(this.minGeographicCoord.deleteObjects(),this.maxGeographicCoord.deleteObjects(),this.minGeographicCoord=void 0,this.maxGeographicCoord=void 0,this.buildingSeedArray){for(var e=this.buildingSeedArray.length,t=0;t2e4&&(this.bigFrustum.far[0]=2e4)},Camera.prototype.setAspectRatioAndFovyRad=function(e,t){var i,o;(o=this.getFrustum(0)).aspectRatio[0]=e,o.fovyRad[0]=t,o.fovRad[0]=t*e,o.tangentOfHalfFovy[0]=Math.tan(t/2);for(var r=this.frustumsArray.length,n=1;nthis.maxHeading?(this.heading=this.maxHeading,this.headingAngularSpeed*=-1):this.heading.5&&(this.greenFactor=.5,this.greenFactorSpeed*=-1),this.greenFactor<0&&(this.greenFactor=0,this.greenFactorSpeed*=-1),this.blueFactor>.9&&(this.blueFactor=.9,this.blueFactorSpeed*=-1),this.blueFactor<0&&(this.blueFactor=0,this.blueFactorSpeed*=-1),this.alphaFactor>.6&&(this.alphaFactor=.6,this.alphaFactorSpeed*=-1),this.alphaFactor<0&&(this.alphaFactor=0,this.alphaFactorSpeed*=-1),this.color.setRGBA(0,this.greenFactor,this.blueFactor,this.alphaFactor)},CCTV.prototype.calculateRotationMatrix=function(){var e;e=Matrix4.getRotationDegZXYMatrix(this.heading,this.pitch,this.roll,e),this.rotMat=e.getMultipliedByMatrix(this.geoLocationData.rotMatrix,this.rotMat)},CCTV.prototype.getVbo=function(e,t){var i;void 0===e&&(e=new VBOVertexIdxCacheKeysContainer),void 0===this.vboKeyContainerEdges&&(this.vboKeyContainerEdges=new VBOVertexIdxCacheKeysContainer),i=this.makeFrustumGeometry_2(i);var o=new Matrix4,r=this.camera.bigFrustum.fovyRad/2;o.rotationAxisAngDeg(-90-r/2*180/Math.PI,1,0,0);var n=i.getSurfaceIndependentMesh(void 0,!0,!0);return n.transformByMatrix4(o),n.setColor(0,.5,.9,.3),n.getVbo(e),n.getVboEdges(this.vboKeyContainerEdges),e},CCTV.prototype.render=function(e,t,i){if(void 0!==this.vboKeyContainer){var o;this.vboKeyContainer.vboCacheKeysArray.length;e.uniformMatrix4fv(i.buildingRotMatrix_loc,!1,this.geoLocationData.rotMatrix._floatArrays),e.uniform3fv(i.buildingPosHIGH_loc,this.geoLocationData.positionHIGH),e.uniform3fv(i.buildingPosLOW_loc,this.geoLocationData.positionLOW),e.uniform1i(i.hasTexture_loc,!1),e.enable(e.POLYGON_OFFSET_FILL),e.polygonOffset(1,3);e.uniform1i(i.refMatrixType_loc,2),e.uniformMatrix4fv(i.refMatrix_loc,!1,this.rotMat._floatArrays);var r=t.renderer;o=!0,r.renderNormals=!1,e.uniform4fv(i.oneColor4_loc,[0,0,0,1]),r.renderVboContainer(e,this.vboKeyContainerEdges,t,i,o),e.enable(e.BLEND),o=!1,r.renderNormals=!0,e.uniform4fv(i.oneColor4_loc,[this.blueFactor,0,0,this.alphaFactor]),r.renderVboContainer(e,this.vboKeyContainer,t,i,o),e.disable(e.BLEND),e.disable(e.POLYGON_OFFSET_FILL)}},CCTV.prototype.makeFrustumGeometry_2=function(e){void 0===e&&(e=new ParametricMesh),e.profile=new Profile;var t,i,o=e.profile,r=this.camera.bigFrustum,n=r.far,a=r.fovyRad/2,s=r.fovRad/2,l=(Math.tan(s),Math.tan(a),o.newOuterRing());(t=l.newElement("POLYLINE")).newPoint2d(-n*Math.sin(s),n*Math.cos(s)),t.newPoint2d(0,0),t.newPoint2d(n*Math.sin(s),n*Math.cos(s));var c,h,d=90-180*s/Math.PI,u=90+180*s/Math.PI;i=l.newElement("ARC"),this.sweepSense=1,i.setCenterPosition(0,0),i.setRadius(n),i.setStartAngleDegree(d),i.setSweepAngleDegree(u-d),i.numPointsFor360Deg=36,c=2*a*180/Math.PI,h=new Segment2D;var f=new Point2D(-1,0),g=new Point2D(1,0);return h.setPoints(f,g),6,e.revolve(o,c,6,h),e},CCTV.prototype.makeFrustumGeometry=function(e){void 0===e&&(e=new Mesh),void 0===e.hedgesList&&(e.hedgesList=new HalfEdgesList);var t,i,o,r,n,a,s=new Point3D(0,0,0),l=this.camera.bigFrustum,c=l.far,h=l.fovyRad/2,d=l.fovRad/2,u=-c*Math.tan(d),f=-u,g=c*Math.tan(h),p=-g,m=new Point3D(u,p,-c),y=new Point3D(f,p,-c),v=new Point3D(f,g,-c),x=new Point3D(u,g,-c),b=new Vertex(s),C=new Vertex(m),M=new Vertex(y),_=new Vertex(v),A=new Vertex(x);void 0===this.vboKeyContainerEdges&&(this.vboKeyContainerEdges=new VBOVertexIdxCacheKeysContainer),(t=e.newSurface().newFace()).addVertex(C),t.addVertex(A),t.addVertex(_),t.addVertex(M);for(var R=0,P=[],T=[],L=t.vertexArray.length,S=0;S=254&&(this.color.b=0,this.color.g+=1,this.color.g>=254&&(this.color.g=0,this.color.r+=1,this.color.r>=254&&(this.color.r=0,this.cycle+=1))),e},SelectionColor.prototype.decodeColor3=function(e,t,i){return 64516*e+254*t+i};var FBO=function(e,t,i){if(!(this instanceof FBO))throw new Error(Messages.CONSTRUCT_ERROR);if(this.gl=e,this.width=new Int32Array(1),this.height=new Int32Array(1),this.width[0]=t,this.height[0]=i,this.fbo=e.createFramebuffer(),this.depthBuffer=e.createRenderbuffer(),this.colorBuffer=e.createTexture(),this.dirty=!0,e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.colorBuffer),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,t,i,0,e.RGBA,e.UNSIGNED_BYTE,null),e.bindFramebuffer(e.FRAMEBUFFER,this.fbo),e.bindRenderbuffer(e.RENDERBUFFER,this.depthBuffer),e.renderbufferStorage(e.RENDERBUFFER,e.DEPTH_COMPONENT16,t,i),e.framebufferRenderbuffer(e.FRAMEBUFFER,e.DEPTH_ATTACHMENT,e.RENDERBUFFER,this.depthBuffer),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.colorBuffer,0),e.checkFramebufferStatus(e.FRAMEBUFFER)!==e.FRAMEBUFFER_COMPLETE)throw"Incomplete frame buffer object.";e.bindFramebuffer(e.FRAMEBUFFER,null)};FBO.prototype.bind=function(){this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,this.fbo)},FBO.prototype.unbind=function(){this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,null)},FBO.prototype.deleteObjects=function(e){this.depthBuffer&&e.deleteRenderbuffer(this.depthBuffer),this.depthBuffer=void 0,this.colorBuffer&&e.deleteTexture(this.colorBuffer),this.colorBuffer=void 0,this.fbo&&e.deleteFramebuffer(this.fbo),this.fbo=void 0};var FileRequestControler=function(){if(!(this instanceof FileRequestControler))throw new Error(Messages.CONSTRUCT_ERROR);this.maxFilesRequestedCount=1,this.filesRequestedCount=0,this.headerFilesRequestedCount=0,this.modelRefFilesRequestedCount=0,this.lowLodDataRequestedCount=0,this.lowLodImagesRequestedCount=0};FileRequestControler.prototype.isFull=function(){return this.filesRequestedCount>=this.maxFilesRequestedCount},FileRequestControler.prototype.isFullHeaders=function(){return this.headerFilesRequestedCount>=1},FileRequestControler.prototype.isFullPlus=function(e){return void 0===e&&(e=0),this.filesRequestedCount>=this.maxFilesRequestedCount+e},FileRequestControler.prototype.isFullPlusModelReferences=function(e){return void 0===e&&(e=0),this.modelRefFilesRequestedCount>=this.maxFilesRequestedCount+e},FileRequestControler.prototype.isFullPlusLowLodData=function(e){return void 0===e&&(e=0),this.lowLodDataRequestedCount>=this.maxFilesRequestedCount+e},FileRequestControler.prototype.isFullPlusLowLodImages=function(e){return void 0===e&&(e=0),this.lowLodImagesRequestedCount>=this.maxFilesRequestedCount+e};var keyFlags={moveForward:!1,moveBackward:!1,moveLeft:!1,moveRight:!1};function getFlagFromKeyCode(e){switch(e){case 37:return"moveLeft";case 38:return"moveForward";case 39:return"moveRight";case 40:return"moveBackward";default:return}}function onKeyDown(e){var t=getFlagFromKeyCode(e.keyCode);void 0!==t&&(keyFlags[t]=!0)}function onKeyUp(e){var t=getFlagFromKeyCode(e.keyCode);void 0!==t&&(keyFlags[t]=!1)}function FirstPersonView(){this._camera=void 0,this._cameraBAK=void 0,this._position=new Point3D,this._rotation=new Point3D,this._positionSpeed=1,this._ratationSpeed=1}Object.defineProperties(FirstPersonView.prototype,{camera:{get:function(){return this._camera},set:function(e){this._camera=e}},position:{get:function(){return this._position},set:function(e){this._position=e}},rotation:{get:function(){return this._rotation},set:function(e){this._rotation=e}},positionSpeed:{get:function(){return this._positionSpeed},set:function(e){this._positionSpeed=e}},rotationSpeed:{get:function(){return this._ratationSpeed},set:function(e){this._ratationSpeed=e}}}),FirstPersonView.prototype.init=function(){this._position.set(0,0,0),this._rotation.set(0,0,0),document.addEventListener("keydown",onKeyDown,!1),document.addEventListener("keyup",onKeyUp,!1)},FirstPersonView.prototype.release=function(){this._camera=void 0,this._cameraBAK=void 0,document.removeEventListener("keydown",onKeyDown,!1),document.removeEventListener("keyup",onKeyUp,!1)},FirstPersonView.prototype.move=function(e){var t=vec3.fromValues(this._position.x,this._position.y,this.position.z),i=mat4.create();mat4.rotateY(i,i,this._rotation.y),vec3.transformMat4(e,e,i),vec3.add(t,t,e),this._position.set(t[0],t[1],t[2])},FirstPersonView.prototype.update=function(e){void 0!==this._camera&&(keyFlags.moveForward&&(this._camera.moveForward(.5),this.move(vec3.fromValues(0,1,0))),keyFlags.moveBackward&&(this._camera.moveBackward(.5),this.move(vec3.fromValues(0,-1,0))),keyFlags.moveLeft&&(this._camera.lookLeft(.1),this.move(vec3.fromValues(-1,0,0))),keyFlags.moveRight&&(this._camera.lookRight(.1),this.move(vec3.fromValues(1,0,0))))};var Frustum=function(){if(!(this instanceof Frustum))throw new Error(Messages.CONSTRUCT_ERROR);this.near=new Float32Array([.1]),this.far=new Float32Array([1e3]),this.fovyRad=new Float32Array([.8037]),this.tangentOfHalfFovy=new Float32Array([0]),this.fovRad=new Float32Array([1.047]),this.aspectRatio=new Float32Array([1.3584]),this.planesArray=[],this.dirty=!0;for(var e=0;e<6;e++){var t=new Plane;this.planesArray.push(t)}};Frustum.prototype.copyParametersFrom=function(e){this.near[0]=e.near[0],this.far[0]=e.far[0],this.fovyRad[0]=e.fovyRad[0],this.tangentOfHalfFovy[0]=e.tangentOfHalfFovy[0],this.fovRad[0]=e.fovRad[0],this.aspectRatio[0]=e.aspectRatio[0]},Frustum.prototype.setNear=function(e){this.near[0]=e},Frustum.prototype.setFar=function(e){this.far[0]=e},Frustum.prototype.intersectionNearFarSphere=function(e){for(var t=!1,i=0;i<2;i++){var o=this.planesArray[i].intersectionSphere(e);if(o===Constant.INTERSECTION_OUTSIDE)return Constant.INTERSECTION_OUTSIDE;o===Constant.INTERSECTION_INTERSECT&&(t=!0)}return t?Constant.INTERSECTION_INTERSECT:Constant.INTERSECTION_INSIDE},Frustum.prototype.intersectionSphere=function(e){for(var t=!1,i=0;i<6;i++){var o=this.planesArray[i].intersectionSphere(e);if(o===Constant.INTERSECTION_OUTSIDE)return Constant.INTERSECTION_OUTSIDE;o===Constant.INTERSECTION_INTERSECT&&(t=!0)}return t?Constant.INTERSECTION_INTERSECT:Constant.INTERSECTION_INSIDE};var FrustumVolumeControl=function(){if(!(this instanceof FrustumVolumeControl))throw new Error(Messages.CONSTRUCT_ERROR);this.frustumVolumensMap={}};FrustumVolumeControl.prototype.getFrustumVolumeCulling=function(e){return this.frustumVolumensMap.hasOwnProperty(e)||(this.frustumVolumensMap[e]={},this.frustumVolumensMap[e].fullyIntersectedLowestTilesArray=[],this.frustumVolumensMap[e].partiallyIntersectedLowestTilesArray=[],this.frustumVolumensMap[e].visibleNodes=new VisibleObjectsController),this.frustumVolumensMap[e]},FrustumVolumeControl.prototype.initArrays=function(){var e;for(var t in this.frustumVolumensMap)(e=this.frustumVolumensMap[t]).fullyIntersectedLowestTilesArray.length=0,e.partiallyIntersectedLowestTilesArray.length=0,e.visibleNodes.initArrays()};var GeographicCoord=function(e,t,i){if(!(this instanceof GeographicCoord))throw new Error(Messages.CONSTRUCT_ERROR);this.longitude,this.latitude,this.altitude,void 0!==e&&(this.longitude=e),void 0!==t&&(this.latitude=t),void 0!==i&&(this.altitude=i)};GeographicCoord.prototype.deleteObjects=function(){this.longitude=void 0,this.latitude=void 0,this.altitude=void 0},GeographicCoord.prototype.copyFrom=function(e){this.longitude=e.longitude,this.latitude=e.latitude,this.altitude=e.altitude},GeographicCoord.prototype.setLonLatAlt=function(e,t,i){this.longitude=e,this.latitude=t,this.altitude=i},GeographicCoord.getMidPoint=function(e,t,i){var o=(e.latitude+t.latitude)/2,r=(e.longitude+t.longitude)/2,n=(e.altitude+t.altitude)/2;return void 0===i?i=new GeographicCoord(r,o,n):i.setLonLatAlt(r,o,n),i};var GeographicExtent=function(){if(!(this instanceof GeographicExtent))throw new Error(Messages.CONSTRUCT_ERROR);this.minGeographicCoord,this.maxGeographicCoord},GeoLocationData=function(e){if(!(this instanceof GeoLocationData))throw new Error(Messages.CONSTRUCT_ERROR);this.name,this.name=void 0===e?"noName":e,this.geographicCoord,this.heading,this.pitch,this.roll,this.date,this.position,this.positionHIGH,this.positionLOW,this.pivotPoint,this.geoLocMatrix,this.geoLocMatrixInv,this.tMatrix,this.tMatrixInv,this.rotMatrix,this.rotMatrixInv,this.pivotPointTraslation};GeoLocationData.prototype.deleteObjects=function(){this.name=void 0,this.geographicCoord&&this.geographicCoord.deleteObjects(),this.geographicCoord=void 0,this.heading=void 0,this.pitch=void 0,this.roll=void 0,this.date=void 0,this.position&&this.position.deleteObjects(),this.position=void 0,this.positionHIGH=void 0,this.positionLOW=void 0,this.pivotPoint&&this.pivotPoint.deleteObjects(),this.pivotPoint=void 0,this.geoLocMatrix&&this.geoLocMatrix.deleteObjects(),this.geoLocMatrixInv&&this.geoLocMatrixInv.deleteObjects(),this.tMatrix&&this.tMatrix.deleteObjects(),this.tMatrixInv&&this.tMatrixInv.deleteObjects(),this.rotMatrix&&this.rotMatrix.deleteObjects(),this.rotMatrixInv&&this.rotMatrixInv.deleteObjects(),this.geoLocMatrix=void 0,this.geoLocMatrixInv=void 0,this.tMatrix=void 0,this.tMatrixInv=void 0,this.rotMatrix=void 0,this.rotMatrixInv=void 0,this.pivotPointTraslation&&this.pivotPointTraslation.deleteObjects(),this.pivotPointTraslation=void 0},GeoLocationData.prototype.doEffectivePivotPointTranslation=function(){var e;void 0!==this.pivotPointTraslation&&(e=this.tMatrix.rotatePoint3D(this.pivotPointTraslation,e),this.position.x+=e.x,this.position.y+=e.y,this.position.z+=e.z,this.positionLOW[0]+=e.x,this.positionLOW[1]+=e.y,this.positionLOW[2]+=e.z,void 0===this.pivotPoint&&(this.pivotPoint=new Point3D),this.pivotPoint.set(this.position.x,this.position.y,this.position.z))},GeoLocationData.prototype.copyFrom=function(e){void 0!==e&&(this.name=e.name,e.geographicCoord&&(void 0===this.geographicCoord&&(this.geographicCoord=new GeographicCoord),this.geographicCoord.copyFrom(e.geographicCoord)),this.heading=e.heading,this.pitch=e.pitch,this.roll=e.roll,this.date=e.date,e.position&&(void 0===this.position&&(this.position=new Point3D),this.position.copyFrom(e.position)),e.positionHIGH&&(void 0===this.positionHIGH&&(this.positionHIGH=new Float32Array(3)),this.positionHIGH[0]=e.positionHIGH[0],this.positionHIGH[1]=e.positionHIGH[1],this.positionHIGH[2]=e.positionHIGH[2]),e.positionLOW&&(void 0===this.positionLOW&&(this.positionLOW=new Float32Array(3)),this.positionLOW[0]=e.positionLOW[0],this.positionLOW[1]=e.positionLOW[1],this.positionLOW[2]=e.positionLOW[2]),e.pivotPoint&&(void 0===this.pivotPoint&&(this.pivotPoint=new Point3D),this.pivotPoint.copyFrom(e.pivotPoint)),e.geoLocMatrix&&(void 0===this.geoLocMatrix&&(this.geoLocMatrix=new Matrix4),this.geoLocMatrix.copyFromMatrix4(e.geoLocMatrix)),e.geoLocMatrixInv&&(void 0===this.geoLocMatrixInv&&(this.geoLocMatrixInv=new Matrix4),this.geoLocMatrixInv.copyFromMatrix4(e.geoLocMatrixInv)),e.tMatrix&&(void 0===this.tMatrix&&(this.tMatrix=new Matrix4),this.tMatrix.copyFromMatrix4(e.tMatrix)),e.tMatrixInv&&(void 0===this.tMatrixInv&&(this.tMatrixInv=new Matrix4),this.tMatrixInv.copyFromMatrix4(e.tMatrixInv)),e.rotMatrix&&(void 0===this.rotMatrix&&(this.rotMatrix=new Matrix4),this.rotMatrix.copyFromMatrix4(e.rotMatrix)),e.rotMatrixInv&&(void 0===this.rotMatrixInv&&(this.rotMatrixInv=new Matrix4),this.rotMatrixInv.copyFromMatrix4(e.rotMatrixInv)),e.aditionalTraslation&&(void 0===this.aditionalTraslation&&(this.aditionalTraslation=new Point3D),this.aditionalTraslation.copyFrom(e.aditionalTraslation)))},GeoLocationData.prototype.localCoordToWorldCoord=function(e,t){if(void 0!==e&&void 0!==this.tMatrix)return void 0===t&&(t=new Point3D),t=this.tMatrix.transformPoint3D(e,t)},GeoLocationData.prototype.worldCoordToLocalCoord=function(e,t){if(void 0!==e&&void 0!==this.tMatrixInv)return void 0===t&&(t=new Point3D),t=this.tMatrixInv.transformPoint3D(e,t)},GeoLocationData.prototype.getTransformedRelativeCamera=function(e,t){var i=new Point3D;return i.set(e.position.x-this.position.x,e.position.y-this.position.y,e.position.z-this.position.z),t.position=this.rotMatrixInv.transformPoint3D(i,t.position),i.set(e.direction.x,e.direction.y,e.direction.z),t.direction=this.rotMatrixInv.transformPoint3D(i,t.direction),i.set(e.up.x,e.up.y,e.up.z),t.up=this.rotMatrixInv.transformPoint3D(i,t.up),i.x=void 0,i.y=void 0,i.z=void 0,i=void 0,t};var GeoLocationDataManager=function(){if(!(this instanceof GeoLocationDataManager))throw new Error(Messages.CONSTRUCT_ERROR);this.geoLocationDataArray=[]};GeoLocationDataManager.prototype.deleteObjects=function(){if(this.geoLocationDataArray){for(var e=0;ethis.geoLocationDataArray.length-1))return this.geoLocationDataArray[e]},GeoLocationDataManager.prototype.getCurrentGeoLocationData=function(){if(0!==this.geoLocationDataArray.length)return this.geoLocationDataArray[0]};var GeometryModifier=function(){if(!(this instanceof GeometryModifier))throw new Error(Messages.CONSTRUCT_ERROR)};GeometryModifier.prototype.setPoint3d=function(e,t,i,o){e.x=t,e.y=i,e.z=o},GeometryModifier.prototype.point3dSquareDistTo=function(e,t,i,o){var r=e.x-t,n=e.y-i,a=e.z-o;return r*r+n*n+a*a},GeometryModifier.prototype.Matrix4SetByFloat32Array=function(e,t){for(var i=0;i<16;i++)e._floatArrays[i]=t[i]},GeometryModifier.prototype.Matrix4TransformPoint3D=function(e,t){var i=new Point3D;return i.x=t.x*e._floatArrays[0]+t.y*e._floatArrays[4]+t.z*e._floatArrays[8]+e._floatArrays[12],i.y=t.x*e._floatArrays[1]+t.y*e._floatArrays[5]+t.z*e._floatArrays[9]+e._floatArrays[13],i.z=t.x*e._floatArrays[2]+t.y*e._floatArrays[6]+t.z*e._floatArrays[10]+e._floatArrays[14],i},GeometryModifier.prototype.Matrix4GetMultipliedByMatrix=function(e,t){for(var i=new Matrix4,o=0;o<4;o++)for(var r=0;r<4;r++){var n=4*o+r;i._floatArrays[n]=0;for(var a=0;a<4;a++)i._floatArrays[n]+=t._floatArrays[4*a+r]*e._floatArrays[4*o+a]}return i},GeometryModifier.prototype.referenceMultiplyTransformMatrix=function(e,t){var i=this.Matrix4GetMultipliedByMatrix(e._matrix4,t);e._matrix4=i},GeometryModifier.prototype.compoundReferencesListMultiplyReferencesMatrices=function(e,t){for(var i=e._compoundRefsArray.length,o=0;o0){var t=(e.maxX+e.minX)/2,i=(e.maxY+e.minY)/2,o=(e.maxZ+e.minZ)/2;this.occlusionCullingOctreeCellSetDimensions(e._subBoxesArray[0],e.minX,t,e.minY,i,e.minZ,o),this.occlusionCullingOctreeCellSetDimensions(e._subBoxesArray[1],t,e.maxX,e.minY,i,e.minZ,o),this.occlusionCullingOctreeCellSetDimensions(e._subBoxesArray[2],t,e.maxX,i,e.maxY,e.minZ,o),this.occlusionCullingOctreeCellSetDimensions(e._subBoxesArray[3],e.minX,t,i,e.maxY,e.minZ,half_z),this.occlusionCullingOctreeCellSetDimensions(e._subBoxesArray[4],e.minX,t,e.minY,i,o,e.maxZ),this.occlusionCullingOctreeCellSetDimensions(e._subBoxesArray[5],t,e.maxX,e.minY,i,o,e.maxZ),this.occlusionCullingOctreeCellSetDimensions(e._subBoxesArray[6],t,e.maxX,i,e.maxY,o,e.maxZ),this.occlusionCullingOctreeCellSetDimensions(e._subBoxesArray[7],e.minX,t,i,e.maxY,o,e.maxZ);for(var r=0;re.minX&&te.minY&&ie.minZ&&o0){var n,a=(e.minX+e.maxX)/2,s=(e.minY+e.maxY)/2,l=(e.minZ+e.maxZ)/2,c=void 0;c=t0&&(r=n._indicesArray),r},GeometryModifier.prototype.occlusionCullingOctreeCellExpandBox=function(e,t){e.minX-=t,e.maxX+=t,e.minY-=t,e.maxY+=t,e.minZ-=t,e.maxZ+=t},GeometryModifier.prototype.vertexTexcoordsArraysCacheKeysContainerNewVertexTexcoordsArraysCacheKey=function(e){var t=new VertexTexcoordsArraysCacheKeys;return e._vtArrays_cacheKeys_array.push(t),t},GeometryModifier.prototype.blocksListGetBlock=function(e,t){var i=null;return t>=0&&t0||0!=S?(E>0?(s=Math.sqrt(E),l=Math.sqrt(T*L*S),a=E>10*P?w+.5*(c=Math.cbrt((s+l)*(s+l)))+2*w*w/c:w+.5*Math.cbrt((s+l)*(s+l))+.5*Math.cbrt((s-l)*(s-l))):(s=Math.sqrt(-E),l=Math.sqrt(-8*w*w*w),c=Math.sqrt(T*L*S),h=2*Math.atan2(c,s+l)/3,a=-4*w*Math.sin(h)*Math.cos(Math.PI/6+h)),u=P*(a+(d=Math.sqrt(a*a+T*S))-S)/(2*d),g=(f=(a+d)/(Math.sqrt(u*u+a+d)+u))*_/(f+P),r=(f+P-1)*(p=Math.sqrt(g*g+C*C))/f,n=2*Math.atan2(C,p+g)):(r=-A*(s=Math.sqrt(1-P))*(l=Math.sqrt(P-L))/(m=Math.sqrt(P)),n=l/(m*l+s*Math.sqrt(L))),y=((v=Math.sqrt(2))-1)*b<_+x?2*Math.atan2(b,_+x):_+b<(v+1)*x?.5*-Math.PI+2*Math.atan2(x,_-b):.5*Math.PI-2*Math.atan2(x,_+b),void 0===o&&(o=new GeographicCoord);var D=180/Math.PI;return o.latitude=D*n,o.longitude=D*y,o.altitude=r,o},Globe.geographicToCartesianWgs84=function(e,t,i,o){var r=Math.PI/180,n=e*r,a=t*r,s=Math.cos(n),l=Math.cos(a),c=Math.sin(n),h=Math.sin(a),d=.00669437999014,u=6378137/Math.sqrt(1-d*h*h),f=i;return void 0===o&&(o=new Float32Array(3)),o[0]=(u+f)*l*s,o[1]=(u+f)*l*c,o[2]=(u*(1-d)+f)*h,o},Globe.geographicRadianArrayToFloat32ArrayWgs84=function(e,t,i,o){var r,n,a,s,l,c,h,d,u=.00669437999014,f=e.length;o=new Float32Array(3*f);for(var g=0;g2&&(p=2),f=this.visibleObjControlerNodes.currentVisibles2.length;for(g=0;g=0;g--)u=this.visibleObjControlerNodes.currentVisibles2[g],this.processQueue.putNodeToDeleteModelReferences(u,0);this.prepareVisibleLowLodNodes(this.visibleObjControlerNodes.currentVisibles3),void 0===this.visibleObjControlerOctreesAux&&(this.visibleObjControlerOctreesAux=new VisibleObjectsController),this.visibleObjControlerOctreesAux.initArrays();for(f=this.visibleObjControlerNodes.currentVisiblesAux.length,g=0;g1)&&!(Object.keys(this.loadQueue.lowLodSkinTextureMap).length>1)){this.sceneState.gl;for(var t,i,o,r,n=this.readerWriter.geometryDataPath,a=e.length,s=0;s1)return;if(Object.keys(this.loadQueue.lowLodSkinTextureMap).length>1)return;var l=(i=e[s].data.neoBuilding).getHeaderVersion();if(void 0!==l&&"0"===l[0]){var c,h;void 0===i.lodMeshesMap&&(i.lodMeshesMap={}),o=i.projectFolderName,r=i.buildingFileName;i.currentLod;var d=i.getLodBuildingData(i.currentLod);if(void 0!==d&&!d.isModelRef&&(c=d.textureFileName,h=d.geometryFileName,void 0===(t=i.lodMeshesMap[h])&&((t=new Lego).fileLoadState=CODE.fileLoadState.READY,t.textureName=c,t.legoKey=i.buildingId+"_"+h,i.lodMeshesMap[h]=t),-1!==t.fileLoadState)){if(t.fileLoadState===CODE.fileLoadState.READY){var u=n+"/"+o+"/"+r+"/"+h;this.loadQueue.putLowLodSkinData(t,u,0),void 0===t.vbo_vicks_container.vboCacheKeysArray&&(t.vbo_vicks_container.vboCacheKeysArray=[])}if(t.vbo_vicks_container.vboCacheKeysArray[0]&&t.vbo_vicks_container.vboCacheKeysArray[0].meshTexcoordsCacheKey&&void 0===t.texture){t.texture=new Texture;var f=n+"/"+o+"/"+r+"/"+c;this.loadQueue.putLowLodSkinTexture(f,t.texture,0)}if(this.fileRequestControler.isFullPlusLowLodData(5))return}}}}},MagoManager.prototype.renderMagoGeometries=function(e){if(void 0===this.nativeProjectsArray){this.nativeProjectsArray=[];var t=new MagoNativeProject;this.nativeProjectsArray.push(t);var i=t.newParametricMesh();i.profile=new Profile;var o,r=i.profile;r.TEST__setFigureHole_2(),void 0===i.vboKeyContainer&&(i.vboKeyContainer=new VBOVertexIdxCacheKeysContainer),void 0===i.vboKeyContainerEdges&&(i.vboKeyContainerEdges=new VBOVertexIdxCacheKeysContainer),90,o=new Segment2D;var n=new Point2D(20,-10),a=new Point2D(20,10);if(o.setPoints(n,a),24,i.revolve(r,90,24,o),!0,!0,(h=i.getSurfaceIndependentMesh(void 0,!0,!0)).setColor(.1,.5,.5,1),h.getVbo(i.vboKeyContainer),h.getVboEdges(i.vboKeyContainerEdges),void 0===t.geoLocDataManager){t.geoLocDataManager=new GeoLocationDataManager;var s=t.geoLocDataManager.newGeoLocationData("deploymentLoc");ManagerUtils.calculateGeoLocationData(126.61120237344926,37.577213509597016,50,0,0,0,s,this)}}var l,c=this.sceneState.gl;0===e&&(l=this.postFxShadersManager.getTriPolyhedronDepthShader(),c.disable(c.BLEND)),1===e&&(l=this.postFxShadersManager.getTriPolyhedronShader(),c.enable(c.BLEND));var h,d,u,f=l.program;c.frontFace(c.CCW),c.useProgram(f),c.enableVertexAttribArray(l.position3_loc),c.uniformMatrix4fv(l.modelViewProjectionMatrix4RelToEye_loc,!1,this.sceneState.modelViewProjRelToEyeMatrix._floatArrays),c.uniformMatrix4fv(l.modelViewMatrix4RelToEye_loc,!1,this.sceneState.modelViewRelToEyeMatrix._floatArrays),c.uniform3fv(l.cameraPosHIGH_loc,this.sceneState.encodedCamPosHigh),c.uniform3fv(l.cameraPosLOW_loc,this.sceneState.encodedCamPosLow),c.uniform1f(l.near_loc,this.sceneState.camera.frustum.near),c.uniform1f(l.far_loc,this.sceneState.camera.frustum.far),c.uniform1i(l.bApplySsao_loc,!1),c.uniformMatrix4fv(l.normalMatrix4_loc,!1,this.sceneState.normalMatrix4._floatArrays),1===e&&(c.enableVertexAttribArray(l.normal3_loc),c.enableVertexAttribArray(l.color4_loc),c.uniform1i(l.bUse1Color_loc,!1),c.uniform4fv(l.oneColor4_loc,[1,.1,.1,1]),c.uniform1i(l.bUseNormal_loc,!0),c.uniformMatrix4fv(l.modelViewMatrix4_loc,!1,this.sceneState.modelViewMatrix._floatArrays),c.uniformMatrix4fv(l.projectionMatrix4_loc,!1,this.sceneState.projectionMatrix._floatArrays),c.uniform1i(l.depthTex_loc,0),c.uniform1i(l.noiseTex_loc,1),c.uniform1i(l.diffuseTex_loc,2),c.uniform1f(l.fov_loc,this.sceneState.camera.frustum.fovyRad),c.uniform1f(l.aspectRatio_loc,this.sceneState.camera.frustum.aspectRatio),c.uniform1f(l.screenWidth_loc,this.sceneState.drawingBufferWidth),c.uniform1f(l.screenHeight_loc,this.sceneState.drawingBufferHeight),c.uniform2fv(l.noiseScale2_loc,[this.depthFboNeo.width/this.noiseTexture.width,this.depthFboNeo.height/this.noiseTexture.height]),c.uniform3fv(l.kernel16_loc,this.kernel),c.activeTexture(c.TEXTURE0),c.bindTexture(c.TEXTURE_2D,this.depthFboNeo.colorBuffer),c.activeTexture(c.TEXTURE1),c.bindTexture(c.TEXTURE_2D,this.noiseTexture));for(var g=this.nativeProjectsArray.length,p=0;p=0&&s.y>=0&&(i.font="13px Arial",i.strokeText(r.data.data_name,s.x,s.y),i.fillText(r.data.data_name,s.x,s.y)));c={},i.restore()}},MagoManager.prototype.cameraMoved=function(){this.sceneState.camera.setDirty(!0),void 0===this.selectionFbo&&(this.selectionFbo=new FBO(this.sceneState.gl,this.sceneState.drawingBufferWidth,this.sceneState.drawingBufferHeight)),this.selectionFbo.dirty=!0},MagoManager.prototype.getNodeGeoLocDataManager=function(e){if(void 0!==e){var t=e.getClosestParentWithData("geoLocDataManager");if(void 0!==t)if(void 0!==t.data)return t.data.geoLocDataManager}},MagoManager.prototype.renderGeometryColorCoding=function(e,t){var i,o,r,n,a,s,l=0,c=e.TRIANGLES,h=this.postFxShadersManager.pFx_shaders_array[5],d=h.program;e.useProgram(d),e.enableVertexAttribArray(h.position3_loc),e.uniformMatrix4fv(h.modelViewProjectionMatrix4RelToEye_loc,!1,this.sceneState.modelViewProjRelToEyeMatrix._floatArrays),e.uniform3fv(h.cameraPosHIGH_loc,this.sceneState.encodedCamPosHigh),e.uniform3fv(h.cameraPosLOW_loc,this.sceneState.encodedCamPosLow);for(var u=t.currentVisibles0.length,f=0;f0)return r.set(-1,-1,0),r;var a=this.sceneState.camera.frustum.tangentOfHalfFovy*n*2,s=a*this.sceneState.camera.frustum.aspectRatio,l=-this.pointSC2.x*this.sceneState.drawingBufferWidth/s,c=-this.pointSC2.y*this.sceneState.drawingBufferHeight/a;return l+=this.sceneState.drawingBufferWidth/2,c+=this.sceneState.drawingBufferHeight/2,c=this.sceneState.drawingBufferHeight-c,r.set(l,c,0),r},MagoManager.prototype.isDragging=function(){var e=this.sceneState.gl;if(this.magoPolicy.objectMoveMode===CODE.moveMode.ALL){this.arrayAuxSC.length=0,this.selectionFbo.bind();var t,i=this.getSelectedObjects(e,this.mouse_x,this.mouse_y,this.arrayAuxSC),o=(this.arrayAuxSC[0],this.arrayAuxSC[3]);return o&&(t=o.getRoot()),this.arrayAuxSC.length=0,t===this.rootNodeSelected}if(this.magoPolicy.objectMoveMode===CODE.moveMode.OBJECT){this.arrayAuxSC.length=0,this.selectionFbo.bind();i=this.getSelectedObjects(e,this.mouse_x,this.mouse_y,this.arrayAuxSC);return this.arrayAuxSC.length=0,i===this.objectSelected}return!1},MagoManager.prototype.setCameraMotion=function(e){this.configInformation.geo_view_library===Constant.WORLDWIND?(this.wwd.navigator.panRecognizer.enabled=e,this.wwd.navigator.primaryDragRecognizer.enabled=e):this.configInformation.geo_view_library===Constant.CESIUM&&(this.scene.screenSpaceCameraController.enableRotate=e,this.scene.screenSpaceCameraController.enableZoom=e,this.scene.screenSpaceCameraController.enableLook=e,this.scene.screenSpaceCameraController.enableTilt=e,this.scene.screenSpaceCameraController.enableTranslate=e)},MagoManager.prototype.mouseActionLeftDown=function(e,t){this.dateSC=new Date,this.startTimeSC=this.dateSC.getTime(),this.mouse_x=e,this.mouse_y=t,this.mouseLeftDown=!0},MagoManager.prototype.saveHistoryObjectMovement=function(e,t){var i=new ChangeHistory,o=i.getReferenceObjectAditionalMovement(),r=i.getReferenceObjectAditionalMovementRelToBuilding();if(void 0===e.moveVector&&(e.moveVector=new Point3D),void 0===e.moveVectorRelToBuilding&&(e.moveVectorRelToBuilding=new Point3D),o.set(e.moveVector.x,e.moveVector.y,e.moveVector.z),r.set(e.moveVectorRelToBuilding.x,e.moveVectorRelToBuilding.y,e.moveVectorRelToBuilding.z),void 0!==t){var n=t.data.projectId,a=t.data.nodeId,s=e._id;i.setProjectId(n),i.setDataKey(a),i.setObjectIndexOrder(s),MagoConfig.saveMovingHistory(n,a,s,i)}},MagoManager.prototype.mouseActionLeftUp=function(e,t){if(this.objectMoved){this.objectMoved=!1;var i=this.selectionCandidates.currentNodeSelected;if(void 0===i)return;this.saveHistoryObjectMovement(this.objectSelected,i)}this.isCameraMoving=!1,this.mouseLeftDown=!1,this.mouseDragging=!1,this.selObjMovePlane=void 0,this.mustCheckIfDragging=!0,this.thereAreStartMovePoint=!1,this.dateSC=new Date,this.currentTimeSC=this.dateSC.getTime(),this.currentTimeSC-this.startTimeSC<1500&&this.mouse_x===e&&this.mouse_y===t&&(this.bPicking=!0),this.setCameraMotion(!0)},MagoManager.prototype.mouseActionMiddleDown=function(e,t){this.dateSC=new Date,this.startTimeSC=this.dateSC.getTime(),this.mouse_x=e,this.mouse_y=t,this.mouseMiddleDown=!0,this.isCameraMoving=!0},MagoManager.prototype.mouseActionMiddleUp=function(e,t){this.isCameraMoving=!1,this.mouseMiddleDown=!1,this.mouseDragging=!1,this.selObjMovePlane=void 0,this.mustCheckIfDragging=!0,this.thereAreStartMovePoint=!1,this.setCameraMotion(!1)},MagoManager.prototype.mouseActionRightDown=function(e,t){},MagoManager.prototype.mouseActionRightUp=function(e,t){},MagoManager.prototype.mouseActionMove=function(e,t){this.mouseLeftDown?this.manageMouseDragging(e,t):this.mouseMiddleDown?this.sceneState.camera.setDirty(!0):this.mouseRightDown?this.sceneState.camera.setDirty(!0):(this.mouseDragging=!1,this.setCameraMotion(!1),this.mouseMiddleDown&&(this.isCameraMoving=!0))},MagoManager.prototype.manageMouseDragging=function(e,t){if(this.sceneState.camera.setDirty(!0),this.magoPolicy.objectMoveMode===CODE.moveMode.ALL)if(void 0!==this.buildingSelected){this.mouse_x=e,this.mouse_y=t,this.mustCheckIfDragging&&(this.isDragging()&&(this.mouseDragging=!0,this.setCameraMotion(!1)),this.mustCheckIfDragging=!1);var i=this.buildingSelected.nodeOwner;if(void 0===i)return;var o=i.data.geoLocDataManager;if(void 0===o)return;var r=o.getGeoLocationData(0);if(void 0===r)return;var n=r.geographicCoord;if(void 0===n)return;movedDataCallback(MagoConfig.getPolicy().geo_callback_moveddata,i.data.projectId,i.data.nodeId,null,n.latitude,n.longitude,n.altitude,r.heading,r.pitch,r.roll)}else this.isCameraMoving=!0;else this.magoPolicy.objectMoveMode===CODE.moveMode.OBJECT&&(void 0!==this.objectSelected?(this.mouse_x=e,this.mouse_y=t,this.mustCheckIfDragging&&(this.isDragging()&&(this.mouseDragging=!0,this.setCameraMotion(!1)),this.mustCheckIfDragging=!1)):this.isCameraMoving=!0);this.isCameraMoving=!0,this.mouseDragging&&this.moveSelectedObjectAsimetricMode(this.sceneState.gl)},MagoManager.prototype.moveSelectedObjectAsimetricMode=function(e){if(this.magoPolicy.objectMoveMode===CODE.moveMode.ALL){if(void 0===this.selectionCandidates.currentNodeSelected)return;var t=(u=this.getNodeGeoLocDataManager(this.selectionCandidates.currentNodeSelected)).getCurrentGeoLocationData();if(void 0===this.selObjMovePlane){this.selObjMovePlane=new Plane;var i=new Point3D;i=this.calculatePixelPositionWorldCoord(e,this.mouse_x,this.mouse_y,i);var o=t.tMatrixInv.transformPoint3D(i,o);this.selObjMovePlane.setPointAndNormal(o.x,o.y,o.z,0,0,1)}void 0===this.lineSC&&(this.lineSC=new Line),this.lineSC=this.getRayWorldSpace(e,this.mouse_x,this.mouse_y,this.lineSC);var r=new Point3D,n=new Point3D;r=t.geoLocMatrixInv.transformPoint3D(this.lineSC.point,r),this.pointSC=t.geoLocMatrixInv.rotatePoint3D(this.lineSC.direction,this.pointSC),n.x=this.pointSC.x,n.y=this.pointSC.y,n.z=this.pointSC.z,(f=new Line).setPointAndDir(r.x,r.y,r.z,n.x,n.y,n.z);var a=new Point3D;if((a=this.selObjMovePlane.intersectionLine(f,a)).set(-a.x,-a.y,-a.z),void 0===this.pointSC&&(this.pointSC=new Point3D),this.pointSC=t.geoLocMatrix.transformPoint3D(a,this.pointSC),a.set(this.pointSC.x,this.pointSC.y,this.pointSC.z),this.thereAreStartMovePoint){d=ManagerUtils.pointToGeographicCoord(a,d,this);this.pointSC.x=d.longitude,this.pointSC.y=d.latitude;var s=this.pointSC.x-this.startMovPoint.x,l=this.pointSC.y-this.startMovPoint.y,c=t.geographicCoord.longitude-s,h=t.geographicCoord.latitude-l;this.changeLocationAndRotationNode(this.selectionCandidates.currentNodeSelected,h,c,void 0,void 0,void 0,void 0),this.displayLocationAndRotation(this.buildingSelected),this.startMovPoint.x-=s,this.startMovPoint.y-=l}else{var d=ManagerUtils.pointToGeographicCoord(a,d,this);this.startMovPoint.x=d.longitude,this.startMovPoint.y=d.latitude,this.thereAreStartMovePoint=!0}}else if(this.magoPolicy.objectMoveMode===CODE.moveMode.OBJECT){if(void 0===this.objectSelected)return;void 0===this.selObjMovePlane&&(this.selObjMovePlane=this.calculateSelObjMovePlaneAsimetricMode(e,this.mouse_x,this.mouse_y,this.selObjMovePlane));var u=this.getNodeGeoLocDataManager(this.selectionCandidates.currentNodeSelected);void 0===this.lineSC&&(this.lineSC=new Line),this.getRayWorldSpace(e,this.mouse_x,this.mouse_y,this.lineSC);var f,g=u.getCurrentGeoLocationData();r=new Point3D,n=new Point3D;r=g.tMatrixInv.transformPoint3D(this.lineSC.point,r),n=g.tMatrixInv.rotatePoint3D(this.lineSC.direction,n),(f=new Line).setPointAndDir(r.x,r.y,r.z,n.x,n.y,n.z);a=new Point3D;if(a=this.selObjMovePlane.intersectionLine(f,a),void 0===this.objectSelected.moveVectorRelToBuilding&&(this.objectSelected.moveVectorRelToBuilding=new Point3D),this.thereAreStartMovePoint){s=a.x-this.startMovPoint.x,l=a.y-this.startMovPoint.y;var p=a.z-this.startMovPoint.z;this.objectSelected.moveVectorRelToBuilding.set(s,l,p),this.objectSelected.moveVector=g.tMatrix.rotatePoint3D(this.objectSelected.moveVectorRelToBuilding,this.objectSelected.moveVector)}else this.startMovPoint=a,this.startMovPoint.add(-this.objectSelected.moveVectorRelToBuilding.x,-this.objectSelected.moveVectorRelToBuilding.y,-this.objectSelected.moveVectorRelToBuilding.z),this.thereAreStartMovePoint=!0;var m=this.selectionCandidates.currentNodeSelected.data.projectId,y=this.selectionCandidates.currentNodeSelected.data.nodeId,v=this.objectSelected._id;MagoConfig.deleteMovingHistoryObject(m,y,v),this.objectMoved=!0}},MagoManager.prototype.getRenderablesDetailedNeoBuildingAsimetricVersion=function(e,t,i,o){var r=t.data.neoBuilding;if(void 0!==r&&void 0!==r.octree){var n=this.getNodeGeoLocDataManager(t),a=(n.getCurrentGeoLocationData(),n.getCurrentGeoLocationData());if(void 0===a)return!1;void 0===r.currentVisibleOctreesControler&&(r.currentVisibleOctreesControler=new VisibleObjectsController);var s,l=this.magoPolicy.getLod0DistInMeters(),c=this.magoPolicy.getLod1DistInMeters(),h=this.magoPolicy.getLod2DistInMeters(),d=(this.magoPolicy.getLod3DistInMeters(),this.magoPolicy.getLod4DistInMeters(),this.magoPolicy.getLod5DistInMeters()),u=!1;if(void 0===this.myCameraRelative&&(this.myCameraRelative=new Camera),this.myCameraRelative.frustum.copyParametersFrom(this.myCameraSCX.bigFrustum),this.myCameraRelative=a.getTransformedRelativeCamera(this.sceneState.camera,this.myCameraRelative),r.currentVisibleOctreesControler.clear(),2===o)r.octree.extractLowestOctreesByLOD(r.currentVisibleOctreesControler,i,this.boundingSphere_Aux,this.myCameraRelative.position,l,c,d),u=!0;else{this.myCameraRelative.calculateFrustumsPlanes();var f=this.myCameraRelative.bigFrustum;u=r.octree.getFrustumVisibleLowestOctreesByLOD(f,r.currentVisibleOctreesControler,i,this.boundingSphere_Aux,this.myCameraRelative.position,l,c,100*h)}if(!u)return r.distToCam>10&&this.processQueue.putNodeToDeleteModelReferences(t,1),!1;this.processQueue.eraseNodeToDeleteModelReferences(t);var g=[].concat(r.currentVisibleOctreesControler.currentVisibles0,r.currentVisibleOctreesControler.currentVisibles1),p=r.getRenderSettingApplyOcclusionCulling();0===g.length?this.processQueue.putNodeToDeleteModelReferences(t,0):this.processQueue.eraseNodeToDeleteModelReferences(t);for(var m=!1,y=0,v=g.length;y6&&(M=6);for(var _=0;_0||p.motherNeoReferencesArray.length>0)&&n++,p.deleteObjectsModelReferences(e,this.vboMemoryManager),n>10)break}var a=0;for(var o in this.processQueue.nodesToDeleteLessThanLod3Map)if(void 0!==(v=this.processQueue.nodesToDeleteLessThanLod3Map[o]).data&&this.processQueue.eraseNodeToDeleteLessThanLod3(v)){if(void 0===(p=v.data.neoBuilding))continue;if(p.octree&&p.octree.deleteObjectsModelReferences(e,this.vboMemoryManager),(p.motherBlocksArray.length>0||p.motherNeoReferencesArray.length>0)&&n++,p.deleteObjectsModelReferences(e,this.vboMemoryManager),p.deleteObjectsLod2(e,this.vboMemoryManager),++a>10)break}for(var o in a=0,this.processQueue.nodesToDeleteLessThanLod4Map)if(void 0!==(v=this.processQueue.nodesToDeleteLessThanLod4Map[o]).data&&this.processQueue.eraseNodeToDeleteLessThanLod4(v)){if(void 0===(p=v.data.neoBuilding))continue;if(p.deleteObjectsModelReferences(e,this.vboMemoryManager),p.deleteObjectsLod2(e,this.vboMemoryManager),p.deleteObjectsLodMesh(e,this.vboMemoryManager,"lod3"),++a>10)break}for(var o in a=0,this.processQueue.nodesToDeleteLessThanLod5Map)if(void 0!==(v=this.processQueue.nodesToDeleteLessThanLod5Map[o]).data&&this.processQueue.eraseNodeToDeleteLessThanLod5(v)){if(void 0===(p=v.data.neoBuilding))continue;if(p.deleteObjectsModelReferences(e,this.vboMemoryManager),p.deleteObjectsLod2(e,this.vboMemoryManager),p.deleteObjectsLodMesh(e,this.vboMemoryManager,"lod3"),p.deleteObjectsLodMesh(e,this.vboMemoryManager,"lod4"),++a>10)break}a=0;var s,l=1,c=0;if(void 0===this.matrix4SC&&(this.matrix4SC=new Matrix4),c=0,l=1,this.parseQueue.parseOctreesLod0References(e,this.visibleObjControlerOctrees,this,l)&&this.selectionFbo&&(this.selectionFbo.dirty=!0),c=0,l=1,Object.keys(this.parseQueue.octreesLod0ReferencesToParseMap).length>0){for(var h=this.visibleObjControlerOctrees.currentVisibles1.length,d=0;dl));d++);if(0===c)for(var o in this.parseQueue.octreesLod0ReferencesToParseMap)if(Object.prototype.hasOwnProperty.call(this.parseQueue.octreesLod0ReferencesToParseMap,o)){var u=this.parseQueue.octreesLod0ReferencesToParseMap[o];if(this.parseQueue.parseOctreesLod0References(e,u,this),++c>l)break}c>0&&this.selectionFbo&&(this.selectionFbo.dirty=!0)}if(c=0,l=1,Object.keys(this.parseQueue.octreesLod0ModelsToParseMap).length>0){for(h=this.visibleObjControlerOctrees.currentVisibles0.length,d=0;dl)break}if(0===c)for(var o in this.parseQueue.octreesLod0ModelsToParseMap)if(Object.prototype.hasOwnProperty.call(this.parseQueue.octreesLod0ModelsToParseMap,o)){u=this.parseQueue.octreesLod0ModelsToParseMap[o];if(delete this.parseQueue.octreesLod0ModelsToParseMap[o],void 0===u.neoReferencesMotherAndIndices)continue;if(void 0===(f=u.neoReferencesMotherAndIndices.blocksList))continue;if(void 0===f.dataArraybuffer)continue;if(f.fileLoadState!==CODE.fileLoadState.LOADING_FINISHED)continue;if("v"===(p=u.neoBuildingOwner).getHeaderVersion()[0]?f.parseBlocksList(f.dataArraybuffer,this.readerWriter,p.motherBlocksArray,this):f.parseBlocksListVersioned(f.dataArraybuffer,this.readerWriter,p.motherBlocksArray,this),f.dataArraybuffer=void 0,++c>l)break}c>0&&this.selectionFbo&&(this.selectionFbo.dirty=!0)}if(c=0,l=1,Object.keys(this.parseQueue.octreesLod0ModelsToParseMap).length>0){for(h=this.visibleObjControlerOctrees.currentVisibles1.length,d=0;dl)break}if(0===c)for(var o in this.parseQueue.octreesLod0ModelsToParseMap)if(Object.prototype.hasOwnProperty.call(this.parseQueue.octreesLod0ModelsToParseMap,o)){var f;u=this.parseQueue.octreesLod0ModelsToParseMap[o];if(delete this.parseQueue.octreesLod0ModelsToParseMap[o],void 0===u.neoReferencesMotherAndIndices)continue;if(void 0===(f=u.neoReferencesMotherAndIndices.blocksList))continue;if(void 0===f.dataArraybuffer)continue;if(f.fileLoadState!==CODE.fileLoadState.LOADING_FINISHED)continue;if("v"===(p=u.neoBuildingOwner).getHeaderVersion()[0]?f.parseBlocksList(f.dataArraybuffer,this.readerWriter,p.motherBlocksArray,this):f.parseBlocksListVersioned(f.dataArraybuffer,this.readerWriter,p.motherBlocksArray,this),f.dataArraybuffer=void 0,++c>l)break}c>0&&this.selectionFbo&&(this.selectionFbo.dirty=!0)}if(c=0,l=1,Object.keys(this.parseQueue.octreesLod2LegosToParseMap).length>0){for(h=this.visibleObjControlerOctrees.currentVisibles2.length,d=0;dl)break}if(0===c)for(var o in this.parseQueue.octreesLod2LegosToParseMap)if(Object.prototype.hasOwnProperty.call(this.parseQueue.octreesLod2LegosToParseMap,o)){u=this.parseQueue.octreesLod2LegosToParseMap[o];if(this.parseQueue.octreesLod2LegosToParseMap.hasOwnProperty(o)){if(delete this.parseQueue.octreesLod2LegosToParseMap[o],void 0===u.lego)continue;u.lego.parseArrayBuffer(e,u.lego.dataArrayBuffer,this),u.lego.dataArrayBuffer=void 0,c++}if(c>l)break}c>0&&this.selectionFbo&&(this.selectionFbo.dirty=!0)}if(c=0,l=1,Object.keys(this.parseQueue.octreesPCloudToParseMap).length>0){for(h=this.visibleObjControlerOctrees.currentVisiblesAux.length,d=0;dl)break}if(0===c)for(var o in this.parseQueue.octreesPCloudToParseMap){u=this.parseQueue.octreesPCloudToParseMap[o];if(this.parseQueue.eraseOctreePCloudToParse(u)){if(void 0===u.lego)continue;u.lego.parsePointsCloudData(u.lego.dataArrayBuffer,e,this),u.lego.dataArrayBuffer=void 0,c++}if(c>l)break}c>0&&this.selectionFbo&&(this.selectionFbo.dirty=!0)}if(c=0,l=1,Object.keys(this.parseQueue.skinLegosToParseMap).length>0){var g,p,m=this.visibleObjControlerNodes.currentVisibles3.length;for(d=0;dl))break}}if(0===c)for(var o in this.parseQueue.skinLegosToParseMap)if(Object.prototype.hasOwnProperty.call(this.parseQueue.skinLegosToParseMap,o)){var v,x,b;if(void 0===(v=this.parseQueue.skinLegosToParseMap[o]).data)continue;if(void 0===(p=v.data.neoBuilding))continue;if((b=(x=p.currentLod)-3)<0)continue;if(void 0===(g=p.lodMeshesArray[b]))continue;if(this.parseQueue.skinLegosToParseMap.hasOwnProperty(g.legoKey)&&(delete this.parseQueue.skinLegosToParseMap[g.legoKey],g.parseArrayBuffer(e,g.dataArrayBuffer,this),g.dataArrayBuffer=void 0,c++),c>l)break}}var C=this.tinTerrainManager.currentVisibles_terrName_geoCoords_map;for(var o in C)void 0!==(s=this.tinTerrainManager.currentTerrainsMap[o])&&this.parseQueue.eraseTinTerrainToParse(s)&&s.parseData(s.dataArrayBuffer)},MagoManager.prototype.prepareVisibleOctreesSortedByDistancePointsCloudType=function(e,t,i){if(!(Object.keys(this.loadQueue.lod2PCloudDataMap).length>5)){var o=i,r=[].concat(t.currentVisibles0,t.currentVisibles1,t.currentVisibles2,t.currentVisibles3);if(void 0!==r)for(var n,a,s,l,c=this.readerWriter.geometryDataPath,h=0,d=r.length;h5)return}}}},MagoManager.prototype.prepareVisibleOctreesSortedByDistance=function(e,t,i){if(!this.fileRequestControler.isFullPlusModelReferences(i)){var o,r,n,a,s=this.readerWriter.geometryDataPath,l=[].concat(t.currentVisibles0,t.currentVisibles1);this.thereAreUrgentOctrees=!1;for(var c=0,h=0,d=l.length;h2)return}}}}},MagoManager.prototype.prepareVisibleOctreesSortedByDistanceLOD2=function(e,t,i){if(!(Object.keys(this.loadQueue.lod2SkinDataMap).length>5)){var o=i;if(void 0!==t)for(var r,n,a,s=this.readerWriter.geometryDataPath,l=0,c=t.length;l5)return}}}},MagoManager.prototype.checkChangesHistoryMovements=function(e){for(var t,i,o,r,n,a,s,l,c,h,d,u=e.length,f=0;f0){this.checkChangesHistoryMovements(n.currentVisibles0),this.checkChangesHistoryColors(n.currentVisibles0),void 0===this.noiseTexture&&(this.noiseTexture=genNoiseTextureRGBA(e,4,4,this.pixels)),x=(a=this.postFxShadersManager.getShader("modelRefSsao")).program,e.useProgram(x),e.uniform1i(a.bApplySpecularLighting_loc,!0),e.enableVertexAttribArray(a.texCoord2_loc),e.enableVertexAttribArray(a.position3_loc),e.enableVertexAttribArray(a.normal3_loc),a.bindUniformGenerals(),e.uniform1i(a.textureFlipYAxis_loc,this.sceneState.textureFlipYAxis),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.depthFboNeo.colorBuffer),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,this.noiseTexture);this.renderer.renderNodes(e,n.currentVisibles0,this,a,!1,r,0,0),a&&(-1!==a.texCoord2_loc&&e.disableVertexAttribArray(a.texCoord2_loc),-1!==a.position3_loc&&e.disableVertexAttribArray(a.position3_loc),-1!==a.normal3_loc&&e.disableVertexAttribArray(a.normal3_loc),-1!==a.color4_loc&&e.disableVertexAttribArray(a.color4_loc)),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,null),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,null),e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,null)}var d=n.currentVisibles2.length,u=n.currentVisibles3.length;if((d>0||h>0||u>0)&&(this.checkChangesHistoryColors(n.currentVisibles2),x=(a=this.postFxShadersManager.getShader("lodBuildingSsao")).program,e.useProgram(x),e.uniform1i(a.bApplySpecularLighting_loc,!0),e.enableVertexAttribArray(a.position3_loc),e.enableVertexAttribArray(a.normal3_loc),e.enableVertexAttribArray(a.color4_loc),a.bindUniformGenerals(),e.uniform1i(a.textureFlipYAxis_loc,this.sceneState.textureFlipYAxis),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.depthFboNeo.colorBuffer),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,this.noiseTexture),e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,this.textureAux_1x1),this.renderer.renderNeoBuildingsLOD2AsimetricVersion(e,n.currentVisibles0,this,a,!1,r),this.renderer.renderNeoBuildingsLOD2AsimetricVersion(e,n.currentVisibles2,this,a,!1,r),this.renderer.renderNeoBuildingsLowLOD(e,n.currentVisibles3,this,a,!1,r),a&&(-1!==a.texCoord2_loc&&e.disableVertexAttribArray(a.texCoord2_loc),-1!==a.position3_loc&&e.disableVertexAttribArray(a.position3_loc),-1!==a.normal3_loc&&e.disableVertexAttribArray(a.normal3_loc),-1!==a.color4_loc&&e.disableVertexAttribArray(a.color4_loc)),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,null),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,null),e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,null)),this.nodeSelected){if(this.magoPolicy.getObjectMoveMode()===CODE.moveMode.OBJECT&&this.objectSelected){l=this.nodeSelected;var f=this.getNodeGeoLocDataManager(l);s=this.buildingSelected;var g=f.getCurrentGeoLocationData(),p=this.octreeSelected.neoReferencesMotherAndIndices,m=e.POINTS;m=e.TRIANGLES;var y=0,v=0,x=(a=this.postFxShadersManager.getModelRefSilhouetteShader()).program;e.useProgram(x),e.enableVertexAttribArray(a.position3_loc),e.uniformMatrix4fv(a.buildingRotMatrix_loc,!1,g.rotMatrix._floatArrays),e.uniformMatrix4fv(a.modelViewProjectionMatrix4RelToEye_loc,!1,this.sceneState.modelViewProjRelToEyeMatrix._floatArrays),e.uniformMatrix4fv(a.ModelViewMatrixRelToEye_loc,!1,this.sceneState.modelViewRelToEyeMatrix._floatArrays),e.uniform3fv(a.cameraPosHIGH_loc,this.sceneState.encodedCamPosHigh),e.uniform3fv(a.cameraPosLOW_loc,this.sceneState.encodedCamPosLow),e.uniform3fv(a.buildingPosHIGH_loc,g.positionHIGH),e.uniform3fv(a.buildingPosLOW_loc,g.positionLOW),e.uniform4fv(a.color4Aux_loc,[0,1,0,1]),e.uniform2fv(a.screenSize_loc,[this.sceneState.drawingBufferWidth,this.sceneState.drawingBufferHeight]),e.uniformMatrix4fv(a.ProjectionMatrix_loc,!1,this.sceneState.projectionMatrix._floatArrays),e.enable(e.STENCIL_TEST),e.disable(e.POLYGON_OFFSET_FILL),e.disable(e.CULL_FACE),e.disable(e.DEPTH_TEST),e.depthRange(0,0),e.stencilFunc(e.EQUAL,0,1),e.stencilOp(e.KEEP,e.KEEP,e.REPLACE),m=e.TRIANGLES;var b=.003;e.uniform2fv(a.camSpacePixelTranslation_loc,[b,b]),this.renderer.renderNeoReferenceAsimetricVersionColorSelection(e,this.objectSelected,p,s,this,a,y,v,m),e.uniform2fv(a.camSpacePixelTranslation_loc,[-b,b]),this.renderer.renderNeoReferenceAsimetricVersionColorSelection(e,this.objectSelected,p,s,this,a,y,v,m),e.uniform2fv(a.camSpacePixelTranslation_loc,[b,-b]),this.renderer.renderNeoReferenceAsimetricVersionColorSelection(e,this.objectSelected,p,s,this,a,y,v,m),e.uniform2fv(a.camSpacePixelTranslation_loc,[-b,-b]),this.renderer.renderNeoReferenceAsimetricVersionColorSelection(e,this.objectSelected,p,s,this,a,y,v,m),e.enable(e.DEPTH_TEST),e.disable(e.STENCIL_TEST),e.depthRange(0,1),e.disableVertexAttribArray(a.position3_loc),a&&(-1!==a.texCoord2_loc&&e.disableVertexAttribArray(a.texCoord2_loc),-1!==a.position3_loc&&e.disableVertexAttribArray(a.position3_loc),-1!==a.normal3_loc&&e.disableVertexAttribArray(a.normal3_loc),-1!==a.color4_loc&&e.disableVertexAttribArray(a.color4_loc))}if(this.magoPolicy.getObjectMoveMode()===CODE.moveMode.ALL&&this.buildingSelected){l=this.nodeSelected;f=this.getNodeGeoLocDataManager(l);s=this.buildingSelected;g=f.getCurrentGeoLocationData(),m=e.POINTS;m=e.TRIANGLES;y=0,v=0;var C=s.getCurrentSkin();if(void 0!==C){x=(a=this.postFxShadersManager.getModelRefSilhouetteShader()).program;e.useProgram(x),e.enableVertexAttribArray(a.position3_loc),e.uniformMatrix4fv(a.buildingRotMatrix_loc,!1,g.rotMatrix._floatArrays),e.uniformMatrix4fv(a.modelViewProjectionMatrix4RelToEye_loc,!1,this.sceneState.modelViewProjRelToEyeMatrix._floatArrays),e.uniformMatrix4fv(a.ModelViewMatrixRelToEye_loc,!1,this.sceneState.modelViewRelToEyeMatrix._floatArrays),e.uniform3fv(a.cameraPosHIGH_loc,this.sceneState.encodedCamPosHigh),e.uniform3fv(a.cameraPosLOW_loc,this.sceneState.encodedCamPosLow),e.uniform3fv(a.buildingPosHIGH_loc,g.positionHIGH),e.uniform3fv(a.buildingPosLOW_loc,g.positionLOW),e.uniform4fv(a.color4Aux_loc,[0,1,0,1]),e.uniform2fv(a.screenSize_loc,[this.sceneState.drawingBufferWidth,this.sceneState.drawingBufferHeight]),e.uniformMatrix4fv(a.ProjectionMatrix_loc,!1,this.sceneState.projectionMatrix._floatArrays),e.uniform3fv(a.aditionalMov_loc,[0,0,0]),e.enable(e.STENCIL_TEST),e.disable(e.POLYGON_OFFSET_FILL),e.disable(e.CULL_FACE),e.disable(e.DEPTH_TEST),e.depthRange(0,0),e.stencilFunc(e.EQUAL,0,1),e.stencilOp(e.KEEP,e.REPLACE,e.REPLACE),m=e.TRIANGLES,e.uniform1i(a.refMatrixType_loc,0);b=.004;e.uniform2fv(a.camSpacePixelTranslation_loc,[b,b]),this.renderer.renderLodBuildingColorSelection(e,C,this,a),e.uniform2fv(a.camSpacePixelTranslation_loc,[-b,b]),this.renderer.renderLodBuildingColorSelection(e,C,this,a),e.uniform2fv(a.camSpacePixelTranslation_loc,[b,-b]),this.renderer.renderLodBuildingColorSelection(e,C,this,a),e.uniform2fv(a.camSpacePixelTranslation_loc,[-b,-b]),this.renderer.renderLodBuildingColorSelection(e,C,this,a),e.enable(e.DEPTH_TEST),e.disable(e.STENCIL_TEST),e.depthRange(0,1),e.disableVertexAttribArray(a.position3_loc),a&&(-1!==a.texCoord2_loc&&e.disableVertexAttribArray(a.texCoord2_loc),-1!==a.position3_loc&&e.disableVertexAttribArray(a.position3_loc),-1!==a.normal3_loc&&e.disableVertexAttribArray(a.normal3_loc),-1!==a.color4_loc&&e.disableVertexAttribArray(a.color4_loc))}}if(this.magoPolicy.getShowOrigin()){c=[l=this.nodeSelected];this.renderAxisNodes(e,c,!0,r)}}if(this.magoPolicy.getShowBoundingBox()){this.renderBoundingBoxesNodes(e,this.visibleObjControlerNodes.currentVisibles0,void 0,!0),this.renderBoundingBoxesNodes(e,this.visibleObjControlerNodes.currentVisibles2,void 0,!0),this.renderBoundingBoxesNodes(e,this.visibleObjControlerNodes.currentVisibles3,void 0,!0)}var M=this.objMarkerManager.objectMarkerArray.length;if(M>0){void 0===this.pin.positionBuffer&&this.pin.createPinCenterBottom(e),x=(a=this.postFxShadersManager.pFx_shaders_array[13]).program,e.useProgram(x),e.uniformMatrix4fv(a.modelViewProjectionMatrix4RelToEye_loc,!1,this.sceneState.modelViewProjRelToEyeMatrix._floatArrays),e.uniform3fv(a.cameraPosHIGH_loc,this.sceneState.encodedCamPosHigh),e.uniform3fv(a.cameraPosLOW_loc,this.sceneState.encodedCamPosLow),e.uniformMatrix4fv(a.buildingRotMatrix_loc,!1,this.sceneState.modelViewRelToEyeMatrixInv._floatArrays),e.uniform1i(a.textureFlipYAxis_loc,this.sceneState.textureFlipYAxis),e.uniform1i(a.texture_loc,0),e.enableVertexAttribArray(a.texCoord2_loc),e.enableVertexAttribArray(a.position3_loc),e.activeTexture(e.TEXTURE0),e.depthRange(0,0),e.bindBuffer(e.ARRAY_BUFFER,this.pin.positionBuffer),e.vertexAttribPointer(a.position3_loc,3,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,this.pin.texcoordBuffer),e.vertexAttribPointer(a.texCoord2_loc,2,e.FLOAT,!1,0,0);for(var _=0,A=0;A=this.pin.texturesArray.length&&(_=0);var R=this.pin.texturesArray[_],P=this.objMarkerManager.objectMarkerArray[A].geoLocationData;e.bindTexture(e.TEXTURE_2D,R.texId),e.uniform3fv(a.buildingPosHIGH_loc,P.positionHIGH),e.uniform3fv(a.buildingPosLOW_loc,P.positionLOW),e.drawArrays(e.TRIANGLES,0,6),_++}e.depthRange(0,1),e.useProgram(null),e.bindTexture(e.TEXTURE_2D,null),e.disableVertexAttribArray(a.texCoord2_loc),e.disableVertexAttribArray(a.position3_loc)}if(void 0!==this.tinTerrainManager){x=(a=this.postFxShadersManager.getShader("tinTerrain")).program,e.useProgram(x),e.enableVertexAttribArray(a.position3_loc),e.enableVertexAttribArray(a.texCoord2_loc),a.bindUniformGenerals();var T=this.pin.texturesArray[4];e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,T.texId),e.uniform1i(a.bIsMakingDepth_loc,!1),e.uniform1i(a.hasTexture_loc,!0),e.uniform4fv(a.oneColor4_loc,[.5,.5,.5,1]);var L,S=this.tinTerrainManager.currentTerrainsMap,w=this.tinTerrainManager.currentVisibles_terrName_geoCoords_map;for(var E in w)if(void 0!==(L=S[E])&&void 0!==L.vboKeyContainer&&0!==L.vboKeyContainer.vboCacheKeysArray.length)if(void 0!==L.texture){e.bindTexture(e.TEXTURE_2D,L.texture.texId),e.uniform3fv(a.buildingPosHIGH_loc,L.terrainPositionHIGH),e.uniform3fv(a.buildingPosLOW_loc,L.terrainPositionLOW);var D=L.vboKeyContainer.vboCacheKeysArray[0];if(D.isReadyPositions(e,this.vboMemoryManager)&&D.isReadyTexCoords(e,this.vboMemoryManager)&&D.isReadyFaces(e,this.vboMemoryManager)){e.bindBuffer(e.ARRAY_BUFFER,D.meshVertexCacheKey),e.vertexAttribPointer(a.position3_loc,3,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,D.meshTexcoordsCacheKey),e.vertexAttribPointer(a.texCoord2_loc,2,e.FLOAT,!1,0,0);var I=D.indicesCount;e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,D.meshFacesCacheKey),e.drawElements(e.TRIANGLES,I,e.UNSIGNED_SHORT,0)}}else{L.texture=new Texture;var O="\\images\\ko\\funny_"+L.depth+".jpg";this.readerWriter.readLegoSimpleBuildingTexture(e,O,L.texture,this)}a&&(-1!==a.texCoord2_loc&&e.disableVertexAttribArray(a.texCoord2_loc),-1!==a.position3_loc&&e.disableVertexAttribArray(a.position3_loc),-1!==a.normal3_loc&&e.disableVertexAttribArray(a.normal3_loc),-1!==a.color4_loc&&e.disableVertexAttribArray(a.color4_loc))}var V=this.cctvList.getCCTVCount();if(V>0){x=(a=this.postFxShadersManager.getShader("modelRefSsao")).program,e.useProgram(x),e.uniform1i(a.bApplySpecularLighting_loc,!1),e.disableVertexAttribArray(a.texCoord2_loc),e.enableVertexAttribArray(a.position3_loc),e.enableVertexAttribArray(a.normal3_loc),a.bindUniformGenerals(),e.uniform1i(a.textureFlipYAxis_loc,this.sceneState.textureFlipYAxis),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.depthFboNeo.colorBuffer),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,this.noiseTexture),e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,this.textureAux_1x1),this.renderer.renderTexture=!1;var B=(new Date).getTime();for(A=0;A0&&(x=(a=this.postFxShadersManager.getShader("pointsCloud")).program,e.useProgram(x),e.enableVertexAttribArray(a.position3_loc),e.enableVertexAttribArray(a.color4_loc),a.bindUniformGenerals(),this.renderer.renderNeoBuildingsPCloud(e,this.visibleObjControlerNodes.currentVisiblesAux,this,a,!1,r),a&&(-1!==a.texCoord2_loc&&e.disableVertexAttribArray(a.texCoord2_loc),-1!==a.position3_loc&&e.disableVertexAttribArray(a.position3_loc),-1!==a.normal3_loc&&e.disableVertexAttribArray(a.normal3_loc),-1!==a.color4_loc&&e.disableVertexAttribArray(a.color4_loc)))}a&&(-1!==a.texCoord2_loc&&e.disableVertexAttribArray(a.texCoord2_loc),-1!==a.position3_loc&&e.disableVertexAttribArray(a.position3_loc),-1!==a.normal3_loc&&e.disableVertexAttribArray(a.normal3_loc),-1!==a.color4_loc&&e.disableVertexAttribArray(a.color4_loc)),e.depthRange(0,1)},MagoManager.prototype.drawCCTVNames=function(e){var t=document.getElementById("objectLabel");if(void 0!==t){t.style.opacity=1,t.width=this.sceneState.drawingBufferWidth,t.height=this.sceneState.drawingBufferHeight;var i=t.getContext("2d");i.strokeStyle="DarkSlateGray",i.fillStyle="PapayaWhip",i.lineWidth=4,i.font="20px Arial",i.textAlign="center",i.fillRect(0,0,i.canvas.width,i.canvas.height),i.save(),i.clearRect(0,0,i.canvas.width,i.canvas.height);i.measureText("M").width;for(var o,r,n,a=this.sceneState.gl,s=e.length,l=0;l=0&&r.y>=0&&(i.font="13px Arial",i.strokeText(n.name,r.x,r.y),i.fillText(n.name,r.x,r.y));i.restore()}},MagoManager.prototype.renderRenderables=function(e,t,i,o,r,n){var a,s,l;if(e.frontFace(e.CCW),e.depthRange(0,1),e.enable(e.DEPTH_TEST),!1,0===r&&(e.disable(e.BLEND),this.depthRenderLowestOctreeAsimetricVersion(e,r,n),this.magoPolicy.getShowOrigin()&&void 0!==this.nodeSelected)){var c=[l=this.nodeSelected];this.renderAxisNodes(e,c,!0,r)}if(1===r){var h=n.currentVisibles0.length;if(h>0){this.checkChangesHistoryMovements(n.currentVisibles0),this.checkChangesHistoryColors(n.currentVisibles0),void 0===this.noiseTexture&&(this.noiseTexture=genNoiseTextureRGBA(e,4,4,this.pixels)),x=(a=this.postFxShadersManager.getShader("modelRefSsao")).program,e.useProgram(x),e.uniform1i(a.bApplySpecularLighting_loc,!1),e.enableVertexAttribArray(a.texCoord2_loc),e.enableVertexAttribArray(a.position3_loc),e.enableVertexAttribArray(a.normal3_loc),a.bindUniformGenerals(),e.uniform1i(a.textureFlipYAxis_loc,this.sceneState.textureFlipYAxis),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.depthFboNeo.colorBuffer),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,this.noiseTexture);this.renderer.renderNodes(e,n.currentVisibles0,this,a,!1,r,0,0),a&&(-1!==a.texCoord2_loc&&e.disableVertexAttribArray(a.texCoord2_loc),-1!==a.position3_loc&&e.disableVertexAttribArray(a.position3_loc),-1!==a.normal3_loc&&e.disableVertexAttribArray(a.normal3_loc),-1!==a.color4_loc&&e.disableVertexAttribArray(a.color4_loc)),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,null),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,null),e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,null)}var d=n.currentVisibles2.length,u=n.currentVisibles3.length;if((d>0||h>0||u>0)&&(this.checkChangesHistoryColors(n.currentVisibles2),x=(a=this.postFxShadersManager.getShader("lodBuildingSsao")).program,e.useProgram(x),e.uniform1i(a.bApplySpecularLighting_loc,!1),e.enableVertexAttribArray(a.position3_loc),e.enableVertexAttribArray(a.normal3_loc),e.enableVertexAttribArray(a.color4_loc),a.bindUniformGenerals(),e.uniform1i(a.textureFlipYAxis_loc,this.sceneState.textureFlipYAxis),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.depthFboNeo.colorBuffer),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,this.noiseTexture),e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,this.textureAux_1x1),this.renderer.renderNeoBuildingsLOD2AsimetricVersion(e,n.currentVisibles0,this,a,!1,r),this.renderer.renderNeoBuildingsLOD2AsimetricVersion(e,n.currentVisibles2,this,a,!1,r),this.renderer.renderNeoBuildingsLowLOD(e,n.currentVisibles3,this,a,!1,r),a&&(-1!==a.texCoord2_loc&&e.disableVertexAttribArray(a.texCoord2_loc),-1!==a.position3_loc&&e.disableVertexAttribArray(a.position3_loc),-1!==a.normal3_loc&&e.disableVertexAttribArray(a.normal3_loc),-1!==a.color4_loc&&e.disableVertexAttribArray(a.color4_loc)),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,null),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,null),e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,null)),this.nodeSelected){if(this.magoPolicy.getObjectMoveMode()===CODE.moveMode.OBJECT&&this.objectSelected){l=this.nodeSelected;var f=this.getNodeGeoLocDataManager(l);s=this.buildingSelected;var g=f.getCurrentGeoLocationData(),p=this.octreeSelected.neoReferencesMotherAndIndices,m=e.POINTS;m=e.TRIANGLES;var y=0,v=0,x=(a=this.postFxShadersManager.getModelRefSilhouetteShader()).program;e.useProgram(x),e.enableVertexAttribArray(a.position3_loc),e.uniformMatrix4fv(a.buildingRotMatrix_loc,!1,g.rotMatrix._floatArrays),e.uniformMatrix4fv(a.modelViewProjectionMatrix4RelToEye_loc,!1,this.sceneState.modelViewProjRelToEyeMatrix._floatArrays),e.uniformMatrix4fv(a.ModelViewMatrixRelToEye_loc,!1,this.sceneState.modelViewRelToEyeMatrix._floatArrays),e.uniform3fv(a.cameraPosHIGH_loc,this.sceneState.encodedCamPosHigh),e.uniform3fv(a.cameraPosLOW_loc,this.sceneState.encodedCamPosLow),e.uniform3fv(a.buildingPosHIGH_loc,g.positionHIGH),e.uniform3fv(a.buildingPosLOW_loc,g.positionLOW),e.uniform4fv(a.color4Aux_loc,[0,1,0,1]),e.uniform2fv(a.screenSize_loc,[this.sceneState.drawingBufferWidth,this.sceneState.drawingBufferHeight]),e.uniformMatrix4fv(a.ProjectionMatrix_loc,!1,this.sceneState.projectionMatrix._floatArrays),e.enable(e.STENCIL_TEST),e.disable(e.POLYGON_OFFSET_FILL),e.disable(e.CULL_FACE),e.disable(e.DEPTH_TEST),e.depthRange(0,0),e.stencilFunc(e.EQUAL,0,1),e.stencilOp(e.KEEP,e.KEEP,e.REPLACE),m=e.TRIANGLES;var b=.003;e.uniform2fv(a.camSpacePixelTranslation_loc,[b,b]),this.renderer.renderNeoReferenceAsimetricVersionColorSelection(e,this.objectSelected,p,s,this,a,y,v,m),e.uniform2fv(a.camSpacePixelTranslation_loc,[-b,b]),this.renderer.renderNeoReferenceAsimetricVersionColorSelection(e,this.objectSelected,p,s,this,a,y,v,m),e.uniform2fv(a.camSpacePixelTranslation_loc,[b,-b]),this.renderer.renderNeoReferenceAsimetricVersionColorSelection(e,this.objectSelected,p,s,this,a,y,v,m),e.uniform2fv(a.camSpacePixelTranslation_loc,[-b,-b]),this.renderer.renderNeoReferenceAsimetricVersionColorSelection(e,this.objectSelected,p,s,this,a,y,v,m),e.enable(e.DEPTH_TEST),e.disable(e.STENCIL_TEST),e.depthRange(0,1),e.disableVertexAttribArray(a.position3_loc),a&&(-1!==a.texCoord2_loc&&e.disableVertexAttribArray(a.texCoord2_loc),-1!==a.position3_loc&&e.disableVertexAttribArray(a.position3_loc),-1!==a.normal3_loc&&e.disableVertexAttribArray(a.normal3_loc),-1!==a.color4_loc&&e.disableVertexAttribArray(a.color4_loc))}if(this.magoPolicy.getObjectMoveMode()===CODE.moveMode.ALL&&this.buildingSelected){l=this.nodeSelected;f=this.getNodeGeoLocDataManager(l);s=this.buildingSelected;g=f.getCurrentGeoLocationData(),m=e.POINTS;m=e.TRIANGLES;y=0,v=0;var C=s.getCurrentSkin();if(void 0!==C){x=(a=this.postFxShadersManager.getModelRefSilhouetteShader()).program;e.useProgram(x),e.enableVertexAttribArray(a.position3_loc),e.uniformMatrix4fv(a.buildingRotMatrix_loc,!1,g.rotMatrix._floatArrays),e.uniformMatrix4fv(a.modelViewProjectionMatrix4RelToEye_loc,!1,this.sceneState.modelViewProjRelToEyeMatrix._floatArrays),e.uniformMatrix4fv(a.ModelViewMatrixRelToEye_loc,!1,this.sceneState.modelViewRelToEyeMatrix._floatArrays),e.uniform3fv(a.cameraPosHIGH_loc,this.sceneState.encodedCamPosHigh),e.uniform3fv(a.cameraPosLOW_loc,this.sceneState.encodedCamPosLow),e.uniform3fv(a.buildingPosHIGH_loc,g.positionHIGH),e.uniform3fv(a.buildingPosLOW_loc,g.positionLOW),e.uniform4fv(a.color4Aux_loc,[0,1,0,1]),e.uniform2fv(a.screenSize_loc,[this.sceneState.drawingBufferWidth,this.sceneState.drawingBufferHeight]),e.uniformMatrix4fv(a.ProjectionMatrix_loc,!1,this.sceneState.projectionMatrix._floatArrays),e.uniform3fv(a.aditionalMov_loc,[0,0,0]),e.enable(e.STENCIL_TEST),e.disable(e.POLYGON_OFFSET_FILL),e.disable(e.CULL_FACE),e.disable(e.DEPTH_TEST),e.depthRange(0,0),e.stencilFunc(e.EQUAL,0,1),e.stencilOp(e.KEEP,e.REPLACE,e.REPLACE),m=e.TRIANGLES,e.uniform1i(a.refMatrixType_loc,0);b=.004;e.uniform2fv(a.camSpacePixelTranslation_loc,[b,b]),this.renderer.renderLodBuildingColorSelection(e,C,this,a),e.uniform2fv(a.camSpacePixelTranslation_loc,[-b,b]),this.renderer.renderLodBuildingColorSelection(e,C,this,a),e.uniform2fv(a.camSpacePixelTranslation_loc,[b,-b]),this.renderer.renderLodBuildingColorSelection(e,C,this,a),e.uniform2fv(a.camSpacePixelTranslation_loc,[-b,-b]),this.renderer.renderLodBuildingColorSelection(e,C,this,a),e.enable(e.DEPTH_TEST),e.disable(e.STENCIL_TEST),e.depthRange(0,1),e.disableVertexAttribArray(a.position3_loc),a&&(-1!==a.texCoord2_loc&&e.disableVertexAttribArray(a.texCoord2_loc),-1!==a.position3_loc&&e.disableVertexAttribArray(a.position3_loc),-1!==a.normal3_loc&&e.disableVertexAttribArray(a.normal3_loc),-1!==a.color4_loc&&e.disableVertexAttribArray(a.color4_loc))}}if(this.magoPolicy.getShowOrigin()){c=[l=this.nodeSelected];this.renderAxisNodes(e,c,!0,r)}}if(this.magoPolicy.getShowBoundingBox()){this.renderBoundingBoxesNodes(e,this.visibleObjControlerNodes.currentVisibles0,void 0,!0),this.renderBoundingBoxesNodes(e,this.visibleObjControlerNodes.currentVisibles2,void 0,!0)}var M=this.objMarkerManager.objectMarkerArray.length;if(M>0){void 0===this.pin.positionBuffer&&this.pin.createPinCenterBottom(e),x=(a=this.postFxShadersManager.pFx_shaders_array[13]).program,e.useProgram(x),e.uniformMatrix4fv(a.modelViewProjectionMatrix4RelToEye_loc,!1,this.sceneState.modelViewProjRelToEyeMatrix._floatArrays),e.uniform3fv(a.cameraPosHIGH_loc,this.sceneState.encodedCamPosHigh),e.uniform3fv(a.cameraPosLOW_loc,this.sceneState.encodedCamPosLow),e.uniformMatrix4fv(a.buildingRotMatrix_loc,!1,this.sceneState.modelViewRelToEyeMatrixInv._floatArrays),e.uniform1i(a.textureFlipYAxis_loc,this.sceneState.textureFlipYAxis),e.uniform1i(a.texture_loc,0),e.enableVertexAttribArray(a.texCoord2_loc),e.enableVertexAttribArray(a.position3_loc),e.activeTexture(e.TEXTURE0),e.depthRange(0,0),e.bindBuffer(e.ARRAY_BUFFER,this.pin.positionBuffer),e.vertexAttribPointer(a.position3_loc,3,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,this.pin.texcoordBuffer),e.vertexAttribPointer(a.texCoord2_loc,2,e.FLOAT,!1,0,0);for(var _=0,A=0;A=this.pin.texturesArray.length&&(_=0);var R=this.pin.texturesArray[_],P=this.objMarkerManager.objectMarkerArray[A].geoLocationData;e.bindTexture(e.TEXTURE_2D,R.texId),e.uniform3fv(a.buildingPosHIGH_loc,P.positionHIGH),e.uniform3fv(a.buildingPosLOW_loc,P.positionLOW),e.drawArrays(e.TRIANGLES,0,6),_++}e.depthRange(0,1),e.useProgram(null),e.bindTexture(e.TEXTURE_2D,null),e.disableVertexAttribArray(a.texCoord2_loc),e.disableVertexAttribArray(a.position3_loc)}if(void 0!==this.tinTerrainManager){x=(a=this.postFxShadersManager.getShader("tinTerrain")).program,e.useProgram(x),e.enableVertexAttribArray(a.position3_loc),e.enableVertexAttribArray(a.texCoord2_loc),a.bindUniformGenerals();var T=this.pin.texturesArray[4];e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,T.texId),e.uniform1i(a.hasTexture_loc,!0),e.uniform4fv(a.oneColor4_loc,[.5,.5,.5,1]);var L,S=this.tinTerrainManager.currentTerrainsMap,w=this.tinTerrainManager.currentVisibles_terrName_geoCoords_map;for(var E in w)if(void 0!==(L=S[E])&&void 0!==L.vboKeyContainer&&0!==L.vboKeyContainer.vboCacheKeysArray.length)if(void 0!==L.texture){e.bindTexture(e.TEXTURE_2D,L.texture.texId),e.uniform3fv(a.buildingPosHIGH_loc,L.terrainPositionHIGH),e.uniform3fv(a.buildingPosLOW_loc,L.terrainPositionLOW);var D=L.vboKeyContainer.vboCacheKeysArray[0];if(D.isReadyPositions(e,this.vboMemoryManager)&&D.isReadyTexCoords(e,this.vboMemoryManager)&&D.isReadyFaces(e,this.vboMemoryManager)){e.bindBuffer(e.ARRAY_BUFFER,D.meshVertexCacheKey),e.vertexAttribPointer(a.position3_loc,3,e.FLOAT,!1,0,0),e.bindBuffer(e.ARRAY_BUFFER,D.meshTexcoordsCacheKey),e.vertexAttribPointer(a.texCoord2_loc,2,e.FLOAT,!1,0,0);var I=D.indicesCount;e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,D.meshFacesCacheKey),e.drawElements(e.TRIANGLES,I,e.UNSIGNED_SHORT,0)}}else{L.texture=new Texture;var O="\\images\\ko\\funny_"+L.depth+".jpg";this.readerWriter.readLegoSimpleBuildingTexture(e,O,L.texture,this)}a&&(-1!==a.texCoord2_loc&&e.disableVertexAttribArray(a.texCoord2_loc),-1!==a.position3_loc&&e.disableVertexAttribArray(a.position3_loc),-1!==a.normal3_loc&&e.disableVertexAttribArray(a.normal3_loc),-1!==a.color4_loc&&e.disableVertexAttribArray(a.color4_loc))}}a&&(-1!==a.texCoord2_loc&&e.disableVertexAttribArray(a.texCoord2_loc),-1!==a.position3_loc&&e.disableVertexAttribArray(a.position3_loc),-1!==a.normal3_loc&&e.disableVertexAttribArray(a.normal3_loc),-1!==a.color4_loc&&e.disableVertexAttribArray(a.color4_loc))},MagoManager.prototype.renderBoundingBoxesNodes=function(e,t,i,o){var r,n=this.postFxShadersManager.getTriPolyhedronShader(),a=n.program;e.enable(e.BLEND),e.frontFace(e.CCW),e.useProgram(a),e.enableVertexAttribArray(n.position3_loc),e.enableVertexAttribArray(n.normal3_loc),e.disableVertexAttribArray(n.color4_loc),e.uniformMatrix4fv(n.modelViewProjectionMatrix4RelToEye_loc,!1,this.sceneState.modelViewProjRelToEyeMatrix._floatArrays),e.uniformMatrix4fv(n.modelViewMatrix4RelToEye_loc,!1,this.sceneState.modelViewRelToEyeMatrix._floatArrays),e.uniformMatrix4fv(n.modelViewMatrix4_loc,!1,this.sceneState.modelViewMatrix._floatArrays),e.uniformMatrix4fv(n.projectionMatrix4_loc,!1,this.sceneState.projectionMatrix._floatArrays),e.uniform3fv(n.cameraPosHIGH_loc,this.sceneState.encodedCamPosHigh),e.uniform3fv(n.cameraPosLOW_loc,this.sceneState.encodedCamPosLow),e.uniform1f(n.near_loc,this.sceneState.camera.frustum.near),e.uniform1f(n.far_loc,this.sceneState.camera.frustum.far),e.uniform1i(n.bApplySsao_loc,!1),e.uniformMatrix4fv(n.normalMatrix4_loc,!1,this.sceneState.normalMatrix4._floatArrays),e.uniform1i(n.hasAditionalMov_loc,!0),e.uniform3fv(n.aditionalMov_loc,[0,0,0]),e.uniform1i(n.bScale_loc,!0);var s;e.uniform1i(n.bUse1Color_loc,!0),i?e.uniform4fv(n.oneColor4_loc,[i.r,i.g,i.b,1]):e.uniform4fv(n.oneColor4_loc,[1,0,1,1]),e.uniform1i(n.depthTex_loc,0),e.uniform1i(n.noiseTex_loc,1),e.uniform1i(n.diffuseTex_loc,2),e.uniform1f(n.fov_loc,this.sceneState.camera.frustum.fovyRad),e.uniform1f(n.aspectRatio_loc,this.sceneState.camera.frustum.aspectRatio),e.uniform1f(n.screenWidth_loc,this.sceneState.drawingBufferWidth),e.uniform1f(n.screenHeight_loc,this.sceneState.drawingBufferHeight),e.uniform2fv(n.noiseScale2_loc,[this.depthFboNeo.width/this.noiseTexture.width,this.depthFboNeo.height/this.noiseTexture.height]),e.uniform3fv(n.kernel16_loc,this.kernel),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.depthFboNeo.colorBuffer),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,this.noiseTexture);for(var l=t.length,c=0;c0){r=(o=this.postFxShadersManager.pFx_shaders_array[3]).program,e.useProgram(r),e.enableVertexAttribArray(o.position3_loc),e.uniformMatrix4fv(o.modelViewProjectionMatrix4RelToEye_loc,!1,this.sceneState.modelViewProjRelToEyeMatrix._floatArrays),e.uniformMatrix4fv(o.modelViewMatrix4RelToEye_loc,!1,this.sceneState.modelViewRelToEyeMatrix._floatArrays),e.uniformMatrix4fv(o.modelViewMatrix4_loc,!1,this.sceneState.modelViewMatrix._floatArrays),e.uniformMatrix4fv(o.projectionMatrix4_loc,!1,this.sceneState.projectionMatrix._floatArrays),e.uniform3fv(o.cameraPosHIGH_loc,this.sceneState.encodedCamPosHigh),e.uniform3fv(o.cameraPosLOW_loc,this.sceneState.encodedCamPosLow),e.uniform1f(o.near_loc,this.sceneState.camera.frustum.near),e.uniform1f(o.far_loc,this.sceneState.camera.frustum.far);this.renderer.renderNodes(e,i.currentVisibles0,this,o,!1,t,0,0,0),-1!==o.position3_loc&&e.disableVertexAttribArray(o.position3_loc)}if((i.currentVisibles2.length>0||n>0)&&(r=(o=this.postFxShadersManager.pFx_shaders_array[7]).program,e.useProgram(r),e.enableVertexAttribArray(o.position3_loc),e.uniformMatrix4fv(o.modelViewProjectionMatrix4RelToEye_loc,!1,this.sceneState.modelViewProjRelToEyeMatrix._floatArrays),e.uniformMatrix4fv(o.modelViewMatrix4RelToEye_loc,!1,this.sceneState.modelViewRelToEyeMatrix._floatArrays),e.uniformMatrix4fv(o.modelViewMatrix4_loc,!1,this.sceneState.modelViewMatrix._floatArrays),e.uniformMatrix4fv(o.projectionMatrix4_loc,!1,this.sceneState.projectionMatrix._floatArrays),e.uniform3fv(o.cameraPosHIGH_loc,this.sceneState.encodedCamPosHigh),e.uniform3fv(o.cameraPosLOW_loc,this.sceneState.encodedCamPosLow),e.uniform1f(o.near_loc,this.sceneState.camera.frustum.near),e.uniform1f(o.far_loc,this.sceneState.camera.frustum.far),e.uniform1i(o.hasAditionalMov_loc,!0),e.uniform3fv(o.aditionalMov_loc,[0,0,0]),this.renderer.renderNeoBuildingsLOD2AsimetricVersion(e,i.currentVisibles0,this,o,!1,t),this.renderer.renderNeoBuildingsLOD2AsimetricVersion(e,i.currentVisibles2,this,o,!1,t),-1!==o.position3_loc&&e.disableVertexAttribArray(o.position3_loc)),i.currentVisibles3.length>0&&(r=(o=this.postFxShadersManager.pFx_shaders_array[7]).program,e.useProgram(r),e.enableVertexAttribArray(o.position3_loc),e.uniformMatrix4fv(o.modelViewProjectionMatrix4RelToEye_loc,!1,this.sceneState.modelViewProjRelToEyeMatrix._floatArrays),e.uniformMatrix4fv(o.modelViewMatrix4RelToEye_loc,!1,this.sceneState.modelViewRelToEyeMatrix._floatArrays),e.uniformMatrix4fv(o.modelViewMatrix4_loc,!1,this.sceneState.modelViewMatrix._floatArrays),e.uniformMatrix4fv(o.projectionMatrix4_loc,!1,this.sceneState.projectionMatrix._floatArrays),e.uniform3fv(o.cameraPosHIGH_loc,this.sceneState.encodedCamPosHigh),e.uniform3fv(o.cameraPosLOW_loc,this.sceneState.encodedCamPosLow),e.uniform1f(o.near_loc,this.sceneState.camera.frustum.near),e.uniform1f(o.far_loc,this.sceneState.camera.frustum.far),e.uniform1i(o.hasAditionalMov_loc,!0),e.uniform3fv(o.aditionalMov_loc,[0,0,0]),this.renderer.renderNeoBuildingsLowLOD(e,i.currentVisibles3,this,o,!1,t),-1!==o.position3_loc&&e.disableVertexAttribArray(o.position3_loc)),void 0!==this.tinTerrainManager){r=(o=this.postFxShadersManager.getShader("tinTerrain")).program,e.useProgram(r),e.enableVertexAttribArray(o.position3_loc),e.disableVertexAttribArray(o.texCoord2_loc),o.bindUniformGenerals();var a=this.pin.texturesArray[4];e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,a.texId),e.uniform1i(o.bIsMakingDepth_loc,!0),e.uniform1i(o.hasTexture_loc,!0),e.uniform4fv(o.oneColor4_loc,[.5,.5,.5,1]);var s,l=this.tinTerrainManager.currentTerrainsMap,c=this.tinTerrainManager.currentVisibles_terrName_geoCoords_map;for(var h in c)if(void 0!==(s=l[h])&&void 0!==s.vboKeyContainer&&0!==s.vboKeyContainer.vboCacheKeysArray.length){e.uniform3fv(o.buildingPosHIGH_loc,s.terrainPositionHIGH),e.uniform3fv(o.buildingPosLOW_loc,s.terrainPositionLOW);var d=s.vboKeyContainer.vboCacheKeysArray[0];if(d.isReadyPositions(e,this.vboMemoryManager)&&d.isReadyTexCoords(e,this.vboMemoryManager)&&d.isReadyFaces(e,this.vboMemoryManager)){e.bindBuffer(e.ARRAY_BUFFER,d.meshVertexCacheKey),e.vertexAttribPointer(o.position3_loc,3,e.FLOAT,!1,0,0);var u=d.indicesCount;e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,d.meshFacesCacheKey),e.drawElements(e.TRIANGLES,u,e.UNSIGNED_SHORT,0)}}o&&(-1!==o.texCoord2_loc&&e.disableVertexAttribArray(o.texCoord2_loc),-1!==o.position3_loc&&e.disableVertexAttribArray(o.position3_loc),-1!==o.normal3_loc&&e.disableVertexAttribArray(o.normal3_loc),-1!==o.color4_loc&&e.disableVertexAttribArray(o.color4_loc))}},MagoManager.prototype.createDefaultShaders=function(e){var t="modelRefSsao",i=this.postFxShadersManager.newShader(t),o=ShaderSource.ModelRefSsaoVS,r=ShaderSource.ModelRefSsaoFS;i.program=e.createProgram(),i.shader_vertex=this.postFxShadersManager.createShader(e,o,e.VERTEX_SHADER,"VERTEX"),i.shader_fragment=this.postFxShadersManager.createShader(e,r,e.FRAGMENT_SHADER,"FRAGMENT"),e.attachShader(i.program,i.shader_vertex),e.attachShader(i.program,i.shader_fragment),e.linkProgram(i.program),i.createUniformGenerals(e,i,this.sceneState),i.createUniformLocals(e,i,this.sceneState),t="lodBuildingSsao",i=this.postFxShadersManager.newShader(t),o=ShaderSource.LodBuildingSsaoVS,r=ShaderSource.LodBuildingSsaoFS,i.program=e.createProgram(),i.shader_vertex=this.postFxShadersManager.createShader(e,o,e.VERTEX_SHADER,"VERTEX"),i.shader_fragment=this.postFxShadersManager.createShader(e,r,e.FRAGMENT_SHADER,"FRAGMENT"),e.attachShader(i.program,i.shader_vertex),e.attachShader(i.program,i.shader_fragment),e.linkProgram(i.program),i.createUniformGenerals(e,i,this.sceneState),i.createUniformLocals(e,i,this.sceneState),t="tinTerrain",i=this.postFxShadersManager.newShader(t),o=ShaderSource.TinTerrainVS,r=ShaderSource.TinTerrainFS,i.program=e.createProgram(),i.shader_vertex=this.postFxShadersManager.createShader(e,o,e.VERTEX_SHADER,"VERTEX"),i.shader_fragment=this.postFxShadersManager.createShader(e,r,e.FRAGMENT_SHADER,"FRAGMENT"),e.attachShader(i.program,i.shader_vertex),e.attachShader(i.program,i.shader_fragment),e.linkProgram(i.program),i.createUniformGenerals(e,i,this.sceneState),i.createUniformLocals(e,i,this.sceneState),i.bIsMakingDepth_loc=e.getUniformLocation(i.program,"bIsMakingDepth"),t="pointsCloud",i=this.postFxShadersManager.newShader(t),o=ShaderSource.PointCloudVS,r=ShaderSource.PointCloudFS,i.program=e.createProgram(),i.shader_vertex=this.postFxShadersManager.createShader(e,o,e.VERTEX_SHADER,"VERTEX"),i.shader_fragment=this.postFxShadersManager.createShader(e,r,e.FRAGMENT_SHADER,"FRAGMENT"),e.attachShader(i.program,i.shader_vertex),e.attachShader(i.program,i.shader_fragment),e.linkProgram(i.program),i.createUniformGenerals(e,i,this.sceneState),i.createUniformLocals(e,i,this.sceneState),i.bPositionCompressed_loc=e.getUniformLocation(i.program,"bPositionCompressed"),i.minPosition_loc=e.getUniformLocation(i.program,"minPosition"),i.bboxSize_loc=e.getUniformLocation(i.program,"bboxSize")},MagoManager.prototype.renderLodBuilding=function(e,t,i,o,r,n,a){a.fileLoadState===CODE.fileLoadState.LOADING_FINISHED&&a.parseArrayBuffer(e,this.readerWriter),this.renderer.renderLodBuilding(e,a,this,o,n)},MagoManager.prototype.reCalculateModelViewProjectionRelToEyeMatrix=function(e){for(var t=0;t<16;t++)if(0===e.context._us._modelView[t])return;var i=new Cesium.Matrix4;(i=Cesium.Matrix4.clone(e.context._us._modelView))[12]=0,i[13]=0,i[14]=0;var o=new Cesium.Matrix4;Cesium.Matrix4.multiply(e.context._us._projection,i,o),Cesium.Matrix4.toArray(o,this.modelViewProjRelToEye_matrix)},MagoManager.prototype.deleteNeoBuilding=function(e,t){var i=this.vboMemoryManager;t===this.buildingSelected&&(this.buildingSelected=void 0,this.octreeSelected=void 0,this.objectSelected=void 0),t.deleteObjects(e,i)},MagoManager.prototype.isFarestFrustum=function(){return this.numFrustums-this.currentFrustumIdx-1==0},MagoManager.prototype.doMultiFrustumCullingSmartTiles=function(e){var t=this.myCameraSCX.bigFrustum,i=this.smartTileManager.tilesArray[0],o=this.smartTileManager.tilesArray[1];void 0===this.frustumVolumeControl&&(this.frustumVolumeControl=new FrustumVolumeControl),void 0===this.fullyIntersectedLowestTilesArray&&(this.fullyIntersectedLowestTilesArray=[]),void 0===this.partiallyIntersectedLowestTilesArray&&(this.partiallyIntersectedLowestTilesArray=[]),void 0===this.lastIntersectedLowestTilesArray&&(this.lastIntersectedLowestTilesArray=[]),this.lastIntersectedLowestTilesArray.push.apply(this.lastIntersectedLowestTilesArray,this.fullyIntersectedLowestTilesArray),this.lastIntersectedLowestTilesArray.push.apply(this.lastIntersectedLowestTilesArray,this.partiallyIntersectedLowestTilesArray);for(var r=this.lastIntersectedLowestTilesArray.length,n=0;n=0;l--){if(this.myCameraSCX.frustumsArray[l].intersectionNearFarSphere(c.sphereExtent)!==Constant.INTERSECTION_OUTSIDE)this.frustumVolumeControl.getFrustumVolumeCulling(l).fullyIntersectedLowestTilesArray.push(c)}}s=this.partiallyIntersectedLowestTilesArray.length;for(n=0;n=0;l--){if(this.myCameraSCX.frustumsArray[l].intersectionNearFarSphere(c.sphereExtent)!==Constant.INTERSECTION_OUTSIDE)this.frustumVolumeControl.getFrustumVolumeCulling(l).partiallyIntersectedLowestTilesArray.push(c)}}var c;for(r=this.lastIntersectedLowestTilesArray.length,n=0;nNumber(p)))if(s.nodesArray&&s.nodesArray.length>0){for(var _=s.nodesArray.length,A=0;A<_;A++){if(void 0!==(h=(c=s.nodesArray[A]).getRoot()).data.geoLocDataManager)if(d=h.data.geoLocDataManager.getCurrentGeoLocationData(),u=c.getBBoxCenterPositionWorldCoord(d),l=c.data.neoBuilding,this.radiusAprox_aux=l.bbox.getRadiusAprox(),void 0===this.boundingSphere_Aux&&(this.boundingSphere_Aux=new Sphere),this.boundingSphere_Aux.setCenterPoint(u.x,u.y,u.z),this.boundingSphere_Aux.setRadius(this.radiusAprox_aux),a=i.distToSphere(this.boundingSphere_Aux),l.distToCam=a,l.distToCamthis.magoPolicy.getFrustumFarDistance())this.processQueue.putNodeToDelete(c,0);else{if(r)if(o.intersectionSphere(this.boundingSphere_Aux)===Constant.INTERSECTION_OUTSIDE){this.processQueue.putNodeToDeleteLessThanLod3(c,0);continue}var R=l.getHeaderVersion();if(void 0!==R)if("v"===R[0])as?a>l?(o=~~(10*(s/(i=a))),r=~~(10*(l/(n=i*this.sqrtTable[o]))),n*this.sqrtTable[r]):(o=~~(10*(a/(i=l))),r=~~(10*(s/(n=i*this.sqrtTable[o]))),n*this.sqrtTable[r]):s>l?(o=~~(10*(a/(i=s))),r=~~(10*(l/(n=i*this.sqrtTable[o]))),n*this.sqrtTable[r]):(o=~~(10*(a/(i=l))),r=~~(10*(s/(n=i*this.sqrtTable[o]))),n*this.sqrtTable[r])},MagoManager.prototype.createBuildingsByBuildingSeedsOnLowestTile=function(e){var t,i,o,r,n=0;e.nodesArray&&(n=e.nodesArray.length);for(var a=e.nodeSeedsArray.length,s=n;sthis.min_squaredDist_to_see||(r<1.2*this.min_squaredDist_to_see_detailed?this.detailedVisibleTiles_array.push(this.terranTileSC):r<1.2*this.min_squaredDist_to_see_LOD0?this.LOD0VisibleTiles_array.push(this.terranTileSC):this.filteredVisibleTiles_array.push(this.terranTileSC));this.boundingSphere_Aux.radius=50;var h,d,u=!1,f=this.detailedVisibleTiles_array.length;for(c=0;c0?1===s._header._f4d_version&&(n?r3.5){var c=this.scene.globe.ellipsoid.cartesianToCartographic(s),h=this.scene.globe.ellipsoid.cartesianToCartographic(e),d=h.height,u=c.height+1.5;ud||u1.5)&&(d=u);var f=Cesium.Math.toDegrees(h.latitude),g=Cesium.Math.toDegrees(h.longitude);return this.cameraFPV.camera.position=Cesium.Cartesian3.fromDegrees(g,f,d),!1}return!0}}};var ManagerFactory=function(e,t,i,o,r,n,a){if(!(this instanceof ManagerFactory))throw new Error(Messages.CONSTRUCT_ERROR);var s=null,l=null,c=CODE.magoManagerState.INIT;function h(){s.handler.setInputAction(function(e){s.mouseActionLeftDown(e.position.x,e.position.y)},Cesium.ScreenSpaceEventType.LEFT_DOWN),s.handler.setInputAction(function(e){s.mouseActionMiddleDown(e.position.x,e.position.y)},Cesium.ScreenSpaceEventType.MIDDLE_DOWN),s.handler.setInputAction(function(e){s.mouseActionRightDown(e.position.x,e.position.y)},Cesium.ScreenSpaceEventType.RIGHT_DOWN),s.handler.setInputAction(function(t){var i;s.mouseLeftDown?t.startPosition.x===t.endPosition.x&&t.startPosition.y===t.endPosition.y||(s.manageMouseDragging(t.startPosition.x,t.startPosition.y),s.cameraMoved()):(s.mouseDragging=!1,i=!0,e.scene.screenSpaceCameraController.enableRotate=i,e.scene.screenSpaceCameraController.enableZoom=i,e.scene.screenSpaceCameraController.enableLook=i,e.scene.screenSpaceCameraController.enableTilt=i,e.scene.screenSpaceCameraController.enableTranslate=i,(s.mouseMiddleDown||s.mouseRightDown)&&(s.isCameraMoving=!0,s.cameraMoved()))},Cesium.ScreenSpaceEventType.MOUSE_MOVE),s.handler.setInputAction(function(e){s.mouseActionLeftUp(e.position.x,e.position.y);var t={lat:null,lon:null,alt:null},o=s.scene.camera.pickEllipsoid(e.position);if(o){var r=Cesium.Cartographic.fromCartesian(o);t.lat=Cesium.Math.toDegrees(r.latitude),t.lon=Cesium.Math.toDegrees(r.longitude),t.alt=r.height}"true"===MagoConfig.getPolicy().geo_callback_enable&&""!==i.geo_callback_clickposition&&clickPositionCallback(i.geo_callback_clickposition,t)},Cesium.ScreenSpaceEventType.LEFT_UP),s.handler.setInputAction(function(e){s.mouseActionMiddleUp(e.position.x,e.position.y)},Cesium.ScreenSpaceEventType.MIDDLE_UP),s.handler.setInputAction(function(e){s.mouseActionRightUp(e.position.x,e.position.y)},Cesium.ScreenSpaceEventType.RIGHT_UP)}function d(){var t,i;MagoConfig.getPolicy().geo_view_library===Constant.CESIUM?function(){var t=e.scene.context._gl;if(e.scene.magoManager.shadersManager.createDefaultShader(t),e.scene.magoManager.postFxShadersManager.gl=t,e.scene.magoManager.postFxShadersManager.createDefaultShaders(t),e.scene.magoManager.createDefaultShaders(t),e.scene.magoManager.scene=e.scene,s=e.scene.magoManager,l=e.scene,e.scene.globe.depthTestAgainstTerrain=!0,null!==o&&o.length>0)for(var i=0;i0&&(e.camera.frustum.fov=Cesium.Math.PI_OVER_THREE*MagoConfig.getPolicy().geo_init_default_fov),"true"===i.geo_server_enable&&null!==i.geo_server_add_url&&""!==i.geo_server_add_url&&(f=new Cesium.WebMapServiceImageryProvider({url:MagoConfig.getPolicy().geo_server_add_url,layers:MagoConfig.getPolicy().geo_server_add_layers,parameters:{service:MagoConfig.getPolicy().geo_server_add_parameters_service,version:MagoConfig.getPolicy().geo_server_add_parameters_version,request:MagoConfig.getPolicy().geo_server_add_parameters_request,transparent:MagoConfig.getPolicy().geo_server_add_parameters_transparent,format:MagoConfig.getPolicy().geo_server_add_parameters_format}}),e.imageryLayers.addImageryProvider(f)),d(),e.entities.add({name:"mago3D",position:Cesium.Cartesian3.fromDegrees(37.521168,126.924185,3e3),box:{dimensions:new Cesium.Cartesian3(3e8,3e8,3e8),fill:!0,material:Cesium.Color.BLUE,outline:!1}}),"true"===i.geo_init_camera_enable&&e.camera.flyTo({destination:Cesium.Cartesian3.fromDegrees(parseFloat(MagoConfig.getPolicy().geo_init_longitude),parseFloat(MagoConfig.getPolicy().geo_init_latitude),parseFloat(MagoConfig.getPolicy().geo_init_height)),duration:parseInt(MagoConfig.getPolicy().geo_init_duration)}),u=new API("renderMode"),s.callAPI(u),"false"===MagoConfig.getPolicy().geo_time_line_enable&&($(e._animation.container).css("visibility","hidden"),$(e._timeline.container).css("visibility","hidden"),e.forceResize())}else if(i.geo_view_library===Constant.WORLDWIND){WorldWind.Logger.setLoggingLevel(WorldWind.Logger.LEVEL_WARNING);var y,v=document.getElementById(t);if("true"===i.geo_server_enable&&null!==i.geo_server_url&&""!==i.geo_server_url){y=new WorldWind.WorldWindow(t,new WorldWind.ZeroElevationModel);var x=i.geo_server_url+"?SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.3.0";$.get(x).done(function(e){var t=new WorldWind.WmsCapabilities(e).getNamedLayer("mago3d"),i=WorldWind.WmsLayer.formLayerConfiguration(t);i.title="imageProvider";var o=new WorldWind.WmsLayer(i);y.addLayer(o)}).fail(function(e,t,i){})}else{y=new WorldWind.WorldWindow(t);for(var b=[{layer:new WorldWind.BMNGLayer,enabled:!0},{layer:new WorldWind.BMNGLandsatLayer,enabled:!1},{layer:new WorldWind.BingAerialWithLabelsLayer(null),enabled:!0},{layer:new WorldWind.OpenStreetMapImageLayer(null),enabled:!1},{layer:new WorldWind.CompassLayer,enabled:!1},{layer:new WorldWind.CoordinatesDisplayLayer(y),enabled:!0},{layer:new WorldWind.ViewControlsLayer(y),enabled:!0}],C=0;C0)for(var i=0;i=0&&r[0]=0&&r[1]t-i&&e0){var e=(this.maxX+this.minX)/2,t=(this.maxY+this.minY)/2,i=(this.maxZ+this.minZ)/2;this._subBoxesArray[0].setDimensions(this.minX,e,this.minY,t,this.minZ,i),this._subBoxesArray[1].setDimensions(e,this.maxX,this.minY,t,this.minZ,i),this._subBoxesArray[2].setDimensions(e,this.maxX,t,this.maxY,this.minZ,i),this._subBoxesArray[3].setDimensions(this.minX,e,t,this.maxY,this.minZ,i),this._subBoxesArray[4].setDimensions(this.minX,e,this.minY,t,i,this.maxZ),this._subBoxesArray[5].setDimensions(e,this.maxX,this.minY,t,i,this.maxZ),this._subBoxesArray[6].setDimensions(e,this.maxX,t,this.maxY,i,this.maxZ),this._subBoxesArray[7].setDimensions(this.minX,e,t,this.maxY,i,this.maxZ);for(var o=0;othis.minX&&ethis.minY&&tthis.minZ&&i0){var r,n=(this.minX+this.maxX)/2,a=(this.minY+this.maxY)/2,s=(this.minZ+this.maxZ)/2;r=e0&&(o=n._indicesArray,r&&(r=this.modelReferencedGroupsList)),o},OcclusionCullingOctreeCell.prototype.expandBox=function(e){this.minX-=e,this.maxX+=e,this.minY-=e,this.maxY+=e,this.minZ-=e,this.maxZ+=e},OcclusionCullingOctreeCell.prototype.parseArrayBuffer=function(e,t,i){var o=i.readInt8(e,t,t+1);if(t+=1,o){var r=i.readFloat32(e,t,t+4);t+=4;var n=i.readFloat32(e,t,t+4);t+=4;var a=i.readFloat32(e,t,t+4);t+=4;var s=i.readFloat32(e,t,t+4);t+=4;var l=i.readFloat32(e,t,t+4);t+=4;var c=i.readFloat32(e,t,t+4);t+=4,this.setDimensions(r,n,a,s,l,c)}var h=i.readUInt32(e,t,t+4);if(t+=4,0===h){var d=i.readUInt32(e,t,t+4);t+=4;for(var u=0;u1e-7){var c=-(this.a*i+this.b*o+this.c*r+this.d)/l;return void 0===t&&(t=new Point3D),t.set(i+c*n,o+c*a,r+c*s),t}},Plane.prototype.intersectionSphere=function(e){if(void 0===e||void 0===e.centerPoint)return Constant.INTERSECTION_OUTSIDE;var t=e.centerPoint,i=t.x*this.a+t.y*this.b+t.z*this.c+this.d;return i<-e.r?Constant.INTERSECTION_OUTSIDE:i0)return!0;i++}return!1},SmartTile.prototype.makeSphereExtent=function(e){this.sphereExtent=SmartTile.computeSphereExtent(e,this.minGeographicCoord,this.maxGeographicCoord,this.sphereExtent)},SmartTile.computeSphereExtent=function(e,t,i,o){void 0===o&&(o=new Sphere);var r,n=(i.longitude+t.longitude)/2,a=(i.latitude+t.latitude)/2,s=(i.altitude+t.altitude)/2;return o.centerPoint=ManagerUtils.geographicCoordToWorldPoint(n,a,s,o.centerPoint,e),r=ManagerUtils.geographicCoordToWorldPoint(t.longitude,t.latitude,t.altitude,r,e),o.r=1.2*o.centerPoint.distTo(r.x,r.y,r.z),o},SmartTile.prototype.makeTreeByDepth=function(e,t){if(void 0!==this.nodeSeedsArray&&0!==this.nodeSeedsArray.length&&(this.makeSphereExtent(t),this.depththis.maxGeographicCoord.altitude&&(this.maxGeographicCoord.altitude=l+c)}}},SmartTile.prototype.intersectPoint=function(e,t){return!(ethis.maxGeographicCoord.longitude)&&!(tthis.maxGeographicCoord.latitude)},SmartTile.prototype.extractLowestTiles=function(e){if(void 0!==this.subTiles)for(var t=this.subTiles.length,i=0;i0&&e.push(this)},SmartTile.prototype.getFrustumIntersectedLowestTiles=function(e,t,i){var o=[];this.getFrustumIntersectedTiles(e,o,i);for(var r=o.length,n=0;n0)for(var r=0;r0&&i.push(this)}else t.push(this)},SmartTile.selectTileAngleRangeByDepth=function(e){if(!(void 0===e||e<0||e>15))return 0===e?180:1===e?90:2===e?45:3===e?22.5:4===e?11.25:5===e?5.625:6===e?2.8125:7===e?1.40625:8===e?.703125:9===e?.3515625:10===e?.17578125:11===e?.087890625:12===e?.043945313:13===e?.021972656:14===e?.010986328:15===e?.005493164:void 0},SmartTile.selectTileName=function(e,t,i,o){var r=SmartTile.selectTileAngleRangeByDepth(e),n=Math.floor((t- -180)/r),a=Math.floor((90-i)/r);return e.toString()+"\\"+n.toString()+"\\"+a.toString()},SmartTile.getFrustumIntersectedTilesNames=function(e,t,i,o,r){var n=new GeographicCoord,a=new GeographicCoord,s=0;n.setLonLatAlt(-180,-90,0),a.setLonLatAlt(0,90,0),s=0,SmartTile.getFrustumIntersectedTilesNamesForGeographicExtent(e,t,s,i,n,a,o,o.boundingSphere_Aux,r),n.setLonLatAlt(0,-90,0),a.setLonLatAlt(180,90,0),s=0,SmartTile.getFrustumIntersectedTilesNamesForGeographicExtent(e,t,s,i,n,a,o,o.boundingSphere_Aux,r)},SmartTile.getFrustumIntersectedTilesNamesForGeographicExtent=function(e,t,i,o,r,n,a,s,l){s=SmartTile.computeSphereExtent(a,r,n,s);var c=e.intersectionSphere(s);if(c!==Constant.INTERSECTION_OUTSIDE){if(c===Constant.INTERSECTION_INSIDE){var h=(r.longitude+n.longitude)/2,d=(r.latitude+n.latitude)/2,u=SmartTile.selectTileName(i,h,d,void 0);return(f=new GeographicExtent).minGeographicCoord=new GeographicCoord(r.longitude,r.latitude,r.altitude),f.maxGeographicCoord=new GeographicCoord(n.longitude,n.latitude,n.altitude),void(l[u]=f)}if(c===Constant.INTERSECTION_INTERSECT){if(o.distToSphere(s)>2e3){h=(r.longitude+n.longitude)/2,d=(r.latitude+n.latitude)/2,u=SmartTile.selectTileName(i,h,d,void 0);return(f=new GeographicExtent).minGeographicCoord=new GeographicCoord(r.longitude,r.latitude,r.altitude),f.maxGeographicCoord=new GeographicCoord(n.longitude,n.latitude,n.altitude),void(l[u]=f)}if(!(i=t)){var i,o=e._header,r=this.fileArrayBuffer,n=this.fileBytesReaded;void 0===this.readWriter&&(this.readWriter=new ReaderWriter);for(var a=0;a<5;a++)o._version+=String.fromCharCode(new Int8Array(r.slice(n,n+1))),n+=1;o._f4d_version=2,i=this.readWriter.readInt32(r,n,n+4),n+=4;for(a=0;a40||o._boundingBox.maxY-o._boundingBox.minY>40)&&(l=!0),!l&&o._boundingBox.maxZ-o._boundingBox.minZ<30&&(o.isSmall=!0);this.readWriter.readUInt8(r,n,n+1);n+=1;var c=Cesium.Cartesian3.fromDegrees(o._longitude,o._latitude,o._elevation),h=Cesium.Ellipsoid.WGS84.cartesianToCartographic(c).height;c=Cesium.Cartesian3.fromDegrees(o._longitude,o._latitude,h),e.buildingPosition=c;Cesium.EncodedCartesian3.encode(c);var d=Cesium.EncodedCartesian3.encode(c.x),u=Cesium.EncodedCartesian3.encode(c.y),f=Cesium.EncodedCartesian3.encode(c.z);e.buildingPositionHIGH=new Float32Array(3),e.buildingPositionHIGH[0]=d.high,e.buildingPositionHIGH[1]=u.high,e.buildingPositionHIGH[2]=f.high,e.buildingPositionLOW=new Float32Array(3),e.buildingPositionLOW[0]=d.low,e.buildingPositionLOW[1]=u.low,e.buildingPositionLOW[2]=f.low,this.fileBytesReaded=n}},TerranTile.prototype.parseFileSimpleBuilding=function(e){var t=this.fileArrayBuffer.byteLength;if(!(this.fileBytesReaded>=t)){void 0===this.readWriter&&(this.readWriter=new ReaderWriter);var i,o,r=this.fileBytesReaded,n=this.fileArrayBuffer;void 0===e._simpleBuilding_v1&&(e._simpleBuilding_v1=new SimpleBuildingV1);var a=e._simpleBuilding_v1,s=this.readWriter.readUInt32(n,r,r+4);r+=4;for(var l=0;l=t)this.fileParsingFinished=!0;else{void 0===this.readWriter&&(this.readWriter=new ReaderWriter);var i=this.fileArrayBuffer,o=this.readWriter.readInt32(i,0,4);this.fileBytesReaded+=4,0===o&&(this.empty_tile=!0);for(var r=0;r=i)this.fileParsingFinished=!0;else{void 0===this.readWriter&&(this.readWriter=new ReaderWriter);var o=this.readWriter.readInt32(this.fileArrayBuffer,0,4);if(this.projectsParsed_count>=o)return this.fileParsingFinished=!0,void(this.fileBytesReaded=null);0===this.current_BRProject_parsing_state&&(0===this.projectsParsed_count&&(this.fileBytesReaded=4),this.current_BRProject_parsing=this.newBRProject());var r=this.current_BRProject_parsing;0===this.current_BRProject_parsing_state?(this.parseFileHeader(r),this.current_BRProject_parsing_state=1):1===this.current_BRProject_parsing_state?t.backGround_imageReadings_count<1&&(this.parseFile_simpleBuilding_old(e,r),this.current_BRProject_parsing_state=2):2===this.current_BRProject_parsing_state&&t.backGround_imageReadings_count<1&&(this.parseFile_nailImage_old(e,r,t),this.current_BRProject_parsing_state=0,this.projectsParsed_count++,t.backGround_imageReadings_count++)}},TerranTile.prototype.setDimensionsSubTiles=function(){var e=this.subTiles_array.length;if(4===e){var t=(this.longitudeMax+this.longitudeMin)/2,i=(this.latitudeMax+this.latitudeMin)/2;this.subTiles_array[0].setDimensions(this.longitudeMin,t,this.latitudeMin,i),this.subTiles_array[1].setDimensions(t,this.longitudeMax,this.latitudeMin,i),this.subTiles_array[2].setDimensions(t,this.longitudeMax,i,this.latitudeMax),this.subTiles_array[3].setDimensions(this.longitudeMin,t,i,this.latitudeMax);for(var o=0;o0)for(var t=0;t0)for(var o=0;o0)return r=this.vboKeysArray.pop();if(!o){var r=e.createBuffer();return this.keysCreated+=1,t.totalBytesUsed+=this.classifiedSize,i.totalBytesUsed+=this.classifiedSize,r}},VBOKeysStore.prototype.storeBufferKey=function(e){this.vboKeysArray.push(e)};var VBOKeysNation=function(e,t){if(!(this instanceof VBOKeysNation))throw new Error(Messages.CONSTRUCT_ERROR);var i;this.vboKeysStoreMap={},this.bufferSizes=e,this.minSize=t,this.maxSize=e[e.length-1],this.totalBytesUsed=0;for(var o=e.length,r=0;rthis.maxSize&&(this.maxSize=e[r])};VBOKeysNation.prototype.getClassifiedBufferKey=function(e,t,i,o){var r=this.vboKeysStoreMap[t];return r?r.getBufferKey(e,this,i,o):-1},VBOKeysNation.prototype.storeClassifiedBufferKey=function(e,t){var i=this.vboKeysStoreMap[t];i&&i.storeBufferKey(e)},VBOKeysNation.prototype.getClosestBufferSize=function(e){if(!this.isInsideRange(e))return-1;for(var t=this.bufferSizes.length,i=0;ithis.maxSize||ethis.bytesLimit&&(i=!0);var o=this.getKeyNationBySize(t),r=void 0;return o&&(r=o.getClassifiedBufferKey(e,t,this,i)),r},VBOKeysWorld.prototype.storeClassifiedBufferKey=function(e,t){var i=this.getKeyNationBySize(t);i&&i.storeClassifiedBufferKey(e,t)},VBOKeysWorld.prototype.getKeyNationBySize=function(e){for(var t=this.vboKeysNationsArray.length,i=0;ithis.buffersKeyWorld.bytesLimit||this.elementKeyWorld.totalBytesUsed>this.elementKeyWorld.bytesLimit},VBOMemoryManager.prototype.getClassifiedBufferKey=function(e,t){return this.enableMemoryManagement?this.buffersKeyWorld.getClassifiedBufferKey(e,t):e.createBuffer()},VBOMemoryManager.prototype.storeClassifiedBufferKey=function(e,t,i){this.enableMemoryManagement?this.buffersKeyWorld.storeClassifiedBufferKey(t,i):e.deleteBuffer(t)},VBOMemoryManager.prototype.getClassifiedElementKey=function(e,t){return this.enableMemoryManagement?this.elementKeyWorld.getClassifiedBufferKey(e,t):e.createBuffer()},VBOMemoryManager.prototype.storeClassifiedElementKey=function(e,t,i){this.enableMemoryManagement?this.elementKeyWorld.storeClassifiedBufferKey(t,i):e.deleteBuffer(t)},VBOMemoryManager.prototype.getClassifiedBufferSize=function(e){return this.enableMemoryManagement?this.buffersKeyWorld.getClassifiedBufferSize(e):e};var VisibleObjectsController=function(){if(!(this instanceof VisibleObjectsController))throw new Error(Messages.CONSTRUCT_ERROR);this.currentVisibles0=[],this.currentVisibles1=[],this.currentVisibles2=[],this.currentVisibles3=[],this.currentVisiblesAux=[]};function changeMagoStateAPI(e,t){if(null!==e){var i=new API("changeMagoState");i.setMagoEnable(t),e.callAPI(i)}}function changeLabelAPI(e,t){if(null!==e){var i=new API("changeLabel");i.setShowLabelInfo(t),e.callAPI(i)}}function changeOriginAPI(e,t){if(null!==e){var i=new API("changeOrigin");i.setShowOrigin(t),e.callAPI(i)}}function changeBoundingBoxAPI(e,t){if(null!==e){var i=new API("changeBoundingBox");i.setShowBoundingBox(t),e.callAPI(i)}}function changePropertyRenderingAPI(e,t,i,o){if(null!==e){var r=new API("changePropertyRendering");r.setShowShadow(t),r.setProjectId(i),r.setProperty(o),e.callAPI(r)}}function changeShadowAPI(e,t){if(null!==e){var i=new API("changeShadow");i.setShowShadow(t),e.callAPI(i)}}function changeColorAPI(e,t,i,o,r,n){if(null!==e){var a=new API("changeColor");a.setProjectId(t),a.setDataKey(i),a.setObjectIds(o),a.setProperty(r),a.setColor(n),e.callAPI(a)}}function changeLocationAndRotationAPI(e,t,i,o,r,n,a,s,l){if(null!==e){var c=new API("changeLocationAndRotation");c.setProjectId(t),c.setDataKey(i),c.setLatitude(o),c.setLongitude(r),c.setElevation(n),c.setHeading(a),c.setPitch(s),c.setRoll(l),e.callAPI(c)}}function changeObjectMoveAPI(e,t){if(null!==e){var i=new API("changeObjectMove");i.setObjectMoveMode(t),e.callAPI(i)}}function saveObjectMoveAPI(e,t){if(null!==e){var i=new API("saveObjectMove");i.setObjectMoveMode(t),e.callAPI(i)}}function deleteAllObjectMoveAPI(e,t){if(null!==e){var i=new API("deleteAllObjectMove");i.setObjectMoveMode(t),e.callAPI(i)}}function deleteAllChangeColorAPI(e){if(null!==e){var t=new API("deleteAllChangeColor");e.callAPI(t)}}function changeInsertIssueModeAPI(e,t){if(null!==e){var i=new API("changeInsertIssueMode");i.setIssueInsertEnable(t),e.callAPI(i)}}function changeObjectInfoViewModeAPI(e,t){if(null!==e){var i=new API("changeObjectInfoViewMode");i.setObjectInfoViewEnable(t),e.callAPI(i)}}function changeOcclusionCullingAPI(e,t,i){if(null!==e){var o=new API("changeOcclusionCulling");o.setOcclusionCullingEnable(t),o.setDataKey(i),e.callAPI(o)}}function changeFPVModeAPI(e,t){if(null!==e){var i=new API("changeFPVMode");i.setFPVMode(t),e.callAPI(i)}}function changeNearGeoIssueListViewModeAPI(e,t){if(null!==e){var i=new API("changeNearGeoIssueListViewMode");i.setNearGeoIssueListEnable(t),e.callAPI(i)}}function changeInsertIssueStateAPI(e,t){if(null!==e){var i=new API("changeInsertIssueState");i.setInsertIssueState(t),e.callAPI(i)}}function changeLodAPI(e,t,i,o,r,n,a){if(null!==e){var s=new API("changeLod");s.setLod0DistInMeters(t),s.setLod1DistInMeters(i),s.setLod2DistInMeters(o),s.setLod3DistInMeters(r),s.setLod4DistInMeters(n),s.setLod5DistInMeters(a),e.callAPI(s)}}function changeLightingAPI(e,t,i,o,r,n){if(null!==e){var a=new API("changeLighting");a.setAmbientReflectionCoef(t),a.setDiffuseReflectionCoef(i),a.setSpecularReflectionCoef(o),a.setAmbientColor(r),a.setSpecularColor(n),e.callAPI(a)}}function changeSsaoRadiusAPI(e,t){if(null!==e){var i=new API("changeSsaoRadius");i.setSsaoRadius(t),e.callAPI(i)}}function clearAllDataAPI(e){if(null!==e){var t=new API("clearAllData");MagoConfig.clearAllData(),e.callAPI(t)}}function drawInsertIssueImageAPI(e,t,i,o,r,n,a,s){if(null!==e){var l=new API("drawInsertIssueImage");l.setDrawType(t),l.setIssueId(i),l.setIssueId(o),l.setDataKey(r),l.setLatitude(n),l.setLongitude(a),l.setElevation(s),e.callAPI(l)}}function gotoProjectAPI(e,t,i,o,r,n,a,s){if(null!==e){MagoConfig.setData(CODE.PROJECT_ID_PREFIX+t,i),MagoConfig.setProjectDataFolder(CODE.PROJECT_DATA_FOLDER_PREFIX+o,o);var l=new API("gotoProject");l.setProjectId(t),l.setProjectDataFolder(o),l.setLatitude(n),l.setLongitude(r),l.setElevation(a),l.setDuration(s),e.callAPI(l)}}function gotoIssueAPI(e,t,i,o,r,n,a,s,l,c){if(null!==e){MagoConfig.setData(CODE.PROJECT_ID_PREFIX+t,i),MagoConfig.setProjectDataFolder(CODE.PROJECT_DATA_FOLDER_PREFIX+o,o);var h=new API("gotoIssue");h.setProjectId(t),h.setProjectDataFolder(o),h.setIssueId(r),h.setIssueType(n),h.setLatitude(s),h.setLongitude(a),h.setElevation(l),h.setDuration(c),e.callAPI(h)}}function mouseMoveAPI(e,t){null!==e&&e.mouseMove(t)}function searchDataAPI(e,t,i){if(null!==e){var o=new API("searchData");o.setProjectId(t),o.setDataKey(i),e.callAPI(o)}}function isDataExistAPI(e){return!!MagoConfig.isDataExist(e)}function getDataAPI(e){return MagoConfig.getData(e)}function getDataInfoByDataKeyAPI(e,t,i){if(null!==e){var o=new API("getDataInfoByDataKey");o.setProjectId(t),o.setDataKey(i),e.callAPI(o)}}function drawAppendDataAPI(e,t,i,o){if(null!==e&&!(t.length<=0)){var r=new API("drawAppendData");t.forEach(function(t,n){MagoConfig.setData(CODE.PROJECT_ID_PREFIX+t,i[n]),MagoConfig.setProjectDataFolder(CODE.PROJECT_DATA_FOLDER_PREFIX+o[n],o[n]),r.setProjectId(t),r.setProjectDataFolder(o[n]),e.callAPI(r)})}}function getCoordinateRelativeToBuildingAPI(e,t,i,o,r){if(null!==e){var n=new API("getCoordinateRelativeToBuilding");return n.setReturnable(!0),n.setProjectId(t),n.setDataKey(i),n.setInputPoint(o),n.setResultPoint(r),e.callAPI(n)}}function getAbsoluteCoodinateOfBuildingPointAPI(e,t,i,o,r){if(null!==e){var n=new API("getAbsoluteCoodinateOfBuildingPoint");return n.setReturnable(!0),n.setProjectId(t),n.setDataKey(i),n.setInputPoint(o),n.setResultPoint(r),e.callAPI(n)}}VisibleObjectsController.prototype.initArrays=function(){this.currentVisibles0=[],this.currentVisibles1=[],this.currentVisibles2=[],this.currentVisibles3=[],this.currentVisiblesAux=[]},VisibleObjectsController.prototype.clear=function(){this.currentVisibles0.length=0,this.currentVisibles1.length=0,this.currentVisibles2.length=0,this.currentVisibles3.length=0,this.currentVisiblesAux.length=0},VisibleObjectsController.prototype.getNodeIdxSortedByDist=function(e,t,i,o){var r=o.data.neoBuilding,n=i-t;if(n<6){for(var a,s=!1,l=t;!s&&l<=i;){var c=e[l].data.neoBuilding;r.distToCamr.distToCam?(h=t,d=u):(h=u,d=i),this.getNodeIdxSortedByDist(e,h,d,o)},VisibleObjectsController.prototype.putNodeToArraySortedByDist=function(e,t){if(e.length>0){var i=e.length-1,o=this.getNodeIdxSortedByDist(e,0,i,t);e.splice(o,0,t)}else e.push(t)};var ColorAPI={changeColor:function(e,t){var i=e.getProjectId(),o=e.getDataKey(),r=e.getObjectIds(),n=e.getProperty(),a=null,s=null;if(null!==n&&""!==n){var l=n.split("=");a=l[0],s=l[1]}var c=e.getColor().split(","),h=[c[0]/255,c[1]/255,c[2]/255],d=!1;null!==r&&0!==r.length&&(d=!0);var u=[];if(d)for(var f=0,g=r.length;f0)for(var o=0;othis._byteLength&&(this._byteLength=t);else{for(i<1&&(i=1);t>i;)i*=2;var o=new ArrayBuffer(i),r=new Uint8Array(this._buffer);new Uint8Array(o,0,r.length).set(r),this.buffer=o,this._byteLength=t}}},DataStream.prototype._trimAlloc=function(){if(this._byteLength!=this._buffer.byteLength){var e=new ArrayBuffer(this._byteLength),t=new Uint8Array(e),i=new Uint8Array(this._buffer,0,t.length);t.set(i),this.buffer=e}},DataStream.prototype.seek=function(e){var t=Math.max(0,Math.min(this.byteLength,e));this.position=isNaN(t)||!isFinite(t)?0:t},DataStream.prototype.isEof=function(){return this.position>=this.byteLength},DataStream.prototype.mapInt32Array=function(e,t){this._realloc(4*e);var i=new Int32Array(this._buffer,this.byteOffset+this.position,e);return DataStream.arrayToNative(i,null==t?this.endianness:t),this.position+=4*e,i},DataStream.prototype.mapInt16Array=function(e,t){this._realloc(2*e);var i=new Int16Array(this._buffer,this.byteOffset+this.position,e);return DataStream.arrayToNative(i,null==t?this.endianness:t),this.position+=2*e,i},DataStream.prototype.mapInt8Array=function(e){this._realloc(1*e);var t=new Int8Array(this._buffer,this.byteOffset+this.position,e);return this.position+=1*e,t},DataStream.prototype.mapUint32Array=function(e,t){this._realloc(4*e);var i=new Uint32Array(this._buffer,this.byteOffset+this.position,e);return DataStream.arrayToNative(i,null==t?this.endianness:t),this.position+=4*e,i},DataStream.prototype.mapUint16Array=function(e,t){this._realloc(2*e);var i=new Uint16Array(this._buffer,this.byteOffset+this.position,e);return DataStream.arrayToNative(i,null==t?this.endianness:t),this.position+=2*e,i},DataStream.prototype.mapUint8Array=function(e){this._realloc(1*e);var t=new Uint8Array(this._buffer,this.byteOffset+this.position,e);return this.position+=1*e,t},DataStream.prototype.mapFloat64Array=function(e,t){this._realloc(8*e);var i=new Float64Array(this._buffer,this.byteOffset+this.position,e);return DataStream.arrayToNative(i,null==t?this.endianness:t),this.position+=8*e,i},DataStream.prototype.mapFloat32Array=function(e,t){this._realloc(4*e);var i=new Float32Array(this._buffer,this.byteOffset+this.position,e);return DataStream.arrayToNative(i,null==t?this.endianness:t),this.position+=4*e,i},DataStream.prototype.readInt32Array=function(e,t){e=null==e?this.byteLength-this.position/4:e;var i=new Int32Array(e);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,e*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,null==t?this.endianness:t),this.position+=i.byteLength,i},DataStream.prototype.readInt16Array=function(e,t){e=null==e?this.byteLength-this.position/2:e;var i=new Int16Array(e);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,e*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,null==t?this.endianness:t),this.position+=i.byteLength,i},DataStream.prototype.readInt8Array=function(e){e=null==e?this.byteLength-this.position:e;var t=new Int8Array(e);return DataStream.memcpy(t.buffer,0,this.buffer,this.byteOffset+this.position,e*t.BYTES_PER_ELEMENT),this.position+=t.byteLength,t},DataStream.prototype.readUint32Array=function(e,t){e=null==e?this.byteLength-this.position/4:e;var i=new Uint32Array(e);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,e*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,null==t?this.endianness:t),this.position+=i.byteLength,i},DataStream.prototype.readUint16Array=function(e,t){e=null==e?this.byteLength-this.position/2:e;var i=new Uint16Array(e);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,e*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,null==t?this.endianness:t),this.position+=i.byteLength,i},DataStream.prototype.readUint8Array=function(e){e=null==e?this.byteLength-this.position:e;var t=new Uint8Array(e);return DataStream.memcpy(t.buffer,0,this.buffer,this.byteOffset+this.position,e*t.BYTES_PER_ELEMENT),this.position+=t.byteLength,t},DataStream.prototype.readFloat64Array=function(e,t){e=null==e?this.byteLength-this.position/8:e;var i=new Float64Array(e);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,e*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,null==t?this.endianness:t),this.position+=i.byteLength,i},DataStream.prototype.readFloat32Array=function(e,t){e=null==e?this.byteLength-this.position/4:e;var i=new Float32Array(e);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,e*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,null==t?this.endianness:t),this.position+=i.byteLength,i},DataStream.prototype.writeInt32Array=function(e,t){if(this._realloc(4*e.length),e instanceof Int32Array&&(this.byteOffset+this.position)%e.BYTES_PER_ELEMENT==0)DataStream.memcpy(this._buffer,this.byteOffset+this.position,e.buffer,e.byteOffset,e.byteLength),this.mapInt32Array(e.length,t);else for(var i=0;i0,DataStream.memcpy=function(e,t,i,o,r){var n=new Uint8Array(e,t,r),a=new Uint8Array(i,o,r);n.set(a)},DataStream.arrayToNative=function(e,t){return t==this.endianness?e:this.flipArrayEndianness(e)},DataStream.nativeToEndian=function(e,t){return this.endianness==t?e:this.flipArrayEndianness(e)},DataStream.flipArrayEndianness=function(e){for(var t=new Uint8Array(e.buffer,e.byteOffset,e.byteLength),i=0;ir;o--,r++){var n=t[r];t[r]=t[o],t[o]=n}return e},DataStream.createStringFromArray=function(e){for(var t=[],i=0;i1?0:r<-1?Math.PI:Math.acos(r)},t.str=function(e){return"vec3("+e[0]+", "+e[1]+", "+e[2]+")"},t.exactEquals=function(e,t){return e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]},t.equals=function(e,t){var i=e[0],r=e[1],n=e[2],a=t[0],s=t[1],l=t[2];return Math.abs(i-a)<=o.EPSILON*Math.max(1,Math.abs(i),Math.abs(a))&&Math.abs(r-s)<=o.EPSILON*Math.max(1,Math.abs(r),Math.abs(s))&&Math.abs(n-l)<=o.EPSILON*Math.max(1,Math.abs(n),Math.abs(l))};var o=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t.default=e,t}(i(0));function r(){var e=new o.ARRAY_TYPE(3);return e[0]=0,e[1]=0,e[2]=0,e}function n(e){var t=e[0],i=e[1],o=e[2];return Math.sqrt(t*t+i*i+o*o)}function a(e,t,i){var r=new o.ARRAY_TYPE(3);return r[0]=e,r[1]=t,r[2]=i,r}function s(e,t,i){return e[0]=t[0]-i[0],e[1]=t[1]-i[1],e[2]=t[2]-i[2],e}function l(e,t,i){return e[0]=t[0]*i[0],e[1]=t[1]*i[1],e[2]=t[2]*i[2],e}function c(e,t,i){return e[0]=t[0]/i[0],e[1]=t[1]/i[1],e[2]=t[2]/i[2],e}function h(e,t){var i=t[0]-e[0],o=t[1]-e[1],r=t[2]-e[2];return Math.sqrt(i*i+o*o+r*r)}function d(e,t){var i=t[0]-e[0],o=t[1]-e[1],r=t[2]-e[2];return i*i+o*o+r*r}function u(e){var t=e[0],i=e[1],o=e[2];return t*t+i*i+o*o}function f(e,t){var i=t[0],o=t[1],r=t[2],n=i*i+o*o+r*r;return n>0&&(n=1/Math.sqrt(n),e[0]=t[0]*n,e[1]=t[1]*n,e[2]=t[2]*n),e}function g(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]}var p;t.sub=s,t.mul=l,t.div=c,t.dist=h,t.sqrDist=d,t.len=n,t.sqrLen=u,t.forEach=(p=r(),function(e,t,i,o,r,n){var a=void 0,s=void 0;for(t||(t=3),i||(i=0),s=o?Math.min(o*t+i,e.length):e.length,a=i;a0&&(a=1/Math.sqrt(a),e[0]=i*a,e[1]=o*a,e[2]=r*a,e[3]=n*a),e}var g;t.sub=n,t.mul=a,t.div=s,t.dist=c,t.sqrDist=h,t.len=d,t.sqrLen=u,t.forEach=(g=r(),function(e,t,i,o,r,n){var a=void 0,s=void 0;for(t||(t=4),i||(i=0),s=o?Math.min(o*t+i,e.length):e.length,a=i;a0?(o=2*Math.sqrt(i+1),e[3]=.25*o,e[0]=(t[6]-t[9])/o,e[1]=(t[8]-t[2])/o,e[2]=(t[1]-t[4])/o):t[0]>t[5]&t[0]>t[10]?(o=2*Math.sqrt(1+t[0]-t[5]-t[10]),e[3]=(t[6]-t[9])/o,e[0]=.25*o,e[1]=(t[1]+t[4])/o,e[2]=(t[8]+t[2])/o):t[5]>t[10]?(o=2*Math.sqrt(1+t[5]-t[0]-t[10]),e[3]=(t[8]-t[2])/o,e[0]=(t[1]+t[4])/o,e[1]=.25*o,e[2]=(t[6]+t[9])/o):(o=2*Math.sqrt(1+t[10]-t[0]-t[5]),e[3]=(t[1]-t[4])/o,e[0]=(t[8]+t[2])/o,e[1]=(t[6]+t[9])/o,e[2]=.25*o);return e},t.fromRotationTranslationScale=function(e,t,i,o){var r=t[0],n=t[1],a=t[2],s=t[3],l=r+r,c=n+n,h=a+a,d=r*l,u=r*c,f=r*h,g=n*c,p=n*h,m=a*h,y=s*l,v=s*c,x=s*h,b=o[0],C=o[1],M=o[2];return e[0]=(1-(g+m))*b,e[1]=(u+x)*b,e[2]=(f-v)*b,e[3]=0,e[4]=(u-x)*C,e[5]=(1-(d+m))*C,e[6]=(p+y)*C,e[7]=0,e[8]=(f+v)*M,e[9]=(p-y)*M,e[10]=(1-(d+g))*M,e[11]=0,e[12]=i[0],e[13]=i[1],e[14]=i[2],e[15]=1,e},t.fromRotationTranslationScaleOrigin=function(e,t,i,o,r){var n=t[0],a=t[1],s=t[2],l=t[3],c=n+n,h=a+a,d=s+s,u=n*c,f=n*h,g=n*d,p=a*h,m=a*d,y=s*d,v=l*c,x=l*h,b=l*d,C=o[0],M=o[1],_=o[2],A=r[0],R=r[1],P=r[2];return e[0]=(1-(p+y))*C,e[1]=(f+b)*C,e[2]=(g-x)*C,e[3]=0,e[4]=(f-b)*M,e[5]=(1-(u+y))*M,e[6]=(m+v)*M,e[7]=0,e[8]=(g+x)*_,e[9]=(m-v)*_,e[10]=(1-(u+p))*_,e[11]=0,e[12]=i[0]+A-(e[0]*A+e[4]*R+e[8]*P),e[13]=i[1]+R-(e[1]*A+e[5]*R+e[9]*P),e[14]=i[2]+P-(e[2]*A+e[6]*R+e[10]*P),e[15]=1,e},t.fromQuat=function(e,t){var i=t[0],o=t[1],r=t[2],n=t[3],a=i+i,s=o+o,l=r+r,c=i*a,h=o*a,d=o*s,u=r*a,f=r*s,g=r*l,p=n*a,m=n*s,y=n*l;return e[0]=1-d-g,e[1]=h+y,e[2]=u-m,e[3]=0,e[4]=h-y,e[5]=1-c-g,e[6]=f+p,e[7]=0,e[8]=u+m,e[9]=f-p,e[10]=1-c-d,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},t.frustum=function(e,t,i,o,r,n,a){var s=1/(i-t),l=1/(r-o),c=1/(n-a);return e[0]=2*n*s,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=2*n*l,e[6]=0,e[7]=0,e[8]=(i+t)*s,e[9]=(r+o)*l,e[10]=(a+n)*c,e[11]=-1,e[12]=0,e[13]=0,e[14]=a*n*2*c,e[15]=0,e},t.perspective=function(e,t,i,o,r){var n=1/Math.tan(t/2),a=1/(o-r);return e[0]=n/i,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=n,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=(r+o)*a,e[11]=-1,e[12]=0,e[13]=0,e[14]=2*r*o*a,e[15]=0,e},t.perspectiveFromFieldOfView=function(e,t,i,o){var r=Math.tan(t.upDegrees*Math.PI/180),n=Math.tan(t.downDegrees*Math.PI/180),a=Math.tan(t.leftDegrees*Math.PI/180),s=Math.tan(t.rightDegrees*Math.PI/180),l=2/(a+s),c=2/(r+n);return e[0]=l,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=c,e[6]=0,e[7]=0,e[8]=-(a-s)*l*.5,e[9]=(r-n)*c*.5,e[10]=o/(i-o),e[11]=-1,e[12]=0,e[13]=0,e[14]=o*i/(i-o),e[15]=0,e},t.ortho=function(e,t,i,o,r,n,a){var s=1/(t-i),l=1/(o-r),c=1/(n-a);return e[0]=-2*s,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=-2*l,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=2*c,e[11]=0,e[12]=(t+i)*s,e[13]=(r+o)*l,e[14]=(a+n)*c,e[15]=1,e},t.lookAt=function(e,t,i,r){var n=void 0,a=void 0,s=void 0,l=void 0,c=void 0,h=void 0,d=void 0,u=void 0,f=void 0,g=void 0,p=t[0],m=t[1],y=t[2],v=r[0],x=r[1],b=r[2],C=i[0],M=i[1],_=i[2];if(Math.abs(p-C)0&&(f=1/Math.sqrt(f),h*=f,d*=f,u*=f);var g=l*u-c*d,p=c*h-s*u,m=s*d-l*h;return e[0]=g,e[1]=p,e[2]=m,e[3]=0,e[4]=d*m-u*p,e[5]=u*g-h*m,e[6]=h*p-d*g,e[7]=0,e[8]=h,e[9]=d,e[10]=u,e[11]=0,e[12]=r,e[13]=n,e[14]=a,e[15]=1,e},t.str=function(e){return"mat4("+e[0]+", "+e[1]+", "+e[2]+", "+e[3]+", "+e[4]+", "+e[5]+", "+e[6]+", "+e[7]+", "+e[8]+", "+e[9]+", "+e[10]+", "+e[11]+", "+e[12]+", "+e[13]+", "+e[14]+", "+e[15]+")"},t.frob=function(e){return Math.sqrt(Math.pow(e[0],2)+Math.pow(e[1],2)+Math.pow(e[2],2)+Math.pow(e[3],2)+Math.pow(e[4],2)+Math.pow(e[5],2)+Math.pow(e[6],2)+Math.pow(e[7],2)+Math.pow(e[8],2)+Math.pow(e[9],2)+Math.pow(e[10],2)+Math.pow(e[11],2)+Math.pow(e[12],2)+Math.pow(e[13],2)+Math.pow(e[14],2)+Math.pow(e[15],2))},t.add=function(e,t,i){return e[0]=t[0]+i[0],e[1]=t[1]+i[1],e[2]=t[2]+i[2],e[3]=t[3]+i[3],e[4]=t[4]+i[4],e[5]=t[5]+i[5],e[6]=t[6]+i[6],e[7]=t[7]+i[7],e[8]=t[8]+i[8],e[9]=t[9]+i[9],e[10]=t[10]+i[10],e[11]=t[11]+i[11],e[12]=t[12]+i[12],e[13]=t[13]+i[13],e[14]=t[14]+i[14],e[15]=t[15]+i[15],e},t.subtract=n,t.multiplyScalar=function(e,t,i){return e[0]=t[0]*i,e[1]=t[1]*i,e[2]=t[2]*i,e[3]=t[3]*i,e[4]=t[4]*i,e[5]=t[5]*i,e[6]=t[6]*i,e[7]=t[7]*i,e[8]=t[8]*i,e[9]=t[9]*i,e[10]=t[10]*i,e[11]=t[11]*i,e[12]=t[12]*i,e[13]=t[13]*i,e[14]=t[14]*i,e[15]=t[15]*i,e},t.multiplyScalarAndAdd=function(e,t,i,o){return e[0]=t[0]+i[0]*o,e[1]=t[1]+i[1]*o,e[2]=t[2]+i[2]*o,e[3]=t[3]+i[3]*o,e[4]=t[4]+i[4]*o,e[5]=t[5]+i[5]*o,e[6]=t[6]+i[6]*o,e[7]=t[7]+i[7]*o,e[8]=t[8]+i[8]*o,e[9]=t[9]+i[9]*o,e[10]=t[10]+i[10]*o,e[11]=t[11]+i[11]*o,e[12]=t[12]+i[12]*o,e[13]=t[13]+i[13]*o,e[14]=t[14]+i[14]*o,e[15]=t[15]+i[15]*o,e},t.exactEquals=function(e,t){return e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&e[4]===t[4]&&e[5]===t[5]&&e[6]===t[6]&&e[7]===t[7]&&e[8]===t[8]&&e[9]===t[9]&&e[10]===t[10]&&e[11]===t[11]&&e[12]===t[12]&&e[13]===t[13]&&e[14]===t[14]&&e[15]===t[15]},t.equals=function(e,t){var i=e[0],r=e[1],n=e[2],a=e[3],s=e[4],l=e[5],c=e[6],h=e[7],d=e[8],u=e[9],f=e[10],g=e[11],p=e[12],m=e[13],y=e[14],v=e[15],x=t[0],b=t[1],C=t[2],M=t[3],_=t[4],A=t[5],R=t[6],P=t[7],T=t[8],L=t[9],S=t[10],w=t[11],E=t[12],D=t[13],I=t[14],O=t[15];return Math.abs(i-x)<=o.EPSILON*Math.max(1,Math.abs(i),Math.abs(x))&&Math.abs(r-b)<=o.EPSILON*Math.max(1,Math.abs(r),Math.abs(b))&&Math.abs(n-C)<=o.EPSILON*Math.max(1,Math.abs(n),Math.abs(C))&&Math.abs(a-M)<=o.EPSILON*Math.max(1,Math.abs(a),Math.abs(M))&&Math.abs(s-_)<=o.EPSILON*Math.max(1,Math.abs(s),Math.abs(_))&&Math.abs(l-A)<=o.EPSILON*Math.max(1,Math.abs(l),Math.abs(A))&&Math.abs(c-R)<=o.EPSILON*Math.max(1,Math.abs(c),Math.abs(R))&&Math.abs(h-P)<=o.EPSILON*Math.max(1,Math.abs(h),Math.abs(P))&&Math.abs(d-T)<=o.EPSILON*Math.max(1,Math.abs(d),Math.abs(T))&&Math.abs(u-L)<=o.EPSILON*Math.max(1,Math.abs(u),Math.abs(L))&&Math.abs(f-S)<=o.EPSILON*Math.max(1,Math.abs(f),Math.abs(S))&&Math.abs(g-w)<=o.EPSILON*Math.max(1,Math.abs(g),Math.abs(w))&&Math.abs(p-E)<=o.EPSILON*Math.max(1,Math.abs(p),Math.abs(E))&&Math.abs(m-D)<=o.EPSILON*Math.max(1,Math.abs(m),Math.abs(D))&&Math.abs(y-I)<=o.EPSILON*Math.max(1,Math.abs(y),Math.abs(I))&&Math.abs(v-O)<=o.EPSILON*Math.max(1,Math.abs(v),Math.abs(O))};var o=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t.default=e,t}(i(0));function r(e,t,i){var o=t[0],r=t[1],n=t[2],a=t[3],s=t[4],l=t[5],c=t[6],h=t[7],d=t[8],u=t[9],f=t[10],g=t[11],p=t[12],m=t[13],y=t[14],v=t[15],x=i[0],b=i[1],C=i[2],M=i[3];return e[0]=x*o+b*s+C*d+M*p,e[1]=x*r+b*l+C*u+M*m,e[2]=x*n+b*c+C*f+M*y,e[3]=x*a+b*h+C*g+M*v,x=i[4],b=i[5],C=i[6],M=i[7],e[4]=x*o+b*s+C*d+M*p,e[5]=x*r+b*l+C*u+M*m,e[6]=x*n+b*c+C*f+M*y,e[7]=x*a+b*h+C*g+M*v,x=i[8],b=i[9],C=i[10],M=i[11],e[8]=x*o+b*s+C*d+M*p,e[9]=x*r+b*l+C*u+M*m,e[10]=x*n+b*c+C*f+M*y,e[11]=x*a+b*h+C*g+M*v,x=i[12],b=i[13],C=i[14],M=i[15],e[12]=x*o+b*s+C*d+M*p,e[13]=x*r+b*l+C*u+M*m,e[14]=x*n+b*c+C*f+M*y,e[15]=x*a+b*h+C*g+M*v,e}function n(e,t,i){return e[0]=t[0]-i[0],e[1]=t[1]-i[1],e[2]=t[2]-i[2],e[3]=t[3]-i[3],e[4]=t[4]-i[4],e[5]=t[5]-i[5],e[6]=t[6]-i[6],e[7]=t[7]-i[7],e[8]=t[8]-i[8],e[9]=t[9]-i[9],e[10]=t[10]-i[10],e[11]=t[11]-i[11],e[12]=t[12]-i[12],e[13]=t[13]-i[13],e[14]=t[14]-i[14],e[15]=t[15]-i[15],e}t.mul=r,t.sub=n},function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.setAxes=t.sqlerp=t.rotationTo=t.equals=t.exactEquals=t.normalize=t.sqrLen=t.squaredLength=t.len=t.length=t.lerp=t.dot=t.scale=t.mul=t.add=t.set=t.copy=t.fromValues=t.clone=void 0,t.create=l,t.identity=function(e){return e[0]=0,e[1]=0,e[2]=0,e[3]=1,e},t.setAxisAngle=c,t.getAxisAngle=function(e,t){var i=2*Math.acos(t[3]),o=Math.sin(i/2);0!=o?(e[0]=t[0]/o,e[1]=t[1]/o,e[2]=t[2]/o):(e[0]=1,e[1]=0,e[2]=0);return i},t.multiply=h,t.rotateX=function(e,t,i){i*=.5;var o=t[0],r=t[1],n=t[2],a=t[3],s=Math.sin(i),l=Math.cos(i);return e[0]=o*l+a*s,e[1]=r*l+n*s,e[2]=n*l-r*s,e[3]=a*l-o*s,e},t.rotateY=function(e,t,i){i*=.5;var o=t[0],r=t[1],n=t[2],a=t[3],s=Math.sin(i),l=Math.cos(i);return e[0]=o*l-n*s,e[1]=r*l+a*s,e[2]=n*l+o*s,e[3]=a*l-r*s,e},t.rotateZ=function(e,t,i){i*=.5;var o=t[0],r=t[1],n=t[2],a=t[3],s=Math.sin(i),l=Math.cos(i);return e[0]=o*l+r*s,e[1]=r*l-o*s,e[2]=n*l+a*s,e[3]=a*l-n*s,e},t.calculateW=function(e,t){var i=t[0],o=t[1],r=t[2];return e[0]=i,e[1]=o,e[2]=r,e[3]=Math.sqrt(Math.abs(1-i*i-o*o-r*r)),e},t.slerp=d,t.invert=function(e,t){var i=t[0],o=t[1],r=t[2],n=t[3],a=i*i+o*o+r*r+n*n,s=a?1/a:0;return e[0]=-i*s,e[1]=-o*s,e[2]=-r*s,e[3]=n*s,e},t.conjugate=function(e,t){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=t[3],e},t.fromMat3=u,t.fromEuler=function(e,t,i,o){var r=.5*Math.PI/180;t*=r,i*=r,o*=r;var n=Math.sin(t),a=Math.cos(t),s=Math.sin(i),l=Math.cos(i),c=Math.sin(o),h=Math.cos(o);return e[0]=n*l*h-a*s*c,e[1]=a*s*h+n*l*c,e[2]=a*l*c-n*s*h,e[3]=a*l*h+n*s*c,e},t.str=function(e){return"quat("+e[0]+", "+e[1]+", "+e[2]+", "+e[3]+")"};var o=s(i(0)),r=s(i(1)),n=s(i(2)),a=s(i(3));function s(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t.default=e,t}function l(){var e=new o.ARRAY_TYPE(4);return e[0]=0,e[1]=0,e[2]=0,e[3]=1,e}function c(e,t,i){i*=.5;var o=Math.sin(i);return e[0]=o*t[0],e[1]=o*t[1],e[2]=o*t[2],e[3]=Math.cos(i),e}function h(e,t,i){var o=t[0],r=t[1],n=t[2],a=t[3],s=i[0],l=i[1],c=i[2],h=i[3];return e[0]=o*h+a*s+r*c-n*l,e[1]=r*h+a*l+n*s-o*c,e[2]=n*h+a*c+o*l-r*s,e[3]=a*h-o*s-r*l-n*c,e}function d(e,t,i,o){var r=t[0],n=t[1],a=t[2],s=t[3],l=i[0],c=i[1],h=i[2],d=i[3],u=void 0,f=void 0,g=void 0,p=void 0,m=void 0;return(f=r*l+n*c+a*h+s*d)<0&&(f=-f,l=-l,c=-c,h=-h,d=-d),1-f>1e-6?(u=Math.acos(f),g=Math.sin(u),p=Math.sin((1-o)*u)/g,m=Math.sin(o*u)/g):(p=1-o,m=o),e[0]=p*r+m*l,e[1]=p*n+m*c,e[2]=p*a+m*h,e[3]=p*s+m*d,e}function u(e,t){var i=t[0]+t[4]+t[8],o=void 0;if(i>0)o=Math.sqrt(i+1),e[3]=.5*o,o=.5/o,e[0]=(t[5]-t[7])*o,e[1]=(t[6]-t[2])*o,e[2]=(t[1]-t[3])*o;else{var r=0;t[4]>t[0]&&(r=1),t[8]>t[3*r+r]&&(r=2);var n=(r+1)%3,a=(r+2)%3;o=Math.sqrt(t[3*r+r]-t[3*n+n]-t[3*a+a]+1),e[r]=.5*o,o=.5/o,e[3]=(t[3*n+a]-t[3*a+n])*o,e[n]=(t[3*n+r]+t[3*r+n])*o,e[a]=(t[3*a+r]+t[3*r+a])*o}return e}t.clone=a.clone,t.fromValues=a.fromValues,t.copy=a.copy,t.set=a.set,t.add=a.add,t.mul=h,t.scale=a.scale,t.dot=a.dot,t.lerp=a.lerp;var f,g,p,m,y,v,x=t.length=a.length,b=(t.len=x,t.squaredLength=a.squaredLength),C=(t.sqrLen=b,t.normalize=a.normalize);t.exactEquals=a.exactEquals,t.equals=a.equals,t.rotationTo=(f=n.create(),g=n.fromValues(1,0,0),p=n.fromValues(0,1,0),function(e,t,i){var o=n.dot(t,i);return o<-.999999?(n.cross(f,g,t),n.len(f)<1e-6&&n.cross(f,p,t),n.normalize(f,f),c(e,f,Math.PI),e):o>.999999?(e[0]=0,e[1]=0,e[2]=0,e[3]=1,e):(n.cross(f,t,i),e[0]=f[0],e[1]=f[1],e[2]=f[2],e[3]=1+o,C(e,e))}),t.sqlerp=(m=l(),y=l(),function(e,t,i,o,r,n){return d(m,t,r,n),d(y,i,o,n),d(e,m,y,2*n*(1-n)),e}),t.setAxes=(v=r.create(),function(e,t,i,o){return v[0]=i[0],v[3]=i[1],v[6]=i[2],v[1]=o[0],v[4]=o[1],v[7]=o[2],v[2]=-t[0],v[5]=-t[1],v[8]=-t[2],C(e,u(e,v))})},function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.forEach=t.sqrLen=t.sqrDist=t.dist=t.div=t.mul=t.sub=t.len=void 0,t.create=r,t.clone=function(e){var t=new o.ARRAY_TYPE(2);return t[0]=e[0],t[1]=e[1],t},t.fromValues=function(e,t){var i=new o.ARRAY_TYPE(2);return i[0]=e,i[1]=t,i},t.copy=function(e,t){return e[0]=t[0],e[1]=t[1],e},t.set=function(e,t,i){return e[0]=t,e[1]=i,e},t.add=function(e,t,i){return e[0]=t[0]+i[0],e[1]=t[1]+i[1],e},t.subtract=n,t.multiply=a,t.divide=s,t.ceil=function(e,t){return e[0]=Math.ceil(t[0]),e[1]=Math.ceil(t[1]),e},t.floor=function(e,t){return e[0]=Math.floor(t[0]),e[1]=Math.floor(t[1]),e},t.min=function(e,t,i){return e[0]=Math.min(t[0],i[0]),e[1]=Math.min(t[1],i[1]),e},t.max=function(e,t,i){return e[0]=Math.max(t[0],i[0]),e[1]=Math.max(t[1],i[1]),e},t.round=function(e,t){return e[0]=Math.round(t[0]),e[1]=Math.round(t[1]),e},t.scale=function(e,t,i){return e[0]=t[0]*i,e[1]=t[1]*i,e},t.scaleAndAdd=function(e,t,i,o){return e[0]=t[0]+i[0]*o,e[1]=t[1]+i[1]*o,e},t.distance=l,t.squaredDistance=c,t.length=h,t.squaredLength=d,t.negate=function(e,t){return e[0]=-t[0],e[1]=-t[1],e},t.inverse=function(e,t){return e[0]=1/t[0],e[1]=1/t[1],e},t.normalize=function(e,t){var i=t[0],o=t[1],r=i*i+o*o;r>0&&(r=1/Math.sqrt(r),e[0]=t[0]*r,e[1]=t[1]*r);return e},t.dot=function(e,t){return e[0]*t[0]+e[1]*t[1]},t.cross=function(e,t,i){var o=t[0]*i[1]-t[1]*i[0];return e[0]=e[1]=0,e[2]=o,e},t.lerp=function(e,t,i,o){var r=t[0],n=t[1];return e[0]=r+o*(i[0]-r),e[1]=n+o*(i[1]-n),e},t.random=function(e,t){t=t||1;var i=2*o.RANDOM()*Math.PI;return e[0]=Math.cos(i)*t,e[1]=Math.sin(i)*t,e},t.transformMat2=function(e,t,i){var o=t[0],r=t[1];return e[0]=i[0]*o+i[2]*r,e[1]=i[1]*o+i[3]*r,e},t.transformMat2d=function(e,t,i){var o=t[0],r=t[1];return e[0]=i[0]*o+i[2]*r+i[4],e[1]=i[1]*o+i[3]*r+i[5],e},t.transformMat3=function(e,t,i){var o=t[0],r=t[1];return e[0]=i[0]*o+i[3]*r+i[6],e[1]=i[1]*o+i[4]*r+i[7],e},t.transformMat4=function(e,t,i){var o=t[0],r=t[1];return e[0]=i[0]*o+i[4]*r+i[12],e[1]=i[1]*o+i[5]*r+i[13],e},t.str=function(e){return"vec2("+e[0]+", "+e[1]+")"},t.exactEquals=function(e,t){return e[0]===t[0]&&e[1]===t[1]},t.equals=function(e,t){var i=e[0],r=e[1],n=t[0],a=t[1];return Math.abs(i-n)<=o.EPSILON*Math.max(1,Math.abs(i),Math.abs(n))&&Math.abs(r-a)<=o.EPSILON*Math.max(1,Math.abs(r),Math.abs(a))};var o=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t.default=e,t}(i(0));function r(){var e=new o.ARRAY_TYPE(2);return e[0]=0,e[1]=0,e}function n(e,t,i){return e[0]=t[0]-i[0],e[1]=t[1]-i[1],e}function a(e,t,i){return e[0]=t[0]*i[0],e[1]=t[1]*i[1],e}function s(e,t,i){return e[0]=t[0]/i[0],e[1]=t[1]/i[1],e}function l(e,t){var i=t[0]-e[0],o=t[1]-e[1];return Math.sqrt(i*i+o*o)}function c(e,t){var i=t[0]-e[0],o=t[1]-e[1];return i*i+o*o}function h(e){var t=e[0],i=e[1];return Math.sqrt(t*t+i*i)}function d(e){var t=e[0],i=e[1];return t*t+i*i}var u;t.len=h,t.sub=n,t.mul=a,t.div=s,t.dist=l,t.sqrDist=c,t.sqrLen=d,t.forEach=(u=r(),function(e,t,i,o,r,n){var a=void 0,s=void 0;for(t||(t=2),i||(i=0),s=o?Math.min(o*t+i,e.length):e.length,a=i;a>3,e.origin=(e.flags&t.Origin.MASK)>>t.Origin.SHIFT,e.alphaBits=e.flags&t.Origin.ALPHA}function r(e){if(e.imageType===t.Type.NO_DATA)throw new Error("Targa::checkHeader() - No data");if(e.hasColorMap){if(e.colorMapLength>256||1!==e.colorMapType)throw new Error("Targa::checkHeader() - Unsupported colormap for indexed type");if(16!==e.colorMapDepth&&24!==e.colorMapDepth&&32!==e.colorMapDepth)throw new Error("Targa::checkHeader() - Unsupported colormap depth")}else if(e.colorMapType)throw new Error("Targa::checkHeader() - Why does the image contain a palette ?");if(e.width<=0||e.height<=0)throw new Error("Targa::checkHeader() - Invalid image size");if(8!==e.pixelDepth&&16!==e.pixelDepth&&24!==e.pixelDepth&&32!==e.pixelDepth)throw new Error('Targa::checkHeader() - Invalid pixel size "'+e.pixelDepth+'"');if(0!==e.alphaBits&&1!==e.alphaBits&&8!==e.alphaBits)throw new Error("Targa::checkHeader() - Unsuppported alpha size")}function n(e,t,i,o,r,n,a,s,l,c){var h,d,u,f,g,p,m=this.header.colorMapDepth>>3;for(f=0,p=r;p!==a;p+=n)for(g=s;g!==c;g+=l,f++)u=4*(g+o*p),d=t[f]*m,4===m?(e[u]=i[d+2],e[u+1]=i[d+1],e[u+2]=i[d],e[u+3]=i[d+3]):3===m?(e[u]=i[d+2],e[u+1]=i[d+1],e[u+2]=i[d],e[u+3]=255):2===m&&(h=i[d]|i[d+1]<<8,e[u]=(31744&h)>>7,e[u+1]=(992&h)>>2,e[u+2]=(31&h)<<3,e[u+3]=32768&h?0:255);return e}function a(e,t,i,o,r,n,a,s,l,c){var h,d,u,f,g;for(u=0,g=r;g!==a;g+=n)for(f=s;f!==c;f+=l,u+=2)h=t[u]|t[u+1]<<8,e[d=4*(f+o*g)]=(31744&h)>>7,e[d+1]=(992&h)>>2,e[d+2]=(31&h)<<3,e[d+3]=32768&h?0:255;return e}function s(e,t,i,o,r,n,a,s,l,c){var h,d,u,f,g=this.header.pixelDepth>>3;for(d=0,f=r;f!==a;f+=n)for(u=s;u!==c;u+=l,d+=g)e[(h=4*(u+o*f))+3]=255,e[h+2]=t[d],e[h+1]=t[d+1],e[h]=t[d+2];return e}function l(e,t,i,o,r,n,a,s,l,c){var h,d,u,f;for(h=0,u=r;u!==a;u+=n)for(d=s;d!==c;d+=l,h+=4)e[(f=4*(d+o*u))+2]=t[h],e[f+1]=t[h+1],e[f]=t[h+2],e[f+3]=t[h+3];return e}function c(e,t,i,o,r,n,a,s,l,c){var h,d,u,f,g;for(h=0,u=r;u!==a;u+=n)for(d=s;d!==c;d+=l,h+=4)f=4*(d+o*u),g=255*t[h+3],e[f+2]=t[h]/g,e[f+1]=t[h+1]/g,e[f]=t[h+2]/g,e[f+3]=t[h+3];return e}function h(e,t,i,o,r,n,a,s,l,c){var h,d,u,f,g;for(u=0,g=r;g!==a;g+=n)for(f=s;f!==c;f+=l,u++)h=t[u],e[d=4*(f+o*g)]=h,e[d+1]=h,e[d+2]=h,e[d+3]=255;return e}function d(e,t,i,o,r,n,a,s,l,c){var h,d,u,f,g;for(u=0,g=r;g!==a;g+=n)for(f=s;f!==c;f+=l,u+=2)h=t[u],e[d=4*(f+o*g)]=h,e[d+1]=h,e[d+2]=h,e[d+3]=t[u+1];return e}function u(e){var i=e.byteLength-t.FOOTER_SIZE,o=t.SIGNATURE,r={},n=new Uint8Array(e.buffer,i+8,o.length);return function(e){for(var i=t.SIGNATURE,o=0;o=e.byteLength)throw new Error("Targa::load() - No data");if(this.header.hasColorMap){var a=this.header.colorMapLength*(this.header.colorMapDepth>>3);this.palette=new Uint8Array(e,n,a),n+=a}var s=this.header.pixelDepth>>3,l=this.header.width*this.header.height,c=l*s;if(this.header.hasEncoding){var h=e.byteLength-n-t.FOOTER_SIZE,d=new Uint8Array(e,n,h);this.imageData=function(e,i,o){var r,n,a,s,l,c,h;for(h=new Uint8Array(o),c=new Uint8Array(i),l=0,r=0;ro)throw new Error("Targa::decodeRLE() - Read bytes: "+r+" Expected bytes: "+o);return h}(d,s,c)}else this.imageData=new Uint8Array(e,n,this.header.hasColorMap?l:c);this.footer=u(i),(0!==this.header.alphaBits||this.footer.hasExtensionArea&&(3===this.footer.attributeType||4===this.footer.attributeType))&&(this.footer.usesAlpha=!0)},t.prototype.getImageData=function(e){var i,o,r,u,f,g,p,m=this.header.width,y=this.header.height,v=(this.header.flags&t.Origin.MASK)>>t.Origin.SHIFT;switch(e||(e=document?document.createElement("canvas").getContext("2d").createImageData(m,y):{width:m,height:y,data:new Uint8ClampedArray(m*y*4)}),v===t.Origin.TOP_LEFT||v===t.Origin.TOP_RIGHT?(u=0,f=1,g=y):(u=y-1,f=-1,g=-1),v===t.Origin.TOP_LEFT||v===t.Origin.BOTTOM_LEFT?(i=0,o=1,r=m):(i=m-1,o=-1,r=-1),this.header.pixelDepth){case 8:p=this.header.isGreyColor?h:n;break;case 16:p=this.header.isGreyColor?d:a;break;case 24:p=s;break;case 32:p=this.footer.hasExtensionArea?3===this.footer.attributeType?l:4===this.footer.attributeType?c:s:0!==this.header.alphaBits?l:s}return p.call(this,e.data,this.imageData,this.palette,m,u,f,g,i,o,r),e},t.prototype.setImageData=function(e){if(!e)throw new Error("Targa::setImageData() - imageData argument missing");var i,o,r,n,a,s,c=this.header.width,h=this.header.height,d=c*h*(this.header.pixelDepth>>3),u=(this.header.flags&t.Origin.MASK)>>t.Origin.SHIFT;u===t.Origin.TOP_LEFT||u===t.Origin.TOP_RIGHT?(n=0,a=1,s=h):(n=h-1,a=-1,s=-1),u===t.Origin.TOP_LEFT||u===t.Origin.BOTTOM_LEFT?(i=0,o=1,r=c):(i=c-1,o=-1,r=-1),this.imageData||(this.imageData=new Uint8Array(d)),l(this.imageData,e.data,this.palette,c,n,a,s,i,o,r);var f=this.imageData;this.header.hasEncoding&&(f=function(e,i){for(var o,r,n,a,s=i,l=[],c=0,h=e.pixelDepth>>3,d=0,u=e.width*e.height*h,f=function(e,t){for(var i=0;i=0&&e7e7);var n=i.vboMemoryManager;this.fileLoadState=CODE.fileLoadState.PARSE_STARTED,this.bbox=new BoundingBox;var a=this.bbox,s=this.vbo_vicks_container.newVBOVertexIdxCacheKey();a.minX=o.readFloat32(),a.minY=o.readFloat32(),a.minZ=o.readFloat32(),a.maxX=o.readFloat32(),a.maxY=o.readFloat32(),a.maxZ=o.readFloat32(),this.bPositionsCompressed=o.readInt8();var l,c=3*r,h=n.getClassifiedBufferSize(c);if(this.bPositionsCompressed?(l=new Uint16Array(h)).set(o.readUint16Array(3*r)):(l=new Float32Array(h)).set(o.readFloat32Array(3*r)),s.vertexCount=r,s.posVboDataArray=l,s.posArrayByteSize=h,s.posArrayByteType=5123,this.hasNormals=o.readInt8(),this.hasColors=o.readInt8(),this.hasColors){var d=r,u=4*d,f=n.getClassifiedBufferSize(u),g=new Uint8Array(f);g.set(o.readUint8Array(4*d)),s.colVboDataArray=g,s.colArrayByteSize=f,s.colArrayByteType=5121}this.hasTexCoords=o.readInt8(),this.hasIndices=o.readInt8(),this.fileLoadState=CODE.fileLoadState.PARSE_FINISHED}},Lego.prototype.parseLegoData=function(e,t,i){if(this.fileLoadState===CODE.fileLoadState.LOADING_FINISHED){var o=i.vboMemoryManager,r=new DataStream(e,0,DataStream.LITTLE_ENDIAN);this.fileLoadState=CODE.fileLoadState.PARSE_STARTED,this.bbox=new BoundingBox;var n=this.bbox,a=this.vbo_vicks_container.newVBOVertexIdxCacheKey();n.minX=r.readFloat32(),n.minY=r.readFloat32(),n.minZ=r.readFloat32(),n.maxX=r.readFloat32(),n.maxY=r.readFloat32(),n.maxZ=r.readFloat32();var s=r.readUint32(),l=3*s,c=o.getClassifiedBufferSize(l),h=new Float32Array(c);if(h.set(r.readFloat32Array(3*s)),a.vertexCount=s,a.posVboDataArray=h,a.posArrayByteSize=c,r.readUint8()){var d=r.readUint32(),u=3*d,f=o.getClassifiedBufferSize(u),g=new Int8Array(f);g.set(r.readInt8Array(3*d)),a.norVboDataArray=g,a.norArrayByteSize=f}if(r.readUint8()){var p=r.readUint32(),m=4*p,y=o.getClassifiedBufferSize(m),v=new Uint8Array(y);v.set(r.readUint8Array(4*p)),a.colVboDataArray=v,a.colArrayByteSize=y}if(this.hasTexCoords=r.readUint8(),this.hasTexCoords){r.readUint16();var x=r.readUint32(),b=2*x,C=o.getClassifiedBufferSize(b),M=new Float32Array(C);M.set(r.readFloat32Array(2*x)),a.tcoordVboDataArray=M,a.tcoordArrayByteSize=C}this.fileLoadState=CODE.fileLoadState.PARSE_FINISHED;var _=!0;return a.isReadyPositions(t,i.vboMemoryManager)||(_=!1),a.isReadyNormals(t,i.vboMemoryManager)||(_=!1),a.isReadyColors(t,i.vboMemoryManager)||(_=!1),this.hasTexCoords&&(a.isReadyTexCoords(t,i.vboMemoryManager)||(_=!1)),_}};var LoadData=function(){if(!(this instanceof LoadData))throw new Error(Messages.CONSTRUCT_ERROR);this.dataType,this.distToCam,this.lod,this.filePath,this.texFilePath,this.skinMesh,this.octree,this.texture};LoadData.prototype.deleteObjects=function(){this.dataType=void 0,this.distToCam=void 0,this.lod=void 0,this.filePath=void 0,this.texFilePath=void 0,this.skinMesh=void 0,this.octree=void 0,this.texture=void 0};var LoadQueue=function(e){if(!(this instanceof LoadQueue))throw new Error(Messages.CONSTRUCT_ERROR);this.magoManager,void 0!==e&&(this.magoManager=e),this.lod2SkinDataMap={},this.lod2PCloudDataMap={},this.lowLodSkinDataMap={},this.lowLodSkinTextureMap={}};LoadQueue.prototype.putLod2SkinData=function(e,t,i,o,r){e.lego.fileLoadState=CODE.fileLoadState.IN_QUEUE;var n=new LoadData;n.filePath=t,n.octree=e,n.texFilePath=o,n.texture=i,this.lod2SkinDataMap[t]=n},LoadQueue.prototype.putLod2PCloudData=function(e,t,i,o,r){e.lego.fileLoadState=CODE.fileLoadState.IN_QUEUE;var n=new LoadData;n.filePath=t,n.octree=e,n.texFilePath=o,n.texture=i,this.lod2PCloudDataMap[t]=n},LoadQueue.prototype.putLowLodSkinData=function(e,t,i){e.fileLoadState=CODE.fileLoadState.IN_QUEUE;var o=new LoadData;o.dataType=3,o.filePath=t,o.skinMesh=e,this.lowLodSkinDataMap[e.legoKey]=o},LoadQueue.prototype.putLowLodSkinTexture=function(e,t,i){t.fileLoadState=CODE.fileLoadState.IN_QUEUE;var o=new LoadData;o.dataType=4,o.filePath=e,o.texture=t,this.lowLodSkinTextureMap[e]=o},LoadQueue.prototype.resetQueue=function(){for(var e in this.lod2SkinDataMap){void 0!==(t=this.lod2SkinDataMap[e]).octree&&void 0!==t.octree.lego&&(t.octree.lego.fileLoadState=CODE.fileLoadState.READY)}for(var e in this.lod2SkinDataMap={},this.lowLodSkinDataMap){void 0!==(t=this.lowLodSkinDataMap[e]).skinMesh&&(t.skinMesh.fileLoadState=CODE.fileLoadState.READY)}for(var e in this.lowLodSkinDataMap={},this.lowLodSkinTextureMap){void 0!==(t=this.lowLodSkinTextureMap[e]).texture&&(t.texture.fileLoadState=CODE.fileLoadState.READY)}for(var e in this.lowLodSkinTextureMap={},this.lod2PCloudDataMap){var t;void 0!==(t=this.lod2PCloudDataMap[e]).octree&&void 0!==t.octree.lego&&(t.octree.lego.fileLoadState=CODE.fileLoadState.READY)}this.lod2PCloudDataMap={}},LoadQueue.prototype.manageQueue=function(){var e=this.magoManager.readerWriter,t=this.magoManager.sceneState.gl,i=0;for(var o in i=0,this.lod2SkinDataMap){var r=(s=this.lod2SkinDataMap[o]).octree,n=s.filePath;if(void 0!==r.lego)void 0!==s.texture&&s.texture.fileLoadState===CODE.fileLoadState.READY&&(e.readLegoSimpleBuildingTexture(t,s.texFilePath,s.texture,this.magoManager),i+=4),e.getOctreeLegoArraybuffer(n,r,this.magoManager);else;if(delete this.lod2SkinDataMap[o],s.deleteObjects(),s=void 0,++i>4){!0;break}}if(!this.magoManager.fileRequestControler.isFullPlusLowLodImages()){for(var o in i=0,this.lowLodSkinTextureMap){var a=(s=this.lowLodSkinTextureMap[o]).skinMesh;n=s.filePath;if(e.readLegoSimpleBuildingTexture(t,n,s.texture,this.magoManager),delete this.lowLodSkinTextureMap[o],s.deleteObjects(),s=void 0,++i>1)break}for(var o in i=0,this.lowLodSkinDataMap){a=(s=this.lowLodSkinDataMap[o]).skinMesh,n=s.filePath;if(e.getLegoArraybuffer(n,a,this.magoManager),delete this.lowLodSkinDataMap[o],s.deleteObjects(),s=void 0,++i>1)break}for(var o in i=0,this.lod2PCloudDataMap){var s;r=(s=this.lod2PCloudDataMap[o]).octree,n=s.filePath;if(void 0!==r.lego)e.getOctreePCloudArraybuffer(n,r,this.magoManager);else;if(delete this.lod2PCloudDataMap[o],s.deleteObjects(),s=void 0,++i>4){!0;break}}this.resetQueue()}};var LodBuildingData=function(){if(!(this instanceof LodBuildingData))throw new Error(Messages.CONSTRUCT_ERROR);this.lod,this.isModelRef,this.geometryFileName,this.textureFileName},MetaData=function(){if(!(this instanceof MetaData))throw new Error(Messages.CONSTRUCT_ERROR);this.guid,this.version="",this.geographicCoord,this.heading,this.pitch,this.roll,this.bbox,this.imageLodCount,this.projectDataType,this.offSetX,this.offSetY,this.offSetZ,this.oct_min_x=0,this.oct_max_x=0,this.oct_min_y=0,this.oct_max_y=0,this.oct_min_z=0,this.oct_max_z=0,this.isSmall=!1,this.fileLoadState=CODE.fileLoadState.READY};MetaData.prototype.deleteObjects=function(){this.guid=void 0,this.geographicCoord&&this.geographicCoord.deleteObjects(),this.geographicCoord=void 0,this.heading=void 0,this.pitch=void 0,this.roll=void 0,this.bbox&&this.bbox.deleteObjects(),this.bbox=void 0,this.imageLodCount=void 0,this.oct_min_x=void 0,this.oct_max_x=void 0,this.oct_min_y=void 0,this.oct_max_y=void 0,this.oct_min_z=void 0,this.oct_max_z=void 0,this.isSmall=void 0,this.fileLoadState=void 0},MetaData.prototype.parseFileHeaderAsimetricVersion=function(e,t){var i,o=0;void 0===t&&(t=new ReaderWriter),this.version="";for(var r=0;r<5;r++)this.version+=String.fromCharCode(new Int8Array(e.slice(o,o+1))),o+=1;void 0===this.guid&&(this.guid=""),i=t.readInt32(e,o,o+4),o+=4;for(r=0;r40||this.bbox.maxY-this.bbox.minY>40)&&(n=!0),!n&&this.bbox.maxZ-this.bbox.minZ<30&&(this.isSmall=!0),"0.0.2"===this.version&&(this.projectDataType=new Uint16Array(e.slice(o,o+2))[0],o+=2,this.offSetX=new Float64Array(e.slice(o,o+8))[0],o+=8,this.offSetY=new Float64Array(e.slice(o,o+8))[0],o+=8,this.offSetZ=new Float64Array(e.slice(o,o+8))[0],o+=8),o};var ModelReferencedGroup=function(){if(!(this instanceof ModelReferencedGroup))throw new Error(Messages.CONSTRUCT_ERROR);this.modelIdx,this.referencesIdxArray=[]},ModelReferencedGroupsList=function(){if(!(this instanceof ModelReferencedGroupsList))throw new Error(Messages.CONSTRUCT_ERROR);this.modelReferencedGroupsMap=[],this.modelReferencedGroupsArray=[]};ModelReferencedGroupsList.prototype.getModelReferencedGroup=function(e){var t=this.modelReferencedGroupsMap[e];return void 0===t&&((t=new ModelReferencedGroup).modelIdx=e,this.modelReferencedGroupsMap[e]=t),t},ModelReferencedGroupsList.prototype.makeModelReferencedGroupsArray=function(){this.modelReferencedGroupsArray.length=0;for(var e=this.modelReferencedGroupsMap.length,t=0;t10)return;if(e.texture.fileLoadState===CODE.fileLoadState.READY){var r=t.sceneState.gl;e.texture.texId=r.createTexture();var n=this.projectFolderName,a=t.readerWriter.geometryDataPath+"/"+n+"/"+this.buildingFileName+"/Images_Resized/"+e.texture.textureImageFileName;this.texturesLoaded.push(e.texture),t.readerWriter.readNeoReferenceTexture(r,a,e.texture,this,t),t.backGround_fileReadings_count++}}else o.fileLoadState===CODE.fileLoadState.LOADING_FINISHED&&(e.texture=o)}return e.texture.fileLoadState}if("0"===this.metaData.version[0]&&"0"===this.metaData.version[2]&&"1"===this.metaData.version[4]){if(void 0===e.texture||e.texture.fileLoadState===CODE.fileLoadState.READY){var s=e.materialId;if(i=this.texturesLoaded[s],e.texture=i,void 0===i.texId&&""!==i.textureImageFileName){if(t.backGround_fileReadings_count>10)return;if(i.fileLoadState===CODE.fileLoadState.READY){r=t.sceneState.gl;i.texId=r.createTexture();n=this.projectFolderName,a=t.readerWriter.getCurrentDataPath()+"/"+n+"/"+this.buildingFileName+"/Images_Resized/"+i.textureImageFileName;t.readerWriter.readNeoReferenceTexture(r,a,i,this,t),t.backGround_fileReadings_count++}}}return e.texture.fileLoadState}};var NeoBuildingsList=function(){if(!(this instanceof NeoBuildingsList))throw new Error(Messages.CONSTRUCT_ERROR);this.neoBuildingsArray=[]};NeoBuildingsList.prototype.newNeoBuilding=function(){var e=new NeoBuilding;return this.neoBuildingsArray.push(e),e},NeoBuildingsList.prototype.getNeoBuildingByTypeId=function(e,t){for(var i,o=this.neoBuildingsArray.length,r=!1,n=0;!r&&n0&&(n=!0),n&&o){var a=this.interior_ocCullOctree.getIntersectedSubBoxByPoint3D(e,t,i);void 0!==a&&a._indicesArray.length>0?(this.currentVisibleIndices=a._indicesArray,r=!1):r=!0}else this.currentVisibleIndices=this.neoRefsIndices,this.currentVisibleMRG=this.modelReferencedGroupsList}if(r&&void 0!==this.exterior_ocCullOctree){n=!1;this.exterior_ocCullOctree._subBoxesArray&&this.exterior_ocCullOctree._subBoxesArray.length>0&&(n=!0),n&&o?(void 0===this.currentVisibleMRG&&(this.currentVisibleMRG=new ModelReferencedGroupsList),this.currentVisibleIndices=this.exterior_ocCullOctree.getIndicesVisiblesForEye(e,t,i,this.currentVisibleIndices,this.currentVisibleMRG)):(this.currentVisibleIndices=this.neoRefsIndices,this.currentVisibleMRG=this.modelReferencedGroupsList)}},NeoReferencesMotherAndIndices.prototype.getNeoReference=function(e){return this.motherNeoRefsList[this.neoRefsIndices[e]]},NeoReferencesMotherAndIndices.prototype.deleteObjects=function(e,t){this.motherNeoRefsList=void 0,this.neoRefsIndices=void 0,this.blocksList=void 0,this.fileLoadState=void 0,this.dataArraybuffer=void 0,this.exterior_ocCullOctree=void 0,this.interior_ocCullOctree=void 0},NeoReferencesMotherAndIndices.prototype.setRenderedFalseToAllReferences=function(){for(var e=this.neoRefsIndices.length,t=0;t0&&void 0===x.vBOVertexIdxCacheKeysContainer&&(x.vBOVertexIdxCacheKeysContainer=new VBOVertexIdxCacheKeysContainer);for(V=0;V0){var O=i.readUInt32(t,l,l+4);l+=4;for(E=0;E0&&void 0===m.vBOVertexIdxCacheKeysContainer&&(m.vBOVertexIdxCacheKeysContainer=new VBOVertexIdxCacheKeysContainer);for(E=0;E0){var U,j="";O=i.readUInt32(t,l,l+4);l+=4;for(E=0;E0&&(m.texture=new Texture,m.hasTexture=!0,m.texture.textureTypeName=j,m.texture.textureImageFileName=U)}else m.hasTexture=!1;r&&m.multiplyTransformMatrix(r)}}void 0===this.exterior_ocCullOctree&&(this.exterior_ocCullOctree=new OcclusionCullingOctreeCell);var G=this.exterior_ocCullOctree;l=this.exterior_ocCullOctree.parseArrayBuffer(t,l,i),G.expandBox(1e3),G.setSizesSubBoxes(),G.createModelReferencedGroups(this.motherNeoRefsList),void 0===this.interior_ocCullOctree&&(this.interior_ocCullOctree=new OcclusionCullingOctreeCell);var z=this.interior_ocCullOctree;return l=this.interior_ocCullOctree.parseArrayBuffer(t,l,i),z.setSizesSubBoxes(),z.createModelReferencedGroups(this.motherNeoRefsList),this.fileLoadState=CODE.fileLoadState.PARSE_FINISHED,this.succesfullyGpuDataBinded};var NeoSimpleBuilding=function(){if(!(this instanceof NeoSimpleBuilding))throw new Error(Messages.CONSTRUCT_ERROR);this.accesorsArray=[],this.vbo_vicks_container=new VBOVertexIdxCacheKeysContainer,this.texturesArray=[]};NeoSimpleBuilding.prototype.newAccesor=function(){var e=new Accessor;return this.accesorsArray.push(e),e},NeoSimpleBuilding.prototype.newTexture=function(){var e=new NeoTexture;return this.texturesArray.push(e),e};var NeoTexture=function(){if(!(this instanceof NeoTexture))throw new Error(Messages.CONSTRUCT_ERROR);this.lod,this.textureId,this.texImage,this.loadStarted=!1,this.loadFinished=!1},Node=function(){if(!(this instanceof Node))throw new Error(Messages.CONSTRUCT_ERROR);this.parent,this.children=[],this.data};Node.prototype.deleteObjects=function(e,t){if(this.parent=void 0,this.data&&(this.data.neoBuilding&&(this.data.neoBuilding.deleteObjects(e,t),this.data.neoBuilding=void 0),this.data.geographicCoord&&(this.data.geographicCoord.deleteObjects(),this.data.geographicCoord=void 0),this.data.rotationsDegree&&(this.data.rotationsDegree.deleteObjects(),this.data.rotationsDegree=void 0),this.data.bbox&&(this.data.bbox.deleteObjects(),this.data.bbox=void 0),this.data=void 0),this.children){for(var i=this.children.length,o=0;o0?Math.floor(Math.log10(e)+1):1},Octree.prototype.getMotherOctree=function(){return void 0===this.octree_owner?this:this.octree_owner.getMotherOctree()},Octree.prototype.getOctree=function(e,t){if(1===t)return 0===e?this.getMotherOctree():this.subOctrees_array[e-1];var i=t-1,o=Math.pow(10,i),r=Math.floor(e/o)%10,n=e-r*o;return this.subOctrees_array[r-1].getOctree(n,t-1)},Octree.prototype.getOctreeByNumberName=function(e){var t=this.getMotherOctree(),i=this.getNumberOfDigits(e);if(1===i)return 0===e?t:t.subOctrees_array[e-1];if(0!==t.subOctrees_array.length){var o=i-1,r=Math.pow(10,o),n=Math.floor(e/r)%10,a=e-n*r;return t.subOctrees_array[n-1].getOctree(a,i-1)}},Octree.prototype.setSizesSubBoxes=function(){if(this.subOctrees_array.length>0){var e=this.centerPos.x,t=this.centerPos.y,i=this.centerPos.z,o=this.centerPos.x-this.half_dx,r=this.centerPos.y-this.half_dy,n=this.centerPos.z-this.half_dz,a=this.centerPos.x+this.half_dx,s=this.centerPos.y+this.half_dy,l=this.centerPos.z+this.half_dz;this.subOctrees_array[0].setBoxSize(o,e,r,t,n,i),this.subOctrees_array[1].setBoxSize(e,a,r,t,n,i),this.subOctrees_array[2].setBoxSize(e,a,t,s,n,i),this.subOctrees_array[3].setBoxSize(o,e,t,s,n,i),this.subOctrees_array[4].setBoxSize(o,e,r,t,i,l),this.subOctrees_array[5].setBoxSize(e,a,r,t,i,l),this.subOctrees_array[6].setBoxSize(e,a,t,s,i,l),this.subOctrees_array[7].setBoxSize(o,e,t,s,i,l);for(var c=0;c<8;c++)this.subOctrees_array[c].setSizesSubBoxes()}},Octree.prototype.setBoxSize=function(e,t,i,o,r,n){this.centerPos.x=(t+e)/2,this.centerPos.y=(o+i)/2,this.centerPos.z=(n+r)/2,this.half_dx=(t-e)/2,this.half_dy=(o-i)/2,this.half_dz=(n-r)/2},Octree.prototype.getCenterPos=function(){return this.centerPos},Octree.prototype.getRadiusAprox=function(){return 1.7*this.half_dx},Octree.prototype.getNeoRefListArray=function(e){void 0===e&&(e=[]);var t=this.subOctrees_array.length;if(t>0)for(var i=0;i0&&e.push(this.neoRefsList_Array[0])},Octree.prototype.getFrustumVisibleLowestOctreesByLOD=function(e,t,i,o,r,n,a,s){var l=[],c=!1;this.getFrustumVisibleOctreesNeoBuildingAsimetricVersion(e,l,o);for(var h=l.length,d=0;d0&&(i&&this.putOctreeInEyeDistanceSortedArray(i.currentVisibles0,l[d]),t.currentVisibles0.push(l[d]),c=!0):l[d].distToCamera0&&(i&&this.putOctreeInEyeDistanceSortedArray(i.currentVisibles1,l[d]),t.currentVisibles1.push(l[d]),c=!0):l[d].distToCamera0&&(i&&this.putOctreeInEyeDistanceSortedArray(i.currentVisibles2,l[d]),t.currentVisibles2.push(l[d]),c=!0):l[d].triPolyhedronsCount>0&&(i&&i.currentVisibles3.push(l[d]),t.currentVisibles3.push(l[d]),c=!0);return l=void 0,c},Octree.prototype.intersectsWithPoint3D=function(e,t,i){var o=this.centerPos.x-this.half_dx,r=this.centerPos.y-this.half_dz,n=this.centerPos.z-this.half_dz,a=this.centerPos.x+this.half_dx,s=this.centerPos.y+this.half_dz,l=this.centerPos.z+this.half_dz,c=!1;return e>o&&er&&tn&&i0){var r,n=this.centerPos.x,a=this.centerPos.y,s=this.centerPos.z;r=e0&&(t&&this.putOctreeInEyeDistanceSortedArray(t.currentVisibles0,this.lowestOctrees_array[c]),e.currentVisibles0.push(this.lowestOctrees_array[c]),s=!0):this.lowestOctrees_array[c].distToCamera0&&(t&&this.putOctreeInEyeDistanceSortedArray(t.currentVisibles1,this.lowestOctrees_array[c]),e.currentVisibles1.push(this.lowestOctrees_array[c]),s=!0):this.lowestOctrees_array[c].distToCamera0&&(t&&this.putOctreeInEyeDistanceSortedArray(t.currentVisibles2,this.lowestOctrees_array[c]),e.currentVisibles2.push(this.lowestOctrees_array[c]),s=!0):this.lowestOctrees_array[c].triPolyhedronsCount>0&&(t&&t.currentVisibles3.push(this.lowestOctrees_array[c]),e.currentVisibles3.push(this.lowestOctrees_array[c]),s=!0);return s},Octree.prototype.getFrustumVisibleOctreesNeoBuildingAsimetricVersion=function(e,t,i){if(void 0!==this.subOctrees_array&&(0!==this.subOctrees_array.length||0!==this.triPolyhedronsCount)){void 0===t&&(t=[]),void 0===i&&(i=new Sphere),i.centerPoint.x=this.centerPos.x,i.centerPoint.y=this.centerPos.y,i.centerPoint.z=this.centerPos.z,i.r=this.getRadiusAprox();var o=e.intersectionSphere(i);if(o===Constant.INTERSECTION_INSIDE)this.getAllSubOctreesIfHasRefLists(t);else if(o===Constant.INTERSECTION_INTERSECT)if(0===this.subOctrees_array.length)t.push(this);else for(var r=0,n=this.subOctrees_array.length;rt.distToCamera?(l=i,c=h):(l=h,c=o),this.getIndexToInsertBySquaredDistToEye(e,t,l,c)},Octree.prototype.putOctreeInEyeDistanceSortedArray=function(e,t){if(e.length>0){var i=e.length-1,o=this.getIndexToInsertBySquaredDistToEye(e,t,0,i);e.splice(o,0,t)}else e.push(t)},Octree.prototype.getAllSubOctreesIfHasRefLists=function(e){if(void 0!==this.subOctrees_array)if(void 0===e&&(e=[]),this.subOctrees_array.length>0)for(var t=0,i=this.subOctrees_array.length;t0&&e.push(this)},Octree.prototype.getAllSubOctrees=function(e){if(void 0===e&&(e=[]),this.subOctrees_array.length>0)for(var t=0,i=this.subOctrees_array.length;t0)e.push(this);else for(var i=0;i0)this.neoReferencesMotherAndIndices&&this.neoReferencesMotherAndIndices.multiplyKeyTransformMatrix(e,t);else for(var o=0;o0&&(this.neoBuildingOwner=o);for(var u=0;u0){for(var a=t.currentVisibles0.length,s=0;so));s++);if(0===n)for(var l in this.octreesLod0ReferencesToParseMap)if(Object.prototype.hasOwnProperty.call(foo,l)&&(r=this.octreesLod0ReferencesToParseMap[l],delete this.octreesLod0ReferencesToParseMap[l],this.parseOctreesLod0References(e,r,i),++n>o))break}return n>0},ParseQueue.prototype.parseOctreesLod0References=function(e,t,i,o){var r;void 0===this.matrix4SC&&(this.matrix4SC=new Matrix4);var n=0;if(void 0===o&&(o=20),Object.keys(this.octreesLod0ReferencesToParseMap).length>0){for(var a=t.currentVisibles0.length,s=0;so));s++);this.octreesLod0ReferencesToParseMap={}}return n>0},ParseQueue.prototype.parseOctreesLod0References=function(e,t,i){var o=!1;if(this.octreesLod0ReferencesToParseMap.hasOwnProperty(t.octreeKey)){if(delete this.octreesLod0ReferencesToParseMap[t.octreeKey],void 0===t.neoReferencesMotherAndIndices)return!1;if(void 0===t.neoReferencesMotherAndIndices.dataArraybuffer)return!1;if(t.neoReferencesMotherAndIndices.fileLoadState!==CODE.fileLoadState.LOADING_FINISHED)return!1;var r,n=t.neoBuildingOwner,a=n.nodeOwner;if(void 0===(r=a?a.getRoot():void 0))return!1;if(void 0===r.data)return!1;var s=r.data.geoLocDataManager;if(void 0===s)return!1;void 0===this.matrix4SC&&(this.matrix4SC=new Matrix4);var l=s.getCurrentGeoLocationData(),c=n.getHeaderVersion();this.matrix4SC.setByFloat32Array(l.rotMatrix._floatArrays),"v"===c[0]?t.neoReferencesMotherAndIndices.parseArrayBufferReferences(e,t.neoReferencesMotherAndIndices.dataArraybuffer,i.readerWriter,n,this.matrix4SC,i):t.neoReferencesMotherAndIndices.parseArrayBufferReferencesVersioned(e,t.neoReferencesMotherAndIndices.dataArraybuffer,i.readerWriter,n,this.matrix4SC,i),t.neoReferencesMotherAndIndices.multiplyKeyTransformMatrix(0,l.rotMatrix),t.neoReferencesMotherAndIndices.dataArraybuffer=void 0,o=!0}return o},ParseQueue.prototype.putOctreeLod0ReferencesToParse=function(e,t){void 0===t&&(t=0),this.octreesLod0ReferencesToParseMap[e.octreeKey]=e},ParseQueue.prototype.eraseOctreeLod0ReferencesToParse=function(e){delete this.octreesLod0ReferencesToParseMap[e.octreeKey]},ParseQueue.prototype.putOctreeLod0ModelsToParse=function(e,t){void 0===t&&(t=0),this.octreesLod0ModelsToParseMap[e.octreeKey]=e},ParseQueue.prototype.eraseOctreeLod0ModelsToParse=function(e){delete this.octreesLod0ModelsToParseMap[e.octreeKey]},ParseQueue.prototype.putOctreeLod2LegosToParse=function(e,t){void 0===t&&(t=0),this.octreesLod2LegosToParseMap[e.octreeKey]=e},ParseQueue.prototype.eraseOctreeLod2LegosToParse=function(e){delete this.octreesLod2LegosToParseMap[e.octreeKey]},ParseQueue.prototype.putOctreePCloudToParse=function(e,t){void 0===t&&(t=0),this.octreesPCloudToParseMap[e.octreeKey]=e},ParseQueue.prototype.eraseOctreePCloudToParse=function(e){if(void 0===e)return!1;var t=e.octreeKey;return!!this.octreesPCloudToParseMap.hasOwnProperty(t)&&(delete this.octreesPCloudToParseMap[t],!0)},ParseQueue.prototype.putSkinLegosToParse=function(e,t){void 0===t&&(t=0),this.skinLegosToParseMap[e.legoKey]=e},ParseQueue.prototype.eraseSkinLegosToParse=function(e){delete this.skinLegosToParseMap[e.legoKey]},ParseQueue.prototype.clearAll=function(){this.octreesLod0ReferencesToParseMap={},this.octreesLod0ModelsToParseMap={},this.octreesLod2LegosToParseMap={}},ParseQueue.prototype.eraseAny=function(e){this.eraseOctreeLod0ReferencesToParse(e),this.eraseOctreeLod0ModelsToParse(e),this.eraseOctreeLod2LegosToParse(e)};var ProcessQueue=function(){if(!(this instanceof ProcessQueue))throw new Error(Messages.CONSTRUCT_ERROR);this.nodesToDeleteMap={},this.nodesToDeleteModelReferencesMap={},this.nodesToDeleteLessThanLod3Map={},this.nodesToDeleteLessThanLod4Map={},this.nodesToDeleteLessThanLod5Map={},this.nodesToDeleteLodMeshMap={},this.tinTerrainsToDeleteMap={}};ProcessQueue.prototype.putNodeToDeleteLodMesh=function(e,t){if(void 0===t&&(t=0),void 0!==e.data&&void 0!==e.data.neoBuilding){var i=e.data.neoBuilding.buildingId;this.nodesToDeleteLodMeshMap[i]=e}},ProcessQueue.prototype.eraseNodeToDeleteLodMesh=function(e){if(void 0!==e.data&&void 0!==e.data.neoBuilding){var t=e.data.neoBuilding.buildingId;return!!this.nodesToDeleteLodMeshMap.hasOwnProperty(t)&&(delete this.nodesToDeleteLodMeshMap[t],!0)}},ProcessQueue.prototype.putTinTerrainToDelete=function(e,t){if(void 0===t&&(t=0),void 0!==e){var i=e.pathName;this.tinTerrainsToDeleteMap[i]=e}},ProcessQueue.prototype.eraseTinTerrainToDelete=function(e){if(void 0!==e){var t=e.pathName;return!!this.tinTerrainsToDeleteMap.hasOwnProperty(t)&&(delete this.tinTerrainsToDeleteMap[t],!0)}},ProcessQueue.prototype.putNodeToDeleteLessThanLod3=function(e,t){if(void 0===t&&(t=0),void 0!==e.data&&void 0!==e.data.neoBuilding){var i=e.data.neoBuilding.buildingId;this.nodesToDeleteLessThanLod3Map[i]=e}},ProcessQueue.prototype.eraseNodeToDeleteLessThanLod3=function(e){if(void 0!==e.data&&void 0!==e.data.neoBuilding){var t=e.data.neoBuilding.buildingId;return!!this.nodesToDeleteLessThanLod3Map.hasOwnProperty(t)&&(delete this.nodesToDeleteLessThanLod3Map[t],!0)}},ProcessQueue.prototype.putNodeToDeleteLessThanLod4=function(e,t){if(void 0===t&&(t=0),void 0!==e.data&&void 0!==e.data.neoBuilding){var i=e.data.neoBuilding.buildingId;this.nodesToDeleteLessThanLod4Map[i]=e}},ProcessQueue.prototype.eraseNodeToDeleteLessThanLod4=function(e){if(void 0!==e.data&&void 0!==e.data.neoBuilding){var t=e.data.neoBuilding.buildingId;return!!this.nodesToDeleteLessThanLod4Map.hasOwnProperty(t)&&(delete this.nodesToDeleteLessThanLod4Map[t],!0)}},ProcessQueue.prototype.putNodeToDeleteLessThanLod5=function(e,t){if(void 0===t&&(t=0),void 0!==e.data&&void 0!==e.data.neoBuilding){var i=e.data.neoBuilding.buildingId;this.nodesToDeleteLessThanLod5Map[i]=e}},ProcessQueue.prototype.eraseNodeToDeleteLessThanLod5=function(e){if(void 0!==e.data&&void 0!==e.data.neoBuilding){var t=e.data.neoBuilding.buildingId;return!!this.nodesToDeleteLessThanLod5Map.hasOwnProperty(t)&&(delete this.nodesToDeleteLessThanLod5Map[t],!0)}},ProcessQueue.prototype.putNodeToDeleteModelReferences=function(e,t){if(void 0===t&&(t=0),void 0!==e.data&&void 0!==e.data.neoBuilding){var i=e.data.neoBuilding.buildingId;this.nodesToDeleteModelReferencesMap[i]=e}},ProcessQueue.prototype.eraseNodeToDeleteModelReferences=function(e){if(void 0!==e.data&&void 0!==e.data.neoBuilding){var t=e.data.neoBuilding.buildingId;return!!this.nodesToDeleteModelReferencesMap.hasOwnProperty(t)&&(delete this.nodesToDeleteModelReferencesMap[t],!0)}},ProcessQueue.prototype.putNodeToDelete=function(e,t){if(void 0===t&&(t=0),void 0!==e.data&&void 0!==e.data.neoBuilding){var i=e.data.neoBuilding.buildingId;this.nodesToDeleteMap[i]=e}},ProcessQueue.prototype.putNodesArrayToDelete=function(e,t){if(void 0!==e){void 0===t&&(t=0);for(var i=e.length,o=0;o=300?t.reject(i.status):t.resolve(i.response)},i.onerror=function(e){t.reject(i.status)},i.send(null),t.promise()}ReaderWriter.prototype.getCurrentDataPath=function(){return void 0!==this.geometrySubDataPath&&""!==this.geometrySubDataPath?this.geometryDataPath+"/"+this.geometrySubDataPath:this.geometryDataPath},ReaderWriter.prototype.readUInt32=function(e,t,i){return new Uint32Array(e.slice(t,i))[0]},ReaderWriter.prototype.readInt32=function(e,t,i){return new Int32Array(e.slice(t,i))[0]},ReaderWriter.prototype.readUInt16=function(e,t,i){return new Uint16Array(e.slice(t,i))[0]},ReaderWriter.prototype.readInt16=function(e,t,i){return new Int16Array(e.slice(t,i))[0]},ReaderWriter.prototype.readFloat64=function(e,t,i){return new Float64Array(e.slice(t,i))[0]},ReaderWriter.prototype.readFloat32=function(e,t,i){return new Float32Array(e.slice(t,i))[0]},ReaderWriter.prototype.readFloat16=function(e,t,i){return new Float32Array(e.slice(t,i))[0]},ReaderWriter.prototype.readInt8=function(e,t,i){return new Int8Array(e.slice(t,i))[0]},ReaderWriter.prototype.readUInt8=function(e,t,i){return new Uint8Array(e.slice(t,i))[0]},ReaderWriter.prototype.readInt8ByteColor=function(e,t,i){var o=new Int8Array(e.slice(t,i))[0];return o>max_color_value&&(o=max_color_value),o<0&&(o+=256),o},ReaderWriter.prototype.getNeoBlocksArraybuffer=function(e,t,i){i.fileRequestControler.modelRefFilesRequestedCount+=1;var o=t.neoReferencesMotherAndIndices.blocksList;o.fileLoadState=CODE.fileLoadState.LOADING_STARTED,loadWithXhr(e).done(function(e){var r=e;r?(o.dataArraybuffer=r,o.fileLoadState=CODE.fileLoadState.LOADING_FINISHED,r=null,i.parseQueue.putOctreeLod0ModelsToParse(t)):o.fileLoadState=500}).fail(function(e){o.fileLoadState=0===e?500:e}).always(function(){i.fileRequestControler.modelRefFilesRequestedCount-=1,i.fileRequestControler.modelRefFilesRequestedCount<0&&(i.fileRequestControler.modelRefFilesRequestedCount=0)})},ReaderWriter.prototype.getNeoReferencesArraybuffer=function(e,t,i){i.fileRequestControler.modelRefFilesRequestedCount+=1,t.neoReferencesMotherAndIndices.fileLoadState=CODE.fileLoadState.LOADING_STARTED,loadWithXhr(e).done(function(e){var o=e;if(o){var r=t.neoReferencesMotherAndIndices;r&&(r.dataArraybuffer=o,r.fileLoadState=CODE.fileLoadState.LOADING_FINISHED,i.parseQueue.putOctreeLod0ReferencesToParse(t)),o=null}else t.neoReferencesMotherAndIndices.fileLoadState=500}).fail(function(e){t.neoReferencesMotherAndIndices.fileLoadState=0===e?500:e}).always(function(){i.fileRequestControler.modelRefFilesRequestedCount-=1,i.fileRequestControler.modelRefFilesRequestedCount<0&&(i.fileRequestControler.modelRefFilesRequestedCount=0)})},ReaderWriter.prototype.getOctreeLegoArraybuffer=function(e,t,i){void 0!==t.lego&&(i.fileRequestControler.filesRequestedCount+=1,t.lego.fileLoadState=CODE.fileLoadState.LOADING_STARTED,loadWithXhr(e).done(function(e){var o=e;o?(t.lego?(t.lego.dataArrayBuffer=o,t.lego.fileLoadState=CODE.fileLoadState.LOADING_FINISHED,i.parseQueue.putOctreeLod2LegosToParse(t)):t=void 0,o=null):t.lego.fileLoadState=500}).fail(function(e){t.lego.fileLoadState=0===e?500:e}).always(function(){i.fileRequestControler.filesRequestedCount-=1,i.fileRequestControler.filesRequestedCount<0&&(i.fileRequestControler.filesRequestedCount=0)}))},ReaderWriter.prototype.getOctreePCloudArraybuffer=function(e,t,i){void 0!==t.lego&&(i.fileRequestControler.filesRequestedCount+=1,t.lego.fileLoadState=CODE.fileLoadState.LOADING_STARTED,loadWithXhr(e).done(function(e){var o=e;o?(t.lego?(t.lego.dataArrayBuffer=o,t.lego.fileLoadState=CODE.fileLoadState.LOADING_FINISHED,i.parseQueue.putOctreePCloudToParse(t)):t=void 0,o=null):t.lego.fileLoadState=500}).fail(function(e){t.lego.fileLoadState=0===e?500:e}).always(function(){i.fileRequestControler.filesRequestedCount-=1,i.fileRequestControler.filesRequestedCount<0&&(i.fileRequestControler.filesRequestedCount=0)}))},ReaderWriter.prototype.getLegoArraybuffer=function(e,t,i){i.fileRequestControler.lowLodDataRequestedCount+=1,t.fileLoadState=CODE.fileLoadState.LOADING_STARTED,loadWithXhr(e).done(function(e){var o=e;o?(t&&(t.dataArrayBuffer=o,t.fileLoadState=CODE.fileLoadState.LOADING_FINISHED,i.parseQueue.putSkinLegosToParse(t)),o=null):t.fileLoadState=500}).fail(function(e){t.fileLoadState=0===e?500:-1}).always(function(){i.fileRequestControler.lowLodDataRequestedCount-=1,i.fileRequestControler.lowLodDataRequestedCount<0&&(i.fileRequestControler.lowLodDataRequestedCount=0)})},ReaderWriter.prototype.getObjectIndexFileForSmartTile=function(e,t,i,o){loadWithXhr(e).done(function(e){var r=e;r&&(i.dataArrayBuffer=r,i.parseBuildingSeedArrayBuffer(),t.makeSmartTile(i,o),r=null)}).fail(function(e){}).always(function(){})},ReaderWriter.prototype.getObjectIndexFile=function(e,t,i,o){loadWithXhr(e).done(function(e){var r=e;r&&(t.parseObjectIndexFile(r,i),r=null,o.createDeploymentGeoLocationsForHeavyIndustries())}).fail(function(e){}).always(function(){})},ReaderWriter.prototype.parseObjectIndexFile=function(e,t){var i,o,r,n,a=0,s=this.readInt32(e,a,a+4);a+=4;for(var l=0;l0){var g=new Texture;g.textureTypeName=c,g.textureImageFileName=l,void 0===i.texturesLoaded&&(i.texturesLoaded=[]),i.texturesLoaded.push(g)}}var p=new Uint8Array(t.slice(r,r+1))[0];if(r+=1,void 0!==p){i.lodBuildingDatasMap={};for(s=0;s0&&r.backGround_imageReadings_count--},c.onerror=function(){},c.src=l},ReaderWriter.prototype.readNailImage=function(e,t,i,o,r,n){void 0===n&&(n=3),3===n?i._f4d_nailImage_readed=!0:0===n&&(i._f4d_lod0Image_readed=!0),void 0===i._simpleBuilding_v1&&(i._simpleBuilding_v1=new SimpleBuildingV1);var a=i._simpleBuilding_v1,s=new Image;s.onload=function(){3===n?(handleTextureLoaded(e,s,a._simpleBuildingTexture),i._f4d_nailImage_readed_finished=!0):0===n&&(void 0===a._texture_0&&(a._texture_0=e.createTexture()),handleTextureLoaded(e,s,a._texture_0),i._f4d_lod0Image_readed_finished=!0),r.backGround_fileReadings_count>0&&(r.backGround_fileReadings_count-=1)},s.onerror=function(){i._f4d_lod0Image_readed_finished=!1,i._f4d_lod0Image_exists=!1,r.backGround_fileReadings_count>0&&(r.backGround_fileReadings_count-=1)};var l=t;s.src=l},ReaderWriter.prototype.readTexture=function(e,t,i,o){i.loadStarted=!0,i.texImage=new Image,i.texImage.onload=function(){i.loadFinished=!0,o.backGround_fileReadings_count>0&&(o.backGround_fileReadings_count-=1)},i.texImage.onerror=function(){i.loadStarted=!1,o.backGround_fileReadings_count>0&&(o.backGround_fileReadings_count-=1)},i.texImage.src=t},ReaderWriter.prototype.decodeTGA=function(e){var t,i,o,r,n,a=new Uint8Array(e),s=18+a[0],l=a[2],c=a[12]+(a[13]<<8),h=a[14]+(a[15]<<8),d=a[16],u=d/8,f=4*c;if(!c||!h)return null;if(2!==l)return null;for(t=new Uint8Array(c*h*4),i=s,n=h-1;n>=0;--n)for(r=0;r0&&void 0!==i.texId)e.bindTexture(e.TEXTURE_2D,i.texId),e.texImage2D(e.TEXTURE_2D,0,n,r.header.width,r.header.height,0,n,e.UNSIGNED_BYTE,r.imageData),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.generateMipmap(e.TEXTURE_2D),i.fileLoadState=CODE.fileLoadState.LOADING_FINISHED,e.bindTexture(e.TEXTURE_2D,null);else;}}}).fail(function(e){o&&(o.metaData.fileLoadState=0===e?500:e)}).always(function(){r.backGround_fileReadings_count-=1,r.backGround_fileReadings_count<0&&(r.backGround_fileReadings_count=0)});else{var a=new Image;i.fileLoadState=CODE.fileLoadState.LOADING_STARTED,a.onload=function(){void 0!==i.texId&&(handleTextureLoaded(e,a,i.texId),i.fileLoadState=CODE.fileLoadState.LOADING_FINISHED,r.backGround_fileReadings_count>0&&(r.backGround_fileReadings_count-=1))},a.onerror=function(){},a.src=t}},ReaderWriter.prototype.readLegoSimpleBuildingTexture=function(e,t,i,o){var r=new Image;i.fileLoadState,CODE.fileLoadState.LOADING_STARTED,o.fileRequestControler.lowLodImagesRequestedCount+=1,r.onload=function(){void 0===i.texId&&(i.texId=e.createTexture()),handleTextureLoaded(e,r,i.texId),i.fileLoadState,CODE.fileLoadState.LOADING_FINISHED,o.fileRequestControler.lowLodImagesRequestedCount-=1,o.backGround_fileReadings_count>0&&(o.backGround_fileReadings_count-=1),o.fileRequestControler.lowLodImagesRequestedCount<0&&(o.fileRequestControler.lowLodImagesRequestedCount=0)},r.onerror=function(){void 0===i.texId&&(i.texId=e.createTexture(),e.bindTexture(e.TEXTURE_2D,i.texId),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,1,1,0,e.RGBA,e.UNSIGNED_BYTE,new Uint8Array([200,200,200,255])),e.bindTexture(e.TEXTURE_2D,null)),i.fileLoadState,CODE.fileLoadState.READY,o.fileRequestControler.lowLodImagesRequestedCount-=1,o.fileRequestControler.lowLodImagesRequestedCount<0&&(o.fileRequestControler.lowLodImagesRequestedCount=0)},r.src=t},ReaderWriter.prototype.getTileArrayBuffer=function(e,t,i,o,r){i.fileReading_started=!0,loadWithXhr(t).done(function(e){var t=e;t&&(i.fileArrayBuffer=t,i.fileReading_finished=!0,r.backGround_fileReadings_count>0&&(r.backGround_fileReadings_count-=1),t=null)}).fail(function(e){}).always(function(){})},ReaderWriter.prototype.loadTINTerrain=function(e,t,i,o){i.fileLoadState=CODE.fileLoadState.LOADING_STARTED,loadWithXhr(t).done(function(e){var t=e;t?(i.dataArrayBuffer=t,i.fileLoadState=CODE.fileLoadState.LOADING_FINISHED,t=void 0):i.fileLoadState=500}).fail(function(e){}).always(function(){})},ReaderWriter.prototype.handleTextureLoaded=function(e,t,i){e.bindTexture(e.TEXTURE_2D,i),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.REPEAT),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.REPEAT),e.generateMipmap(e.TEXTURE_2D),e.bindTexture(e.TEXTURE_2D,null)};var TinTerrain=function(){if(!(this instanceof TinTerrain))throw new Error(Messages.CONSTRUCT_ERROR);this.owner,this.geographicExtent,this.fileLoadState=0,this.dataArrayBuffer,this.vboKeyContainer,this.terrainPositionHIGH,this.terrainPositionLOW,this.pathName,this.texture};TinTerrain.prototype.zigZagDecode=function(e){return e>>1^-(1&e)},TinTerrain.prototype.makeVbo=function(){if(void 0!==this.cartesiansArray){for(var e=this.cartesiansArray.length/3,t=0;t65536?(this.indices=new Uint32Array(e.slice(t,t+4*l*3)),t+=4*l*3):(this.indices=new Uint16Array(e.slice(t,t+2*l*3)),t+=2*l*3);var c=0,h=this.indices.length;for(a=0;a65536?(this.westVertexCount=new Uint32Array(e.slice(t,t+4)),t+=4,this.westIndices=new Uint32Array(e.slice(t,t+4*this.westVertexCount)),t+=4*this.westVertexCount,this.southVertexCount=new Uint32Array(e.slice(t,t+4)),t+=4,this.southIndices=new Uint32Array(e.slice(t,t+4*this.southVertexCount)),t+=4*this.southVertexCount,this.eastVertexCount=new Uint32Array(e.slice(t,t+4)),t+=4,this.eastIndices=new Uint32Array(e.slice(t,t+4*this.eastVertexCount)),t+=4*this.eastVertexCount,this.northVertexCount=new Uint32Array(e.slice(t,t+4)),t+=4,this.northIndices=new Uint32Array(e.slice(t,t+4*this.northVertexCount)),t+=4*this.northVertexCount):(this.westVertexCount=new Uint32Array(e.slice(t,t+4)),t+=4,this.westIndices=new Uint16Array(e.slice(t,t+2*this.westVertexCount)),t+=2*this.westVertexCount,this.southVertexCount=new Uint32Array(e.slice(t,t+4)),t+=4,this.southIndices=new Uint16Array(e.slice(t,t+2*this.southVertexCount)),t+=2*this.southVertexCount,this.eastVertexCount=new Uint32Array(e.slice(t,t+4)),t+=4,this.eastIndices=new Uint16Array(e.slice(t,t+2*this.eastVertexCount)),t+=2*this.eastVertexCount,this.northVertexCount=new Uint32Array(e.slice(t,t+4)),t+=4,this.northIndices=new Uint16Array(e.slice(t,t+2*this.northVertexCount)),t+=2*this.northVertexCount),this.extensionId=new Uint8Array(e.slice(t,t+1)),t+=1,this.extensionLength=new Uint32Array(e.slice(t,t+4)),t+=4,this.fileLoadState=CODE.fileLoadState.PARSE_FINISHED,e=void this.extensionId.length};var TinTerrainManager=function(){if(!(this instanceof TinTerrainManager))throw new Error(Messages.CONSTRUCT_ERROR);this.maxDepth=15,this.currentVisibles_terrName_geoCoords_map={},this.currentTerrainsMap={}},Arc=function(){if(!(this instanceof Arc))throw new Error(Messages.CONSTRUCT_ERROR);this.centerPoint,this.radius,this.startAngleDeg,this.sweepAngleDeg,this.numPointsFor360Deg,this.startPoint,this.endPoint,this.sweepSense};Arc.prototype.deleteObjects=function(){void 0!==this.centerPoint&&this.centerPoint.deleteObjects(),this.centerPoint=void 0,this.radius=void 0,this.startAngleDeg=void 0,this.sweepAngleDeg=void 0,this.numPointsFor360Deg=void 0,void 0!==this.startPoint&&this.startPoint.deleteObjects(),this.startPoint=void 0,void 0!==this.endPoint&&this.endPoint.deleteObjects(),this.endPoint=void 0,this.sweepSense=void 0},Arc.prototype.setCenterPosition=function(e,t){void 0===this.centerPoint&&(this.centerPoint=new Point2D),this.centerPoint.set(e,t)},Arc.prototype.setRadius=function(e){this.radius=e},Arc.prototype.setStartAngleDegree=function(e){this.startAngleDeg=e},Arc.prototype.setStartPoint=function(e,t){void 0===this.startPoint&&(this.startPoint=new Point2D),this.startPoint.set(e,t)},Arc.prototype.setEndPoint=function(e,t){void 0===this.endPoint&&(this.endPoint=new Point2D),this.endPoint.set(e,t)},Arc.prototype.setSense=function(e){this.sweepSense=e},Arc.prototype.setSweepAngleDegree=function(e){this.sweepAngleDeg=e},Arc.prototype.getPoints=function(e,t){if(void 0===this.centerPoint)return e;var i,o;if(t&&(this.numPointsFor360Deg=t),void 0===this.numPointsFor360Deg&&(this.numPointsFor360Deg=36),void 0===this.startAngleDeg){if(void 0===this.startPoint)return e;(i=new Point2D).set(this.startPoint.x-this.centerPoint.x,this.startPoint.y-this.centerPoint.y),o=i.getModul();var r=Math.acos(n/o);this.startPoint.y<0&&(r*=-1),this.startAngleDeg=180*r/Math.PI}if(void 0===this.radius){if(void 0===this.startPoint)return e;void 0===o&&(void 0===i&&(i=new Point2D).set(this.startPoint.x-this.centerPoint.x,this.startPoint.y-this.centerPoint.y),o=i.getModul()),this.radius=o}if(void 0===this.sweepAngleDeg){if(void 0===this.endPoint||void 0===this.sweepSense)return e;(new Point2D).set(this.endPoint.x-this.centerPoint.x,this.endPoint.y-this.endPoint.y);endPoint.getModul(),r=Math.acos(n/o);this.endPoint.y<0&&(r*=-1),this.sweepAngleDeg=180*r/Math.PI,this.sweepSense<0&&(this.sweepAngleDeg=360-this.sweepAngleDeg)}void 0===e&&(e=[]);var n,a,s,l=[],c=2*Math.PI/this.numPointsFor360Deg,h=this.centerPoint.x,d=this.centerPoint.y,u=Math.PI/180*this.startAngleDeg,f=Math.PI/180*this.sweepAngleDeg;if(f>=0)for(var g=0;gf;g-=c)n=h+this.radius*Math.cos(g+u),a=d+this.radius*Math.sin(g+u),s=new Point2D(n,a),l.push(s);var p=l.length;p>0&&(l[0].pointType=1,l[p-1].pointType=1);for(var m=e.length,y=0;y0){var v=e[m-1];s=l[y],v.isCoincidentToPoint(s,1e-4)||e.push(s)}else e.push(l[y]);else e.push(l[y]);if((m=e.length)>0){var x=e[m-1],b=e[0];x.isCoincidentToPoint(b,1e-4)&&(e.pop(),x.deleteObjects())}return e};var AxisXYZ=function(e){if(!(this instanceof AxisXYZ))throw new Error(Messages.CONSTRUCT_ERROR);this.length=void 0===e?60:e,this.vbo_vicks_container=new VBOVertexIdxCacheKeysContainer};AxisXYZ.prototype.setDimension=function(e){this.length=e},AxisXYZ.prototype.makeMesh=function(e){void 0!==e&&(this.length=e);var t=new ParametricMesh;t.profile=new Profile;var i,o=t.profile,r=o.newOuterRing(),n=this.length,a=.1*this.length,s=r.newElement("POLYLINE");s.newPoint2d(0,0);s.newPoint2d(.25*a,.25*n),s.newPoint2d(.25*a,.75*n),s.newPoint2d(.5*a,.75*n),s.newPoint2d(0,n),i=new Segment2D;var l=new Point2D(0,-10),c=new Point2D(0,10);i.setPoints(l,c),t.revolve(o,360,8,i);var h=t.getSurfaceIndependentMesh(void 0,!1,!1);h.setColor(.1,1,.1,1),h.reverseSense();var d=new Matrix4,u=h.getCopy(void 0);d.rotationAxisAngDeg(-90,0,0,1),u.transformByMatrix4(d),u.setColor(1,.1,.1,1);var f=h.getCopy(void 0);return d.rotationAxisAngDeg(90,1,0,0),f.transformByMatrix4(d),f.setColor(.1,.1,1,1),h.mergeMesh(u),h.mergeMesh(f),h},AxisXYZ.prototype.getVboKeysContainer=function(){return this.vbo_vicks_container};var BoundingRectangle=function(e,t){if(!(this instanceof BoundingRectangle))throw new Error(Messages.CONSTRUCT_ERROR);this.minX=1e5,this.maxX=-1e5,this.minY=1e5,this.maxY=-1e5};BoundingRectangle.prototype.setInit=function(e){void 0!==e&&(this.minX=e.x,this.minY=e.y,this.maxX=e.x,this.maxY=e.y)},BoundingRectangle.prototype.setInitByRectangle=function(e){void 0!==e&&(this.minX=e.minX,this.minY=e.minY,this.maxX=e.maxX,this.maxY=e.maxY)},BoundingRectangle.prototype.addPoint=function(e){void 0!==e&&(e.xthis.maxX&&(this.maxX=e.x),e.ythis.maxY&&(this.maxY=e.y))},BoundingRectangle.prototype.addRectangle=function(e){void 0!==e&&(e.minXthis.maxX&&(this.maxX=e.maxX),e.minYthis.maxY&&(this.maxY=e.maxY))},BoundingRectangle.prototype.intersectsWithRectangle=function(e){return void 0!==e&&(!(e.minX>this.maxX)&&(!(e.maxXthis.maxY)&&!(e.maxY2e4&&(t=s*s*1e-9,i=.01*s),s>16e3?(t=s*s*1e-9,i=.001*s):s>14e3?(t=s*s*1e-9,i=.001*s):s>1e4?(t=s*s*1e-10,i=1e-4*s):s>6e3?(t=s*s*1e-11,i=1e-7*s):(t=s*s*1e-11,i=1e-8*s),o*=t+i+1,n.add(a.x*o,a.y*o,a.z*o),this.updateModelViewMatrixByCamera(r)},MagoWorld.prototype.mousemove=function(e){var t=this.magoManager.sceneState.mouseAction;if(0===this.magoManager.sceneState.mouseButton){this.magoManager.sceneState.gl,this.magoManager.sceneState;var i,o,r=t.curCamera,n=this.magoManager.sceneState.camera,a=t.curWorldPoint,s=a.getModul(),l=e.clientX,c=e.clientY;if(l===t.curX&&c===t.curY)return;o=this.magoManager.getRayCamSpace(l,c,o),void 0===this.pointSC&&(this.pointSC=new Point3D),this.pointSC.set(o[0],o[1],o[2]);var h,d=t.curModelViewMatrixInv;if(this.pointSC2=d.rotatePoint3D(this.pointSC,this.pointSC2),this.pointSC2.unitary(),(i=new Line).setPointAndDir(r.position.x,r.position.y,r.position.z,this.pointSC2.x,this.pointSC2.y,this.pointSC2.z),void 0===(h=this.magoManager.globe.intersectionLineWgs84(i,h,s)))return;var u,f=new Point3D(a.x,a.y,a.z),g=new Point3D(h[0],h[1],h[2]);if((u=f.crossProduct(g,u)).unitary(),u.isNAN())return;var p=f.angleRadToVector(g);if(0===p||isNaN(p))return;n.copyPosDirUpFrom(r);var m=mat4.create();m=mat4.rotate(m,m,-p,[u.x,u.y,u.z]),n.transformByMatrix4(m),this.updateModelViewMatrixByCamera(n)}else if(1===this.magoManager.sceneState.mouseButton){r=t.curCamera;(n=this.magoManager.sceneState.camera).copyPosDirUpFrom(r);n.position,n.direction,n.up;var y,v=t.curWorldPoint;void 0===this.magoManager.globe&&(this.magoManager.globe=new Globe),y=this.magoManager.globe.normalAtCartesianPointWgs84(v.x,v.y,v.z,y);var x=n.getCameraRight(),b=(l=e.clientX,c=e.clientY,.003*(l-t.curX)),C=.003*(c-t.curY);if(0===b&&0==C)return;void 0===this.rotMatX&&(this.rotMatX=mat4.create()),void 0===this.rotMatZ&&(this.rotMatZ=mat4.create()),void 0===this.rotMat&&(this.rotMat=mat4.create()),this.rotMatX=mat4.identity(this.rotMatX),this.rotMatZ=mat4.identity(this.rotMatZ),this.rotMat=mat4.identity(this.rotMat),this.rotMatX=mat4.fromRotation(this.rotMatX,-C,[x.x,x.y,x.z]),this.rotMatZ=mat4.fromRotation(this.rotMatZ,-b,y),this.rotMat=mat4.multiply(this.rotMat,this.rotMatZ,this.rotMatX);var M=mat4.create(),_=mat4.create();M=mat4.fromTranslation(M,[-v.x,-v.y,-v.z]),_=mat4.fromTranslation(_,[v.x,v.y,v.z]);var A=mat4.create();A=mat4.multiply(A,_,this.rotMat);var R=mat4.create();R=mat4.multiply(R,A,_),n.transformByMatrix4(M),n.transformByMatrix4(this.rotMat),n.transformByMatrix4(_),this.updateModelViewMatrixByCamera(n)}},MagoWorld.prototype.keydown=function(e){};var Mesh=function(){if(!(this instanceof Mesh))throw new Error(Messages.CONSTRUCT_ERROR);this.vertexList,this.surfacesArray,this.hedgesList};Mesh.prototype.newSurface=function(){void 0===this.surfacesArray&&(this.surfacesArray=[]);var e=new Surface;return this.surfacesArray.push(e),e},Mesh.prototype.getSurface=function(e){if(void 0!==this.surfacesArray)return this.surfacesArray[e]},Mesh.prototype.addSurface=function(e){void 0!==e&&(void 0===this.surfacesArray&&(this.surfacesArray=[]),this.surfacesArray.push(e))},Mesh.prototype.mergeMesh=function(e){if(void 0!==e){void 0===this.surfacesArray&&(this.surfacesArray=[]);for(var t=e.getSurfacesCount(),i=0;i0&&(t=this.getTrianglesListsArrayBy2ByteSize(n,t)),t},Mesh.prototype.getVbo=function(e){void 0===e&&(e=new VBOVertexIdxCacheKeysContainer);for(var t,i,o=this.getTrianglesConvex(void 0),r=(o.length,this.getTrianglesListsArrayBy2ByteSize(o,void 0)),n=r.length,a=0;at.squaredDist?(l=i,c=h):(l=h,c=o),this.getIndexToInsertBySquaredDist(e,t,l,c)};var Point3D=function(e,t,i){if(!(this instanceof Point3D))throw new Error(Messages.CONSTRUCT_ERROR);this.x=void 0!==e?e:0,this.y=void 0!==t?t:0,this.z=void 0!==i?i:0,this.pointType};Point3D.prototype.deleteObjects=function(){this.x=void 0,this.y=void 0,this.z=void 0},Point3D.prototype.copyFrom=function(e){this.x=e.x,this.y=e.y,this.z=e.z},Point3D.prototype.getSquaredModul=function(){return this.x*this.x+this.y*this.y+this.z*this.z},Point3D.prototype.getModul=function(){return Math.sqrt(this.getSquaredModul())},Point3D.prototype.unitary=function(){var e=this.getModul();this.x/=e,this.y/=e,this.z/=e},Point3D.prototype.isNAN=function(){return!!(isNaN(this.x)||isNaN(this.y)||isNaN(this.z))},Point3D.prototype.crossProduct=function(e,t){return void 0===t&&(t=new Point3D),t.x=this.y*e.z-e.y*this.z,t.y=e.x*this.z-this.x*e.z,t.z=this.x*e.y-e.x*this.y,t},Point3D.prototype.scalarProduct=function(e){return this.x*e.x+this.y*e.y+this.z*e.z},Point3D.prototype.angleRadToVector=function(e){if(void 0!==e){var t=this.getModul(),i=e.getModul();if(!(t<1e-9||i<1e-9))return Math.acos(this.scalarProduct(e)/(t*i))}},Point3D.prototype.angleDegToVector=function(e){if(void 0!==e){var t=this.angleRadToVector(e);if(void 0!==t)return 180*t/Math.PI}},Point3D.prototype.squareDistToPoint=function(e){var t=this.x-e.x,i=this.y-e.y,o=this.z-e.z;return t*t+i*i+o*o},Point3D.prototype.isCoincidentToPoint=function(e,t){var i=!1;return this.distToPoint(e)s?a>l?(o=s/(i=a),r=l/(n=i*t[Math.floor(10*o)]),n*t[Math.floor(10*r)]):(o=a/(i=l),r=s/(n=i*t[Math.floor(10*o)]),n*t[Math.floor(10*r)]):s>l?(o=a/(i=s),r=l/(n=i*t[Math.floor(10*o)]),n*t[Math.floor(10*r)]):(o=a/(i=l),r=s/(n=i*t[Math.floor(10*o)]),n*t[Math.floor(10*r)])},Point3D.prototype.getVectorToPoint=function(e,t){if(void 0!==e)return void 0===t&&(t=new Point3D),t.set(e.x-this.x,e.y-this.y,e.z-this.z),t},Point3D.prototype.set=function(e,t,i){this.x=e,this.y=t,this.z=i},Point3D.prototype.add=function(e,t,i){this.x+=e,this.y+=t,this.z+=i},Point3D.prototype.addPoint=function(e){this.x+=e.x,this.y+=e.y,this.z+=e.z},Point3D.prototype.scale=function(e){this.x*=e,this.y*=e,this.z*=e};var Polygon=function(){if(!(this instanceof Polygon))throw new Error(Messages.CONSTRUCT_ERROR);this.point2dList,this.normal,this.convexPolygonsArray,this.bRect};Polygon.prototype.deleteObjects=function(){void 0!==this.point2dList&&(this.point2dList.deleteObjects(),this.point2dList=void 0),this.normal=void 0},Polygon.prototype.getBoundingRectangle=function(e){return void 0===this.point2dList?e:e=this.point2dList.getBoundingRectangle(e)},Polygon.prototype.getEdgeDirection=function(e){return this.point2dList.getSegment(e).getDirection(void 0)},Polygon.prototype.getEdgeVector=function(e){return this.point2dList.getSegment(e).getVector(void 0)},Polygon.prototype.reverseSense=function(){void 0!==this.point2dList&&this.point2dList.reverse()},Polygon.prototype.getCopy=function(e){return void 0===this.point2dList?e:(void 0===e&&(e=new Polygon),void 0===e.point2dList&&(e.point2dList=new Point2DList),e.point2dList=this.point2dList.getCopy(e.point2dList),this.normal&&(e.normal=this.normal),e)},Polygon.prototype.calculateNormal=function(e){void 0===e&&(e=[]),this.normal=0;for(var t=this.point2dList.getPointsCount(),i=0;i0&&(a=1);var l=s,c=Math.acos(l);this.normal+=a*c}return this.normal>0?this.normal=1:this.normal=-1,e},Polygon.prototype.tessellate=function(e,t){var i=e.length;if(0===i)return t.push(this),t;for(var o,r=!1,n=0;!r&&n0?t=f.tessellate(p,t):(void 0===t&&(t=[]),t.push(f)),m.length>0?t=g.tessellate(m,t):(void 0===t&&(t=[]),t.push(g))),h++}}}else h++;n++}return t},Polygon.prototype.intersectionWithSegment=function(e){if(void 0!==this.bRect){var t=e.getBoundaryRectangle(t);if(!this.bRect.intersectsWithRectangle(t))return!1}for(var i,o=this.point2dList.getPointsCount(),r=0;r0?1:-1;for(var n=this.point2dList.getPointsCount(),a=0;a0?1:-1;for(var s=e.point2dList.getPointsCount(),l=0;l0){var n=e[i-1],a=this.point2dArray[r];n.isCoincidentToPoint(a,1e-7)||((t=new Point2D).copyFrom(this.point2dArray[r]),t.pointType=1,e.push(t))}else(t=new Point2D).copyFrom(this.point2dArray[r]),t.pointType=1,e.push(t);else(t=new Point2D).copyFrom(this.point2dArray[r]),t.pointType=1,e.push(t);return e};var Profile=function(){if(!(this instanceof Profile))throw new Error(Messages.CONSTRUCT_ERROR);this.outerRing,this.innerRingsList};Profile.prototype.newOuterRing=function(){return void 0===this.outerRing?this.outerRing=new Ring:this.outerRing.deleteObjects(),this.outerRing},Profile.prototype.newInnerRing=function(){return void 0===this.innerRingsList&&(this.innerRingsList=new RingsList),this.innerRingsList.newRing()},Profile.prototype.deleteObjects=function(){this.outerRing&&(this.outerRing.deleteObjects(),this.outerRing=void 0),this.innerRingsList&&(this.innerRingsList.deleteObjects(),this.innerRingsList=void 0)},Profile.prototype.hasHoles=function(){return void 0!==this.innerRingsList&&0!==this.innerRingsList.getRingsCount()},Profile.prototype.getVBO=function(e){if(void 0===this.outerRing)return e;this.getGeneralPolygon(void 0).getVbo(e)},Profile.prototype.getConvexFacesIndicesData=function(e){if(void 0===this.outerRing)return resultVbo;var t,i,o,r,n,a,s=this.getGeneralPolygon(void 0);if(void 0===e&&(e=[]),this.outerRing.polygon.point2dList.setIdxInList(),void 0!==this.innerRingsList)for(var l=this.innerRingsList.getRingsCount(),c=0;c1){e[o-1].pointType=0;var r=e[0],n=e[o-1];r.isCoincidentToPoint(n,1e-7)&&((n=e.pop()).deleteObjects(),n=void 0)}return e};var RingsList=function(){if(!(this instanceof RingsList))throw new Error(Messages.CONSTRUCT_ERROR);this.ringsArray,this.idxInList};RingsList.prototype.newRing=function(){void 0===this.ringsArray&&(this.ringsArray=[]);var e=new Ring;return this.ringsArray.push(e),e},RingsList.prototype.deleteObjects=function(){if(this.ringsArray){for(var e=this.ringsArray.length,t=0;tt.squaredDist?(l=i,c=h):(l=h,c=o),this.getIndexToInsertBySquaredDist(e,t,l,c)};var Segment2D=function(e,t){if(!(this instanceof Segment2D))throw new Error(Messages.CONSTRUCT_ERROR);this.startPoint2d,this.endPoint2d,e&&(this.startPoint2d=e),t&&(this.endPoint2d=t)};Segment2D.prototype.setPoints=function(e,t){e&&(this.startPoint2d=e),t&&(this.endPoint2d=t)},Segment2D.prototype.getVector=function(e){if(void 0!==this.startPoint2d&&void 0!==this.endPoint2d)return void 0===e&&(e=new Point2D),e=this.startPoint2d.getVectorToPoint(this.endPoint2d,e)},Segment2D.prototype.getDirection=function(e){return void 0===e&&(e=new Point2D),(e=this.getVector(e)).unitary(),e},Segment2D.prototype.getBoundaryRectangle=function(e){return void 0===e&&(e=new BoundaryRectangle),e.setInit(this.startPoint2d),e.addPoint(this.endPoint2d),e},Segment2D.prototype.getLine=function(e){void 0===e&&(e=new Line2D);var t=this.getDirection(),i=this.startPoint2d;return e.setPointAndDir(i.x,i.y,t.x,t.y),e},Segment2D.prototype.getSquaredLength=function(){return this.startPoint2d.squareDistToPoint(this.endPoint2d)},Segment2D.prototype.getLength=function(){return Math.sqrt(this.getSquaredLength())},Segment2D.prototype.intersectionWithPointByDistances=function(e,t){if(void 0!==e){void 0===t&&(t=1e-7);var i=this.startPoint2d.distToPoint(e),o=this.endPoint2d.distToPoint(e),r=this.getLength();return ir||o>r?Constant.INTERSECTION_OUTSIDE:Math.abs(i+o-r)i-1))return 0===e?i-1:e-1},VertexList.getNextIdx=function(e,t){var i=t.length;if(!(e<0||e>i-1))return e===i-1?0:e+1},VertexList.getVtxSegment=function(e,t,i){var o=t[e],r=t[VertexList.getNextIdx(e,t)];return void 0===i?i=new VtxSegment(o,r):i.setVertices(o,r),i},VertexList.getVector=function(e,t,i){var o=t[e],r=t[VertexList.getNextIdx(e,t)],n=o.point3d,a=r.point3d;return void 0===i?i=new Point3D(a.x-n.x,a.y-n.y,a.z-n.z):i.setVertices(a.x-n.x,a.y-n.y,a.z-n.z),i},VertexList.getCrossProduct=function(e,t,i){var o=VertexList.getVector(e,t,void 0),r=VertexList.getPrevIdx(e,t);return i=VertexList.getVector(r,t,void 0).crossProduct(o,i)},VertexList.prototype.deleteObjects=function(){for(var e=0,t=this.vertexArray.length;e=0&&e0)for(var y=f.length,v=0;v0){y=f.length;for(var C,M,_=0;_n||r>n?Constant.INTERSECTION_OUTSIDE:Math.abs(o+r-n)=0&&e 0.49)\n\t\t\tcontinue;\n float depthBufferValue = getDepth(offset.xy);\t\t\t\t \n float range_check = abs(linearDepth - depthBufferValue)+radius*0.998;\n if (range_check < radius*1.001 && depthBufferValue <= sampleDepth)\n {\n occlusion += 1.0;\n }\n } \n \n occlusion = 1.0 - occlusion / float(kernelSize);\n\n vec3 lightPos = vec3(20.0, 60.0, 20.0);\n vec3 L = normalize(lightPos - vertexPos);\n float lambertian = max(dot(normal2, L), 0.0);\n float specular = 0.0;\n if(lambertian > 0.0)\n {\n vec3 R = reflect(-L, normal2); // Reflected light vector\n vec3 V = normalize(-vertexPos); // Vector to viewer\n \n // Compute the specular term\n float specAngle = max(dot(R, V), 0.0);\n specular = pow(specAngle, shininessValue);\n }\n\t\n\tif(lambertian < 0.5)\n {\n\t\tlambertian = 0.5;\n\t}\n\n vec4 textureColor;\n if(hasTexture)\n {\n if(textureFlipYAxis)\n {\n textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, 1.0 - vTexCoord.t));\n }\n else{\n textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, vTexCoord.t));\n }\n\t\t\n if(textureColor.w == 0.0)\n {\n discard;\n }\n }\n else{\n textureColor = vColor4Aux;\n }\n\t\n\tvec3 ambientColor = vec3(textureColor.x, textureColor.y, textureColor.z);\n\n gl_FragColor = vec4((ambientReflectionCoef * ambientColor + diffuseReflectionCoef * lambertian * textureColor.xyz + specularReflectionCoef * specular * specularColor)*vLightWeighting * occlusion, 1.0); \n}\n",InvertedBoxVS:"\tattribute vec3 position;\n\tattribute vec3 normal;\n\tattribute vec2 texCoord;\n\t\n\tuniform mat4 buildingRotMatrix; \n\tuniform mat4 projectionMatrix; \n\tuniform mat4 modelViewMatrix;\n\tuniform mat4 modelViewMatrixRelToEye; \n\tuniform mat4 ModelViewProjectionMatrixRelToEye;\n\tuniform mat4 RefTransfMatrix;\n\tuniform mat4 normalMatrix4;\n\tuniform vec3 buildingPosHIGH;\n\tuniform vec3 buildingPosLOW;\n\tuniform vec3 encodedCameraPositionMCHigh;\n\tuniform vec3 encodedCameraPositionMCLow;\n\tuniform vec3 aditionalPosition;\n\tuniform vec3 refTranslationVec;\n\tuniform int refMatrixType; // 0= identity, 1= translate, 2= transform\n\n\tvarying vec3 vNormal;\n\tvarying vec2 vTexCoord; \n\tvarying vec3 uAmbientColor;\n\tvarying vec3 vLightWeighting;\n\tvarying vec3 vertexPos;\n\t\n\tvoid main()\n {\t\n\t\tvec4 rotatedPos;\n\t\tmat3 currentTMat;\n\t\tif(refMatrixType == 0)\n\t\t{\n\t\t\trotatedPos = buildingRotMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t\t\tcurrentTMat = mat3(buildingRotMatrix);\n\t\t}\n\t\telse if(refMatrixType == 1)\n\t\t{\n\t\t\trotatedPos = buildingRotMatrix * vec4(position.xyz + refTranslationVec.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t\t\tcurrentTMat = mat3(buildingRotMatrix);\n\t\t}\n\t\telse if(refMatrixType == 2)\n\t\t{\n\t\t\trotatedPos = RefTransfMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t\t\tcurrentTMat = mat3(RefTransfMatrix);\n\t\t}\n\n\t\tvec3 objPosHigh = buildingPosHIGH;\n\t\tvec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n\t\tvec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\t\tvec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\t\tvec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\n\t\tvertexPos = vec3(modelViewMatrixRelToEye * pos4);\n\t\tvec3 rotatedNormal = currentTMat * normal;\n\t\tvLightWeighting = vec3(1.0, 1.0, 1.0);\n\t\tuAmbientColor = vec3(0.8);\n\t\tvec3 uLightingDirection = vec3(0.6, 0.6, 0.6);\n\t\tvec3 directionalLightColor = vec3(0.7, 0.7, 0.7);\n\t\tvNormal = (normalMatrix4 * vec4(rotatedNormal.x, rotatedNormal.y, rotatedNormal.z, 1.0)).xyz;\n\t\tvTexCoord = texCoord;\n\t\tfloat directionalLightWeighting = max(dot(vNormal, uLightingDirection), 0.0);\n\t\tvLightWeighting = uAmbientColor + directionalLightColor * directionalLightWeighting;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\t}\n",LegoDepthFS:"#ifdef GL_ES\nprecision highp float;\n#endif\nuniform float near;\nuniform float far;\n\nvarying float depth; \n\nvec4 packDepth(const in float depth)\n{\n const vec4 bit_shift = vec4(16777216.0, 65536.0, 256.0, 1.0);\n const vec4 bit_mask = vec4(0.0, 0.00390625, 0.00390625, 0.00390625); \n vec4 res = fract(depth * bit_shift);\n res -= res.xxyz * bit_mask;\n return res; \n}\n\nvoid main()\n{ \n gl_FragData[0] = packDepth(-depth);\n}\n",LegoDepthVS:"attribute vec3 position;\nattribute vec3 normal;\nattribute vec2 texCoord;\n\nuniform mat4 modelViewMatrixRelToEye; \nuniform mat4 RefTransfMatrix;\nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nuniform float near;\nuniform float far;\nuniform vec3 aditionalPosition;\n\nvarying float depth; \nvoid main()\n{\t\n vec4 rotatedPos = RefTransfMatrix * vec4(position.xyz + aditionalPosition.xyz, 1.0);\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\n depth = (modelViewMatrixRelToEye * pos4).z/far;\n \n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n}\n",LegoSsaoFS:"#ifdef GL_ES\n precision highp float;\n#endif\nuniform sampler2D depthTex;\nuniform sampler2D noiseTex; \nuniform sampler2D diffuseTex;\nuniform bool hasTexture;\nvarying vec3 vNormal;\nuniform mat4 projectionMatrix;\nuniform mat4 m;\nuniform vec2 noiseScale;\nuniform float near;\nuniform float far; \nuniform float fov;\nuniform float aspectRatio; \nuniform float screenWidth; \nuniform float screenHeight; \nuniform vec3 kernel[16]; \nuniform vec4 vColor4Aux;\n\nvarying vec2 vTexCoord; \nvarying vec3 vLightWeighting;\nvarying vec4 vcolor4;\n\nconst int kernelSize = 16; \nconst float radius = 0.5; \n\nfloat unpackDepth(const in vec4 rgba_depth)\n{\n const vec4 bit_shift = vec4(0.000000059605, 0.000015258789, 0.00390625, 1.0);\n float depth = dot(rgba_depth, bit_shift);\n return depth;\n} \n\nvec3 getViewRay(vec2 tc)\n{\n float hfar = 2.0 * tan(fov/2.0) * far;\n float wfar = hfar * aspectRatio; \n vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n return ray; \n} \n \n//linear view space depth\nfloat getDepth(vec2 coord)\n{ \n return unpackDepth(texture2D(depthTex, coord.xy));\n} \n\nvoid main()\n{ \n vec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight);\t\t \n float linearDepth = getDepth(screenPos); \n vec3 origin = getViewRay(screenPos) * linearDepth; \n vec3 normal2 = vNormal; \n \n vec3 rvec = texture2D(noiseTex, screenPos.xy * noiseScale).xyz * 2.0 - 1.0;\n vec3 tangent = normalize(rvec - normal2 * dot(rvec, normal2));\n vec3 bitangent = cross(normal2, tangent);\n mat3 tbn = mat3(tangent, bitangent, normal2); \n \n float occlusion = 0.0;\n for(int i = 0; i < kernelSize; ++i)\n { \t \n vec3 sample = origin + (tbn * kernel[i]) * radius;\n vec4 offset = projectionMatrix * vec4(sample, 1.0);\t\t\n offset.xy /= offset.w;\n offset.xy = offset.xy * 0.5 + 0.5; \n float sampleDepth = -sample.z/far;\n float depthBufferValue = getDepth(offset.xy);\t\t\t\t \n float range_check = abs(linearDepth - depthBufferValue)+radius*0.998;\n if (range_check < radius*1.001 && depthBufferValue <= sampleDepth)\n {\n occlusion += 1.0;\n }\n \n } \n \n occlusion = 1.0 - occlusion / float(kernelSize);\n \n vec3 lightPos = vec3(10.0, 10.0, 10.0);\n vec3 L = normalize(lightPos);\n float DiffuseFactor = dot(normal2, L);\n float NdotL = abs(DiffuseFactor);\n vec3 diffuse = vec3(NdotL);\n vec3 ambient = vec3(1.0);\n vec4 textureColor;\n textureColor = vcolor4;\n\n gl_FragColor.rgb = vec3((textureColor.xyz)*vLightWeighting * occlusion); \n gl_FragColor.a = 1.0; \n}\n",LegoSsaoVS:"attribute vec3 position;\nattribute vec3 normal;\nattribute vec4 color4;\nattribute vec2 texCoord;\n\nuniform mat4 projectionMatrix; \nuniform mat4 modelViewMatrix;\nuniform mat4 modelViewMatrixRelToEye; \nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform mat4 RefTransfMatrix;\nuniform mat4 normalMatrix4;\nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nuniform vec3 aditionalPosition;\n\nvarying vec3 vNormal;\nvarying vec2 vTexCoord; \nvarying vec3 uAmbientColor;\nvarying vec3 vLightWeighting;\nvarying vec4 vcolor4;\n\nvoid main()\n{\t\n vec4 rotatedPos = RefTransfMatrix * vec4(position.xyz + aditionalPosition.xyz, 1.0);\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n \n vec3 rotatedNormal = mat3(RefTransfMatrix) * normal;\n vLightWeighting = vec3(1.0, 1.0, 1.0);\n uAmbientColor = vec3(0.8, 0.8, 0.8);\n vec3 uLightingDirection = vec3(0.5, 0.5, 0.5);\n vec3 directionalLightColor = vec3(0.6, 0.6, 0.6);\n vNormal = (normalMatrix4 * vec4(rotatedNormal.x, rotatedNormal.y, rotatedNormal.z, 1.0)).xyz;\n\n float directionalLightWeighting = max(dot(vNormal, uLightingDirection), 0.0);\n vLightWeighting = uAmbientColor + directionalLightColor * directionalLightWeighting;\n vcolor4 = color4;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n}\n",LodBuildingDepthFS:"#ifdef GL_ES\n precision highp float;\n#endif\nvarying float depth; \n\nvec4 packDepth(const in float depth)\n{\n const vec4 bit_shift = vec4(16777216.0, 65536.0, 256.0, 1.0);\n const vec4 bit_mask = vec4(0.0, 0.00390625, 0.00390625, 0.00390625); \n vec4 res = fract(depth * bit_shift);\n res -= res.xxyz * bit_mask;\n return res; \n}\n\nvoid main()\n{ \n gl_FragData[0] = packDepth(-depth);\n}\n",LodBuildingDepthVS:"attribute vec3 position;\n\nuniform mat4 modelViewMatrixRelToEye; \nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform mat4 buildingRotMatrix; \nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nuniform float near;\nuniform float far;\nuniform vec3 aditionalPosition;\n\nvarying float depth; \nvoid main()\n{\t\n vec4 rotatedPos = buildingRotMatrix * vec4(position.xyz + aditionalPosition.xyz, 1.0);\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n \n depth = (modelViewMatrixRelToEye * pos4).z/far;\n \n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n}\n",LodBuildingSsaoFS:"#ifdef GL_ES\n precision highp float;\n#endif\nuniform sampler2D depthTex;\nuniform sampler2D noiseTex; \nuniform sampler2D diffuseTex;\nuniform bool hasTexture;\nuniform bool textureFlipYAxis;\nvarying vec3 vNormal;\nuniform mat4 projectionMatrix;\nuniform mat4 m;\nuniform vec2 noiseScale;\nuniform float near;\nuniform float far; \nuniform float fov;\nuniform float aspectRatio; \nuniform float screenWidth; \nuniform float screenHeight; \nuniform float shininessValue; \nuniform vec3 kernel[16]; \nuniform vec4 vColor4Aux;\nuniform bool bApplyScpecularLighting;\n\nvarying vec2 vTexCoord; \nvarying vec3 vLightWeighting;\nvarying vec4 vcolor4;\nuniform vec3 specularColor;\nvarying vec3 vertexPos;\nvarying float applySpecLighting;\n\nconst int kernelSize = 16; \nuniform float radius; \n\nuniform float ambientReflectionCoef;\nuniform float diffuseReflectionCoef; \nuniform float specularReflectionCoef; \n\nfloat unpackDepth(const in vec4 rgba_depth)\n{\n const vec4 bit_shift = vec4(0.000000059605, 0.000015258789, 0.00390625, 1.0);\n float depth = dot(rgba_depth, bit_shift);\n return depth;\n} \n\nvec3 getViewRay(vec2 tc)\n{\n float hfar = 2.0 * tan(fov/2.0) * far;\n float wfar = hfar * aspectRatio; \n vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n return ray; \n} \n \n//linear view space depth\nfloat getDepth(vec2 coord)\n{ \n return unpackDepth(texture2D(depthTex, coord.xy));\n} \n\nvoid main()\n{ \n vec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight);\t\t \n float linearDepth = getDepth(screenPos); \n vec3 origin = getViewRay(screenPos) * linearDepth; \n\n vec3 normal2 = vNormal; \n \n vec3 rvec = texture2D(noiseTex, screenPos.xy * noiseScale).xyz * 2.0 - 1.0;\n vec3 tangent = normalize(rvec - normal2 * dot(rvec, normal2));\n vec3 bitangent = cross(normal2, tangent);\n mat3 tbn = mat3(tangent, bitangent, normal2); \n \n float occlusion = 0.0;\n for(int i = 0; i < kernelSize; ++i)\n { \t \n vec3 sample = origin + (tbn * kernel[i]) * radius;\n vec4 offset = projectionMatrix * vec4(sample, 1.0);\t\t\n offset.xy /= offset.w;\n offset.xy = offset.xy * 0.5 + 0.5; \n float sampleDepth = -sample.z/far;\n\t\tif(sampleDepth > 0.49)\n\t\t\tcontinue;\n float depthBufferValue = getDepth(offset.xy);\t\t\t\t \n float range_check = abs(linearDepth - depthBufferValue)+radius*0.998;\n if (range_check < radius*1.001 && depthBufferValue <= sampleDepth)\n {\n occlusion += 1.0;\n }\n \n } \n \n occlusion = 1.0 - occlusion / float(kernelSize);\n\n\tfloat lambertian;\n\tfloat specular;\n if(applySpecLighting > 0.0)\n\t{\n\t\tvec3 lightPos = vec3(20.0, 60.0, 20.0);\n\t\tvec3 L = normalize(lightPos - vertexPos);\n\t\tlambertian = max(dot(normal2, L), 0.0);\n\t\tspecular = 0.0;\n\t\tif(lambertian > 0.0)\n\t\t{\n\t\t\tvec3 R = reflect(-L, normal2); // Reflected light vector\n\t\t\tvec3 V = normalize(-vertexPos); // Vector to viewer\n\t\t\t\n\t\t\t// Compute the specular term\n\t\t\tfloat specAngle = max(dot(R, V), 0.0);\n\t\t\tspecular = pow(specAngle, shininessValue);\n\t\t}\n\t\t\n\t\tif(lambertian < 0.5)\n\t\t{\n\t\t\tlambertian = 0.5;\n\t\t}\n\t}\n\n vec4 textureColor;\n if(hasTexture)\n {\n if(textureFlipYAxis)\n {\n textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, 1.0 - vTexCoord.t));\n }\n else{\n textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, vTexCoord.t));\n }\n\t\t\n if(textureColor.w == 0.0)\n {\n discard;\n }\n }\n else{\n textureColor = vcolor4;\n }\n\t\n\tvec3 ambientColor = vec3(textureColor.x, textureColor.y, textureColor.z);\n\tvec4 finalColor;\n\tif(applySpecLighting > 0.0)\n\t{\n\t\tfinalColor = vec4((ambientReflectionCoef * ambientColor + diffuseReflectionCoef * lambertian * textureColor.xyz + specularReflectionCoef * specular * specularColor)*vLightWeighting * occlusion, 1.0); \n\t}\n\telse{\n\t\tfinalColor = vec4((textureColor.xyz) * occlusion, 1.0);\n\t}\n gl_FragColor = finalColor; \n}\n",LodBuildingSsaoSimpleCompressFS:"#ifdef GL_ES\n precision highp float;\n#endif\nuniform sampler2D depthTex;\nuniform sampler2D noiseTex; \nuniform sampler2D diffuseTex;\nuniform bool hasTexture;\nuniform bool textureFlipYAxis;\nvarying vec3 vNormal;\nuniform mat4 projectionMatrix;\nuniform mat4 m;\nuniform vec2 noiseScale;\nuniform float near;\nuniform float far; \nuniform float fov;\nuniform float aspectRatio; \nuniform float screenWidth; \nuniform float screenHeight; \nuniform vec3 kernel[16]; \nuniform vec4 vColor4Aux;\n\nvarying vec2 vTexCoord; \nvarying vec4 vcolor4;\nuniform vec3 specularColor;\n\nconst int kernelSize = 16; \nuniform float radius; \n\nfloat unpackDepth(const in vec4 rgba_depth)\n{\n const vec4 bit_shift = vec4(0.000000059605, 0.000015258789, 0.00390625, 1.0);\n float depth = dot(rgba_depth, bit_shift);\n return depth;\n} \n\nvec3 getViewRay(vec2 tc)\n{\n float hfar = 2.0 * tan(fov/2.0) * far;\n float wfar = hfar * aspectRatio; \n vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n return ray; \n} \n \n//linear view space depth\nfloat getDepth(vec2 coord)\n{ \n return unpackDepth(texture2D(depthTex, coord.xy));\n} \n\nvoid main()\n{ \n vec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight);\t\t \n float linearDepth = getDepth(screenPos); \n vec3 origin = getViewRay(screenPos) * linearDepth; \n\n vec3 normal2 = vNormal; \n \n vec3 rvec = texture2D(noiseTex, screenPos.xy * noiseScale).xyz * 2.0 - 1.0;\n vec3 tangent = normalize(rvec - normal2 * dot(rvec, normal2));\n vec3 bitangent = cross(normal2, tangent);\n mat3 tbn = mat3(tangent, bitangent, normal2); \n \n float occlusion = 0.0;\n for(int i = 0; i < kernelSize; ++i)\n { \t \n vec3 sample = origin + (tbn * kernel[i]) * radius;\n vec4 offset = projectionMatrix * vec4(sample, 1.0);\t\t\n offset.xy /= offset.w;\n offset.xy = offset.xy * 0.5 + 0.5; \n float sampleDepth = -sample.z/far;\n\t\tif(sampleDepth > 0.49)\n\t\t\tcontinue;\n float depthBufferValue = getDepth(offset.xy);\t\t\t\t \n float range_check = abs(linearDepth - depthBufferValue)+radius*0.998;\n if (range_check < radius*1.001 && depthBufferValue <= sampleDepth)\n {\n occlusion += 1.0;\n }\n } \n \n occlusion = 1.0 - occlusion / float(kernelSize);\n\n vec4 textureColor;\n if(hasTexture)\n {\n if(textureFlipYAxis)\n {\n textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, 1.0 - vTexCoord.t));\n }\n else{\n textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, vTexCoord.t));\n }\n\t\t\n if(textureColor.w == 0.0)\n {\n discard;\n }\n }\n else{\n textureColor = vcolor4;\n }\n\n gl_FragColor = vec4((textureColor.xyz) * occlusion, 1.0); \n}\n",LodBuildingSsaoSimpleCompressVS:"attribute vec3 position;\nattribute vec3 normal;\nattribute vec4 color4;\nattribute vec2 texCoord;\n\nuniform sampler2D diffuseTex;\nuniform mat4 projectionMatrix; \nuniform mat4 modelViewMatrix;\nuniform mat4 modelViewMatrixRelToEye; \nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform mat4 normalMatrix4;\nuniform mat4 buildingRotMatrix; \nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nuniform vec3 aditionalPosition;\nuniform vec4 oneColor4;\nuniform bool bUse1Color;\nuniform bool hasTexture;\n\nuniform int posDataByteSize;\nuniform int texCoordByteSize;\nuniform vec3 compressionMaxPoint;\nuniform vec3 compressionMinPoint;\n\nvarying vec3 vNormal;\nvarying vec2 vTexCoord; \nvarying vec3 vLightWeighting;\nvarying vec4 vcolor4;\n\nvoid main()\n{\t\n vec3 finalPos;\n\tvec2 finalTexCoord;\n\tif(posDataByteSize == 2)\n\t{\n\t\t// Decompress the position.*** \n\t\tfloat rangeX = compressionMaxPoint.x - compressionMinPoint.x;\n\t\tfloat rangeY = compressionMaxPoint.y - compressionMinPoint.y;\n\t\tfloat rangeZ = compressionMaxPoint.z - compressionMinPoint.z;\n\t\tfloat shortMax = 65535.0;\n\t\tfinalPos.x = (float(position.x) * rangeX / shortMax) + compressionMinPoint.x;\n\t\tfinalPos.y = (float(position.y) * rangeY / shortMax) + compressionMinPoint.y;\n\t\tfinalPos.z = (float(position.z) * rangeZ / shortMax) + compressionMinPoint.z;\n\t}\n\telse{\n\t\tfinalPos = position;\n\t}\n\tvec4 rotatedPos = buildingRotMatrix * vec4(finalPos.xyz + aditionalPosition.xyz, 1.0);\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\t\n vec4 rotatedNormal = buildingRotMatrix * vec4(normal.xyz, 1.0);\n vNormal = (normalMatrix4 * vec4(rotatedNormal.x, rotatedNormal.y, rotatedNormal.z, 1.0)).xyz;\n\n if(bUse1Color)\n {\n vcolor4 = oneColor4;\n }\n else\n {\n vcolor4 = color4;\n }\n\t\n if(texCoordByteSize == 2)\n\t{\n\t\t// Decompress the texCoord.***\n\t\tfloat shortMax = 65535.0;\n\t\tfinalTexCoord.x = float(texCoord.x) / shortMax;\n\t\tfinalTexCoord.y = float(texCoord.y) / shortMax;\n\t}\n\telse\n\t{\n\t\tfinalTexCoord = texCoord;\n\t}\n vTexCoord = finalTexCoord;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n}\n",LodBuildingSsaoSimpleFS:"#ifdef GL_ES\n precision highp float;\n#endif\nuniform sampler2D depthTex;\nuniform sampler2D noiseTex; \nuniform sampler2D diffuseTex;\nuniform bool hasTexture;\nuniform bool textureFlipYAxis;\nvarying vec3 vNormal;\nuniform mat4 projectionMatrix;\nuniform mat4 m;\nuniform vec2 noiseScale;\nuniform float near;\nuniform float far; \nuniform float fov;\nuniform float aspectRatio; \nuniform float screenWidth; \nuniform float screenHeight; \nuniform vec3 kernel[16]; \nuniform vec4 vColor4Aux;\n\nvarying vec2 vTexCoord; \nvarying vec4 vcolor4;\nuniform vec3 specularColor;\n\nconst int kernelSize = 16; \nuniform float radius; \n\nfloat unpackDepth(const in vec4 rgba_depth)\n{\n const vec4 bit_shift = vec4(0.000000059605, 0.000015258789, 0.00390625, 1.0);\n float depth = dot(rgba_depth, bit_shift);\n return depth;\n} \n\nvec3 getViewRay(vec2 tc)\n{\n float hfar = 2.0 * tan(fov/2.0) * far;\n float wfar = hfar * aspectRatio; \n vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n return ray; \n} \n \n//linear view space depth\nfloat getDepth(vec2 coord)\n{ \n return unpackDepth(texture2D(depthTex, coord.xy));\n} \n\nvoid main()\n{ \n vec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight);\t\t \n float linearDepth = getDepth(screenPos); \n vec3 origin = getViewRay(screenPos) * linearDepth; \n\n vec3 normal2 = vNormal; \n \n vec3 rvec = texture2D(noiseTex, screenPos.xy * noiseScale).xyz * 2.0 - 1.0;\n vec3 tangent = normalize(rvec - normal2 * dot(rvec, normal2));\n vec3 bitangent = cross(normal2, tangent);\n mat3 tbn = mat3(tangent, bitangent, normal2); \n \n float occlusion = 0.0;\n for(int i = 0; i < kernelSize; ++i)\n { \t \n vec3 sample = origin + (tbn * kernel[i]) * radius;\n vec4 offset = projectionMatrix * vec4(sample, 1.0);\t\t\n offset.xy /= offset.w;\n offset.xy = offset.xy * 0.5 + 0.5; \n float sampleDepth = -sample.z/far;\n\t\tif(sampleDepth > 0.49)\n\t\t\tcontinue;\n float depthBufferValue = getDepth(offset.xy);\t\t\t\t \n float range_check = abs(linearDepth - depthBufferValue)+radius*0.998;\n if (range_check < radius*1.001 && depthBufferValue <= sampleDepth)\n {\n occlusion += 1.0;\n }\n } \n \n occlusion = 1.0 - occlusion / float(kernelSize);\n\n vec4 textureColor;\n if(hasTexture)\n {\n if(textureFlipYAxis)\n {\n textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, 1.0 - vTexCoord.t));\n }\n else{\n textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, vTexCoord.t));\n }\n\t\t\n if(textureColor.w == 0.0)\n {\n discard;\n }\n }\n else{\n textureColor = vcolor4;\n }\n\n gl_FragColor = vec4((textureColor.xyz) * occlusion, 1.0); \n}\n",LodBuildingSsaoSimpleVS:"attribute vec3 position;\nattribute vec3 normal;\nattribute vec4 color4;\nattribute vec2 texCoord;\n\nuniform sampler2D diffuseTex;\nuniform mat4 projectionMatrix; \nuniform mat4 modelViewMatrix;\nuniform mat4 modelViewMatrixRelToEye; \nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform mat4 normalMatrix4;\nuniform mat4 buildingRotMatrix; \nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nuniform vec3 aditionalPosition;\nuniform vec4 oneColor4;\nuniform bool bUse1Color;\nuniform bool hasTexture;\n\nvarying vec2 vTexCoord; \nvarying vec4 vcolor4;\n\nvoid main()\n{\t\n vec4 rotatedPos = buildingRotMatrix * vec4(position.xyz + aditionalPosition.xyz, 1.0);\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\n if(bUse1Color)\n {\n vcolor4 = oneColor4;\n }\n else\n {\n vcolor4 = color4;\n }\n vTexCoord = texCoord;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n}",LodBuildingSsaoVS:"attribute vec3 position;\nattribute vec3 normal;\nattribute vec4 color4;\nattribute vec2 texCoord;\n\nuniform sampler2D diffuseTex;\nuniform mat4 projectionMatrix; \nuniform mat4 modelViewMatrix;\nuniform mat4 modelViewMatrixRelToEye; \nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform mat4 normalMatrix4;\nuniform mat4 buildingRotMatrix; \nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nuniform vec3 aditionalPosition;\nuniform vec4 oneColor4;\nuniform bool bUse1Color;\nuniform bool hasTexture;\nuniform bool bApplySpecularLighting;\n\nvarying vec3 vNormal;\nvarying vec2 vTexCoord; \nvarying vec3 uAmbientColor;\nvarying vec3 vLightWeighting;\nvarying vec4 vcolor4;\nvarying vec3 vertexPos;\nvarying float applySpecLighting;\n\nvoid main()\n{\t\n vec4 rotatedPos = buildingRotMatrix * vec4(position.xyz + aditionalPosition.xyz, 1.0);\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\t\n\tvertexPos = vec3(modelViewMatrixRelToEye * pos4);\n vec4 rotatedNormal = buildingRotMatrix * vec4(normal.xyz, 1.0);\n vLightWeighting = vec3(1.0, 1.0, 1.0);\n uAmbientColor = vec3(0.8, 0.8, 0.8);\n vec3 uLightingDirection = vec3(0.6, 0.6, 0.6);\n vec3 directionalLightColor = vec3(0.7, 0.7, 0.7);\n vNormal = (normalMatrix4 * vec4(rotatedNormal.x, rotatedNormal.y, rotatedNormal.z, 1.0)).xyz;\n float directionalLightWeighting = max(dot(vNormal, uLightingDirection), 0.0);\n vLightWeighting = uAmbientColor + directionalLightColor * directionalLightWeighting;\n\t\n\tif(bApplySpecularLighting)\n\t\t\tapplySpecLighting = 1.0;\n\t\telse\n\t\t\tapplySpecLighting = -1.0;\n\n if(bUse1Color)\n {\n vcolor4 = oneColor4;\n }\n else\n {\n vcolor4 = color4;\n }\n vTexCoord = texCoord;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n}\n",ModelRefSsaoFS:"#ifdef GL_ES\n precision highp float;\n#endif\n\nuniform sampler2D depthTex;\nuniform sampler2D noiseTex; \nuniform sampler2D diffuseTex;\nuniform bool hasTexture;\nuniform bool textureFlipYAxis;\nvarying vec3 vNormal;\nuniform mat4 projectionMatrix;\nuniform mat4 m;\nuniform vec2 noiseScale;\nuniform float near;\nuniform float far; \nuniform float fov;\nuniform float aspectRatio; \nuniform float screenWidth; \nuniform float screenHeight; \nuniform float shininessValue;\nuniform vec3 kernel[16]; \nuniform vec4 oneColor4;\nuniform bool bApplyScpecularLighting;\n\nvarying vec2 vTexCoord; \nvarying vec3 vLightWeighting;\n\nvarying vec3 diffuseColor;\nuniform vec3 specularColor;\nvarying vec3 vertexPos;\n\nconst int kernelSize = 16; \nuniform float radius; \n\nuniform float ambientReflectionCoef;\nuniform float diffuseReflectionCoef; \nuniform float specularReflectionCoef; \nvarying float applySpecLighting;\n\nfloat unpackDepth(const in vec4 rgba_depth)\n{\n const vec4 bit_shift = vec4(0.000000059605, 0.000015258789, 0.00390625, 1.0);\n float depth = dot(rgba_depth, bit_shift);\n return depth;\n} \n\nvec3 getViewRay(vec2 tc)\n{\n float hfar = 2.0 * tan(fov/2.0) * far;\n float wfar = hfar * aspectRatio; \n vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n return ray; \n} \n \n//linear view space depth\nfloat getDepth(vec2 coord)\n{\n return unpackDepth(texture2D(depthTex, coord.xy));\n} \n\nvoid main()\n{ \n vec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight);\t\t \n float linearDepth = getDepth(screenPos); \n vec3 origin = getViewRay(screenPos) * linearDepth; \n\n vec3 normal2 = vNormal;\n \n vec3 rvec = texture2D(noiseTex, screenPos.xy * noiseScale).xyz * 2.0 - 1.0;\n vec3 tangent = normalize(rvec - normal2 * dot(rvec, normal2));\n vec3 bitangent = cross(normal2, tangent);\n mat3 tbn = mat3(tangent, bitangent, normal2); \n \n float occlusion = 0.0;\n for(int i = 0; i < kernelSize; ++i)\n { \t \n vec3 sample = origin + (tbn * kernel[i]) * radius;\n vec4 offset = projectionMatrix * vec4(sample, 1.0);\t\t\n offset.xy /= offset.w;\n offset.xy = offset.xy * 0.5 + 0.5; \n float sampleDepth = -sample.z/far;\n\t\tif(sampleDepth > 0.49)\n\t\t\tcontinue;\n float depthBufferValue = getDepth(offset.xy);\t\t\t\t \n float range_check = abs(linearDepth - depthBufferValue)+radius*0.998;\n if (range_check < radius*1.001 && depthBufferValue <= sampleDepth)\n {\n occlusion += 1.0;\n }\n } \n \n occlusion = 1.0 - occlusion / float(kernelSize);\n\n // Do specular lighting.***\n\tfloat lambertian;\n\tfloat specular;\n\t\t\n\tif(applySpecLighting> 0.0)\n\t{\n\t\tvec3 lightPos = vec3(20.0, 60.0, 20.0);\n\t\tvec3 L = normalize(lightPos - vertexPos);\n\t\tlambertian = max(dot(normal2, L), 0.0);\n\t\tspecular = 0.0;\n\t\tif(lambertian > 0.0)\n\t\t{\n\t\t\tvec3 R = reflect(-L, normal2); // Reflected light vector\n\t\t\tvec3 V = normalize(-vertexPos); // Vector to viewer\n\t\t\t\n\t\t\t// Compute the specular term\n\t\t\tfloat specAngle = max(dot(R, V), 0.0);\n\t\t\tspecular = pow(specAngle, shininessValue);\n\t\t}\n\t\t\n\t\tif(lambertian < 0.5)\n\t\t{\n\t\t\tlambertian = 0.5;\n\t\t}\n\t}\n\n vec4 textureColor;\n if(hasTexture)\n {\n if(textureFlipYAxis)\n {\n textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, 1.0 - vTexCoord.t));\n }\n else{\n textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, vTexCoord.t));\n }\n\t\t\n if(textureColor.w == 0.0)\n {\n discard;\n }\n }\n else{\n textureColor = oneColor4;\n }\n\t\n\tvec3 ambientColor = vec3(textureColor.x, textureColor.y, textureColor.z);\n\tfloat alfa = textureColor.w;\n\n vec4 finalColor;\n\tif(applySpecLighting> 0.0)\n\t{\n\t\tfinalColor = vec4((ambientReflectionCoef * ambientColor + diffuseReflectionCoef * lambertian * textureColor.xyz + specularReflectionCoef * specular * specularColor)*vLightWeighting * occlusion, alfa); \n\t}\n\telse{\n\t\tfinalColor = vec4((textureColor.xyz) * occlusion, alfa);\n\t}\n gl_FragColor = finalColor; \n}\n",ModelRefSsaoSimpleFS:"#ifdef GL_ES\n precision highp float;\n#endif\n\nuniform sampler2D depthTex;\nuniform sampler2D noiseTex; \nuniform sampler2D diffuseTex;\nuniform bool hasTexture;\nuniform bool textureFlipYAxis;\nvarying vec3 vNormal;\nuniform mat4 projectionMatrix;\nuniform mat4 m;\nuniform vec2 noiseScale;\nuniform float near;\nuniform float far; \nuniform float fov;\nuniform float aspectRatio; \nuniform float screenWidth; \nuniform float screenHeight; \nuniform float shininessValue;\nuniform vec3 kernel[16]; \nuniform vec4 oneColor4;\n\nvarying vec2 vTexCoord; \nvarying vec3 vLightWeighting;\n\nvarying vec3 diffuseColor;\nuniform vec3 specularColor;\nvarying vec3 vertexPos;\n\nconst int kernelSize = 16; \nuniform float radius; \n\nuniform float ambientReflectionCoef;\nuniform float diffuseReflectionCoef; \nuniform float specularReflectionCoef; \n\nfloat unpackDepth(const in vec4 rgba_depth)\n{\n const vec4 bit_shift = vec4(0.000000059605, 0.000015258789, 0.00390625, 1.0);\n float depth = dot(rgba_depth, bit_shift);\n return depth;\n} \n\nvec3 getViewRay(vec2 tc)\n{\n float hfar = 2.0 * tan(fov/2.0) * far;\n float wfar = hfar * aspectRatio; \n vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n return ray; \n} \n \n//linear view space depth\nfloat getDepth(vec2 coord)\n{\n return unpackDepth(texture2D(depthTex, coord.xy));\n} \n\nvoid main()\n{ \n vec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight);\t\t \n float linearDepth = getDepth(screenPos); \n vec3 origin = getViewRay(screenPos) * linearDepth; \n\n vec3 normal2 = vNormal;\n \n vec3 rvec = texture2D(noiseTex, screenPos.xy * noiseScale).xyz * 2.0 - 1.0;\n vec3 tangent = normalize(rvec - normal2 * dot(rvec, normal2));\n vec3 bitangent = cross(normal2, tangent);\n mat3 tbn = mat3(tangent, bitangent, normal2); \n \n float occlusion = 0.0;\n for(int i = 0; i < kernelSize; ++i)\n { \t \n vec3 sample = origin + (tbn * kernel[i]) * radius;\n vec4 offset = projectionMatrix * vec4(sample, 1.0);\t\t\n offset.xy /= offset.w;\n offset.xy = offset.xy * 0.5 + 0.5; \n float sampleDepth = -sample.z/far;\n\t\tif(sampleDepth > 0.49)\n\t\t\tcontinue;\n float depthBufferValue = getDepth(offset.xy);\t\t\t\t \n float range_check = abs(linearDepth - depthBufferValue)+radius*0.998;\n if (range_check < radius*1.001 && depthBufferValue <= sampleDepth)\n {\n occlusion += 1.0;\n }\n } \n \n occlusion = 1.0 - occlusion / float(kernelSize);\n\n vec4 textureColor;\n if(hasTexture)\n {\n if(textureFlipYAxis)\n {\n textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, 1.0 - vTexCoord.t));\n }\n else{\n textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, vTexCoord.t));\n }\n\t\t\n if(textureColor.w == 0.0)\n {\n discard;\n }\n }\n else{\n textureColor = oneColor4;\n }\n\t\n\tgl_FragColor = vec4((textureColor.xyz) * occlusion, 1.0); \n}\n",ModelRefSsaoSimpleVS:"\tattribute vec3 position;\n\tattribute vec3 normal;\n\tattribute vec2 texCoord;\n\t\n\tuniform mat4 buildingRotMatrix; \n\tuniform mat4 projectionMatrix; \n\tuniform mat4 modelViewMatrix;\n\tuniform mat4 modelViewMatrixRelToEye; \n\tuniform mat4 ModelViewProjectionMatrixRelToEye;\n\tuniform mat4 RefTransfMatrix;\n\tuniform mat4 normalMatrix4;\n\tuniform vec3 buildingPosHIGH;\n\tuniform vec3 buildingPosLOW;\n\tuniform vec3 encodedCameraPositionMCHigh;\n\tuniform vec3 encodedCameraPositionMCLow;\n\tuniform vec3 aditionalPosition;\n\tuniform vec3 refTranslationVec;\n\tuniform int refMatrixType; // 0= identity, 1= translate, 2= transform\n\n\tvarying vec3 vNormal;\n\tvarying vec2 vTexCoord; \n\tvarying vec3 uAmbientColor;\n\tvarying vec3 vLightWeighting;\n\tvarying vec3 vertexPos;\n\t\n\tvoid main()\n {\t\n\t\tvec4 rotatedPos;\n\t\tmat3 currentTMat;\n\t\tif(refMatrixType == 0)\n\t\t{\n\t\t\trotatedPos = buildingRotMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t\t\tcurrentTMat = mat3(buildingRotMatrix);\n\t\t}\n\t\telse if(refMatrixType == 1)\n\t\t{\n\t\t\trotatedPos = buildingRotMatrix * vec4(position.xyz + refTranslationVec.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t\t\tcurrentTMat = mat3(buildingRotMatrix);\n\t\t}\n\t\telse if(refMatrixType == 2)\n\t\t{\n\t\t\trotatedPos = RefTransfMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t\t\tcurrentTMat = mat3(RefTransfMatrix);\n\t\t}\n\n\t\tvec3 objPosHigh = buildingPosHIGH;\n\t\tvec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n\t\tvec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\t\tvec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\t\tvec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\n\t\tvertexPos = vec3(modelViewMatrixRelToEye * pos4);\n\t\tvec3 rotatedNormal = currentTMat * normal;\n\t\tvLightWeighting = vec3(1.0, 1.0, 1.0);\n\t\tuAmbientColor = vec3(0.8);\n\t\tvec3 uLightingDirection = vec3(0.6, 0.6, 0.6);\n\t\tvec3 directionalLightColor = vec3(0.7, 0.7, 0.7);\n\t\tvNormal = (normalMatrix4 * vec4(rotatedNormal.x, rotatedNormal.y, rotatedNormal.z, 1.0)).xyz;\n\t\tvTexCoord = texCoord;\n\t\tfloat directionalLightWeighting = max(dot(vNormal, uLightingDirection), 0.0);\n\t\tvLightWeighting = uAmbientColor + directionalLightColor * directionalLightWeighting;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\t}\n",ModelRefSsaoVS:"\tattribute vec3 position;\n\tattribute vec3 normal;\n\tattribute vec2 texCoord;\n\t\n\tuniform mat4 buildingRotMatrix; \n\tuniform mat4 projectionMatrix; \n\tuniform mat4 modelViewMatrix;\n\tuniform mat4 modelViewMatrixRelToEye; \n\tuniform mat4 ModelViewProjectionMatrixRelToEye;\n\tuniform mat4 RefTransfMatrix;\n\tuniform mat4 normalMatrix4;\n\tuniform vec3 buildingPosHIGH;\n\tuniform vec3 buildingPosLOW;\n\tuniform vec3 encodedCameraPositionMCHigh;\n\tuniform vec3 encodedCameraPositionMCLow;\n\tuniform vec3 aditionalPosition;\n\tuniform vec3 refTranslationVec;\n\tuniform int refMatrixType; // 0= identity, 1= translate, 2= transform\n\tuniform bool bApplySpecularLighting;\n\n\tvarying vec3 vNormal;\n\tvarying vec2 vTexCoord; \n\tvarying vec3 uAmbientColor;\n\tvarying vec3 vLightWeighting;\n\tvarying vec3 vertexPos;\n\tvarying float applySpecLighting;\n\t\n\tvoid main()\n {\t\n\t\tvec4 rotatedPos;\n\t\tmat3 currentTMat;\n\t\tif(refMatrixType == 0)\n\t\t{\n\t\t\trotatedPos = buildingRotMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t\t\tcurrentTMat = mat3(buildingRotMatrix);\n\t\t}\n\t\telse if(refMatrixType == 1)\n\t\t{\n\t\t\trotatedPos = buildingRotMatrix * vec4(position.xyz + refTranslationVec.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t\t\tcurrentTMat = mat3(buildingRotMatrix);\n\t\t}\n\t\telse if(refMatrixType == 2)\n\t\t{\n\t\t\trotatedPos = RefTransfMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t\t\tcurrentTMat = mat3(RefTransfMatrix);\n\t\t}\n\n\t\tvec3 objPosHigh = buildingPosHIGH;\n\t\tvec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n\t\tvec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\t\tvec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\t\tvec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\n\t\tvertexPos = vec3(modelViewMatrixRelToEye * pos4);\n\t\tvec3 rotatedNormal = currentTMat * normal;\n\t\tvLightWeighting = vec3(1.0, 1.0, 1.0);\n\t\tuAmbientColor = vec3(0.8);\n\t\tvec3 uLightingDirection = vec3(0.6, 0.6, 0.6);\n\t\tvec3 directionalLightColor = vec3(0.7, 0.7, 0.7);\n\t\tvNormal = (normalMatrix4 * vec4(rotatedNormal.x, rotatedNormal.y, rotatedNormal.z, 1.0)).xyz;\n\t\tvTexCoord = texCoord;\n\t\tfloat directionalLightWeighting = max(dot(vNormal, uLightingDirection), 0.0);\n\t\tvLightWeighting = uAmbientColor + directionalLightColor * directionalLightWeighting;\n\t\t\n\t\tif(bApplySpecularLighting)\n\t\t\tapplySpecLighting = 1.0;\n\t\telse\n\t\t\tapplySpecLighting = -1.0;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\t}\n",PngImageFS:"precision mediump float;\nvarying vec2 v_texcoord;\nuniform bool textureFlipYAxis;\nuniform sampler2D u_texture;\n\nvoid main()\n{\n vec4 textureColor;\n if(textureFlipYAxis)\n {\n textureColor = texture2D(u_texture, vec2(v_texcoord.s, 1.0 - v_texcoord.t));\n }\n else\n {\n textureColor = texture2D(u_texture, v_texcoord);\n }\n if(textureColor.w < 0.1)\n {\n discard;\n }\n\n gl_FragColor = textureColor;\n}",PngImageVS:"attribute vec3 a_position;\nattribute vec2 a_texcoord;\nuniform mat4 buildingRotMatrix; \nuniform mat4 ModelViewProjectionMatrixRelToEye; \nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nvarying vec2 v_texcoord;\n\nvoid main()\n{\n vec4 position2 = vec4(a_position.xyz, 1.0);\n vec4 rotatedPos = buildingRotMatrix * vec4(position2.xyz, 1.0);\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\n v_texcoord = a_texcoord;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n}\n",PointCloudFS:"\tprecision lowp float;\n\tvarying vec4 vColor;\n\n\tvoid main()\n {\n\t\tgl_FragColor = vColor;\n\t}",PointCloudVS:"attribute vec3 position;\nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform mat4 buildingRotMatrix;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nuniform bool bPositionCompressed;\nuniform vec3 minPosition;\nuniform vec3 bboxSize;\nattribute vec4 color4;\nvarying vec4 vColor;\n\nvoid main()\n{\n\tvec3 realPos;\n\tvec4 rotatedPos;\n\tif(bPositionCompressed)\n\t{\n\t\tfloat maxShort = 65535.0;\n\t\trealPos = vec3(float(position.x)/maxShort*bboxSize.x + minPosition.x, float(position.y)/maxShort*bboxSize.y + minPosition.y, float(position.z)/maxShort*bboxSize.z + minPosition.z);\n\t}\n\telse\n\t{\n\t\trealPos = position;\n\t}\n\trotatedPos = buildingRotMatrix * vec4(realPos.xyz, 1.0);\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\n vColor=color4;\n\t\n gl_Position = ModelViewProjectionMatrixRelToEye * pos;\n\tgl_PointSize = 1.0 + 50.0/gl_Position.z;\n\tif(gl_PointSize > 10.0)\n\t\tgl_PointSize = 10.0;\n}",RenderShowDepthFS:"#ifdef GL_ES\nprecision highp float;\n#endif\nuniform float near;\nuniform float far;\n\nvarying float depth; \n\nvec4 packDepth(const in float depth)\n{\n const vec4 bit_shift = vec4(16777216.0, 65536.0, 256.0, 1.0);\n const vec4 bit_mask = vec4(0.0, 0.00390625, 0.00390625, 0.00390625); \n vec4 res = fract(depth * bit_shift);\n res -= res.xxyz * bit_mask;\n return res; \n}\n\nvoid main()\n{ \n gl_FragData[0] = packDepth(-depth);\n}\n",RenderShowDepthVS:"attribute vec3 position;\n\nuniform mat4 buildingRotMatrix; \nuniform mat4 modelViewMatrixRelToEye; \nuniform mat4 RefTransfMatrix;\nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nuniform float near;\nuniform float far;\nuniform vec3 aditionalPosition;\nuniform vec3 refTranslationVec;\nuniform int refMatrixType; // 0= identity, 1= translate, 2= transform\n\nvarying float depth;\n \nvoid main()\n{\t\n\tvec4 rotatedPos;\n\n\tif(refMatrixType == 0)\n\t{\n\t\trotatedPos = buildingRotMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t}\n\telse if(refMatrixType == 1)\n\t{\n\t\trotatedPos = buildingRotMatrix * vec4(position.xyz + refTranslationVec.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t}\n\telse if(refMatrixType == 2)\n\t{\n\t\trotatedPos = RefTransfMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t}\n\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n \n //linear depth in camera space (0..far)\n depth = (modelViewMatrixRelToEye * pos4).z/far;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\tgl_PointSize = 2.0;\n}\n",ShowDepthFS:"#ifdef GL_ES\n precision highp float;\n#endif\nuniform float near;\nuniform float far;\n\nvarying float depth; \nvarying vec3 vN; \nvarying vec4 vVSPos;\n\n// from http://spidergl.org/example.php?id=6\nvec4 packDepth(const in float depth)\n{\n const vec4 bit_shift = vec4(16777216.0, 65536.0, 256.0, 1.0);\n const vec4 bit_mask = vec4(0.0, 0.00390625, 0.00390625, 0.00390625); \n vec4 res = fract(depth * bit_shift);\n res -= res.xxyz * bit_mask;\n\n return res; \n}\n\nvoid main()\n{\n gl_FragData[0] = packDepth(-depth);\n gl_FragData[0].r = -depth/far;\n}\n",ShowDepthVS:"attribute vec3 position;\nattribute vec3 normal;\n\nuniform mat4 modelViewMatrixRelToEye; \nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform mat4 normalMatrix3;\nuniform mat4 normalMatrix4;\nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nuniform float near;\nuniform float far;\n\nvarying vec3 vN;\nvarying float depth; \nvarying vec4 vVSPos;\n\nvoid main()\n{\t\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + position.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\n vN = normalize((normalMatrix4 * vec4(normal, 1.0)).xyz);\n \n //linear depth in camera space (0..far)\n depth = (modelViewMatrixRelToEye * pos4).z/far;\n vVSPos = modelViewMatrixRelToEye * pos4;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n}\n",SilhouetteFS:"precision highp float;\nuniform vec4 vColor4Aux;\n\nvoid main()\n{ \n gl_FragColor = vColor4Aux;\n}",SilhouetteVS:"attribute vec3 position;\n\nuniform mat4 buildingRotMatrix; \nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform mat4 ModelViewMatrixRelToEye;\nuniform mat4 ProjectionMatrix;\nuniform mat4 RefTransfMatrix;\nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nuniform vec3 aditionalPosition;\nuniform vec3 refTranslationVec;\nuniform int refMatrixType; // 0= identity, 1= translate, 2= transform\nuniform vec2 camSpacePixelTranslation;\nuniform vec2 screenSize; \nvarying vec2 camSpaceTranslation;\n\nvoid main()\n{ \n vec4 rotatedPos;\n\tif(refMatrixType == 0)\n\t{\n\t\trotatedPos = buildingRotMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t}\n\telse if(refMatrixType == 1)\n\t{\n\t\trotatedPos = buildingRotMatrix * vec4(position.xyz + refTranslationVec.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t}\n\telse if(refMatrixType == 2)\n\t{\n\t\trotatedPos = RefTransfMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t}\n\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n vec4 camSpacePos = ModelViewMatrixRelToEye * pos4;\n vec4 translationVec = ProjectionMatrix * vec4(camSpacePixelTranslation.x*(-camSpacePos.z), camSpacePixelTranslation.y*(-camSpacePos.z), 0.0, 1.0);\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n gl_Position += translationVec; \n}",SimpleDepthSsaoFS:"precision highp float;\nconst vec4 bitEnc = vec4(1.0,255.0,65025.0,16581375.0);\nconst vec4 bitDec = 1.0/bitEnc;\nvarying float zDepth;\n\nvec4 EncodeFloatRGBA (float v)\n{\n vec4 enc = bitEnc * v;\n enc = fract(enc);\n enc -= enc.yzww * vec2(1.0/255.0, 0.0).xxxy;\n return enc;\n}\n\nvoid main()\n{ \n vec4 encodedZ = EncodeFloatRGBA(zDepth);\n gl_FragData[0] = encodedZ;\n}\n",SimpleDepthSsaoVS:"attribute vec3 position;\n\nuniform mat4 modelViewMatrixRelToEye; \nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform mat4 RefTransfMatrix;\nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nvarying float zDepth;\nuniform float far;\n\nvoid main()\n{\t\n vec4 rotatedPos = RefTransfMatrix * vec4(position.xyz, 1.0);\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n \n zDepth = (modelViewMatrixRelToEye * pos4).z/far;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n}\n",SsaoFS:"#ifdef GL_ES\n precision highp float;\n#endif\nuniform sampler2D depthTex;\nuniform sampler2D noiseTex; \nuniform sampler2D diffuseTex;\nvarying vec3 vNormal;\nuniform mat4 projectionMatrix;\nuniform mat4 m;\nuniform vec2 noiseScale;\nuniform float near;\nuniform float far; \nuniform float fov;\nuniform float aspectRatio; \nuniform float screenWidth; \nuniform float screenHeight; \nuniform vec3 kernel[16]; \n\nvarying vec2 vTexCoord; \n\nconst int kernelSize = 16; \nconst float radius = 1.0; \n\nfloat unpackDepth(const in vec4 rgba_depth)\n{\n const vec4 bit_shift = vec4(0.000000059605, 0.000015258789, 0.00390625, 1.0);\n float depth = dot(rgba_depth, bit_shift);\n return depth;\n} \n\nvec3 getViewRay(vec2 tc)\n{\n float hfar = 2.0 * tan(fov/2.0) * far;\n float wfar = hfar * aspectRatio; \n vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n return ray; \n} \n \n//linear view space depth\nfloat getDepth(vec2 coord)\n{ \n return unpackDepth(texture2D(depthTex, coord.xy));\n} \n\nvoid main()\n{ \n vec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight);\t\t \n float linearDepth = getDepth(screenPos); \n vec3 origin = getViewRay(screenPos) * linearDepth; \n \n vec3 normal2 = vNormal; \n \n vec3 rvec = texture2D(noiseTex, screenPos.xy * noiseScale).xyz * 2.0 - 1.0;\n vec3 tangent = normalize(rvec - normal2 * dot(rvec, normal2));\n vec3 bitangent = cross(normal2, tangent);\n mat3 tbn = mat3(tangent, bitangent, normal2); \n \n float occlusion = 0.0;\n for(int i = 0; i < kernelSize; ++i)\n { \t \n vec3 sample = origin + (tbn * kernel[i]) * radius;\n vec4 offset = projectionMatrix * vec4(sample, 1.0);\t\t\n offset.xy /= offset.w;\n offset.xy = offset.xy * 0.5 + 0.5; \n float sampleDepth = -sample.z/far;\n float depthBufferValue = getDepth(offset.xy);\t\t\t\t \n\n float range_check = abs(linearDepth - depthBufferValue)+radius*0.998;\n if (range_check < radius && depthBufferValue <= sampleDepth)\n {\n occlusion += 1.0;\n }\n \n } \n \n occlusion = 1.0 - (occlusion) / float(kernelSize);\n \n vec3 lightPos = vec3(10.0, 10.0, 10.0);\n vec3 L = normalize(lightPos);\n float NdotL = abs(dot(normal2, L));\n vec3 diffuse = vec3(NdotL);\n vec3 ambient = vec3(1.0);\n vec4 textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, vTexCoord.t));\n\n gl_FragColor.rgb = vec3((textureColor.xyz*0.2 + textureColor.xyz*0.8) * occlusion); // with texture.***\n gl_FragColor.a = 1.0; \n}\n",SsaoVS:"attribute vec3 position;\nattribute vec3 normal;\nattribute vec2 texCoord;\n\nuniform mat4 projectionMatrix; \nuniform mat4 modelViewMatrix;\nuniform mat4 modelViewMatrixRelToEye; \nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform mat4 normalMatrix4;\nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\n\nvarying vec3 vNormal;\nvarying vec2 vTexCoord; \n\nvoid main()\n{\t\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + position.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\n vNormal = (normalMatrix4 * vec4(-normal.x, -normal.y, -normal.z, 1.0)).xyz;\n vTexCoord = texCoord;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n}",StandardFS:"precision lowp float;\nvarying vec3 vColor;\n\nvoid main()\n{\n gl_FragColor = vec4(vColor, 1.);\n}",StandardVS:"attribute vec3 position;\nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nuniform mat4 RefTransfMatrix;\nattribute vec3 color;\nvarying vec3 vColor;\n\nvoid main()\n{\n vec4 rotatedPos = RefTransfMatrix * vec4(position.xyz, 1.0);\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n \n vColor=color;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos;\n}",TextureA1FS:"precision mediump float;\nvarying vec4 vColor;\nvarying vec2 vTextureCoord;\nuniform sampler2D uSampler;\n\nvoid main()\n{\n gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n}\n",TextureA1VS:"attribute vec3 position;\nattribute vec4 aVertexColor;\nattribute vec2 aTextureCoord;\nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nvarying vec4 vColor;\nvarying vec2 vTextureCoord;\n\nvoid main()\n{\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + position.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n \n vColor=aVertexColor;\n vTextureCoord = aTextureCoord;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos;\n}",TextureFS:"precision mediump float;\nvarying vec4 vColor;\nvarying vec2 vTextureCoord;\nuniform sampler2D uSampler;\n\nvoid main()\n{\n gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n}",TextureNormalFS:"\tprecision mediump float;\n\tvarying vec4 vColor;\n\tvarying vec2 vTextureCoord;\n\tuniform sampler2D uSampler;\n\tvarying vec3 vLightWeighting;\n\n\tvoid main()\n {\n\t\tvec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n \n\t\tgl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a);\n\t}\n",TextureNormalVS:"attribute vec3 position;\nattribute vec4 aVertexColor;\nattribute vec2 aTextureCoord;\nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nvarying vec4 vColor;\nvarying vec2 vTextureCoord;\nattribute vec3 aVertexNormal;\nvarying vec3 uAmbientColor;\nvarying vec3 vLightWeighting;\nuniform mat3 uNMatrix;\n\nvoid main()\n{\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + position.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n \n vColor = aVertexColor;\n vTextureCoord = aTextureCoord;\n \n vLightWeighting = vec3(1.0, 1.0, 1.0);\n uAmbientColor = vec3(0.7, 0.7, 0.7);\n vec3 uLightingDirection = vec3(0.8, 0.2, -0.9);\n vec3 directionalLightColor = vec3(0.4, 0.4, 0.4);\n vec3 transformedNormal = uNMatrix * aVertexNormal;\n float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);\n vLightWeighting = uAmbientColor + directionalLightColor * directionalLightWeighting;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos;\n}\n",TextureVS:"attribute vec3 position;\nattribute vec4 aVertexColor;\nattribute vec2 aTextureCoord;\nuniform mat4 Mmatrix;\nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nvarying vec4 vColor;\nvarying vec2 vTextureCoord;\n\nvoid main()\n{\n vec4 rotatedPos = Mmatrix * vec4(position.xyz, 1.0);\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\n vColor=aVertexColor;\n vTextureCoord = aTextureCoord;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos;\n \n}",TinTerrainFS:"#ifdef GL_ES\n precision highp float;\n#endif\n\nuniform sampler2D depthTex;\nuniform sampler2D noiseTex; \nuniform sampler2D diffuseTex;\nuniform bool hasTexture;\nuniform bool textureFlipYAxis;\nuniform bool bIsMakingDepth;\nvarying vec3 vNormal;\nuniform mat4 projectionMatrix;\nuniform mat4 m;\nuniform vec2 noiseScale;\nuniform float near;\nuniform float far; \nuniform float fov;\nuniform float aspectRatio; \nuniform float screenWidth; \nuniform float screenHeight; \nuniform float shininessValue;\nuniform vec3 kernel[16]; \nuniform vec4 vColor4Aux;\n\nvarying vec2 vTexCoord; \nvarying vec3 vLightWeighting;\n\nvarying vec3 diffuseColor;\nuniform vec3 specularColor;\nvarying vec3 vertexPos;\nvarying float depthValue;\n\nconst int kernelSize = 16; \nuniform float radius; \n\nuniform float ambientReflectionCoef;\nuniform float diffuseReflectionCoef; \nuniform float specularReflectionCoef; \n\nfloat unpackDepth(const in vec4 rgba_depth)\n{\n const vec4 bit_shift = vec4(0.000000059605, 0.000015258789, 0.00390625, 1.0);\n float depth = dot(rgba_depth, bit_shift);\n return depth;\n} \n\nvec4 packDepth(const in float depth)\n{\n const vec4 bit_shift = vec4(16777216.0, 65536.0, 256.0, 1.0);\n const vec4 bit_mask = vec4(0.0, 0.00390625, 0.00390625, 0.00390625); \n vec4 res = fract(depth * bit_shift);\n res -= res.xxyz * bit_mask;\n return res; \n} \n\nvec3 getViewRay(vec2 tc)\n{\n float hfar = 2.0 * tan(fov/2.0) * far;\n float wfar = hfar * aspectRatio; \n vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n return ray; \n} \n \n//linear view space depth\nfloat getDepth(vec2 coord)\n{\n return unpackDepth(texture2D(depthTex, coord.xy));\n} \n\nvoid main()\n{ \n\tif(bIsMakingDepth)\n\t{\n\t\tgl_FragColor = packDepth(-depthValue);\n\t}\n\telse{\n\t\tvec4 textureColor;\n\t\tif(hasTexture)\n\t\t{\n\t\t\tif(textureFlipYAxis)\n\t\t\t{\n\t\t\t\ttextureColor = texture2D(diffuseTex, vec2(vTexCoord.s, 1.0 - vTexCoord.t));\n\t\t\t}\n\t\t\telse{\n\t\t\t\ttextureColor = texture2D(diffuseTex, vec2(vTexCoord.s, vTexCoord.t));\n\t\t\t}\n\t\t\t\n\t\t\tif(textureColor.w == 0.0)\n\t\t\t{\n\t\t\t\tdiscard;\n\t\t\t}\n\t\t}\n\t\telse{\n\t\t\ttextureColor = vColor4Aux;\n\t\t}\n\t\t//vec3 ambientColor = vec3(textureColor.x, textureColor.y, textureColor.z);\n\t\tgl_FragColor = vec4(textureColor.xyz, 1.0); \n\t}\n}",TinTerrainVS:"attribute vec3 position;\nattribute vec3 normal;\nattribute vec4 color4;\nattribute vec2 texCoord;\n\nuniform sampler2D diffuseTex;\nuniform mat4 projectionMatrix; \nuniform mat4 modelViewMatrix;\nuniform mat4 modelViewMatrixRelToEye; \nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform mat4 ModelViewProjectionMatrix;\nuniform mat4 normalMatrix4;\nuniform mat4 buildingRotMatrix; \nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nuniform vec3 aditionalPosition;\nuniform vec4 oneColor4;\nuniform bool bUse1Color;\nuniform bool hasTexture;\nuniform bool bIsMakingDepth;\nuniform float near;\nuniform float far;\n\nvarying vec3 vNormal;\nvarying vec2 vTexCoord; \nvarying vec3 uAmbientColor;\nvarying vec3 vLightWeighting;\nvarying vec4 vcolor4;\nvarying vec3 vertexPos;\nvarying float depthValue;\n\nvoid main()\n{\t\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + position.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\n\tif(bIsMakingDepth)\n\t{\n\t\tdepthValue = (modelViewMatrixRelToEye * pos4).z/far;\n\t}\n\telse\n\t{\n\t\tvTexCoord = texCoord;\n\t}\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\t\n}"},MAGO3DJS_MESSAGE=new Object,Renderer=function(){if(!(this instanceof Renderer))throw new Error(Messages.CONSTRUCT_ERROR);this.renderNormals=!0,this.renderTexture=!0,this.vbo_vi_cacheKey_aux,this.byteColorAux=new ByteColor,this.currentTimeSC,this.dateSC,this.startTimeSC,this.simpObj_scratch};Renderer.prototype.renderRenderables=function(e,t,i,o,r,n,a,s){for(var l=t.length,c=0;c0),i.magoPolicy.getObjectMoveMode()===CODE.moveMode.ALL&&i.buildingSelected===h&&this.enableStencilBuffer(e)),f=0,d=h.currentVisibleOctreesControler.currentVisibles0.length;for(var x=0;xthis.vbo_vi_cacheKey_aux.indicesCount&&(b=this.vbo_vi_cacheKey_aux.indicesCount):o.thereAreUrgentOctrees?(b=this.vbo_vi_cacheKey_aux.bigTrianglesIndicesCount)>this.vbo_vi_cacheKey_aux.indicesCount&&(b=this.vbo_vi_cacheKey_aux.indicesCount):b=this.vbo_vi_cacheKey_aux.indicesCount,e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.vbo_vi_cacheKey_aux.meshFacesCacheKey),e.drawElements(e.TRIANGLES,b,e.UNSIGNED_SHORT,0)}y.swapRenderingFase(),o.magoPolicy.getObjectMoveMode()===CODE.moveMode.OBJECT&&o.objectSelected===y&&(this.disableStencilBuffer(e),e.disable(e.POLYGON_OFFSET_FILL))}}}else this.depthRenderNeoRefListsAsimetricVersion(e,t,i,o,r,n,a,s,l,c,h)},Renderer.prototype.depthRenderNeoRefListsAsimetricVersion=function(e,t,i,o,r,n,a,s,l,c,h){if(this.isReadyNeoRefList(t))for(var d,u,f,g=t.currentVisibleIndices.length,p=0;pthis.vbo_vi_cacheKey_aux.indicesCount&&(v=this.vbo_vi_cacheKey_aux.indicesCount):v=this.vbo_vi_cacheKey_aux.indicesCount,e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this.vbo_vi_cacheKey_aux.meshFacesCacheKey),e.drawElements(e.TRIANGLES,v,e.UNSIGNED_SHORT,0)}m.swapRenderingFase()}}},Renderer.prototype.renderNeoRefListsAsimetricVersionColorSelection=function(e,t,i,o,r,n,a,s,l){var c=i.data.neoBuilding,h=t.neoReferencesMotherAndIndices;if(this.isReadyNeoRefList(h))for(var d,u=h.currentVisibleIndices.length,f=o.selectionCandidates,g=0;g0){if(!h.isReadyFaces(e,i.vboMemoryManager))return;e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,h.meshFacesCacheKey),e.drawElements(e.TRIANGLES,h.indicesCount,e.UNSIGNED_SHORT,0)}else e.drawArrays(e.TRIANGLES,0,d);else e.drawArrays(e.LINE_STRIP,0,d)}}};var SceneState=function(){if(!(this instanceof SceneState))throw new Error(Messages.CONSTRUCT_ERROR);this.gl,this.modelViewProjRelToEyeMatrix=new Matrix4,this.modelViewRelToEyeMatrix=new Matrix4,this.modelViewRelToEyeMatrixInv=new Matrix4,this.modelViewMatrix=new Matrix4,this.modelViewMatrixInv=new Matrix4,this.projectionMatrix=new Matrix4,this.modelViewProjMatrix=new Matrix4,this.normalMatrix4=new Matrix4,this.identityMatrix4=new Matrix4,this.encodedCamPosHigh=new Float32Array([0,0,0]),this.encodedCamPosLow=new Float32Array([0,0,0]),this.camera=new Camera,this.drawingBufferWidth=new Int32Array([1e3]),this.drawingBufferHeight=new Int32Array([1e3]),this.mouseAction=new MouseAction,this.ambientReflectionCoef=.45,this.diffuseReflectionCoef=.75,this.specularReflectionCoef=.6,this.specularColor=new Float32Array([.7,.7,.7]),this.ssaoRadius=.15,this.shininessValue=40,this.ssaoNoiseScale2=new Float32Array([1,1]),this.ssaoKernel16=[.33,0,.85,.25,.3,.5,.1,.3,.85,-.15,.2,.85,-.33,.05,.6,-.1,-.15,.85,-.05,-.32,.25,.2,-.15,.85,.6,0,.55,.5,.6,.45,-.01,.7,.35,-.33,.5,.45,-.45,0,.55,-.65,-.5,.7,0,-.5,.55,.33,.3,.35],this.ssaoSphereKernel32=[.33,0,.85,.25,.3,.5,.1,.3,.85,-.15,.2,.85,-.33,.05,.6,-.1,-.15,.85,-.05,-.32,.25,.2,-.15,.85,.6,0,.55,.5,.6,.45,-.01,.7,.35,-.33,.5,.45,-.45,0,.55,-.65,-.5,.7,0,-.5,.55,.33,.3,.35,.33,0,-.85,.25,.3,-.5,.1,.3,-.85,-.15,.2,-.85,-.33,.05,-.6,-.1,-.15,-.85,-.05,-.32,-.25,.2,-.15,-.85,.6,0,-.55,.5,.6,-.45,-.01,.7,-.35,-.33,.5,-.45,-.45,0,-.55,-.65,-.5,-.7,0,-.5,-.55,.33,.3,-.35],this.bMust=!1,this.dc,this.insertIssueState=0,this.textureFlipYAxis=!1,this.mouseButton=-1},Selection=function(){if(!(this instanceof Selection))throw new Error(Messages.CONSTRUCT_ERROR);this.drawing_height,this.drawing_width,this.GAIA_selectFrameBuffer,this.GAIA_selectRenderBuffer,this.GAIA_selectRttTexture,this.currentByteColorPicked=new Uint8Array(4),this.currentSelectedObj_idx=-1};Selection.prototype.init=function(e,t,i){this.drawing_height=i,this.drawing_width=t,this.GAIA_selectFrameBuffer=e.createFramebuffer(),e.bindFramebuffer(e.FRAMEBUFFER,this.GAIA_selectFrameBuffer),this.GAIA_selectRenderBuffer=e.createRenderbuffer(),e.bindRenderbuffer(e.RENDERBUFFER,this.GAIA_selectRenderBuffer),e.renderbufferStorage(e.RENDERBUFFER,e.DEPTH_COMPONENT16,this.drawing_width,this.drawing_height),this.GAIA_selectRttTexture=e.createTexture(),e.bindTexture(e.TEXTURE_2D,this.GAIA_selectRttTexture),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.NEAREST),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,this.drawing_width,this.drawing_height,0,e.RGBA,e.UNSIGNED_BYTE,null),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.GAIA_selectRttTexture,0),e.framebufferRenderbuffer(e.FRAMEBUFFER,e.DEPTH_ATTACHMENT,e.RENDERBUFFER,this.GAIA_selectRenderBuffer),e.bindTexture(e.TEXTURE_2D,null),e.bindRenderbuffer(e.RENDERBUFFER,null),e.bindFramebuffer(e.FRAMEBUFFER,null)};var SelectionCandidates=function(){if(!(this instanceof SelectionCandidates))throw new Error(Messages.CONSTRUCT_ERROR);this.referencesMap={},this.octreesMap={},this.buildingsMap={},this.nodesMap={},this.currentReferenceSelected,this.currentOctreeSelected,this.currentBuildingSelected,this.currentNodeSelected};function defaultValue(e,t){return void 0!==e?e:t}SelectionCandidates.prototype.setCandidates=function(e,t,i,o,r){t&&(this.referencesMap[e]=t),i&&(this.octreesMap[e]=i),o&&(this.buildingsMap[e]=o),r&&(this.nodesMap[e]=r)},SelectionCandidates.prototype.clearCandidates=function(){this.referencesMap={},this.octreesMap={},this.buildingsMap={},this.nodesMap={}},SelectionCandidates.prototype.selectObjects=function(e){this.currentReferenceSelected=this.referencesMap[e],this.currentOctreeSelected=this.octreesMap[e],this.currentBuildingSelected=this.buildingsMap[e],this.currentNodeSelected=this.nodesMap[e]},SelectionCandidates.prototype.clearCurrents=function(e){this.currentReferenceSelected=void 0,this.currentOctreeSelected=void 0,this.currentBuildingSelected=void 0,this.currentNodeSelected=void 0};var ByteColor=function(){if(!(this instanceof ByteColor))throw new Error(Messages.CONSTRUCT_ERROR);this.ByteR=0,this.ByteG=0,this.ByteB=0,this.ByteAlfa=255};ByteColor.prototype.destroy=function(){this.ByteR=null,this.ByteG=null,this.ByteB=null,this.ByteAlfa=null},ByteColor.prototype.set=function(e,t,i){this.ByteR=e,this.ByteG=t,this.ByteB=i};var Point3DAux=function(){if(!(this instanceof Point3DAux))throw new Error(Messages.CONSTRUCT_ERROR);this.x=0,this.y=0,this.z=0},TTriangle=function(){if(!(this instanceof TTriangle))throw new Error(Messages.CONSTRUCT_ERROR);this.mVertex1,this.mVertex2,this.mVertex3};TTriangle.prototype.setVertices=function(e,t,i){this.mVertex1=e,this.mVertex2=t,this.mVertex3=i},TTriangle.prototype.invert=function(){var e=this.mVertex2;this.mVertex2=this.mVertex3,this.mVertex3=e};var TTrianglesList=function(){if(!(this instanceof TTrianglesList))throw new Error(Messages.CONSTRUCT_ERROR);this.tTrianglesArray=[]};TTrianglesList.prototype.newTTriangle=function(){var e=new TTriangle;return this.tTrianglesArray.push(e),e},TTrianglesList.prototype.invertTrianglesSense=function(){for(var e=0,t=this.tTrianglesArray.length;e=0&&e=0?(i=65536*Math.floor(e/65536),t.high=i,t.low=e-i):(i=65536*Math.floor(-e/65536),t.high=-i,t.low=e+i),t},ManagerUtils.calculateSplited3fv=function(e,t,i){if(void 0!==e){void 0===t&&(t=new Float32Array(3)),void 0===i&&(i=new Float32Array(3));var o=new SplitValue;o=this.calculateSplitedValues(e[0],o);var r=new SplitValue;r=this.calculateSplitedValues(e[1],r);var n=new SplitValue;n=this.calculateSplitedValues(e[2],n),t[0]=o.high,t[1]=r.high,t[2]=n.high,i[0]=o.low,i[1]=r.low,i[2]=n.low}},ManagerUtils.calculateAproxDist2D=function(e,t,i){var o,r,n=Math.abs(e.x-t.x),a=Math.abs(e.y-t.y);return r=n>a?a/(o=n):n/(o=a),o*i[Math.floor(100*r)]};for(var sqrtTable=new Float32Array(11),increValue=.1,i=0;i<11;i++)sqrtTable[i]=Math.sqrt(1+increValue*i*(increValue*i));ManagerUtils.calculateAproxDist3D=function(e,t){var i,o,r,n,a,s,l=Math.abs(e.x-t.x),c=Math.abs(e.y-t.y),h=Math.abs(e.z-t.z);return l>c?l>h?(o=c/(i=l),n=Math.floor(100*o),r=h/(s=i*sqrtTable[n]),a=Math.floor(100*r),s*sqrtTable[a]):(o=l/(i=h),n=Math.floor(100*o),r=c/(s=i*sqrtTable[n]),a=Math.floor(100*r),s*sqrtTable[a]):c>h?(o=l/(i=c),n=Math.floor(100*o),r=h/(s=i*sqrtTable[n]),a=Math.floor(100*r),s*sqrtTable[a]):(o=l/(i=h),n=Math.floor(100*o),r=c/(s=i*sqrtTable[n]),a=Math.floor(100*r),s*sqrtTable[a])},function(){var e=window.URL||window.webkitURL;if(!e)throw new Error("This browser does not support Blob URLs");if(!window.Worker)throw new Error("This browser does not support Web Workers");function t(e){this.threads=Math.max(2,0|e),this._queue=[],this._queueSize=0,this._activeThreads=0,this._debug={start:0,end:0,time:0}}t.prototype._worker={JSON:function(){var e=func;self.addEventListener("message",function(t){for(var i=t.data,o=new DataView(i),r=i.byteLength,n=Array(r),a=0;athis._byteLength&&(this._byteLength=e);else{for(i<1&&(i=1);e>i;)i*=2;var r=new ArrayBuffer(i),o=new Uint8Array(this._buffer);new Uint8Array(r,0,o.length).set(o),this.buffer=r,this._byteLength=e}}},DataStream.prototype._trimAlloc=function(){if(this._byteLength!=this._buffer.byteLength){var t=new ArrayBuffer(this._byteLength),e=new Uint8Array(t),i=new Uint8Array(this._buffer,0,e.length);e.set(i),this.buffer=t}},DataStream.prototype.seek=function(t){var e=Math.max(0,Math.min(this.byteLength,t));this.position=isNaN(e)||!isFinite(e)?0:e},DataStream.prototype.isEof=function(){return this.position>=this.byteLength},DataStream.prototype.mapInt32Array=function(t,e){this._realloc(4*t);var i=new Int32Array(this._buffer,this.byteOffset+this.position,t);return DataStream.arrayToNative(i,null==e?this.endianness:e),this.position+=4*t,i},DataStream.prototype.mapInt16Array=function(t,e){this._realloc(2*t);var i=new Int16Array(this._buffer,this.byteOffset+this.position,t);return DataStream.arrayToNative(i,null==e?this.endianness:e),this.position+=2*t,i},DataStream.prototype.mapInt8Array=function(t){this._realloc(1*t);var e=new Int8Array(this._buffer,this.byteOffset+this.position,t);return this.position+=1*t,e},DataStream.prototype.mapUint32Array=function(t,e){this._realloc(4*t);var i=new Uint32Array(this._buffer,this.byteOffset+this.position,t);return DataStream.arrayToNative(i,null==e?this.endianness:e),this.position+=4*t,i},DataStream.prototype.mapUint16Array=function(t,e){this._realloc(2*t);var i=new Uint16Array(this._buffer,this.byteOffset+this.position,t);return DataStream.arrayToNative(i,null==e?this.endianness:e),this.position+=2*t,i},DataStream.prototype.mapUint8Array=function(t){this._realloc(1*t);var e=new Uint8Array(this._buffer,this.byteOffset+this.position,t);return this.position+=1*t,e},DataStream.prototype.mapFloat64Array=function(t,e){this._realloc(8*t);var i=new Float64Array(this._buffer,this.byteOffset+this.position,t);return DataStream.arrayToNative(i,null==e?this.endianness:e),this.position+=8*t,i},DataStream.prototype.mapFloat32Array=function(t,e){this._realloc(4*t);var i=new Float32Array(this._buffer,this.byteOffset+this.position,t);return DataStream.arrayToNative(i,null==e?this.endianness:e),this.position+=4*t,i},DataStream.prototype.readInt32Array=function(t,e){t=null==t?this.byteLength-this.position/4:t;var i=new Int32Array(t);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,t*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,null==e?this.endianness:e),this.position+=i.byteLength,i},DataStream.prototype.readInt16Array=function(t,e){t=null==t?this.byteLength-this.position/2:t;var i=new Int16Array(t);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,t*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,null==e?this.endianness:e),this.position+=i.byteLength,i},DataStream.prototype.readInt8Array=function(t){t=null==t?this.byteLength-this.position:t;var e=new Int8Array(t);return DataStream.memcpy(e.buffer,0,this.buffer,this.byteOffset+this.position,t*e.BYTES_PER_ELEMENT),this.position+=e.byteLength,e},DataStream.prototype.readUint32Array=function(t,e){t=null==t?this.byteLength-this.position/4:t;var i=new Uint32Array(t);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,t*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,null==e?this.endianness:e),this.position+=i.byteLength,i},DataStream.prototype.readUint16Array=function(t,e){t=null==t?this.byteLength-this.position/2:t;var i=new Uint16Array(t);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,t*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,null==e?this.endianness:e),this.position+=i.byteLength,i},DataStream.prototype.readUint8Array=function(t){t=null==t?this.byteLength-this.position:t;var e=new Uint8Array(t);return DataStream.memcpy(e.buffer,0,this.buffer,this.byteOffset+this.position,t*e.BYTES_PER_ELEMENT),this.position+=e.byteLength,e},DataStream.prototype.readFloat64Array=function(t,e){t=null==t?this.byteLength-this.position/8:t;var i=new Float64Array(t);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,t*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,null==e?this.endianness:e),this.position+=i.byteLength,i},DataStream.prototype.readFloat32Array=function(t,e){t=null==t?this.byteLength-this.position/4:t;var i=new Float32Array(t);return DataStream.memcpy(i.buffer,0,this.buffer,this.byteOffset+this.position,t*i.BYTES_PER_ELEMENT),DataStream.arrayToNative(i,null==e?this.endianness:e),this.position+=i.byteLength,i},DataStream.prototype.writeInt32Array=function(t,e){if(this._realloc(4*t.length),t instanceof Int32Array&&(this.byteOffset+this.position)%t.BYTES_PER_ELEMENT==0)DataStream.memcpy(this._buffer,this.byteOffset+this.position,t.buffer,t.byteOffset,t.byteLength),this.mapInt32Array(t.length,e);else for(var i=0;i0,DataStream.memcpy=function(t,e,i,r,o){var n=new Uint8Array(t,e,o),a=new Uint8Array(i,r,o);n.set(a)},DataStream.arrayToNative=function(t,e){return e==this.endianness?t:this.flipArrayEndianness(t)},DataStream.nativeToEndian=function(t,e){return this.endianness==e?t:this.flipArrayEndianness(t)},DataStream.flipArrayEndianness=function(t){for(var e=new Uint8Array(t.buffer,t.byteOffset,t.byteLength),i=0;io;r--,o++){var n=e[o];e[o]=e[r],e[r]=n}return t},DataStream.createStringFromArray=function(t){for(var e=[],i=0;i0?(r=2*Math.sqrt(i+1),t[3]=.25*r,t[0]=(e[6]-e[9])/r,t[1]=(e[8]-e[2])/r,t[2]=(e[1]-e[4])/r):e[0]>e[5]&&e[0]>e[10]?(r=2*Math.sqrt(1+e[0]-e[5]-e[10]),t[3]=(e[6]-e[9])/r,t[0]=.25*r,t[1]=(e[1]+e[4])/r,t[2]=(e[8]+e[2])/r):e[5]>e[10]?(r=2*Math.sqrt(1+e[5]-e[0]-e[10]),t[3]=(e[8]-e[2])/r,t[0]=(e[1]+e[4])/r,t[1]=.25*r,t[2]=(e[6]+e[9])/r):(r=2*Math.sqrt(1+e[10]-e[0]-e[5]),t[3]=(e[1]-e[4])/r,t[0]=(e[8]+e[2])/r,t[1]=(e[6]+e[9])/r,t[2]=.25*r),t}function _(t,e,i){return t[0]=e[0]-i[0],t[1]=e[1]-i[1],t[2]=e[2]-i[2],t[3]=e[3]-i[3],t[4]=e[4]-i[4],t[5]=e[5]-i[5],t[6]=e[6]-i[6],t[7]=e[7]-i[7],t[8]=e[8]-i[8],t[9]=e[9]-i[9],t[10]=e[10]-i[10],t[11]=e[11]-i[11],t[12]=e[12]-i[12],t[13]=e[13]-i[13],t[14]=e[14]-i[14],t[15]=e[15]-i[15],t}var S=M,R=_,L=Object.freeze({create:function(){var t=new i(16);return i!=Float32Array&&(t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[11]=0,t[12]=0,t[13]=0,t[14]=0),t[0]=1,t[5]=1,t[10]=1,t[15]=1,t},clone:function(t){var e=new i(16);return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e},copy:function(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t},fromValues:function(t,e,r,o,n,a,s,l,d,h,c,u,f,g,p,v){var y=new i(16);return y[0]=t,y[1]=e,y[2]=r,y[3]=o,y[4]=n,y[5]=a,y[6]=s,y[7]=l,y[8]=d,y[9]=h,y[10]=c,y[11]=u,y[12]=f,y[13]=g,y[14]=p,y[15]=v,y},set:function(t,e,i,r,o,n,a,s,l,d,h,c,u,f,g,p,v){return t[0]=e,t[1]=i,t[2]=r,t[3]=o,t[4]=n,t[5]=a,t[6]=s,t[7]=l,t[8]=d,t[9]=h,t[10]=c,t[11]=u,t[12]=f,t[13]=g,t[14]=p,t[15]=v,t},identity:A,transpose:function(t,e){if(t===e){var i=e[1],r=e[2],o=e[3],n=e[6],a=e[7],s=e[11];t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=i,t[6]=e[9],t[7]=e[13],t[8]=r,t[9]=n,t[11]=e[14],t[12]=o,t[13]=a,t[14]=s}else t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=e[12],t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=e[13],t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=e[14],t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=e[15];return t},invert:function(t,e){var i=e[0],r=e[1],o=e[2],n=e[3],a=e[4],s=e[5],l=e[6],d=e[7],h=e[8],c=e[9],u=e[10],f=e[11],g=e[12],p=e[13],v=e[14],y=e[15],m=i*s-r*a,x=i*l-o*a,b=i*d-n*a,C=r*l-o*s,A=r*d-n*s,M=o*d-n*l,P=h*p-c*g,T=h*v-u*g,w=h*y-f*g,_=c*v-u*p,S=c*y-f*p,R=u*y-f*v,L=m*R-x*S+b*_+C*w-A*T+M*P;return L?(L=1/L,t[0]=(s*R-l*S+d*_)*L,t[1]=(o*S-r*R-n*_)*L,t[2]=(p*M-v*A+y*C)*L,t[3]=(u*A-c*M-f*C)*L,t[4]=(l*w-a*R-d*T)*L,t[5]=(i*R-o*w+n*T)*L,t[6]=(v*b-g*M-y*x)*L,t[7]=(h*M-u*b+f*x)*L,t[8]=(a*S-s*w+d*P)*L,t[9]=(r*w-i*S-n*P)*L,t[10]=(g*A-p*b+y*m)*L,t[11]=(c*b-h*A-f*m)*L,t[12]=(s*T-a*_-l*P)*L,t[13]=(i*_-r*T+o*P)*L,t[14]=(p*x-g*C-v*m)*L,t[15]=(h*C-c*x+u*m)*L,t):null},adjoint:function(t,e){var i=e[0],r=e[1],o=e[2],n=e[3],a=e[4],s=e[5],l=e[6],d=e[7],h=e[8],c=e[9],u=e[10],f=e[11],g=e[12],p=e[13],v=e[14],y=e[15];return t[0]=s*(u*y-f*v)-c*(l*y-d*v)+p*(l*f-d*u),t[1]=-(r*(u*y-f*v)-c*(o*y-n*v)+p*(o*f-n*u)),t[2]=r*(l*y-d*v)-s*(o*y-n*v)+p*(o*d-n*l),t[3]=-(r*(l*f-d*u)-s*(o*f-n*u)+c*(o*d-n*l)),t[4]=-(a*(u*y-f*v)-h*(l*y-d*v)+g*(l*f-d*u)),t[5]=i*(u*y-f*v)-h*(o*y-n*v)+g*(o*f-n*u),t[6]=-(i*(l*y-d*v)-a*(o*y-n*v)+g*(o*d-n*l)),t[7]=i*(l*f-d*u)-a*(o*f-n*u)+h*(o*d-n*l),t[8]=a*(c*y-f*p)-h*(s*y-d*p)+g*(s*f-d*c),t[9]=-(i*(c*y-f*p)-h*(r*y-n*p)+g*(r*f-n*c)),t[10]=i*(s*y-d*p)-a*(r*y-n*p)+g*(r*d-n*s),t[11]=-(i*(s*f-d*c)-a*(r*f-n*c)+h*(r*d-n*s)),t[12]=-(a*(c*v-u*p)-h*(s*v-l*p)+g*(s*u-l*c)),t[13]=i*(c*v-u*p)-h*(r*v-o*p)+g*(r*u-o*c),t[14]=-(i*(s*v-l*p)-a*(r*v-o*p)+g*(r*l-o*s)),t[15]=i*(s*u-l*c)-a*(r*u-o*c)+h*(r*l-o*s),t},determinant:function(t){var e=t[0],i=t[1],r=t[2],o=t[3],n=t[4],a=t[5],s=t[6],l=t[7],d=t[8],h=t[9],c=t[10],u=t[11],f=t[12],g=t[13],p=t[14],v=t[15];return(e*a-i*n)*(c*v-u*p)-(e*s-r*n)*(h*v-u*g)+(e*l-o*n)*(h*p-c*g)+(i*s-r*a)*(d*v-u*f)-(i*l-o*a)*(d*p-c*f)+(r*l-o*s)*(d*g-h*f)},multiply:M,translate:function(t,e,i){var r,o,n,a,s,l,d,h,c,u,f,g,p=i[0],v=i[1],y=i[2];return e===t?(t[12]=e[0]*p+e[4]*v+e[8]*y+e[12],t[13]=e[1]*p+e[5]*v+e[9]*y+e[13],t[14]=e[2]*p+e[6]*v+e[10]*y+e[14],t[15]=e[3]*p+e[7]*v+e[11]*y+e[15]):(r=e[0],o=e[1],n=e[2],a=e[3],s=e[4],l=e[5],d=e[6],h=e[7],c=e[8],u=e[9],f=e[10],g=e[11],t[0]=r,t[1]=o,t[2]=n,t[3]=a,t[4]=s,t[5]=l,t[6]=d,t[7]=h,t[8]=c,t[9]=u,t[10]=f,t[11]=g,t[12]=r*p+s*v+c*y+e[12],t[13]=o*p+l*v+u*y+e[13],t[14]=n*p+d*v+f*y+e[14],t[15]=a*p+h*v+g*y+e[15]),t},scale:function(t,e,i){var r=i[0],o=i[1],n=i[2];return t[0]=e[0]*r,t[1]=e[1]*r,t[2]=e[2]*r,t[3]=e[3]*r,t[4]=e[4]*o,t[5]=e[5]*o,t[6]=e[6]*o,t[7]=e[7]*o,t[8]=e[8]*n,t[9]=e[9]*n,t[10]=e[10]*n,t[11]=e[11]*n,t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t},rotate:function(t,i,r,o){var n,a,s,l,d,h,c,u,f,g,p,v,y,m,x,b,C,A,M,P,T,w,_,S,R=o[0],L=o[1],D=o[2],I=Math.sqrt(R*R+L*L+D*D);return I0?(r[0]=2*(l*s+c*o+d*a-h*n)/u,r[1]=2*(d*s+c*n+h*o-l*a)/u,r[2]=2*(h*s+c*a+l*n-d*o)/u):(r[0]=2*(l*s+c*o+d*a-h*n),r[1]=2*(d*s+c*n+h*o-l*a),r[2]=2*(h*s+c*a+l*n-d*o)),P(t,e,r),t},getTranslation:T,getScaling:function(t,e){var i=e[0],r=e[1],o=e[2],n=e[4],a=e[5],s=e[6],l=e[8],d=e[9],h=e[10];return t[0]=Math.sqrt(i*i+r*r+o*o),t[1]=Math.sqrt(n*n+a*a+s*s),t[2]=Math.sqrt(l*l+d*d+h*h),t},getRotation:w,fromRotationTranslationScale:function(t,e,i,r){var o=e[0],n=e[1],a=e[2],s=e[3],l=o+o,d=n+n,h=a+a,c=o*l,u=o*d,f=o*h,g=n*d,p=n*h,v=a*h,y=s*l,m=s*d,x=s*h,b=r[0],C=r[1],A=r[2];return t[0]=(1-(g+v))*b,t[1]=(u+x)*b,t[2]=(f-m)*b,t[3]=0,t[4]=(u-x)*C,t[5]=(1-(c+v))*C,t[6]=(p+y)*C,t[7]=0,t[8]=(f+m)*A,t[9]=(p-y)*A,t[10]=(1-(c+g))*A,t[11]=0,t[12]=i[0],t[13]=i[1],t[14]=i[2],t[15]=1,t},fromRotationTranslationScaleOrigin:function(t,e,i,r,o){var n=e[0],a=e[1],s=e[2],l=e[3],d=n+n,h=a+a,c=s+s,u=n*d,f=n*h,g=n*c,p=a*h,v=a*c,y=s*c,m=l*d,x=l*h,b=l*c,C=r[0],A=r[1],M=r[2],P=o[0],T=o[1],w=o[2],_=(1-(p+y))*C,S=(f+b)*C,R=(g-x)*C,L=(f-b)*A,D=(1-(u+y))*A,I=(v+m)*A,E=(g+x)*M,O=(v-m)*M,F=(1-(u+p))*M;return t[0]=_,t[1]=S,t[2]=R,t[3]=0,t[4]=L,t[5]=D,t[6]=I,t[7]=0,t[8]=E,t[9]=O,t[10]=F,t[11]=0,t[12]=i[0]+P-(_*P+L*T+E*w),t[13]=i[1]+T-(S*P+D*T+O*w),t[14]=i[2]+w-(R*P+I*T+F*w),t[15]=1,t},fromQuat:function(t,e){var i=e[0],r=e[1],o=e[2],n=e[3],a=i+i,s=r+r,l=o+o,d=i*a,h=r*a,c=r*s,u=o*a,f=o*s,g=o*l,p=n*a,v=n*s,y=n*l;return t[0]=1-c-g,t[1]=h+y,t[2]=u-v,t[3]=0,t[4]=h-y,t[5]=1-d-g,t[6]=f+p,t[7]=0,t[8]=u+v,t[9]=f-p,t[10]=1-d-c,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},frustum:function(t,e,i,r,o,n,a){var s=1/(i-e),l=1/(o-r),d=1/(n-a);return t[0]=2*n*s,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*n*l,t[6]=0,t[7]=0,t[8]=(i+e)*s,t[9]=(o+r)*l,t[10]=(a+n)*d,t[11]=-1,t[12]=0,t[13]=0,t[14]=a*n*2*d,t[15]=0,t},perspective:function(t,e,i,r,o){var n,a=1/Math.tan(e/2);return t[0]=a/i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[11]=-1,t[12]=0,t[13]=0,t[15]=0,null!=o&&o!==1/0?(n=1/(r-o),t[10]=(o+r)*n,t[14]=2*o*r*n):(t[10]=-1,t[14]=-2*r),t},perspectiveFromFieldOfView:function(t,e,i,r){var o=Math.tan(e.upDegrees*Math.PI/180),n=Math.tan(e.downDegrees*Math.PI/180),a=Math.tan(e.leftDegrees*Math.PI/180),s=Math.tan(e.rightDegrees*Math.PI/180),l=2/(a+s),d=2/(o+n);return t[0]=l,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=d,t[6]=0,t[7]=0,t[8]=-(a-s)*l*.5,t[9]=(o-n)*d*.5,t[10]=r/(i-r),t[11]=-1,t[12]=0,t[13]=0,t[14]=r*i/(i-r),t[15]=0,t},ortho:function(t,e,i,r,o,n,a){var s=1/(e-i),l=1/(r-o),d=1/(n-a);return t[0]=-2*s,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*l,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*d,t[11]=0,t[12]=(e+i)*s,t[13]=(o+r)*l,t[14]=(a+n)*d,t[15]=1,t},lookAt:function(t,i,r,o){var n,a,s,l,d,h,c,u,f,g,p=i[0],v=i[1],y=i[2],m=o[0],x=o[1],b=o[2],C=r[0],M=r[1],P=r[2];return Math.abs(p-C)0&&(h*=f=1/Math.sqrt(f),c*=f,u*=f);var g=l*u-d*c,p=d*h-s*u,v=s*c-l*h;return(f=g*g+p*p+v*v)>0&&(g*=f=1/Math.sqrt(f),p*=f,v*=f),t[0]=g,t[1]=p,t[2]=v,t[3]=0,t[4]=c*v-u*p,t[5]=u*g-h*v,t[6]=h*p-c*g,t[7]=0,t[8]=h,t[9]=c,t[10]=u,t[11]=0,t[12]=o,t[13]=n,t[14]=a,t[15]=1,t},str:function(t){return"mat4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+")"},frob:function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2)+Math.pow(t[9],2)+Math.pow(t[10],2)+Math.pow(t[11],2)+Math.pow(t[12],2)+Math.pow(t[13],2)+Math.pow(t[14],2)+Math.pow(t[15],2))},add:function(t,e,i){return t[0]=e[0]+i[0],t[1]=e[1]+i[1],t[2]=e[2]+i[2],t[3]=e[3]+i[3],t[4]=e[4]+i[4],t[5]=e[5]+i[5],t[6]=e[6]+i[6],t[7]=e[7]+i[7],t[8]=e[8]+i[8],t[9]=e[9]+i[9],t[10]=e[10]+i[10],t[11]=e[11]+i[11],t[12]=e[12]+i[12],t[13]=e[13]+i[13],t[14]=e[14]+i[14],t[15]=e[15]+i[15],t},subtract:_,multiplyScalar:function(t,e,i){return t[0]=e[0]*i,t[1]=e[1]*i,t[2]=e[2]*i,t[3]=e[3]*i,t[4]=e[4]*i,t[5]=e[5]*i,t[6]=e[6]*i,t[7]=e[7]*i,t[8]=e[8]*i,t[9]=e[9]*i,t[10]=e[10]*i,t[11]=e[11]*i,t[12]=e[12]*i,t[13]=e[13]*i,t[14]=e[14]*i,t[15]=e[15]*i,t},multiplyScalarAndAdd:function(t,e,i,r){return t[0]=e[0]+i[0]*r,t[1]=e[1]+i[1]*r,t[2]=e[2]+i[2]*r,t[3]=e[3]+i[3]*r,t[4]=e[4]+i[4]*r,t[5]=e[5]+i[5]*r,t[6]=e[6]+i[6]*r,t[7]=e[7]+i[7]*r,t[8]=e[8]+i[8]*r,t[9]=e[9]+i[9]*r,t[10]=e[10]+i[10]*r,t[11]=e[11]+i[11]*r,t[12]=e[12]+i[12]*r,t[13]=e[13]+i[13]*r,t[14]=e[14]+i[14]*r,t[15]=e[15]+i[15]*r,t},exactEquals:function(t,e){return t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[11]===e[11]&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[15]===e[15]},equals:function(t,i){var r=t[0],o=t[1],n=t[2],a=t[3],s=t[4],l=t[5],d=t[6],h=t[7],c=t[8],u=t[9],f=t[10],g=t[11],p=t[12],v=t[13],y=t[14],m=t[15],x=i[0],b=i[1],C=i[2],A=i[3],M=i[4],P=i[5],T=i[6],w=i[7],_=i[8],S=i[9],R=i[10],L=i[11],D=i[12],I=i[13],E=i[14],O=i[15];return Math.abs(r-x)<=e*Math.max(1,Math.abs(r),Math.abs(x))&&Math.abs(o-b)<=e*Math.max(1,Math.abs(o),Math.abs(b))&&Math.abs(n-C)<=e*Math.max(1,Math.abs(n),Math.abs(C))&&Math.abs(a-A)<=e*Math.max(1,Math.abs(a),Math.abs(A))&&Math.abs(s-M)<=e*Math.max(1,Math.abs(s),Math.abs(M))&&Math.abs(l-P)<=e*Math.max(1,Math.abs(l),Math.abs(P))&&Math.abs(d-T)<=e*Math.max(1,Math.abs(d),Math.abs(T))&&Math.abs(h-w)<=e*Math.max(1,Math.abs(h),Math.abs(w))&&Math.abs(c-_)<=e*Math.max(1,Math.abs(c),Math.abs(_))&&Math.abs(u-S)<=e*Math.max(1,Math.abs(u),Math.abs(S))&&Math.abs(f-R)<=e*Math.max(1,Math.abs(f),Math.abs(R))&&Math.abs(g-L)<=e*Math.max(1,Math.abs(g),Math.abs(L))&&Math.abs(p-D)<=e*Math.max(1,Math.abs(p),Math.abs(D))&&Math.abs(v-I)<=e*Math.max(1,Math.abs(v),Math.abs(I))&&Math.abs(y-E)<=e*Math.max(1,Math.abs(y),Math.abs(E))&&Math.abs(m-O)<=e*Math.max(1,Math.abs(m),Math.abs(O))},mul:S,sub:R});function D(){var t=new i(3);return i!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t}function I(t){var e=t[0],i=t[1],r=t[2];return Math.sqrt(e*e+i*i+r*r)}function E(t,e,r){var o=new i(3);return o[0]=t,o[1]=e,o[2]=r,o}function O(t,e,i){return t[0]=e[0]-i[0],t[1]=e[1]-i[1],t[2]=e[2]-i[2],t}function F(t,e,i){return t[0]=e[0]*i[0],t[1]=e[1]*i[1],t[2]=e[2]*i[2],t}function V(t,e,i){return t[0]=e[0]/i[0],t[1]=e[1]/i[1],t[2]=e[2]/i[2],t}function N(t,e){var i=e[0]-t[0],r=e[1]-t[1],o=e[2]-t[2];return Math.sqrt(i*i+r*r+o*o)}function B(t,e){var i=e[0]-t[0],r=e[1]-t[1],o=e[2]-t[2];return i*i+r*r+o*o}function j(t){var e=t[0],i=t[1],r=t[2];return e*e+i*i+r*r}function U(t,e){var i=e[0],r=e[1],o=e[2],n=i*i+r*r+o*o;return n>0&&(n=1/Math.sqrt(n)),t[0]=e[0]*n,t[1]=e[1]*n,t[2]=e[2]*n,t}function G(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function k(t,e,i){var r=e[0],o=e[1],n=e[2],a=i[0],s=i[1],l=i[2];return t[0]=o*l-n*s,t[1]=n*a-r*l,t[2]=r*s-o*a,t}var z,H=O,W=F,X=V,K=N,Y=B,q=I,Z=j,Q=(z=D(),function(t,e,i,r,o,n){var a,s;for(e||(e=3),i||(i=0),s=r?Math.min(r*e+i,t.length):t.length,a=i;a1?0:o<-1?Math.PI:Math.acos(o)},zero:function(t){return t[0]=0,t[1]=0,t[2]=0,t},str:function(t){return"vec3("+t[0]+", "+t[1]+", "+t[2]+")"},exactEquals:function(t,e){return t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]},equals:function(t,i){var r=t[0],o=t[1],n=t[2],a=i[0],s=i[1],l=i[2];return Math.abs(r-a)<=e*Math.max(1,Math.abs(r),Math.abs(a))&&Math.abs(o-s)<=e*Math.max(1,Math.abs(o),Math.abs(s))&&Math.abs(n-l)<=e*Math.max(1,Math.abs(n),Math.abs(l))},sub:H,mul:W,div:X,dist:K,sqrDist:Y,len:q,sqrLen:Z,forEach:Q});function $(){var t=new i(4);return i!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0,t[3]=0),t}function tt(t){var e=new i(4);return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e}function et(t,e,r,o){var n=new i(4);return n[0]=t,n[1]=e,n[2]=r,n[3]=o,n}function it(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t}function rt(t,e,i,r,o){return t[0]=e,t[1]=i,t[2]=r,t[3]=o,t}function ot(t,e,i){return t[0]=e[0]+i[0],t[1]=e[1]+i[1],t[2]=e[2]+i[2],t[3]=e[3]+i[3],t}function nt(t,e,i){return t[0]=e[0]-i[0],t[1]=e[1]-i[1],t[2]=e[2]-i[2],t[3]=e[3]-i[3],t}function at(t,e,i){return t[0]=e[0]*i[0],t[1]=e[1]*i[1],t[2]=e[2]*i[2],t[3]=e[3]*i[3],t}function st(t,e,i){return t[0]=e[0]/i[0],t[1]=e[1]/i[1],t[2]=e[2]/i[2],t[3]=e[3]/i[3],t}function lt(t,e,i){return t[0]=e[0]*i,t[1]=e[1]*i,t[2]=e[2]*i,t[3]=e[3]*i,t}function dt(t,e){var i=e[0]-t[0],r=e[1]-t[1],o=e[2]-t[2],n=e[3]-t[3];return Math.sqrt(i*i+r*r+o*o+n*n)}function ht(t,e){var i=e[0]-t[0],r=e[1]-t[1],o=e[2]-t[2],n=e[3]-t[3];return i*i+r*r+o*o+n*n}function ct(t){var e=t[0],i=t[1],r=t[2],o=t[3];return Math.sqrt(e*e+i*i+r*r+o*o)}function ut(t){var e=t[0],i=t[1],r=t[2],o=t[3];return e*e+i*i+r*r+o*o}function ft(t,e){var i=e[0],r=e[1],o=e[2],n=e[3],a=i*i+r*r+o*o+n*n;return a>0&&(a=1/Math.sqrt(a)),t[0]=i*a,t[1]=r*a,t[2]=o*a,t[3]=n*a,t}function gt(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]+t[3]*e[3]}function pt(t,e,i,r){var o=e[0],n=e[1],a=e[2],s=e[3];return t[0]=o+r*(i[0]-o),t[1]=n+r*(i[1]-n),t[2]=a+r*(i[2]-a),t[3]=s+r*(i[3]-s),t}function vt(t,e){return t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]}function yt(t,i){var r=t[0],o=t[1],n=t[2],a=t[3],s=i[0],l=i[1],d=i[2],h=i[3];return Math.abs(r-s)<=e*Math.max(1,Math.abs(r),Math.abs(s))&&Math.abs(o-l)<=e*Math.max(1,Math.abs(o),Math.abs(l))&&Math.abs(n-d)<=e*Math.max(1,Math.abs(n),Math.abs(d))&&Math.abs(a-h)<=e*Math.max(1,Math.abs(a),Math.abs(h))}var mt=nt,xt=at,bt=st,Ct=dt,At=ht,Mt=ct,Pt=ut,Tt=function(){var t=$();return function(e,i,r,o,n,a){var s,l;for(i||(i=4),r||(r=0),l=o?Math.min(o*i+r,e.length):e.length,s=r;s=1);do{l=(n=2*r()-1)*n+(a=2*r()-1)*a}while(l>=1);var d=Math.sqrt((1-s)/l);return t[0]=e*i,t[1]=e*o,t[2]=e*n*d,t[3]=e*a*d,t},transformMat4:function(t,e,i){var r=e[0],o=e[1],n=e[2],a=e[3];return t[0]=i[0]*r+i[4]*o+i[8]*n+i[12]*a,t[1]=i[1]*r+i[5]*o+i[9]*n+i[13]*a,t[2]=i[2]*r+i[6]*o+i[10]*n+i[14]*a,t[3]=i[3]*r+i[7]*o+i[11]*n+i[15]*a,t},transformQuat:function(t,e,i){var r=e[0],o=e[1],n=e[2],a=i[0],s=i[1],l=i[2],d=i[3],h=d*r+s*n-l*o,c=d*o+l*r-a*n,u=d*n+a*o-s*r,f=-a*r-s*o-l*n;return t[0]=h*d+f*-a+c*-l-u*-s,t[1]=c*d+f*-s+u*-a-h*-l,t[2]=u*d+f*-l+h*-s-c*-a,t[3]=e[3],t},zero:function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t},str:function(t){return"vec4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},exactEquals:vt,equals:yt,sub:mt,mul:xt,div:bt,dist:Ct,sqrDist:At,len:Mt,sqrLen:Pt,forEach:Tt});function _t(){var t=new i(4);return i!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t[3]=1,t}function St(t,e,i){i*=.5;var r=Math.sin(i);return t[0]=r*e[0],t[1]=r*e[1],t[2]=r*e[2],t[3]=Math.cos(i),t}function Rt(t,e,i){var r=e[0],o=e[1],n=e[2],a=e[3],s=i[0],l=i[1],d=i[2],h=i[3];return t[0]=r*h+a*s+o*d-n*l,t[1]=o*h+a*l+n*s-r*d,t[2]=n*h+a*d+r*l-o*s,t[3]=a*h-r*s-o*l-n*d,t}function Lt(t,e,i){i*=.5;var r=e[0],o=e[1],n=e[2],a=e[3],s=Math.sin(i),l=Math.cos(i);return t[0]=r*l+a*s,t[1]=o*l+n*s,t[2]=n*l-o*s,t[3]=a*l-r*s,t}function Dt(t,e,i){i*=.5;var r=e[0],o=e[1],n=e[2],a=e[3],s=Math.sin(i),l=Math.cos(i);return t[0]=r*l-n*s,t[1]=o*l+a*s,t[2]=n*l+r*s,t[3]=a*l-o*s,t}function It(t,e,i){i*=.5;var r=e[0],o=e[1],n=e[2],a=e[3],s=Math.sin(i),l=Math.cos(i);return t[0]=r*l+o*s,t[1]=o*l-r*s,t[2]=n*l+a*s,t[3]=a*l-n*s,t}function Et(t,i,r,o){var n,a,s,l,d,h=i[0],c=i[1],u=i[2],f=i[3],g=r[0],p=r[1],v=r[2],y=r[3];return(a=h*g+c*p+u*v+f*y)<0&&(a=-a,g=-g,p=-p,v=-v,y=-y),1-a>e?(n=Math.acos(a),s=Math.sin(n),l=Math.sin((1-o)*n)/s,d=Math.sin(o*n)/s):(l=1-o,d=o),t[0]=l*h+d*g,t[1]=l*c+d*p,t[2]=l*u+d*v,t[3]=l*f+d*y,t}function Ot(t,e){var i,r=e[0]+e[4]+e[8];if(r>0)i=Math.sqrt(r+1),t[3]=.5*i,i=.5/i,t[0]=(e[5]-e[7])*i,t[1]=(e[6]-e[2])*i,t[2]=(e[1]-e[3])*i;else{var o=0;e[4]>e[0]&&(o=1),e[8]>e[3*o+o]&&(o=2);var n=(o+1)%3,a=(o+2)%3;i=Math.sqrt(e[3*o+o]-e[3*n+n]-e[3*a+a]+1),t[o]=.5*i,i=.5/i,t[3]=(e[3*n+a]-e[3*a+n])*i,t[n]=(e[3*n+o]+e[3*o+n])*i,t[a]=(e[3*a+o]+e[3*o+a])*i}return t}var Ft,Vt,Nt,Bt,jt,Ut,Gt=tt,kt=et,zt=it,Ht=rt,Wt=ot,Xt=Rt,Kt=lt,Yt=gt,qt=pt,Zt=ct,Qt=Zt,Jt=ut,$t=Jt,te=ft,ee=vt,ie=yt,re=(Ft=D(),Vt=E(1,0,0),Nt=E(0,1,0),function(t,e,i){var r=G(e,i);return r<-.999999?(k(Ft,Vt,e),q(Ft)<1e-6&&k(Ft,Nt,e),U(Ft,Ft),St(t,Ft,Math.PI),t):r>.999999?(t[0]=0,t[1]=0,t[2]=0,t[3]=1,t):(k(Ft,e,i),t[0]=Ft[0],t[1]=Ft[1],t[2]=Ft[2],t[3]=1+r,te(t,t))}),oe=(Bt=_t(),jt=_t(),function(t,e,i,r,o,n){return Et(Bt,e,o,n),Et(jt,i,r,n),Et(t,Bt,jt,2*n*(1-n)),t}),ne=(Ut=v(),function(t,e,i,r){return Ut[0]=i[0],Ut[3]=i[1],Ut[6]=i[2],Ut[1]=r[0],Ut[4]=r[1],Ut[7]=r[2],Ut[2]=-e[0],Ut[5]=-e[1],Ut[8]=-e[2],te(t,Ot(t,Ut))}),ae=Object.freeze({create:_t,identity:function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},setAxisAngle:St,getAxisAngle:function(t,i){var r=2*Math.acos(i[3]),o=Math.sin(r/2);return o>e?(t[0]=i[0]/o,t[1]=i[1]/o,t[2]=i[2]/o):(t[0]=1,t[1]=0,t[2]=0),r},multiply:Rt,rotateX:Lt,rotateY:Dt,rotateZ:It,calculateW:function(t,e){var i=e[0],r=e[1],o=e[2];return t[0]=i,t[1]=r,t[2]=o,t[3]=Math.sqrt(Math.abs(1-i*i-r*r-o*o)),t},slerp:Et,random:function(t){var e=r(),i=r(),o=r(),n=Math.sqrt(1-e),a=Math.sqrt(e);return t[0]=n*Math.sin(2*Math.PI*i),t[1]=n*Math.cos(2*Math.PI*i),t[2]=a*Math.sin(2*Math.PI*o),t[3]=a*Math.cos(2*Math.PI*o),t},invert:function(t,e){var i=e[0],r=e[1],o=e[2],n=e[3],a=i*i+r*r+o*o+n*n,s=a?1/a:0;return t[0]=-i*s,t[1]=-r*s,t[2]=-o*s,t[3]=n*s,t},conjugate:function(t,e){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=e[3],t},fromMat3:Ot,fromEuler:function(t,e,i,r){var o=.5*Math.PI/180;e*=o,i*=o,r*=o;var n=Math.sin(e),a=Math.cos(e),s=Math.sin(i),l=Math.cos(i),d=Math.sin(r),h=Math.cos(r);return t[0]=n*l*h-a*s*d,t[1]=a*s*h+n*l*d,t[2]=a*l*d-n*s*h,t[3]=a*l*h+n*s*d,t},str:function(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},clone:Gt,fromValues:kt,copy:zt,set:Ht,add:Wt,mul:Xt,scale:Kt,dot:Yt,lerp:qt,length:Zt,len:Qt,squaredLength:Jt,sqrLen:$t,normalize:te,exactEquals:ee,equals:ie,rotationTo:re,sqlerp:oe,setAxes:ne});function se(t,e,i){var r=.5*i[0],o=.5*i[1],n=.5*i[2],a=e[0],s=e[1],l=e[2],d=e[3];return t[0]=a,t[1]=s,t[2]=l,t[3]=d,t[4]=r*d+o*l-n*s,t[5]=o*d+n*a-r*l,t[6]=n*d+r*s-o*a,t[7]=-r*a-o*s-n*l,t}function le(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t}var de=zt;var he=zt;function ce(t,e,i){var r=e[0],o=e[1],n=e[2],a=e[3],s=i[4],l=i[5],d=i[6],h=i[7],c=e[4],u=e[5],f=e[6],g=e[7],p=i[0],v=i[1],y=i[2],m=i[3];return t[0]=r*m+a*p+o*y-n*v,t[1]=o*m+a*v+n*p-r*y,t[2]=n*m+a*y+r*v-o*p,t[3]=a*m-r*p-o*v-n*y,t[4]=r*h+a*s+o*d-n*l+c*m+g*p+u*y-f*v,t[5]=o*h+a*l+n*s-r*d+u*m+g*v+f*p-c*y,t[6]=n*h+a*d+r*l-o*s+f*m+g*y+c*v-u*p,t[7]=a*h-r*s-o*l-n*d+g*m-c*p-u*v-f*y,t}var ue=ce;var fe=Yt;var ge=Zt,pe=ge,ve=Jt,ye=ve;var me=Object.freeze({create:function(){var t=new i(8);return i!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0,t[4]=0,t[5]=0,t[6]=0,t[7]=0),t[3]=1,t},clone:function(t){var e=new i(8);return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e},fromValues:function(t,e,r,o,n,a,s,l){var d=new i(8);return d[0]=t,d[1]=e,d[2]=r,d[3]=o,d[4]=n,d[5]=a,d[6]=s,d[7]=l,d},fromRotationTranslationValues:function(t,e,r,o,n,a,s){var l=new i(8);l[0]=t,l[1]=e,l[2]=r,l[3]=o;var d=.5*n,h=.5*a,c=.5*s;return l[4]=d*o+h*r-c*e,l[5]=h*o+c*t-d*r,l[6]=c*o+d*e-h*t,l[7]=-d*t-h*e-c*r,l},fromRotationTranslation:se,fromTranslation:function(t,e){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t[4]=.5*e[0],t[5]=.5*e[1],t[6]=.5*e[2],t[7]=0,t},fromRotation:function(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=0,t[5]=0,t[6]=0,t[7]=0,t},fromMat4:function(t,e){var r=_t();w(r,e);var o=new i(3);return T(o,e),se(t,r,o),t},copy:le,identity:function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t[6]=0,t[7]=0,t},set:function(t,e,i,r,o,n,a,s,l){return t[0]=e,t[1]=i,t[2]=r,t[3]=o,t[4]=n,t[5]=a,t[6]=s,t[7]=l,t},getReal:de,getDual:function(t,e){return t[0]=e[4],t[1]=e[5],t[2]=e[6],t[3]=e[7],t},setReal:he,setDual:function(t,e){return t[4]=e[0],t[5]=e[1],t[6]=e[2],t[7]=e[3],t},getTranslation:function(t,e){var i=e[4],r=e[5],o=e[6],n=e[7],a=-e[0],s=-e[1],l=-e[2],d=e[3];return t[0]=2*(i*d+n*a+r*l-o*s),t[1]=2*(r*d+n*s+o*a-i*l),t[2]=2*(o*d+n*l+i*s-r*a),t},translate:function(t,e,i){var r=e[0],o=e[1],n=e[2],a=e[3],s=.5*i[0],l=.5*i[1],d=.5*i[2],h=e[4],c=e[5],u=e[6],f=e[7];return t[0]=r,t[1]=o,t[2]=n,t[3]=a,t[4]=a*s+o*d-n*l+h,t[5]=a*l+n*s-r*d+c,t[6]=a*d+r*l-o*s+u,t[7]=-r*s-o*l-n*d+f,t},rotateX:function(t,e,i){var r=-e[0],o=-e[1],n=-e[2],a=e[3],s=e[4],l=e[5],d=e[6],h=e[7],c=s*a+h*r+l*n-d*o,u=l*a+h*o+d*r-s*n,f=d*a+h*n+s*o-l*r,g=h*a-s*r-l*o-d*n;return Lt(t,e,i),r=t[0],o=t[1],n=t[2],a=t[3],t[4]=c*a+g*r+u*n-f*o,t[5]=u*a+g*o+f*r-c*n,t[6]=f*a+g*n+c*o-u*r,t[7]=g*a-c*r-u*o-f*n,t},rotateY:function(t,e,i){var r=-e[0],o=-e[1],n=-e[2],a=e[3],s=e[4],l=e[5],d=e[6],h=e[7],c=s*a+h*r+l*n-d*o,u=l*a+h*o+d*r-s*n,f=d*a+h*n+s*o-l*r,g=h*a-s*r-l*o-d*n;return Dt(t,e,i),r=t[0],o=t[1],n=t[2],a=t[3],t[4]=c*a+g*r+u*n-f*o,t[5]=u*a+g*o+f*r-c*n,t[6]=f*a+g*n+c*o-u*r,t[7]=g*a-c*r-u*o-f*n,t},rotateZ:function(t,e,i){var r=-e[0],o=-e[1],n=-e[2],a=e[3],s=e[4],l=e[5],d=e[6],h=e[7],c=s*a+h*r+l*n-d*o,u=l*a+h*o+d*r-s*n,f=d*a+h*n+s*o-l*r,g=h*a-s*r-l*o-d*n;return It(t,e,i),r=t[0],o=t[1],n=t[2],a=t[3],t[4]=c*a+g*r+u*n-f*o,t[5]=u*a+g*o+f*r-c*n,t[6]=f*a+g*n+c*o-u*r,t[7]=g*a-c*r-u*o-f*n,t},rotateByQuatAppend:function(t,e,i){var r=i[0],o=i[1],n=i[2],a=i[3],s=e[0],l=e[1],d=e[2],h=e[3];return t[0]=s*a+h*r+l*n-d*o,t[1]=l*a+h*o+d*r-s*n,t[2]=d*a+h*n+s*o-l*r,t[3]=h*a-s*r-l*o-d*n,s=e[4],l=e[5],d=e[6],h=e[7],t[4]=s*a+h*r+l*n-d*o,t[5]=l*a+h*o+d*r-s*n,t[6]=d*a+h*n+s*o-l*r,t[7]=h*a-s*r-l*o-d*n,t},rotateByQuatPrepend:function(t,e,i){var r=e[0],o=e[1],n=e[2],a=e[3],s=i[0],l=i[1],d=i[2],h=i[3];return t[0]=r*h+a*s+o*d-n*l,t[1]=o*h+a*l+n*s-r*d,t[2]=n*h+a*d+r*l-o*s,t[3]=a*h-r*s-o*l-n*d,s=i[4],l=i[5],d=i[6],h=i[7],t[4]=r*h+a*s+o*d-n*l,t[5]=o*h+a*l+n*s-r*d,t[6]=n*h+a*d+r*l-o*s,t[7]=a*h-r*s-o*l-n*d,t},rotateAroundAxis:function(t,i,r,o){if(Math.abs(o)0){i=Math.sqrt(i);var r=e[0]/i,o=e[1]/i,n=e[2]/i,a=e[3]/i,s=e[4],l=e[5],d=e[6],h=e[7],c=r*s+o*l+n*d+a*h;t[0]=r,t[1]=o,t[2]=n,t[3]=a,t[4]=(s-r*c)/i,t[5]=(l-o*c)/i,t[6]=(d-n*c)/i,t[7]=(h-a*c)/i}return t},str:function(t){return"quat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+")"},exactEquals:function(t,e){return t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]},equals:function(t,i){var r=t[0],o=t[1],n=t[2],a=t[3],s=t[4],l=t[5],d=t[6],h=t[7],c=i[0],u=i[1],f=i[2],g=i[3],p=i[4],v=i[5],y=i[6],m=i[7];return Math.abs(r-c)<=e*Math.max(1,Math.abs(r),Math.abs(c))&&Math.abs(o-u)<=e*Math.max(1,Math.abs(o),Math.abs(u))&&Math.abs(n-f)<=e*Math.max(1,Math.abs(n),Math.abs(f))&&Math.abs(a-g)<=e*Math.max(1,Math.abs(a),Math.abs(g))&&Math.abs(s-p)<=e*Math.max(1,Math.abs(s),Math.abs(p))&&Math.abs(l-v)<=e*Math.max(1,Math.abs(l),Math.abs(v))&&Math.abs(d-y)<=e*Math.max(1,Math.abs(d),Math.abs(y))&&Math.abs(h-m)<=e*Math.max(1,Math.abs(h),Math.abs(m))}});function xe(){var t=new i(2);return i!=Float32Array&&(t[0]=0,t[1]=0),t}function be(t,e,i){return t[0]=e[0]-i[0],t[1]=e[1]-i[1],t}function Ce(t,e,i){return t[0]=e[0]*i[0],t[1]=e[1]*i[1],t}function Ae(t,e,i){return t[0]=e[0]/i[0],t[1]=e[1]/i[1],t}function Me(t,e){var i=e[0]-t[0],r=e[1]-t[1];return Math.sqrt(i*i+r*r)}function Pe(t,e){var i=e[0]-t[0],r=e[1]-t[1];return i*i+r*r}function Te(t){var e=t[0],i=t[1];return Math.sqrt(e*e+i*i)}function we(t){var e=t[0],i=t[1];return e*e+i*i}var _e=Te,Se=be,Re=Ce,Le=Ae,De=Me,Ie=Pe,Ee=we,Oe=function(){var t=xe();return function(e,i,r,o,n,a){var s,l;for(i||(i=2),r||(r=0),l=o?Math.min(o*i+r,e.length):e.length,s=r;s0&&(o=1/Math.sqrt(o)),t[0]=e[0]*o,t[1]=e[1]*o,t},dot:function(t,e){return t[0]*e[0]+t[1]*e[1]},cross:function(t,e,i){var r=e[0]*i[1]-e[1]*i[0];return t[0]=t[1]=0,t[2]=r,t},lerp:function(t,e,i,r){var o=e[0],n=e[1];return t[0]=o+r*(i[0]-o),t[1]=n+r*(i[1]-n),t},random:function(t,e){e=e||1;var i=2*r()*Math.PI;return t[0]=Math.cos(i)*e,t[1]=Math.sin(i)*e,t},transformMat2:function(t,e,i){var r=e[0],o=e[1];return t[0]=i[0]*r+i[2]*o,t[1]=i[1]*r+i[3]*o,t},transformMat2d:function(t,e,i){var r=e[0],o=e[1];return t[0]=i[0]*r+i[2]*o+i[4],t[1]=i[1]*r+i[3]*o+i[5],t},transformMat3:function(t,e,i){var r=e[0],o=e[1];return t[0]=i[0]*r+i[3]*o+i[6],t[1]=i[1]*r+i[4]*o+i[7],t},transformMat4:function(t,e,i){var r=e[0],o=e[1];return t[0]=i[0]*r+i[4]*o+i[12],t[1]=i[1]*r+i[5]*o+i[13],t},rotate:function(t,e,i,r){var o=e[0]-i[0],n=e[1]-i[1],a=Math.sin(r),s=Math.cos(r);return t[0]=o*s-n*a+i[0],t[1]=o*a+n*s+i[1],t},angle:function(t,e){var i=t[0],r=t[1],o=e[0],n=e[1],a=i*i+r*r;a>0&&(a=1/Math.sqrt(a));var s=o*o+n*n;s>0&&(s=1/Math.sqrt(s));var l=(i*o+r*n)*a*s;return l>1?0:l<-1?Math.PI:Math.acos(l)},zero:function(t){return t[0]=0,t[1]=0,t},str:function(t){return"vec2("+t[0]+", "+t[1]+")"},exactEquals:function(t,e){return t[0]===e[0]&&t[1]===e[1]},equals:function(t,i){var r=t[0],o=t[1],n=i[0],a=i[1];return Math.abs(r-n)<=e*Math.max(1,Math.abs(r),Math.abs(n))&&Math.abs(o-a)<=e*Math.max(1,Math.abs(o),Math.abs(a))},len:_e,sub:Se,mul:Re,div:Le,dist:De,sqrDist:Ie,sqrLen:Ee,forEach:Oe});t.glMatrix=n,t.mat2=h,t.mat2d=p,t.mat3=C,t.mat4=L,t.quat=ae,t.quat2=me,t.vec2=Fe,t.vec3=J,t.vec4=wt,Object.defineProperty(t,"__esModule",{value:!0})}),function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).i18next=e()}(this,function(){function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:{};e(this,t),this.init(i,r)}return r(t,[{key:"init",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.prefix=e.prefix||"i18next:",this.logger=t||f,this.options=e,this.debug=e.debug}},{key:"setDebug",value:function(t){this.debug=t}},{key:"log",value:function(){for(var t=arguments.length,e=new Array(t),i=0;i-1&&i.observers[t].splice(r,1)}else delete i.observers[t]})}},{key:"emit",value:function(t){for(var e=arguments.length,i=new Array(e>1?e-1:0),r=1;r-1?t.replace(/###/g,"."):t}function o(){return!t||"string"==typeof t}for(var n="string"!=typeof e?[].concat(e):e.split(".");n.length>1;){if(o())return{};var a=r(n.shift());!t[a]&&i&&(t[a]=new i),t=t[a]}return o()?{}:{obj:t,k:r(n.shift())}}function x(t,e,i){var r=m(t,e,Object);r.obj[r.k]=i}function b(t,e){var i=m(t,e),r=i.obj,o=i.k;if(r)return r[o]}function C(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}var A={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};function M(t){return"string"==typeof t?t.replace(/[&<>"'\/]/g,function(t){return A[t]}):t}var P=function(t){function i(t){var r,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{ns:["translation"],defaultNS:"translation"};return e(this,i),r=h(this,s(i).call(this)),p.call(d(d(r))),r.data=t||{},r.options=o,void 0===r.options.keySeparator&&(r.options.keySeparator="."),r}return a(i,p),r(i,[{key:"addNamespaces",value:function(t){this.options.ns.indexOf(t)<0&&this.options.ns.push(t)}},{key:"removeNamespaces",value:function(t){var e=this.options.ns.indexOf(t);e>-1&&this.options.ns.splice(e,1)}},{key:"getResource",value:function(t,e,i){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},o=void 0!==r.keySeparator?r.keySeparator:this.options.keySeparator,n=[t,e];return i&&"string"!=typeof i&&(n=n.concat(i)),i&&"string"==typeof i&&(n=n.concat(o?i.split(o):i)),t.indexOf(".")>-1&&(n=t.split(".")),b(this.data,n)}},{key:"addResource",value:function(t,e,i,r){var o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{silent:!1},n=this.options.keySeparator;void 0===n&&(n=".");var a=[t,e];i&&(a=a.concat(n?i.split(n):i)),t.indexOf(".")>-1&&(r=e,e=(a=t.split("."))[1]),this.addNamespaces(e),x(this.data,a,r),o.silent||this.emit("added",t,e,i,r)}},{key:"addResources",value:function(t,e,i){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{silent:!1};for(var o in i)"string"!=typeof i[o]&&"[object Array]"!==Object.prototype.toString.apply(i[o])||this.addResource(t,e,o,i[o],{silent:!0});r.silent||this.emit("added",t,e,i)}},{key:"addResourceBundle",value:function(t,e,i,r,o){var a=arguments.length>5&&void 0!==arguments[5]?arguments[5]:{silent:!1},s=[t,e];t.indexOf(".")>-1&&(r=i,i=e,e=(s=t.split("."))[1]),this.addNamespaces(e);var l=b(this.data,s)||{};r?function t(e,i,r){for(var o in i)o in e?"string"==typeof e[o]||e[o]instanceof String||"string"==typeof i[o]||i[o]instanceof String?r&&(e[o]=i[o]):t(e[o],i[o],r):e[o]=i[o];return e}(l,i,o):l=n({},l,i),x(this.data,s,l),a.silent||this.emit("added",t,e,i)}},{key:"removeResourceBundle",value:function(t,e){this.hasResourceBundle(t,e)&&delete this.data[t][e],this.removeNamespaces(e),this.emit("removed",t,e)}},{key:"hasResourceBundle",value:function(t,e){return void 0!==this.getResource(t,e)}},{key:"getResourceBundle",value:function(t,e){return e||(e=this.options.defaultNS),"v1"===this.options.compatibilityAPI?n({},{},this.getResource(t,e)):this.getResource(t,e)}},{key:"getDataByLanguage",value:function(t){return this.data[t]}},{key:"toJSON",value:function(){return this.data}}]),i}(),T={processors:{},addPostProcessor:function(t){this.processors[t.name]=t},handle:function(t,e,i,r,o){var n=this;return t.forEach(function(t){n.processors[t]&&(e=n.processors[t].process(e,i,r,o))}),e}},w=function(i){function o(t){var i,r,n,a,l=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e(this,o),i=h(this,s(o).call(this)),p.call(d(d(i))),r=["resourceStore","languageUtils","pluralResolver","interpolator","backendConnector","i18nFormat"],n=t,a=d(d(i)),r.forEach(function(t){n[t]&&(a[t]=n[t])}),i.options=l,void 0===i.options.keySeparator&&(i.options.keySeparator="."),i.logger=g.create("translator"),i}return a(o,p),r(o,[{key:"changeLanguage",value:function(t){t&&(this.language=t)}},{key:"exists",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{interpolation:{}},i=this.resolve(t,e);return i&&void 0!==i.res}},{key:"extractFromKey",value:function(t,e){var i=e.nsSeparator||this.options.nsSeparator;void 0===i&&(i=":");var r=void 0!==e.keySeparator?e.keySeparator:this.options.keySeparator,o=e.ns||this.options.defaultNS;if(i&&t.indexOf(i)>-1){var n=t.split(i);(i!==r||i===r&&this.options.ns.indexOf(n[0])>-1)&&(o=n.shift()),t=n.join(r)}return"string"==typeof o&&(o=[o]),{key:t,namespaces:o}}},{key:"translate",value:function(e,i){var r=this;if("object"!==t(i)&&this.options.overloadTranslationOptionHandler&&(i=this.options.overloadTranslationOptionHandler(arguments)),i||(i={}),void 0===e||null===e)return"";Array.isArray(e)||(e=[String(e)]);var o=void 0!==i.keySeparator?i.keySeparator:this.options.keySeparator,a=this.extractFromKey(e[e.length-1],i),s=a.key,l=a.namespaces,d=l[l.length-1],h=i.lng||this.language,c=i.appendNamespaceToCIMode||this.options.appendNamespaceToCIMode;if(h&&"cimode"===h.toLowerCase()){if(c){var u=i.nsSeparator||this.options.nsSeparator;return d+u+s}return s}var f=this.resolve(e,i),g=f&&f.res,p=f&&f.usedKey||s,v=f&&f.exactUsedKey||s,y=Object.prototype.toString.apply(g),m=void 0!==i.joinArrays?i.joinArrays:this.options.joinArrays,x=!this.i18nFormat||this.i18nFormat.handleAsObject;if(x&&g&&("string"!=typeof g&&"boolean"!=typeof g&&"number"!=typeof g)&&["[object Number]","[object Function]","[object RegExp]"].indexOf(y)<0&&("string"!=typeof m||"[object Array]"!==y)){if(!i.returnObjects&&!this.options.returnObjects)return this.logger.warn("accessing an object - but returnObjects options is not enabled!"),this.options.returnedObjectHandler?this.options.returnedObjectHandler(p,g,i):"key '".concat(s," (").concat(this.language,")' returned an object instead of string.");if(o){var b="[object Array]"===y,C=b?[]:{},A=b?v:p;for(var M in g)if(Object.prototype.hasOwnProperty.call(g,M)){var P="".concat(A).concat(o).concat(M);C[M]=this.translate(P,n({},i,{joinArrays:!1,ns:l})),C[M]===P&&(C[M]=g[M])}g=C}}else if(x&&"string"==typeof m&&"[object Array]"===y)(g=g.join(m))&&(g=this.extendTranslation(g,e,i));else{var T=!1,w=!1;if(!this.isValidLookup(g)&&void 0!==i.defaultValue){if(T=!0,void 0!==i.count){var _=this.pluralResolver.getSuffix(h,i.count);g=i["defaultValue".concat(_)]}g||(g=i.defaultValue)}this.isValidLookup(g)||(w=!0,g=s);var S=i.defaultValue&&i.defaultValue!==g&&this.options.updateMissing;if(w||T||S){this.logger.log(S?"updateKey":"missingKey",h,d,s,S?i.defaultValue:g);var R=[],L=this.languageUtils.getFallbackCodes(this.options.fallbackLng,i.lng||this.language);if("fallback"===this.options.saveMissingTo&&L&&L[0])for(var D=0;D1&&void 0!==arguments[1]?arguments[1]:{};return"string"==typeof t&&(t=[t]),t.forEach(function(t){if(!a.isValidLookup(e)){var l=a.extractFromKey(t,s),d=l.key;i=d;var h=l.namespaces;a.options.fallbackNS&&(h=h.concat(a.options.fallbackNS));var c=void 0!==s.count&&"string"!=typeof s.count,u=void 0!==s.context&&"string"==typeof s.context&&""!==s.context,f=s.lngs?s.lngs:a.languageUtils.toResolveHierarchy(s.lng||a.language,s.fallbackLng);h.forEach(function(t){a.isValidLookup(e)||(n=t,f.forEach(function(i){if(!a.isValidLookup(e)){o=i;var n,l,h=d,f=[h];if(a.i18nFormat&&a.i18nFormat.addLookupKeys)a.i18nFormat.addLookupKeys(f,d,i,t,s);else c&&(n=a.pluralResolver.getSuffix(i,s.count)),c&&u&&f.push(h+n),u&&f.push(h+="".concat(a.options.contextSeparator).concat(s.context)),c&&f.push(h+=n);for(;l=f.pop();)a.isValidLookup(e)||(r=l,e=a.getResource(i,t,l,s))}}))})}}),{res:e,usedKey:i,exactUsedKey:r,usedLng:o,usedNS:n}}},{key:"isValidLookup",value:function(t){return!(void 0===t||!this.options.returnNull&&null===t||!this.options.returnEmptyString&&""===t)}},{key:"getResource",value:function(t,e,i){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};return this.i18nFormat&&this.i18nFormat.getResource?this.i18nFormat.getResource(t,e,i,r):this.resourceStore.getResource(t,e,i,r)}}]),o}();function _(t){return t.charAt(0).toUpperCase()+t.slice(1)}var S=function(){function t(i){e(this,t),this.options=i,this.whitelist=this.options.whitelist||!1,this.logger=g.create("languageUtils")}return r(t,[{key:"getScriptPartFromCode",value:function(t){if(!t||t.indexOf("-")<0)return null;var e=t.split("-");return 2===e.length?null:(e.pop(),this.formatLanguageCode(e.join("-")))}},{key:"getLanguagePartFromCode",value:function(t){if(!t||t.indexOf("-")<0)return t;var e=t.split("-");return this.formatLanguageCode(e[0])}},{key:"formatLanguageCode",value:function(t){if("string"==typeof t&&t.indexOf("-")>-1){var e=["hans","hant","latn","cyrl","cans","mong","arab"],i=t.split("-");return this.options.lowerCaseLng?i=i.map(function(t){return t.toLowerCase()}):2===i.length?(i[0]=i[0].toLowerCase(),i[1]=i[1].toUpperCase(),e.indexOf(i[1].toLowerCase())>-1&&(i[1]=_(i[1].toLowerCase()))):3===i.length&&(i[0]=i[0].toLowerCase(),2===i[1].length&&(i[1]=i[1].toUpperCase()),"sgn"!==i[0]&&2===i[2].length&&(i[2]=i[2].toUpperCase()),e.indexOf(i[1].toLowerCase())>-1&&(i[1]=_(i[1].toLowerCase())),e.indexOf(i[2].toLowerCase())>-1&&(i[2]=_(i[2].toLowerCase()))),i.join("-")}return this.options.cleanCode||this.options.lowerCaseLng?t.toLowerCase():t}},{key:"isWhitelisted",value:function(t){return("languageOnly"===this.options.load||this.options.nonExplicitWhitelist)&&(t=this.getLanguagePartFromCode(t)),!this.whitelist||!this.whitelist.length||this.whitelist.indexOf(t)>-1}},{key:"getFallbackCodes",value:function(t,e){if(!t)return[];if("string"==typeof t&&(t=[t]),"[object Array]"===Object.prototype.toString.apply(t))return t;if(!e)return t.default||[];var i=t[e];return i||(i=t[this.getScriptPartFromCode(e)]),i||(i=t[this.formatLanguageCode(e)]),i||(i=t.default),i||[]}},{key:"toResolveHierarchy",value:function(t,e){var i=this,r=this.getFallbackCodes(e||this.options.fallbackLng||[],t),o=[],n=function(t){t&&(i.isWhitelisted(t)?o.push(t):i.logger.warn("rejecting non-whitelisted language code: ".concat(t)))};return"string"==typeof t&&t.indexOf("-")>-1?("languageOnly"!==this.options.load&&n(this.formatLanguageCode(t)),"languageOnly"!==this.options.load&&"currentOnly"!==this.options.load&&n(this.getScriptPartFromCode(t)),"currentOnly"!==this.options.load&&n(this.getLanguagePartFromCode(t))):"string"==typeof t&&n(this.formatLanguageCode(t)),r.forEach(function(t){o.indexOf(t)<0&&n(i.formatLanguageCode(t))}),o}}]),t}(),R=[{lngs:["ach","ak","am","arn","br","fil","gun","ln","mfe","mg","mi","oc","pt","pt-BR","tg","ti","tr","uz","wa"],nr:[1,2],fc:1},{lngs:["af","an","ast","az","bg","bn","ca","da","de","dev","el","en","eo","es","et","eu","fi","fo","fur","fy","gl","gu","ha","hi","hu","hy","ia","it","kn","ku","lb","mai","ml","mn","mr","nah","nap","nb","ne","nl","nn","no","nso","pa","pap","pms","ps","pt-PT","rm","sco","se","si","so","son","sq","sv","sw","ta","te","tk","ur","yo"],nr:[1,2],fc:2},{lngs:["ay","bo","cgg","fa","id","ja","jbo","ka","kk","km","ko","ky","lo","ms","sah","su","th","tt","ug","vi","wo","zh"],nr:[1],fc:3},{lngs:["be","bs","dz","hr","ru","sr","uk"],nr:[1,2,5],fc:4},{lngs:["ar"],nr:[0,1,2,3,11,100],fc:5},{lngs:["cs","sk"],nr:[1,2,5],fc:6},{lngs:["csb","pl"],nr:[1,2,5],fc:7},{lngs:["cy"],nr:[1,2,3,8],fc:8},{lngs:["fr"],nr:[1,2],fc:9},{lngs:["ga"],nr:[1,2,3,7,11],fc:10},{lngs:["gd"],nr:[1,2,3,20],fc:11},{lngs:["is"],nr:[1,2],fc:12},{lngs:["jv"],nr:[0,1],fc:13},{lngs:["kw"],nr:[1,2,3,4],fc:14},{lngs:["lt"],nr:[1,2,10],fc:15},{lngs:["lv"],nr:[1,2,0],fc:16},{lngs:["mk"],nr:[1,2],fc:17},{lngs:["mnk"],nr:[0,1,2],fc:18},{lngs:["mt"],nr:[1,2,11,20],fc:19},{lngs:["or"],nr:[2,1],fc:2},{lngs:["ro"],nr:[1,2,20],fc:20},{lngs:["sl"],nr:[5,1,2,3],fc:21},{lngs:["he"],nr:[1,2,20,21],fc:22}],L={1:function(t){return Number(t>1)},2:function(t){return Number(1!=t)},3:function(t){return 0},4:function(t){return Number(t%10==1&&t%100!=11?0:t%10>=2&&t%10<=4&&(t%100<10||t%100>=20)?1:2)},5:function(t){return Number(0===t?0:1==t?1:2==t?2:t%100>=3&&t%100<=10?3:t%100>=11?4:5)},6:function(t){return Number(1==t?0:t>=2&&t<=4?1:2)},7:function(t){return Number(1==t?0:t%10>=2&&t%10<=4&&(t%100<10||t%100>=20)?1:2)},8:function(t){return Number(1==t?0:2==t?1:8!=t&&11!=t?2:3)},9:function(t){return Number(t>=2)},10:function(t){return Number(1==t?0:2==t?1:t<7?2:t<11?3:4)},11:function(t){return Number(1==t||11==t?0:2==t||12==t?1:t>2&&t<20?2:3)},12:function(t){return Number(t%10!=1||t%100==11)},13:function(t){return Number(0!==t)},14:function(t){return Number(1==t?0:2==t?1:3==t?2:3)},15:function(t){return Number(t%10==1&&t%100!=11?0:t%10>=2&&(t%100<10||t%100>=20)?1:2)},16:function(t){return Number(t%10==1&&t%100!=11?0:0!==t?1:2)},17:function(t){return Number(1==t||t%10==1?0:1)},18:function(t){return Number(0==t?0:1==t?1:2)},19:function(t){return Number(1==t?0:0===t||t%100>1&&t%100<11?1:t%100>10&&t%100<20?2:3)},20:function(t){return Number(1==t?0:0===t||t%100>0&&t%100<20?1:2)},21:function(t){return Number(t%100==1?1:t%100==2?2:t%100==3||t%100==4?3:0)},22:function(t){return Number(1===t?0:2===t?1:(t<0||t>10)&&t%10==0?2:3)}};var D=function(){function t(i){var r,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};e(this,t),this.languageUtils=i,this.options=o,this.logger=g.create("pluralResolver"),this.rules=(r={},R.forEach(function(t){t.lngs.forEach(function(e){r[e]={numbers:t.nr,plurals:L[t.fc]}})}),r)}return r(t,[{key:"addRule",value:function(t,e){this.rules[t]=e}},{key:"getRule",value:function(t){return this.rules[t]||this.rules[this.languageUtils.getLanguagePartFromCode(t)]}},{key:"needsPlural",value:function(t){var e=this.getRule(t);return e&&e.numbers.length>1}},{key:"getPluralFormsOfKey",value:function(t,e){var i=this,r=[],o=this.getRule(t);return o?(o.numbers.forEach(function(o){var n=i.getSuffix(t,o);r.push("".concat(e).concat(n))}),r):r}},{key:"getSuffix",value:function(t,e){var i=this,r=this.getRule(t);if(r){var o=r.noAbs?r.plurals(e):r.plurals(Math.abs(e)),n=r.numbers[o];this.options.simplifyPluralSuffix&&2===r.numbers.length&&1===r.numbers[0]&&(2===n?n="plural":1===n&&(n=""));var a=function(){return i.options.prepend&&n.toString()?i.options.prepend+n.toString():n.toString()};return"v1"===this.options.compatibilityJSON?1===n?"":"number"==typeof n?"_plural_".concat(n.toString()):a():"v2"===this.options.compatibilityJSON?a():this.options.simplifyPluralSuffix&&2===r.numbers.length&&1===r.numbers[0]?a():this.options.prepend&&o.toString()?this.options.prepend+o.toString():o.toString()}return this.logger.warn("no plural rule found for: ".concat(t)),""}}]),t}(),I=function(){function t(){var i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};e(this,t),this.logger=g.create("interpolator"),this.init(i,!0)}return r(t,[{key:"init",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};(arguments.length>1?arguments[1]:void 0)&&(this.options=t,this.format=t.interpolation&&t.interpolation.format||function(t){return t}),t.interpolation||(t.interpolation={escapeValue:!0});var e=t.interpolation;this.escape=void 0!==e.escape?e.escape:M,this.escapeValue=void 0===e.escapeValue||e.escapeValue,this.useRawValueToEscape=void 0!==e.useRawValueToEscape&&e.useRawValueToEscape,this.prefix=e.prefix?C(e.prefix):e.prefixEscaped||"{{",this.suffix=e.suffix?C(e.suffix):e.suffixEscaped||"}}",this.formatSeparator=e.formatSeparator?e.formatSeparator:e.formatSeparator||",",this.unescapePrefix=e.unescapeSuffix?"":e.unescapePrefix||"-",this.unescapeSuffix=this.unescapePrefix?"":e.unescapeSuffix||"",this.nestingPrefix=e.nestingPrefix?C(e.nestingPrefix):e.nestingPrefixEscaped||C("$t("),this.nestingSuffix=e.nestingSuffix?C(e.nestingSuffix):e.nestingSuffixEscaped||C(")"),this.maxReplaces=e.maxReplaces?e.maxReplaces:1e3,this.resetRegExp()}},{key:"reset",value:function(){this.options&&this.init(this.options)}},{key:"resetRegExp",value:function(){var t="".concat(this.prefix,"(.+?)").concat(this.suffix);this.regexp=new RegExp(t,"g");var e="".concat(this.prefix).concat(this.unescapePrefix,"(.+?)").concat(this.unescapeSuffix).concat(this.suffix);this.regexpUnescape=new RegExp(e,"g");var i="".concat(this.nestingPrefix,"(.+?)").concat(this.nestingSuffix);this.nestingRegexp=new RegExp(i,"g")}},{key:"interpolate",value:function(t,e,i,r){var o,n,a,s=this;function l(t){return t.replace(/\$/g,"$$$$")}var d=function(t){if(t.indexOf(s.formatSeparator)<0)return b(e,t);var r=t.split(s.formatSeparator),o=r.shift().trim(),n=r.join(s.formatSeparator).trim();return s.format(b(e,o),n,i)};this.resetRegExp();var h=r&&r.missingInterpolationHandler||this.options.missingInterpolationHandler;for(a=0;(o=this.regexpUnescape.exec(t))&&(n=d(o[1].trim()),t=t.replace(o[0],n),this.regexpUnescape.lastIndex=0,!(++a>=this.maxReplaces)););for(a=0;o=this.regexp.exec(t);){if(void 0===(n=d(o[1].trim())))if("function"==typeof h){var c=h(t,o,r);n="string"==typeof c?c:""}else this.logger.warn("missed to pass in variable ".concat(o[1]," for interpolating ").concat(t)),n="";else"string"==typeof n||this.useRawValueToEscape||(n=y(n));if(n=this.escapeValue?l(this.escape(n)):l(n),t=t.replace(o[0],n),this.regexp.lastIndex=0,++a>=this.maxReplaces)break}return t}},{key:"nest",value:function(t,e){var i,r,o=n({},arguments.length>2&&void 0!==arguments[2]?arguments[2]:{});function a(t,e){if(t.indexOf(",")<0)return t;var i=t.split(",");t=i.shift();var r=i.join(",");r=(r=this.interpolate(r,o)).replace(/'/g,'"');try{o=JSON.parse(r),e&&(o=n({},e,o))}catch(e){this.logger.error("failed parsing options string in nesting for key ".concat(t),e)}return t}for(o.applyPostProcessor=!1;i=this.nestingRegexp.exec(t);){if((r=e(a.call(this,i[1].trim(),o),o))&&i[0]===t&&"string"!=typeof r)return r;"string"!=typeof r&&(r=y(r)),r||(this.logger.warn("missed to resolve ".concat(i[1]," for nesting ").concat(t)),r=""),t=t.replace(i[0],r),this.regexp.lastIndex=0}return t}}]),t}();var E=function(t){function i(t,r,o){var n,a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};return e(this,i),n=h(this,s(i).call(this)),p.call(d(d(n))),n.backend=t,n.store=r,n.languageUtils=o.languageUtils,n.options=a,n.logger=g.create("backendConnector"),n.state={},n.queue=[],n.backend&&n.backend.init&&n.backend.init(o,a.backend,a),n}return a(i,p),r(i,[{key:"queueLoad",value:function(t,e,i,r){var o=this,n=[],a=[],s=[],l=[];return t.forEach(function(t){var r=!0;e.forEach(function(e){var s="".concat(t,"|").concat(e);!i.reload&&o.store.hasResourceBundle(t,e)?o.state[s]=2:o.state[s]<0||(1===o.state[s]?a.indexOf(s)<0&&a.push(s):(o.state[s]=1,r=!1,a.indexOf(s)<0&&a.push(s),n.indexOf(s)<0&&n.push(s),l.indexOf(e)<0&&l.push(e)))}),r||s.push(t)}),(n.length||a.length)&&this.queue.push({pending:a,loaded:{},errors:[],callback:r}),{toLoad:n,pending:a,toLoadLanguages:s,toLoadNamespaces:l}}},{key:"loaded",value:function(t,e,i){var r=c(t.split("|"),2),o=r[0],n=r[1];e&&this.emit("failedLoading",o,n,e),i&&this.store.addResourceBundle(o,n,i),this.state[t]=e?-1:2;var a={};this.queue.forEach(function(i){var r,s,l,d,h,c;r=i.loaded,s=n,d=m(r,[o],Object),h=d.obj,c=d.k,h[c]=h[c]||[],l&&(h[c]=h[c].concat(s)),l||h[c].push(s),function(t,e){for(var i=t.indexOf(e);-1!==i;)t.splice(i,1),i=t.indexOf(e)}(i.pending,t),e&&i.errors.push(e),0!==i.pending.length||i.done||(Object.keys(i.loaded).forEach(function(t){a[t]||(a[t]=[]),i.loaded[t].length&&i.loaded[t].forEach(function(e){a[t].indexOf(e)<0&&a[t].push(e)})}),i.done=!0,i.errors.length?i.callback(i.errors):i.callback())}),this.emit("loaded",a),this.queue=this.queue.filter(function(t){return!t.done})}},{key:"read",value:function(t,e,i){var r=this,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,n=arguments.length>4&&void 0!==arguments[4]?arguments[4]:250,a=arguments.length>5?arguments[5]:void 0;return t.length?this.backend[i](t,e,function(s,l){s&&l&&o<5?setTimeout(function(){r.read.call(r,t,e,i,o+1,2*n,a)},n):a(s,l)}):a(null,{})}},{key:"prepareLoading",value:function(t,e){var i=this,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=arguments.length>3?arguments[3]:void 0;if(!this.backend)return this.logger.warn("No backend was added via i18next.use. Will not load resources."),o&&o();"string"==typeof t&&(t=this.languageUtils.toResolveHierarchy(t)),"string"==typeof e&&(e=[e]);var n=this.queueLoad(t,e,r,o);if(!n.toLoad.length)return n.pending.length||o(),null;n.toLoad.forEach(function(t){i.loadOne(t)})}},{key:"load",value:function(t,e,i){this.prepareLoading(t,e,{},i)}},{key:"reload",value:function(t,e,i){this.prepareLoading(t,e,{reload:!0},i)}},{key:"loadOne",value:function(t){var e=this,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",r=c(t.split("|"),2),o=r[0],n=r[1];this.read(o,n,"read",null,null,function(r,a){r&&e.logger.warn("".concat(i,"loading namespace ").concat(n," for language ").concat(o," failed"),r),!r&&a&&e.logger.log("".concat(i,"loaded namespace ").concat(n," for language ").concat(o),a),e.loaded(t,r,a)})}},{key:"saveMissing",value:function(t,e,i,r,o){var a=arguments.length>5&&void 0!==arguments[5]?arguments[5]:{};this.backend&&this.backend.create&&this.backend.create(t,e,i,r,null,n({},a,{isUpdate:o})),t&&t[0]&&this.store.addResource(t[0],e,i,r)}}]),i}();function O(t){return"string"==typeof t.ns&&(t.ns=[t.ns]),"string"==typeof t.fallbackLng&&(t.fallbackLng=[t.fallbackLng]),"string"==typeof t.fallbackNS&&(t.fallbackNS=[t.fallbackNS]),t.whitelist&&t.whitelist.indexOf("cimode")<0&&(t.whitelist=t.whitelist.concat(["cimode"])),t}function F(){}return new(function(i){function o(){var t,i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=arguments.length>1?arguments[1]:void 0;if(e(this,o),t=h(this,s(o).call(this)),p.call(d(d(t))),t.options=O(i),t.services={},t.logger=g,t.modules={external:[]},r&&!t.isInitialized&&!i.isClone){if(!t.options.initImmediate)return t.init(i,r),h(t,d(d(t)));setTimeout(function(){t.init(i,r)},0)}return t}return a(o,p),r(o,[{key:"init",value:function(){var e=this,i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=arguments.length>1?arguments[1]:void 0;function o(t){return t?"function"==typeof t?new t:t:null}if("function"==typeof i&&(r=i,i={}),this.options=n({},{debug:!1,initImmediate:!0,ns:["translation"],defaultNS:["translation"],fallbackLng:["dev"],fallbackNS:!1,whitelist:!1,nonExplicitWhitelist:!1,load:"all",preload:!1,simplifyPluralSuffix:!0,keySeparator:".",nsSeparator:":",pluralSeparator:"_",contextSeparator:"_",partialBundledLanguages:!1,saveMissing:!1,updateMissing:!1,saveMissingTo:"fallback",saveMissingPlurals:!0,missingKeyHandler:!1,missingInterpolationHandler:!1,postProcess:!1,returnNull:!0,returnEmptyString:!0,returnObjects:!1,joinArrays:!1,returnedObjectHandler:function(){},parseMissingKeyHandler:!1,appendNamespaceToMissingKey:!1,appendNamespaceToCIMode:!1,overloadTranslationOptionHandler:function(e){var i={};if("object"===t(e[1])&&(i=e[1]),"string"==typeof e[1]&&(i.defaultValue=e[1]),"string"==typeof e[2]&&(i.tDescription=e[2]),"object"===t(e[2])||"object"===t(e[3])){var r=e[3]||e[2];Object.keys(r).forEach(function(t){i[t]=r[t]})}return i},interpolation:{escapeValue:!0,format:function(t,e,i){return t},prefix:"{{",suffix:"}}",formatSeparator:",",unescapePrefix:"-",nestingPrefix:"$t(",nestingSuffix:")",maxReplaces:1e3}},this.options,O(i)),this.format=this.options.interpolation.format,r||(r=F),!this.options.isClone){this.modules.logger?g.init(o(this.modules.logger),this.options):g.init(null,this.options);var a=new S(this.options);this.store=new P(this.options.resources,this.options);var s=this.services;s.logger=g,s.resourceStore=this.store,s.languageUtils=a,s.pluralResolver=new D(a,{prepend:this.options.pluralSeparator,compatibilityJSON:this.options.compatibilityJSON,simplifyPluralSuffix:this.options.simplifyPluralSuffix}),s.interpolator=new I(this.options),s.backendConnector=new E(o(this.modules.backend),s.resourceStore,s,this.options),s.backendConnector.on("*",function(t){for(var i=arguments.length,r=new Array(i>1?i-1:0),o=1;o1?i-1:0),o=1;o0&&void 0!==arguments[0]?arguments[0]:F;if(!this.options.resources||this.options.partialBundledLanguages){if(this.language&&"cimode"===this.language.toLowerCase())return e();var i=[],r=function(e){e&&t.services.languageUtils.toResolveHierarchy(e).forEach(function(t){i.indexOf(t)<0&&i.push(t)})};if(this.language)r(this.language);else this.services.languageUtils.getFallbackCodes(this.options.fallbackLng).forEach(function(t){return r(t)});this.options.preload&&this.options.preload.forEach(function(t){return r(t)}),this.services.backendConnector.load(i,this.options.ns,e)}else e(null)}},{key:"reloadResources",value:function(t,e,i){var r=v();return t||(t=this.languages),e||(e=this.options.ns),i||(i=F),this.services.backendConnector.reload(t,e,function(t){r.resolve(),i(t)}),r}},{key:"use",value:function(t){return"backend"===t.type&&(this.modules.backend=t),("logger"===t.type||t.log&&t.warn&&t.error)&&(this.modules.logger=t),"languageDetector"===t.type&&(this.modules.languageDetector=t),"i18nFormat"===t.type&&(this.modules.i18nFormat=t),"postProcessor"===t.type&&T.addPostProcessor(t),"3rdParty"===t.type&&this.modules.external.push(t),this}},{key:"changeLanguage",value:function(t,e){var i=this,r=v();this.emit("languageChanging",t);var o=function(t){t&&(i.language=t,i.languages=i.services.languageUtils.toResolveHierarchy(t),i.translator.language||i.translator.changeLanguage(t),i.services.languageDetector&&i.services.languageDetector.cacheUserLanguage(t)),i.loadResources(function(o){!function(t,o){i.translator.changeLanguage(o),o&&(i.emit("languageChanged",o),i.logger.log("languageChanged",o)),r.resolve(function(){return i.t.apply(i,arguments)}),e&&e(t,function(){return i.t.apply(i,arguments)})}(o,t)})};return t||!this.services.languageDetector||this.services.languageDetector.async?!t&&this.services.languageDetector&&this.services.languageDetector.async?this.services.languageDetector.detect(o):o(t):o(this.services.languageDetector.detect()),r}},{key:"getFixedT",value:function(e,i){var r=this,o=function e(i,o){var a=n({},o);if("object"!==t(o)){for(var s=arguments.length,l=new Array(s>2?s-2:0),d=2;d0?this.languages[0]:this.language),!t)return"rtl";return["ar","shu","sqr","ssh","xaa","yhd","yud","aao","abh","abv","acm","acq","acw","acx","acy","adf","ads","aeb","aec","afb","ajp","apc","apd","arb","arq","ars","ary","arz","auz","avl","ayh","ayl","ayn","ayp","bbz","pga","he","iw","ps","pbt","pbu","pst","prp","prd","ur","ydd","yds","yih","ji","yi","hbo","men","xmn","fa","jpr","peo","pes","prs","dv","sam"].indexOf(this.services.languageUtils.getLanguagePartFromCode(t))>=0?"rtl":"ltr"}},{key:"createInstance",value:function(){return new o(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},arguments.length>1?arguments[1]:void 0)}},{key:"cloneInstance",value:function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:F,r=n({},this.options,e,{isClone:!0}),a=new o(r);return["store","services","language"].forEach(function(e){a[e]=t[e]}),a.translator=new w(a.services,a.options),a.translator.on("*",function(t){for(var e=arguments.length,i=new Array(e>1?e-1:0),r=1;r0)i[r].substring(0,o)===t.lookupQuerystring&&(e=i[r].substring(o+1))}return e}},s=void 0;try{s="undefined"!==window&&null!==window.localStorage;window.localStorage.setItem("i18next.translate.boo","foo"),window.localStorage.removeItem("i18next.translate.boo")}catch(t){s=!1}var l={name:"localStorage",lookup:function(t){var e=void 0;if(t.lookupLocalStorage&&s){var i=window.localStorage.getItem(t.lookupLocalStorage);i&&(e=i)}return e},cacheUserLanguage:function(t,e){e.lookupLocalStorage&&s&&window.localStorage.setItem(e.lookupLocalStorage,t)}},d={name:"navigator",lookup:function(t){var e=[];if("undefined"!=typeof navigator){if(navigator.languages)for(var i=0;i0?e:void 0}},h={name:"htmlTag",lookup:function(t){var e=void 0,i=t.htmlTag||("undefined"!=typeof document?document.documentElement:null);return i&&"function"==typeof i.getAttribute&&(e=i.getAttribute("lang")),e}},c={name:"path",lookup:function(t){var e=void 0;if("undefined"!=typeof window){var i=window.location.pathname.match(/\/([a-zA-Z-]*)/g);if(i instanceof Array)if("number"==typeof t.lookupFromPathIndex){if("string"!=typeof i[t.lookupFromPathIndex])return;e=i[t.lookupFromPathIndex].replace("/","")}else e=i[0].replace("/","")}return e}},u={name:"subdomain",lookup:function(t){var e=void 0;if("undefined"!=typeof window){var i=window.location.href.match(/(?:http[s]*\:\/\/)*(.*?)\.(?=[^\/]*\..{2,5})/gi);i instanceof Array&&(e="number"==typeof t.lookupFromSubdomainIndex?i[t.lookupFromSubdomainIndex].replace("http://","").replace("https://","").replace(".",""):i[0].replace("http://","").replace("https://","").replace(".",""))}return e}},f=function(){function t(t,e){for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:{};!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.type="languageDetector",this.detectors={},this.init(e,i)}return f(t,[{key:"init",value:function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};this.services=t,this.options=function(t){return e.call(i.call(arguments,1),function(e){if(e)for(var i in e)void 0===t[i]&&(t[i]=e[i])}),t}(r,this.options||{},{order:["querystring","cookie","localStorage","navigator","htmlTag"],lookupQuerystring:"lng",lookupCookie:"i18next",lookupLocalStorage:"i18nextLng",caches:["localStorage"],excludeCacheFor:["cimode"]}),this.options.lookupFromUrlIndex&&(this.options.lookupFromPathIndex=this.options.lookupFromUrlIndex),this.i18nOptions=o,this.addDetector(n),this.addDetector(a),this.addDetector(l),this.addDetector(d),this.addDetector(h),this.addDetector(c),this.addDetector(u)}},{key:"addDetector",value:function(t){this.detectors[t.name]=t}},{key:"detect",value:function(t){var e=this;t||(t=this.options.order);var i=[];t.forEach(function(t){if(e.detectors[t]){var r=e.detectors[t].lookup(e.options);r&&"string"==typeof r&&(r=[r]),r&&(i=i.concat(r))}});var r=void 0;if(i.forEach(function(t){if(!r){var i=e.services.languageUtils.formatLanguageCode(t);e.services.languageUtils.isWhitelisted(i)&&(r=i)}}),!r){var o=this.i18nOptions.fallbackLng;"string"==typeof o&&(o=[o]),o||(o=[]),r="[object Array]"===Object.prototype.toString.apply(o)?o[0]:o[0]||o.default&&o.default[0]}return r}},{key:"cacheUserLanguage",value:function(t,e){var i=this;e||(e=this.options.caches),e&&(this.options.excludeCacheFor&&this.options.excludeCacheFor.indexOf(t)>-1||e.forEach(function(e){i.detectors[e]&&i.detectors[e].cacheUserLanguage(t,i.options)}))}}]),t}();return g.type="languageDetector",g}),function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.i18nextXHRBackend=e()}(this,function(){var t=[],e=t.forEach,i=t.slice;var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};function o(t,e){if(e&&"object"===(void 0===e?"undefined":r(e))){var i="",o=encodeURIComponent;for(var n in e)i+="&"+o(n)+"="+o(e[n]);if(!i)return t;t=t+(-1!==t.indexOf("?")?"&":"?")+i.slice(1)}return t}function n(t,e,i,n,a){n&&"object"===(void 0===n?"undefined":r(n))&&(a||(n._t=new Date),n=o("",n).slice(1)),e.queryStringParams&&(t=o(t,e.queryStringParams));try{var s;(s=XMLHttpRequest?new XMLHttpRequest:new ActiveXObject("MSXML2.XMLHTTP.3.0")).open(n?"POST":"GET",t,1),e.crossDomain||s.setRequestHeader("X-Requested-With","XMLHttpRequest"),s.withCredentials=!!e.withCredentials,n&&s.setRequestHeader("Content-type","application/x-www-form-urlencoded"),s.overrideMimeType&&s.overrideMimeType("application/json");var l=e.customHeaders;if(l)for(var d in l)s.setRequestHeader(d,l[d]);s.onreadystatechange=function(){s.readyState>3&&i&&i(s.responseText,s)},s.send(n)}catch(t){console&&console.log(t)}}var a=function(){function t(t,e){for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:{};!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.init(e,i),this.type="backend"}return a(t,[{key:"init",value:function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.services=t,this.options=function(t){return e.call(i.call(arguments,1),function(e){if(e)for(var i in e)void 0===t[i]&&(t[i]=e[i])}),t}(r,this.options||{},{loadPath:"/locales/{{lng}}/{{ns}}.json",addPath:"/locales/add/{{lng}}/{{ns}}",allowMultiLoading:!1,parse:JSON.parse,crossDomain:!1,ajax:n})}},{key:"readMulti",value:function(t,e,i){var r=this.options.loadPath;"function"==typeof this.options.loadPath&&(r=this.options.loadPath(t,e));var o=this.services.interpolator.interpolate(r,{lng:t.join("+"),ns:e.join("+")});this.loadUrl(o,i)}},{key:"read",value:function(t,e,i){var r=this.options.loadPath;"function"==typeof this.options.loadPath&&(r=this.options.loadPath([t],[e]));var o=this.services.interpolator.interpolate(r,{lng:t,ns:e});this.loadUrl(o,i)}},{key:"loadUrl",value:function(t,e){var i=this;this.options.ajax(t,this.options,function(r,o){if(o.status>=500&&o.status<600)return e("failed loading "+t,!0);if(o.status>=400&&o.status<500)return e("failed loading "+t,!1);var n=void 0,a=void 0;try{n=i.options.parse(r,t)}catch(e){a="failed parsing "+t+" to json"}if(a)return e(a,!1);e(null,n)})}},{key:"create",value:function(t,e,i,r){var o=this;"string"==typeof t&&(t=[t]);var n={};n[i]=r||"",t.forEach(function(t){var i=o.services.interpolator.interpolate(o.options.addPath,{lng:t,ns:e});o.options.ajax(i,o.options,function(t,e){},n)})}}]),t}();return s.type="backend",s}),function(t){function e(){if(1==arguments.length){var t=arguments[0];this.header={idLength:i((n=t).idLength,0),colorMapType:i(n.colorMapType,0),imageType:i(n.imageType,e.Type.RGB),colorMapIndex:i(n.colorMapIndex,0),colorMapLength:i(n.colorMapLength,0),colorMapDepth:i(n.colorMapDepth,0),offsetX:i(n.offsetX,0),offsetY:i(n.offsetY,0),width:i(n.width,0),height:i(n.height,0),pixelDepth:i(n.pixelDepth,32),flags:i(n.flags,8)},r(this.header),o(this.header)}var n}function i(t,e){return void 0!==t?t:e}function r(t){t.hasEncoding=t.imageType===e.Type.RLE_INDEXED||t.imageType===e.Type.RLE_RGB||t.imageType===e.Type.RLE_GREY,t.hasColorMap=t.imageType===e.Type.RLE_INDEXED||t.imageType===e.Type.INDEXED,t.isGreyColor=t.imageType===e.Type.RLE_GREY||t.imageType===e.Type.GREY,t.bytePerPixel=t.pixelDepth>>3,t.origin=(t.flags&e.Origin.MASK)>>e.Origin.SHIFT,t.alphaBits=t.flags&e.Origin.ALPHA}function o(t){if(t.imageType===e.Type.NO_DATA)throw new Error("Targa::checkHeader() - No data");if(t.hasColorMap){if(t.colorMapLength>256||1!==t.colorMapType)throw new Error("Targa::checkHeader() - Unsupported colormap for indexed type");if(16!==t.colorMapDepth&&24!==t.colorMapDepth&&32!==t.colorMapDepth)throw new Error("Targa::checkHeader() - Unsupported colormap depth")}else if(t.colorMapType)throw new Error("Targa::checkHeader() - Why does the image contain a palette ?");if(t.width<=0||t.height<=0)throw new Error("Targa::checkHeader() - Invalid image size");if(8!==t.pixelDepth&&16!==t.pixelDepth&&24!==t.pixelDepth&&32!==t.pixelDepth)throw new Error('Targa::checkHeader() - Invalid pixel size "'+t.pixelDepth+'"');if(0!==t.alphaBits&&1!==t.alphaBits&&8!==t.alphaBits)throw new Error("Targa::checkHeader() - Unsuppported alpha size")}function n(t,e,i,r,o,n,a,s,l,d){var h,c,u,f,g,p,v=this.header.colorMapDepth>>3;for(f=0,p=o;p!==a;p+=n)for(g=s;g!==d;g+=l,f++)u=4*(g+r*p),c=e[f]*v,4===v?(t[u]=i[c+2],t[u+1]=i[c+1],t[u+2]=i[c],t[u+3]=i[c+3]):3===v?(t[u]=i[c+2],t[u+1]=i[c+1],t[u+2]=i[c],t[u+3]=255):2===v&&(h=i[c]|i[c+1]<<8,t[u]=(31744&h)>>7,t[u+1]=(992&h)>>2,t[u+2]=(31&h)<<3,t[u+3]=32768&h?0:255);return t}function a(t,e,i,r,o,n,a,s,l,d){var h,c,u,f,g;for(u=0,g=o;g!==a;g+=n)for(f=s;f!==d;f+=l,u+=2)h=e[u]|e[u+1]<<8,t[c=4*(f+r*g)]=(31744&h)>>7,t[c+1]=(992&h)>>2,t[c+2]=(31&h)<<3,t[c+3]=32768&h?0:255;return t}function s(t,e,i,r,o,n,a,s,l,d){var h,c,u,f,g=this.header.pixelDepth>>3;for(c=0,f=o;f!==a;f+=n)for(u=s;u!==d;u+=l,c+=g)t[(h=4*(u+r*f))+3]=255,t[h+2]=e[c],t[h+1]=e[c+1],t[h]=e[c+2];return t}function l(t,e,i,r,o,n,a,s,l,d){var h,c,u,f;for(h=0,u=o;u!==a;u+=n)for(c=s;c!==d;c+=l,h+=4)t[(f=4*(c+r*u))+2]=e[h],t[f+1]=e[h+1],t[f]=e[h+2],t[f+3]=e[h+3];return t}function d(t,e,i,r,o,n,a,s,l,d){var h,c,u,f,g;for(h=0,u=o;u!==a;u+=n)for(c=s;c!==d;c+=l,h+=4)f=4*(c+r*u),g=255*e[h+3],t[f+2]=e[h]/g,t[f+1]=e[h+1]/g,t[f]=e[h+2]/g,t[f+3]=e[h+3];return t}function h(t,e,i,r,o,n,a,s,l,d){var h,c,u,f,g;for(u=0,g=o;g!==a;g+=n)for(f=s;f!==d;f+=l,u++)h=e[u],t[c=4*(f+r*g)]=h,t[c+1]=h,t[c+2]=h,t[c+3]=255;return t}function c(t,e,i,r,o,n,a,s,l,d){var h,c,u,f,g;for(u=0,g=o;g!==a;g+=n)for(f=s;f!==d;f+=l,u+=2)h=e[u],t[c=4*(f+r*g)]=h,t[c+1]=h,t[c+2]=h,t[c+3]=e[u+1];return t}function u(t){var i=t.byteLength-e.FOOTER_SIZE,r=e.SIGNATURE,o={},n=new Uint8Array(t.buffer,i+8,r.length);return function(t){for(var i=e.SIGNATURE,r=0;r=t.byteLength)throw new Error("Targa::load() - No data");if(this.header.hasColorMap){var a=this.header.colorMapLength*(this.header.colorMapDepth>>3);this.palette=new Uint8Array(t,n,a),n+=a}var s=this.header.pixelDepth>>3,l=this.header.width*this.header.height,d=l*s;if(this.header.hasEncoding){var h=t.byteLength-n-e.FOOTER_SIZE,c=new Uint8Array(t,n,h);this.imageData=function(t,i,r){var o,n,a,s,l,d,h;for(h=new Uint8Array(r),d=new Uint8Array(i),l=0,o=0;or)throw new Error("Targa::decodeRLE() - Read bytes: "+o+" Expected bytes: "+r);return h}(c,s,d)}else this.imageData=new Uint8Array(t,n,this.header.hasColorMap?l:d);this.footer=u(i),(0!==this.header.alphaBits||this.footer.hasExtensionArea&&(3===this.footer.attributeType||4===this.footer.attributeType))&&(this.footer.usesAlpha=!0)},e.prototype.getImageData=function(t){var i,r,o,u,f,g,p,v=this.header.width,y=this.header.height,m=(this.header.flags&e.Origin.MASK)>>e.Origin.SHIFT;switch(t||(t=document?document.createElement("canvas").getContext("2d").createImageData(v,y):{width:v,height:y,data:new Uint8ClampedArray(v*y*4)}),m===e.Origin.TOP_LEFT||m===e.Origin.TOP_RIGHT?(u=0,f=1,g=y):(u=y-1,f=-1,g=-1),m===e.Origin.TOP_LEFT||m===e.Origin.BOTTOM_LEFT?(i=0,r=1,o=v):(i=v-1,r=-1,o=-1),this.header.pixelDepth){case 8:p=this.header.isGreyColor?h:n;break;case 16:p=this.header.isGreyColor?c:a;break;case 24:p=s;break;case 32:p=this.footer.hasExtensionArea?3===this.footer.attributeType?l:4===this.footer.attributeType?d:s:0!==this.header.alphaBits?l:s}return p.call(this,t.data,this.imageData,this.palette,v,u,f,g,i,r,o),t},e.prototype.setImageData=function(t){if(!t)throw new Error("Targa::setImageData() - imageData argument missing");var i,r,o,n,a,s,d=this.header.width,h=this.header.height,c=d*h*(this.header.pixelDepth>>3),u=(this.header.flags&e.Origin.MASK)>>e.Origin.SHIFT;u===e.Origin.TOP_LEFT||u===e.Origin.TOP_RIGHT?(n=0,a=1,s=h):(n=h-1,a=-1,s=-1),u===e.Origin.TOP_LEFT||u===e.Origin.BOTTOM_LEFT?(i=0,r=1,o=d):(i=d-1,r=-1,o=-1),this.imageData||(this.imageData=new Uint8Array(c)),l(this.imageData,t.data,this.palette,d,n,a,s,i,r,o);var f=this.imageData;this.header.hasEncoding&&(f=function(t,i){for(var r,o,n,a,s=i,l=[],d=0,h=t.pixelDepth>>3,c=0,u=t.width*t.height*h,f=function(t,e){for(var i=0;ia.units.RADIAN)throw new Error("unit parameter needs CODE.units");this.unit=t}},o.prototype.getInstantiateObj=function(){return this.instantiateObj},o.prototype.setInstantiateObj=function(t){this.instantiateObj=t},o.prototype.getStaticModelAttributeObj=function(){return this.staticModelAttributeObj},o.prototype.setStaticModelAttributeObj=function(t){this.staticModelAttributeObj=t},o.prototype.getAnimationOption=function(){return this.animationOption},o.prototype.setAnimationOption=function(t){this.animationOption=t};var n=function(){if(!(this instanceof n))throw new Error(z.CONSTRUCT_ERROR);this.moveHistory=!1,this.colorHistory=!1,this.rotationHistory=!1,this.objectMoveMode=null,this.projectId=null,this.projectDataFolder=null,this.dataKey=null,this.objectId=null,this.objectIndexOrder=0,this.refObjectAditionalMove,this.refObjectAditionalMoveRelToBuilding,this.latitude=0,this.longitude=0,this.elevation=0,this.heading=0,this.pitch=0,this.roll=0,this.duration=0,this.color=0,this.rgbColor=[],this.property=null,this.propertyKey=null,this.propertyValue=null};n.prototype.getReferenceObjectAditionalMovement=function(){return void 0===this.refObjectAditionalMove&&(this.refObjectAditionalMove=new Ae),this.refObjectAditionalMove},n.prototype.getReferenceObjectAditionalMovementRelToBuilding=function(){return void 0===this.refObjectAditionalMoveRelToBuilding&&(this.refObjectAditionalMoveRelToBuilding=new Ae),this.refObjectAditionalMoveRelToBuilding},n.prototype.getProjectId=function(){return this.projectId},n.prototype.setProjectId=function(t){this.projectId=t},n.prototype.getProjectDataFolder=function(){return this.projectDataFolder},n.prototype.setProjectDataFolder=function(t){this.projectDataFolder=t},n.prototype.getDataKey=function(){return this.dataKey},n.prototype.setDataKey=function(t){this.dataKey=t},n.prototype.getObjectId=function(){return this.objectId},n.prototype.setObjectId=function(t){this.objectId=t},n.prototype.getObjectIndexOrder=function(){return this.objectIndexOrder},n.prototype.setObjectIndexOrder=function(t){this.objectIndexOrder=t},n.prototype.getLatitude=function(){return this.latitude},n.prototype.setLatitude=function(t){this.latitude=t},n.prototype.getLongitude=function(){return this.longitude},n.prototype.setLongitude=function(t){this.longitude=t},n.prototype.getElevation=function(){return this.elevation},n.prototype.setElevation=function(t){this.elevation=t},n.prototype.getHeading=function(){return this.heading},n.prototype.setHeading=function(t){this.heading=t},n.prototype.getPitch=function(){return this.pitch},n.prototype.setPitch=function(t){this.pitch=t},n.prototype.getRoll=function(){return this.roll},n.prototype.setRoll=function(t){this.roll=t},n.prototype.getColor=function(){return this.color},n.prototype.setColor=function(t){this.color=t},n.prototype.getRgbColor=function(){return this.rgbColor},n.prototype.setRgbColor=function(t){this.rgbColor=t},n.prototype.getProperty=function(){return this.property},n.prototype.setProperty=function(t){this.property=t},n.prototype.getPropertyKey=function(){return this.propertyKey},n.prototype.setPropertyKey=function(t){this.propertyKey=t},n.prototype.getPropertyValue=function(){return this.propertyValue},n.prototype.setPropertyValue=function(t){this.propertyValue=t},n.prototype.getDuration=function(){return this.duration},n.prototype.setDuration=function(t){this.duration=t},n.prototype.getObjectMoveMode=function(){return this.objectMoveMode},n.prototype.setObjectMoveMode=function(t){this.objectMoveMode=t};var a={magoManagerState:{INIT:0,STARTED:1,READY:2},fileLoadState:{READY:0,LOADING_STARTED:1,LOADING_FINISHED:2,PARSE_STARTED:3,PARSE_FINISHED:4,IN_QUEUE:5,LOAD_FAILED:6},moveMode:{ALL:"0",OBJECT:"1",GEOGRAPHICPOINTS:"2",NONE:"3"},magoMode:{NORMAL:0,DRAWING:1},modelerMode:{INACTIVE:0,DRAWING_POLYLINE:1,DRAWING_PLANEGRID:2,DRAWING_GEOGRAPHICPOINTS:3,DRAWING_EXCAVATIONPOINTS:4,DRAWING_TUNNELPOINTS:5,DRAWING_STATICGEOMETRY:6},modelerDrawingState:{NO_STARTED:0,STARTED:1},modelerDrawingElement:{NOTHING:0,POINTS:1,LINES:2,POLYLINES:3,GEOGRAPHICPOINTS:4},units:{METRE:0,DEGREE:1,RADIAN:2},PROJECT_ID_PREFIX:"projectId_",PROJECT_DATA_FOLDER_PREFIX:"projectDataFolder_"},s={CESIUM:"cesium",WORLDWIND:"worldwind",MAGOWORLD:"magoworld",OBJECT_INDEX_FILE:"/objectIndexFile.ihe",CACHE_VERSION:"?cache_version=",SIMPLE_BUILDING_TEXTURE3x3_BMP:"/SimpleBuildingTexture3x3.bmp",RESULT_XDO2F4D:"/Result_xdo2f4d/Images/",RESULT_XDO2F4D_TERRAINTILES:"/Result_xdo2f4d/F4D_TerrainTiles/",RESULT_XDO2F4D_TERRAINTILEFILE_TXT:"/Result_xdo2f4d/f4dTerranTileFile.txt",INTERSECTION_OUTSIDE:0,INTERSECTION_INTERSECT:1,INTERSECTION_INSIDE:2,INTERSECTION_POINT_A:3,INTERSECTION_POINT_B:4},l={getPolicy:function(){return this.serverPolicy},getData:function(t){return this.dataObject[t]},isDataExist:function(t){return this.dataObject.hasOwnProperty(t)},deleteData:function(t){return delete this.dataObject[t]},setData:function(t,e){this.isDataExist(t)||(this.dataObject[t]=e)},getProjectDataFolder:function(t){var e=a.PROJECT_DATA_FOLDER_PREFIX+t;return this.dataObject[e]},isProjectDataFolderExist:function(t){var e=a.PROJECT_DATA_FOLDER_PREFIX+t;return this.dataObject.hasOwnProperty(e)},deleteProjectDataFolder:function(t){var e=a.PROJECT_DATA_FOLDER_PREFIX+t;return delete this.dataObject[e]},setProjectDataFolder:function(t,e){var i=a.PROJECT_DATA_FOLDER_PREFIX+t;this.isProjectDataFolderExist(i)||(this.dataObject[i]=e)},init:function(t,e,i){if(this.dataObject={},this.selectHistoryObject={},this.movingHistoryObject={},this.colorHistoryObject={},this.locationAndRotationHistoryObject={},this.serverPolicy=t,null!==e&&e.length>0)for(var r=0;rthis.maxX&&(this.maxX=t.x),t.ythis.maxY&&(this.maxY=t.y),t.zthis.maxZ&&(this.maxZ=t.z))},v.prototype.addBox=function(t){void 0!==t&&(t.minXthis.maxX&&(this.maxX=t.maxX),t.minYthis.maxY&&(this.maxY=t.maxY),t.minZthis.maxZ&&(this.maxZ=t.maxZ))},v.prototype.getMinLength=function(){return Math.min(this.maxX-this.minX,this.maxY-this.minY,this.maxZ-this.minZ)},v.prototype.getMaxLength=function(){return Math.max(this.maxX-this.minX,this.maxY-this.minY,this.maxZ-this.minZ)},v.prototype.getXLength=function(){return this.maxX-this.minX},v.prototype.getYLength=function(){return this.maxY-this.minY},v.prototype.getZLength=function(){return this.maxZ-this.minZ},v.prototype.getCenterPoint=function(t){return void 0===t&&(t=new Ae),t.set((this.maxX+this.minX)/2,(this.maxY+this.minY)/2,(this.maxZ+this.minZ)/2),t},v.prototype.getRadiusAprox=function(){return this.getMaxLength()/1.5},v.prototype.intersectWithPoint=function(t){return void 0!==t&&!(t.xthis.maxX||t.ythis.maxY||t.zthis.maxZ)},v.prototype.isPoint3dInside=function(t,e,i){return!(tthis.maxX)&&(!(ethis.maxY)&&!(ithis.maxZ))},v.prototype.intersectWithBox=function(t){return void 0!==t&&!(t.minX>this.maxX||t.maxXthis.maxY||t.maxYthis.maxZ||t.maxZt.maxX?e=!1:this.maxYt.maxY?e=!1:this.maxZt.maxZ&&(e=!1),e};var y=function(){if(!(this instanceof y))throw new Error(z.CONSTRUCT_ERROR);this.center=new Ae,this.radius=0},m=function(t,e,i){if(!(this instanceof m))throw new Error(z.CONSTRUCT_ERROR);this.mesh,this.vbo_vicks_container,this.vbo_vicks_containerEdges,this.centerPoint,this.width,this.length,this.height,void 0!==t&&(this.width=t),void 0!==e&&(this.length=e),void 0!==i&&(this.height=i)};m.prototype.getVboKeysContainer=function(){return this.vbo_vicks_container},m.prototype.render=function(t,e,i){void 0!==this.mesh?this.mesh.render(t,e,i):this.mesh=this.makeMesh(this.width,this.length,this.height)},m.prototype.makeMesh=function(t,e,i){void 0!==t&&(this.width=t),void 0!==e&&(this.length=e),void 0!==i&&(this.height=i),void 0===this.width&&(this.width=1),void 0===this.length&&(this.length=1),void 0===this.height&&(this.height=1),void 0===this.centerPoint&&(this.centerPoint=new Ae(0,0,0)),void 0===this.vbo_vicks_container&&(this.vbo_vicks_container=new vt),void 0===this.vbo_vicks_containerEdges&&(this.vbo_vicks_containerEdges=new vt);var r=new ye;r.profile=new _e;var o=r.profile,n=o.newOuterRing().newElement("RECTANGLE");n.setCenterPosition(this.centerPoint.x,this.centerPoint.y),n.setDimensions(this.width,this.length);r.extrude(o,this.height,1,void 0);var a=r.getSurfaceIndependentMesh(void 0,!0,!0);return a.translate(0,0,-this.height/2),a};var x,b=function(){if(!(this instanceof b))throw new Error(z.CONSTRUCT_ERROR);this.fisrtName,this.name="",this.buildingId,this.buildingFileName,this.geographicCoord,this.rotationsDegree,this.bBox,this.geographicCoordOfBBox,this.smartTileOwner};b.prototype.deleteObjects=function(){this.fisrtName=void 0,this.name=void 0,this.buildingId=void 0,this.buildingFileName=void 0,this.geographicCoord.deleteObjects(),this.rotationsDegree.deleteObjects(),this.bBox.deleteObjects(),this.geographicCoordOfBBox.deleteObjects(),this.geographicCoord=void 0,this.rotationsDegree=void 0,this.bBox=void 0,this.geographicCoordOfBBox=void 0},(x=function(){if(!(this instanceof x))throw new Error(z.CONSTRUCT_ERROR);this.buildingSeedArray=[],this.minGeographicCoord,this.maxGeographicCoord,this.dataArrayBuffer}).prototype.deleteObjects=function(){if(this.minGeographicCoord.deleteObjects(),this.maxGeographicCoord.deleteObjects(),this.minGeographicCoord=void 0,this.maxGeographicCoord=void 0,this.buildingSeedArray){for(var t=this.buildingSeedArray.length,e=0;e0?this.heading>=this.targetHeading&&(this.heading=this.targetHeading,this.targetHeading=void 0):this.heading<=this.targetHeading&&(this.heading=this.targetHeading,this.targetHeading=void 0),0===this.headingAngularSpeed&&(this.targetHeading=void 0,this.headingAngularSpeed=void 0)),void 0!==this.pitchAngularSpeed&&(this.pitch+=e*this.pitchAngularSpeed,this.pitchAngularSpeed>0?this.pitch>=this.targetPitch&&(this.pitch=this.targetPitch,this.targetPitch=void 0):this.pitch<=this.targetPitch&&(this.pitch=this.targetPitch,this.targetPitch=void 0),0===this.pitchAngularSpeed&&(this.targetPitch=void 0,this.pitchAngularSpeed=0)),void 0!==this.rollAngularSpeed&&(this.roll+=e*this.rollAngularSpeed,this.rollAngularSpeed>0?this.roll>=this.targetRoll&&(this.roll=this.targetRoll,this.targetRoll=void 0):this.roll<=this.targetRoll&&(this.roll=this.targetRoll,this.targetRoll=void 0),0===this.rollAngularSpeed&&(this.targetRoll=void 0,this.rollAngularSpeed=void 0)),this.calculateRotationMatrix()}},M.prototype.updateHeading=function(t){void 0===this.lastTime&&(this.lastTime=t);var e=(t-this.lastTime)/1e3;this.heading+=e*this.headingAngularSpeed,this.heading>this.maxHeading?(this.heading=this.maxHeading,this.headingAngularSpeed*=-1):this.heading.5&&(this.greenFactor=.5,this.greenFactorSpeed*=-1),this.greenFactor<0&&(this.greenFactor=0,this.greenFactorSpeed*=-1),this.blueFactor>.9&&(this.blueFactor=.9,this.blueFactorSpeed*=-1),this.blueFactor<0&&(this.blueFactor=0,this.blueFactorSpeed*=-1),this.alphaFactor>.6&&(this.alphaFactor=.6,this.alphaFactorSpeed*=-1),this.alphaFactor<0&&(this.alphaFactor=0,this.alphaFactorSpeed*=-1),this.color.setRGBA(0,this.greenFactor,this.blueFactor,this.alphaFactor)},M.prototype.calculateRotationMatrix=function(){var t;t=k.getRotationDegZXYMatrix(this.heading,this.pitch,this.roll,t),this.rotMat=t.getMultipliedByMatrix(this.geoLocationData.rotMatrix,this.rotMat)},M.prototype.getVbo=function(t,e,i){var r;void 0===t&&(t=new vt),void 0===this.vboKeyContainerEdges&&(this.vboKeyContainerEdges=new vt),r=this.makeFrustumGeometry_2(r);var o=new k,n=this.camera.bigFrustum.fovyRad/2;o.rotationAxisAngDeg(180*-n/Math.PI,1,0,0);var a=r.getSurfaceIndependentMesh(void 0,!0,!0);return a.transformByMatrix4(o),a.setColor(0,.5,.9,.3),a.getVbo(t,i),a.getVboEdges(this.vboKeyContainerEdges,i),t},M.prototype.render=function(t,e,i){if(void 0!==this.vboKeyContainer){var r;this.vboKeyContainer.vboCacheKeysArray.length;t.uniformMatrix4fv(i.buildingRotMatrix_loc,!1,this.geoLocationData.rotMatrix._floatArrays),t.uniform3fv(i.buildingPosHIGH_loc,this.geoLocationData.positionHIGH),t.uniform3fv(i.buildingPosLOW_loc,this.geoLocationData.positionLOW),t.uniform1i(i.hasTexture_loc,!1),t.enable(t.POLYGON_OFFSET_FILL),t.polygonOffset(1,3);t.uniform1i(i.refMatrixType_loc,2),t.uniformMatrix4fv(i.refMatrix_loc,!1,this.rotMat._floatArrays);var o=e.renderer;r=!0,o.renderNormals=!1,t.uniform4fv(i.oneColor4_loc,[0,0,0,1]),o.renderVboContainer(t,this.vboKeyContainerEdges,e,i,r),t.enable(t.BLEND),r=!1,o.renderNormals=!0,t.uniform4fv(i.oneColor4_loc,[this.blueFactor,0,0,this.alphaFactor]),o.renderVboContainer(t,this.vboKeyContainer,e,i,r),t.disable(t.BLEND),t.disable(t.POLYGON_OFFSET_FILL)}},M.prototype.makeFrustumGeometry_2=function(t){void 0===t&&(t=new ye),t.profile=new _e;var e,i,r=t.profile,o=this.camera.bigFrustum,n=o.far,a=o.fovyRad/2,s=o.fovRad/2,l=(Math.tan(s),Math.tan(a),r.newOuterRing());(e=l.newElement("POLYLINE")).newPoint2d(-n*Math.sin(s),n*Math.cos(s)),e.newPoint2d(0,0),e.newPoint2d(n*Math.sin(s),n*Math.cos(s));var d,h,c=90-180*s/Math.PI,u=90+180*s/Math.PI;i=l.newElement("ARC"),this.sweepSense=1,i.setCenterPosition(0,0),i.setRadius(n),i.setStartAngleDegree(c),i.setSweepAngleDegree(u-c),i.numPointsFor360Deg=36,d=2*a*180/Math.PI,h=new Ie;var f=new xe(-1,0),g=new xe(1,0);return h.setPoints(f,g),6,t.revolve(r,d,6,h),t},M.prototype.makeFrustumGeometry=function(t){void 0===t&&(t=new pe),void 0===t.hedgesList&&(t.hedgesList=new le);var e,i,r,o,n,a,s=new Ae(0,0,0),l=this.camera.bigFrustum,d=l.far,h=l.fovyRad/2,c=l.fovRad/2,u=-d*Math.tan(c),f=-u,g=d*Math.tan(h),p=-g,v=new Ae(u,p,-d),y=new Ae(f,p,-d),m=new Ae(f,g,-d),x=new Ae(u,g,-d),b=new ke(s),C=new ke(v),A=new ke(y),M=new ke(m),P=new ke(x);void 0===this.vboKeyContainerEdges&&(this.vboKeyContainerEdges=new vt),(e=t.newSurface().newFace()).addVertex(C),e.addVertex(P),e.addVertex(M),e.addVertex(A);for(var T=0,w=[],_=[],S=e.vertexArray.length,R=0;R1?t=1:t<0&&(t=0),i=1-t,r=t>.5?2*-t+2:2*t,o=t,e.setRGB(i,r,o),e},P.prototype.copyFrom=function(t){this.r=t.r,this.g=t.g,this.b=t.b,this.a=t.a},P.prototype.deleteObjects=function(){this.r=void 0,this.g=void 0,this.b=void 0,this.a=void 0},P.prototype.set=function(t,e,i,r){this.r=t,this.g=e,this.b=i,this.a=r},P.prototype.setRGB=function(t,e,i){this.r=t,this.g=e,this.b=i},P.prototype.setRGBA=function(t,e,i,r){this.r=t,this.g=e,this.b=i,this.a=r},(Q=function(){if(!(this instanceof Q))throw new Error(z.CONSTRUCT_ERROR);this.color=new P}).prototype.init=function(){this.color.r=0,this.color.g=0,this.color.b=0,this.cycle=0},Q.prototype.getAvailableColor=function(t){return void 0===t&&(t=new P),t.setRGB(this.color.r,this.color.g,this.color.b),this.color.b+=1,this.color.b>=254&&(this.color.b=0,this.color.g+=1,this.color.g>=254&&(this.color.g=0,this.color.r+=1,this.color.r>=254&&(this.color.r=0,this.cycle+=1))),t},Q.prototype.decodeColor3=function(t,e,i){return 64516*t+254*e+i};var T=function(t,e,i){if(!(this instanceof T))throw new Error(z.CONSTRUCT_ERROR);if(this.gl=t,this.width=new Int32Array(1),this.height=new Int32Array(1),this.fbo=t.createFramebuffer(),this.depthBuffer=t.createRenderbuffer(),this.colorBuffer=t.createTexture(),this.dirty=!0,this.width[0]=e,this.height[0]=i,t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,this.colorBuffer),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,e[0],i[0],0,t.RGBA,t.UNSIGNED_BYTE,null),t.bindFramebuffer(t.FRAMEBUFFER,this.fbo),t.bindRenderbuffer(t.RENDERBUFFER,this.depthBuffer),t.renderbufferStorage(t.RENDERBUFFER,t.DEPTH_COMPONENT16,e[0],i[0]),t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_ATTACHMENT,t.RENDERBUFFER,this.depthBuffer),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,this.colorBuffer,0),t.checkFramebufferStatus(t.FRAMEBUFFER)!==t.FRAMEBUFFER_COMPLETE)throw"Incomplete frame buffer object.";t.bindFramebuffer(t.FRAMEBUFFER,null)};T.prototype.bind=function(){this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,this.fbo)},T.prototype.unbind=function(){this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,null)},T.prototype.deleteObjects=function(t){this.depthBuffer&&t.deleteRenderbuffer(this.depthBuffer),this.depthBuffer=void 0,this.colorBuffer&&t.deleteTexture(this.colorBuffer),this.colorBuffer=void 0,this.fbo&&t.deleteFramebuffer(this.fbo),this.fbo=void 0},T.createBuffer=function(t,e){const i=t.createBuffer();return t.bindBuffer(t.ARRAY_BUFFER,i),t.bufferData(t.ARRAY_BUFFER,e,t.STATIC_DRAW),i},T.bindFramebuffer=function(t,e,i){t.bindFramebuffer(t.FRAMEBUFFER,e),i&&t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,i,0)},T.bindAttribute=function(t,e,i,r){t.bindBuffer(t.ARRAY_BUFFER,e),t.enableVertexAttribArray(i),t.vertexAttribPointer(i,r,t.FLOAT,!1,0,0)},T.bindTexture=function(t,e,i){t.activeTexture(t.TEXTURE0+i),t.bindTexture(t.TEXTURE_2D,e)};var w=function(){if(!(this instanceof w))throw new Error(z.CONSTRUCT_ERROR);this.maxFilesRequestedCount=1,this.filesRequestedCount=0,this.headerFilesRequestedCount=0,this.modelRefFilesRequestedCount=0,this.lowLodDataRequestedCount=0,this.lowLodImagesRequestedCount=0};w.prototype.isFull=function(){return this.filesRequestedCount>=this.maxFilesRequestedCount},w.prototype.isFullHeaders=function(){return this.headerFilesRequestedCount>=1},w.prototype.isFullPlus=function(t){return void 0===t&&(t=0),this.filesRequestedCount>=this.maxFilesRequestedCount+t},w.prototype.isFullPlusModelReferences=function(t){return void 0===t&&(t=0),this.modelRefFilesRequestedCount>=this.maxFilesRequestedCount+t},w.prototype.isFullPlusLowLodData=function(t){return void 0===t&&(t=0),this.lowLodDataRequestedCount>=this.maxFilesRequestedCount+t},w.prototype.isFullPlusLowLodImages=function(t){return void 0===t&&(t=0),this.lowLodImagesRequestedCount>=this.maxFilesRequestedCount+t};var _={moveForward:!1,moveBackward:!1,moveLeft:!1,moveRight:!1};function S(t){switch(t){case 37:return"moveLeft";case 38:return"moveForward";case 39:return"moveRight";case 40:return"moveBackward";default:return}}function R(t){var e=S(t.keyCode);void 0!==e&&(_[e]=!0)}function L(t){var e=S(t.keyCode);void 0!==e&&(_[e]=!1)}function D(){this._camera=void 0,this._cameraBAK=void 0,this._position=new Ae,this._rotation=new Ae,this._positionSpeed=1,this._ratationSpeed=1}Object.defineProperties(D.prototype,{camera:{get:function(){return this._camera},set:function(t){this._camera=t}},position:{get:function(){return this._position},set:function(t){this._position=t}},rotation:{get:function(){return this._rotation},set:function(t){this._rotation=t}},positionSpeed:{get:function(){return this._positionSpeed},set:function(t){this._positionSpeed=t}},rotationSpeed:{get:function(){return this._ratationSpeed},set:function(t){this._ratationSpeed=t}}}),D.prototype.init=function(){this._position.set(0,0,0),this._rotation.set(0,0,0),document.addEventListener("keydown",R,!1),document.addEventListener("keyup",L,!1)},D.prototype.release=function(){this._camera=void 0,this._cameraBAK=void 0,document.removeEventListener("keydown",R,!1),document.removeEventListener("keyup",L,!1)},D.prototype.move=function(t){var e=glMatrix.vec3.fromValues(this._position.x,this._position.y,this.position.z),i=glMatrix.mat4.create();glMatrix.mat4.rotateY(i,i,this._rotation.y),glMatrix.vec3.transformMat4(t,t,i),glMatrix.vec3.add(e,e,t),this._position.set(e[0],e[1],e[2])},D.prototype.update=function(t){void 0!==this._camera&&(_.moveForward&&(this._camera.moveForward(.5),this.move(vec3.fromValues(0,1,0))),_.moveBackward&&(this._camera.moveBackward(.5),this.move(vec3.fromValues(0,-1,0))),_.moveLeft&&(this._camera.lookLeft(.1),this.move(vec3.fromValues(-1,0,0))),_.moveRight&&(this._camera.lookRight(.1),this.move(vec3.fromValues(1,0,0))))};var I=function(){if(!(this instanceof I))throw new Error(z.CONSTRUCT_ERROR);this.near=new Float32Array([.1]),this.far=new Float32Array([1e3]),this.fovyRad=new Float32Array([.8037]),this.tangentOfHalfFovy=new Float32Array([0]),this.fovRad=new Float32Array([1.047]),this.aspectRatio=new Float32Array([1.3584]),this.planesArray=[],this.dirty=!0;for(var t=0;t<6;t++){var e=new Z;this.planesArray.push(e)}};I.prototype.copyParametersFrom=function(t){this.near[0]=t.near[0],this.far[0]=t.far[0],this.fovyRad[0]=t.fovyRad[0],this.tangentOfHalfFovy[0]=t.tangentOfHalfFovy[0],this.fovRad[0]=t.fovRad[0],this.aspectRatio[0]=t.aspectRatio[0]},I.prototype.setNear=function(t){this.near[0]=t},I.prototype.setFar=function(t){this.far[0]=t},I.prototype.intersectionNearFarSphere=function(t){for(var e=!1,i=0;i<2;i++){var r=this.planesArray[i].intersectionSphere(t);if(r===s.INTERSECTION_OUTSIDE)return s.INTERSECTION_OUTSIDE;r===s.INTERSECTION_INTERSECT&&(e=!0)}return e?s.INTERSECTION_INTERSECT:s.INTERSECTION_INSIDE},I.prototype.intersectionSphere=function(t){for(var e=!1,i=0;i<6;i++){var r=this.planesArray[i].intersectionSphere(t);if(r===s.INTERSECTION_OUTSIDE)return s.INTERSECTION_OUTSIDE;r===s.INTERSECTION_INTERSECT&&(e=!0)}return e?s.INTERSECTION_INTERSECT:s.INTERSECTION_INSIDE};var E=function(){if(!(this instanceof E))throw new Error(z.CONSTRUCT_ERROR);this.frustumVolumensMap={}};E.prototype.getFrustumVolumeCulling=function(t){return this.frustumVolumensMap.hasOwnProperty(t)||(this.frustumVolumensMap[t]={},this.frustumVolumensMap[t].fullyIntersectedLowestTilesArray=[],this.frustumVolumensMap[t].partiallyIntersectedLowestTilesArray=[],this.frustumVolumensMap[t].visibleNodes=new yt),this.frustumVolumensMap[t]},E.prototype.initArrays=function(){var t;for(var e in this.frustumVolumensMap)Object.prototype.hasOwnProperty.call(this.frustumVolumensMap,e)&&((t=this.frustumVolumensMap[e]).fullyIntersectedLowestTilesArray.length=0,t.partiallyIntersectedLowestTilesArray.length=0,t.visibleNodes.initArrays())};var O,F=function(t,e,i){if(!(this instanceof F))throw new Error(z.CONSTRUCT_ERROR);this.longitude,this.latitude,this.altitude,void 0!==t&&(this.longitude=t),void 0!==e&&(this.latitude=e),void 0!==i&&(this.altitude=i),this.absolutePoint,this.vboKeysContainer,this.geoLocDataManager,this.owner};F.prototype.deleteObjects=function(t){this.longitude=void 0,this.latitude=void 0,this.altitude=void 0,void 0!==this.absolutePoint&&(this.absolutePoint.deleteObjects(),this.absolutePoint=void 0),void 0!==this.vboKeysContainer&&this.vboKeysContainer.deleteGlObjects(t.gl,t),void 0!==this.geoLocDataManager&&this.geoLocDataManager.deleteObjects(),this.owner=void 0},F.prototype.getWgs84Point3D=function(t){var e=j.geographicToCartesianWgs84(this.longitude,this.latitude,this.altitude,void 0);return void 0===t&&(t=new Ae),t.set(e[0],e[1],e[2]),t},F.prototype.getMercatorProjection=function(t){return j.geographicToMercatorProjection(this.longitude,this.latitude,t)},F.prototype.getGeoLocationDataManager=function(){return void 0===this.geoLocDataManager&&(this.geoLocDataManager=new N),this.geoLocDataManager},F.prototype.copyFrom=function(t){this.longitude=t.longitude,this.latitude=t.latitude,this.altitude=t.altitude},F.prototype.setLonLatAlt=function(t,e,i){void 0!==t&&(this.longitude=t),void 0!==e&&(this.latitude=e),void 0!==i&&(this.altitude=i)},F.getMidPoint=function(t,e,i){var r=(t.latitude+e.latitude)/2,o=(t.longitude+e.longitude)/2,n=(t.altitude+e.altitude)/2;return void 0===i?i=new F(o,r,n):i.setLonLatAlt(o,r,n),i},F.prototype.prepareData=function(t){if(void 0===this.vboKeysContainer&&(this.vboKeysContainer=new vt),0===this.vboKeysContainer.getVbosCount()){var e=this.vboKeysContainer.newVBOVertexIdxCacheKey(),i=new Float32Array([0,0,0]);e.setDataArrayPos(i,t)}return!0},F.prototype.renderPoint=function(t,e,i,r){if(!this.prepareData(t.vboMemoryManager))return!1;if(this.geoLocDataManager.getCurrentGeoLocationData().bindGeoLocationUniforms(i,e),2===r){var o=t.selectionManager,n=t.selectionColor,a=n.getAvailableColor(void 0),s=n.decodeColor3(a.r,a.g,a.b);o.setCandidateGeneral(s,this),i.uniform4fv(e.oneColor4_loc,[a.r/255,a.g/255,a.b/255,1])}var l=this.vboKeysContainer.vboCacheKeysArray[0];if(!l.bindDataPosition(e,t.vboMemoryManager))return!1;i.drawArrays(i.POINTS,0,l.vertexCount)},(O=function(){if(!(this instanceof O))throw new Error(z.CONSTRUCT_ERROR);this.geographicCoordsArray=[],this.vboKeysContainer,this.owner,this.points3dList}).prototype.addGeoCoord=function(t){this.geographicCoordsArray.push(t),t.owner=this},O.prototype.getGeoCoord=function(t){if(void 0!==this.geographicCoordsArray)return this.geographicCoordsArray[t]},O.prototype.getGeoCoordsCount=function(){return void 0===this.geographicCoordsArray?0:this.geographicCoordsArray.length},O.prototype.getPointsRelativeToGeoLocation=function(t,e){void 0===e&&(e=[]);for(var i=this.getGeoCoordsCount(),r=0;r=0&&c.y>=0){var u="lon: "+o.longitude.toFixed(5)+", lat: "+o.latitude.toFixed(5);d.strokeText(u,c.x,c.y),d.fillText(u,c.x,c.y)}}d.restore()},O.prototype.getWgs84Points3D=function(t){void 0===t&&(t=[]);for(var e=this.geographicCoordsArray.length,i=0;i=0&&c.y>=0){var u="lon: "+o.longitude.toFixed(5)+", lat: "+o.latitude.toFixed(5);d.strokeText(u,c.x,c.y),d.fillText(u,c.x,c.y)}}d.restore()},O.prototype.getWgs84Points3D=function(t){void 0===t&&(t=[]);for(var e=this.geographicCoordsArray.length,i=0;ithis.geoLocationDataArrayMaxLengthAllowed&&this.geoLocationDataArray.pop(),e},N.prototype.getGeoLocationDatasCount=function(){return this.geoLocationDataArray.length},N.prototype.getGeoLocationData=function(t){if(!(t>this.geoLocationDataArray.length-1))return this.geoLocationDataArray[t]},N.prototype.getCurrentGeoLocationData=function(){if(0!==this.geoLocationDataArray.length)return this.geoLocationDataArray[0]},(N=function(){if(!(this instanceof N))throw new Error(z.CONSTRUCT_ERROR);this.geoLocationDataArray=[],this.geoLocationDataArrayMaxLengthAllowed=15}).prototype.deleteObjects=function(){if(this.geoLocationDataArray){for(var t=0;tthis.geoLocationDataArrayMaxLengthAllowed&&this.geoLocationDataArray.pop(),e},N.prototype.getGeoLocationDatasCount=function(){return this.geoLocationDataArray.length},N.prototype.getGeoLocationData=function(t){if(!(t>this.geoLocationDataArray.length-1))return this.geoLocationDataArray[t]},N.prototype.getCurrentGeoLocationData=function(){if(0!==this.geoLocationDataArray.length)return this.geoLocationDataArray[0]};var j=function(){if(!(this instanceof j))throw new Error(z.CONSTRUCT_ERROR);this.equatorialRadius=6378137,this.polarRadius=6356752.3142,this.firstEccentricitySquared=.00669437999014,this.secondEccentricitySquared=.00673949674228,this.degToRadFactor=Math.PI/180};j.equatorialRadius=function(){return 6378137},j.equatorialRadiusSquared=function(){return 40680631590769},j.polarRadius=function(){return 6356752.3142},j.polarRadiusSquared=function(){return 40408299984087.055},j.radiusAtLatitudeDeg=function(t){var e=t*Math.PI/180,i=j.equatorialRadius(),r=j.polarRadius(),o=j.equatorialRadiusSquared(),n=j.polarRadiusSquared(),a=Math.sin(e),s=Math.cos(e),l=a*a,d=s*s;return i*r/Math.sqrt(o*l+n*d)},j.prototype.normalizeCartesian=function(t){if(void 0!==t){var e=Math.sqrt(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);return t[0]/=e,t[1]/=e,t[2]/=e,t}},j.prototype.transformMatrixAtCartesianPointWgs84=function(t,e,i,r){var o,n;n=this.normalAtCartesianPointWgs84(t,e,i,n),(o=new Float32Array(3))[0]=-e,o[1]=t,o[2]=0,o=this.normalizeCartesian(o);var a=new Ae(o[0],o[1],o[2]),s=new Ae,l=new Ae(n[0],n[1],n[2]);return s=l.crossProduct(a,s),void 0===r&&(r=new Float32Array(16)),r[0]=a.x,r[1]=a.y,r[2]=a.z,r[3]=0,r[4]=s.x,r[5]=s.y,r[6]=s.z,r[7]=0,r[8]=l.x,r[9]=l.y,r[10]=l.z,r[11]=0,r[12]=t,r[13]=e,r[14]=i,r[15]=1,r},j.prototype.intersectionLineWgs84=function(t,e,i){var r=t.point,o=t.direction,n=new Ae(r.x+1e3*o.x,r.y+1e3*o.y,r.z+1e3*o.z),a=r.x,s=r.y,l=r.z,d=n.x,h=n.y,c=n.z,u=this.equatorialRadius;void 0!==i&&(u=i);var f=d-a,g=h-s,p=c-l,v=f*f+g*g+p*p,y=2*(f*(a-0)+g*(s-0)+p*(l-0)),m=y*y-4*v*(0+a*a+s*s+l*l-2*(0*a+0*s+0*l)-u*u);if(!(m<0)){if(0===m){void 0===e&&(e=[]);var x=new Ae(a+(d-a)*(b=-y/(2*v)),s+(h-s)*b,l+(c-l)*b);e[0]=x.x,e[1]=x.y,e[2]=x.z}else{var b,C=Math.sqrt(m),A=(-y-C)/(2*v),M=(x=new Ae(a+(d-a)*(b=(-y+C)/(2*v)),s+(h-s)*b,l+(c-l)*b),new Ae(a+(d-a)*A,s+(h-s)*A,l+(c-l)*A)),P=r.squareDistToPoint(x),T=r.squareDistToPoint(M);void 0===e&&(e=[]),P0?Math.atan(t/e):e<0?t>=0?Math.atan(t/e)+i:Math.atan(t/e)-i:0===e?t>0?i/2:t<0?-i/2:0:void 0},j.CartesianToGeographicWgs84=function(t,e,i,r,o){var n,a,s,l,d,h,c,u,f,g,p,v,y,m,x,b=t,C=e,A=i,M=b*b+C*C,P=Math.sqrt(M),T=6378137,w=1/(T*T),_=.00669437999014,S=_*_,R=M*w,L=A*A*(1-_)*w,D=(R+L-S)/6,I=8*D*D*D+S*R*L;I>0||0!==L?(I>0?(l=Math.sqrt(I),d=Math.sqrt(S*R*L),s=I>10*_?D+.5*(h=Math.cbrt((l+d)*(l+d)))+2*D*D/h:D+.5*Math.cbrt((l+d)*(l+d))+.5*Math.cbrt((l-d)*(l-d))):(l=Math.sqrt(-I),d=Math.sqrt(-8*D*D*D),h=Math.sqrt(S*R*L),c=2*j.atan2Test(h,l+d)/3,s=-4*D*Math.sin(c)*Math.cos(Math.PI/6+c)),f=_*(s+(u=Math.sqrt(s*s+S*L))-L)/(2*u),p=(g=(s+u)/(Math.sqrt(f*f+s+u)+f))*P/(g+_),n=(g+_-1)*(v=Math.sqrt(p*p+A*A))/g,a=2*j.atan2Test(A,v+p)):(n=-T*(l=Math.sqrt(1-_))*(d=Math.sqrt(_-R))/(y=Math.sqrt(_)),a=d/(y*d+l*Math.sqrt(R))),m=((x=Math.sqrt(2))-1)*C5))for(var e=t.length,i=0;i5)return},U.prototype.drawBuildingNames=function(t){var e=this.getObjectLabel().getContext("2d");e.clearRect(0,0,e.canvas.width,e.canvas.height);for(var i,r,o,n,a,s=this.getGl(),l={},d=t.currentVisibles2.concat(t.currentVisibles3),h=d.length,c=0;c=0&&a.y>=0&&(e.font="13px Arial",e.strokeText(r.data.data_name,a.x,a.y),e.fillText(r.data.data_name,a.x,a.y)));l={},e.restore()},U.prototype.cameraMoved=function(){this.sceneState.camera.setDirty(!0),void 0===this.selectionFbo&&(this.selectionFbo=new T(this.sceneState.gl,this.sceneState.drawingBufferWidth,this.sceneState.drawingBufferHeight)),this.selectionFbo.dirty=!0},U.prototype.getSelectedObjects=function(t,e,i,r){var o=new Uint8Array(324),n=e-Math.floor(4.5),a=this.sceneState.drawingBufferHeight-i-Math.floor(4.5);n<0&&(n=0),a<0&&(a=0),t.readPixels(n,a,9,9,t.RGBA,t.UNSIGNED_BYTE,o),t.bindFramebuffer(t.FRAMEBUFFER,null);var s=Math.floor(40.5),l=this.selectionColor.decodeColor3(o[3*s],o[3*s+1],o[3*s+2]);this.selectionManager.selectObjects(l);var d=this.selectionManager.currentReferenceSelected;r[0]=this.selectionManager.currentBuildingSelected,r[1]=this.selectionManager.currentOctreeSelected,r[2]=this.selectionManager.currentReferenceSelected,r[3]=this.selectionManager.currentNodeSelected;var h=this.selectionManager.getSelectionCandidatesFamily("networkEdges");if(h)for(var c=h.currentSelected,u=0;void 0===c&&u<81;){l=this.selectionColor.decodeColor3(o[3*u],o[3*u+1],o[3*u+2]);c=h.selectObject(l),u++}var f=this.selectionManager.getSelectionCandidatesFamily("general");if(f){var g=f.currentSelected;for(u=0;void 0===g&&u<81;){l=this.selectionColor.decodeColor3(o[3*u],o[3*u+1],o[3*u+2]);g=f.selectObject(l),u++}}return d},U.prototype.calculateSelObjMovePlaneAsimetricMode=function(t,e,i,r){void 0===this.pointSC&&(this.pointSC=new Ae),void 0===this.pointSC2&&(this.pointSC2=new Ae);var o=this.nodeSelected.getNodeGeoLocDataManager();pi.calculatePixelPositionWorldCoord(t,e,i,this.pointSC2,void 0,void 0,this);var n=o.getCurrentGeoLocationData().getTMatrixInv();return this.pointSC=n.transformPoint3D(this.pointSC2,this.pointSC),void 0===r&&(r=new Z),r.setPointAndNormal(this.pointSC.x,this.pointSC.y,this.pointSC.z,0,0,1),r},U.prototype.isDragging=function(){var t=!1,e=this.sceneState.gl;if(this.magoPolicy.objectMoveMode===a.moveMode.ALL){this.arrayAuxSC.length=0,this.selectionFbo.bind();var i,r=this.getSelectedObjects(e,this.mouse_x,this.mouse_y,this.arrayAuxSC),o=(this.arrayAuxSC[0],this.arrayAuxSC[3]);o&&(i=o.getRoot()),this.arrayAuxSC.length=0,t=i===this.rootNodeSelected}else if(this.magoPolicy.objectMoveMode===a.moveMode.OBJECT){this.arrayAuxSC.length=0,this.selectionFbo.bind();r=this.getSelectedObjects(e,this.mouse_x,this.mouse_y,this.arrayAuxSC);this.arrayAuxSC.length=0,t=r===this.objectSelected}else if(this.magoPolicy.objectMoveMode===a.moveMode.GEOGRAPHICPOINTS){var n=this.selectionManager.getSelectedGeneral();this.arrayAuxSC.length=0,this.selectionFbo.bind(),this.getSelectedObjects(e,this.mouse_x,this.mouse_y,this.arrayAuxSC);var s=this.selectionManager.getSelectedGeneral();if(void 0!==s&&s===n)t="GeographicCoord"===s.constructor.name}else if(this.weatherStation){this.selectionFbo.bind();r=this.getSelectedObjects(e,this.mouse_x,this.mouse_y,this.arrayAuxSC);var l=this.selectionManager.getSelectionCandidatesFamily("general");if(l){var d=l.currentSelected;d?d instanceof re&&(t=!0):t=!1}else t=!1}return t||this.selectionManager.clearCandidates(),t},U.prototype.setCameraMotion=function(t){this.configInformation.geo_view_library===s.CESIUM&&(this.scene.screenSpaceCameraController.enableRotate=t,this.scene.screenSpaceCameraController.enableZoom=t,this.scene.screenSpaceCameraController.enableLook=t,this.scene.screenSpaceCameraController.enableTilt=t,this.scene.screenSpaceCameraController.enableTranslate=t)},U.prototype.mouseActionLeftUp=function(t,e){if(this.objectMoved){this.objectMoved=!1;var i=this.selectionManager.currentNodeSelected;if(void 0===i)return;this.saveHistoryObjectMovement(this.objectSelected,i)}this.isCameraMoving=!1,this.mouseLeftDown=!1,this.mouseDragging=!1,this.selObjMovePlane=void 0,this.mustCheckIfDragging=!0,this.thereAreStartMovePoint=!1,this.dateSC=new Date,this.currentTimeSC=this.dateSC.getTime(),this.currentTimeSC-this.startTimeSC<1500&&this.mouse_x===t&&this.mouse_y===e&&(this.bPicking=!0),this.setCameraMotion(!0),this.sceneState.mouseAction.clearStartPositionsAux()},U.prototype.keyDown=function(t){if(32===t)void 0===this.pointsCloudSsao&&(this.pointsCloudSsao=!0),this.pointsCloudSsao?this.pointsCloudSsao=!1:this.pointsCloudSsao=!0;else if(49===t)void 0===this.pointsCloudWhite&&(this.pointsCloudWhite=!0),this.pointsCloudWhite?this.pointsCloudWhite=!1:this.pointsCloudWhite=!0;else if(80===t){var e=this.hierarchyManager.getNodeByDataKey("AutonomousBus","AutonomousBus_0");e.data.isTrailRender=!0;var i=e.getNodeGeoLocDataManager().getCurrentGeoLocationData().getGeographicCoords(),r=i.longitude,n=i.latitude,s=i.altitude,l=Math.random(),d=Math.random(),h=Math.random();l=n+.01,d=r+.01,h=s;this.changeLocationAndRotation("AutonomousBus","AutonomousBus_0",l,d,h,void 0,void 0,void 0,100)}else if(84===t){var c=this.modeler.getExcavation();void 0!==c&&c.makeExtrudeObject(this);var u=this.modeler.getTunnel();void 0!==u&&(u.getProfileGeographicCoordsList(),u.makeMesh(this));var f=new o;f.apiName="changeColor",f.setProjectId("AutonomousBus"),f.setDataKey("AutonomousBus_0"),f.setObjectIds("13"),f.setColor("220,150,20"),this.callAPI(f)}else 89===t&&(void 0===this.magoMode&&(this.magoMode=a.magoMode.NORMAL),this.magoMode===a.magoMode.NORMAL?this.magoMode=a.magoMode.DRAWING:this.magoMode===a.magoMode.DRAWING&&(this.magoMode=a.magoMode.NORMAL,this.modeler.mode=a.modelerMode.INACTIVE))},U.prototype.mouseActionLeftClick=function(t,e){if(this.magoMode===a.magoMode.DRAWING){var i,r;if(void 0===this.modeler&&(this.modeler=new ve),this.modeler.mode=a.modelerMode.DRAWING_STATICGEOMETRY,this.configInformation.geo_view_library===s.CESIUM){var o=this.scene.frameState.camera,n=this.scene,l=o.getPickRay(new Cesium.Cartesian2(t,e));r=n.globe.pick(l,n)}else{r=this.sceneState.mouseAction.strWorldPoint}(i=j.CartesianToGeographicWgs84(r.x,r.y,r.z,void 0,!0)).absolutePoint=r;this.modeler.mode;if(this.modeler.mode===a.modelerMode.DRAWING_PLANEGRID&&void 0===this.modeler.planeGrid){this.modeler.createPlaneGrid(),this.modeler.planeGrid.makeVbo(this.vboMemoryManager),void 0===this.modeler.planeGrid.geoLocDataManager&&(this.modeler.planeGrid.geoLocDataManager=new N);var d=this.modeler.planeGrid.geoLocDataManager.newGeoLocationData("noName");return void(d=pi.calculateGeoLocationData(i.longitude,i.latitude,i.altitude+1,void 0,void 0,void 0,d,this))}if(this.modeler.mode===a.modelerMode.DRAWING_GEOGRAPHICPOINTS){d=i.getGeoLocationDataManager().newGeoLocationData("noName");d=pi.calculateGeoLocationData(i.longitude,i.latitude,i.altitude+1,void 0,void 0,void 0,d,this),(h=this.modeler.getGeographicCoordsList()).addGeoCoord(i)}else if(this.modeler.mode===a.modelerMode.DRAWING_EXCAVATIONPOINTS){d=i.getGeoLocationDataManager().newGeoLocationData("noName");d=pi.calculateGeoLocationData(i.longitude,i.latitude,i.altitude+1,void 0,void 0,void 0,d,this),(h=this.modeler.getExcavation().getGeographicCoordsList()).addGeoCoord(i),h.makeLines(this)}else if(this.modeler.mode===a.modelerMode.DRAWING_TUNNELPOINTS){var h;d=i.getGeoLocationDataManager().newGeoLocationData("noName");d=pi.calculateGeoLocationData(i.longitude,i.latitude,i.altitude+1,void 0,void 0,void 0,d,this),(h=this.modeler.getTunnel().getPathGeographicCoordsList()).addGeoCoord(i),h.makeLines(this)}else if(this.modeler.mode===a.modelerMode.DRAWING_STATICGEOMETRY){this.isExistStaticModel("AutonomousBus")||this.addStaticModel({projectId:"AutonomousBus",projectFolderName:"staticModels",buildingFolderName:"F4D_AutonomousBus"});var c=this.hierarchyManager.getNodesMap("AutonomousBus",void 0),u="AutonomousBus_"+Object.keys(c).length.toString();this.instantiateStaticModel({projectId:"AutonomousBus",instanceId:u,longitude:i.longitude,latitude:i.latitude,height:i.altitude+1})}}},U.prototype.mouseActionLeftDown=function(t,e){this.dateSC=new Date,this.startTimeSC=this.dateSC.getTime(),this.mouse_x=t,this.mouse_y=e,this.mouseLeftDown=!0,ge.updateMouseStartClick(t,e,this)},U.prototype.saveHistoryObjectMovement=function(t,e){var i=new n,r=i.getReferenceObjectAditionalMovement(),o=i.getReferenceObjectAditionalMovementRelToBuilding();if(void 0===t.moveVector&&(t.moveVector=new Ae),void 0===t.moveVectorRelToBuilding&&(t.moveVectorRelToBuilding=new Ae),r.set(t.moveVector.x,t.moveVector.y,t.moveVector.z),o.set(t.moveVectorRelToBuilding.x,t.moveVectorRelToBuilding.y,t.moveVectorRelToBuilding.z),void 0!==e){var a=e.data.projectId,s=e.data.nodeId,d=t._id;i.setProjectId(a),i.setDataKey(s),i.setObjectIndexOrder(d),l.saveMovingHistory(a,s,d,i)}},U.prototype.mouseActionMiddleDown=function(t,e){this.dateSC=new Date,this.startTimeSC=this.dateSC.getTime(),this.mouse_x=t,this.mouse_y=e,this.mouseMiddleDown=!0,this.isCameraMoving=!0},U.prototype.mouseActionMiddleUp=function(t,e){this.isCameraMoving=!1,this.mouseMiddleDown=!1,this.mouseDragging=!1,this.selObjMovePlane=void 0,this.mustCheckIfDragging=!0,this.thereAreStartMovePoint=!1,this.setCameraMotion(!1)},U.prototype.mouseActionRightDown=function(t,e){},U.prototype.mouseActionRightUp=function(t,e){},U.prototype.mouseActionMove=function(t,e){this.mouseLeftDown?this.manageMouseDragging(t,e):this.mouseMiddleDown?this.sceneState.camera.setDirty(!0):this.mouseRightDown?this.sceneState.camera.setDirty(!0):(this.mouseDragging=!1,this.setCameraMotion(!1),this.mouseMiddleDown&&(this.isCameraMoving=!0))},U.prototype.manageMouseDragging=function(t,e){if(this.sceneState.camera.setDirty(!0),this.mouse_x=t,this.mouse_y=e,this.magoPolicy.objectMoveMode===a.moveMode.ALL)if(void 0!==this.buildingSelected){this.mustCheckIfDragging&&(this.isDragging()&&(this.mouseDragging=!0,this.setCameraMotion(!1)),this.mustCheckIfDragging=!1);var i=this.buildingSelected.nodeOwner;if(void 0===i)return;var r=i.data.geoLocDataManager;if(void 0===r)return;var o=r.getGeoLocationData(0);if(void 0===o)return;var n=o.geographicCoord;if(void 0===n)return;movedDataCallback(l.getPolicy().geo_callback_moveddata,i.data.projectId,i.data.nodeId,null,n.latitude,n.longitude,n.altitude,o.heading,o.pitch,o.roll)}else this.isCameraMoving=!0;else if(this.magoPolicy.objectMoveMode===a.moveMode.OBJECT)void 0!==this.objectSelected?this.mustCheckIfDragging&&(this.isDragging()&&(this.mouseDragging=!0,this.setCameraMotion(!1)),this.mustCheckIfDragging=!1):this.isCameraMoving=!0;else if(this.magoPolicy.objectMoveMode===a.moveMode.GEOGRAPHICPOINTS){var s=this.selectionManager.getSelectedGeneral();if(s)"GeographicCoord"===s.constructor.name&&this.mustCheckIfDragging&&(this.isDragging()&&(this.mouseDragging=!0,this.setCameraMotion(!1)),this.mustCheckIfDragging=!1)}else this.mustCheckIfDragging&&(this.isDragging()&&(this.mouseDragging=!0,this.setCameraMotion(!1)),this.mustCheckIfDragging=!1);this.isCameraMoving=!0,this.mouseDragging&&this.moveSelectedObjectAsimetricMode(this.sceneState.gl)},U.prototype.moveSelectedObjectAsimetricMode=function(t){if(this.magoPolicy.objectMoveMode===a.moveMode.ALL){if(void 0===this.selectionManager.currentNodeSelected)return;var e=(y=this.selectionManager.currentNodeSelected.getNodeGeoLocDataManager()).getCurrentGeoLocationData(),i=this.sceneState.mouseAction;if(void 0===this.selObjMovePlane){this.selObjMovePlane=new Z;var r=(m=e.getGeoLocationMatrixInv()).transformPoint3D(i.strWorldPoint,r);this.selObjMovePlane.setPointAndNormal(r.x,r.y,r.z,0,0,1)}void 0===this.lineSC&&(this.lineSC=new ce),this.lineSC=pi.getRayWorldSpace(t,this.mouse_x,this.mouse_y,this.lineSC,this);var o=new Ae,n=new Ae,d=e.getGeoLocationMatrixInv();o=d.transformPoint3D(this.lineSC.point,o),this.pointSC=d.rotatePoint3D(this.lineSC.direction,this.pointSC),n.x=this.pointSC.x,n.y=this.pointSC.y,n.z=this.pointSC.z,(x=new ce).setPointAndDir(o.x,o.y,o.z,n.x,n.y,n.z);var h=new Ae;(h=this.selObjMovePlane.intersectionLine(x,h)).set(-h.x,-h.y,-h.z);var c=new Ae;if(c=e.geoLocMatrix.transformPoint3D(h,c),this.thereAreStartMovePoint){var u=(v=pi.pointToGeographicCoord(c,v,this)).longitude-this.startMovPoint.x,f=v.latitude-this.startMovPoint.y,g=e.geographicCoord.longitude-u,p=e.geographicCoord.latitude-f;this.changeLocationAndRotationNode(this.selectionManager.currentNodeSelected,p,g,void 0,void 0,void 0,void 0),this.displayLocationAndRotation(this.buildingSelected),this.startMovPoint.x-=u,this.startMovPoint.y-=f}else{var v=pi.pointToGeographicCoord(c,v,this);this.startMovPoint.x=v.longitude,this.startMovPoint.y=v.latitude,this.thereAreStartMovePoint=!0}}else if(this.magoPolicy.objectMoveMode===a.moveMode.OBJECT){if(void 0===this.objectSelected)return;void 0===this.selObjMovePlane&&(this.selObjMovePlane=this.calculateSelObjMovePlaneAsimetricMode(t,this.mouse_x,this.mouse_y,this.selObjMovePlane));var y=this.selectionManager.currentNodeSelected.getNodeGeoLocDataManager();void 0===this.lineSC&&(this.lineSC=new ce),this.lineSC=pi.getRayWorldSpace(t,this.mouse_x,this.mouse_y,this.lineSC,this);var m,x,b=y.getCurrentGeoLocationData();o=new Ae,n=new Ae;o=(m=b.getTMatrixInv()).transformPoint3D(this.lineSC.point,o),n=m.rotatePoint3D(this.lineSC.direction,n),(x=new ce).setPointAndDir(o.x,o.y,o.z,n.x,n.y,n.z);h=new Ae;if(h=this.selObjMovePlane.intersectionLine(x,h),void 0===this.objectSelected.moveVectorRelToBuilding&&(this.objectSelected.moveVectorRelToBuilding=new Ae),this.thereAreStartMovePoint){u=h.x-this.startMovPoint.x,f=h.y-this.startMovPoint.y;var C=h.z-this.startMovPoint.z;this.objectSelected.moveVectorRelToBuilding.set(u,f,C),this.objectSelected.moveVector=b.tMatrix.rotatePoint3D(this.objectSelected.moveVectorRelToBuilding,this.objectSelected.moveVector)}else this.startMovPoint=h,this.startMovPoint.add(-this.objectSelected.moveVectorRelToBuilding.x,-this.objectSelected.moveVectorRelToBuilding.y,-this.objectSelected.moveVectorRelToBuilding.z),this.thereAreStartMovePoint=!0;var A=this.selectionManager.currentNodeSelected.data.projectId,M=this.selectionManager.currentNodeSelected.data.nodeId,P=this.objectSelected._id;l.deleteMovingHistoryObject(A,M,P),this.objectMoved=!0}else if(this.magoPolicy.objectMoveMode===a.moveMode.GEOGRAPHICPOINTS){var T=this.selectionManager.getSelectedGeneral();if(T)if("GeographicCoord"===T.constructor.name){var w;e=(y=T.getGeoLocationDataManager()).getCurrentGeoLocationData();if(this.configInformation.geo_view_library===s.CESIUM){var _=this.scene.frameState.camera,S=this.scene,R=_.getPickRay(new Cesium.Cartesian2(this.mouse_x,this.mouse_y));V=S.globe.pick(R,S),w=j.CartesianToGeographicWgs84(V.x,V.y,V.z,void 0,!0)}else{V=(i=this.sceneState.mouseAction).strWorldPoint,w=j.CartesianToGeographicWgs84(V.x,V.y,V.z,void 0,!0)}T.setLonLatAlt(w.longitude,w.latitude,void 0);var L=(y=T.getGeoLocationDataManager()).getCurrentGeoLocationData();L=pi.calculateGeoLocationData(T.longitude,T.latitude,T.altitude,void 0,void 0,void 0,L,this);var D=T.owner;if(D){"GeographicCoordsList"===D.constructor.name&&D.makeLines(this);var I=D.owner;I&&("Excavation"===I.constructor.name?I.remakeExtrudeObject(this):"Tunnel"===I.constructor.name&&I.remakeMesh(this))}}}else if(this.weatherStation){var E=this.selectionManager.getSelectionCandidatesFamily("general");if(E){var O=E.currentSelected;if(O&&O instanceof re){e=(y=O.geoLocDataManager).getCurrentGeoLocationData(),i=this.sceneState.mouseAction;var V,N=pi.getRayWorldSpace(t,this.mouse_x,this.mouse_y,void 0,this);if(V=i.strWorldPointAux){var B,U=V.getModul();if(B=this.globe.intersectionLineWgs84(N,B,U)){var G=new Ae(B[0],B[1],B[2]),k=pi.pointToGeographicCoord(G,void 0,this),z=i.strLocationAux,H=e.geographicCoord,W=new F;W.setLonLatAlt(k.longitude-z.longitude,k.latitude-z.latitude,k.altitude-z.altitude);g=H.longitude+W.longitude,p=H.latitude+W.latitude;e=pi.calculateGeoLocationData(g,p,void 0,void 0,void 0,void 0,e,this),i.strLocationAux.setLonLatAlt(k.longitude,k.latitude,k.altitude)}}}}}},U.prototype.test_renderDepth_objectSelected=function(t){var e=this.sceneState.gl;void 0===this.depthFboAux&&(this.depthFboAux=new T(e,this.sceneState.drawingBufferWidth,this.sceneState.drawingBufferHeight)),this.sceneState.drawingBufferWidth[0]===this.depthFboAux.width[0]&&this.sceneState.drawingBufferHeight[0]===this.depthFboAux.height[0]||(this.depthFboAux.deleteObjects(e),this.depthFboAux=new T(e,this.sceneState.drawingBufferWidth,this.sceneState.drawingBufferHeight)),this.depthFboAux.bind(),this.isFarestFrustum()&&(e.clearColor(1,1,1,1),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT)),e.disable(e.BLEND),e.frontFace(e.CCW),e.enable(e.DEPTH_TEST),e.depthFunc(e.LEQUAL),e.enable(e.CULL_FACE);var i=this.postFxShadersManager.getShader("modelRefDepth");i.useProgram(),i.bindUniformGenerals(),i.enableVertexAttribArray(i.position3_loc);var r=t.geoLocDataManager.getCurrentGeoLocationData(),o=i.uniformsMapGeneral.frustumFar.uniformLocation;e.uniform1f(o,new Float32Array([1e8]));r.bindGeoLocationUniforms(e,i),e.uniform3fv(i.aditionalMov_loc,[0,0,0]),t.render(this,i,0),this.depthFboAux.unbind()},U.prototype.getRenderablesDetailedNeoBuildingAsimetricVersion=function(t,e,i,r){var o=e.data,n=o.neoBuilding;o.currentLod;if(void 0===n||void 0===n.octree)return!1;var a=n.getLodBuildingData(o.currentLod);if(void 0===a)return!1;if(!a.isModelRef)return!0;var s=e.getNodeGeoLocDataManager(),l=(s.getCurrentGeoLocationData(),s.getCurrentGeoLocationData());if(void 0===l)return!1;void 0===o.currentVisibleOctreesControler&&(o.currentVisibleOctreesControler=new yt);var d=this.magoPolicy.getLod0DistInMeters(),h=this.magoPolicy.getLod1DistInMeters(),c=this.magoPolicy.getLod2DistInMeters(),u=(this.magoPolicy.getLod3DistInMeters(),this.magoPolicy.getLod4DistInMeters(),this.magoPolicy.getLod5DistInMeters()),f=!1;if(void 0===o.myCameraRelative&&(o.myCameraRelative=new C),o.myCameraRelative.frustum.copyParametersFrom(this.myCameraSCX.bigFrustum),o.myCameraRelative=l.getTransformedRelativeCamera(this.sceneState.camera,o.myCameraRelative),o.currentVisibleOctreesControler.clear(),2===r)n.octree.extractLowestOctreesByLOD(o.currentVisibleOctreesControler,i,this.boundingSphere_Aux,o.myCameraRelative.position,d,h,u),f=!0;else{o.myCameraRelative.calculateFrustumsPlanes();var g=o.myCameraRelative.bigFrustum;f=n.octree.getFrustumVisibleLowestOctreesByLOD(g,o.currentVisibleOctreesControler,i,this.boundingSphere_Aux,o.myCameraRelative.position,d,h,100*c)}return f?(this.processQueue.eraseNodeToDeleteModelReferences(e),!0):(o.distToCam>100&&this.processQueue.putNodeToDeleteModelReferences(e,1),!1)},U.prototype.manageQueue=function(){var t=this.sceneState.gl;this.processQueue.manageDeleteQueue(this),this.parseQueue.initCounters(),this.parseQueue.parseArrayOctreesLod0References(t,this.visibleObjControlerOctrees.currentVisibles0,this),this.parseQueue.parseArrayOctreesLod0References(t,this.visibleObjControlerOctrees.currentVisibles1,this),this.parseQueue.parseArrayOctreesLod0Models(t,this.visibleObjControlerOctrees.currentVisibles0,this),this.parseQueue.parseArrayOctreesLod0Models(t,this.visibleObjControlerOctrees.currentVisibles1,this),this.parseQueue.parseArrayOctreesLod2Legos(t,this.visibleObjControlerOctrees.currentVisibles2,this),this.parseQueue.parseArrayOctreesPCloud(t,this.visibleObjControlerOctrees.currentVisiblesAux,this),this.parseQueue.parseArrayOctreesPCloudPartition(t,this.visibleObjControlerOctrees.currentVisiblesAux,this),this.parseQueue.parseArraySkins(t,this.visibleObjControlerNodes.currentVisibles0,this),this.parseQueue.parseArraySkins(t,this.visibleObjControlerNodes.currentVisibles2,this),this.parseQueue.parseArraySkins(t,this.visibleObjControlerNodes.currentVisibles3,this);var e=0;for(var i in this.parseQueue.tinTerrainsToParseMap){var r;if(Object.prototype.hasOwnProperty.call(this.parseQueue.tinTerrainsToParseMap,i))if(void 0!==(r=this.parseQueue.tinTerrainsToParseMap[i])&&this.parseQueue.eraseTinTerrainToParse(r)&&(r.parseData(r.dataArrayBuffer),e++),e>1)break}},U.prototype.prepareVisibleOctreesSortedByDistancePointsCloudType=function(t,e,i){if(!(Object.keys(this.loadQueue.lod2PCloudDataMap).length>5)){var r=i,o=e.getAllVisibles();if(void 0!==o)for(var n,s,l,d,h=this.readerWriter.geometryDataPath,c=0,u=o.length;c5)return}}}}},U.prototype.prepareVisibleOctreesSortedByDistance=function(t,e){if(!(this.readerWriter.referencesList_requested>5)){var i,r=[].concat(e.currentVisibles0,e.currentVisibles1);this.thereAreUrgentOctrees=!1;for(var o=0,n=r.length;o5)return;0}}},U.prototype.prepareVisibleOctreesSortedByDistanceLOD2=function(t,e){if(!(this.readerWriter.octreesSkinLegos_requested>5)&&void 0!==e)for(var i=0,r=e.length;i5)return},U.prototype.checkChangesHistoryMovements=function(t){for(var e,i,r,o,n,a=t.length,s=0;s=0&&r.y>=0&&(e.font="13px Arial",e.strokeText(o.name,r.x,r.y),e.fillText(o.name,r.x,r.y));e.restore()},U.prototype.createDefaultShaders=function(t){var e="modelRefSsao",i=this.postFxShadersManager.newShader(e),r=ei.ModelRefSsaoVS,o=ei.ModelRefSsaoFS;i.program=t.createProgram(),i.shader_vertex=this.postFxShadersManager.createShader(t,r,t.VERTEX_SHADER,"VERTEX"),i.shader_fragment=this.postFxShadersManager.createShader(t,o,t.FRAGMENT_SHADER,"FRAGMENT"),t.attachShader(i.program,i.shader_vertex),t.attachShader(i.program,i.shader_fragment),t.linkProgram(i.program),i.createUniformGenerals(t,i,this.sceneState),i.createUniformLocals(t,i,this.sceneState);e="modelRefDepth",i=this.postFxShadersManager.newShader(e);var n=ei.RenderShowDepthVS,a=ei.RenderShowDepthFS;i.program=t.createProgram(),i.shader_vertex=this.postFxShadersManager.createShader(t,n,t.VERTEX_SHADER,"VERTEX"),i.shader_fragment=this.postFxShadersManager.createShader(t,a,t.FRAGMENT_SHADER,"FRAGMENT"),t.attachShader(i.program,i.shader_vertex),t.attachShader(i.program,i.shader_fragment),t.linkProgram(i.program),i.createUniformGenerals(t,i,this.sceneState),i.createUniformLocals(t,i,this.sceneState);e="modelRefColorCoding",i=this.postFxShadersManager.newShader(e),n=ei.ColorSelectionSsaoVS,a=ei.ColorSelectionSsaoFS;i.program=t.createProgram(),i.shader_vertex=this.postFxShadersManager.createShader(t,n,t.VERTEX_SHADER,"VERTEX"),i.shader_fragment=this.postFxShadersManager.createShader(t,a,t.FRAGMENT_SHADER,"FRAGMENT"),t.attachShader(i.program,i.shader_vertex),t.attachShader(i.program,i.shader_fragment),t.linkProgram(i.program),i.createUniformGenerals(t,i,this.sceneState),i.createUniformLocals(t,i,this.sceneState),e="tinTerrain",i=this.postFxShadersManager.newShader(e),r=ei.TinTerrainVS,o=ei.TinTerrainFS,i.program=t.createProgram(),i.shader_vertex=this.postFxShadersManager.createShader(t,r,t.VERTEX_SHADER,"VERTEX"),i.shader_fragment=this.postFxShadersManager.createShader(t,o,t.FRAGMENT_SHADER,"FRAGMENT"),t.attachShader(i.program,i.shader_vertex),t.attachShader(i.program,i.shader_fragment),t.linkProgram(i.program),i.createUniformGenerals(t,i,this.sceneState),i.createUniformLocals(t,i,this.sceneState),i.bIsMakingDepth_loc=t.getUniformLocation(i.program,"bIsMakingDepth"),e="pointsCloud",i=this.postFxShadersManager.newShader(e),r=ei.PointCloudVS,o=ei.PointCloudFS,i.program=t.createProgram(),i.shader_vertex=this.postFxShadersManager.createShader(t,r,t.VERTEX_SHADER,"VERTEX"),i.shader_fragment=this.postFxShadersManager.createShader(t,o,t.FRAGMENT_SHADER,"FRAGMENT"),t.attachShader(i.program,i.shader_vertex),t.attachShader(i.program,i.shader_fragment),t.linkProgram(i.program),i.createUniformGenerals(t,i,this.sceneState),i.createUniformLocals(t,i,this.sceneState),i.bPositionCompressed_loc=t.getUniformLocation(i.program,"bPositionCompressed"),i.minPosition_loc=t.getUniformLocation(i.program,"minPosition"),i.bboxSize_loc=t.getUniformLocation(i.program,"bboxSize"),e="testQuad",i=this.postFxShadersManager.newShader(e),r=ei.Test_QuadVS,o=ei.Test_QuadFS,i.program=t.createProgram(),i.shader_vertex=this.postFxShadersManager.createShader(t,r,t.VERTEX_SHADER,"VERTEX"),i.shader_fragment=this.postFxShadersManager.createShader(t,o,t.FRAGMENT_SHADER,"FRAGMENT"),t.attachShader(i.program,i.shader_vertex),t.attachShader(i.program,i.shader_fragment),t.linkProgram(i.program),i.createUniformGenerals(t,i,this.sceneState),i.createUniformLocals(t,i,this.sceneState),e="filterSilhouette",i=this.postFxShadersManager.newShader(e),r=ei.wgs84_volumVS,o=ei.filterSilhouetteFS,i.program=t.createProgram(),i.shader_vertex=this.postFxShadersManager.createShader(t,r,t.VERTEX_SHADER,"VERTEX"),i.shader_fragment=this.postFxShadersManager.createShader(t,o,t.FRAGMENT_SHADER,"FRAGMENT"),t.attachShader(i.program,i.shader_vertex),t.attachShader(i.program,i.shader_fragment),t.linkProgram(i.program),i.createUniformGenerals(t,i,this.sceneState),i.createUniformLocals(t,i,this.sceneState),e="pointsCloudDepth",i=this.postFxShadersManager.newShader(e),r=ei.PointCloudDepthVS,o=ei.RenderShowDepthFS,i.program=t.createProgram(),i.shader_vertex=this.postFxShadersManager.createShader(t,r,t.VERTEX_SHADER,"VERTEX"),i.shader_fragment=this.postFxShadersManager.createShader(t,o,t.FRAGMENT_SHADER,"FRAGMENT"),t.attachShader(i.program,i.shader_vertex),t.attachShader(i.program,i.shader_fragment),t.linkProgram(i.program),i.createUniformGenerals(t,i,this.sceneState),i.createUniformLocals(t,i,this.sceneState),i.bPositionCompressed_loc=t.getUniformLocation(i.program,"bPositionCompressed"),i.minPosition_loc=t.getUniformLocation(i.program,"minPosition"),i.bboxSize_loc=t.getUniformLocation(i.program,"bboxSize"),e="pointsCloudSsao",i=this.postFxShadersManager.newShader(e),r=ei.PointCloudVS,o=ei.PointCloudSsaoFS,i.program=t.createProgram(),i.shader_vertex=this.postFxShadersManager.createShader(t,r,t.VERTEX_SHADER,"VERTEX"),i.shader_fragment=this.postFxShadersManager.createShader(t,o,t.FRAGMENT_SHADER,"FRAGMENT"),t.attachShader(i.program,i.shader_vertex),t.attachShader(i.program,i.shader_fragment),t.linkProgram(i.program),i.createUniformGenerals(t,i,this.sceneState),i.createUniformLocals(t,i,this.sceneState),i.bPositionCompressed_loc=t.getUniformLocation(i.program,"bPositionCompressed"),i.minPosition_loc=t.getUniformLocation(i.program,"minPosition"),i.bboxSize_loc=t.getUniformLocation(i.program,"bboxSize")},U.prototype.isFarestFrustum=function(){return this.numFrustums-this.currentFrustumIdx-1==0},U.prototype.doMultiFrustumCullingSmartTiles=function(t){var e=this.myCameraSCX.bigFrustum,i=this.smartTileManager.tilesArray[0],r=this.smartTileManager.tilesArray[1];void 0===this.frustumVolumeControl&&(this.frustumVolumeControl=new E),void 0===this.fullyIntersectedLowestTilesArray&&(this.fullyIntersectedLowestTilesArray=[]),void 0===this.partiallyIntersectedLowestTilesArray&&(this.partiallyIntersectedLowestTilesArray=[]),void 0===this.lastIntersectedLowestTilesArray&&(this.lastIntersectedLowestTilesArray=[]),this.lastIntersectedLowestTilesArray.push.apply(this.lastIntersectedLowestTilesArray,this.fullyIntersectedLowestTilesArray),this.lastIntersectedLowestTilesArray.push.apply(this.lastIntersectedLowestTilesArray,this.partiallyIntersectedLowestTilesArray);for(var o=this.lastIntersectedLowestTilesArray.length,n=0;n=0;d--){if(this.myCameraSCX.frustumsArray[d].intersectionNearFarSphere(h.sphereExtent)!==s.INTERSECTION_OUTSIDE)this.frustumVolumeControl.getFrustumVolumeCulling(d).fullyIntersectedLowestTilesArray.push(h)}}l=this.partiallyIntersectedLowestTilesArray.length;for(n=0;n=0;d--){if(this.myCameraSCX.frustumsArray[d].intersectionNearFarSphere(h.sphereExtent)!==s.INTERSECTION_OUTSIDE)this.frustumVolumeControl.getFrustumVolumeCulling(d).partiallyIntersectedLowestTilesArray.push(h)}}var h;for(o=this.lastIntersectedLowestTilesArray.length,n=0;nNumber(g)))if(l.nodesArray&&l.nodesArray.length>0){for(var A=l.nodesArray.length,M=0;Mc.getFrustumFarDistance())this.processQueue.putNodeToDelete(h,0);else{if(o)if(r.intersectionSphere(this.boundingSphere_Aux)===s.INTERSECTION_OUTSIDE){this.processQueue.putNodeToDeleteLessThanLod3(h,0);continue}var T=d.getHeaderVersion();if(void 0!==T)if("v"===T[0])a3.5){var d=this.scene.globe.ellipsoid.cartesianToCartographic(s),h=this.scene.globe.ellipsoid.cartesianToCartographic(t),c=h.height,u=d.height+1.5;uc||u1.5)&&(c=u);var f=Cesium.Math.toDegrees(h.latitude),g=Cesium.Math.toDegrees(h.longitude);return this.cameraFPV.camera.position=Cesium.Cartesian3.fromDegrees(g,f,c),!1}return!0}}};var G=function(t,e,i,r,n,d,h){if(!(this instanceof G))throw new Error(z.CONSTRUCT_ERROR);var c=null,u=null,f=a.magoManagerState.INIT;function g(){c.handler.setInputAction(function(t){c.mouseActionLeftDown(t.position.x,t.position.y)},Cesium.ScreenSpaceEventType.LEFT_DOWN),c.handler.setInputAction(function(t){c.mouseActionMiddleDown(t.position.x,t.position.y)},Cesium.ScreenSpaceEventType.MIDDLE_DOWN),c.handler.setInputAction(function(t){c.mouseActionRightDown(t.position.x,t.position.y)},Cesium.ScreenSpaceEventType.RIGHT_DOWN),c.handler.setInputAction(function(e){var i;c.mouseLeftDown?e.startPosition.x===e.endPosition.x&&e.startPosition.y===e.endPosition.y||(c.manageMouseDragging(e.startPosition.x,e.startPosition.y),c.cameraMoved()):(c.mouseDragging=!1,i=!0,t.scene.screenSpaceCameraController.enableRotate=i,t.scene.screenSpaceCameraController.enableZoom=i,t.scene.screenSpaceCameraController.enableLook=i,t.scene.screenSpaceCameraController.enableTilt=i,t.scene.screenSpaceCameraController.enableTranslate=i,(c.mouseMiddleDown||c.mouseRightDown)&&(c.isCameraMoving=!0,c.cameraMoved()))},Cesium.ScreenSpaceEventType.MOUSE_MOVE),c.handler.setInputAction(function(t){c.mouseActionLeftUp(t.position.x,t.position.y);var e={lat:null,lon:null,alt:null},r=c.scene.camera.pickEllipsoid(t.position);if(r){var o=Cesium.Cartographic.fromCartesian(r);e.lat=Cesium.Math.toDegrees(o.latitude),e.lon=Cesium.Math.toDegrees(o.longitude),e.alt=o.height}"true"===l.getPolicy().geo_callback_enable&&""!==i.geo_callback_clickposition&&clickPositionCallback(i.geo_callback_clickposition,e)},Cesium.ScreenSpaceEventType.LEFT_UP),c.handler.setInputAction(function(t){c.mouseActionMiddleUp(t.position.x,t.position.y)},Cesium.ScreenSpaceEventType.MIDDLE_UP),c.handler.setInputAction(function(t){c.mouseActionRightUp(t.position.x,t.position.y)},Cesium.ScreenSpaceEventType.RIGHT_UP),c.handler.setInputAction(function(t){c.mouseActionLeftClick(t.position.x,t.position.y)},Cesium.ScreenSpaceEventType.LEFT_CLICK)}function p(){var e,i;l.getPolicy().geo_view_library===s.CESIUM?function(){var e=t.scene.context._gl;if(t.scene.magoManager.postFxShadersManager.gl=e,t.scene.magoManager.postFxShadersManager.createDefaultShaders(e),t.scene.magoManager.createDefaultShaders(e),t.scene.magoManager.scene=t.scene,c=t.scene.magoManager,u=t.scene,t.scene.globe.depthTestAgainstTerrain=!0,t.scene.logarithmicDepthBuffer=!1,t.scene.highDynamicRange=!1,null!==r&&r.length>0)for(var i=0;i0&&(t.camera.frustum.fov=Cesium.Math.PI_OVER_THREE*l.getPolicy().geo_init_default_fov),"true"===i.geo_server_enable&&null!==i.geo_server_add_url&&""!==i.geo_server_add_url&&(y=new Cesium.WebMapServiceImageryProvider({url:l.getPolicy().geo_server_add_url,layers:l.getPolicy().geo_server_add_layers,parameters:{service:l.getPolicy().geo_server_add_parameters_service,version:l.getPolicy().geo_server_add_parameters_version,request:l.getPolicy().geo_server_add_parameters_request,transparent:l.getPolicy().geo_server_add_parameters_transparent,format:l.getPolicy().geo_server_add_parameters_format}}),t.imageryLayers.addImageryProvider(y)),p(),t.entities.add({name:"mago3D",position:Cesium.Cartesian3.fromDegrees(37.521168,126.924185,3e3),box:{dimensions:new Cesium.Cartesian3(3e8,3e8,3e8),fill:!0,material:Cesium.Color.BLUE,outline:!1}}),"true"===i.geo_init_camera_enable&&t.camera.flyTo({destination:Cesium.Cartesian3.fromDegrees(parseFloat(l.getPolicy().geo_init_longitude),parseFloat(l.getPolicy().geo_init_latitude),parseFloat(l.getPolicy().geo_init_height)),duration:parseInt(l.getPolicy().geo_init_duration)}),v=new o("renderMode"),c.callAPI(v),"false"===l.getPolicy().geo_time_line_enable&&($(t._animation.container).css("visibility","hidden"),$(t._timeline.container).css("visibility","hidden"),t.forceResize())}else if(i.geo_view_library===s.WORLDWIND){WorldWind.Logger.setLoggingLevel(WorldWind.Logger.LEVEL_WARNING);var C,A=document.getElementById(e);if("true"===i.geo_server_enable&&null!==i.geo_server_url&&""!==i.geo_server_url){C=new WorldWind.WorldWindow(e,new WorldWind.ZeroElevationModel);var M=i.geo_server_url+"?SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.3.0";$.get(M).done(function(t){var e=new WorldWind.WmsCapabilities(t).getNamedLayer("mago3d"),i=WorldWind.WmsLayer.formLayerConfiguration(e);i.title="imageProvider";var r=new WorldWind.WmsLayer(i);C.addLayer(r)}).fail(function(t,e,i){console.log("There was a failure retrieving the capabilities document: "+e+" exception: "+i)})}else{C=new WorldWind.WorldWindow(e);for(var P=[{layer:new WorldWind.BMNGLayer,enabled:!0},{layer:new WorldWind.BMNGLandsatLayer,enabled:!1},{layer:new WorldWind.BingAerialWithLabelsLayer(null),enabled:!0},{layer:new WorldWind.OpenStreetMapImageLayer(null),enabled:!1},{layer:new WorldWind.CompassLayer,enabled:!1},{layer:new WorldWind.CoordinatesDisplayLayer(C),enabled:!0},{layer:new WorldWind.ViewControlsLayer(C),enabled:!0}],T=0;T0)for(var i=0;i=0&&o[0]=0&&o[1]e-i&&t0){var t=(this.maxX+this.minX)/2,e=(this.maxY+this.minY)/2,i=(this.maxZ+this.minZ)/2;this._subBoxesArray[0].setDimensions(this.minX,t,this.minY,e,this.minZ,i),this._subBoxesArray[1].setDimensions(t,this.maxX,this.minY,e,this.minZ,i),this._subBoxesArray[2].setDimensions(t,this.maxX,e,this.maxY,this.minZ,i),this._subBoxesArray[3].setDimensions(this.minX,t,e,this.maxY,this.minZ,i),this._subBoxesArray[4].setDimensions(this.minX,t,this.minY,e,i,this.maxZ),this._subBoxesArray[5].setDimensions(t,this.maxX,this.minY,e,i,this.maxZ),this._subBoxesArray[6].setDimensions(t,this.maxX,e,this.maxY,i,this.maxZ),this._subBoxesArray[7].setDimensions(this.minX,t,e,this.maxY,i,this.maxZ);for(var r=0;rthis.minX&&tthis.minY&&ethis.minZ&&i0){var o,n=(this.minX+this.maxX)/2,a=(this.minY+this.maxY)/2,s=(this.minZ+this.maxZ)/2;o=t0&&(r=n._indicesArray,o&&(o=this.modelReferencedGroupsList)),r},Y.prototype.expandBox=function(t){this.minX-=t,this.maxX+=t,this.minY-=t,this.maxY+=t,this.minZ-=t,this.maxZ+=t},Y.prototype.parseArrayBuffer=function(t,e,i){var r=i.readInt8(t,e,e+1);if(e+=1,r){var o=i.readFloat32(t,e,e+4);e+=4;var n=i.readFloat32(t,e,e+4);e+=4;var a=i.readFloat32(t,e,e+4);e+=4;var s=i.readFloat32(t,e,e+4);e+=4;var l=i.readFloat32(t,e,e+4);e+=4;var d=i.readFloat32(t,e,e+4);e+=4,this.setDimensions(o,n,a,s,l,d)}var h=i.readUInt32(t,e,e+4);if(e+=4,0===h){var c=i.readUInt32(t,e,e+4);e+=4;for(var u=0;u1e-7){var d=-(this.a*i+this.b*r+this.c*o+this.d)/l;return void 0===e&&(e=new Ae),e.set(i+d*n,r+d*a,o+d*s),e}},Z.prototype.intersectionSphere=function(t){if(void 0===t||void 0===t.centerPoint)return s.INTERSECTION_OUTSIDE;var e=t.centerPoint,i=e.x*this.a+e.y*this.b+e.z*this.c+this.d;return i<-t.r?s.INTERSECTION_OUTSIDE:i=254&&(this.color.b=0,this.color.g+=1,this.color.g>=254&&(this.color.g=0,this.color.r+=1,this.color.r>=254&&(this.color.r=0,this.cycle+=1))),t},Q.prototype.decodeColor3=function(t,e,i){return 64516*t+254*e+i};var tt=function(t){if(!(this instanceof tt))throw new Error(z.CONSTRUCT_ERROR);this.name,t&&(this.name=t),this.depth,this.minGeographicCoord,this.maxGeographicCoord,this.sphereExtent,this.subTiles,this.nodeSeedsArray,this.nodesArray,this.isVisible};tt.prototype.deleteObjects=function(){if(this.name=void 0,this.depth=void 0,this.minGeographicCoord&&this.minGeographicCoord.deleteObjects(),this.maxGeographicCoord&&this.maxGeographicCoord.deleteObjects(),this.minGeographicCoord=void 0,this.maxGeographicCoord=void 0,this.sphereExtent&&this.sphereExtent.deleteObjects(),this.sphereExtent=void 0,this.nodeSeedsArray){for(var t=this.nodeSeedsArray.length,e=0;e0)return!0;i++}return!1},tt.prototype.makeSphereExtent=function(t){this.sphereExtent=tt.computeSphereExtent(t,this.minGeographicCoord,this.maxGeographicCoord,this.sphereExtent)},tt.computeSphereExtent=function(t,e,i,r){if(void 0!==e&&void 0!==i){void 0===r&&(r=new it);var o,n=(i.longitude+e.longitude)/2,a=(i.latitude+e.latitude)/2,s=(i.altitude+e.altitude)/2;return r.centerPoint=pi.geographicCoordToWorldPoint(n,a,s,r.centerPoint,t),o=pi.geographicCoordToWorldPoint(e.longitude,e.latitude,e.altitude,o,t),r.r=1.1*r.centerPoint.distTo(o.x,o.y,o.z),r}},tt.prototype.putNode=function(t,e,i){if(void 0===this.sphereExtent&&this.makeSphereExtent(i),this.depththis.maxGeographicCoord.altitude&&(this.maxGeographicCoord.altitude=n+a)}},tt.prototype.intersectPoint=function(t,e){return!(tthis.maxGeographicCoord.longitude)&&!(ethis.maxGeographicCoord.latitude)},tt.prototype.eraseNode=function(t){if(void 0!==this.nodeSeedsArray)for(var e=this.nodeSeedsArray.length,i=!1,r=0;!i&&r0&&t.push(this)},tt.prototype.getFrustumIntersectedLowestTiles=function(t,e,i){var r=[];this.getFrustumIntersectedTiles(t,r,i);for(var o=r.length,n=0;n0)for(var o=0;o0&&i.push(this)}else e.push(this)},tt.selectTileAngleRangeByDepth=function(t){if(!(void 0===t||t<0||t>15))return 0===t?180:1===t?90:2===t?45:3===t?22.5:4===t?11.25:5===t?5.625:6===t?2.8125:7===t?1.40625:8===t?.703125:9===t?.3515625:10===t?.17578125:11===t?.087890625:12===t?.043945313:13===t?.021972656:14===t?.010986328:15===t?.005493164:void 0},tt.selectTileName=function(t,e,i,r){var o=tt.selectTileAngleRangeByDepth(t),n=Math.floor((e- -180)/o),a=Math.floor((90-i)/o);return t.toString()+"\\"+n.toString()+"\\"+a.toString()},tt.getFrustumIntersectedTilesNames=function(t,e,i,r,o){var n=new F,a=new F,s=0;n.setLonLatAlt(-180,-90,0),a.setLonLatAlt(0,90,0),s=0,tt.getFrustumIntersectedTilesNamesForGeographicExtent(t,e,s,i,n,a,r,r.boundingSphere_Aux,o),n.setLonLatAlt(0,-90,0),a.setLonLatAlt(180,90,0),s=0,tt.getFrustumIntersectedTilesNamesForGeographicExtent(t,e,s,i,n,a,r,r.boundingSphere_Aux,o)},tt.getFrustumIntersectedTilesNamesForGeographicExtent=function(t,e,i,r,o,n,a,l,d){l=tt.computeSphereExtent(a,o,n,l);var h=t.intersectionSphere(l);if(h!==s.INTERSECTION_OUTSIDE){if(h===s.INTERSECTION_INSIDE){var c=(o.longitude+n.longitude)/2,u=(o.latitude+n.latitude)/2,f=tt.selectTileName(i,c,u,void 0);return(g=new V).minGeographicCoord=new F(o.longitude,o.latitude,o.altitude),g.maxGeographicCoord=new F(n.longitude,n.latitude,n.altitude),void(d[f]=g)}if(h===s.INTERSECTION_INTERSECT){if(r.distToSphere(l)>2e3){c=(o.longitude+n.longitude)/2,u=(o.latitude+n.latitude)/2,f=tt.selectTileName(i,c,u,void 0);return(g=new V).minGeographicCoord=new F(o.longitude,o.latitude,o.altitude),g.maxGeographicCoord=new F(n.longitude,n.latitude,n.altitude),void(d[f]=g)}if(!(i=e)){var i,r=t._header,o=this.fileArrayBuffer,n=this.fileBytesReaded;void 0===this.readWriter&&(this.readWriter=new kt);for(var a=0;a<5;a++)r._version+=String.fromCharCode(new Int8Array(o.slice(n,n+1))),n+=1;r._f4d_version=2,i=this.readWriter.readInt32(o,n,n+4),n+=4;for(a=0;a40||r._boundingBox.maxY-r._boundingBox.minY>40)&&(l=!0),!l&&r._boundingBox.maxZ-r._boundingBox.minZ<30&&(r.isSmall=!0);this.readWriter.readUInt8(o,n,n+1);n+=1;var d=Cesium.Cartesian3.fromDegrees(r._longitude,r._latitude,r._elevation),h=Cesium.Ellipsoid.WGS84.cartesianToCartographic(d).height;d=Cesium.Cartesian3.fromDegrees(r._longitude,r._latitude,h),t.buildingPosition=d;Cesium.EncodedCartesian3.encode(d);var c=Cesium.EncodedCartesian3.encode(d.x),u=Cesium.EncodedCartesian3.encode(d.y),f=Cesium.EncodedCartesian3.encode(d.z);t.buildingPositionHIGH=new Float32Array(3),t.buildingPositionHIGH[0]=c.high,t.buildingPositionHIGH[1]=u.high,t.buildingPositionHIGH[2]=f.high,t.buildingPositionLOW=new Float32Array(3),t.buildingPositionLOW[0]=c.low,t.buildingPositionLOW[1]=u.low,t.buildingPositionLOW[2]=f.low,this.fileBytesReaded=n}},ot.prototype.parseFileSimpleBuilding=function(t){var e=this.fileArrayBuffer.byteLength;if(!(this.fileBytesReaded>=e)){void 0===this.readWriter&&(this.readWriter=new kt);var i,r,o=this.fileBytesReaded,n=this.fileArrayBuffer;void 0===t._simpleBuilding_v1&&(t._simpleBuilding_v1=new SimpleBuildingV1);var a=t._simpleBuilding_v1,s=this.readWriter.readUInt32(n,o,o+4);o+=4;for(var l=0;l=e)this.fileParsingFinished=!0;else{void 0===this.readWriter&&(this.readWriter=new kt);var i=this.fileArrayBuffer,r=this.readWriter.readInt32(i,0,4);this.fileBytesReaded+=4,0===r&&(this.empty_tile=!0);for(var o=0;o=i)this.fileParsingFinished=!0;else{void 0===this.readWriter&&(this.readWriter=new kt);var r=this.readWriter.readInt32(this.fileArrayBuffer,0,4);if(this.projectsParsed_count>=r)return this.fileParsingFinished=!0,void(this.fileBytesReaded=null);0===this.current_BRProject_parsing_state&&(0===this.projectsParsed_count&&(this.fileBytesReaded=4),this.current_BRProject_parsing=this.newBRProject());var o=this.current_BRProject_parsing;0===this.current_BRProject_parsing_state?(this.parseFileHeader(o),this.current_BRProject_parsing_state=1):1===this.current_BRProject_parsing_state?e.backGround_imageReadings_count<1&&(this.parseFile_simpleBuilding_old(t,o),this.current_BRProject_parsing_state=2):2===this.current_BRProject_parsing_state&&e.backGround_imageReadings_count<1&&(this.parseFile_nailImage_old(t,o,e),this.current_BRProject_parsing_state=0,this.projectsParsed_count++,e.backGround_imageReadings_count++)}},ot.prototype.setDimensionsSubTiles=function(){var t=this.subTiles_array.length;if(4===t){var e=(this.longitudeMax+this.longitudeMin)/2,i=(this.latitudeMax+this.latitudeMin)/2;this.subTiles_array[0].setDimensions(this.longitudeMin,e,this.latitudeMin,i),this.subTiles_array[1].setDimensions(e,this.longitudeMax,this.latitudeMin,i),this.subTiles_array[2].setDimensions(e,this.longitudeMax,i,this.latitudeMax),this.subTiles_array[3].setDimensions(this.longitudeMin,e,i,this.latitudeMax);for(var r=0;r0)for(var e=0;e0)for(var r=0;rthis.maxSize&&(this.maxSize=t[o])};ct.prototype.getClassifiedBufferKey=function(t,e,i,r){var o=this.getClosestBufferSize(e),n=this.vboKeysStoreMap[o];return n?n.getBufferKey(t,this,i,r):-1},ct.prototype.storeClassifiedBufferKey=function(t,e){var i=this.vboKeysStoreMap[e];i&&i.storeBufferKey(t)},ct.prototype.getClosestBufferSize=function(t){if(!this.isInsideRange(t))return-1;for(var e=this.bufferSizes.length,i=0;ithis.maxSize||t0)return o=this.vboKeysArray.pop();if(!r){var o=t.createBuffer();return this.keysCreated+=1,e.totalBytesUsed+=this.classifiedSize,i.totalBytesUsed+=this.classifiedSize,o}},ut.prototype.storeBufferKey=function(t){this.vboKeysArray.push(t)};var ft=function(){if(!(this instanceof ft))throw new Error(z.CONSTRUCT_ERROR);this.totalBytesUsed=0,this.bytesLimit=1e3,this.vboKeysNationsArray=[],this.vboKeyNation12to128=new ct(new Uint32Array([12,16,32,48,64,76,92,128]),0),this.vboKeysNationsArray.push(this.vboKeyNation12to128),this.vboKeyNation200to1000=new ct(new Uint32Array([200,300,400,500,600,700,800,900,1e3]),129),this.vboKeysNationsArray.push(this.vboKeyNation200to1000),this.vboKeyNation1500to6000=new ct(new Uint32Array([1500,2e3,2500,3e3,3500,4e3,4500,5e3,5500,6e3]),1001),this.vboKeysNationsArray.push(this.vboKeyNation1500to6000),this.vboKeyNation7000to16000=new ct(new Uint32Array([7e3,8e3,9e3,1e4,11e3,12e3,13e3,14e3,15e3,16e3]),6001),this.vboKeysNationsArray.push(this.vboKeyNation7000to16000),this.vboKeyNation20000to56000=new ct(new Uint32Array([2e4,24e3,28e3,32e3,36e3,4e4,44e3,48e3,52e3,56e3]),16001),this.vboKeysNationsArray.push(this.vboKeyNation20000to56000),this.vboKeyNation60000to150000=new ct(new Uint32Array([6e4,7e4,8e4,9e4,1e5,11e4,12e4,13e4,14e4,15e4]),56001),this.vboKeysNationsArray.push(this.vboKeyNation60000to150000),this.vboKeyNation200000to1100000=new ct(new Uint32Array([2e5,3e5,4e5,5e5,6e5,7e5,8e5,9e5,1e6,11e5]),150001),this.vboKeysNationsArray.push(this.vboKeyNation200000to1100000),this.vboKeyNation1500000to3000000=new ct(new Uint32Array([15e5,2e6,25e5,3e6,6e6,12e6,24e6,36e6,6e7]),1100001),this.vboKeysNationsArray.push(this.vboKeyNation1500000to3000000)};ft.prototype.getClassifiedBufferKey=function(t,e){var i=!1;this.totalBytesUsed>this.bytesLimit&&(i=!0);var r=this.getKeyNationBySize(e),o=void 0;return r&&(o=r.getClassifiedBufferKey(t,e,this,i)),o},ft.prototype.storeClassifiedBufferKey=function(t,e){var i=this.getKeyNationBySize(e);i&&i.storeClassifiedBufferKey(t,e)},ft.prototype.getKeyNationBySize=function(t){for(var e=this.vboKeysNationsArray.length,i=0;ithis.buffersKeyWorld.bytesLimit||this.elementKeyWorld.totalBytesUsed>this.elementKeyWorld.bytesLimit},gt.prototype.getClassifiedBufferKey=function(t,e){if(this.enableMemoryManagement){var i=this.buffersKeyWorld.getClassifiedBufferKey(t,e);return void 0!==i&&(this.currentMemoryUsage+=e),i}return this.currentMemoryUsage+=e,t.createBuffer()},gt.prototype.storeClassifiedBufferKey=function(t,e,i){this.enableMemoryManagement?this.buffersKeyWorld.storeClassifiedBufferKey(e,i):t.deleteBuffer(e),this.currentMemoryUsage-=i,this.currentMemoryUsage<0&&(this.currentMemoryUsage=0)},gt.prototype.getClassifiedElementKey=function(t,e){return this.enableMemoryManagement?this.elementKeyWorld.getClassifiedBufferKey(t,e):t.createBuffer()},gt.prototype.storeClassifiedElementKey=function(t,e,i){this.enableMemoryManagement?this.elementKeyWorld.storeClassifiedBufferKey(e,i):t.deleteBuffer(e)},gt.prototype.getClassifiedBufferSize=function(t){return this.enableMemoryManagement?this.buffersKeyWorld.getClassifiedBufferSize(t):t};var pt=function(){if(!(this instanceof pt))throw new Error(z.CONSTRUCT_ERROR);this.indicesCount=-1,this.vertexCount=-1,this.bigTrianglesIndicesCount=-1,this.vboBufferPos,this.vboBufferNor,this.vboBufferIdx,this.vboBufferCol,this.vboBufferTCoord};pt.prototype.stepOverPosNorIdx=function(t,e,i,r){var o=e.readUInt32(t,r,r+4),n=3*o;r+=4,r+=4*n;var a=3*(o=e.readUInt32(t,r,r+4));r+=4,r+=1*a;var s=e.readUInt32(t,r,r+4);r+=4;var l=e.readUInt8(t,r,r+1);r+=1;for(var d=0;dr.distToCamera?(d=e,h=c):(d=c,h=i),this.getObjectIdxSortedByDist(t,d,h,r)},yt.prototype.putObjectToArraySortedByDist=function(t,e){if(t.length>0){var i=t.length-1,r=this.getObjectIdxSortedByDist(t,0,i,e);t.splice(r,0,e)}else t.push(e)},yt.prototype.getNodeIdxSortedByDist=function(t,e,i,r){r.data.neoBuilding;var o=i-e;if(o<6){for(var n,a=!1,s=e;!a&&s<=i;){var l=t[s];r.data.distToCamr.data.distToCam?(d=e,h=c):(d=c,h=i),this.getNodeIdxSortedByDist(t,d,h,r)},yt.prototype.putNodeToArraySortedByDist=function(t,e){if(t.length>0){var i=t.length-1,r=this.getNodeIdxSortedByDist(t,0,i,e);t.splice(r,0,e)}else t.push(e)};var mt=function(){if(!(this instanceof mt))throw new Error(z.CONSTRUCT_ERROR);this.bufferId,this.accesorType,this.bufferStart,this.stride,this.dataType,this.dimension,this.minX=0,this.minY=0,this.minZ=0,this.maxX=0,this.maxY=0,this.maxZ=0},xt=function(){if(!(this instanceof xt))throw new Error(z.CONSTRUCT_ERROR);this.vBOVertexIdxCacheKeysContainer=new vt,this.mIFCEntityType=-1,this.isSmallObj=!1,this.radius=10,this.vertexCount=0,this.lego};xt.prototype.deleteObjects=function(t,e){this.vBOVertexIdxCacheKeysContainer.deleteGlObjects(t,e),this.vBOVertexIdxCacheKeysContainer=void 0,this.mIFCEntityType=void 0,this.isSmallObj=void 0,this.radius=void 0,this.vertexCount=void 0,this.lego&&this.lego.deleteGlObjects(t),this.lego=void 0},xt.prototype.isReadyToRender=function(t,e,i){return!(i&&this.radius=0&&t1&&(s=y.stepOverPosNorIdx(n,t,l,s))}return o.fileLoadState=a.fileLoadState.PARSE_FINISHED,this.fileLoadState=a.fileLoadState.PARSE_FINISHED,!0}},Ct.prototype.parseBlocksList=function(t,e,i,r){this.fileLoadState=a.fileLoadState.PARSE_STARTED;var o=0,n=e.readUInt32(t,o,o+4);o+=4;for(var s=r.vboMemoryManager,l=0;l4){!0;break}}this.resetQueue()}};var _t=function(){if(!(this instanceof _t))throw new Error(z.CONSTRUCT_ERROR);this.lod,this.isModelRef,this.geometryFileName,this.textureFileName},St=function(){if(!(this instanceof St))throw new Error(z.CONSTRUCT_ERROR);this.guid,this.version="",this.geographicCoord,this.heading,this.pitch,this.roll,this.bbox,this.imageLodCount,this.projectDataType,this.offSetX,this.offSetY,this.offSetZ,this.oct_min_x=0,this.oct_max_x=0,this.oct_min_y=0,this.oct_max_y=0,this.oct_min_z=0,this.oct_max_z=0,this.isSmall=!1,this.fileLoadState=a.fileLoadState.READY};St.prototype.deleteObjects=function(){this.guid=void 0,this.geographicCoord&&this.geographicCoord.deleteObjects(),this.geographicCoord=void 0,this.heading=void 0,this.pitch=void 0,this.roll=void 0,this.bbox&&this.bbox.deleteObjects(),this.bbox=void 0,this.imageLodCount=void 0,this.oct_min_x=void 0,this.oct_max_x=void 0,this.oct_min_y=void 0,this.oct_max_y=void 0,this.oct_min_z=void 0,this.oct_max_z=void 0,this.isSmall=void 0,this.fileLoadState=void 0},St.prototype.parseFileHeaderAsimetricVersion=function(t,e){var i,r=0;void 0===e&&(e=new kt),this.version="";for(var o=0;o<5;o++)this.version+=String.fromCharCode(new Int8Array(t.slice(r,r+1))[0]),r+=1;void 0===this.guid&&(this.guid=""),i=e.readInt32(t,r,r+4),r+=4;for(o=0;o40||this.bbox.maxY-this.bbox.minY>40)&&(n=!0),!n&&this.bbox.maxZ-this.bbox.minZ<30&&(this.isSmall=!0),"0.0.2"===this.version&&(this.projectDataType=new Uint16Array(t.slice(r,r+2))[0],r+=2,this.offSetX=new Float64Array(t.slice(r,r+8))[0],r+=8,this.offSetY=new Float64Array(t.slice(r,r+8))[0],r+=8,this.offSetZ=new Float64Array(t.slice(r,r+8))[0],r+=8),r};var Rt=function(){if(!(this instanceof Rt))throw new Error(z.CONSTRUCT_ERROR);this.modelIdx,this.referencesIdxArray=[]},Lt=function(){if(!(this instanceof Lt))throw new Error(z.CONSTRUCT_ERROR);this.modelReferencedGroupsMap=[],this.modelReferencedGroupsArray=[]};Lt.prototype.getModelReferencedGroup=function(t){var e=this.modelReferencedGroupsMap[t];return void 0===e&&((e=new Rt).modelIdx=t,this.modelReferencedGroupsMap[t]=e),e},Lt.prototype.makeModelReferencedGroupsArray=function(){this.modelReferencedGroupsArray.length=0;for(var t=this.modelReferencedGroupsMap.length,e=0;e=0;i--){var r=this.getLodBuildingData(i);if(void 0!==r&&!r.isModelRef){var o=r.geometryFileName,n=this.lodMeshesMap[o];if(void 0===n||n.fileLoadState===a.fileLoadState.READY){e=i;break}if(void 0===n.vbo_vicks_container.vboCacheKeysArray){e=i;break}if(n.vbo_vicks_container.vboCacheKeysArray[0]&&n.vbo_vicks_container.vboCacheKeysArray[0].vboBufferTCoord&&void 0===n.texture){e=i;break}}}return e},Dt.prototype.getCurrentSkin=function(){if(void 0!==this.lodMeshesMap){var t,e=this.getLodBuildingData(this.currentLod);if(void 0!==e){var i=e.geometryFileName;return void 0!==(t=this.lodMeshesMap[i])&&t.isReadyToRender()?t:(0===this.currentLod?void 0!==(t=this.lodMeshesMap.lod0)&&t.isReadyToRender()||void 0!==(t=this.lodMeshesMap.lod1)&&t.isReadyToRender()||void 0!==(t=this.lodMeshesMap.lod2)&&t.isReadyToRender()||void 0!==(t=this.lodMeshesMap.lod3)&&t.isReadyToRender()||void 0!==(t=this.lodMeshesMap.lod4)&&t.isReadyToRender()||(t=this.lodMeshesMap.lod5):1===this.currentLod?void 0!==(t=this.lodMeshesMap.lod1)&&t.isReadyToRender()||void 0!==(t=this.lodMeshesMap.lod2)&&t.isReadyToRender()||void 0!==(t=this.lodMeshesMap.lod3)&&t.isReadyToRender()||void 0!==(t=this.lodMeshesMap.lod4)&&t.isReadyToRender()||(t=this.lodMeshesMap.lod5):2===this.currentLod?void 0!==(t=this.lodMeshesMap.lod2)&&t.isReadyToRender()||void 0!==(t=this.lodMeshesMap.lod3)&&t.isReadyToRender()||void 0!==(t=this.lodMeshesMap.lod4)&&t.isReadyToRender()||(t=this.lodMeshesMap.lod5):3===this.currentLod?void 0!==(t=this.lodMeshesMap.lod3)&&t.isReadyToRender()||void 0!==(t=this.lodMeshesMap.lod4)&&t.isReadyToRender()||(t=this.lodMeshesMap.lod5):4===this.currentLod?void 0!==(t=this.lodMeshesMap.lod4)&&t.isReadyToRender()||void 0!==(t=this.lodMeshesMap.lod5)&&t.isReadyToRender()||(t=this.lodMeshesMap.lod3):5===this.currentLod&&(void 0!==(t=this.lodMeshesMap.lod5)&&t.isReadyToRender()||void 0!==(t=this.lodMeshesMap.lod4)&&t.isReadyToRender()||(t=this.lodMeshesMap.lod3)),t)}}},Dt.prototype.manageNeoReferenceTexture=function(t,e){var i=void 0;if("v"===this.metaData.version[0]){if(void 0===t.texture)return;if(void 0===t.texture.texId&&""!==t.texture.textureImageFileName){void 0===this.texturesLoaded&&(this.texturesLoaded=[]);var r=this.getSameTexture(t.texture);if(void 0===r){if(e.backGround_fileReadings_count>10)return;if(t.texture.fileLoadState===a.fileLoadState.READY){var o=e.sceneState.gl;t.texture.texId=o.createTexture();var n=this.projectFolderName,s=e.readerWriter.geometryDataPath+"/"+n+"/"+this.buildingFileName+"/Images_Resized/"+t.texture.textureImageFileName;this.texturesLoaded.push(t.texture),e.readerWriter.readNeoReferenceTexture(o,s,t.texture,this,e),e.backGround_fileReadings_count++}}else r.fileLoadState===a.fileLoadState.LOADING_FINISHED&&(t.texture=r)}return t.texture.fileLoadState}if("0"===this.metaData.version[0]&&"0"===this.metaData.version[2]&&"1"===this.metaData.version[4]){if(void 0===t.texture||t.texture.fileLoadState===a.fileLoadState.READY){var l=t.materialId;if(i=this.texturesLoaded[l],t.texture=i,void 0===i.texId&&""!==i.textureImageFileName){if(e.backGround_fileReadings_count>10)return;if(i.fileLoadState===a.fileLoadState.READY){o=e.sceneState.gl;i.texId=o.createTexture();n=this.projectFolderName,s=e.readerWriter.getCurrentDataPath()+"/"+n+"/"+this.buildingFileName+"/Images_Resized/"+i.textureImageFileName;e.readerWriter.readNeoReferenceTexture(o,s,i,this,e),e.backGround_fileReadings_count++}}}return t.texture.fileLoadState}if("0"===this.metaData.version[0]&&"0"===this.metaData.version[2]&&"2"===this.metaData.version[4]){if(void 0===this.metaData.projectDataType||this.metaData.projectDataType>3)return t.texture.fileLoadState;if(void 0===t.texture||t.texture.fileLoadState===a.fileLoadState.READY){l=t.materialId;if(i=this.texturesLoaded[l],t.texture=i,void 0===i.texId&&""!==i.textureImageFileName){if(e.backGround_fileReadings_count>10)return;if(i.fileLoadState===a.fileLoadState.READY){o=e.sceneState.gl;i.texId=o.createTexture();n=this.projectFolderName,s=e.readerWriter.getCurrentDataPath()+"/"+n+"/"+this.buildingFileName+"/Images_Resized/"+i.textureImageFileName;e.readerWriter.readNeoReferenceTexture(o,s,i,this,e),e.backGround_fileReadings_count++}}}return t.texture.fileLoadState}},Dt.prototype.getShaderName=function(t,e,i){var r;return 0===i?t<=1&&(r="modelRefDepth"):1===i?t<=2&&(r="modelRefSsao"):2===i&&t<=1&&(r="modelRefSsao"),r},Dt.prototype.prepareSkin=function(t){var e=this.getHeaderVersion();if(void 0===e)return!1;if("0"!==e[0])return!1;void 0===this.lodMeshesMap&&(this.lodMeshesMap={});var i,r=this.projectFolderName,o=this.buildingFileName,n=t.readerWriter.geometryDataPath;i=this.getLowerSkinLodToLoad(this.currentLod);var s=this.getLodBuildingData(i);if(void 0===s)return!1;if(s.isModelRef)return!1;var l=s.textureFileName,d=s.geometryFileName,h=this.lodMeshesMap[d];if(void 0===h&&((h=new Pt).fileLoadState=a.fileLoadState.READY,h.textureName=l,h.legoKey=this.buildingId+"_"+d,this.lodMeshesMap[d]=h),-1===h.fileLoadState)return!1;if(h.fileLoadState===a.fileLoadState.READY){var c=n+"/"+r+"/"+o+"/"+d;t.readerWriter.getLegoArraybuffer(c,h,t),void 0===h.vbo_vicks_container.vboCacheKeysArray&&(h.vbo_vicks_container.vboCacheKeysArray=[])}if(h.vbo_vicks_container.vboCacheKeysArray[0]&&h.vbo_vicks_container.vboCacheKeysArray[0].vboBufferTCoord&&void 0===h.texture){h.texture=new nt;var u=n+"/"+r+"/"+o+"/"+l,f=t.sceneState.gl;t.readerWriter.readLegoSimpleBuildingTexture(f,u,h.texture,t)}return!0},Dt.prototype.render=function(t,e,i,r,o,n){t.sceneState.gl;if(void 0!==n&&(this.currentLod=n),5!==this.metaData.projectDataType)if(this.currentLod<=2){var a=this.getLodBuildingData(this.currentLod);if(a&&!a.isModelRef)this.renderSkin(t,e,i);else{var s=this.renderDetailed(t,e,i,r,o);if(void 0===this.currentVisibleOctreesControler)this.renderSkin(t,e,i);else s<.4*(this.currentVisibleOctreesControler.currentVisibles0.length+this.currentVisibleOctreesControler.currentVisibles1.length+this.currentVisibleOctreesControler.currentVisibles2.length)&&this.renderSkin(t,e,i)}}else this.currentLod>2&&this.renderSkin(t,e,i)},Dt.prototype.renderSkin=function(t,e,i){var r=this.getCurrentSkin();if(void 0!==r&&r.fileLoadState===a.fileLoadState.PARSE_FINISHED){var o=t.sceneState.gl;1===i&&t.magoPolicy.getObjectMoveMode()===a.moveMode.ALL&&t.buildingSelected===this&&t.renderer.enableStencilBuffer(o),t.renderer.currentObjectsRendering.curOctree=this;var n,s=t.renderer.currentObjectsRendering;2===i&&(t.selectionManager,t.selectionColor,l=!1,n=s.curNode,s.curOctree);var l=!0;if(1===i)this.isHighLighted?(o.uniform1i(e.colorType_loc,0),o.uniform4fv(e.oneColor4_loc,this.highLightColor4),l=!1):this.isColorChanged&&(o.uniform1i(e.colorType_loc,0),o.uniform4fv(e.oneColor4_loc,[this.aditionalColor.r,this.aditionalColor.g,this.aditionalColor.b,this.aditionalColor.a]),l=!1),void 0!==r.texture&&r.texture.texId&&l?(e.enableVertexAttribArray(e.texCoord2_loc),o.uniform1i(e.colorType_loc,2),e.last_tex_id!==r.texture.texId&&(o.bindTexture(o.TEXTURE_2D,r.texture.texId),e.last_tex_id=r.texture.texId)):void 0!==t.textureAux_1x1&&l?(e.enableVertexAttribArray(e.texCoord2_loc),o.uniform1i(e.colorType_loc,2),o.bindTexture(o.TEXTURE_2D,t.textureAux_1x1)):o.uniform1i(e.colorType_loc,0);else if(2===i){var d;d=t.selectionColor.getAvailableColor(d);var h=t.selectionColor.decodeColor3(d.r,d.g,d.b);t.selectionManager.setCandidates(h,void 0,void 0,this,n),o.uniform1i(e.colorType_loc,0),o.uniform4fv(e.oneColor4_loc,[d.r/255,d.g/255,d.b/255,1])}o.uniform1i(e.refMatrixType_loc,0),r.render(t,i,l,e),1===i&&t.magoPolicy.getObjectMoveMode()===a.moveMode.ALL&&t.buildingSelected===this&&t.renderer.disableStencilBuffer(o)}},Dt.prototype.renderDetailed=function(t,e,i,r,o){var n=0;if(void 0===this.currentVisibleOctreesControler)return n;var s,l=!1,d=t.sceneState.gl;0===i?l=!1:1===i&&(l=!!(this.texturesLoaded&&this.texturesLoaded.length>0),t.magoPolicy.getObjectMoveMode()===a.moveMode.ALL&&t.buildingSelected===this&&t.renderer.enableStencilBuffer(d)),t.renderer.currentObjectsRendering.curBuilding=this;var h,c,u,f=this.getRenderSettingApplyOcclusionCulling();void 0===f&&(f=!0),f&&(h=this.myCameraRelative.position.x,c=this.myCameraRelative.position.y,u=this.myCameraRelative.position.z);for(var g=0,p=this.currentVisibleOctreesControler.currentVisibles0.length,v=0;v=1&&(this.isAdult=!0),this.blendAlpha},Et.prototype.multiplyTransformMatrix=function(t){this._matrix4=this._originalMatrix4.getMultipliedByMatrix(t)},Et.prototype.multiplyKeyTransformMatrix=function(t,e){void 0===this.tMatrixAuxArray&&(this.tMatrixAuxArray=[]),this.tMatrixAuxArray[t]=this._originalMatrix4.getMultipliedByMatrix(e,this.tMatrixAuxArray[t]),this.moveVectorRelToBuilding&&(this.moveVector=e.rotatePoint3D(this.moveVectorRelToBuilding,this.moveVector))},Et.prototype.hasKeyMatrix=function(t){return void 0!==this.tMatrixAuxArray&&void 0!==this.tMatrixAuxArray[t]},Et.prototype.isReadyToRender=function(){return void 0!==this.tMatrixAuxArray},Et.prototype.solveReferenceColorOrTexture=function(t,e,i,r){var o=t.sceneState.gl,n=!1;t.selectionManager.parentSelected&&t.objectSelected===this&&(n=!0,t.magoPolicy.getObjectMoveMode()===a.moveMode.OBJECT&&t.renderer.enableStencilBuffer(o)),e.isHighLighted?(o.uniform1i(i.colorType_loc,0),o.uniform4fv(i.oneColor4_loc,t.highLightColor4)):e.isColorChanged?(o.uniform1i(i.colorType_loc,0),n?o.uniform4fv(i.oneColor4_loc,[1,0,0,1]):o.uniform4fv(i.oneColor4_loc,[e.aditionalColor.r,e.aditionalColor.g,e.aditionalColor.b,e.aditionalColor.a])):this.aditionalColor?(o.uniform1i(i.colorType_loc,0),n?o.uniform4fv(i.oneColor4_loc,[1,0,0,1]):o.uniform4fv(i.oneColor4_loc,[this.aditionalColor.r,this.aditionalColor.g,this.aditionalColor.b,this.aditionalColor.a])):t.magoPolicy.getObjectMoveMode()===a.moveMode.OBJECT&&n?(o.uniform1i(i.colorType_loc,0),o.uniform4fv(i.oneColor4_loc,[1,0,0,1])):t.magoPolicy.colorChangedObjectId===this.objectId?(o.uniform1i(i.colorType_loc,0),o.uniform4fv(i.oneColor4_loc,[t.magoPolicy.color[0],t.magoPolicy.color[1],t.magoPolicy.color[2],1])):this.hasTexture?void 0!==this.texture&&void 0!==this.texture.texId?(o.uniform1i(i.colorType_loc,2),i.last_tex_id!==this.texture.texId&&(o.bindTexture(o.TEXTURE_2D,this.texture.texId),i.last_tex_id=this.texture.texId)):(o.uniform1i(i.colorType_loc,0),o.uniform4fv(i.oneColor4_loc,[.8,0,.8,1])):(o.uniform1i(i.bUse1Color_loc,!0),this.color4?(o.uniform1i(i.colorType_loc,0),o.uniform4fv(i.oneColor4_loc,[this.color4.r/255,this.color4.g/255,this.color4.b/255,this.color4.a/255])):(o.uniform1i(i.colorType_loc,0),o.uniform4fv(i.oneColor4_loc,[.8,.8,.8,1])))},Et.prototype.render=function(t,e,i,r,o,n,s){if(!this.isReadyToRender())return!1;if(this.hasTexture){if(e.manageNeoReferenceTexture(this,t)!==a.fileLoadState.LOADING_FINISHED)return!1;if(void 0===this.texture)return!1;if(void 0===this.texture.texId)return!1}var l,d,h,c,u=t.renderer.currentObjectsRendering;2===i&&(l=t.selectionManager,d=t.selectionColor,r=!1,h=u.curNode,c=u.curOctree);var f=t.sceneState.gl,g=this._block_idx,p=e.motherBlocksArray[g];if(void 0===p)return!1;if((t.mouseLeftDown||t.mouseMiddleDown)&&(s=.5),!p.isReadyToRender(this,t,s))return!1;if(1===i)this.solveReferenceColorOrTexture(t,e,o,u);else if(2===i){this.selColor4=d.getAvailableColor(this.selColor4);var v=d.decodeColor3(this.selColor4.r,this.selColor4.g,this.selColor4.b);l.setCandidates(v,this,c,e,h),this.selColor4&&f.uniform4fv(o.oneColor4_loc,[this.selColor4.r/255,this.selColor4.g/255,this.selColor4.b/255,1])}if(this.aditionalColor=void 0,void 0===t.isTrailRender||!1===t.isTrailRender){var y=this.getBlendAlpha(t.currTime);f.uniform1f(o.externalAlpha_loc,y)}var m,x=p.vBOVertexIdxCacheKeysContainer.vboCacheKeysArray.length;f.uniform1i(o.refMatrixType_loc,this.refMatrixType),1===this.refMatrixType?f.uniform3fv(o.refTranslationVec_loc,this.refTranslationVec):2===this.refMatrixType&&f.uniformMatrix4fv(o.refMatrix_loc,!1,this.tMatrixAuxArray[n]._floatArrays),void 0!==this.moveVector?(f.uniform1i(o.hasAditionalMov_loc,!0),f.uniform3fv(o.aditionalMov_loc,[this.moveVector.x,this.moveVector.y,this.moveVector.z]),o.last_isAditionalMovedZero=!1):o.last_isAditionalMovedZero||(f.uniform1i(o.hasAditionalMov_loc,!1),f.uniform3fv(o.aditionalMov_loc,[0,0,0]),o.last_isAditionalMovedZero=!0);for(var b=0;bm.indicesCount&&(C=m.indicesCount):C=m.indicesCount,!m.bindDataIndice(o,t.vboMemoryManager))return!1;f.drawElements(f.TRIANGLES,C,f.UNSIGNED_SHORT,0)}return!0},Et.prototype.deleteObjects=function(t,e){this._id=void 0,this._block_idx=void 0,this._matrix4._floatArrays=void 0,this._matrix4=void 0,this._originalMatrix4._floatArrays=void 0,this._originalMatrix4=void 0,this.hasTexture=void 0,this.texture=void 0,this.color4&&this.color4.deleteObjects(),this.color4=void 0,this.selColor4&&this.selColor4.deleteObjects(),this.selColor4=void 0,this.moveVector&&this.moveVector.deleteObjects(),this.moveVector=void 0,this.bRendered=void 0,void 0!==this.vBOVertexIdxCacheKeysContainer&&(this.vBOVertexIdxCacheKeysContainer.deleteGlObjects(t,e),this.vBOVertexIdxCacheKeysContainer=void 0)};var Ot=function(){if(!(this instanceof Ot))throw new Error(z.CONSTRUCT_ERROR);this.motherNeoRefsList,this.neoRefsIndices=[],this.modelReferencedGroupsList,this.blocksList,this.fileLoadState=0,this.dataArraybuffer,this.succesfullyGpuDataBinded,this.exterior_ocCullOctree,this.interior_ocCullOctree,this.currentVisibleIndices=[],this.currentVisibleMRG,this.xhr};Ot.prototype.multiplyKeyTransformMatrix=function(t,e){for(var i=this.neoRefsIndices.length,r=0;r0&&(n=!0),n&&r){var a=this.interior_ocCullOctree.getIntersectedSubBoxByPoint3D(t,e,i);void 0!==a&&a._indicesArray.length>0?(this.currentVisibleIndices=a._indicesArray,o=!1):o=!0}else this.currentVisibleIndices=this.neoRefsIndices,this.currentVisibleMRG=this.modelReferencedGroupsList}if(o&&void 0!==this.exterior_ocCullOctree){n=!1;this.exterior_ocCullOctree._subBoxesArray&&this.exterior_ocCullOctree._subBoxesArray.length>0&&(n=!0),n&&r?(void 0===this.currentVisibleMRG&&(this.currentVisibleMRG=new Lt),this.currentVisibleIndices=this.exterior_ocCullOctree.getIndicesVisiblesForEye(t,e,i,this.currentVisibleIndices,this.currentVisibleMRG)):(this.currentVisibleIndices=this.neoRefsIndices,this.currentVisibleMRG=this.modelReferencedGroupsList)}},Ot.prototype.getNeoReference=function(t){return this.motherNeoRefsList[this.neoRefsIndices[t]]},Ot.prototype.deleteObjects=function(t,e){void 0!==this.xhr&&(this.xhr.abort(),this.xhr=void 0),this.motherNeoRefsList=void 0,this.neoRefsIndices=void 0,void 0!==this.blocksList&&void 0!==this.blocksList.xhr&&this.fileLoadState!==a.fileLoadState.READY&&(this.blocksList.xhr.abort(),this.blocksList.xhr=void 0),this.blocksList=void 0,this.fileLoadState=void 0,this.dataArraybuffer=void 0,this.exterior_ocCullOctree=void 0,this.interior_ocCullOctree=void 0},Ot.prototype.isReadyToRender=function(){return void 0!==this.neoRefsIndices&&0!==this.neoRefsIndices.length&&(void 0!==this.blocksList&&this.blocksList.fileLoadState===a.fileLoadState.PARSE_FINISHED)},Ot.prototype.setRenderedFalseToAllReferences=function(){for(var t=this.neoRefsIndices.length,e=0;e0&&void 0===y.vBOVertexIdxCacheKeysContainer&&(y.vBOVertexIdxCacheKeysContainer=new vt);for(O=0;O0){var V=i.readUInt32(e,d,d+4);d+=4;for(E=0;E0&&void 0===y.vBOVertexIdxCacheKeysContainer&&(y.vBOVertexIdxCacheKeysContainer=new vt);for(E=0;E0){var G,k="";V=i.readUInt32(e,d,d+4);d+=4;for(E=0;E0&&(y.texture=new nt,y.hasTexture=!0,y.texture.textureTypeName=k,y.texture.textureImageFileName=G)}else y.hasTexture=!1;o&&y.multiplyTransformMatrix(o)}}void 0===this.exterior_ocCullOctree&&(this.exterior_ocCullOctree=new Y);var H=this.exterior_ocCullOctree;d=this.exterior_ocCullOctree.parseArrayBuffer(e,d,i),H.expandBox(1e3),H.setSizesSubBoxes(),H.createModelReferencedGroups(this.motherNeoRefsList),void 0===this.interior_ocCullOctree&&(this.interior_ocCullOctree=new Y);var W=this.interior_ocCullOctree;return d=this.interior_ocCullOctree.parseArrayBuffer(e,d,i),W.setSizesSubBoxes(),W.createModelReferencedGroups(this.motherNeoRefsList),this.fileLoadState=a.fileLoadState.PARSE_FINISHED,this.succesfullyGpuDataBinded},Ot.prototype.render=function(t,e,i,r,o,n,s){var l=!0;if(!this.isReadyToRender())return!1;2===i&&(r=!1);var d=t.sceneState.gl;2===i&&(o.disableVertexAttribArray(o.texCoord2_loc),o.disableVertexAttribArray(o.normal3_loc)),0===i&&(o.disableVertexAttribArray(o.texCoord2_loc),o.disableVertexAttribArray(o.normal3_loc),o.disableVertexAttribArray(o.color4_loc)),r&&(d.activeTexture(d.TEXTURE2),1===i&&d.uniform1i(o.colorType_loc,2));var h=t.texturesManager.getTextureAux1x1();d.bindTexture(d.TEXTURE_2D,h),o.last_tex_id=h;for(var c=this.currentVisibleIndices.length,u=0,f=0;f1?1:0,s.getGeoLocationData(u).bindGeoLocationUniforms(l,e),l.uniform1f(e.externalAlpha_loc,1),n.currentLod=o.currentLod,n.render(t,e,i,r,h,o.currentLod),t.renderingFase=c,void 0!==this.data.animationData&&!0===this.data.animationData.finished&&(s.getGeoLocationDatasCount()>1?s.popGeoLocationData():this.data.animationData=void 0)}}},Nt.prototype.addChildren=function(t){t.setParent(this),this.children.push(t)},Nt.prototype.setParent=function(t){this.parent=t},Nt.prototype.getRoot=function(){return void 0===this.parent?this:this.parent.getRoot()},Nt.prototype.getClosestParentWithData=function(t){return this.data&&this.data[t]?this:this.parent?this.parent.getClosestParentWithData(t):void 0},Nt.prototype.extractNodesByDataName=function(t,e){this.data[e]&&t.push(this);for(var i=this.children.length,r=0;ri.durationInSeconds)o=i.targetLongitude,n=i.targetLatitude,a=i.targetAltitude,e=!0,this.data.animationData.finished=!0;else{i.targetLongitude,i.targetLatitude,i.targetAltitude;o=i.startLongitude+l*s,n=i.startLatitude+d*s,a=i.startAltitude+h*s,i.lastTime=r,e=!1}return this.changeLocationAndRotation(n,o,a,u.heading,u.pitch,u.roll,t),e},Nt.prototype.changeLocationAndRotationAnimated=function(t,e,i,r,o,n,a,s){void 0===this.data.animationData&&(this.data.animationData=new h);var l=this.data.animationData;l.finished=!1,l.birthTime=a.getCurrentTime();var d=this.getNodeGeoLocDataManager();if(void 0!==d){var c=d.getCurrentGeoLocationData();if(void 0!==c){var u=c.getGeographicCoords();if(void 0!==u&&u.longitude&&u.latitude&&u.altitude&&void 0!==u.longitude&&void 0!==u.latitude&&void 0!==u.altitude){l.startLongitude=u.longitude,l.startLatitude=u.latitude,l.startAltitude=u.altitude,l.targetLongitude=e,l.targetLatitude=t,l.targetAltitude=i;u.longitude,u.latitude,u.altitude;l.targetHeading=r,l.targetPitch=o,l.targetRoll=n,c.heading=l.targetHeading,c.pitch=l.targetPitch,c.roll=l.targetRoll;var f=3;if("object"==typeof s&&isNaN(s)){if(s.duration&&(f=s.duration),s.autoChangeRotation){var g,p=j.geographicToCartesianWgs84(l.targetLongitude,l.targetLatitude,l.targetAltitude,void 0),v=new Ae(p[0],p[1],p[2]);g=c.getTransformedRelativePositionNoApplyHeadingPitchRoll(v,g);var y=180*Math.atan(-g.x/g.y)/Math.PI,m=Math.sqrt(g.x*g.x+g.y*g.y),x=180*Math.atan(g.z/m)/Math.PI;c.heading=y,c.pitch=x,c.roll=l.targetRoll}}else f=s;l.durationInSeconds=f}}}},Nt.prototype.changeLocationAndRotation=function(t,e,i,r,o,n,a){var s;if(void 0!==(s=this.getClosestParentWithData("geoLocDataManager"))){var l,d=[];s.extractNodesByDataName(d,"neoBuilding"),s.data.geographicCoord.longitude=e,s.data.geographicCoord.latitude=t,s.data.geographicCoord.altitude=i;for(var h=d.length,c=0;c=2&&this.prepareSkinData(t)},Bt.prototype.prepareSkinData=function(t){if(void 0!==this.octree_number_name){void 0===this.lego&&(this.lego=new Pt,this.lego.birthTime=t.currTime,this.lego.fileLoadState=a.fileLoadState.READY,this.lego.legoKey=this.octreeKey+"_lego");var e=this.neoBuildingOwner;if(void 0!==e){var i=t.sceneState.gl,r=t.readerWriter.geometryDataPath,o=e.projectFolderName,n=e.buildingFileName,s=e.getHeaderVersion();if(this.lego.fileLoadState===a.fileLoadState.READY){var l=r+"/"+o+"/"+n+"/Bricks"+"/"+this.octree_number_name.toString()+"_Brick";if("v"===s[0])if(this.lego.vbo_vicks_container.vboCacheKeysArray[0]&&this.lego.vbo_vicks_container.vboCacheKeysArray[0].meshTexcoordsCacheKey){if(void 0===e.simpleBuilding3x3Texture){e.simpleBuilding3x3Texture=new nt;var d=r+"/"+o+"/"+(n=e.buildingFileName)+"/SimpleBuildingTexture3x3.png"}void 0!==e.simpleBuilding3x3Texture&&e.simpleBuilding3x3Texture.fileLoadState===a.fileLoadState.READY&&t.readerWriter.readLegoSimpleBuildingTexture(i,d,e.simpleBuilding3x3Texture,t),t.readerWriter.getOctreeLegoArraybuffer(l,this,t)}else t.readerWriter.getOctreeLegoArraybuffer(l,this,t);else{void 0===e.simpleBuilding3x3Texture&&(e.simpleBuilding3x3Texture=new nt);d=r+"/"+o+"/"+n+"/"+e.getImageFileNameForLOD(2);void 0!==e.simpleBuilding3x3Texture&&e.simpleBuilding3x3Texture.fileLoadState===a.fileLoadState.READY&&t.readerWriter.readLegoSimpleBuildingTexture(i,d,e.simpleBuilding3x3Texture,t),t.readerWriter.getOctreeLegoArraybuffer(l,this,t)}}}}},Bt.prototype.prepareModelReferencesListData=function(t){var e=this.neoBuildingOwner;if(void 0!==e&&(0!==this.triPolyhedronsCount&&void 0!==this.octree_number_name))if("0.0.2"!==e.getHeaderVersion()){var i=t.readerWriter.geometryDataPath,r=e.buildingFileName,o=e.projectFolderName;if(void 0===this.neoReferencesMotherAndIndices&&(this.neoReferencesMotherAndIndices=new Ot,this.neoReferencesMotherAndIndices.motherNeoRefsList=e.motherNeoReferencesArray),this.neoReferencesMotherAndIndices.fileLoadState===a.fileLoadState.READY){void 0===this.neoReferencesMotherAndIndices.blocksList&&(this.neoReferencesMotherAndIndices.blocksList=new Ct("0.0.1"));var n=i+"/"+o+"/"+r+"/References"+"/"+this.octree_number_name.toString()+"_Ref";t.readerWriter.getNeoReferencesArraybuffer(n,this,t)}var s=this.neoReferencesMotherAndIndices.blocksList;if(void 0!==s&&s.fileLoadState===a.fileLoadState.READY){var l=i+"/"+o+"/"+r+"/Models"+"/"+this.octree_number_name.toString()+"_Model";t.readerWriter.getNeoBlocksArraybuffer(l,this,t)}}else this.prepareModelReferencesListData_v002(t)},Bt.prototype.prepareModelReferencesListData_v002=function(t){var e=this.neoBuildingOwner;if(void 0!==e&&0!==this.triPolyhedronsCount&&void 0!==this.octree_number_name){var i=t.readerWriter.geometryDataPath,r=e.buildingFileName,o=e.projectFolderName;if(void 0===this.neoReferencesMotherAndIndices&&(this.neoReferencesMotherAndIndices=new Ot,this.neoReferencesMotherAndIndices.motherNeoRefsList=e.motherNeoReferencesArray),this.neoReferencesMotherAndIndices.fileLoadState===a.fileLoadState.READY){if(void 0===this.neoReferencesMotherAndIndices.blocksList){var n=new Ct("0.0.2");this.neoReferencesMotherAndIndices.blocksList=n,n.blocksArrayPartitionsCount=this.blocksListsPartitionsCount;var s=i+"/"+o+"/"+r+"/Models"+"/"+this.octree_number_name.toString()+"_Model_";n.blocksArrayPartitionsMasterPathName=s}var l=i+"/"+o+"/"+r+"/References"+"/"+this.octree_number_name.toString()+"_Ref";t.readerWriter.getNeoReferencesArraybuffer(l,this,t)}void 0!==(n=this.neoReferencesMotherAndIndices.blocksList)&&n.prepareData(t,this)}},Bt.prototype.renderSkin=function(t,e,i,r,o){var n=t.sceneState.gl;if(void 0===this.lego)return this.lego=new Pt,this.lego.fileLoadState=a.fileLoadState.READY,this.lego.legoKey=this.octreeKey+"_lego",!1;if(this.lego.fileLoadState!==a.fileLoadState.PARSE_FINISHED)return!1;if(r=!0,n.uniform1i(o.refMatrixType_loc,0),1===i){if(e.isHighLighted?(n.uniform1i(o.colorType_loc,0),n.uniform4fv(o.oneColor4_loc,this.highLightColor4),r=!1):e.isColorChanged&&(n.uniform1i(o.colorType_loc,0),n.uniform4fv(o.oneColor4_loc,[e.aditionalColor.r,e.aditionalColor.g,e.aditionalColor.b,e.aditionalColor.a]),r=!1),void 0===e.simpleBuilding3x3Texture||!e.simpleBuilding3x3Texture.texId||!r)return!1;n.uniform1i(o.textureFlipYAxis_loc,!1),n.uniform1i(o.colorType_loc,2),o.last_tex_id!==e.simpleBuilding3x3Texture.texId&&(n.bindTexture(n.TEXTURE_2D,e.simpleBuilding3x3Texture.texId),o.last_tex_id=e.simpleBuilding3x3Texture.texId)}else if(2===i){var s;s=t.selectionColor.getAvailableColor(s);var l=t.selectionColor.decodeColor3(s.r,s.g,s.b),d=t.renderer.currentObjectsRendering.curNode;t.selectionManager.setCandidates(l,void 0,this,e,d),n.uniform1i(o.colorType_loc,0),n.uniform4fv(o.oneColor4_loc,[s.r/255,s.g/255,s.b/255,1])}return this.lego.render(t,i,r,o)},Bt.prototype.renderContent=function(t,e,i,r,o,n,a,s){var l=!1,d=t.sceneState.gl;if(this.lod<2){if(void 0===this.neoReferencesMotherAndIndices)return;d.uniform1i(o.textureFlipYAxis_loc,s),(l=this.neoReferencesMotherAndIndices.render(t,e,i,r,o,n,a))||(l=this.renderSkin(t,e,i,r,o))}else 2===this.lod&&(l=this.renderSkin(t,e,i,r,o));return l},Bt.prototype.getPartitionsCountsForLod=function(t,e,i){var r=1;if(0===t)(r=e)>(o=i.magoPolicy.getPointsCloudSettings()).maxPartitionsLod0&&(r=o.maxPartitionsLod0);else if(1===t){var o=i.magoPolicy.getPointsCloudSettings();(r=Math.ceil(e/4))>o.maxPartitionsLod1&&(r=o.maxPartitionsLod1)}else t>1&&(r=1);return r},Bt.prototype.preparePCloudData=function(t){if(void 0===this.pCloudPartitionsCount&&0===this.pCloudPartitionsCount)return!1;var e=this.neoBuildingOwner;if(void 0===e)return!1;if(t.processQueue.existOctreeToDeletePCloud(this))return!1;void 0===this.pCloudPartitionsArray&&(this.pCloudPartitionsArray=[]);for(var i=this.getPartitionsCountsForLod(this.lod,this.pCloudPartitionsCount,t),r=0;r50){if(void 0!==this.pCloudPartitionsArray)for(p=this.pCloudPartitionsArray.length,v=0;v0?Math.floor(Math.log10(t)+1):1},Bt.prototype.getMotherOctree=function(){return void 0===this.octree_owner?this:this.octree_owner.getMotherOctree()},Bt.prototype.getOctree=function(t,e){if(1===e)return 0===t?this.getMotherOctree():this.subOctrees_array[t-1];var i=e-1,r=Math.pow(10,i),o=Math.floor(t/r)%10,n=t-o*r;return this.subOctrees_array[o-1].getOctree(n,e-1)},Bt.prototype.getOctreeByNumberName=function(t){var e=this.getMotherOctree(),i=this.getNumberOfDigits(t);if(1===i)return 0===t?e:e.subOctrees_array[t-1];if(0!==e.subOctrees_array.length){var r=i-1,o=Math.pow(10,r),n=Math.floor(t/o)%10,a=t-n*o;return e.subOctrees_array[n-1].getOctree(a,i-1)}},Bt.prototype.setSizesSubBoxes=function(){if(this.subOctrees_array.length>0){var t=this.centerPos.x,e=this.centerPos.y,i=this.centerPos.z,r=this.centerPos.x-this.half_dx,o=this.centerPos.y-this.half_dy,n=this.centerPos.z-this.half_dz,a=this.centerPos.x+this.half_dx,s=this.centerPos.y+this.half_dy,l=this.centerPos.z+this.half_dz;this.subOctrees_array[0].setBoxSize(r,t,o,e,n,i),this.subOctrees_array[1].setBoxSize(t,a,o,e,n,i),this.subOctrees_array[2].setBoxSize(t,a,e,s,n,i),this.subOctrees_array[3].setBoxSize(r,t,e,s,n,i),this.subOctrees_array[4].setBoxSize(r,t,o,e,i,l),this.subOctrees_array[5].setBoxSize(t,a,o,e,i,l),this.subOctrees_array[6].setBoxSize(t,a,e,s,i,l),this.subOctrees_array[7].setBoxSize(r,t,e,s,i,l);for(var d=0;d<8;d++)this.subOctrees_array[d].setSizesSubBoxes()}},Bt.prototype.setBoxSize=function(t,e,i,r,o,n){this.centerPos.x=(e+t)/2,this.centerPos.y=(r+i)/2,this.centerPos.z=(n+o)/2,this.half_dx=(e-t)/2,this.half_dy=(r-i)/2,this.half_dz=(n-o)/2},Bt.prototype.getCenterPos=function(){return this.centerPos},Bt.prototype.getRadiusAprox=function(){return 1.7*this.half_dx},Bt.prototype.getFrustumVisibleLowestOctreesByLOD=function(t,e,i,r,o,n,a,s){for(var l=[],d=!1,h=(l=this.getFrustumVisibleOctreesNeoBuildingAsimetricVersion(t,l,r)).length,c=0;c0&&(i&&this.putOctreeInEyeDistanceSortedArray(i.currentVisibles0,l[c]),e.currentVisibles0.push(l[c]),l[c].lod=0,d=!0):l[c].distToCamera0&&(i&&this.putOctreeInEyeDistanceSortedArray(i.currentVisibles1,l[c]),e.currentVisibles1.push(l[c]),l[c].lod=1,d=!0):l[c].distToCamera0&&(i&&this.putOctreeInEyeDistanceSortedArray(i.currentVisibles2,l[c]),e.currentVisibles2.push(l[c]),l[c].lod=2,d=!0):l[c].triPolyhedronsCount>0&&(i&&i.currentVisibles3.push(l[c]),e.currentVisibles3.push(l[c]),l[c].lod=3,d=!0);return l=void 0,d},Bt.prototype.intersectsWithPoint3D=function(t,e,i){var r=this.centerPos.x-this.half_dx,o=this.centerPos.y-this.half_dz,n=this.centerPos.z-this.half_dz,a=this.centerPos.x+this.half_dx,s=this.centerPos.y+this.half_dz,l=this.centerPos.z+this.half_dz,d=!1;return t>r&&to&&en&&i0){var o,n=this.centerPos.x,a=this.centerPos.y,s=this.centerPos.z;o=t0&&(e&&this.putOctreeInEyeDistanceSortedArray(e.currentVisibles0,this.lowestOctrees_array[d]),t.currentVisibles0.push(this.lowestOctrees_array[d]),this.lowestOctrees_array[d].lod=0,s=!0):this.lowestOctrees_array[d].distToCamera0&&(e&&this.putOctreeInEyeDistanceSortedArray(e.currentVisibles1,this.lowestOctrees_array[d]),t.currentVisibles1.push(this.lowestOctrees_array[d]),this.lowestOctrees_array[d].lod=1,s=!0):this.lowestOctrees_array[d].distToCamera0&&(e&&this.putOctreeInEyeDistanceSortedArray(e.currentVisibles2,this.lowestOctrees_array[d]),t.currentVisibles2.push(this.lowestOctrees_array[d]),this.lowestOctrees_array[d].lod=2,s=!0):this.lowestOctrees_array[d].triPolyhedronsCount>0&&(e&&e.currentVisibles3.push(this.lowestOctrees_array[d]),t.currentVisibles3.push(this.lowestOctrees_array[d]),this.lowestOctrees_array[d].lod=3,s=!0);return s},Bt.prototype.intersectionFrustum=function(t,e){return void 0===e&&(e=new it),e.centerPoint.x=this.centerPos.x,e.centerPoint.y=this.centerPos.y,e.centerPoint.z=this.centerPos.z,e.r=this.getRadiusAprox(),t.intersectionSphere(e)},Bt.prototype.getFrustumVisibleOctreesNeoBuildingAsimetricVersion=function(t,e,i){if(void 0!==this.subOctrees_array&&(0!==this.subOctrees_array.length||0!==this.triPolyhedronsCount)){void 0===e&&(e=[]);var r=this.intersectionFrustum(t,i);if(r===s.INTERSECTION_INSIDE)this.getAllSubOctreesIfHasRefLists(e);else if(r===s.INTERSECTION_INTERSECT)if(0===this.subOctrees_array.length)e.push(this);else for(var o=0,n=this.subOctrees_array.length;oe.distToCamera?(l=i,d=h):(l=h,d=r),this.getIndexToInsertBySquaredDistToEye(t,e,l,d)},Bt.prototype.putOctreeInEyeDistanceSortedArray=function(t,e){if(t.length>0){var i=t.length-1,r=this.getIndexToInsertBySquaredDistToEye(t,e,0,i);t.splice(r,0,e)}else t.push(e)},Bt.prototype.getAllSubOctreesIfHasRefLists=function(t){if(void 0!==this.subOctrees_array)if(void 0===t&&(t=[]),this.subOctrees_array.length>0)for(var e=0,i=this.subOctrees_array.length;e0&&t.push(this)},Bt.prototype.getAllSubOctrees=function(t){if(void 0===t&&(t=[]),this.subOctrees_array.length>0)for(var e=0,i=this.subOctrees_array.length;e0)t.push(this);else for(var i=0;i0)this.neoReferencesMotherAndIndices&&this.neoReferencesMotherAndIndices.multiplyKeyTransformMatrix(t,e);else for(var r=0;r0&&(this.neoBuildingOwner=r),"0.0.2"===o&&(this.blocksListsPartitionsCount=e.readInt32(t,i,i+4),i+=4);for(var f=0;f0&&(this.neoBuildingOwner=r),this.pCloudPartitionsCount=e.readInt32(t,i,i+4),i+=4;for(var u=0;ui&&n>0){for(var a,s,l,d=0;d0&&(h=!0),c.triPolyhedronsCount&&c.triPolyhedronsCount>0&&(h=!0),h&&(a=c.centerPos.squareDistToPoint(t),void 0===s?(s=a,l=c):a0)for(var r,o,n=0,a=this.maxNumParses,s=e.length,l=0;la))break}}},jt.prototype.parseArrayOctreesPCloud=function(t,e,i){if(Object.keys(this.octreesPCloudToParseMap).length>0){for(var r,o=this.maxNumParses,n=0,a=e.length,s=0;so)break}if(0===n)for(var l in this.octreesPCloudToParseMap)if(Object.prototype.hasOwnProperty.call(this.octreesPCloudToParseMap,l)){if(r=this.octreesPCloudToParseMap[l],this.eraseOctreePCloudToParse(r)){if(void 0===r.lego)continue;r.lego.parsePointsCloudData(r.lego.dataArrayBuffer,t,i),r.lego.dataArrayBuffer=void 0,n++}if(n>o)break}n>0&&this.selectionFbo&&(this.selectionFbo.dirty=!0)}},jt.prototype.parseArrayOctreesPCloudPartition=function(t,e,i){if(Object.keys(this.octreesPCloudPartitionToParseMap).length>0){for(var r,o=this.maxNumParses,n=0,a=e.length,s=0;so)break}if(0===n)for(var c in this.octreesPCloudPartitionToParseMap)if(Object.prototype.hasOwnProperty.call(this.octreesPCloudPartitionToParseMap,c)&&(r=this.octreesPCloudPartitionToParseMap[c],this.eraseOctreePCloudPartitionToParse(r)&&(h.parsePointsCloudData(t,h.dataArrayBuffer,i),n++),n>o))break;n>0&&this.selectionFbo&&(this.selectionFbo.dirty=!0)}},jt.prototype.parseArrayOctreesLod2Legos=function(t,e,i){if(Object.keys(this.octreesLod2LegosToParseMap).length>0){for(var r,o=this.maxNumParses,n=0,a=e.length,s=0;so)break}n>0&&i.selectionFbo&&(i.selectionFbo.dirty=!0)}},jt.prototype.parseArrayOctreesLod0Models=function(t,e,i){if(Object.keys(this.octreesLod0ModelsToParseMap).length>0){for(var r,o,n,s=this.maxNumParses,l=0,d=e.length,h=0;hs)break}l>0&&i.selectionFbo&&(i.selectionFbo.dirty=!0)}},jt.prototype.parseArrayOctreesLod0References=function(t,e,i){if(Object.keys(this.octreesLod0ReferencesToParseMap).length>0){for(var r,o=this.maxNumParses,n=0,a=e.length,s=0;so));s++);n>0&&i.selectionFbo&&(i.selectionFbo.dirty=!0)}},jt.prototype.parseOctreesLod0References=function(t,e,i){var r=!1;if(this.eraseOctreeLod0ReferencesToParse(e)){if(void 0===e.neoReferencesMotherAndIndices)return!1;if(void 0===e.neoReferencesMotherAndIndices.dataArraybuffer)return!1;if(e.neoReferencesMotherAndIndices.fileLoadState!==a.fileLoadState.LOADING_FINISHED)return!1;var o,n=e.neoBuildingOwner,s=n.nodeOwner;if(void 0===(o=s?s.getRoot():void 0))return!1;if(void 0===o.data)return!1;var l=o.data.geoLocDataManager;if(void 0===l)return!1;void 0===this.matrix4SC&&(this.matrix4SC=new k);var d=l.getCurrentGeoLocationData(),h=n.getHeaderVersion();this.matrix4SC.setByFloat32Array(d.rotMatrix._floatArrays),"v"===h[0]?e.neoReferencesMotherAndIndices.parseArrayBufferReferences(t,e.neoReferencesMotherAndIndices.dataArraybuffer,i.readerWriter,n,this.matrix4SC,i):e.neoReferencesMotherAndIndices.parseArrayBufferReferencesVersioned(t,e.neoReferencesMotherAndIndices.dataArraybuffer,i.readerWriter,n,this.matrix4SC,i),e.neoReferencesMotherAndIndices.multiplyKeyTransformMatrix(0,d.rotMatrix),e.neoReferencesMotherAndIndices.dataArraybuffer=void 0,r=!0}return r},jt.prototype.putOctreeLod0ReferencesToParse=function(t,e){void 0===e&&(e=0),this.octreesLod0ReferencesToParseMap[t.octreeKey]=t},jt.prototype.eraseOctreeLod0ReferencesToParse=function(t){var e=t.octreeKey;return!!this.octreesLod0ReferencesToParseMap.hasOwnProperty(e)&&(delete this.octreesLod0ReferencesToParseMap[e],!0)},jt.prototype.putOctreeLod0ModelsToParse=function(t,e){void 0===e&&(e=0),this.octreesLod0ModelsToParseMap[t.octreeKey]=t},jt.prototype.eraseOctreeLod0ModelsToParse=function(t){var e=t.octreeKey;return!!this.octreesLod0ModelsToParseMap.hasOwnProperty(e)&&(delete this.octreesLod0ModelsToParseMap[e],!0)},jt.prototype.putOctreeLod2LegosToParse=function(t,e){void 0===e&&(e=0),this.octreesLod2LegosToParseMap[t.octreeKey]=t},jt.prototype.eraseOctreeLod2LegosToParse=function(t){var e=t.octreeKey;return!!this.octreesLod2LegosToParseMap.hasOwnProperty(e)&&(delete this.octreesLod2LegosToParseMap[e],!0)},jt.prototype.putOctreePCloudToParse=function(t,e){void 0===e&&(e=0),this.octreesPCloudToParseMap[t.octreeKey]=t},jt.prototype.eraseOctreePCloudToParse=function(t){if(void 0===t)return!1;var e=t.octreeKey;return!!this.octreesPCloudToParseMap.hasOwnProperty(e)&&(delete this.octreesPCloudToParseMap[e],!0)},jt.prototype.putOctreePCloudPartitionToParse=function(t,e){void 0===e&&(e=0),this.octreesPCloudPartitionToParseMap[t.legoKey]=t},jt.prototype.eraseOctreePCloudPartitionToParse=function(t){if(void 0===t)return!1;var e=t.legoKey;return!!this.octreesPCloudPartitionToParseMap.hasOwnProperty(e)&&(delete this.octreesPCloudPartitionToParseMap[e],!0)},jt.prototype.putSkinLegosToParse=function(t,e){void 0===e&&(e=0),this.skinLegosToParseMap[t.legoKey]=t},jt.prototype.eraseSkinLegosToParse=function(t){var e=t.legoKey;return!!this.skinLegosToParseMap.hasOwnProperty(e)&&(delete this.skinLegosToParseMap[e],!0)},jt.prototype.clearAll=function(){this.octreesLod0ReferencesToParseMap={},this.octreesLod0ModelsToParseMap={},this.octreesLod2LegosToParseMap={}},jt.prototype.eraseAny=function(t){this.eraseOctreeLod0ReferencesToParse(t),this.eraseOctreeLod0ModelsToParse(t),this.eraseOctreeLod2LegosToParse(t)},jt.prototype.initCounters=function(){this.pCloudPartitionsParsed=0};var Ut=function(){if(!(this instanceof Ut))throw new Error(z.CONSTRUCT_ERROR);this.nodesToDeleteMap={},this.nodesToDeleteModelReferencesMap={},this.nodesToDeleteLessThanLod3Map={},this.nodesToDeleteLessThanLod4Map={},this.nodesToDeleteLessThanLod5Map={},this.nodesToDeleteLodMeshMap={},this.tinTerrainsToDeleteMap={},this.octreeToDeletePCloudsMap={}};Ut.prototype.putOctreeToDeletePCloud=function(t,e){if(void 0===e&&(e=0),void 0!==t){var i=t.octreeKey;this.octreeToDeletePCloudsMap[i]=t}},Ut.prototype.existOctreeToDeletePCloud=function(t){if(void 0===t)return!1;var e=t.octreeKey;return!!this.octreeToDeletePCloudsMap.hasOwnProperty(e)},Ut.prototype.eraseOctreeToDeletePCloud=function(t){if(void 0===t)return!1;var e=t.octreeKey;return!!this.octreeToDeletePCloudsMap.hasOwnProperty(e)&&(delete this.octreeToDeletePCloudsMap[e],!0)},Ut.prototype.putNodeToDeleteLodMesh=function(t,e){if(!t.isReferenceNode()&&(void 0===e&&(e=0),void 0!==t.data&&void 0!==t.data.neoBuilding)){var i=t.data.neoBuilding.buildingId;this.nodesToDeleteLodMeshMap[i]=t}},Ut.prototype.eraseNodeToDeleteLodMesh=function(t){if(void 0!==t.data&&void 0!==t.data.neoBuilding){var e=t.data.neoBuilding.buildingId;return!!this.nodesToDeleteLodMeshMap.hasOwnProperty(e)&&(delete this.nodesToDeleteLodMeshMap[e],!0)}},Ut.prototype.putTinTerrainToDelete=function(t,e){if(void 0===e&&(e=0),void 0!==t){var i=t.pathName;this.tinTerrainsToDeleteMap[i]=t}},Ut.prototype.eraseTinTerrainToDelete=function(t){if(void 0===t)return!1;var e=t.pathName;return!!this.tinTerrainsToDeleteMap.hasOwnProperty(e)&&(delete this.tinTerrainsToDeleteMap[e],!0)},Ut.prototype.putNodeToDeleteLessThanLod3=function(t,e){if(!t.isReferenceNode()&&(void 0===e&&(e=0),void 0!==t.data&&void 0!==t.data.neoBuilding)){var i=t.data.neoBuilding.buildingId;this.nodesToDeleteLessThanLod3Map[i]=t}},Ut.prototype.eraseNodeToDeleteLessThanLod3=function(t){if(void 0!==t.data&&void 0!==t.data.neoBuilding){var e=t.data.neoBuilding.buildingId;return!!this.nodesToDeleteLessThanLod3Map.hasOwnProperty(e)&&(delete this.nodesToDeleteLessThanLod3Map[e],!0)}},Ut.prototype.putNodeToDeleteLessThanLod4=function(t,e){if(!t.isReferenceNode()&&(void 0===e&&(e=0),void 0!==t.data&&void 0!==t.data.neoBuilding)){var i=t.data.neoBuilding.buildingId;this.nodesToDeleteLessThanLod4Map[i]=t}},Ut.prototype.eraseNodeToDeleteLessThanLod4=function(t){if(void 0!==t.data&&void 0!==t.data.neoBuilding){var e=t.data.neoBuilding.buildingId;return!!this.nodesToDeleteLessThanLod4Map.hasOwnProperty(e)&&(delete this.nodesToDeleteLessThanLod4Map[e],!0)}},Ut.prototype.putNodeToDeleteLessThanLod5=function(t,e){if(!t.isReferenceNode()&&(void 0===e&&(e=0),void 0!==t.data&&void 0!==t.data.neoBuilding)){var i=t.data.neoBuilding.buildingId;this.nodesToDeleteLessThanLod5Map[i]=t}},Ut.prototype.eraseNodeToDeleteLessThanLod5=function(t){if(void 0!==t.data&&void 0!==t.data.neoBuilding){var e=t.data.neoBuilding.buildingId;return!!this.nodesToDeleteLessThanLod5Map.hasOwnProperty(e)&&(delete this.nodesToDeleteLessThanLod5Map[e],!0)}},Ut.prototype.putNodeToDeleteModelReferences=function(t,e){if(!t.isReferenceNode()&&(void 0===e&&(e=0),void 0!==t.data&&void 0!==t.data.neoBuilding)){var i=t.data.neoBuilding.buildingId;this.nodesToDeleteModelReferencesMap[i]=t}},Ut.prototype.eraseNodeToDeleteModelReferences=function(t){if(void 0!==t.data&&void 0!==t.data.neoBuilding){var e=t.data.neoBuilding.buildingId;return!!this.nodesToDeleteModelReferencesMap.hasOwnProperty(e)&&(delete this.nodesToDeleteModelReferencesMap[e],!0)}},Ut.prototype.putNodeToDelete=function(t,e){if(!t.isReferenceNode()&&(void 0===e&&(e=0),void 0!==t.data&&void 0!==t.data.neoBuilding)){var i=t.data.neoBuilding.buildingId;this.nodesToDeleteMap[i]=t}},Ut.prototype.putNodesArrayToDelete=function(t,e){if(void 0!==t){void 0===e&&(e=0);for(var i=t.length,r=0;r0||e.motherNeoReferencesArray.length>0)&&s++,e.deleteObjectsModelReferences(r,t.vboMemoryManager),s>10)break}var l=0;for(var a in this.nodesToDeleteLessThanLod3Map)if(Object.prototype.hasOwnProperty.call(this.nodesToDeleteLessThanLod3Map,a)){if(void 0===(i=this.nodesToDeleteLessThanLod3Map[a]).data)continue;if(this.eraseNodeToDeleteLessThanLod3(i)){if(void 0===(e=i.data.neoBuilding))continue;if(e.octree&&(e.octree.deleteObjectsModelReferences(r,t.vboMemoryManager),e.octree.deletePCloudObjects(r,t.vboMemoryManager)),(e.motherBlocksArray.length>0||e.motherNeoReferencesArray.length>0)&&s++,e.deleteObjectsModelReferences(r,t.vboMemoryManager),e.deleteObjectsLod2(r,t.vboMemoryManager),++l>10)break}}for(var a in l=0,this.nodesToDeleteLessThanLod4Map)if(Object.prototype.hasOwnProperty.call(this.nodesToDeleteLessThanLod4Map,a)){if(void 0===(i=this.nodesToDeleteLessThanLod4Map[a]).data)continue;if(this.eraseNodeToDeleteLessThanLod4(i)){if(void 0===(e=i.data.neoBuilding))continue;if(e.deleteObjectsModelReferences(r,t.vboMemoryManager),e.deleteObjectsLod2(r,t.vboMemoryManager),e.deleteObjectsLodMesh(r,t.vboMemoryManager,"lod3"),++l>10)break}}for(var a in l=0,this.nodesToDeleteLessThanLod5Map)if(Object.prototype.hasOwnProperty.call(this.nodesToDeleteLessThanLod5Map,a)){if(void 0===(i=this.nodesToDeleteLessThanLod5Map[a]).data)continue;if(this.eraseNodeToDeleteLessThanLod5(i)){if(void 0===(e=i.data.neoBuilding))continue;if(e.deleteObjectsModelReferences(r,t.vboMemoryManager),e.deleteObjectsLod2(r,t.vboMemoryManager),e.deleteObjectsLodMesh(r,t.vboMemoryManager,"lod3"),e.deleteObjectsLodMesh(r,t.vboMemoryManager,"lod4"),++l>10)break}}l=0;for(var a in this.tinTerrainsToDeleteMap)if(Object.prototype.hasOwnProperty.call(this.tinTerrainsToDeleteMap,a)){var d=this.tinTerrainsToDeleteMap[a];if(void 0===d)continue;if(this.eraseTinTerrainToDelete(d)&&(d.deleteObjects(t),d=void 0,l++),l>10)break}l=0;for(var a in this.octreeToDeletePCloudsMap)if(Object.prototype.hasOwnProperty.call(this.octreeToDeletePCloudsMap,a)){var h=this.octreeToDeletePCloudsMap[a];if(void 0===h)continue;if(this.eraseOctreeToDeletePCloud(h)&&(h.deletePCloudObjects(r,t.vboMemoryManager),h=void 0,l++),l>1e4)break}};var Gt=function(){if(!(this instanceof Gt))throw new Error(z.CONSTRUCT_ERROR);this.root,this.nodesArray=[]},kt=function(){if(!(this instanceof kt))throw new Error(z.CONSTRUCT_ERROR);var t=l.getPolicy();void 0!==t&&(this.geometryDataPath=t.geo_data_path),this.geometrySubDataPath,this.j_counter,this.k_counter,this.referencesList_requested=0,this.blocksList_requested=0,this.blocksListPartitioned_requested=0,this.octreesSkinLegos_requested=0,this.skinLegos_requested=0,this.pCloudPartitionsMother_requested=0,this.pCloudPartitions_requested=0,this.gl,this.incre_latAng=.001,this.incre_longAng=.001,this.GAIA3D__offset_latitude=-.001,this.GAIA3D__offset_longitude=-.001,this.GAIA3D__counter=0,this.uint32,this.uint16,this.int16,this.float32,this.float16,this.int8,this.int8_value,this.max_color_value=126,this.startBuff,this.endBuff,this.filesReadings_count=0,this.temp_var_to_waste,this.countSC,this.xSC,this.ySC,this.zSC,this.point3dSC=new Ae,this.bboxSC=new v};function zt(t,e,i){var r=$.Deferred();return void 0===e&&(e=new XMLHttpRequest),e.open("GET",t,!0),e.responseType="arraybuffer",void 0!==i&&(e.timeout=i),e.onload=function(){e.status<200||e.status>=300?r.reject(e.status):r.resolve(e.response)},e.ontimeout=function(t){r.reject(-1)},e.onerror=function(t){console.log("Invalid XMLHttpRequest response type."),r.reject(e.status)},e.send(null),r.promise()}kt.prototype.getCurrentDataPath=function(){return void 0!==this.geometrySubDataPath&&""!==this.geometrySubDataPath?this.geometryDataPath+"/"+this.geometrySubDataPath:this.geometryDataPath},kt.prototype.readUInt32=function(t,e,i){return new Uint32Array(t.slice(e,i))[0]},kt.prototype.readInt32=function(t,e,i){return new Int32Array(t.slice(e,i))[0]},kt.prototype.readUInt16=function(t,e,i){return new Uint16Array(t.slice(e,i))[0]},kt.prototype.readInt16=function(t,e,i){return new Int16Array(t.slice(e,i))[0]},kt.prototype.readFloat64=function(t,e,i){return new Float64Array(t.slice(e,i))[0]},kt.prototype.readFloat32=function(t,e,i){return new Float32Array(t.slice(e,i))[0]},kt.prototype.readFloat16=function(t,e,i){return new Float32Array(t.slice(e,i))[0]},kt.prototype.readInt8=function(t,e,i){return new Int8Array(t.slice(e,i))[0]},kt.prototype.readUInt8=function(t,e,i){return new Uint8Array(t.slice(e,i))[0]},kt.prototype.readInt8ByteColor=function(t,e,i){var r=new Int8Array(t.slice(e,i))[0];return r>max_color_value&&(r=max_color_value),r<0&&(r+=256),r},kt.prototype.getNeoBlocksArraybuffer=function(t,e,i){i.fileRequestControler.modelRefFilesRequestedCount+=1;var r=e.neoReferencesMotherAndIndices.blocksList;r.fileLoadState=a.fileLoadState.LOADING_STARTED,r.xhr=void 0,this.blocksList_requested++,zt(t,void 0).done(function(t){var o=t;o?(r.dataArraybuffer=o,r.fileLoadState=a.fileLoadState.LOADING_FINISHED,o=null,i.parseQueue.putOctreeLod0ModelsToParse(e)):r.fileLoadState=500}).fail(function(t){console.log("Invalid XMLHttpRequest status = "+t),r.fileLoadState=0===t?500:-1===t?a.fileLoadState.READY:t}).always(function(){i.readerWriter.blocksList_requested--,i.fileRequestControler.modelRefFilesRequestedCount-=1,i.fileRequestControler.modelRefFilesRequestedCount<0&&(i.fileRequestControler.modelRefFilesRequestedCount=0)})},kt.prototype.getNeoBlocksArraybuffer_partition=function(t,e,i,r){r.fileRequestControler.modelRefFilesRequestedCount+=1,i.fileLoadState=a.fileLoadState.LOADING_STARTED,this.blocksListPartitioned_requested++,zt(t,void 0).done(function(t){var o=t;o?(i.dataArraybuffer=o,i.fileLoadState=a.fileLoadState.LOADING_FINISHED,o=null,r.parseQueue.putOctreeLod0ModelsToParse(e)):i.fileLoadState=500}).fail(function(t){console.log("Invalid XMLHttpRequest status = "+t),i.fileLoadState=0===t?500:-1===t?a.fileLoadState.READY:t}).always(function(){r.readerWriter.blocksListPartitioned_requested--,r.fileRequestControler.blocksListPartitioned_requested<0&&(r.fileRequestControler.blocksListPartitioned_requested=0)})},kt.prototype.getNeoReferencesArraybuffer=function(t,e,i){void 0!==e.neoReferencesMotherAndIndices&&(i.fileRequestControler.modelRefFilesRequestedCount+=1,e.neoReferencesMotherAndIndices.fileLoadState=a.fileLoadState.LOADING_STARTED,e.neoReferencesMotherAndIndices.xhr=void 0,this.referencesList_requested++,zt(t,void 0).done(function(t){var r=t;if(r){var o=e.neoReferencesMotherAndIndices;o&&(o.dataArraybuffer=r,o.fileLoadState=a.fileLoadState.LOADING_FINISHED,i.parseQueue.putOctreeLod0ReferencesToParse(e)),r=null}else e.neoReferencesMotherAndIndices.fileLoadState=a.fileLoadState.LOAD_FAILED}).fail(function(t){console.log("xhr status = "+t),e.neoReferencesMotherAndIndices.fileLoadState=0===t?a.fileLoadState.LOAD_FAILED:-1===t?a.fileLoadState.READY:t}).always(function(){i.readerWriter.referencesList_requested--,i.fileRequestControler.modelRefFilesRequestedCount-=1,i.fileRequestControler.modelRefFilesRequestedCount<0&&(i.fileRequestControler.modelRefFilesRequestedCount=0)}))},kt.prototype.getOctreeLegoArraybuffer=function(t,e,i){if(void 0!==e.lego){this.octreesSkinLegos_requested++,i.fileRequestControler.filesRequestedCount+=1,e.lego.fileLoadState=a.fileLoadState.LOADING_STARTED;var r=new XMLHttpRequest;e.lego.xhr=r,zt(t,r).done(function(t){var r=t;r?(e.lego?(e.lego.dataArrayBuffer=r,e.lego.fileLoadState=a.fileLoadState.LOADING_FINISHED,i.parseQueue.putOctreeLod2LegosToParse(e)):e=void 0,r=null):e.lego.fileLoadState=500}).fail(function(t){console.log("xhr status = "+t),e.lego.fileLoadState=0===t?500:t}).always(function(){i.readerWriter.octreesSkinLegos_requested--,i.fileRequestControler.filesRequestedCount-=1,i.fileRequestControler.filesRequestedCount<0&&(i.fileRequestControler.filesRequestedCount=0)})}},kt.prototype.getOctreePCloudArraybuffer=function(t,e,i){void 0!==e.lego&&(i.fileRequestControler.filesRequestedCount+=1,e.lego.fileLoadState=a.fileLoadState.LOADING_STARTED,zt(t).done(function(t){var r=t;r?(e.lego?(e.lego.dataArrayBuffer=r,e.lego.fileLoadState=a.fileLoadState.LOADING_FINISHED,i.parseQueue.putOctreePCloudToParse(e)):e=void 0,r=null):e.lego.fileLoadState=500}).fail(function(t){console.log("xhr status = "+t),e.lego.fileLoadState=0===t?500:t}).always(function(){i.fileRequestControler.filesRequestedCount-=1,i.fileRequestControler.filesRequestedCount<0&&(i.fileRequestControler.filesRequestedCount=0)}))},kt.prototype.getOctreePCloudPartitionArraybuffer=function(t,e,i,r){i.fileLoadState=a.fileLoadState.LOADING_STARTED;var o=e.octree_level;0===o?r.readerWriter.pCloudPartitionsMother_requested++:r.readerWriter.pCloudPartitions_requested++,zt(t).done(function(t){var r=t;r?(e&&i&&(i.dataArrayBuffer=r,i.fileLoadState=a.fileLoadState.LOADING_FINISHED),r=null):i.fileLoadState=500}).fail(function(t){console.log("xhr status = "+t),i.fileLoadState=0===t?500:t}).always(function(){0===o?(r.readerWriter.pCloudPartitionsMother_requested--,r.readerWriter.pCloudPartitionsMother_requested<0&&(r.readerWriter.pCloudPartitionsMother_requested=0)):(r.readerWriter.pCloudPartitions_requested--,r.readerWriter.pCloudPartitions_requested<0&&(r.readerWriter.pCloudPartitions_requested=0))})},kt.prototype.getLegoArraybuffer=function(t,e,i){this.skinLegos_requested++,i.fileRequestControler.lowLodDataRequestedCount+=1,e.fileLoadState=a.fileLoadState.LOADING_STARTED,e.xhr=void 0,zt(t,void 0).done(function(t){var r=t;r?(e&&(e.dataArrayBuffer=r,e.fileLoadState=a.fileLoadState.LOADING_FINISHED,i.parseQueue.putSkinLegosToParse(e)),r=null):e.fileLoadState=500}).fail(function(t){console.log("xhr status = "+t),e.fileLoadState=0===t?500:-1}).always(function(){i.readerWriter.skinLegos_requested--,i.fileRequestControler.lowLodDataRequestedCount-=1,i.fileRequestControler.lowLodDataRequestedCount<0&&(i.fileRequestControler.lowLodDataRequestedCount=0)})},kt.prototype.getObjectIndexFileForSmartTile=function(t,e,i,r){zt(t).done(function(t){var o=t;o&&(i.dataArrayBuffer=o,i.parseBuildingSeedArrayBuffer(),e.makeSmartTile(i,r),o=null)}).fail(function(t){console.log("xhr status = "+t)}).always(function(){})},kt.prototype.getObjectIndexFile=function(t,e,i,r){zt(t).done(function(t){var o=t;o&&(e.parseObjectIndexFile(o,i),o=null,r.createDeploymentGeoLocationsForHeavyIndustries())}).fail(function(t){console.log("xhr status = "+t)}).always(function(){})},kt.prototype.parseObjectIndexFile=function(t,e){var i,r,o,n,a=0,s=this.readInt32(t,a,a+4);a+=4;for(var l=0;l0){var v=new nt;v.textureTypeName=c,v.textureImageFileName=h,void 0===i.texturesLoaded&&(i.texturesLoaded=[]),i.texturesLoaded.push(v)}}var y=new Uint8Array(e.slice(n,n+1))[0];if(n+=1,void 0!==y){i.lodBuildingDatasMap={};for(d=0;d=0;--n)for(o=0;o0&&void 0!==i.texId&&(t.bindTexture(t.TEXTURE_2D,i.texId),t.texImage2D(t.TEXTURE_2D,0,n,o.header.width,o.header.height,0,n,t.UNSIGNED_BYTE,o.imageData),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),t.generateMipmap(t.TEXTURE_2D),i.fileLoadState=a.fileLoadState.LOADING_FINISHED,t.bindTexture(t.TEXTURE_2D,null))}}}).fail(function(t){r&&(console.log("xhr status = "+t),r.metaData.fileLoadState=0===t?500:t)}).always(function(){o.backGround_fileReadings_count-=1,o.backGround_fileReadings_count<0&&(o.backGround_fileReadings_count=0)});else{var s=new Image;i.fileLoadState=a.fileLoadState.LOADING_STARTED,s.onload=function(){void 0!==i.texId&&(st(t,s,i.texId),i.fileLoadState=a.fileLoadState.LOADING_FINISHED,o.backGround_fileReadings_count>0&&(o.backGround_fileReadings_count-=1))},s.onerror=function(){},s.src=e}},kt.loadBinaryData=function(t,e,i){e.fileLoadState=a.fileLoadState.LOADING_STARTED,zt(t).done(function(t){var r=t;r?(e.dataArraybuffer=r,e.fileLoadState=a.fileLoadState.LOADING_FINISHED,r=null,i.parseData(e)):e.fileLoadState=500}).fail(function(t){console.log("Invalid XMLHttpRequest status = "+t),e.fileLoadState=0===t?500:t}).always(function(){})},kt.loadImage=function(t,e,i){var r=new Image;i.fileLoadState=a.fileLoadState.LOADING_STARTED,r.onload=function(){var e,o,n,s,l,d;void 0!==i.texId&&(i.texId=(e=t,o=t.LINEAR,n=r,d=e.createTexture(),e.bindTexture(e.TEXTURE_2D,d),e.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,o),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,o),n instanceof Uint8Array?e.texImage2D(e.TEXTURE_2D,0,e.RGBA,s,l,0,e.RGBA,e.UNSIGNED_BYTE,n):e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,n),e.bindTexture(e.TEXTURE_2D,null),d),i.fileLoadState=a.fileLoadState.LOADING_FINISHED)},r.onerror=function(){},r.src=e},kt.prototype.readLegoSimpleBuildingTexture=function(t,e,i,r){var o=new Image;i.fileLoadState=a.fileLoadState.LOADING_STARTED,r.fileRequestControler.lowLodImagesRequestedCount+=1,o.onload=function(){void 0===i.texId&&(i.texId=t.createTexture()),st(t,o,i.texId),i.fileLoadState=a.fileLoadState.LOADING_FINISHED,r.fileRequestControler.lowLodImagesRequestedCount-=1,r.backGround_fileReadings_count>0&&(r.backGround_fileReadings_count-=1),r.fileRequestControler.lowLodImagesRequestedCount<0&&(r.fileRequestControler.lowLodImagesRequestedCount=0)},o.onerror=function(){void 0===i.texId&&(i.texId=t.createTexture(),t.bindTexture(t.TEXTURE_2D,i.texId),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,1,1,0,t.RGBA,t.UNSIGNED_BYTE,new Uint8Array([200,200,200,255])),t.bindTexture(t.TEXTURE_2D,null)),i.fileLoadState=a.fileLoadState.READY,r.fileRequestControler.lowLodImagesRequestedCount-=1,r.fileRequestControler.lowLodImagesRequestedCount<0&&(r.fileRequestControler.lowLodImagesRequestedCount=0)},o.src=e},kt.prototype.getTileArrayBuffer=function(t,e,i,r,o){i.fileReading_started=!0,zt(e).done(function(t){var e=t;e&&(i.fileArrayBuffer=e,i.fileReading_finished=!0,o.backGround_fileReadings_count>0&&(o.backGround_fileReadings_count-=1),e=null)}).fail(function(t){console.log("xhr status = "+t)}).always(function(){})},kt.prototype.loadTINTerrain=function(t,e,i){e.fileLoadState=a.fileLoadState.LOADING_STARTED,zt(t).done(function(t){var i=t;i?(e.dataArrayBuffer=i,e.fileLoadState=a.fileLoadState.LOADING_FINISHED,i=void 0):e.fileLoadState=500}).fail(function(t){e.fileLoadState=a.fileLoadState.LOAD_FAILED}).always(function(){})},kt.prototype.imageFromArrayBuffer=function(t,e,i,r,o){var n=new Blob([e],{type:"image/png"}),s=(window.URL||window.webkitURL).createObjectURL(n),l=new Image;l.onload=function(){void 0===o&&(o=!1),void 0===i.texId&&(i.texId=t.createTexture()),st(t,l,i.texId,o),i.fileLoadState=a.fileLoadState.LOADING_FINISHED,e=null},l.onerror=function(){},l.src=s},kt.prototype.loadWMSImage=function(t,e,i,r,o){i.fileLoadState=a.fileLoadState.LOADING_STARTED;var n=this;zt(e).done(function(e){var s=e;s&&(void 0===o&&(o=!1),n.imageFromArrayBuffer(t,s,i,r,o),i.fileLoadState=a.fileLoadState.LOADING_FINISHED)}).fail(function(t){console.log(t)}).always(function(){r.backGround_fileReadings_count-=1,r.backGround_fileReadings_count<0&&(r.backGround_fileReadings_count=0)})},kt.prototype.handleTextureLoaded=function(t,e,i){t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),t.bindTexture(t.TEXTURE_2D,i),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,e),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.REPEAT),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.REPEAT),t.generateMipmap(t.TEXTURE_2D),t.bindTexture(t.TEXTURE_2D,null)};var Ht=function(t){if(!(this instanceof Ht))throw new Error(z.CONSTRUCT_ERROR);this.owner,this.depth,t?(this.owner=t,this.depth=t.depth+1):this.depth=0,this.childArray,this.childMap,this.X,this.Y,this.centerX,this.centerY,this.centerZ,this.cartesiansArray,this.normalsArray,this.texCoordsArray,this.colorsArray,this.indices,this.geographicExtent,this.sphereExtent,this.fileLoadState=0,this.dataArrayBuffer,this.vboKeyContainer,this.terrainPositionHIGH,this.terrainPositionLOW,this.indexName,this.pathName,this.texture,this.visible,this.imageryGeoExtent};Ht.prototype.deleteObjects=function(t){var e=t.sceneState.gl;if(void 0!==this.childMap){var i=this.childMap.LU;void 0!==i&&(i.deleteObjects(t),delete this.childMap.LU);var r=this.childMap.LD;void 0!==r&&(r.deleteObjects(t),delete this.childMap.LD);var o=this.childMap.RU;void 0!==o&&(o.deleteObjects(t),delete this.childMap.RU);var n=this.childMap.RD;void 0!==n&&(n.deleteObjects(t),delete this.childMap.RD),this.childMap=void 0}this.depth<2||(this.owner=void 0,this.depth=void 0,this.childArray=void 0,this.childMap=void 0,this.X=void 0,this.Y=void 0,void 0!==this.geographicExtent&&(this.geographicExtent.deleteObjects(),this.geographicExtent=void 0),void 0!==this.sphereExtent&&(this.sphereExtent.deleteObjects(),this.sphereExtent=void 0),this.fileLoadState=0,this.dataArrayBuffer=void 0,void 0!==this.vboKeyContainer&&(this.vboKeyContainer.deleteGlObjects(e,t.vboMemoryManager),this.vboKeyContainer=void 0),this.terrainPositionHIGH=void 0,this.terrainPositionLOW=void 0,this.indexName=void 0,this.pathName=void 0,void 0!==this.texture&&(this.texture.deleteObjects(e),this.texture=void 0),this.visible=void 0)},Ht.prototype.getPathName=function(){return this.depth.toString()+"\\"+this.X.toString()+"\\"+this.Y.toString()},Ht.prototype.setGeographicExtent=function(t,e,i,r,o,n){void 0===this.geographicExtent&&(this.geographicExtent=new V);var a=this.geographicExtent;void 0===a.minGeographicCoord&&(a.minGeographicCoord=new F),void 0===a.maxGeographicCoord&&(a.maxGeographicCoord=new F),a.minGeographicCoord.setLonLatAlt(t,e,i),a.maxGeographicCoord.setLonLatAlt(r,o,n)},Ht.prototype.isPrepared=function(){return this.fileLoadState===a.fileLoadState.LOAD_FAILED||this.fileLoadState===a.fileLoadState.PARSE_FINISHED&&(void 0!==this.texture&&this.texture.fileLoadState===a.fileLoadState.LOADING_FINISHED&&(void 0!==this.vboKeyContainer&&void 0!==this.vboKeyContainer.vboCacheKeysArray&&0!==this.vboKeyContainer.vboCacheKeysArray.length))},Ht.prototype.prepareTexture=function(t,e){var i=t.sceneState.gl;this.texture=new nt;e.geoServURL;var r=this.depth.toString(),o=this.X.toString(),n=this.Y.toString(),a=(o=Math.floor(this.X/2).toString(),"https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/"+r+"/"+n+"/"+o+".png");t.readerWriter.loadWMSImage(i,a,this.texture,t,!1)},Ht.prototype.prepareTinTerrainPlain=function(t,e){return void 0===this.owner||this.owner.isPrepared()?(t.processQueue.eraseTinTerrainToDelete(this),this.fileLoadState=a.fileLoadState.PARSE_FINISHED,void(this.fileLoadState===a.fileLoadState.READY||this.fileLoadState===a.fileLoadState.LOADING_FINISHED||(this.fileLoadState===a.fileLoadState.PARSE_FINISHED&&void 0===this.vboKeyContainer?(this.calculateCenterPosition(),this.makeMeshVirtually(20,20,void 0,void 0),this.makeVbo(t.vboMemoryManager)):void 0===this.texture&&this.prepareTexture(t,e)))):void this.owner.prepareTinTerrainPlain(t,e)},Ht.prototype.prepareTinTerrain=function(t,e){if(void 0===this.owner||this.owner.isPrepared())if(t.processQueue.eraseTinTerrainToDelete(this),this.fileLoadState===a.fileLoadState.READY){var i="CesiumTerrain/"+this.getPathName()+".terrain";t.readerWriter.loadTINTerrain(i,this,t)}else this.fileLoadState===a.fileLoadState.LOADING_FINISHED?t.parseQueue.putTinTerrainToParse(this,0):this.fileLoadState===a.fileLoadState.PARSE_FINISHED&&void 0===this.vboKeyContainer?(this.decodeData(),this.makeVbo(t.vboMemoryManager)):void 0===this.texture&&this.prepareTexture(t,e);else this.owner.prepareTinTerrain(t,e)},Ht.prototype.hasChildren=function(){return void 0!==this.childMap&&this.childMap.length>0},Ht.prototype.deleteTinTerrain=function(t){if(this.hasChildren()){for(var e in this.childMap){if(Object.prototype.hasOwnProperty.call(this.childMap,e))this.childMap[e].deleteTinTerrain(t)}return!1}return t.parseQueue.eraseTinTerrainToParse(this),t.processQueue.putTinTerrainToDelete(this,0),delete this.owner.childMap[this.indexName],0===this.owner.childMap.length&&(this.owner.childMap=void 0),!0},Ht.prototype.render=function(t,e,i){if(void 0===this.owner||this.owner.isPrepared())if(this.isPrepared()){if(this.fileLoadState===a.fileLoadState.LOAD_FAILED)return;var r=e.sceneState.gl;r.bindTexture(r.TEXTURE_2D,this.texture.texId),r.uniform3fv(t.buildingPosHIGH_loc,this.terrainPositionHIGH),r.uniform3fv(t.buildingPosLOW_loc,this.terrainPositionLOW);var o=this.vboKeyContainer.vboCacheKeysArray[0];if(!o.bindDataPosition(t,e.vboMemoryManager))return!1;if(!i&&!o.bindDataTexCoord(t,e.vboMemoryManager))return!1;if(!o.bindDataIndice(t,e.vboMemoryManager))return!1;var n=o.indicesCount;r.drawElements(r.TRIANGLES,n,r.UNSIGNED_SHORT,0)}else void 0!==this.owner&&this.owner.render(t,e,i);else this.owner.render(t,e,i)},Ht.prototype.getFrustumIntersectedTinTerrainsQuadTree=function(t,e,i,r,o,n){if(void 0!==this.geographicExtent&&void 0!==this.geographicExtent.minGeographicCoord&&void 0!==this.geographicExtent.maxGeographicCoord){var a=this.geographicExtent.minGeographicCoord,l=this.geographicExtent.maxGeographicCoord;void 0===this.sphereExtent&&(this.sphereExtent=tt.computeSphereExtent(r,a,l,this.sphereExtent));var d=this.sphereExtent,h=t.intersectionSphere(d);if(h===s.INTERSECTION_OUTSIDE)return this.visible=!1,void n.push(this);if(h===s.INTERSECTION_INTERSECT||h===s.INTERSECTION_INSIDE){if(i.distToSphere(d)>5e3)return this.visible=!0,void o.push(this);if(!(this.depth>1^-(1&t)},Ht.prototype.makeVbo=function(t){if(void 0!==this.cartesiansArray){for(var e=this.cartesiansArray.length/3,i=0;i65536?(this.indices=new Uint32Array(t.slice(e,e+4*d*3)),e+=4*d*3):(this.indices=new Uint16Array(t.slice(e,e+2*d*3)),e+=2*d*3);var h=0,c=this.indices.length;for(s=0;s65536?(this.westVertexCount=new Uint32Array(t.slice(e,e+4)),e+=4,this.westIndices=new Uint32Array(t.slice(e,e+4*this.westVertexCount)),e+=4*this.westVertexCount,this.southVertexCount=new Uint32Array(t.slice(e,e+4)),e+=4,this.southIndices=new Uint32Array(t.slice(e,e+4*this.southVertexCount)),e+=4*this.southVertexCount,this.eastVertexCount=new Uint32Array(t.slice(e,e+4)),e+=4,this.eastIndices=new Uint32Array(t.slice(e,e+4*this.eastVertexCount)),e+=4*this.eastVertexCount,this.northVertexCount=new Uint32Array(t.slice(e,e+4)),e+=4,this.northIndices=new Uint32Array(t.slice(e,e+4*this.northVertexCount)),e+=4*this.northVertexCount):(this.westVertexCount=new Uint32Array(t.slice(e,e+4)),e+=4,this.westIndices=new Uint16Array(t.slice(e,e+2*this.westVertexCount)),e+=2*this.westVertexCount,this.southVertexCount=new Uint32Array(t.slice(e,e+4)),e+=4,this.southIndices=new Uint16Array(t.slice(e,e+2*this.southVertexCount)),e+=2*this.southVertexCount,this.eastVertexCount=new Uint32Array(t.slice(e,e+4)),e+=4,this.eastIndices=new Uint16Array(t.slice(e,e+2*this.eastVertexCount)),e+=2*this.eastVertexCount,this.northVertexCount=new Uint32Array(t.slice(e,e+4)),e+=4,this.northIndices=new Uint16Array(t.slice(e,e+2*this.northVertexCount)),e+=2*this.northVertexCount),this.extensionId=new Uint8Array(t.slice(e,e+1)),e+=1,this.extensionLength=new Uint32Array(t.slice(e,e+4)),e+=4,this.fileLoadState=a.fileLoadState.PARSE_FINISHED,t=void this.extensionId.length};var Wt=function(){if(!(this instanceof Wt))throw new Error(z.CONSTRUCT_ERROR);this.maxDepth=17,this.currentVisibles_terrName_geoCoords_map={},this.currentTerrainsMap={},this.visibleTilesArray=[],this.noVisibleTilesArray=[],this.tinTerrainsQuadTreeAsia,this.tinTerrainsQuadTreeAmerica,this.geoServURL="http://192.168.10.57:9090/geoserver/gwc/service/wmts",this.terrainType=0,this.init()};Wt.prototype.init=function(){this.tinTerrainsQuadTreeAsia=new Ht(void 0),this.tinTerrainsQuadTreeAmerica=new Ht(void 0);var t=0,e=-90,i=0,r=180,o=90,n=0;this.tinTerrainsQuadTreeAsia.setGeographicExtent(t,e,i,r,o,n),this.tinTerrainsQuadTreeAsia.X=1,this.tinTerrainsQuadTreeAsia.Y=0,t=-180,e=-90,i=0,r=0,o=90,n=0,this.tinTerrainsQuadTreeAmerica.setGeographicExtent(t,e,i,r,o,n),this.tinTerrainsQuadTreeAmerica.X=0,this.tinTerrainsQuadTreeAmerica.Y=0;var a=j.equatorialRadius(),s=a*Math.PI/2,l=-s,d=s;this.tinTerrainsQuadTreeAsia.imageryGeoExtent=new V,this.tinTerrainsQuadTreeAsia.imageryGeoExtent.setExtent(-20037507.22959434,l,0,20037507.22959434,d,0),this.tinTerrainsQuadTreeAmerica.imageryGeoExtent=new V,this.tinTerrainsQuadTreeAmerica.imageryGeoExtent.setExtent(-20037507.22959434,l,0,20037507.22959434,d,0)},Wt.prototype.doFrustumCulling=function(t,e,i,r){void 0===r&&(r=this.maxDepth),this.visibleTilesArray.length=0,this.noVisibleTilesArray.length=0,this.tinTerrainsQuadTreeAsia.getFrustumIntersectedTinTerrainsQuadTree(t,r,e,i,this.visibleTilesArray,this.noVisibleTilesArray),this.tinTerrainsQuadTreeAmerica.getFrustumIntersectedTinTerrainsQuadTree(t,r,e,i,this.visibleTilesArray,this.noVisibleTilesArray)},Wt.prototype.prepareVisibleTinTerrains=function(t){var e,i=this.visibleTilesArray.length;if(0===this.terrainType)for(var r=0;r2&&(e.deleteTinTerrain(t),o++),!(o>5));r++);},Wt.prototype.render=function(t,e){var i=t.sceneState.gl,r=t.postFxShadersManager.getShader("tinTerrain"),o=r.program;i.useProgram(o),i.enableVertexAttribArray(r.position3_loc),e?i.disableVertexAttribArray(r.texCoord2_loc):i.enableVertexAttribArray(r.texCoord2_loc),r.bindUniformGenerals();var n=t.pin.texturesArray[4];i.activeTexture(i.TEXTURE2),i.bindTexture(i.TEXTURE_2D,n.texId),i.uniform1i(r.bIsMakingDepth_loc,e),i.uniform1i(r.hasTexture_loc,!0),i.uniform4fv(r.oneColor4_loc,[.5,.5,.5,1]);var a=!0;t.configInformation.geo_view_library===s.CESIUM&&(a=!1),i.uniform1i(r.textureFlipYAxis_loc,a);for(var l,d=this.visibleTilesArray.length,h=0;h0){if(!d.bindDataIndice(r,i.vboMemoryManager))return!1;t.drawElements(t.TRIANGLES,d.indicesCount,t.UNSIGNED_SHORT,0)}else t.drawArrays(t.TRIANGLES,0,h);else t.drawArrays(t.LINE_STRIP,0,h)}}},Kt.prototype.renderGeometryDepth=function(t,e,i){var r,o=this.magoManager;if(void 0!==o.modeler){(r=o.postFxShadersManager.getShader("modelRefDepth")).resetLastBuffersBinded(),r.program,r.useProgram(),r.enableVertexAttribArray(r.position3_loc),r.disableVertexAttribArray(r.texCoord2_loc),r.disableVertexAttribArray(r.normal3_loc),r.disableVertexAttribArray(r.color4_loc),r.bindUniformGenerals();var n=0;e=0;o.modeler.render(o,r,e),r.disableVertexAttribArrayAll(),t.useProgram(null)}var a=i.currentVisibles0.length,s=i.currentVisibles2.length,l=i.currentVisibles3.length;if(a>0||s>0||l>0){(r=o.postFxShadersManager.getShader("modelRefDepth")).resetLastBuffersBinded(),r.program,r.useProgram(),r.enableVertexAttribArray(r.position3_loc),r.disableVertexAttribArray(r.texCoord2_loc),r.disableVertexAttribArray(r.normal3_loc),r.disableVertexAttribArray(r.color4_loc),r.bindUniformGenerals();n=0;o.renderer.renderNodes(t,i.currentVisibles0,o,r,!1,e,0,0,n),r.disableVertexAttribArray(r.position3_loc),t.useProgram(null)}if(o.visibleObjControlerNodes.currentVisiblesAux.length>0){(r=o.postFxShadersManager.getShader("pointsCloudDepth")).useProgram(),r.resetLastBuffersBinded(),r.enableVertexAttribArray(r.position3_loc),r.disableVertexAttribArray(r.color4_loc),r.disableVertexAttribArray(r.normal3_loc),r.disableVertexAttribArray(r.texCoord2_loc),r.bindUniformGenerals(),void 0===o.visibleObjControlerPCloudOctrees&&(o.visibleObjControlerPCloudOctrees=new yt),o.visibleObjControlerPCloudOctrees.clear(),o.renderer.renderNeoBuildingsPCloud(t,o.visibleObjControlerNodes.currentVisiblesAux,o,r,!1,e),r.disableVertexAttribArrayAll(),t.useProgram(null);var d=o.visibleObjControlerPCloudOctrees.currentVisibles0,h=d.length,c=0;if(!o.isCameraMoving&&!o.mouseLeftDown&&!o.mouseMiddleDown)for(var u=0;u1)break}}if(o.weatherStation&&o.weatherStation.test_renderCuttingPlanes(o,e),void 0!==o.tinTerrainManager){o.tinTerrainManager.render(o,!0),t.useProgram(null)}var f=o.selectionManager.getSelectionCandidatesFamily("general");if(f){var g=f.currentSelected;g&&g instanceof re&&o.test_renderDepth_objectSelected(g)}},Kt.prototype.renderGeometry=function(t,e,i){var r,o,n,s;t.frontFace(t.CCW),t.enable(t.DEPTH_TEST),t.depthFunc(t.LEQUAL),t.enable(t.CULL_FACE);var l=this.magoManager;if(0===e&&(t.disable(t.BLEND),l.renderer.renderGeometryDepth(t,e,i),l.magoPolicy.getShowOrigin()&&void 0!==l.nodeSelected)){var d=[s=l.nodeSelected];this.renderAxisNodes(d,e)}if(1===e){var h=l.texturesManager.getTextureAux1x1(),c=l.texturesManager.getNoiseTexture4x4();if(void 0!==l.modeler){(r=l.postFxShadersManager.getShader("modelRefSsao")).useProgram(),t.uniform1i(r.bApplySsao_loc,!1),t.uniform1i(r.bApplySpecularLighting_loc,!0),t.enableVertexAttribArray(r.texCoord2_loc),t.enableVertexAttribArray(r.position3_loc),t.enableVertexAttribArray(r.normal3_loc),-1!==r.color4_loc&&t.disableVertexAttribArray(r.color4_loc),r.bindUniformGenerals(),t.uniform1i(r.textureFlipYAxis_loc,l.sceneState.textureFlipYAxis),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,l.depthFboNeo.colorBuffer),t.activeTexture(t.TEXTURE1),t.bindTexture(t.TEXTURE_2D,c),t.activeTexture(t.TEXTURE2),t.bindTexture(t.TEXTURE_2D,h),r.last_tex_id=h;var u=0,f=0,g=(e=1,0);l.modeler.render(l,r,e),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,null),t.activeTexture(t.TEXTURE1),t.bindTexture(t.TEXTURE_2D,null),t.activeTexture(t.TEXTURE2),t.bindTexture(t.TEXTURE_2D,null),r.disableVertexAttribArrayAll(),t.useProgram(null)}l.checkChangesHistoryMovements(i.currentVisibles0),l.checkChangesHistoryColors(i.currentVisibles0),l.checkChangesHistoryMovements(i.currentVisibles2),l.checkChangesHistoryColors(i.currentVisibles2),l.checkChangesHistoryMovements(i.currentVisibles3),l.checkChangesHistoryColors(i.currentVisibles3);var p=i.currentVisibles0.length,v=i.currentVisibles2.length,y=i.currentVisibles3.length;if(p>0||v>0||y>0){t.enable(t.BLEND),(r=l.postFxShadersManager.getShader("modelRefSsao")).useProgram();var m=!0;t.uniform1i(r.bApplySsao_loc,m),t.uniform1i(r.bApplySpecularLighting_loc,!0),t.enableVertexAttribArray(r.texCoord2_loc),t.enableVertexAttribArray(r.position3_loc),t.enableVertexAttribArray(r.normal3_loc),-1!==r.color4_loc&&t.disableVertexAttribArray(r.color4_loc),r.bindUniformGenerals(),t.uniform1f(r.externalAlpha_loc,1),t.uniform1i(r.textureFlipYAxis_loc,l.sceneState.textureFlipYAxis),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,l.depthFboNeo.colorBuffer),t.activeTexture(t.TEXTURE1),t.bindTexture(t.TEXTURE_2D,c),t.activeTexture(t.TEXTURE2),t.bindTexture(t.TEXTURE_2D,h),r.last_tex_id=h;u=0,f=0,e=1,g=0;l.renderer.renderNodes(t,i.currentVisibles0,l,r,!1,e,f,u),m=!1,t.uniform1i(r.bApplySsao_loc,m),l.renderer.renderNodes(t,i.currentVisibles2,l,r,!1,e,f,u),l.renderer.renderNodes(t,i.currentVisibles3,l,r,!1,e,f,u),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,null),t.activeTexture(t.TEXTURE1),t.bindTexture(t.TEXTURE_2D,null),t.activeTexture(t.TEXTURE2),t.bindTexture(t.TEXTURE_2D,null),r.disableVertexAttribArrayAll(),t.useProgram(null)}if(l.nodeSelected){if(l.magoPolicy.getObjectMoveMode()===a.moveMode.OBJECT&&l.objectSelected){var x=(s=l.nodeSelected).getNodeGeoLocDataManager();n=l.buildingSelected;var b=x.getCurrentGeoLocationData();l.octreeSelected.neoReferencesMotherAndIndices,t.POINTS;t.TRIANGLES;g=0;(r=l.postFxShadersManager.getModelRefSilhouetteShader()).useProgram(),r.enableVertexAttribArray(r.position3_loc),r.disableVertexAttribArray(r.texCoord2_loc),r.disableVertexAttribArray(r.normal3_loc),r.disableVertexAttribArray(r.color4_loc),b.bindGeoLocationUniforms(t,r),t.uniformMatrix4fv(r.modelViewProjectionMatrix4RelToEye_loc,!1,l.sceneState.modelViewProjRelToEyeMatrix._floatArrays),t.uniformMatrix4fv(r.ModelViewMatrixRelToEye_loc,!1,l.sceneState.modelViewRelToEyeMatrix._floatArrays),t.uniform3fv(r.cameraPosHIGH_loc,l.sceneState.encodedCamPosHigh),t.uniform3fv(r.cameraPosLOW_loc,l.sceneState.encodedCamPosLow),t.uniform4fv(r.color4Aux_loc,[0,1,0,1]),t.uniform2fv(r.screenSize_loc,[l.sceneState.drawingBufferWidth,l.sceneState.drawingBufferHeight]),t.uniformMatrix4fv(r.ProjectionMatrix_loc,!1,l.sceneState.projectionMatrix._floatArrays),t.enable(t.STENCIL_TEST),t.disable(t.POLYGON_OFFSET_FILL),t.disable(t.CULL_FACE),t.disable(t.DEPTH_TEST),t.depthRange(0,0),t.stencilFunc(t.EQUAL,0,1),t.stencilOp(t.KEEP,t.KEEP,t.REPLACE),t.TRIANGLES;f=0;var C=.003;t.uniform2fv(r.camSpacePixelTranslation_loc,[C,C]),l.objectSelected.render(l,n,0,!1,r,g,f),t.uniform2fv(r.camSpacePixelTranslation_loc,[-C,C]),l.objectSelected.render(l,n,0,!1,r,g,f),t.uniform2fv(r.camSpacePixelTranslation_loc,[C,-C]),l.objectSelected.render(l,n,0,!1,r,g,f),t.uniform2fv(r.camSpacePixelTranslation_loc,[-C,-C]),l.objectSelected.render(l,n,0,!1,r,g,f),t.enable(t.DEPTH_TEST),t.disable(t.STENCIL_TEST),t.depthRange(0,1),r.disableVertexAttribArrayAll(),t.useProgram(null)}if(l.magoPolicy.getObjectMoveMode()===a.moveMode.ALL&&l.buildingSelected&&void 0!==(s=l.nodeSelected)){x=s.getNodeGeoLocDataManager();n=l.buildingSelected;b=x.getCurrentGeoLocationData();(r=l.postFxShadersManager.getModelRefSilhouetteShader()).useProgram(),t.enableVertexAttribArray(r.position3_loc),b.bindGeoLocationUniforms(t,r),t.uniformMatrix4fv(r.modelViewProjectionMatrix4RelToEye_loc,!1,l.sceneState.modelViewProjRelToEyeMatrix._floatArrays),t.uniformMatrix4fv(r.ModelViewMatrixRelToEye_loc,!1,l.sceneState.modelViewRelToEyeMatrix._floatArrays),t.uniform3fv(r.cameraPosHIGH_loc,l.sceneState.encodedCamPosHigh),t.uniform3fv(r.cameraPosLOW_loc,l.sceneState.encodedCamPosLow),t.uniform4fv(r.color4Aux_loc,[0,1,0,1]),t.uniform2fv(r.screenSize_loc,[l.sceneState.drawingBufferWidth,l.sceneState.drawingBufferHeight]),t.uniformMatrix4fv(r.ProjectionMatrix_loc,!1,l.sceneState.projectionMatrix._floatArrays),t.uniform3fv(r.aditionalMov_loc,[0,0,0]),t.enable(t.STENCIL_TEST),t.disable(t.POLYGON_OFFSET_FILL),t.disable(t.CULL_FACE),t.disable(t.DEPTH_TEST),t.depthRange(0,0),t.stencilFunc(t.EQUAL,0,1),t.stencilOp(t.KEEP,t.KEEP,t.REPLACE),t.TRIANGLES,t.uniform1i(r.refMatrixType_loc,0);u=0,f=0,e=0,g=0,C=.004;t.uniform2fv(r.camSpacePixelTranslation_loc,[C,C]),l.renderer.renderNodes(t,[s],l,r,!1,e,f,u),t.uniform2fv(r.camSpacePixelTranslation_loc,[-C,C]),l.renderer.renderNodes(t,[s],l,r,!1,e,f,u),t.uniform2fv(r.camSpacePixelTranslation_loc,[C,-C]),l.renderer.renderNodes(t,[s],l,r,!1,e,f,u),t.uniform2fv(r.camSpacePixelTranslation_loc,[-C,-C]),l.renderer.renderNodes(t,[s],l,r,!1,e,f,u),r.disableVertexAttribArrayAll()}if(l.magoPolicy.getShowOrigin()){d=[s=l.nodeSelected];this.renderAxisNodes(d,e)}}if(l.magoPolicy.getShowBoundingBox()){this.renderBoundingBoxesNodes(l.visibleObjControlerNodes.currentVisibles0,void 0,!0),this.renderBoundingBoxesNodes(l.visibleObjControlerNodes.currentVisibles2,void 0,!0),this.renderBoundingBoxesNodes(l.visibleObjControlerNodes.currentVisibles3,void 0,!0)}var A=l.objMarkerManager.objectMarkerArray.length;if(A>0){void 0===l.pin.positionBuffer&&l.pin.createPinCenterBottom(t),(r=l.postFxShadersManager.pngImageShader).resetLastBuffersBinded(),o=r.program,t.useProgram(o),t.uniformMatrix4fv(r.modelViewProjectionMatrix4RelToEye_loc,!1,l.sceneState.modelViewProjRelToEyeMatrix._floatArrays),t.uniform3fv(r.cameraPosHIGH_loc,l.sceneState.encodedCamPosHigh),t.uniform3fv(r.cameraPosLOW_loc,l.sceneState.encodedCamPosLow),t.uniformMatrix4fv(r.buildingRotMatrix_loc,!1,l.sceneState.modelViewRelToEyeMatrixInv._floatArrays),t.uniform1i(r.textureFlipYAxis_loc,l.sceneState.textureFlipYAxis),t.uniform1i(r.texture_loc,0),t.enableVertexAttribArray(r.texCoord2_loc),t.enableVertexAttribArray(r.position3_loc),t.activeTexture(t.TEXTURE0),t.depthRange(0,0),t.bindBuffer(t.ARRAY_BUFFER,l.pin.positionBuffer),t.vertexAttribPointer(r.position3_loc,3,t.FLOAT,!1,0,0),t.bindBuffer(t.ARRAY_BUFFER,l.pin.texcoordBuffer),t.vertexAttribPointer(r.texCoord2_loc,2,t.FLOAT,!1,0,0);for(var M=0,P=0;P=l.pin.texturesArray.length&&(M=0);var T=l.pin.texturesArray[M],w=l.objMarkerManager.objectMarkerArray[P].geoLocationData;t.bindTexture(t.TEXTURE_2D,T.texId),t.uniform3fv(r.buildingPosHIGH_loc,w.positionHIGH),t.uniform3fv(r.buildingPosLOW_loc,w.positionLOW),t.drawArrays(t.TRIANGLES,0,6),M++}t.depthRange(0,1),t.useProgram(null),t.bindTexture(t.TEXTURE_2D,null),r.disableVertexAttribArrayAll()}if(l.visibleObjControlerNodes.currentVisiblesAux.length>0){l.sceneState.camera.setCurrentFrustum(0);var _=l.currentFrustumIdx;l.sceneState.camera.frustum.near[0]=l.sceneState.camera.frustumsArray[_].near[0],l.sceneState.camera.frustum.far[0]=l.sceneState.camera.frustumsArray[_].far[0],void 0===l.pointsCloudSsao&&(l.pointsCloudSsao=!0),(r=l.pointsCloudSsao?l.postFxShadersManager.getShader("pointsCloudSsao"):l.postFxShadersManager.getShader("pointsCloud")).useProgram(),r.resetLastBuffersBinded(),r.enableVertexAttribArray(r.position3_loc),r.enableVertexAttribArray(r.color4_loc),r.bindUniformGenerals(),t.uniform1f(r.externalAlpha_loc,1);m=!0;t.uniform1i(r.bApplySsao_loc,m),void 0!==l.pointsCloudWhite&&l.pointsCloudWhite?(t.uniform1i(r.bUse1Color_loc,!0),t.uniform4fv(r.oneColor4_loc,[.99,.99,.99,1])):t.uniform1i(r.bUse1Color_loc,!1),t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,l.depthFboNeo.colorBuffer),void 0===l.visibleObjControlerPCloudOctrees&&(l.visibleObjControlerPCloudOctrees=new yt),l.visibleObjControlerPCloudOctrees.clear(),l.renderer.renderNeoBuildingsPCloud(t,l.visibleObjControlerNodes.currentVisiblesAux,l,r,!1,e),r.disableVertexAttribArrayAll(),t.useProgram(null)}if((r=l.postFxShadersManager.getShader("modelRefSsao")).disableVertexAttribArrayAll(),(r=l.postFxShadersManager.getShader("modelRefColorCoding")).disableVertexAttribArrayAll(),(r=l.postFxShadersManager.getModelRefSilhouetteShader()).disableVertexAttribArrayAll(),void 0!==l.tinTerrainManager){l.tinTerrainManager.render(l,!1)}}(r=l.postFxShadersManager.getShader("modelRefSsao")).disableVertexAttribArrayAll(),(r=l.postFxShadersManager.getShader("modelRefColorCoding")).disableVertexAttribArrayAll(),(r=l.postFxShadersManager.getModelRefSilhouetteShader()).disableVertexAttribArrayAll(),t.disable(t.BLEND),t.depthRange(0,1)},Kt.prototype.renderAxisNodes=function(t,e){var i=this.magoManager;0===i.axisXYZ.vbo_vicks_container.vboCacheKeysArray.length&&i.axisXYZ.makeMesh(30).getVboTrianglesConvex(i.axisXYZ.vbo_vicks_container,i.vboMemoryManager);var r,o,n=i.getGl();0===e&&(o=i.postFxShadersManager.getShader("modelRefDepth"),n.disable(n.BLEND)),1===e&&(o=i.postFxShadersManager.getShader("modelRefSsao"),n.enable(n.BLEND));var a=i.texturesManager.getNoiseTexture4x4();o.useProgram(),n.uniform1i(o.bApplySsao_loc,!0),n.uniform1i(o.refMatrixType_loc,0),n.uniform1i(o.colorType_loc,1),o.disableVertexAttribArray(o.texCoord2_loc);o.program;if(o.bindUniformGenerals(),n.enableVertexAttribArray(o.position3_loc),1===e){var s=i.texturesManager.getTextureAux1x1();n.enableVertexAttribArray(o.normal3_loc),n.enableVertexAttribArray(o.color4_loc),n.uniform1i(o.bUse1Color_loc,!1),n.uniform4fv(o.oneColor4_loc,[1,.1,.1,1]),n.uniform1i(o.bUseNormal_loc,!0),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,i.depthFboNeo.colorBuffer),n.activeTexture(n.TEXTURE1),n.bindTexture(n.TEXTURE_2D,a),n.activeTexture(n.TEXTURE2),n.bindTexture(n.TEXTURE_2D,s)}for(var l=t.length,d=0;d=0)for(var g=0;gf;g-=d)n=h+this.radius*Math.cos(g+u),a=c+this.radius*Math.sin(g+u),s=new xe(n,a),l.push(s);var p=l.length;p>0&&(l[0].pointType=1,l[p-1].pointType=1);for(var v=t.length,y=0;y0){var m=t[v-1];s=l[y],m.isCoincidentToPoint(s,1e-4)||t.push(s)}else t.push(l[y]);else t.push(l[y]);if((v=t.length)>0){var x=t[v-1],b=t[0];x.isCoincidentToPoint(b,1e-4)&&(t.pop(),x.deleteObjects())}return t};var $t=function(t){if(!(this instanceof $t))throw new Error(z.CONSTRUCT_ERROR);this.length=void 0===t?60:t,this.vbo_vicks_container=new vt};$t.prototype.setDimension=function(t){this.length=t},$t.prototype.makeMesh=function(t){void 0!==t&&(this.length=t);var e=new ye;e.profile=new _e;var i,r=e.profile,o=r.newOuterRing(),n=this.length,a=.1*this.length,s=o.newElement("POLYLINE");s.newPoint2d(0,0);s.newPoint2d(.25*a,.25*n),s.newPoint2d(.25*a,.75*n),s.newPoint2d(.5*a,.75*n),s.newPoint2d(0,n),i=new Ie;var l=new xe(0,-10),d=new xe(0,10);i.setPoints(l,d),e.revolve(r,360,8,i);var h=e.getSurfaceIndependentMesh(void 0,!1,!1);h.setColor(.1,1,.1,1),h.reverseSense();var c=new k,u=h.getCopy(void 0);c.rotationAxisAngDeg(-90,0,0,1),u.transformByMatrix4(c),u.setColor(1,.1,.1,1);var f=h.getCopy(void 0);return c.rotationAxisAngDeg(90,1,0,0),f.transformByMatrix4(c),f.setColor(.1,.1,1,1),h.mergeMesh(u),h.mergeMesh(f),h},$t.prototype.getVboKeysContainer=function(){return this.vbo_vicks_container};var te=function(t,e){if(!(this instanceof te))throw new Error(z.CONSTRUCT_ERROR);this.minX=Number.MAX_VALUE,this.maxX=Number.MIN_VALUE,this.minY=Number.MAX_VALUE,this.maxY=Number.MIN_VALUE};te.prototype.setInit=function(t){void 0!==t&&(this.minX=t.x,this.minY=t.y,this.maxX=t.x,this.maxY=t.y)},te.prototype.setInitByRectangle=function(t){void 0!==t&&(this.minX=t.minX,this.minY=t.minY,this.maxX=t.maxX,this.maxY=t.maxY)},te.prototype.addPoint=function(t){void 0!==t&&(t.xthis.maxX&&(this.maxX=t.x),t.ythis.maxY&&(this.maxY=t.y))},te.prototype.addRectangle=function(t){void 0!==t&&(t.minXthis.maxX&&(this.maxX=t.maxX),t.minYthis.maxY&&(this.maxY=t.maxY))},te.prototype.intersectsWithRectangle=function(t){return void 0!==t&&(!(t.minX>this.maxX)&&(!(t.maxXthis.maxY)&&!(t.maxY1?l=1:l<-1&&(l=-1);var d=Math.acos(l);e.add(s.x*d,s.y*d,s.z*d)}}}return e.unitary(),e},ae.prototype.calculatePlaneNormal=function(){return this.planeNormal=ae.calculatePlaneNormal(this.vertexArray,this.planeNormal),this.planeNormal},ae.prototype.calculateVerticesNormals=function(t){var e=this.vertexArray.length;void 0!==t&&t&&this.calculatePlaneNormal(),void 0===this.planeNormal&&this.calculatePlaneNormal();e=this.getVerticesCount();for(var i=0;ii&&o>=r?e=0:i>=r&&i>=o?e=1:r>i&&r>=o&&(e=2),e},ae.getProjectedPolygon2D=function(t,e,i){void 0===i&&(i=new Pe),void 0===i.point2dList&&(i.point2dList=new be);var r=i.point2dList;return r.pointsArray=ze.getProjectedPoints2DArray(t,e,r.pointsArray),i},ae.prototype.getTessellatedTriangles=function(t){if(void 0===t&&(t=[]),this.getVerticesCount()<=3)return t=this.getTrianglesConvex(t);var e,i=this.getPlaneNormal(),r=(ae.getBestFacePlaneToProject(i),ae.getProjectedPolygon2D(this.vertexArray,i,void 0));e=r.calculateNormal(e);var o=[];r.tessellate(e,o),this.calculateVerticesNormals();for(var n=o.length,a=0;a2e5&&(e=2e5),r.add(o.x*e,o.y*e,o.z*e),this.updateModelViewMatrixByCamera(i)}},ge.prototype.mousemove=function(t){var e=this.magoManager.sceneState.mouseAction;if(0===this.magoManager.sceneState.mouseButton){this.magoManager.sceneState.gl,this.magoManager.sceneState;var i,r,o=e.strCamera,n=this.magoManager.sceneState.camera,a=e.strWorldPoint,s=a.getModul(),l=t.clientX,d=t.clientY;if(l===e.strX&&d===e.strY)return;r=pi.getRayCamSpace(l,d,r,this.magoManager),void 0===this.pointSC&&(this.pointSC=new Ae),this.pointSC.set(r[0],r[1],r[2]);var h,c=e.strModelViewMatrixInv;if(this.pointSC2=c.rotatePoint3D(this.pointSC,this.pointSC2),this.pointSC2.unitary(),(i=new ce).setPointAndDir(o.position.x,o.position.y,o.position.z,this.pointSC2.x,this.pointSC2.y,this.pointSC2.z),void 0===(h=this.magoManager.globe.intersectionLineWgs84(i,h,s)))return;var u,f=new Ae(a.x,a.y,a.z),g=new Ae(h[0],h[1],h[2]);if((u=f.crossProduct(g,u)).unitary(),u.isNAN())return;var p=f.angleRadToVector(g);if(0===p||isNaN(p))return;n.copyPosDirUpFrom(o);var v=new k;v.rotationAxisAngRad(-p,u.x,u.y,u.z),n.transformByMatrix4(v),this.updateModelViewMatrixByCamera(n)}else if(1===this.magoManager.sceneState.mouseButton){o=e.strCamera;(n=this.magoManager.sceneState.camera).copyPosDirUpFrom(o);n.position,n.direction,n.up;var y,m=e.strWorldPoint;void 0===this.magoManager.globe&&(this.magoManager.globe=new j),y=this.magoManager.globe.normalAtCartesianPointWgs84(m.x,m.y,m.z,y);var x=n.getCameraRight(),b=(l=t.clientX,d=t.clientY,.003*(l-e.strX)),C=.003*(d-e.strY);if(0===b&&0===C)return;void 0===this.rotMatX&&(this.rotMatX=new k),void 0===this.rotMatZ&&(this.rotMatZ=new k),void 0===this.rotMat&&(this.rotMat=new k),this.rotMatX.rotationAxisAngRad(-C,x.x,x.y,x.z),this.rotMatZ.rotationAxisAngRad(-b,y[0],y[1],y[2]),this.rotMat=this.rotMatX.getMultipliedByMatrix(this.rotMatZ,this.rotMat);var A=new Ae(-m.x,-m.y,-m.z),M=new Ae(m.x,m.y,m.z);n.translate(A),n.transformByMatrix4(this.rotMat),n.translate(M),this.updateModelViewMatrixByCamera(n)}},ge.prototype.keydown=function(t){console.log("keydown")};var pe=function(){if(!(this instanceof pe))throw new Error(z.CONSTRUCT_ERROR);this.vertexList,this.surfacesArray,this.hedgesList,this.vboKeysContainer};pe.prototype.deleteObjects=function(t){if(void 0!==this.vertexList&&this.vertexList.deleteObjects(),void 0!==this.surfacesArray){for(var e=this.surfacesArray.length,i=0;i0&&(e=this.getTrianglesListsArrayBy2ByteSize(n,e)),e},pe.prototype.render=function(t,e,i,r){var o=t.vboMemoryManager;if(void 0!==this.vboKeysContainer)for(var n,a=t.sceneState.gl,s=this.vboKeysContainer.vboCacheKeysArray.length,l=0;le.squaredDist?(l=i,d=h):(l=h,d=r),this.getIndexToInsertBySquaredDist(t,e,l,d)};var Ce,Ae=function(t,e,i){if(!(this instanceof Ae))throw new Error(i18next.t("error.construct.create"));this.x=void 0!==t?t:0,this.y=void 0!==e?e:0,this.z=void 0!==i?i:0,this.pointType};Ae.prototype.deleteObjects=function(){this.x=void 0,this.y=void 0,this.z=void 0},Ae.prototype.copyFrom=function(t){this.x=t.x,this.y=t.y,this.z=t.z},Ae.prototype.getSquaredModul=function(){return this.x*this.x+this.y*this.y+this.z*this.z},Ae.prototype.getModul=function(){return Math.sqrt(this.getSquaredModul())},Ae.prototype.unitary=function(){var t=this.getModul();this.x/=t,this.y/=t,this.z/=t},Ae.prototype.isNAN=function(){return!!(isNaN(this.x)||isNaN(this.y)||isNaN(this.z))},Ae.prototype.crossProduct=function(t,e){return void 0===e&&(e=new Ae),e.x=this.y*t.z-t.y*this.z,e.y=t.x*this.z-this.x*t.z,e.z=this.x*t.y-t.x*this.y,e},Ae.prototype.scalarProduct=function(t){return this.x*t.x+this.y*t.y+this.z*t.z},Ae.prototype.getSphericalCoords=function(t){void 0===t&&(t=new F);var e=new xe(this.x,this.y),i=new xe(1,0),r=e.angleDegToVector(i);this.y<0&&(r=360-r);var o=e.getModul(),n=180*Math.atan(this.z/o)/Math.PI;return this.z<0&&(n*=-1),t.longitude=r,t.latitude=n,t},Ae.prototype.getRelativeOrientationToVector=function(t,e){var i=this.angleRadToVector(t);return is?a>l?(r=s/(i=a),o=l/(n=i*e[Math.floor(10*r)]),n*e[Math.floor(10*o)]):(r=a/(i=l),o=s/(n=i*e[Math.floor(10*r)]),n*e[Math.floor(10*o)]):s>l?(r=a/(i=s),o=l/(n=i*e[Math.floor(10*r)]),n*e[Math.floor(10*o)]):(r=a/(i=l),o=s/(n=i*e[Math.floor(10*r)]),n*e[Math.floor(10*o)])},Ae.prototype.getVectorToPoint=function(t,e){if(void 0!==t)return void 0===e&&(e=new Ae),e.set(t.x-this.x,t.y-this.y,t.z-this.z),e},Ae.prototype.set=function(t,e,i){this.x=t,this.y=e,this.z=i},Ae.prototype.add=function(t,e,i){this.x+=t,this.y+=e,this.z+=i},Ae.prototype.addPoint=function(t){this.x+=t.x,this.y+=t.y,this.z+=t.z},Ae.prototype.scale=function(t){this.x*=t,this.y*=t,this.z*=t},(Ce=function(){if(!(this instanceof Ce))throw new Error(z.CONSTRUCT_ERROR);this.points3dArray}).prototype.newPoint3D=function(t,e,i){void 0===this.points3dArray&&(this.points3dArray=[]);var r=new Ae(t,e,i);return this.points3dArray.push(r),r},Ce.prototype.addPoint3D=function(t){void 0===this.points3dArray&&(this.points3dArray=[]),this.points3dArray.push(t)},Ce.calculateBBox=function(t,e){if(void 0!==t){var i=t.length;if(0!==i){void 0===e&&(e=new v),e.init(t[0]);for(var r=1;r0))continue;a=1}var l=s,d=Math.acos(l);this.normal+=a*d}return this.normal>0?this.normal=1:this.normal=-1,t},Pe.prototype.tessellate=function(t,e){var i=t.length;if(0===i)return e.push(this),e;for(var r,o=!1,n=0;!o&&n0?e=f.tessellate(p,e):(void 0===e&&(e=[]),e.push(f)),v.length>0?e=g.tessellate(v,e):(void 0===e&&(e=[]),e.push(g))),h++}}}else h++;n++}return e},Pe.prototype.intersectionWithSegment=function(t){if(void 0!==this.bRect){var e=t.getBoundaryRectangle(e);if(!this.bRect.intersectsWithRectangle(e))return!1}for(var i,r=this.point2dList.getPointsCount(),o=0;o0?1:-1;for(var n=this.point2dList.getPointsCount(),a=0;a0?1:-1;for(var s=t.point2dList.getPointsCount(),l=0;l0){var n=t[i-1],a=this.point2dArray[o];n.isCoincidentToPoint(a,1e-7)||((e=new xe).copyFrom(this.point2dArray[o]),e.pointType=1,t.push(e))}else(e=new xe).copyFrom(this.point2dArray[o]),e.pointType=1,t.push(e);else(e=new xe).copyFrom(this.point2dArray[o]),e.pointType=1,t.push(e);return t};var we=function(){if(!(this instanceof we))throw new Error(z.CONSTRUCT_ERROR);this.point3dArray,this.geoLocDataManager,this.vboKeysContainer};we.prototype.newPoint3d=function(t,e,i){void 0===this.point3dArray&&(this.point3dArray=[]);var r=new Ae(t,e,i);return this.point3dArray.push(r),r},we.prototype.addPoint3dArray=function(t){void 0!==t&&(void 0===this.point3dArray&&(this.point3dArray=[]),this.point3dArray.push.apply(this.point3dArray,t))},we.prototype.getGeographicLocation=function(){void 0===this.geoLocDataManager&&(this.geoLocDataManager=new N);var t=this.geoLocDataManager.getCurrentGeoLocationData();return void 0===t&&(t=this.geoLocDataManager.newGeoLocationData("default")),t},we.prototype.makeVbo=function(t){void 0===this.vboKeysContainer&&(this.vboKeysContainer=new vt);for(var e,i=this.point3dArray.length,r=new Float32Array(3*i),o=0;o1){var o=t[0],n=t[r-1];n.pointType=1,o.isCoincidentToPoint(n,1e-7)&&((n=t.pop()).deleteObjects(),n=void 0)}return t};var De=function(){if(!(this instanceof De))throw new Error(z.CONSTRUCT_ERROR);this.ringsArray=[],this.idxInList};De.prototype.newRing=function(){var t=new Le;return this.ringsArray.push(t),t},De.prototype.addRing=function(t){this.ringsArray.push(t)},De.prototype.deleteObjects=function(){for(var t=0,e=this.ringsArray.length;te.squaredDist?(l=i,d=h):(l=h,d=r),this.getIndexToInsertBySquaredDist(t,e,l,d)},De.getBinarySearchIndex=function(t,e,i){var r=0,o=t.length-1;for(i=i||function(t){return t};r<=o;){var n=Math.floor((r+o)/2);i(t[n])o||r>o?s.INTERSECTION_OUTSIDE:Math.abs(i+r-o)i-1))return 0===t?i-1:t-1},ze.getNextIdx=function(t,e){var i=e.length;if(!(t<0||t>i-1))return t===i-1?0:t+1},ze.getVtxSegment=function(t,e,i){var r=e[t],o=e[ze.getNextIdx(t,e)];return void 0===i?i=new qe(r,o):i.setVertices(r,o),i},ze.getVector=function(t,e,i){var r=e[t],o=e[ze.getNextIdx(t,e)],n=r.point3d,a=o.point3d;return void 0===i?i=new Ae(a.x-n.x,a.y-n.y,a.z-n.z):i.setVertices(a.x-n.x,a.y-n.y,a.z-n.z),i},ze.getDirection=function(t,e,i){return(i=ze.getVector(t,e,i)).unitary(),i},ze.getCrossProduct=function(t,e,i){var r=ze.getVector(t,e,void 0),o=ze.getPrevIdx(t,e);return i=ze.getVector(o,e,void 0).crossProduct(r,i)},ze.getProjectedOntoPlane=function(t,e,i,r){if(void 0===t)return r;var o,n;void 0===r&&(r=new ze);for(var a=t.getVertexCount(),s=0;s0?new xe(s.x,s.y):new xe(s.x,-s.y)).ownerVertex3d=l,i.push(r)}else if(1===o)for(a=0;a0?new xe(s.y,s.z):new xe(-s.y,s.z)).ownerVertex3d=l,i.push(r)}else if(2===o)for(a=0;a0?new xe(-s.x,s.z):new xe(s.x,s.z)).ownerVertex3d=l,i.push(r)}return i},ze.prototype.deleteObjects=function(){for(var t=0,e=this.vertexArray.length;t=0&&t0&&(i=t.getInnerRingsList());for(var o=0;o0)for(var m=g.length,x=0;x0){m=g.length;for(var A,M,P=0;Pn||o>n?s.INTERSECTION_OUTSIDE:Math.abs(r+o-n) 1.0)speed_t = 1.0;\n\t\tfloat b = 1.0 - speed_t;\n\t\tfloat g;\n\t\tif(speed_t > 0.5)\n\t\t{\n\t\t\tg = 2.0-2.0*speed_t;\n\t\t}\n\t\telse{\n\t\t\tg = 2.0*speed_t;\n\t\t}\n\t\tfloat r = speed_t;\n\t\tgl_FragColor = vec4(r,g,b,1.0);\n\t}\n\telse{\n\t\tfloat intensity = speed_t*3.0;\n\t\tif(intensity > 1.0)\n\t\t\tintensity = 1.0;\n\t\tgl_FragColor = vec4(intensity,intensity,intensity,1.0);\n\t}\n}\n",draw_vert:"precision mediump float;\n\nattribute float a_index;\n\nuniform sampler2D u_particles;\nuniform float u_particles_res;\n\nvarying vec2 v_particle_pos;\n\nvoid main() {\n vec4 color = texture2D(u_particles, vec2(\n fract(a_index / u_particles_res),\n floor(a_index / u_particles_res) / u_particles_res));\n\n // decode current particle position from the pixel's RGBA value\n v_particle_pos = vec2(\n color.r / 255.0 + color.b,\n color.g / 255.0 + color.a);\n\n gl_PointSize = 1.0;\n gl_Position = vec4(2.0 * v_particle_pos.x - 1.0, 1.0 - 2.0 * v_particle_pos.y, 0, 1);\n}\n",draw_vert3D:"precision mediump float;\n\n\t// This shader draws windParticles in 3d directly from positions on u_particles image.***\nattribute float a_index;\n\nuniform sampler2D u_particles;\nuniform float u_particles_res;\nuniform mat4 ModelViewProjectionMatrix;\n\nvarying vec2 v_particle_pos;\n\n#define M_PI 3.1415926535897932384626433832795\nvec4 geographicToWorldCoord(float lonDeg, float latDeg, float alt)\n{\n\t// defined in the LINZ standard LINZS25000 (Standard for New Zealand Geodetic Datum 2000)\n\t// https://www.linz.govt.nz/data/geodetic-system/coordinate-conversion/geodetic-datum-conversions/equations-used-datum\n\t// a = semi-major axis.\n\t// e2 = firstEccentricitySquared.\n\t// v = a / sqrt(1 - e2 * sin2(lat)).\n\t// x = (v+h)*cos(lat)*cos(lon).\n\t// y = (v+h)*cos(lat)*sin(lon).\n\t// z = [v*(1-e2)+h]*sin(lat).\n\tfloat degToRadFactor = M_PI/180.0;\n\tfloat equatorialRadius = 6378137.0; // meters.\n\tfloat firstEccentricitySquared = 6.69437999014E-3;\n\tfloat lonRad = lonDeg * degToRadFactor;\n\tfloat latRad = latDeg * degToRadFactor;\n\tfloat cosLon = cos(lonRad);\n\tfloat cosLat = cos(latRad);\n\tfloat sinLon = sin(lonRad);\n\tfloat sinLat = sin(latRad);\n\tfloat a = equatorialRadius;\n\tfloat e2 = firstEccentricitySquared;\n\tfloat v = a/sqrt(1.0 - e2 * sinLat * sinLat);\n\tfloat h = alt;\n\t\n\tvec4 resultCartesian = vec4((v+h)*cosLat*cosLon, (v+h)*cosLat*sinLon, (v*(1.0-e2)+h)*sinLat, 1.0);\n\treturn resultCartesian;\n}\n\nvoid main() {\n vec4 color = texture2D(u_particles, vec2(\n fract(a_index / u_particles_res),\n floor(a_index / u_particles_res) / u_particles_res));\n\n // decode current particle position from the pixel's RGBA value\n v_particle_pos = vec2(\n color.r / 255.0 + color.b,\n color.g / 255.0 + color.a);\n\n gl_PointSize = 1.0;\n vec4 pos2d = vec4(2.0 * v_particle_pos.x - 1.0, 1.0 - 2.0 * v_particle_pos.y, 0, 1);\n\t\n\t// Now, must calculate geographic coords of the pos2d.***\n\tfloat longitudeDeg = -180.0 + pos2d.x * 360.0;\n\tfloat latitudeDeg = 90.0 - pos2d.y * 180.0;\n\tfloat altitude = 0.0;\n\t// Now, calculate worldPosition of the geographicCoords (lon, lat, alt).***\n\tvec4 worldPos = geographicToWorldCoord(longitudeDeg, latitudeDeg, altitude);\n\t\n\t// Now calculate the position on camCoord.***\n\t\n\tgl_Position = ModelViewProjectionMatrix * worldPos;\n}",filterSilhouetteFS:"precision mediump float;\n\nuniform sampler2D depthTex;\nuniform sampler2D noiseTex; \nuniform mat4 projectionMatrix;\nuniform vec2 noiseScale;\nuniform float near;\nuniform float far; \nuniform float fov;\nuniform float aspectRatio; \nuniform float screenWidth; \nuniform float screenHeight; \nuniform vec3 kernel[16]; \n\n\nconst int kernelSize = 16; \nuniform float radius; \n\nuniform bool bApplySsao;\n\nfloat unpackDepth(const in vec4 rgba_depth)\n{\n const vec4 bit_shift = vec4(0.000000059605, 0.000015258789, 0.00390625, 1.0);\n float depth = dot(rgba_depth, bit_shift);\n return depth;\n} \n\nvec3 getViewRay(vec2 tc)\n{\n float hfar = 2.0 * tan(fov/2.0) * far;\n float wfar = hfar * aspectRatio; \n vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n return ray; \n} \n \n//linear view space depth\nfloat getDepth(vec2 coord)\n{\n return unpackDepth(texture2D(depthTex, coord.xy));\n} \n\nvoid main()\n{\n\tfloat occlusion = 0.0;\n\tvec3 normal2 = vec3(0.0, 0.0, 1.0);\n\tfloat radiusAux = radius * 5.0;\n\tif(bApplySsao)\n\t{ \n\t\tvec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight);\t\t \n\t\tfloat linearDepth = getDepth(screenPos); \n\t\tvec3 origin = getViewRay(screenPos) * linearDepth; \n\n\t\tvec3 rvec = texture2D(noiseTex, screenPos.xy * noiseScale).xyz * 2.0 - 1.0;\n\t\tvec3 tangent = normalize(rvec - normal2 * dot(rvec, normal2));\n\t\tvec3 bitangent = cross(normal2, tangent);\n\t\tmat3 tbn = mat3(tangent, bitangent, normal2); \n\t\t\n\t\tfor(int i = 0; i < kernelSize; ++i)\n\t\t{ \t \n\t\t\t//vec3 sample = origin + (tbn * kernel[i]) * radiusAux;\n\t\t\tvec3 sample = origin + (kernel[i]) * radiusAux;\n\t\t\tvec4 offset = projectionMatrix * vec4(sample, 1.0);\t\t\n\t\t\toffset.xy /= offset.w;\n\t\t\toffset.xy = offset.xy * 0.5 + 0.5; \n\t\t\tfloat sampleDepth = -sample.z/far;\n\t\t\tif(sampleDepth > 0.49)\n\t\t\t\tcontinue;\n\t\t\tfloat depthBufferValue = getDepth(offset.xy);\n\t\t\tfloat range_check = abs(linearDepth - depthBufferValue)+radiusAux*0.998;\n\t\t\tif (range_check > radius*1.001 && depthBufferValue <= sampleDepth)\n\t\t\t{\n\t\t\t\tocclusion += 1.0;\n\t\t\t}\n\t\t} \n\t\t\n\t\tif(occlusion > float(kernelSize)*0.4)\n\t\t{\n\t\t\tocclusion = occlusion / float(kernelSize);\n\t\t}\n\t\telse{\n\t\t\tocclusion = 0.0;\n\t\t}\n\t\t//occlusion = 1.0 - occlusion / float(kernelSize);\n\t}\n\telse{\n\t\tocclusion = 0.0;\n\t}\n\n vec4 finalColor;\n\tfinalColor = vec4(1.0, 1.0, 1.0, occlusion*0.9);\n gl_FragColor = finalColor; \n}\n",InvertedBoxFS:"#ifdef GL_ES\n precision highp float;\n#endif\n\nuniform sampler2D depthTex;\nuniform sampler2D noiseTex; \nuniform sampler2D diffuseTex;\nuniform bool hasTexture;\nuniform bool textureFlipYAxis;\nvarying vec3 vNormal;\nuniform mat4 projectionMatrix;\nuniform mat4 m;\nuniform vec2 noiseScale;\nuniform float near;\nuniform float far; \nuniform float fov;\nuniform float aspectRatio; \nuniform float screenWidth; \nuniform float screenHeight; \nuniform float shininessValue;\nuniform vec3 kernel[16]; \nuniform vec4 vColor4Aux;\n\nvarying vec2 vTexCoord; \nvarying vec3 vLightWeighting;\n\nvarying vec3 diffuseColor;\nuniform vec3 specularColor;\nvarying vec3 vertexPos;\n\nconst int kernelSize = 16; \nuniform float radius; \n\nuniform float ambientReflectionCoef;\nuniform float diffuseReflectionCoef; \nuniform float specularReflectionCoef; \n\nfloat unpackDepth(const in vec4 rgba_depth)\n{\n const vec4 bit_shift = vec4(0.000000059605, 0.000015258789, 0.00390625, 1.0);\n float depth = dot(rgba_depth, bit_shift);\n return depth;\n} \n\nvec3 getViewRay(vec2 tc)\n{\n float hfar = 2.0 * tan(fov/2.0) * far;\n float wfar = hfar * aspectRatio; \n vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n return ray; \n} \n \n//linear view space depth\nfloat getDepth(vec2 coord)\n{\n return unpackDepth(texture2D(depthTex, coord.xy));\n} \n\nvoid main()\n{ \n vec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight);\t\t \n float linearDepth = getDepth(screenPos); \n vec3 origin = getViewRay(screenPos) * linearDepth; \n\n vec3 normal2 = vNormal;\n \n vec3 rvec = texture2D(noiseTex, screenPos.xy * noiseScale).xyz * 2.0 - 1.0;\n vec3 tangent = normalize(rvec - normal2 * dot(rvec, normal2));\n vec3 bitangent = cross(normal2, tangent);\n mat3 tbn = mat3(tangent, bitangent, normal2); \n \n float occlusion = 0.0;\n for(int i = 0; i < kernelSize; ++i)\n { \t \n vec3 sample = origin + (tbn * kernel[i]) * radius;\n vec4 offset = projectionMatrix * vec4(sample, 1.0);\t\t\n offset.xy /= offset.w;\n offset.xy = offset.xy * 0.5 + 0.5; \n float sampleDepth = -sample.z/far;\n\t\tif(sampleDepth > 0.49)\n\t\t\tcontinue;\n float depthBufferValue = getDepth(offset.xy);\t\t\t\t \n float range_check = abs(linearDepth - depthBufferValue)+radius*0.998;\n if (range_check < radius*1.001 && depthBufferValue <= sampleDepth)\n {\n occlusion += 1.0;\n }\n } \n \n occlusion = 1.0 - occlusion / float(kernelSize);\n\n vec3 lightPos = vec3(20.0, 60.0, 20.0);\n vec3 L = normalize(lightPos - vertexPos);\n float lambertian = max(dot(normal2, L), 0.0);\n float specular = 0.0;\n if(lambertian > 0.0)\n {\n vec3 R = reflect(-L, normal2); // Reflected light vector\n vec3 V = normalize(-vertexPos); // Vector to viewer\n \n // Compute the specular term\n float specAngle = max(dot(R, V), 0.0);\n specular = pow(specAngle, shininessValue);\n }\n\t\n\tif(lambertian < 0.5)\n {\n\t\tlambertian = 0.5;\n\t}\n\n vec4 textureColor;\n if(hasTexture)\n {\n if(textureFlipYAxis)\n {\n textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, 1.0 - vTexCoord.t));\n }\n else{\n textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, vTexCoord.t));\n }\n\t\t\n if(textureColor.w == 0.0)\n {\n discard;\n }\n }\n else{\n textureColor = vColor4Aux;\n }\n\t\n\tvec3 ambientColor = vec3(textureColor.x, textureColor.y, textureColor.z);\n\n gl_FragColor = vec4((ambientReflectionCoef * ambientColor + diffuseReflectionCoef * lambertian * textureColor.xyz + specularReflectionCoef * specular * specularColor)*vLightWeighting * occlusion, 1.0); \n}\n",InvertedBoxVS:"\tattribute vec3 position;\n\tattribute vec3 normal;\n\tattribute vec2 texCoord;\n\t\n\tuniform mat4 buildingRotMatrix; \n\tuniform mat4 projectionMatrix; \n\tuniform mat4 modelViewMatrix;\n\tuniform mat4 modelViewMatrixRelToEye; \n\tuniform mat4 ModelViewProjectionMatrixRelToEye;\n\tuniform mat4 RefTransfMatrix;\n\tuniform mat4 normalMatrix4;\n\tuniform vec3 buildingPosHIGH;\n\tuniform vec3 buildingPosLOW;\n\tuniform vec3 encodedCameraPositionMCHigh;\n\tuniform vec3 encodedCameraPositionMCLow;\n\tuniform vec3 aditionalPosition;\n\tuniform vec3 refTranslationVec;\n\tuniform int refMatrixType; // 0= identity, 1= translate, 2= transform\n\n\tvarying vec3 vNormal;\n\tvarying vec2 vTexCoord; \n\tvarying vec3 uAmbientColor;\n\tvarying vec3 vLightWeighting;\n\tvarying vec3 vertexPos;\n\t\n\tvoid main()\n {\t\n\t\tvec4 rotatedPos;\n\t\tmat3 currentTMat;\n\t\tif(refMatrixType == 0)\n\t\t{\n\t\t\trotatedPos = buildingRotMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t\t\tcurrentTMat = mat3(buildingRotMatrix);\n\t\t}\n\t\telse if(refMatrixType == 1)\n\t\t{\n\t\t\trotatedPos = buildingRotMatrix * vec4(position.xyz + refTranslationVec.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t\t\tcurrentTMat = mat3(buildingRotMatrix);\n\t\t}\n\t\telse if(refMatrixType == 2)\n\t\t{\n\t\t\trotatedPos = RefTransfMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t\t\tcurrentTMat = mat3(RefTransfMatrix);\n\t\t}\n\n\t\tvec3 objPosHigh = buildingPosHIGH;\n\t\tvec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n\t\tvec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\t\tvec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\t\tvec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\n\t\tvertexPos = vec3(modelViewMatrixRelToEye * pos4);\n\t\tvec3 rotatedNormal = currentTMat * normal;\n\t\tvLightWeighting = vec3(1.0, 1.0, 1.0);\n\t\tuAmbientColor = vec3(0.8);\n\t\tvec3 uLightingDirection = vec3(0.6, 0.6, 0.6);\n\t\tvec3 directionalLightColor = vec3(0.7, 0.7, 0.7);\n\t\tvNormal = (normalMatrix4 * vec4(rotatedNormal.x, rotatedNormal.y, rotatedNormal.z, 1.0)).xyz;\n\t\tvTexCoord = texCoord;\n\t\tfloat directionalLightWeighting = max(dot(vNormal, uLightingDirection), 0.0);\n\t\tvLightWeighting = uAmbientColor + directionalLightColor * directionalLightWeighting;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\t}\n",ModelRefSsaoFS:"#ifdef GL_ES\n precision highp float;\n#endif\n\nuniform sampler2D depthTex;\nuniform sampler2D noiseTex; \nuniform sampler2D diffuseTex;\nuniform bool textureFlipYAxis;\nvarying vec3 vNormal;\nuniform mat4 projectionMatrix;\nuniform mat4 m;\nuniform vec2 noiseScale;\nuniform float near;\nuniform float far; \nuniform float fov;\nuniform float aspectRatio; \nuniform float screenWidth; \nuniform float screenHeight; \nuniform float shininessValue;\nuniform vec3 kernel[16]; \nuniform vec4 oneColor4;\nvarying vec4 aColor4; // color from attributes\nuniform bool bApplyScpecularLighting;\nuniform highp int colorType; // 0= oneColor, 1= attribColor, 2= texture.\n\nvarying vec2 vTexCoord; \nvarying vec3 vLightWeighting;\n\nvarying vec3 diffuseColor;\nuniform vec3 specularColor;\nvarying vec3 vertexPos;\n\nconst int kernelSize = 16; \nuniform float radius; \n\nuniform float ambientReflectionCoef;\nuniform float diffuseReflectionCoef; \nuniform float specularReflectionCoef; \nvarying float applySpecLighting;\nuniform bool bApplySsao;\nuniform float externalAlpha;\n\nfloat unpackDepth(const in vec4 rgba_depth)\n{\n const vec4 bit_shift = vec4(0.000000059605, 0.000015258789, 0.00390625, 1.0);\n float depth = dot(rgba_depth, bit_shift);\n return depth;\n} \n\nvec3 getViewRay(vec2 tc)\n{\n float hfar = 2.0 * tan(fov/2.0) * far;\n float wfar = hfar * aspectRatio; \n vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n return ray; \n} \n \n//linear view space depth\nfloat getDepth(vec2 coord)\n{\n return unpackDepth(texture2D(depthTex, coord.xy));\n} \n\nvoid main()\n{\n\tfloat occlusion = 0.0;\n\tvec3 normal2 = vNormal;\n\tif(bApplySsao)\n\t{ \n\t\tvec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight);\t\t \n\t\tfloat linearDepth = getDepth(screenPos); \n\t\tvec3 origin = getViewRay(screenPos) * linearDepth; \n\n\t\tvec3 rvec = texture2D(noiseTex, screenPos.xy * noiseScale).xyz * 2.0 - 1.0;\n\t\tvec3 tangent = normalize(rvec - normal2 * dot(rvec, normal2));\n\t\tvec3 bitangent = cross(normal2, tangent);\n\t\tmat3 tbn = mat3(tangent, bitangent, normal2); \n\t\t\n\t\tfor(int i = 0; i < kernelSize; ++i)\n\t\t{ \t \n\t\t\tvec3 sample = origin + (tbn * kernel[i]) * radius;\n\t\t\tvec4 offset = projectionMatrix * vec4(sample, 1.0);\t\t\n\t\t\toffset.xy /= offset.w;\n\t\t\toffset.xy = offset.xy * 0.5 + 0.5; \n\t\t\tfloat sampleDepth = -sample.z/far;\n\t\t\tif(sampleDepth > 0.49)\n\t\t\t\tcontinue;\n\t\t\tfloat depthBufferValue = getDepth(offset.xy);\t\t\t\t \n\t\t\tfloat range_check = abs(linearDepth - depthBufferValue)+radius*0.998;\n\t\t\tif (range_check < radius*1.001 && depthBufferValue <= sampleDepth)\n\t\t\t{\n\t\t\t\tocclusion += 1.0;\n\t\t\t}\n\t\t} \n\t\t\t\n\t\tocclusion = 1.0 - occlusion / float(kernelSize);\n\t}\n\telse{\n\t\tocclusion = 1.0;\n\t}\n\n // Do specular lighting.***\n\tfloat lambertian;\n\tfloat specular;\n\t\t\n\tif(applySpecLighting> 0.0)\n\t{\n\t\tvec3 lightPos = vec3(20.0, 60.0, 200.0);\n\t\tvec3 L = normalize(lightPos - vertexPos);\n\t\tlambertian = max(dot(normal2, L), 0.0);\n\t\tspecular = 0.0;\n\t\tif(lambertian > 0.0)\n\t\t{\n\t\t\tvec3 R = reflect(-L, normal2); // Reflected light vector\n\t\t\tvec3 V = normalize(-vertexPos); // Vector to viewer\n\t\t\t\n\t\t\t// Compute the specular term\n\t\t\tfloat specAngle = max(dot(R, V), 0.0);\n\t\t\tspecular = pow(specAngle, shininessValue);\n\t\t}\n\t\t\n\t\tif(lambertian < 0.5)\n\t\t{\n\t\t\tlambertian = 0.5;\n\t\t}\n\t}\n\n vec4 textureColor;\n if(colorType == 2)\n {\n if(textureFlipYAxis)\n {\n textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, 1.0 - vTexCoord.t));\n }\n else{\n textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, vTexCoord.t));\n }\n\t\t\n if(textureColor.w == 0.0)\n {\n discard;\n }\n }\n else if(colorType == 0)\n\t{\n textureColor = oneColor4;\n }\n\telse if(colorType == 1)\n\t{\n textureColor = aColor4;\n }\n\t\n\tvec3 ambientColor = vec3(textureColor.x, textureColor.y, textureColor.z);\n\tfloat alfa = textureColor.w * externalAlpha;\n\n vec4 finalColor;\n\tif(applySpecLighting> 0.0)\n\t{\n\t\tfinalColor = vec4((ambientReflectionCoef * ambientColor + diffuseReflectionCoef * lambertian * textureColor.xyz + specularReflectionCoef * specular * specularColor)*vLightWeighting * occlusion, alfa); \n\t}\n\telse{\n\t\tfinalColor = vec4((textureColor.xyz) * occlusion, alfa);\n\t}\n gl_FragColor = finalColor; \n}",ModelRefSsaoVS:"\tattribute vec3 position;\n\tattribute vec3 normal;\n\tattribute vec2 texCoord;\n\tattribute vec4 color4;\n\t\n\tuniform mat4 buildingRotMatrix; \n\tuniform mat4 projectionMatrix; \n\tuniform mat4 modelViewMatrix;\n\tuniform mat4 modelViewMatrixRelToEye; \n\tuniform mat4 ModelViewProjectionMatrixRelToEye;\n\tuniform mat4 RefTransfMatrix;\n\tuniform mat4 normalMatrix4;\n\tuniform vec3 buildingPosHIGH;\n\tuniform vec3 buildingPosLOW;\n\tuniform vec3 encodedCameraPositionMCHigh;\n\tuniform vec3 encodedCameraPositionMCLow;\n\tuniform vec3 aditionalPosition;\n\tuniform vec3 refTranslationVec;\n\tuniform int refMatrixType; // 0= identity, 1= translate, 2= transform\n\tuniform bool bApplySpecularLighting;\n\tuniform highp int colorType; // 0= oneColor, 1= attribColor, 2= texture.\n\n\tvarying vec3 vNormal;\n\tvarying vec2 vTexCoord; \n\tvarying vec3 uAmbientColor;\n\tvarying vec3 vLightWeighting;\n\tvarying vec3 vertexPos;\n\tvarying float applySpecLighting;\n\tvarying vec4 aColor4; // color from attributes\n\t\n\tvoid main()\n {\t\n\t\tvec4 rotatedPos;\n\t\tmat3 currentTMat;\n\t\tif(refMatrixType == 0)\n\t\t{\n\t\t\trotatedPos = buildingRotMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t\t\tcurrentTMat = mat3(buildingRotMatrix);\n\t\t}\n\t\telse if(refMatrixType == 1)\n\t\t{\n\t\t\trotatedPos = buildingRotMatrix * vec4(position.xyz + refTranslationVec.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t\t\tcurrentTMat = mat3(buildingRotMatrix);\n\t\t}\n\t\telse if(refMatrixType == 2)\n\t\t{\n\t\t\trotatedPos = RefTransfMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t\t\tcurrentTMat = mat3(RefTransfMatrix);\n\t\t}\n\n\t\tvec3 objPosHigh = buildingPosHIGH;\n\t\tvec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n\t\tvec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n\t\tvec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n\t\tvec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\n\t\t//vertexPos = vec3(modelViewMatrixRelToEye * pos4);\n\t\tvec3 rotatedNormal = currentTMat * normal;\n\t\tvLightWeighting = vec3(1.0, 1.0, 1.0);\n\t\tuAmbientColor = vec3(0.8);\n\t\tvec3 uLightingDirection = vec3(0.6, 0.6, 0.6);\n\t\tvec3 directionalLightColor = vec3(0.7, 0.7, 0.7);\n\t\tvNormal = (normalMatrix4 * vec4(rotatedNormal.x, rotatedNormal.y, rotatedNormal.z, 1.0)).xyz;\n\t\tvTexCoord = texCoord;\n\t\tfloat directionalLightWeighting = max(dot(vNormal, uLightingDirection), 0.0);\n\t\tvLightWeighting = uAmbientColor + directionalLightColor * directionalLightWeighting;\n\t\t\n\t\tif(bApplySpecularLighting)\n\t\t\tapplySpecLighting = 1.0;\n\t\telse\n\t\t\tapplySpecLighting = -1.0;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\t\t\n\t\tif(colorType == 1)\n\t\t\taColor4 = color4;\n\t}",PngImageFS:"precision mediump float;\nvarying vec2 v_texcoord;\nuniform bool textureFlipYAxis;\nuniform sampler2D u_texture;\n\nvoid main()\n{\n vec4 textureColor;\n if(textureFlipYAxis)\n {\n textureColor = texture2D(u_texture, vec2(v_texcoord.s, 1.0 - v_texcoord.t));\n }\n else\n {\n textureColor = texture2D(u_texture, v_texcoord);\n }\n if(textureColor.w < 0.1)\n {\n discard;\n }\n\n gl_FragColor = textureColor;\n}",PngImageVS:"attribute vec3 a_position;\nattribute vec2 a_texcoord;\nuniform mat4 buildingRotMatrix; \nuniform mat4 ModelViewProjectionMatrixRelToEye; \nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nvarying vec2 v_texcoord;\n\nvoid main()\n{\n vec4 position2 = vec4(a_position.xyz, 1.0);\n vec4 rotatedPos = buildingRotMatrix * vec4(position2.xyz, 1.0);\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\n v_texcoord = a_texcoord;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n}\n",PointCloudDepthVS:"attribute vec3 position;\nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform mat4 modelViewMatrixRelToEye; \nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform mat4 buildingRotMatrix;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nuniform float near;\nuniform float far;\nuniform bool bPositionCompressed;\nuniform vec3 minPosition;\nuniform vec3 bboxSize;\nattribute vec4 color4;\nuniform bool bUse1Color;\nuniform vec4 oneColor4;\nuniform float fixPointSize;\nuniform bool bUseFixPointSize;\nvarying vec4 vColor;\n//varying float glPointSize;\nvarying float depth; \n\nvoid main()\n{\n\tvec3 realPos;\n\tvec4 rotatedPos;\n\tif(bPositionCompressed)\n\t{\n\t\tfloat maxShort = 65535.0;\n\t\trealPos = vec3(float(position.x)/maxShort*bboxSize.x + minPosition.x, float(position.y)/maxShort*bboxSize.y + minPosition.y, float(position.z)/maxShort*bboxSize.z + minPosition.z);\n\t}\n\telse\n\t{\n\t\trealPos = position;\n\t}\n\trotatedPos = buildingRotMatrix * vec4(realPos.xyz, 1.0);\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\t\n if(bUse1Color)\n\t{\n\t\tvColor=oneColor4;\n\t}\n\telse\n\t\tvColor=color4;\n\t\n gl_Position = ModelViewProjectionMatrixRelToEye * pos;\n\tfloat z_b = gl_Position.z/gl_Position.w;\n\tfloat z_n = 2.0 * z_b - 1.0;\n float z_e = 2.0 * near * far / (far + near - z_n * (far - near));\n\tgl_PointSize = 1.0 + 40.0/z_e; // Original.***\n\tif(gl_PointSize > 10.0)\n\t\tgl_PointSize = 10.0;\n\tif(gl_PointSize < 2.0)\n\t\tgl_PointSize = 2.0;\n\t\t\n\tdepth = (modelViewMatrixRelToEye * pos).z/far; // original.***\n}",PointCloudFS:"\tprecision lowp float;\n\tvarying vec4 vColor;\n\n\tvoid main()\n {\n\t\tgl_FragColor = vColor;\n\t}",PointCloudSsaoFS:"#ifdef GL_ES\n precision highp float;\n#endif\n\nuniform sampler2D depthTex;\nuniform mat4 projectionMatrix;\nuniform float near;\nuniform float far; \nuniform float fov;\nuniform float aspectRatio; \nuniform float screenWidth; \nuniform float screenHeight; \nuniform vec3 kernel[16]; \nuniform vec4 oneColor4;\nvarying vec4 aColor4; // color from attributes\nvarying vec4 vColor;\nvarying float glPointSize;\n\nconst int kernelSize = 16; \nuniform float radius; \n\nuniform bool bApplySsao;\nuniform float externalAlpha;\n\nfloat unpackDepth(const in vec4 rgba_depth)\n{\n const vec4 bit_shift = vec4(0.000000059605, 0.000015258789, 0.00390625, 1.0);\n float depth = dot(rgba_depth, bit_shift);\n return depth;\n} \n\nvec3 getViewRay(vec2 tc)\n{\n float hfar = 2.0 * tan(fov/2.0) * far;\n float wfar = hfar * aspectRatio; \n vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n return ray; \n} \n \n//linear view space depth\nfloat getDepth(vec2 coord)\n{\n return unpackDepth(texture2D(depthTex, coord.xy));\n} \n\nvoid main()\n{\n\tfloat occlusion = 0.0;\n\tif(bApplySsao)\n\t{ \n\t\tvec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight);\n\t\tfloat linearDepth = getDepth(screenPos);\n\t\tvec3 origin = getViewRay(screenPos) * linearDepth;\n\t\tfloat radiusAux = glPointSize/1.9;\n\t\tradiusAux = 1.5;\n\t\tvec2 screenPosAdjacent;\n\t\t\n\t\tfor(int j = 0; j < 1; ++j)\n\t\t{\n\t\t\tradiusAux = 1.5 *(float(j)+1.0);\n\t\t\tfor(int i = 0; i < 8; ++i)\n\t\t\t{ \t \n\t\t\t\tif(i == 0)\n\t\t\t\t\tscreenPosAdjacent = vec2((gl_FragCoord.x - radiusAux)/ screenWidth, (gl_FragCoord.y - radiusAux) / screenHeight);\n\t\t\t\telse if(i == 1)\n\t\t\t\t\tscreenPosAdjacent = vec2((gl_FragCoord.x)/ screenWidth, (gl_FragCoord.y - radiusAux) / screenHeight);\n\t\t\t\telse if(i == 2)\n\t\t\t\t\tscreenPosAdjacent = vec2((gl_FragCoord.x + radiusAux)/ screenWidth, (gl_FragCoord.y - radiusAux) / screenHeight);\n\t\t\t\telse if(i == 3)\n\t\t\t\t\tscreenPosAdjacent = vec2((gl_FragCoord.x + radiusAux)/ screenWidth, (gl_FragCoord.y) / screenHeight);\n\t\t\t\telse if(i == 4)\n\t\t\t\t\tscreenPosAdjacent = vec2((gl_FragCoord.x + radiusAux)/ screenWidth, (gl_FragCoord.y + radiusAux) / screenHeight);\n\t\t\t\telse if(i == 5)\n\t\t\t\t\tscreenPosAdjacent = vec2((gl_FragCoord.x)/ screenWidth, (gl_FragCoord.y + radiusAux) / screenHeight);\n\t\t\t\telse if(i == 6)\n\t\t\t\t\tscreenPosAdjacent = vec2((gl_FragCoord.x - radiusAux)/ screenWidth, (gl_FragCoord.y + radiusAux) / screenHeight);\n\t\t\t\telse if(i == 7)\n\t\t\t\t\tscreenPosAdjacent = vec2((gl_FragCoord.x - radiusAux)/ screenWidth, (gl_FragCoord.y) / screenHeight);\n\t\t\t\tfloat depthBufferValue = getDepth(screenPosAdjacent);\n\t\t\t\tfloat range_check = abs(linearDepth - depthBufferValue)*far;\n\t\t\t\tif (range_check > 1.5 && depthBufferValue > linearDepth)\n\t\t\t\t{\n\t\t\t\t\tif (range_check < 20.0)\n\t\t\t\t\t\tocclusion += 1.0;\n\t\t\t\t}\n\t\t\t} \n\t\t} \n\t\t\t\n\t\tif(occlusion > 6.0)\n\t\t\tocclusion = 8.0;\n\t\t//else occlusion = 0.0;\n\t\tocclusion = 1.0 - occlusion / 8.0;\n\t}\n\telse{\n\t\tocclusion = 1.0;\n\t}\n\n vec4 finalColor;\n\tfinalColor = vec4((vColor.xyz) * occlusion, externalAlpha);\n\t//finalColor = vec4(vec3(0.8, 0.8, 0.8) * occlusion, externalAlpha);\n gl_FragColor = finalColor; \n}",PointCloudVS:"attribute vec3 position;\nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform mat4 buildingRotMatrix;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nuniform float near;\nuniform float far;\nuniform bool bPositionCompressed;\nuniform vec3 minPosition;\nuniform vec3 bboxSize;\nattribute vec4 color4;\nuniform bool bUse1Color;\nuniform vec4 oneColor4;\nuniform float fixPointSize;\nuniform bool bUseFixPointSize;\nvarying vec4 vColor;\nvarying float glPointSize;\n\nvoid main()\n{\n\tvec3 realPos;\n\tvec4 rotatedPos;\n\tif(bPositionCompressed)\n\t{\n\t\tfloat maxShort = 65535.0;\n\t\trealPos = vec3(float(position.x)/maxShort*bboxSize.x + minPosition.x, float(position.y)/maxShort*bboxSize.y + minPosition.y, float(position.z)/maxShort*bboxSize.z + minPosition.z);\n\t}\n\telse\n\t{\n\t\trealPos = position;\n\t}\n\trotatedPos = buildingRotMatrix * vec4(realPos.xyz, 1.0);\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\t\n if(bUse1Color)\n\t{\n\t\tvColor=oneColor4;\n\t}\n\telse\n\t\tvColor=color4;\n\t\n gl_Position = ModelViewProjectionMatrixRelToEye * pos;\n\tfloat z_b = gl_Position.z/gl_Position.w;\n\tfloat z_n = 2.0 * z_b - 1.0;\n float z_e = 2.0 * near * far / (far + near - z_n * (far - near));\n\tgl_PointSize = 1.0 + 40.0/z_e; // Original.***\n\tif(gl_PointSize > 10.0)\n\t\tgl_PointSize = 10.0;\n\tif(gl_PointSize < 2.0)\n\t\tgl_PointSize = 2.0;\n\t\t\n\tglPointSize = gl_PointSize;\n}",quad_vert:"precision mediump float;\n\nattribute vec2 a_pos;\n\nvarying vec2 v_tex_pos;\n\nvoid main() {\n v_tex_pos = a_pos;\n gl_Position = vec4(1.0 - 2.0 * a_pos, 0, 1);\n}\n",RenderShowDepthFS:"#ifdef GL_ES\nprecision highp float;\n#endif\nuniform float near;\nuniform float far;\n\nvarying float depth; \n\nvec4 packDepth(const in float depth)\n{\n const vec4 bit_shift = vec4(16777216.0, 65536.0, 256.0, 1.0);\n const vec4 bit_mask = vec4(0.0, 0.00390625, 0.00390625, 0.00390625); \n vec4 res = fract(depth * bit_shift);\n res -= res.xxyz * bit_mask;\n return res; \n}\n\nvoid main()\n{ \n gl_FragData[0] = packDepth(-depth);\n}",RenderShowDepthVS:"attribute vec3 position;\n\nuniform mat4 buildingRotMatrix; \nuniform mat4 modelViewMatrixRelToEye; \nuniform mat4 RefTransfMatrix;\nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nuniform float near;\nuniform float far;\nuniform vec3 aditionalPosition;\nuniform vec3 refTranslationVec;\nuniform int refMatrixType; // 0= identity, 1= translate, 2= transform\n\nvarying float depth;\n \nvoid main()\n{\t\n\tvec4 rotatedPos;\n\n\tif(refMatrixType == 0)\n\t{\n\t\trotatedPos = buildingRotMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t}\n\telse if(refMatrixType == 1)\n\t{\n\t\trotatedPos = buildingRotMatrix * vec4(position.xyz + refTranslationVec.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t}\n\telse if(refMatrixType == 2)\n\t{\n\t\trotatedPos = RefTransfMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t}\n\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n \n //linear depth in camera space (0..far)\n depth = (modelViewMatrixRelToEye * pos4).z/far; // original.***\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\tgl_PointSize = 2.0;\n}",screen_frag:"precision mediump float;\n\nuniform sampler2D u_screen;\nuniform float u_opacity;\n\nvarying vec2 v_tex_pos;\n\nvoid main() {\n vec4 color = texture2D(u_screen, 1.0 - v_tex_pos);\n // a hack to guarantee opacity fade out even with a value close to 1.0\n gl_FragColor = vec4(floor(255.0 * color * u_opacity) / 255.0);\n}\n",SilhouetteFS:"precision highp float;\nuniform vec4 vColor4Aux;\n\nvoid main()\n{ \n gl_FragColor = vColor4Aux;\n}",SilhouetteVS:"attribute vec3 position;\n\nuniform mat4 buildingRotMatrix; \nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform mat4 ModelViewMatrixRelToEye;\nuniform mat4 ProjectionMatrix;\nuniform mat4 RefTransfMatrix;\nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nuniform vec3 aditionalPosition;\nuniform vec3 refTranslationVec;\nuniform int refMatrixType; // 0= identity, 1= translate, 2= transform\nuniform vec2 camSpacePixelTranslation;\nuniform vec2 screenSize; \nvarying vec2 camSpaceTranslation;\n\nvoid main()\n{ \n vec4 rotatedPos;\n\tif(refMatrixType == 0)\n\t{\n\t\trotatedPos = buildingRotMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t}\n\telse if(refMatrixType == 1)\n\t{\n\t\trotatedPos = buildingRotMatrix * vec4(position.xyz + refTranslationVec.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t}\n\telse if(refMatrixType == 2)\n\t{\n\t\trotatedPos = RefTransfMatrix * vec4(position.xyz, 1.0) + vec4(aditionalPosition.xyz, 0.0);\n\t}\n\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n vec4 camSpacePos = ModelViewMatrixRelToEye * pos4;\n vec4 translationVec = ProjectionMatrix * vec4(camSpacePixelTranslation.x*(-camSpacePos.z), camSpacePixelTranslation.y*(-camSpacePos.z), 0.0, 1.0);\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n gl_Position += translationVec; \n}",StandardFS:"precision lowp float;\nvarying vec3 vColor;\n\nvoid main()\n{\n gl_FragColor = vec4(vColor, 1.);\n}",StandardVS:"attribute vec3 position;\nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nuniform mat4 RefTransfMatrix;\nattribute vec3 color;\nvarying vec3 vColor;\n\nvoid main()\n{\n vec4 rotatedPos = RefTransfMatrix * vec4(position.xyz, 1.0);\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n \n vColor=color;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos;\n}",Test_QuadFS:"#ifdef GL_ES\n precision highp float;\n#endif\n \nuniform sampler2D diffuseTex; \nvarying vec2 vTexCoord; \nvoid main()\n{ \n vec4 textureColor = texture2D(diffuseTex, vec2(vTexCoord.s, vTexCoord.t));\n gl_FragColor = textureColor; \n}\n",Test_QuadVS:"attribute vec3 position;\nattribute vec2 texCoord;\n\nuniform sampler2D diffuseTex;\nuniform mat4 projectionMatrix; \nuniform mat4 modelViewMatrix;\nuniform mat4 modelViewMatrixRelToEye; \nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform mat4 normalMatrix4;\nuniform mat4 buildingRotMatrix; \nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\n\nvarying vec3 vNormal;\nvarying vec2 vTexCoord; \n\nvoid main()\n{\t\n vec4 rotatedPos = buildingRotMatrix * vec4(position.xyz, 1.0);\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\t\n vTexCoord = texCoord;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n}\n",TextureA1FS:"precision mediump float;\nvarying vec4 vColor;\nvarying vec2 vTextureCoord;\nuniform sampler2D uSampler;\n\nvoid main()\n{\n gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n}\n",TextureA1VS:"attribute vec3 position;\nattribute vec4 aVertexColor;\nattribute vec2 aTextureCoord;\nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nvarying vec4 vColor;\nvarying vec2 vTextureCoord;\n\nvoid main()\n{\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + position.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n \n vColor=aVertexColor;\n vTextureCoord = aTextureCoord;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos;\n}",TextureFS:"precision mediump float;\nvarying vec4 vColor;\nvarying vec2 vTextureCoord;\nuniform sampler2D uSampler;\n\nvoid main()\n{\n gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n}",TextureNormalFS:"\tprecision mediump float;\n\tvarying vec4 vColor;\n\tvarying vec2 vTextureCoord;\n\tuniform sampler2D uSampler;\n\tvarying vec3 vLightWeighting;\n\n\tvoid main()\n {\n\t\tvec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));\n \n\t\tgl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a);\n\t}\n",TextureNormalVS:"attribute vec3 position;\nattribute vec4 aVertexColor;\nattribute vec2 aTextureCoord;\nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nvarying vec4 vColor;\nvarying vec2 vTextureCoord;\nattribute vec3 aVertexNormal;\nvarying vec3 uAmbientColor;\nvarying vec3 vLightWeighting;\nuniform mat3 uNMatrix;\n\nvoid main()\n{\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + position.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n \n vColor = aVertexColor;\n vTextureCoord = aTextureCoord;\n \n vLightWeighting = vec3(1.0, 1.0, 1.0);\n uAmbientColor = vec3(0.7, 0.7, 0.7);\n vec3 uLightingDirection = vec3(0.8, 0.2, -0.9);\n vec3 directionalLightColor = vec3(0.4, 0.4, 0.4);\n vec3 transformedNormal = uNMatrix * aVertexNormal;\n float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);\n vLightWeighting = uAmbientColor + directionalLightColor * directionalLightWeighting;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos;\n}\n",TextureVS:"attribute vec3 position;\nattribute vec4 aVertexColor;\nattribute vec2 aTextureCoord;\nuniform mat4 Mmatrix;\nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nvarying vec4 vColor;\nvarying vec2 vTextureCoord;\n\nvoid main()\n{\n vec4 rotatedPos = Mmatrix * vec4(position.xyz, 1.0);\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\n vColor=aVertexColor;\n vTextureCoord = aTextureCoord;\n\n gl_Position = ModelViewProjectionMatrixRelToEye * pos;\n \n}",TinTerrainFS:"#ifdef GL_ES\n precision highp float;\n#endif\n\nuniform sampler2D depthTex;\nuniform sampler2D noiseTex; \nuniform sampler2D diffuseTex;\nuniform bool hasTexture;\nuniform bool textureFlipYAxis;\nuniform bool bIsMakingDepth;\nvarying vec3 vNormal;\nuniform mat4 projectionMatrix;\nuniform mat4 m;\nuniform vec2 noiseScale;\nuniform float near;\nuniform float far; \nuniform float fov;\nuniform float aspectRatio; \nuniform float screenWidth; \nuniform float screenHeight; \nuniform float shininessValue;\nuniform vec3 kernel[16]; \nuniform vec4 vColor4Aux;\n\nvarying vec2 vTexCoord; \nvarying vec3 vLightWeighting;\n\nvarying vec3 diffuseColor;\nuniform vec3 specularColor;\nvarying vec3 vertexPos;\nvarying float depthValue;\n\nconst int kernelSize = 16; \nuniform float radius; \n\nuniform float ambientReflectionCoef;\nuniform float diffuseReflectionCoef; \nuniform float specularReflectionCoef; \n\nfloat unpackDepth(const in vec4 rgba_depth)\n{\n const vec4 bit_shift = vec4(0.000000059605, 0.000015258789, 0.00390625, 1.0);\n float depth = dot(rgba_depth, bit_shift);\n return depth;\n} \n\nvec4 packDepth(const in float depth)\n{\n const vec4 bit_shift = vec4(16777216.0, 65536.0, 256.0, 1.0);\n const vec4 bit_mask = vec4(0.0, 0.00390625, 0.00390625, 0.00390625); \n vec4 res = fract(depth * bit_shift);\n res -= res.xxyz * bit_mask;\n return res; \n} \n\nvec3 getViewRay(vec2 tc)\n{\n float hfar = 2.0 * tan(fov/2.0) * far;\n float wfar = hfar * aspectRatio; \n vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n return ray; \n}\n\n//linear view space depth\nfloat getDepth(vec2 coord)\n{\n return unpackDepth(texture2D(depthTex, coord.xy));\n} \n\nvoid main()\n{ \n\tif(bIsMakingDepth)\n\t{\n\t\tgl_FragColor = packDepth(-depthValue);\n\t}\n\telse{\n\t\tvec4 textureColor;\n\t\tif(hasTexture)\n\t\t{\n\t\t\tif(textureFlipYAxis)\n\t\t\t{\n\t\t\t\ttextureColor = texture2D(diffuseTex, vec2(vTexCoord.s, 1.0 - vTexCoord.t));\n\t\t\t}\n\t\t\telse{\n\t\t\t\ttextureColor = texture2D(diffuseTex, vec2(vTexCoord.s, vTexCoord.t));\n\t\t\t}\n\t\t\t\n\t\t\tif(textureColor.w == 0.0)\n\t\t\t{\n\t\t\t\tdiscard;\n\t\t\t}\n\t\t}\n\t\telse{\n\t\t\ttextureColor = vColor4Aux;\n\t\t}\n\t\t//vec3 ambientColor = vec3(textureColor.x, textureColor.y, textureColor.z);\n\t\tgl_FragColor = vec4(textureColor.xyz, 1.0); \n\t}\n}",TinTerrainVS:"attribute vec3 position;\nattribute vec3 normal;\nattribute vec4 color4;\nattribute vec2 texCoord;\n\nuniform sampler2D diffuseTex;\nuniform mat4 projectionMatrix; \nuniform mat4 modelViewMatrix;\nuniform mat4 modelViewMatrixRelToEye; \nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform mat4 ModelViewProjectionMatrix;\nuniform mat4 normalMatrix4;\nuniform mat4 buildingRotMatrix; \nuniform vec3 buildingPosHIGH;\nuniform vec3 buildingPosLOW;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\nuniform vec3 aditionalPosition;\nuniform vec4 oneColor4;\nuniform bool bUse1Color;\nuniform bool hasTexture;\nuniform bool bIsMakingDepth;\nuniform float near;\nuniform float far;\n\nvarying vec3 vNormal;\nvarying vec2 vTexCoord; \nvarying vec3 uAmbientColor;\nvarying vec3 vLightWeighting;\nvarying vec4 vcolor4;\nvarying vec3 vertexPos;\nvarying float depthValue;\n\nvoid main()\n{\t\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + position.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\n\tif(bIsMakingDepth)\n\t{\n\t\tdepthValue = (modelViewMatrixRelToEye * pos4).z/far;\n\t}\n\telse\n\t{\n\t\tvTexCoord = texCoord;\n\t}\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n\t\n}",update_frag:"precision highp float;\n\nuniform sampler2D u_particles;\nuniform sampler2D u_wind;\nuniform vec2 u_wind_res;\nuniform vec2 u_wind_min;\nuniform vec2 u_wind_max;\nuniform float u_rand_seed;\nuniform float u_speed_factor;\nuniform float u_drop_rate;\nuniform float u_drop_rate_bump;\nuniform bool u_flipTexCoordY_windMap;\n\nvarying vec2 v_tex_pos;\n\n// pseudo-random generator\nconst vec3 rand_constants = vec3(12.9898, 78.233, 4375.85453);\nfloat rand(const vec2 co) {\n float t = dot(rand_constants.xy, co);\n return fract(sin(t) * (rand_constants.z + t));\n}\n\n// wind speed lookup; use manual bilinear filtering based on 4 adjacent pixels for smooth interpolation\nvec2 lookup_wind(const vec2 uv) {\n // return texture2D(u_wind, uv).rg; // lower-res hardware filtering\n vec2 px = 1.0 / u_wind_res;\n vec2 vc = (floor(uv * u_wind_res)) * px;\n vec2 f = fract(uv * u_wind_res);\n vec2 tl = texture2D(u_wind, vc).rg;\n vec2 tr = texture2D(u_wind, vc + vec2(px.x, 0)).rg;\n vec2 bl = texture2D(u_wind, vc + vec2(0, px.y)).rg;\n vec2 br = texture2D(u_wind, vc + px).rg;\n return mix(mix(tl, tr, f.x), mix(bl, br, f.x), f.y);\n}\n\nvoid main() {\n vec4 color = texture2D(u_particles, v_tex_pos);\n vec2 pos = vec2(\n color.r / 255.0 + color.b,\n color.g / 255.0 + color.a); // decode particle position from pixel RGBA\n\tvec2 windMapTexCoord = pos;\n\tif(u_flipTexCoordY_windMap)\n\t{\n\t\twindMapTexCoord.y = 1.0 - windMapTexCoord.y;\n\t}\n vec2 velocity = mix(u_wind_min, u_wind_max, lookup_wind(windMapTexCoord));\n float speed_t = length(velocity) / length(u_wind_max);\n\n // take EPSG:4236 distortion into account for calculating where the particle moved\n float distortion = cos(radians(pos.y * 180.0 - 90.0));\n vec2 offset = vec2(velocity.x / distortion, -velocity.y) * 0.0001 * u_speed_factor;\n\n // update particle position, wrapping around the date line\n pos = fract(1.0 + pos + offset);\n\n // a random seed to use for the particle drop\n vec2 seed = (pos + v_tex_pos) * u_rand_seed;\n\n // drop rate is a chance a particle will restart at random position, to avoid degeneration\n float drop_rate = u_drop_rate + speed_t * u_drop_rate_bump;\n float drop = step(1.0 - drop_rate, rand(seed));\n\n vec2 random_pos = vec2(\n rand(seed + 1.3),\n rand(seed + 2.1));\n pos = mix(pos, random_pos, drop);\n\n // encode the new particle position back into RGBA\n gl_FragColor = vec4(\n fract(pos * 255.0),\n floor(pos * 255.0) / 255.0);\n}",vol_fs:"#ifdef GL_ES\nprecision highp float;\n#endif\n\n//---------------------------------------------------------\n// MACROS\n//---------------------------------------------------------\n\n#define EPS 0.0001\n#define PI 3.14159265\n#define HALFPI 1.57079633\n#define ROOTTHREE 1.73205081\n\n#define EQUALS(A,B) ( abs((A)-(B)) < EPS )\n#define EQUALSZERO(A) ( ((A)-EPS) )\n\n\n//---------------------------------------------------------\n// CONSTANTS\n//---------------------------------------------------------\n\n// 32 48 64 96 128\n#define MAX_STEPS 64\n\n#define LIGHT_NUM 2\n//#define uTMK 20.0\n#define TM_MIN 0.05\n\n\n//---------------------------------------------------------\n// SHADER VARS\n//---------------------------------------------------------\n\nvarying vec2 vUv;\nvarying vec3 vPos0; // position in world coords\nvarying vec3 vPos1; // position in object coords\nvarying vec3 vPos1n; // normalized 0 to 1, for texture lookup\n\nuniform vec3 uOffset; // TESTDEBUG\n\nuniform vec3 uCamPos;\n\nuniform vec3 uLightP[LIGHT_NUM]; // point lights\nuniform vec3 uLightC[LIGHT_NUM];\n\nuniform vec3 uColor; // color of volume\nuniform sampler2D uTex; // 3D(2D) volume texture\nuniform vec3 uTexDim; // dimensions of texture\n\nuniform float uTMK;\n\nfloat gStepSize;\nfloat gStepFactor;\n\n\n//---------------------------------------------------------\n// PROGRAM\n//---------------------------------------------------------\n\n// TODO: convert world to local volume space\nvec3 toLocal(vec3 p) {\n return p + vec3(0.5);\n}\n\nfloat sampleVolTex(vec3 pos) {\n pos = pos + uOffset; // TESTDEBUG\n \n // note: z is up in 3D tex coords, pos.z is tex.y, pos.y is zSlice\n float zSlice = (1.0-pos.y)*(uTexDim.z-1.0); // float value of slice number, slice 0th to 63rd\n \n // calc pixels from top of texture\n float fromTopPixels =\n floor(zSlice)*uTexDim.y + // offset pix from top of tex, from upper slice \n pos.z*(uTexDim.y-1.0) + // y pos in pixels, range 0th to 63rd pix\n 0.5; // offset to center of cell\n \n // calc y tex coords of two slices\n float y0 = min( (fromTopPixels)/(uTexDim.y*uTexDim.z), 1.0);\n float y1 = min( (fromTopPixels+uTexDim.y)/(uTexDim.y*uTexDim.z), 1.0);\n \n // get (bi)linear interped texture reads at two slices\n float z0 = texture2D(uTex, vec2(pos.x, y0)).g;\n float z1 = texture2D(uTex, vec2(pos.x, y1)).g;\n \n // lerp them again (thus trilinear), using remaining fraction of zSlice\n return mix(z0, z1, fract(zSlice));\n}\n\n// accumulate density by ray marching\nfloat getDensity(vec3 ro, vec3 rd) {\n vec3 step = rd*gStepSize;\n vec3 pos = ro;\n \n float density = 0.0;\n \n for (int i=0; i 0.95 ||\n pos.x > 1.0 || pos.x < 0.0 ||\n pos.y > 1.0 || pos.y < 0.0 ||\n pos.z > 1.0 || pos.z < 0.0)\n break;\n }\n \n return density;\n}\n\n// calc transmittance\nfloat getTransmittance(vec3 ro, vec3 rd) {\n vec3 step = rd*gStepSize;\n vec3 pos = ro;\n \n float tm = 1.0;\n \n for (int i=0; i 1.0 || pos.x < 0.0 ||\n pos.y > 1.0 || pos.y < 0.0 ||\n pos.z > 1.0 || pos.z < 0.0)\n break;\n }\n \n return tm;\n}\n\nvec4 raymarchNoLight(vec3 ro, vec3 rd) {\n vec3 step = rd*gStepSize;\n vec3 pos = ro;\n \n vec3 col = vec3(0.0);\n float tm = 1.0;\n \n for (int i=0; i 1.0 || pos.x < 0.0 ||\n pos.y > 1.0 || pos.y < 0.0 ||\n pos.z > 1.0 || pos.z < 0.0)\n break;\n }\n \n float alpha = 1.0-tm;\n return vec4(col/alpha, alpha);\n}\n\nvec4 raymarchLight(vec3 ro, vec3 rd) {\n vec3 step = rd*gStepSize;\n vec3 pos = ro;\n \n \n vec3 col = vec3(0.0); // accumulated color\n float tm = 1.0; // accumulated transmittance\n \n for (int i=0; i 1.0 || pos.x < 0.0 ||\n pos.y > 1.0 || pos.y < 0.0 ||\n pos.z > 1.0 || pos.z < 0.0)\n break;\n }\n \n float alpha = 1.0-tm;\n return vec4(col/alpha, alpha);\n}\n\nvoid main() {\n // in world coords, just for now\n vec3 ro = vPos1n;\n vec3 rd = normalize( ro - toLocal(uCamPos) );\n //vec3 rd = normalize(ro-uCamPos);\n \n // step_size = root_three / max_steps ; to get through diagonal \n gStepSize = ROOTTHREE / float(MAX_STEPS);\n gStepFactor = 32.0 * gStepSize;\n \n gl_FragColor = raymarchLight(ro, rd);\n //gl_FragColor = vec4(uColor, getDensity(ro,rd));\n //gl_FragColor = vec4(vec3(sampleVolTex(pos)), 1.0);\n //gl_FragColor = vec4(vPos1n, 1.0);\n //gl_FragColor = vec4(uLightP[0], 1.0);\n}",vol_vs:"attribute vec3 aPosition;\n\nuniform sampler2D diffuseTex;\nuniform mat4 projectionMatrix; \nuniform mat4 modelViewMatrix;\nuniform mat4 modelViewMatrixRelToEye; \nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\n\nvarying vec3 vNormal;\nvarying vec3 vPosObjectCoord;\nvarying vec3 vPosCameraCoord;\nvarying vec3 vPosWorldCoord;\n\n// Render a fullScreen quad (2 triangles).***\nvoid main()\n{\n\tvec4 rotatedPos = buildingRotMatrix * vec4(position.xyz + aditionalPosition.xyz, 1.0);\n vec3 objPosHigh = buildingPosHIGH;\n vec3 objPosLow = buildingPosLOW.xyz + rotatedPos.xyz;\n vec3 highDifference = objPosHigh.xyz - encodedCameraPositionMCHigh.xyz;\n vec3 lowDifference = objPosLow.xyz - encodedCameraPositionMCLow.xyz;\n vec4 pos4 = vec4(highDifference.xyz + lowDifference.xyz, 1.0);\n\t\n gl_Position = ModelViewProjectionMatrixRelToEye * pos4;\n}",wgs84_volumFS:"precision mediump float;\n\n#define M_PI 3.1415926535897932384626433832795\n\nuniform sampler2D volumeTex;\nuniform mat4 projectionMatrix; \nuniform mat4 modelViewMatrix;\nuniform mat4 modelViewMatrixInv;\nuniform mat4 modelViewMatrixRelToEye; \nuniform mat4 ModelViewProjectionMatrixRelToEye;\nuniform vec3 encodedCameraPositionMCHigh;\nuniform vec3 encodedCameraPositionMCLow;\n\nuniform float screenWidth; \nuniform float screenHeight;\nuniform float aspectRatio;\nuniform float far;\nuniform float fovyRad;\nuniform float tanHalfFovy;\n\n// volume tex definition.***\nuniform int texNumCols;\nuniform int texNumRows;\nuniform int texNumSlices;\nuniform int numSlicesPerStacks;\nuniform int slicesNumCols;\nuniform int slicesNumRows;\nuniform float maxLon;\nuniform float minLon;\nuniform float maxLat;\nuniform float minLat;\nuniform float maxAlt;\nuniform float minAlt;\nuniform vec4 cuttingPlanes[6]; \nuniform int cuttingPlanesCount;\n\nuniform float maxValue;\nuniform float minValue;\n\nvec3 getViewRay(vec2 tc)\n{\n\tfloat hfar = 2.0 * tanHalfFovy * far;\n float wfar = hfar * aspectRatio; \n vec3 ray = vec3(wfar * (tc.x - 0.5), hfar * (tc.y - 0.5), -far); \n return ray; \n} \n\nfloat squaredLength(vec3 point1, vec3 point2)\n{\n\tfloat a = point1.x - point2.x;\n\tfloat b = point1.y - point2.y;\n\tfloat c = point1.z - point2.z;\n\t\n\tfloat sqDist = a*a + b*b + c*c;\n\treturn sqDist;\n}\n\nvoid intersectionLineSphere(float radius, vec3 rayPos, vec3 rayDir, out int intersectType, out vec3 nearIntersectPos, out vec3 farIntersectPos)\n{\n\t// line: (x, y, z) = x1 + t(x2 - x1), y1 + t(y2 - y1), z1 + t(z2 - z1)\n\t// sphere: (x - x3)^2 + (y - y3)^2 + (z - z3)^2 = r^2, where x3, y3, z3 is the center of the sphere.\n\t\n\t// line:\n\tvec3 p1 = rayPos;\n\tvec3 lineDir = rayDir;\n\tfloat dist = 1000.0;// any value is ok.***\n\tvec3 p2 = vec3(p1.x + lineDir.x * dist, p1.y + lineDir.y * dist, p1.z + lineDir.z * dist);\n\tfloat x1 = p1.x;\n\tfloat y1 = p1.y;\n\tfloat z1 = p1.z;\n\tfloat x2 = p2.x;\n\tfloat y2 = p2.y;\n\tfloat z2 = p2.z;\n\n\t// sphere:\n\tfloat x3 = 0.0;\n\tfloat y3 = 0.0;\n\tfloat z3 = 0.0;\n\tfloat r = radius;\n\t\n\t// resolve:\n\tfloat x21 = (x2-x1);\n\tfloat y21 = (y2-y1);\n\tfloat z21 = (z2-z1);\n\t\n\tfloat a = x21*x21 + y21*y21 + z21*z21;\n\t\n\tfloat x13 = (x1-x3);\n\tfloat y13 = (y1-y3);\n\tfloat z13 = (z1-z3);\n\t\n\tfloat b = 2.0*(x21 * x13 + y21 * y13 + z21 * z13);\n\t\n\tfloat c = x3*x3 + y3*y3 + z3*z3 + x1*x1 + y1*y1 + z1*z1 - 2.0*(x3*x1 + y3*y1+ z3*z1) - r*r;\n\t\n\tfloat discriminant = b*b - 4.0*a*c;\n\t\n\tif (discriminant < 0.0)\n\t{\n\t\t// no intersection.***\n\t\tintersectType = 0;\n\t}\n\telse if (discriminant == 0.0)\n\t{\n\t\t// this is tangent.***\n\t\tintersectType = 1;\n\t\t\n\t\tfloat t1 = (-b)/(2.0*a);\n\t\tnearIntersectPos = vec3(x1 + (x2 - x1)*t1, y1 + (y2 - y1)*t1, z1 + (z2 - z1)*t1);\n\t}\n\telse\n\t{\n\t\tintersectType = 2;\n\t\t\n\t\t// find the nearest to p1.***\n\t\tfloat sqrtDiscriminant = sqrt(discriminant);\n\t\tfloat t1 = (-b + sqrtDiscriminant)/(2.0*a);\n\t\tfloat t2 = (-b - sqrtDiscriminant)/(2.0*a);\n\t\t\n\t\t// solution 1.***\n\t\tvec3 intersectPoint1 = vec3(x1 + (x2 - x1)*t1, y1 + (y2 - y1)*t1, z1 + (z2 - z1)*t1);\n\t\tvec3 intersectPoint2 = vec3(x1 + (x2 - x1)*t2, y1 + (y2 - y1)*t2, z1 + (z2 - z1)*t2);\n\t\t\n\t\tfloat dist1 = squaredLength(p1,intersectPoint1);\n\t\tfloat dist2 = squaredLength(p1,intersectPoint2);\n\t\t\n\t\t// nearIntersectPos, out vec3 farIntersectPos\n\t\tif (dist1 < dist2)\n\t\t{\n\t\t\tnearIntersectPos = intersectPoint1;\n\t\t\tfarIntersectPos = intersectPoint2;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tnearIntersectPos = intersectPoint2;\n\t\t\tfarIntersectPos = intersectPoint1;\n\t\t}\n\t}\n}\n\nfloat atan2(float y, float x) \n{\n\tif(x > 0.0)\n\t{\n\t\treturn atan(y/x);\n\t}\n\telse if(x < 0.0)\n\t{\n\t\tif(y >= 0.0)\n\t\t{\n\t\t\treturn atan(y/x) + M_PI;\n\t\t}\n\t\telse{\n\t\t\treturn atan(y/x) - M_PI;\n\t\t}\n\t}\n\telse if(x == 0.0)\n\t{\n\t\tif(y>0.0)\n\t\t{\n\t\t\treturn M_PI/2.0;\n\t\t}\n\t\telse if(y<0.0)\n\t\t{\n\t\t\treturn -M_PI/2.0;\n\t\t}\n\t\telse{\n\t\t\treturn 0.0; // return undefined.***\n\t\t}\n\t}\n}\n\nvoid cartesianToGeographicWgs84(vec3 point, out vec3 result) \n{\n\t// From WebWorldWind.***\n\t// According to H. Vermeille, An analytical method to transform geocentric into geodetic coordinates\n\t// http://www.springerlink.com/content/3t6837t27t351227/fulltext.pdf\n\t\n\tfloat firstEccentricitySquared = 6.69437999014E-3;\n\tfloat equatorialRadius = 6378137.0;\n\n\t// wwwind coord type.***\n\t// X = point.z;\n\t// Y = point.x;\n\t// Z = point.y;\n\n\t// magoWorld coord type.***\n\tfloat X = point.x;\n\tfloat Y = point.y;\n\tfloat Z = point.z;\n\tfloat XXpYY = X * X + Y * Y;\n\tfloat sqrtXXpYY = sqrt(XXpYY);\n\tfloat a = equatorialRadius;\n\tfloat ra2 = 1.0 / (a * a);\n\tfloat e2 = firstEccentricitySquared;\n\tfloat e4 = e2 * e2;\n\tfloat p = XXpYY * ra2;\n\tfloat q = Z * Z * (1.0 - e2) * ra2;\n\tfloat r = (p + q - e4) / 6.0;\n\tfloat h;\n\tfloat phi;\n\tfloat u;\n\tfloat evoluteBorderTest = 8.0 * r * r * r + e4 * p * q;\n\tfloat rad1;\n\tfloat rad2;\n\tfloat rad3;\n\tfloat atanAux;\n\tfloat v;\n\tfloat w;\n\tfloat k;\n\tfloat D;\n\tfloat sqrtDDpZZ;\n\tfloat e;\n\tfloat lambda;\n\tfloat s2;\n\tfloat cbrtFac = 1.0/3.0;\n\n\tif (evoluteBorderTest > 0.0 || q != 0.0) \n\t{\n\t\tif (evoluteBorderTest > 0.0) \n\t\t{\n\t\t\t// Step 2: general case\n\t\t\trad1 = sqrt(evoluteBorderTest);\n\t\t\trad2 = sqrt(e4 * p * q);\n\n\t\t\t// 10*e2 is my arbitrary decision of what Vermeille means by near... the cusps of the evolute.\n\t\t\tif (evoluteBorderTest > 10.0 * e2) \n\t\t\t{\n\t\t\t\trad3 = pow((rad1 + rad2) * (rad1 + rad2), cbrtFac);\n\t\t\t\tu = r + 0.5 * rad3 + 2.0 * r * r / rad3;\n\t\t\t}\n\t\t\telse \n\t\t\t{\n\t\t\t\tu = r + 0.5 * pow((rad1 + rad2) * (rad1 + rad2), cbrtFac)\n\t\t\t\t\t+ 0.5 * pow((rad1 - rad2) * (rad1 - rad2), cbrtFac);\n\t\t\t}\n\t\t}\n\t\telse \n\t\t{\n\t\t\t// Step 3: near evolute\n\t\t\trad1 = sqrt(-evoluteBorderTest);\n\t\t\trad2 = sqrt(-8.0 * r * r * r);\n\t\t\trad3 = sqrt(e4 * p * q);\n\t\t\tatanAux = 2.0 * atan2(rad3, rad1 + rad2) / 3.0;\n\n\t\t\tu = -4.0 * r * sin(atanAux) * cos(M_PI / 6.0 + atanAux);\n\t\t}\n\n\t\tv = sqrt(u * u + e4 * q);\n\t\tw = e2 * (u + v - q) / (2.0 * v);\n\t\tk = (u + v) / (sqrt(w * w + u + v) + w);\n\t\tD = k * sqrtXXpYY / (k + e2);\n\t\tsqrtDDpZZ = sqrt(D * D + Z * Z);\n\n\t\th = (k + e2 - 1.0) * sqrtDDpZZ / k;\n\t\tphi = 2.0 * atan2(Z, sqrtDDpZZ + D);\n\t}\n\telse \n\t{\n\t\t// Step 4: singular disk\n\t\trad1 = sqrt(1.0 - e2);\n\t\trad2 = sqrt(e2 - p);\n\t\te = sqrt(e2);\n\n\t\th = -a * rad1 * rad2 / e;\n\t\tphi = rad2 / (e * rad2 + rad1 * sqrt(p));\n\t}\n\n\t// Compute lambda\n\ts2 = sqrt(2.0);\n\tif ((s2 - 1.0) * Y < sqrtXXpYY + X) \n\t{\n\t\t// case 1 - -135deg < lambda < 135deg\n\t\tlambda = 2.0 * atan2(Y, sqrtXXpYY + X);\n\t}\n\telse if (sqrtXXpYY + Y < (s2 + 1.0) * X) \n\t{\n\t\t// case 2 - -225deg < lambda < 45deg\n\t\tlambda = -M_PI * 0.5 + 2.0 * atan2(X, sqrtXXpYY - Y);\n\t}\n\telse \n\t{\n\t\t// if (sqrtXXpYY-Y<(s2=1)*X) { // is the test, if needed, but it's not\n\t\t// case 3: - -45deg < lambda < 225deg\n\t\tlambda = M_PI * 0.5 - 2.0 * atan2(X, sqrtXXpYY + Y);\n\t}\n\n\tfloat factor = 180.0 / M_PI;\n\tresult = vec3(factor * lambda, factor * phi, h); // (longitude, latitude, altitude).***\n}\n\nbool isPointRearCamera(vec3 point, vec3 camPos, vec3 camDir)\n{\n\tbool isRear = false;\n\tfloat lambdaX = 10.0;\n\tfloat lambdaY = 10.0;\n\tfloat lambdaZ = 10.0;\n\tif(abs(camDir.x) > 0.0000001)\n\t{\n\t\tfloat lambdaX = (point.x - camPos.x)/camDir.x;\n\t}\n\telse if(abs(camDir.y) > 0.0000001)\n\t{\n\t\tfloat lambdaY = (point.y - camPos.y)/camDir.y;\n\t}\n\telse if(abs(camDir.z) > 0.0000001)\n\t{\n\t\tfloat lambdaZ = (point.z - camPos.z)/camDir.z;\n\t}\n\t\n\tif(lambdaZ < 0.0 || lambdaY < 0.0 || lambdaX < 0.0)\n\t\t\tisRear = true;\n\t\telse\n\t\t\tisRear = false;\n\treturn isRear;\n}\n\nfloat distPointToPlane(vec3 point, vec4 plane)\n{\n\treturn (point.x*plane.x + point.y*plane.y + point.z*plane.z + plane.w);\n}\n\nbool getValue(vec3 geoLoc, out vec4 value)\n{\n\t// geoLoc = (longitude, latitude, altitude).***\n\tfloat lon = geoLoc.x;\n\tfloat lat = geoLoc.y;\n\tfloat alt = geoLoc.z;\n\t\n\t// 1rst, check if geoLoc intersects the volume.***\n\t// Note: minLon, maxLon, minLat, maxLat, minAlt & maxAlt are uniforms.***\n\tif(lon < minLon || lon > maxLon)\n\t\treturn false;\n\telse if(lat < minLat || lat > maxLat)\n\t\treturn false;\n\telse if(alt < minAlt || alt > maxAlt)\n\t\treturn false;\n\t\t\n\tfloat lonRange = maxLon - minLon;\n\tfloat latRange = maxLat - minLat;\n\tfloat altRange = maxAlt - minAlt;\n\tfloat col = (lon - minLon)/lonRange * float(slicesNumCols); \n\tfloat row = (lat - minLat)/latRange * float(slicesNumRows); \n\tfloat slice = (alt - minAlt)/altRange * float(texNumSlices); // slice if texture has only one stack.***\n\tfloat sliceDown = floor(slice);\n\tfloat sliceUp = ceil(slice);\n\tfloat sliceDownDist = slice - sliceDown;\n\t//slice = 18.0; // test. force slice to nearest to ground.***\n\t\n\tfloat stackDown = floor(sliceDown/float(numSlicesPerStacks));\n\tfloat realSliceDown = sliceDown - stackDown * float(numSlicesPerStacks);\n\tfloat tx = stackDown * float(slicesNumCols) + col;\n\tfloat ty = realSliceDown * float(slicesNumRows) + row;\n\tvec2 texCoord = vec2(tx/float(texNumCols), ty/float(texNumRows));\n\tvec4 valueDown = texture2D(volumeTex, texCoord);\n\t\n\tif(sliceDown < float(texNumSlices-1))\n\t{\n\t\tfloat stackUp = floor(sliceUp/float(numSlicesPerStacks));\n\t\tfloat realSliceUp = sliceUp - stackUp * float(numSlicesPerStacks);\n\t\tfloat tx2 = stackUp * float(slicesNumCols) + col;\n\t\tfloat ty2 = realSliceUp * float(slicesNumRows) + row;\n\t\tvec2 texCoord2 = vec2(tx2/float(texNumCols), ty2/float(texNumRows));\n\t\tvec4 valueUp = texture2D(volumeTex, texCoord2);\n\t\tvalue = valueDown*(1.0-sliceDownDist)+valueUp*(sliceDownDist);\n\t}\n\telse{\n\t\tvalue = valueDown;\n\t}\n\t//if((value.r * (maxValue - minValue)) > maxValue * 0.3)\n\t//\treturn true;\n\t//else return false;\n\treturn true;\n}\n\nvoid main() {\n\tvec2 screenPos = vec2(gl_FragCoord.x / screenWidth, gl_FragCoord.y / screenHeight);\n\tfloat linearDepth = 1.0; // the quad is 1m of dist of the camera.*** \n vec3 rayCamCoord = getViewRay(screenPos) * linearDepth; \n\trayCamCoord = normalize(rayCamCoord);\n\t\n\tvec3 camTarget = rayCamCoord * 10000.0;\n\tvec4 camPosWorld = vec4(encodedCameraPositionMCHigh + encodedCameraPositionMCLow, 1.0);\n\tvec4 camTargetWorld = modelViewMatrixInv * vec4(camTarget.xyz, 1.0);\n\tvec3 camDirWorld = camTargetWorld.xyz - camPosWorld.xyz;\n\tcamDirWorld = normalize(camDirWorld);\n\n\t// now, must find sampling points.***\n\tint intersectType = 0;\n\tvec3 nearP;\n\tvec3 farP;\n\tfloat radius = 6378137.0 + maxAlt; // equatorial radius.***\n\t//radius = 6250000.0 + maxAlt; // test radius.***\n\t\n\tintersectionLineSphere(radius, camPosWorld.xyz, camDirWorld, intersectType, nearP, farP);\n\t\n\tif(intersectType == 0)\n\t{\n\t\tdiscard;\n\t}\n\t\t\n\tif(intersectType == 1)\n\t{\n\t\t// provisionally discard.***\n\t\tdiscard;\t\n\t}\n\t\n\t// check if nearP is rear of the camera.***\n\tif(isPointRearCamera(nearP, camPosWorld.xyz, camDirWorld.xyz))\n\t{\n\t\tnearP = vec3(camPosWorld.xyz);\n\t}\n\tfloat dist = distance(nearP, farP);\n\tfloat testDist = dist;\n\tif(dist > 1500000.0)\n\t\ttestDist = 1500000.0;\n\t\n\t// now calculate the geographicCoords of 2 points.***\n\t// now, depending the dist(nearP, endPoint), determine numSmples.***\n\t// provisionally take 16 samples.***\n\tfloat numSamples = 512.0;\n\tvec4 color = vec4(0.0, 0.0, 0.0, 0.0);\n\tfloat alpha = 0.8/numSamples;\n\tfloat tempRange = maxValue - minValue;\n\tvec4 value;\n\tfloat totalValue = 0.0;\n\tint sampledsCount = 0;\n\tint intAux = 0;\n\tfloat increDist = testDist / numSamples;\n\tint c = 0;\n\tbool isPointRearPlane = true;\n\tfor(int i=0; i<512; i++)\n\t{\n\t\tvec3 currGeoLoc;\n\t\tvec3 currPosWorld = vec3(nearP.x + camDirWorld.x * increDist*float(c), nearP.y + camDirWorld.y * increDist*float(c), nearP.z + camDirWorld.z * increDist*float(c));\n\t\t// Check if the currPosWorld is in front or rear of planes (if exist planes).***\n\t\tint planesCounter = 0;\n\t\tfor(int j=0; j<6; j++)\n\t\t{\n\t\t\tif(planesCounter == cuttingPlanesCount)\n\t\t\t\tbreak;\n\t\t\t\n\t\t\tvec4 plane = cuttingPlanes[j];\n\t\t\tfloat dist = distPointToPlane(currPosWorld, plane);\n\t\t\tif(dist > 0.0)\n\t\t\t{\n\t\t\t\tisPointRearPlane = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\telse{\n\t\t\t\tisPointRearPlane = true;\n\t\t\t}\n\t\t\tplanesCounter++;\n\t\t}\n\t\t\n\t\t\n\t\tif(isPointRearPlane)\n\t\t{\n\t\t\tcartesianToGeographicWgs84(currPosWorld, currGeoLoc);\n\t\t\tif(getValue(currGeoLoc, value))\n\t\t\t{\n\t\t\t\tfloat realValue = value.r * tempRange + minValue*255.0;\n\t\t\t\ttotalValue += (value.r);\n\t\t\t\tsampledsCount += 1;\n\t\t\t}\n\t\t}\n\t\tif(sampledsCount >= 1)\n\t\t{\n\t\t\tbreak;\n\t\t}\n\t\tc++;\n\t}\n\tif(sampledsCount == 0)\n\t{\n\t\tdiscard;\n\t}\n\tfloat fValue = totalValue/numSamples;\n\tfValue = totalValue;\n\tif(fValue > 1.0)\n\t{\n\t\tgl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n\t\treturn;\n\t}\n\tfloat b = 1.0 - fValue;\n\tfloat g;\n\tif(fValue > 0.5)\n\t{\n\t\tg = 2.0-2.0*fValue;\n\t}\n\telse{\n\t\tg = 2.0*fValue;\n\t}\n\tfloat r = fValue;\n\tcolor += vec4(r,g,b,0.8);\n\tgl_FragColor = color;\n}",wgs84_volumVS:"precision mediump float;\n\nattribute vec3 position;\nuniform mat4 projectionMatrix;\n\nvoid main()\n{\t\n\tvec4 pos = projectionMatrix * vec4(position.xyz, 1.0);\n gl_Position = pos;\n}"},ii=function(t,e){if(!(this instanceof ii))throw new Error(z.CONSTRUCT_ERROR);this.gl=t,this.name=e,this.uniformLocation,this.floatValue};ii.prototype.bindUniform=function(){this.gl.uniform1f(this.uniformLocation,this.floatValue[0])};var ri=function(t,e){if(!(this instanceof ri))throw new Error(z.CONSTRUCT_ERROR);this.gl=t,this.name=e,this.uniformLocation,this.intValue};ri.prototype.bindUniform=function(){this.gl.uniform1i(this.uniformLocation,this.intValue)};var oi=function(t,e){if(!(this instanceof oi))throw new Error(z.CONSTRUCT_ERROR);this.gl=t,this.name=e,this.uniformLocation,this.matrix4fv};oi.prototype.bindUniform=function(){this.gl.uniformMatrix4fv(this.uniformLocation,!1,this.matrix4fv)};var ni=function(t,e){if(!(this instanceof ni))throw new Error(z.CONSTRUCT_ERROR);this.gl=t,this.name=e,this.uniformLocation,this.vec2fv};ni.prototype.bindUniform=function(){this.gl.uniform2fv(this.uniformLocation,this.vec2fv)};var ai=function(t,e){if(!(this instanceof ai))throw new Error(z.CONSTRUCT_ERROR);this.gl=t,this.name=e,this.uniformLocation,this.vec3fv};ai.prototype.bindUniform=function(){this.gl.uniform3fv(this.uniformLocation,this.vec3fv)};var si=function(t,e){if(!(this instanceof si))throw new Error(z.CONSTRUCT_ERROR);this.gl=t,this.name=e,this.uniformLocation,this.vec4fv};si.prototype.bindUniform=function(){this.gl.uniform4fv(this.uniformLocation,this.vec4fv)};var li=function(t){if(!(this instanceof li))throw new Error(z.CONSTRUCT_ERROR);this.nodeOwner,t&&(this.nodeOwner=t),this.id,this.nodesArray,this.edgesArray,this.spacesArray,this.attributes,this.edgesVboKeysContainer,this.nodesVboKeysContainer,this.renderSpaces=!0,this.spacesAlpha=.2};li.prototype.newNode=function(){void 0===this.nodesArray&&(this.nodesArray=[]);var t=new hi(this);return this.nodesArray.push(t),t},li.prototype.newEdge=function(){void 0===this.edgesArray&&(this.edgesArray=[]);var t=new di(this);return this.edgesArray.push(t),t},li.prototype.newSpace=function(){void 0===this.spacesArray&&(this.spacesArray=[]);var t=new ci(this);return this.spacesArray.push(t),t},li.prototype.test__makeVbos=function(t){var e=0;this.edgesArray&&(e=this.edgesArray.length);for(var i=[],r=0;r0){var c=1;l.uniform1i(e.refMatrixType_loc,c);for(var u=this.nodesArray[0],f=0;f0){s.uniform1i(e.colorType_loc,0);var h=1;s.uniform1i(e.refMatrixType_loc,h),s.uniform4fv(e.oneColor4_loc,[.3,.3,.9,1]);for(var c=this.nodesArray[0],u=0;u=0?(i=65536*Math.floor(t/65536),e.high=i,e.low=t-i):(i=65536*Math.floor(-t/65536),e.high=-i,e.low=t+i),e},pi.calculateSplited3fv=function(t,e,i){if(void 0!==t){void 0===e&&(e=new Float32Array(3)),void 0===i&&(i=new Float32Array(3));var r=new rt;r=this.calculateSplitedValues(t[0],r);var o=new rt;o=this.calculateSplitedValues(t[1],o);var n=new rt;n=this.calculateSplitedValues(t[2],n),e[0]=r.high,e[1]=o.high,e[2]=n.high,i[0]=r.low,i[1]=o.low,i[2]=n.low}},pi.calculatePixelLinearDepth=function(t,e,i,r,o){void 0===r&&(r=o.depthFboNeo),r&&r.bind();var n=new Uint8Array(4);return t.readPixels(e,o.sceneState.drawingBufferHeight-i,1,1,t.RGBA,t.UNSIGNED_BYTE,n),(n[0]/16777216+n[1]/65536+n[2]/256+n[3])/256},pi.calculatePixelPositionCamCoord=function(t,e,i,r,o,n,a){void 0===n&&(n=a.sceneState.camera.frustum.far);var s=pi.calculatePixelLinearDepth(t,e,i,o,a)*n;return a.resultRaySC=pi.getRayCamSpace(e,i,a.resultRaySC,a),void 0===r&&(r=new Ae),r.set(a.resultRaySC[0]*s,a.resultRaySC[1]*s,a.resultRaySC[2]*s),t.bindFramebuffer(t.FRAMEBUFFER,null),r},pi.cameraCoordPositionToWorldCoord=function(t,e,i){var r=i.sceneState.getModelViewMatrixInv();if(void 0===e)e=new Ae;return e=r.transformPoint3D(t,e)},pi.calculatePixelPositionWorldCoord=function(t,e,i,r,o,n,a){var s=new Ae;if(void 0===n&&(n=a.sceneState.camera.frustum.far),void 0===o&&(o=a.depthFboNeo),s=pi.calculatePixelPositionCamCoord(t,e,i,s,o,n,a),void 0===r)r=new Ae;return r=pi.cameraCoordPositionToWorldCoord(s,r,a)},pi.calculateWorldPositionToScreenCoord=function(t,e,i,r,o,n){void 0===o&&(o=new Ae),void 0===n.pointSC&&(n.pointSC=new Ae),void 0===n.pointSC2&&(n.pointSC2=new Ae),n.pointSC.set(e,i,r);var a=n.pointSC2,s=n.sceneState,l=(a=s.modelViewMatrix.transformPoint3D(n.pointSC,a)).z;if(l>0)return o.set(-1,-1,0),o;var d=s.camera.frustum.tangentOfHalfFovy*l*2,h=d*s.camera.frustum.aspectRatio,c=-a.x*s.drawingBufferWidth/h,u=-a.y*s.drawingBufferHeight/d;return c+=s.drawingBufferWidth/2,u+=s.drawingBufferHeight/2,u=s.drawingBufferHeight-u,o.set(c,u,0),o},pi.getRayCamSpace=function(t,e,i,r){var o=r.sceneState,n=o.camera.frustum,a=n.aspectRatio,s=2*n.tangentOfHalfFovy*1,l=s*a,d=t,h=o.drawingBufferHeight-e;return void 0===i&&(i=new Float32Array(3)),i[0]=l*(d/o.drawingBufferWidth-.5),i[1]=s*(h/o.drawingBufferHeight-.5),i[2]=-1,i},pi.getRayWorldSpace=function(t,e,i,r,o){void 0===r&&(r=new ce);var n=o.sceneState.camera.position,a=new Float32Array(3);a=pi.getRayCamSpace(e,i,a,o),void 0===o.pointSC&&(o.pointSC=new Ae);var s=o.pointSC,l=o.pointSC2;return s.set(a[0],a[1],a[2]),(l=o.sceneState.modelViewMatrixInv.rotatePoint3D(s,l)).unitary(),r.setPointAndDir(n.x,n.y,n.z,l.x,l.y,l.z),r};var vi=function(){if(!(this instanceof vi))throw new Error(z.CONSTRUCT_ERROR);this.mVertex1,this.mVertex2,this.mVertex3};vi.prototype.setVertices=function(t,e,i){this.mVertex1=t,this.mVertex2=e,this.mVertex3=i},vi.prototype.invert=function(){var t=this.mVertex2;this.mVertex2=this.mVertex3,this.mVertex3=t};var yi=function(){if(!(this instanceof yi))throw new Error(z.CONSTRUCT_ERROR);this.tTrianglesArray=[]};yi.prototype.newTTriangle=function(){var t=new vi;return this.tTrianglesArray.push(t),t},yi.prototype.invertTrianglesSense=function(){for(var t=0,e=this.tTrianglesArray.length;t=0&&tthis.max_X?this.max_X=i:ithis.max_Y?this.max_Y=r:rthis.max_Z?this.max_Z=o:othis.max_X?this.max_X=i:ithis.max_Y?this.max_Y=r:rthis.max_Z?this.max_Z=o:o 2 && arguments[2] !== undefined ? arguments[2] : {}; + + + options = _extends({}, defaults, options); + + function parse(ele, key, opts) { + if (key.length === 0) return; + + var attr = 'text'; + + if (key.indexOf('[') === 0) { + var parts = key.split(']'); + key = parts[1]; + attr = parts[0].substr(1, parts[0].length - 1); + } + + if (key.indexOf(';') === key.length - 1) { + key = key.substr(0, key.length - 2); + } + + function extendDefault(o, val) { + if (!options.parseDefaultValueFromContent) return o; + return _extends({}, o, { defaultValue: val }); + } + + if (attr === 'html') { + ele.html(i18next.t(key, extendDefault(opts, ele.html()))); + } else if (attr === 'text') { + ele.text(i18next.t(key, extendDefault(opts, ele.text()))); + } else if (attr === 'prepend') { + ele.prepend(i18next.t(key, extendDefault(opts, ele.html()))); + } else if (attr === 'append') { + ele.append(i18next.t(key, extendDefault(opts, ele.html()))); + } else if (attr.indexOf('data-') === 0) { + var dataAttr = attr.substr('data-'.length); + var translated = i18next.t(key, extendDefault(opts, ele.data(dataAttr))); + + // we change into the data cache + ele.data(dataAttr, translated); + // we change into the dom + ele.attr(attr, translated); + } else { + ele.attr(attr, i18next.t(key, extendDefault(opts, ele.attr(attr)))); + } + } + + function localize(ele, opts) { + var key = ele.attr(options.selectorAttr); + if (!key && typeof key !== 'undefined' && key !== false) key = ele.text() || ele.val(); + if (!key) return; + + var target = ele, + targetSelector = ele.data(options.targetAttr); + + if (targetSelector) target = ele.find(targetSelector) || ele; + + if (!opts && options.useOptionsAttr === true) opts = ele.data(options.optionsAttr); + + opts = opts || {}; + + if (key.indexOf(';') >= 0) { + var keys = key.split(';'); + + $.each(keys, function (m, k) { + // .trim(): Trim the comma-separated parameters on the data-i18n attribute. + if (k !== '') parse(target, k.trim(), opts); + }); + } else { + parse(target, key, opts); + } + + if (options.useOptionsAttr === true) { + var clone = {}; + clone = _extends({ clone: clone }, opts); + + delete clone.lng; + ele.data(options.optionsAttr, clone); + } + } + + function handle(opts) { + return this.each(function () { + // localize element itself + localize($(this), opts); + + // localize children + var elements = $(this).find('[' + options.selectorAttr + ']'); + elements.each(function () { + localize($(this), opts); + }); + }); + }; + + // $.t $.i18n shortcut + $[options.tName] = i18next.t.bind(i18next); + $[options.i18nName] = i18next; + + // selector function $(mySelector).localize(opts); + $.fn[options.handleName] = handle; +} + +var index = { + init: init +}; + +return index; + +}))); \ No newline at end of file diff --git a/externlib/jquery-i18next/jquery-i18next.min.js b/externlib/jquery-i18next/jquery-i18next.min.js new file mode 100644 index 00000000..aa24b693 --- /dev/null +++ b/externlib/jquery-i18next/jquery-i18next.min.js @@ -0,0 +1 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.jqueryI18next=e()}(this,function(){"use strict";function t(t,a){function i(n,a,i){function r(t,n){return f.parseDefaultValueFromContent?e({},t,{defaultValue:n}):t}if(0!==a.length){var o="text";if(0===a.indexOf("[")){var l=a.split("]");a=l[1],o=l[0].substr(1,l[0].length-1)}if(a.indexOf(";")===a.length-1&&(a=a.substr(0,a.length-2)),"html"===o)n.html(t.t(a,r(i,n.html())));else if("text"===o)n.text(t.t(a,r(i,n.text())));else if("prepend"===o)n.prepend(t.t(a,r(i,n.html())));else if("append"===o)n.append(t.t(a,r(i,n.html())));else if(0===o.indexOf("data-")){var s=o.substr("data-".length),d=t.t(a,r(i,n.data(s)));n.data(s,d),n.attr(o,d)}else n.attr(o,t.t(a,r(i,n.attr(o))))}}function r(t,n){var r=t.attr(f.selectorAttr);if(r||void 0===r||!1===r||(r=t.text()||t.val()),r){var o=t,l=t.data(f.targetAttr);if(l&&(o=t.find(l)||t),n||!0!==f.useOptionsAttr||(n=t.data(f.optionsAttr)),n=n||{},r.indexOf(";")>=0){var s=r.split(";");a.each(s,function(t,e){""!==e&&i(o,e.trim(),n)})}else i(o,r,n);if(!0===f.useOptionsAttr){var d={};d=e({clone:d},n),delete d.lng,t.data(f.optionsAttr,d)}}}function o(t){return this.each(function(){r(a(this),t),a(this).find("["+f.selectorAttr+"]").each(function(){r(a(this),t)})})}var f=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};f=e({},n,f),a[f.tName]=t.t.bind(t),a[f.i18nName]=t,a.fn[f.handleName]=o}var e=Object.assign||function(t){for(var e=1;e= min and a <= max. + */ + function inRange(a, min, max) { + return min <= a && a <= max; + } + + /** + * @param {!Array.<*>} array The array to check. + * @param {*} item The item to look for in the array. + * @return {boolean} True if the item appears in the array. + */ + function includes(array, item) { + return array.indexOf(item) !== -1; + } + + var floor = Math.floor; + + /** + * @param {*} o + * @return {Object} + */ + function ToDictionary(o) { + if (o === undefined) return {}; + if (o === Object(o)) return o; + throw TypeError('Could not convert argument to dictionary'); + } + + /** + * @param {string} string Input string of UTF-16 code units. + * @return {!Array.} Code points. + */ + function stringToCodePoints(string) { + // https://heycam.github.io/webidl/#dfn-obtain-unicode + + // 1. Let S be the DOMString value. + var s = String(string); + + // 2. Let n be the length of S. + var n = s.length; + + // 3. Initialize i to 0. + var i = 0; + + // 4. Initialize U to be an empty sequence of Unicode characters. + var u = []; + + // 5. While i < n: + while (i < n) { + + // 1. Let c be the code unit in S at index i. + var c = s.charCodeAt(i); + + // 2. Depending on the value of c: + + // c < 0xD800 or c > 0xDFFF + if (c < 0xD800 || c > 0xDFFF) { + // Append to U the Unicode character with code point c. + u.push(c); + } + + // 0xDC00 ≤ c ≤ 0xDFFF + else if (0xDC00 <= c && c <= 0xDFFF) { + // Append to U a U+FFFD REPLACEMENT CHARACTER. + u.push(0xFFFD); + } + + // 0xD800 ≤ c ≤ 0xDBFF + else if (0xD800 <= c && c <= 0xDBFF) { + // 1. If i = n−1, then append to U a U+FFFD REPLACEMENT + // CHARACTER. + if (i === n - 1) { + u.push(0xFFFD); + } + // 2. Otherwise, i < n−1: + else { + // 1. Let d be the code unit in S at index i+1. + var d = s.charCodeAt(i + 1); + + // 2. If 0xDC00 ≤ d ≤ 0xDFFF, then: + if (0xDC00 <= d && d <= 0xDFFF) { + // 1. Let a be c & 0x3FF. + var a = c & 0x3FF; + + // 2. Let b be d & 0x3FF. + var b = d & 0x3FF; + + // 3. Append to U the Unicode character with code point + // 2^16+2^10*a+b. + u.push(0x10000 + (a << 10) + b); + + // 4. Set i to i+1. + i += 1; + } + + // 3. Otherwise, d < 0xDC00 or d > 0xDFFF. Append to U a + // U+FFFD REPLACEMENT CHARACTER. + else { + u.push(0xFFFD); + } + } + } + + // 3. Set i to i+1. + i += 1; + } + + // 6. Return U. + return u; + } + + /** + * @param {!Array.} code_points Array of code points. + * @return {string} string String of UTF-16 code units. + */ + function codePointsToString(code_points) { + var s = ''; + for (var i = 0; i < code_points.length; ++i) { + var cp = code_points[i]; + if (cp <= 0xFFFF) { + s += String.fromCharCode(cp); + } else { + cp -= 0x10000; + s += String.fromCharCode((cp >> 10) + 0xD800, + (cp & 0x3FF) + 0xDC00); + } + } + return s; + } + + + // + // Implementation of Encoding specification + // https://encoding.spec.whatwg.org/ + // + + // + // 4. Terminology + // + + /** + * An ASCII byte is a byte in the range 0x00 to 0x7F, inclusive. + * @param {number} a The number to test. + * @return {boolean} True if a is in the range 0x00 to 0x7F, inclusive. + */ + function isASCIIByte(a) { + return 0x00 <= a && a <= 0x7F; + } + + /** + * An ASCII code point is a code point in the range U+0000 to + * U+007F, inclusive. + */ + var isASCIICodePoint = isASCIIByte; + + + /** + * End-of-stream is a special token that signifies no more tokens + * are in the stream. + * @const + */ var end_of_stream = -1; + + /** + * A stream represents an ordered sequence of tokens. + * + * @constructor + * @param {!(Array.|Uint8Array)} tokens Array of tokens that provide + * the stream. + */ + function Stream(tokens) { + /** @type {!Array.} */ + this.tokens = [].slice.call(tokens); + // Reversed as push/pop is more efficient than shift/unshift. + this.tokens.reverse(); + } + + Stream.prototype = { + /** + * @return {boolean} True if end-of-stream has been hit. + */ + endOfStream: function() { + return !this.tokens.length; + }, + + /** + * When a token is read from a stream, the first token in the + * stream must be returned and subsequently removed, and + * end-of-stream must be returned otherwise. + * + * @return {number} Get the next token from the stream, or + * end_of_stream. + */ + read: function() { + if (!this.tokens.length) + return end_of_stream; + return this.tokens.pop(); + }, + + /** + * When one or more tokens are prepended to a stream, those tokens + * must be inserted, in given order, before the first token in the + * stream. + * + * @param {(number|!Array.)} token The token(s) to prepend to the + * stream. + */ + prepend: function(token) { + if (Array.isArray(token)) { + var tokens = /**@type {!Array.}*/(token); + while (tokens.length) + this.tokens.push(tokens.pop()); + } else { + this.tokens.push(token); + } + }, + + /** + * When one or more tokens are pushed to a stream, those tokens + * must be inserted, in given order, after the last token in the + * stream. + * + * @param {(number|!Array.)} token The tokens(s) to push to the + * stream. + */ + push: function(token) { + if (Array.isArray(token)) { + var tokens = /**@type {!Array.}*/(token); + while (tokens.length) + this.tokens.unshift(tokens.shift()); + } else { + this.tokens.unshift(token); + } + } + }; + + // + // 5. Encodings + // + + // 5.1 Encoders and decoders + + /** @const */ + var finished = -1; + + /** + * @param {boolean} fatal If true, decoding errors raise an exception. + * @param {number=} opt_code_point Override the standard fallback code point. + * @return {number} The code point to insert on a decoding error. + */ + function decoderError(fatal, opt_code_point) { + if (fatal) + throw TypeError('Decoder error'); + return opt_code_point || 0xFFFD; + } + + /** + * @param {number} code_point The code point that could not be encoded. + * @return {number} Always throws, no value is actually returned. + */ + function encoderError(code_point) { + throw TypeError('The code point ' + code_point + ' could not be encoded.'); + } + + /** @interface */ + function Decoder() {} + Decoder.prototype = { + /** + * @param {Stream} stream The stream of bytes being decoded. + * @param {number} bite The next byte read from the stream. + * @return {?(number|!Array.)} The next code point(s) + * decoded, or null if not enough data exists in the input + * stream to decode a complete code point, or |finished|. + */ + handler: function(stream, bite) {} + }; + + /** @interface */ + function Encoder() {} + Encoder.prototype = { + /** + * @param {Stream} stream The stream of code points being encoded. + * @param {number} code_point Next code point read from the stream. + * @return {(number|!Array.)} Byte(s) to emit, or |finished|. + */ + handler: function(stream, code_point) {} + }; + + // 5.2 Names and labels + + // TODO: Define @typedef for Encoding: {name:string,labels:Array.} + // https://github.com/google/closure-compiler/issues/247 + + /** + * @param {string} label The encoding label. + * @return {?{name:string,labels:Array.}} + */ + function getEncoding(label) { + // 1. Remove any leading and trailing ASCII whitespace from label. + label = String(label).trim().toLowerCase(); + + // 2. If label is an ASCII case-insensitive match for any of the + // labels listed in the table below, return the corresponding + // encoding, and failure otherwise. + if (Object.prototype.hasOwnProperty.call(label_to_encoding, label)) { + return label_to_encoding[label]; + } + return null; + } + + /** + * Encodings table: https://encoding.spec.whatwg.org/encodings.json + * @const + * @type {!Array.<{ + * heading: string, + * encodings: Array.<{name:string,labels:Array.}> + * }>} + */ + var encodings = [ + { + "encodings": [ + { + "labels": [ + "unicode-1-1-utf-8", + "utf-8", + "utf8" + ], + "name": "UTF-8" + } + ], + "heading": "The Encoding" + }, + { + "encodings": [ + { + "labels": [ + "866", + "cp866", + "csibm866", + "ibm866" + ], + "name": "IBM866" + }, + { + "labels": [ + "csisolatin2", + "iso-8859-2", + "iso-ir-101", + "iso8859-2", + "iso88592", + "iso_8859-2", + "iso_8859-2:1987", + "l2", + "latin2" + ], + "name": "ISO-8859-2" + }, + { + "labels": [ + "csisolatin3", + "iso-8859-3", + "iso-ir-109", + "iso8859-3", + "iso88593", + "iso_8859-3", + "iso_8859-3:1988", + "l3", + "latin3" + ], + "name": "ISO-8859-3" + }, + { + "labels": [ + "csisolatin4", + "iso-8859-4", + "iso-ir-110", + "iso8859-4", + "iso88594", + "iso_8859-4", + "iso_8859-4:1988", + "l4", + "latin4" + ], + "name": "ISO-8859-4" + }, + { + "labels": [ + "csisolatincyrillic", + "cyrillic", + "iso-8859-5", + "iso-ir-144", + "iso8859-5", + "iso88595", + "iso_8859-5", + "iso_8859-5:1988" + ], + "name": "ISO-8859-5" + }, + { + "labels": [ + "arabic", + "asmo-708", + "csiso88596e", + "csiso88596i", + "csisolatinarabic", + "ecma-114", + "iso-8859-6", + "iso-8859-6-e", + "iso-8859-6-i", + "iso-ir-127", + "iso8859-6", + "iso88596", + "iso_8859-6", + "iso_8859-6:1987" + ], + "name": "ISO-8859-6" + }, + { + "labels": [ + "csisolatingreek", + "ecma-118", + "elot_928", + "greek", + "greek8", + "iso-8859-7", + "iso-ir-126", + "iso8859-7", + "iso88597", + "iso_8859-7", + "iso_8859-7:1987", + "sun_eu_greek" + ], + "name": "ISO-8859-7" + }, + { + "labels": [ + "csiso88598e", + "csisolatinhebrew", + "hebrew", + "iso-8859-8", + "iso-8859-8-e", + "iso-ir-138", + "iso8859-8", + "iso88598", + "iso_8859-8", + "iso_8859-8:1988", + "visual" + ], + "name": "ISO-8859-8" + }, + { + "labels": [ + "csiso88598i", + "iso-8859-8-i", + "logical" + ], + "name": "ISO-8859-8-I" + }, + { + "labels": [ + "csisolatin6", + "iso-8859-10", + "iso-ir-157", + "iso8859-10", + "iso885910", + "l6", + "latin6" + ], + "name": "ISO-8859-10" + }, + { + "labels": [ + "iso-8859-13", + "iso8859-13", + "iso885913" + ], + "name": "ISO-8859-13" + }, + { + "labels": [ + "iso-8859-14", + "iso8859-14", + "iso885914" + ], + "name": "ISO-8859-14" + }, + { + "labels": [ + "csisolatin9", + "iso-8859-15", + "iso8859-15", + "iso885915", + "iso_8859-15", + "l9" + ], + "name": "ISO-8859-15" + }, + { + "labels": [ + "iso-8859-16" + ], + "name": "ISO-8859-16" + }, + { + "labels": [ + "cskoi8r", + "koi", + "koi8", + "koi8-r", + "koi8_r" + ], + "name": "KOI8-R" + }, + { + "labels": [ + "koi8-ru", + "koi8-u" + ], + "name": "KOI8-U" + }, + { + "labels": [ + "csmacintosh", + "mac", + "macintosh", + "x-mac-roman" + ], + "name": "macintosh" + }, + { + "labels": [ + "dos-874", + "iso-8859-11", + "iso8859-11", + "iso885911", + "tis-620", + "windows-874" + ], + "name": "windows-874" + }, + { + "labels": [ + "cp1250", + "windows-1250", + "x-cp1250" + ], + "name": "windows-1250" + }, + { + "labels": [ + "cp1251", + "windows-1251", + "x-cp1251" + ], + "name": "windows-1251" + }, + { + "labels": [ + "ansi_x3.4-1968", + "ascii", + "cp1252", + "cp819", + "csisolatin1", + "ibm819", + "iso-8859-1", + "iso-ir-100", + "iso8859-1", + "iso88591", + "iso_8859-1", + "iso_8859-1:1987", + "l1", + "latin1", + "us-ascii", + "windows-1252", + "x-cp1252" + ], + "name": "windows-1252" + }, + { + "labels": [ + "cp1253", + "windows-1253", + "x-cp1253" + ], + "name": "windows-1253" + }, + { + "labels": [ + "cp1254", + "csisolatin5", + "iso-8859-9", + "iso-ir-148", + "iso8859-9", + "iso88599", + "iso_8859-9", + "iso_8859-9:1989", + "l5", + "latin5", + "windows-1254", + "x-cp1254" + ], + "name": "windows-1254" + }, + { + "labels": [ + "cp1255", + "windows-1255", + "x-cp1255" + ], + "name": "windows-1255" + }, + { + "labels": [ + "cp1256", + "windows-1256", + "x-cp1256" + ], + "name": "windows-1256" + }, + { + "labels": [ + "cp1257", + "windows-1257", + "x-cp1257" + ], + "name": "windows-1257" + }, + { + "labels": [ + "cp1258", + "windows-1258", + "x-cp1258" + ], + "name": "windows-1258" + }, + { + "labels": [ + "x-mac-cyrillic", + "x-mac-ukrainian" + ], + "name": "x-mac-cyrillic" + } + ], + "heading": "Legacy single-byte encodings" + }, + { + "encodings": [ + { + "labels": [ + "chinese", + "csgb2312", + "csiso58gb231280", + "gb2312", + "gb_2312", + "gb_2312-80", + "gbk", + "iso-ir-58", + "x-gbk" + ], + "name": "GBK" + }, + { + "labels": [ + "gb18030" + ], + "name": "gb18030" + } + ], + "heading": "Legacy multi-byte Chinese (simplified) encodings" + }, + { + "encodings": [ + { + "labels": [ + "big5", + "big5-hkscs", + "cn-big5", + "csbig5", + "x-x-big5" + ], + "name": "Big5" + } + ], + "heading": "Legacy multi-byte Chinese (traditional) encodings" + }, + { + "encodings": [ + { + "labels": [ + "cseucpkdfmtjapanese", + "euc-jp", + "x-euc-jp" + ], + "name": "EUC-JP" + }, + { + "labels": [ + "csiso2022jp", + "iso-2022-jp" + ], + "name": "ISO-2022-JP" + }, + { + "labels": [ + "csshiftjis", + "ms932", + "ms_kanji", + "shift-jis", + "shift_jis", + "sjis", + "windows-31j", + "x-sjis" + ], + "name": "Shift_JIS" + } + ], + "heading": "Legacy multi-byte Japanese encodings" + }, + { + "encodings": [ + { + "labels": [ + "cseuckr", + "csksc56011987", + "euc-kr", + "iso-ir-149", + "korean", + "ks_c_5601-1987", + "ks_c_5601-1989", + "ksc5601", + "ksc_5601", + "windows-949" + ], + "name": "EUC-KR" + } + ], + "heading": "Legacy multi-byte Korean encodings" + }, + { + "encodings": [ + { + "labels": [ + "csiso2022kr", + "hz-gb-2312", + "iso-2022-cn", + "iso-2022-cn-ext", + "iso-2022-kr" + ], + "name": "replacement" + }, + { + "labels": [ + "utf-16be" + ], + "name": "UTF-16BE" + }, + { + "labels": [ + "utf-16", + "utf-16le" + ], + "name": "UTF-16LE" + }, + { + "labels": [ + "x-user-defined" + ], + "name": "x-user-defined" + } + ], + "heading": "Legacy miscellaneous encodings" + } + ]; + + // Label to encoding registry. + /** @type {Object.}>} */ + var label_to_encoding = {}; + encodings.forEach(function(category) { + category.encodings.forEach(function(encoding) { + encoding.labels.forEach(function(label) { + label_to_encoding[label] = encoding; + }); + }); + }); + + // Registry of of encoder/decoder factories, by encoding name. + /** @type {Object.} */ + var encoders = {}; + /** @type {Object.} */ + var decoders = {}; + + // + // 6. Indexes + // + + /** + * @param {number} pointer The |pointer| to search for. + * @param {(!Array.|undefined)} index The |index| to search within. + * @return {?number} The code point corresponding to |pointer| in |index|, + * or null if |code point| is not in |index|. + */ + function indexCodePointFor(pointer, index) { + if (!index) return null; + return index[pointer] || null; + } + + /** + * @param {number} code_point The |code point| to search for. + * @param {!Array.} index The |index| to search within. + * @return {?number} The first pointer corresponding to |code point| in + * |index|, or null if |code point| is not in |index|. + */ + function indexPointerFor(code_point, index) { + var pointer = index.indexOf(code_point); + return pointer === -1 ? null : pointer; + } + + /** + * @param {string} name Name of the index. + * @return {(!Array.|!Array.>)} + * */ + function index(name) { + if (!('encoding-indexes' in global)) { + throw Error("Indexes missing." + + " Did you forget to include encoding-indexes.js first?"); + } + return global['encoding-indexes'][name]; + } + + /** + * @param {number} pointer The |pointer| to search for in the gb18030 index. + * @return {?number} The code point corresponding to |pointer| in |index|, + * or null if |code point| is not in the gb18030 index. + */ + function indexGB18030RangesCodePointFor(pointer) { + // 1. If pointer is greater than 39419 and less than 189000, or + // pointer is greater than 1237575, return null. + if ((pointer > 39419 && pointer < 189000) || (pointer > 1237575)) + return null; + + // 2. If pointer is 7457, return code point U+E7C7. + if (pointer === 7457) return 0xE7C7; + + // 3. Let offset be the last pointer in index gb18030 ranges that + // is equal to or less than pointer and let code point offset be + // its corresponding code point. + var offset = 0; + var code_point_offset = 0; + var idx = index('gb18030-ranges'); + var i; + for (i = 0; i < idx.length; ++i) { + /** @type {!Array.} */ + var entry = idx[i]; + if (entry[0] <= pointer) { + offset = entry[0]; + code_point_offset = entry[1]; + } else { + break; + } + } + + // 4. Return a code point whose value is code point offset + + // pointer − offset. + return code_point_offset + pointer - offset; + } + + /** + * @param {number} code_point The |code point| to locate in the gb18030 index. + * @return {number} The first pointer corresponding to |code point| in the + * gb18030 index. + */ + function indexGB18030RangesPointerFor(code_point) { + // 1. If code point is U+E7C7, return pointer 7457. + if (code_point === 0xE7C7) return 7457; + + // 2. Let offset be the last code point in index gb18030 ranges + // that is equal to or less than code point and let pointer offset + // be its corresponding pointer. + var offset = 0; + var pointer_offset = 0; + var idx = index('gb18030-ranges'); + var i; + for (i = 0; i < idx.length; ++i) { + /** @type {!Array.} */ + var entry = idx[i]; + if (entry[1] <= code_point) { + offset = entry[1]; + pointer_offset = entry[0]; + } else { + break; + } + } + + // 3. Return a pointer whose value is pointer offset + code point + // − offset. + return pointer_offset + code_point - offset; + } + + /** + * @param {number} code_point The |code_point| to search for in the Shift_JIS + * index. + * @return {?number} The code point corresponding to |pointer| in |index|, + * or null if |code point| is not in the Shift_JIS index. + */ + function indexShiftJISPointerFor(code_point) { + // 1. Let index be index jis0208 excluding all entries whose + // pointer is in the range 8272 to 8835, inclusive. + shift_jis_index = shift_jis_index || + index('jis0208').map(function(code_point, pointer) { + return inRange(pointer, 8272, 8835) ? null : code_point; + }); + var index_ = shift_jis_index; + + // 2. Return the index pointer for code point in index. + return index_.indexOf(code_point); + } + var shift_jis_index; + + /** + * @param {number} code_point The |code_point| to search for in the big5 + * index. + * @return {?number} The code point corresponding to |pointer| in |index|, + * or null if |code point| is not in the big5 index. + */ + function indexBig5PointerFor(code_point) { + // 1. Let index be index Big5 excluding all entries whose pointer + big5_index_no_hkscs = big5_index_no_hkscs || + index('big5').map(function(code_point, pointer) { + return (pointer < (0xA1 - 0x81) * 157) ? null : code_point; + }); + var index_ = big5_index_no_hkscs; + + // 2. If code point is U+2550, U+255E, U+2561, U+256A, U+5341, or + // U+5345, return the last pointer corresponding to code point in + // index. + if (code_point === 0x2550 || code_point === 0x255E || + code_point === 0x2561 || code_point === 0x256A || + code_point === 0x5341 || code_point === 0x5345) { + return index_.lastIndexOf(code_point); + } + + // 3. Return the index pointer for code point in index. + return indexPointerFor(code_point, index_); + } + var big5_index_no_hkscs; + + // + // 8. API + // + + /** @const */ var DEFAULT_ENCODING = 'utf-8'; + + // 8.1 Interface TextDecoder + + /** + * @constructor + * @param {string=} label The label of the encoding; + * defaults to 'utf-8'. + * @param {Object=} options + */ + function TextDecoder(label, options) { + // Web IDL conventions + if (!(this instanceof TextDecoder)) + throw TypeError('Called as a function. Did you forget \'new\'?'); + label = label !== undefined ? String(label) : DEFAULT_ENCODING; + options = ToDictionary(options); + + // A TextDecoder object has an associated encoding, decoder, + // stream, ignore BOM flag (initially unset), BOM seen flag + // (initially unset), error mode (initially replacement), and do + // not flush flag (initially unset). + + /** @private */ + this._encoding = null; + /** @private @type {?Decoder} */ + this._decoder = null; + /** @private @type {boolean} */ + this._ignoreBOM = false; + /** @private @type {boolean} */ + this._BOMseen = false; + /** @private @type {string} */ + this._error_mode = 'replacement'; + /** @private @type {boolean} */ + this._do_not_flush = false; + + + // 1. Let encoding be the result of getting an encoding from + // label. + var encoding = getEncoding(label); + + // 2. If encoding is failure or replacement, throw a RangeError. + if (encoding === null || encoding.name === 'replacement') + throw RangeError('Unknown encoding: ' + label); + if (!decoders[encoding.name]) { + throw Error('Decoder not present.' + + ' Did you forget to include encoding-indexes.js first?'); + } + + // 3. Let dec be a new TextDecoder object. + var dec = this; + + // 4. Set dec's encoding to encoding. + dec._encoding = encoding; + + // 5. If options's fatal member is true, set dec's error mode to + // fatal. + if (Boolean(options['fatal'])) + dec._error_mode = 'fatal'; + + // 6. If options's ignoreBOM member is true, set dec's ignore BOM + // flag. + if (Boolean(options['ignoreBOM'])) + dec._ignoreBOM = true; + + // For pre-ES5 runtimes: + if (!Object.defineProperty) { + this.encoding = dec._encoding.name.toLowerCase(); + this.fatal = dec._error_mode === 'fatal'; + this.ignoreBOM = dec._ignoreBOM; + } + + // 7. Return dec. + return dec; + } + + if (Object.defineProperty) { + // The encoding attribute's getter must return encoding's name. + Object.defineProperty(TextDecoder.prototype, 'encoding', { + /** @this {TextDecoder} */ + get: function() { return this._encoding.name.toLowerCase(); } + }); + + // The fatal attribute's getter must return true if error mode + // is fatal, and false otherwise. + Object.defineProperty(TextDecoder.prototype, 'fatal', { + /** @this {TextDecoder} */ + get: function() { return this._error_mode === 'fatal'; } + }); + + // The ignoreBOM attribute's getter must return true if ignore + // BOM flag is set, and false otherwise. + Object.defineProperty(TextDecoder.prototype, 'ignoreBOM', { + /** @this {TextDecoder} */ + get: function() { return this._ignoreBOM; } + }); + } + + /** + * @param {BufferSource=} input The buffer of bytes to decode. + * @param {Object=} options + * @return {string} The decoded string. + */ + TextDecoder.prototype.decode = function decode(input, options) { + var bytes; + if (typeof input === 'object' && input instanceof ArrayBuffer) { + bytes = new Uint8Array(input); + } else if (typeof input === 'object' && 'buffer' in input && + input.buffer instanceof ArrayBuffer) { + bytes = new Uint8Array(input.buffer, + input.byteOffset, + input.byteLength); + } else { + bytes = new Uint8Array(0); + } + + options = ToDictionary(options); + + // 1. If the do not flush flag is unset, set decoder to a new + // encoding's decoder, set stream to a new stream, and unset the + // BOM seen flag. + if (!this._do_not_flush) { + this._decoder = decoders[this._encoding.name]({ + fatal: this._error_mode === 'fatal'}); + this._BOMseen = false; + } + + // 2. If options's stream is true, set the do not flush flag, and + // unset the do not flush flag otherwise. + this._do_not_flush = Boolean(options['stream']); + + // 3. If input is given, push a copy of input to stream. + // TODO: Align with spec algorithm - maintain stream on instance. + var input_stream = new Stream(bytes); + + // 4. Let output be a new stream. + var output = []; + + /** @type {?(number|!Array.)} */ + var result; + + // 5. While true: + while (true) { + // 1. Let token be the result of reading from stream. + var token = input_stream.read(); + + // 2. If token is end-of-stream and the do not flush flag is + // set, return output, serialized. + // TODO: Align with spec algorithm. + if (token === end_of_stream) + break; + + // 3. Otherwise, run these subsubsteps: + + // 1. Let result be the result of processing token for decoder, + // stream, output, and error mode. + result = this._decoder.handler(input_stream, token); + + // 2. If result is finished, return output, serialized. + if (result === finished) + break; + + if (result !== null) { + if (Array.isArray(result)) + output.push.apply(output, /**@type {!Array.}*/(result)); + else + output.push(result); + } + + // 3. Otherwise, if result is error, throw a TypeError. + // (Thrown in handler) + + // 4. Otherwise, do nothing. + } + // TODO: Align with spec algorithm. + if (!this._do_not_flush) { + do { + result = this._decoder.handler(input_stream, input_stream.read()); + if (result === finished) + break; + if (result === null) + continue; + if (Array.isArray(result)) + output.push.apply(output, /**@type {!Array.}*/(result)); + else + output.push(result); + } while (!input_stream.endOfStream()); + this._decoder = null; + } + + // A TextDecoder object also has an associated serialize stream + // algorithm... + /** + * @param {!Array.} stream + * @return {string} + * @this {TextDecoder} + */ + function serializeStream(stream) { + // 1. Let token be the result of reading from stream. + // (Done in-place on array, rather than as a stream) + + // 2. If encoding is UTF-8, UTF-16BE, or UTF-16LE, and ignore + // BOM flag and BOM seen flag are unset, run these subsubsteps: + if (includes(['UTF-8', 'UTF-16LE', 'UTF-16BE'], this._encoding.name) && + !this._ignoreBOM && !this._BOMseen) { + if (stream.length > 0 && stream[0] === 0xFEFF) { + // 1. If token is U+FEFF, set BOM seen flag. + this._BOMseen = true; + stream.shift(); + } else if (stream.length > 0) { + // 2. Otherwise, if token is not end-of-stream, set BOM seen + // flag and append token to stream. + this._BOMseen = true; + } else { + // 3. Otherwise, if token is not end-of-stream, append token + // to output. + // (no-op) + } + } + // 4. Otherwise, return output. + return codePointsToString(stream); + } + + return serializeStream.call(this, output); + }; + + // 8.2 Interface TextEncoder + + /** + * @constructor + * @param {string=} label The label of the encoding. NONSTANDARD. + * @param {Object=} options NONSTANDARD. + */ + function TextEncoder(label, options) { + // Web IDL conventions + if (!(this instanceof TextEncoder)) + throw TypeError('Called as a function. Did you forget \'new\'?'); + options = ToDictionary(options); + + // A TextEncoder object has an associated encoding and encoder. + + /** @private */ + this._encoding = null; + /** @private @type {?Encoder} */ + this._encoder = null; + + // Non-standard + /** @private @type {boolean} */ + this._do_not_flush = false; + /** @private @type {string} */ + this._fatal = Boolean(options['fatal']) ? 'fatal' : 'replacement'; + + // 1. Let enc be a new TextEncoder object. + var enc = this; + + // 2. Set enc's encoding to UTF-8's encoder. + if (Boolean(options['NONSTANDARD_allowLegacyEncoding'])) { + // NONSTANDARD behavior. + label = label !== undefined ? String(label) : DEFAULT_ENCODING; + var encoding = getEncoding(label); + if (encoding === null || encoding.name === 'replacement') + throw RangeError('Unknown encoding: ' + label); + if (!encoders[encoding.name]) { + throw Error('Encoder not present.' + + ' Did you forget to include encoding-indexes.js first?'); + } + enc._encoding = encoding; + } else { + // Standard behavior. + enc._encoding = getEncoding('utf-8'); + + if (label !== undefined && 'console' in global) { + console.warn('TextEncoder constructor called with encoding label, ' + + 'which is ignored.'); + } + } + + // For pre-ES5 runtimes: + if (!Object.defineProperty) + this.encoding = enc._encoding.name.toLowerCase(); + + // 3. Return enc. + return enc; + } + + if (Object.defineProperty) { + // The encoding attribute's getter must return encoding's name. + Object.defineProperty(TextEncoder.prototype, 'encoding', { + /** @this {TextEncoder} */ + get: function() { return this._encoding.name.toLowerCase(); } + }); + } + + /** + * @param {string=} opt_string The string to encode. + * @param {Object=} options + * @return {!Uint8Array} Encoded bytes, as a Uint8Array. + */ + TextEncoder.prototype.encode = function encode(opt_string, options) { + opt_string = opt_string === undefined ? '' : String(opt_string); + options = ToDictionary(options); + + // NOTE: This option is nonstandard. None of the encodings + // permitted for encoding (i.e. UTF-8, UTF-16) are stateful when + // the input is a USVString so streaming is not necessary. + if (!this._do_not_flush) + this._encoder = encoders[this._encoding.name]({ + fatal: this._fatal === 'fatal'}); + this._do_not_flush = Boolean(options['stream']); + + // 1. Convert input to a stream. + var input = new Stream(stringToCodePoints(opt_string)); + + // 2. Let output be a new stream + var output = []; + + /** @type {?(number|!Array.)} */ + var result; + // 3. While true, run these substeps: + while (true) { + // 1. Let token be the result of reading from input. + var token = input.read(); + if (token === end_of_stream) + break; + // 2. Let result be the result of processing token for encoder, + // input, output. + result = this._encoder.handler(input, token); + if (result === finished) + break; + if (Array.isArray(result)) + output.push.apply(output, /**@type {!Array.}*/(result)); + else + output.push(result); + } + // TODO: Align with spec algorithm. + if (!this._do_not_flush) { + while (true) { + result = this._encoder.handler(input, input.read()); + if (result === finished) + break; + if (Array.isArray(result)) + output.push.apply(output, /**@type {!Array.}*/(result)); + else + output.push(result); + } + this._encoder = null; + } + // 3. If result is finished, convert output into a byte sequence, + // and then return a Uint8Array object wrapping an ArrayBuffer + // containing output. + return new Uint8Array(output); + }; + + + // + // 9. The encoding + // + + // 9.1 utf-8 + + // 9.1.1 utf-8 decoder + /** + * @constructor + * @implements {Decoder} + * @param {{fatal: boolean}} options + */ + function UTF8Decoder(options) { + var fatal = options.fatal; + + // utf-8's decoder's has an associated utf-8 code point, utf-8 + // bytes seen, and utf-8 bytes needed (all initially 0), a utf-8 + // lower boundary (initially 0x80), and a utf-8 upper boundary + // (initially 0xBF). + var /** @type {number} */ utf8_code_point = 0, + /** @type {number} */ utf8_bytes_seen = 0, + /** @type {number} */ utf8_bytes_needed = 0, + /** @type {number} */ utf8_lower_boundary = 0x80, + /** @type {number} */ utf8_upper_boundary = 0xBF; + + /** + * @param {Stream} stream The stream of bytes being decoded. + * @param {number} bite The next byte read from the stream. + * @return {?(number|!Array.)} The next code point(s) + * decoded, or null if not enough data exists in the input + * stream to decode a complete code point. + */ + this.handler = function(stream, bite) { + // 1. If byte is end-of-stream and utf-8 bytes needed is not 0, + // set utf-8 bytes needed to 0 and return error. + if (bite === end_of_stream && utf8_bytes_needed !== 0) { + utf8_bytes_needed = 0; + return decoderError(fatal); + } + + // 2. If byte is end-of-stream, return finished. + if (bite === end_of_stream) + return finished; + + // 3. If utf-8 bytes needed is 0, based on byte: + if (utf8_bytes_needed === 0) { + + // 0x00 to 0x7F + if (inRange(bite, 0x00, 0x7F)) { + // Return a code point whose value is byte. + return bite; + } + + // 0xC2 to 0xDF + else if (inRange(bite, 0xC2, 0xDF)) { + // 1. Set utf-8 bytes needed to 1. + utf8_bytes_needed = 1; + + // 2. Set UTF-8 code point to byte & 0x1F. + utf8_code_point = bite & 0x1F; + } + + // 0xE0 to 0xEF + else if (inRange(bite, 0xE0, 0xEF)) { + // 1. If byte is 0xE0, set utf-8 lower boundary to 0xA0. + if (bite === 0xE0) + utf8_lower_boundary = 0xA0; + // 2. If byte is 0xED, set utf-8 upper boundary to 0x9F. + if (bite === 0xED) + utf8_upper_boundary = 0x9F; + // 3. Set utf-8 bytes needed to 2. + utf8_bytes_needed = 2; + // 4. Set UTF-8 code point to byte & 0xF. + utf8_code_point = bite & 0xF; + } + + // 0xF0 to 0xF4 + else if (inRange(bite, 0xF0, 0xF4)) { + // 1. If byte is 0xF0, set utf-8 lower boundary to 0x90. + if (bite === 0xF0) + utf8_lower_boundary = 0x90; + // 2. If byte is 0xF4, set utf-8 upper boundary to 0x8F. + if (bite === 0xF4) + utf8_upper_boundary = 0x8F; + // 3. Set utf-8 bytes needed to 3. + utf8_bytes_needed = 3; + // 4. Set UTF-8 code point to byte & 0x7. + utf8_code_point = bite & 0x7; + } + + // Otherwise + else { + // Return error. + return decoderError(fatal); + } + + // Return continue. + return null; + } + + // 4. If byte is not in the range utf-8 lower boundary to utf-8 + // upper boundary, inclusive, run these substeps: + if (!inRange(bite, utf8_lower_boundary, utf8_upper_boundary)) { + + // 1. Set utf-8 code point, utf-8 bytes needed, and utf-8 + // bytes seen to 0, set utf-8 lower boundary to 0x80, and set + // utf-8 upper boundary to 0xBF. + utf8_code_point = utf8_bytes_needed = utf8_bytes_seen = 0; + utf8_lower_boundary = 0x80; + utf8_upper_boundary = 0xBF; + + // 2. Prepend byte to stream. + stream.prepend(bite); + + // 3. Return error. + return decoderError(fatal); + } + + // 5. Set utf-8 lower boundary to 0x80 and utf-8 upper boundary + // to 0xBF. + utf8_lower_boundary = 0x80; + utf8_upper_boundary = 0xBF; + + // 6. Set UTF-8 code point to (UTF-8 code point << 6) | (byte & + // 0x3F) + utf8_code_point = (utf8_code_point << 6) | (bite & 0x3F); + + // 7. Increase utf-8 bytes seen by one. + utf8_bytes_seen += 1; + + // 8. If utf-8 bytes seen is not equal to utf-8 bytes needed, + // continue. + if (utf8_bytes_seen !== utf8_bytes_needed) + return null; + + // 9. Let code point be utf-8 code point. + var code_point = utf8_code_point; + + // 10. Set utf-8 code point, utf-8 bytes needed, and utf-8 bytes + // seen to 0. + utf8_code_point = utf8_bytes_needed = utf8_bytes_seen = 0; + + // 11. Return a code point whose value is code point. + return code_point; + }; + } + + // 9.1.2 utf-8 encoder + /** + * @constructor + * @implements {Encoder} + * @param {{fatal: boolean}} options + */ + function UTF8Encoder(options) { + var fatal = options.fatal; + /** + * @param {Stream} stream Input stream. + * @param {number} code_point Next code point read from the stream. + * @return {(number|!Array.)} Byte(s) to emit. + */ + this.handler = function(stream, code_point) { + // 1. If code point is end-of-stream, return finished. + if (code_point === end_of_stream) + return finished; + + // 2. If code point is an ASCII code point, return a byte whose + // value is code point. + if (isASCIICodePoint(code_point)) + return code_point; + + // 3. Set count and offset based on the range code point is in: + var count, offset; + // U+0080 to U+07FF, inclusive: + if (inRange(code_point, 0x0080, 0x07FF)) { + // 1 and 0xC0 + count = 1; + offset = 0xC0; + } + // U+0800 to U+FFFF, inclusive: + else if (inRange(code_point, 0x0800, 0xFFFF)) { + // 2 and 0xE0 + count = 2; + offset = 0xE0; + } + // U+10000 to U+10FFFF, inclusive: + else if (inRange(code_point, 0x10000, 0x10FFFF)) { + // 3 and 0xF0 + count = 3; + offset = 0xF0; + } + + // 4. Let bytes be a byte sequence whose first byte is (code + // point >> (6 × count)) + offset. + var bytes = [(code_point >> (6 * count)) + offset]; + + // 5. Run these substeps while count is greater than 0: + while (count > 0) { + + // 1. Set temp to code point >> (6 × (count − 1)). + var temp = code_point >> (6 * (count - 1)); + + // 2. Append to bytes 0x80 | (temp & 0x3F). + bytes.push(0x80 | (temp & 0x3F)); + + // 3. Decrease count by one. + count -= 1; + } + + // 6. Return bytes bytes, in order. + return bytes; + }; + } + + /** @param {{fatal: boolean}} options */ + encoders['UTF-8'] = function(options) { + return new UTF8Encoder(options); + }; + /** @param {{fatal: boolean}} options */ + decoders['UTF-8'] = function(options) { + return new UTF8Decoder(options); + }; + + // + // 10. Legacy single-byte encodings + // + + // 10.1 single-byte decoder + /** + * @constructor + * @implements {Decoder} + * @param {!Array.} index The encoding index. + * @param {{fatal: boolean}} options + */ + function SingleByteDecoder(index, options) { + var fatal = options.fatal; + /** + * @param {Stream} stream The stream of bytes being decoded. + * @param {number} bite The next byte read from the stream. + * @return {?(number|!Array.)} The next code point(s) + * decoded, or null if not enough data exists in the input + * stream to decode a complete code point. + */ + this.handler = function(stream, bite) { + // 1. If byte is end-of-stream, return finished. + if (bite === end_of_stream) + return finished; + + // 2. If byte is an ASCII byte, return a code point whose value + // is byte. + if (isASCIIByte(bite)) + return bite; + + // 3. Let code point be the index code point for byte − 0x80 in + // index single-byte. + var code_point = index[bite - 0x80]; + + // 4. If code point is null, return error. + if (code_point === null) + return decoderError(fatal); + + // 5. Return a code point whose value is code point. + return code_point; + }; + } + + // 10.2 single-byte encoder + /** + * @constructor + * @implements {Encoder} + * @param {!Array.} index The encoding index. + * @param {{fatal: boolean}} options + */ + function SingleByteEncoder(index, options) { + var fatal = options.fatal; + /** + * @param {Stream} stream Input stream. + * @param {number} code_point Next code point read from the stream. + * @return {(number|!Array.)} Byte(s) to emit. + */ + this.handler = function(stream, code_point) { + // 1. If code point is end-of-stream, return finished. + if (code_point === end_of_stream) + return finished; + + // 2. If code point is an ASCII code point, return a byte whose + // value is code point. + if (isASCIICodePoint(code_point)) + return code_point; + + // 3. Let pointer be the index pointer for code point in index + // single-byte. + var pointer = indexPointerFor(code_point, index); + + // 4. If pointer is null, return error with code point. + if (pointer === null) + encoderError(code_point); + + // 5. Return a byte whose value is pointer + 0x80. + return pointer + 0x80; + }; + } + + (function() { + if (!('encoding-indexes' in global)) + return; + encodings.forEach(function(category) { + if (category.heading !== 'Legacy single-byte encodings') + return; + category.encodings.forEach(function(encoding) { + var name = encoding.name; + var idx = index(name.toLowerCase()); + /** @param {{fatal: boolean}} options */ + decoders[name] = function(options) { + return new SingleByteDecoder(idx, options); + }; + /** @param {{fatal: boolean}} options */ + encoders[name] = function(options) { + return new SingleByteEncoder(idx, options); + }; + }); + }); + }()); + + // + // 11. Legacy multi-byte Chinese (simplified) encodings + // + + // 11.1 gbk + + // 11.1.1 gbk decoder + // gbk's decoder is gb18030's decoder. + /** @param {{fatal: boolean}} options */ + decoders['GBK'] = function(options) { + return new GB18030Decoder(options); + }; + + // 11.1.2 gbk encoder + // gbk's encoder is gb18030's encoder with its gbk flag set. + /** @param {{fatal: boolean}} options */ + encoders['GBK'] = function(options) { + return new GB18030Encoder(options, true); + }; + + // 11.2 gb18030 + + // 11.2.1 gb18030 decoder + /** + * @constructor + * @implements {Decoder} + * @param {{fatal: boolean}} options + */ + function GB18030Decoder(options) { + var fatal = options.fatal; + // gb18030's decoder has an associated gb18030 first, gb18030 + // second, and gb18030 third (all initially 0x00). + var /** @type {number} */ gb18030_first = 0x00, + /** @type {number} */ gb18030_second = 0x00, + /** @type {number} */ gb18030_third = 0x00; + /** + * @param {Stream} stream The stream of bytes being decoded. + * @param {number} bite The next byte read from the stream. + * @return {?(number|!Array.)} The next code point(s) + * decoded, or null if not enough data exists in the input + * stream to decode a complete code point. + */ + this.handler = function(stream, bite) { + // 1. If byte is end-of-stream and gb18030 first, gb18030 + // second, and gb18030 third are 0x00, return finished. + if (bite === end_of_stream && gb18030_first === 0x00 && + gb18030_second === 0x00 && gb18030_third === 0x00) { + return finished; + } + // 2. If byte is end-of-stream, and gb18030 first, gb18030 + // second, or gb18030 third is not 0x00, set gb18030 first, + // gb18030 second, and gb18030 third to 0x00, and return error. + if (bite === end_of_stream && + (gb18030_first !== 0x00 || gb18030_second !== 0x00 || + gb18030_third !== 0x00)) { + gb18030_first = 0x00; + gb18030_second = 0x00; + gb18030_third = 0x00; + decoderError(fatal); + } + var code_point; + // 3. If gb18030 third is not 0x00, run these substeps: + if (gb18030_third !== 0x00) { + // 1. Let code point be null. + code_point = null; + // 2. If byte is in the range 0x30 to 0x39, inclusive, set + // code point to the index gb18030 ranges code point for + // (((gb18030 first − 0x81) × 10 + gb18030 second − 0x30) × + // 126 + gb18030 third − 0x81) × 10 + byte − 0x30. + if (inRange(bite, 0x30, 0x39)) { + code_point = indexGB18030RangesCodePointFor( + (((gb18030_first - 0x81) * 10 + gb18030_second - 0x30) * 126 + + gb18030_third - 0x81) * 10 + bite - 0x30); + } + + // 3. Let buffer be a byte sequence consisting of gb18030 + // second, gb18030 third, and byte, in order. + var buffer = [gb18030_second, gb18030_third, bite]; + + // 4. Set gb18030 first, gb18030 second, and gb18030 third to + // 0x00. + gb18030_first = 0x00; + gb18030_second = 0x00; + gb18030_third = 0x00; + + // 5. If code point is null, prepend buffer to stream and + // return error. + if (code_point === null) { + stream.prepend(buffer); + return decoderError(fatal); + } + + // 6. Return a code point whose value is code point. + return code_point; + } + + // 4. If gb18030 second is not 0x00, run these substeps: + if (gb18030_second !== 0x00) { + + // 1. If byte is in the range 0x81 to 0xFE, inclusive, set + // gb18030 third to byte and return continue. + if (inRange(bite, 0x81, 0xFE)) { + gb18030_third = bite; + return null; + } + + // 2. Prepend gb18030 second followed by byte to stream, set + // gb18030 first and gb18030 second to 0x00, and return error. + stream.prepend([gb18030_second, bite]); + gb18030_first = 0x00; + gb18030_second = 0x00; + return decoderError(fatal); + } + + // 5. If gb18030 first is not 0x00, run these substeps: + if (gb18030_first !== 0x00) { + + // 1. If byte is in the range 0x30 to 0x39, inclusive, set + // gb18030 second to byte and return continue. + if (inRange(bite, 0x30, 0x39)) { + gb18030_second = bite; + return null; + } + + // 2. Let lead be gb18030 first, let pointer be null, and set + // gb18030 first to 0x00. + var lead = gb18030_first; + var pointer = null; + gb18030_first = 0x00; + + // 3. Let offset be 0x40 if byte is less than 0x7F and 0x41 + // otherwise. + var offset = bite < 0x7F ? 0x40 : 0x41; + + // 4. If byte is in the range 0x40 to 0x7E, inclusive, or 0x80 + // to 0xFE, inclusive, set pointer to (lead − 0x81) × 190 + + // (byte − offset). + if (inRange(bite, 0x40, 0x7E) || inRange(bite, 0x80, 0xFE)) + pointer = (lead - 0x81) * 190 + (bite - offset); + + // 5. Let code point be null if pointer is null and the index + // code point for pointer in index gb18030 otherwise. + code_point = pointer === null ? null : + indexCodePointFor(pointer, index('gb18030')); + + // 6. If code point is null and byte is an ASCII byte, prepend + // byte to stream. + if (code_point === null && isASCIIByte(bite)) + stream.prepend(bite); + + // 7. If code point is null, return error. + if (code_point === null) + return decoderError(fatal); + + // 8. Return a code point whose value is code point. + return code_point; + } + + // 6. If byte is an ASCII byte, return a code point whose value + // is byte. + if (isASCIIByte(bite)) + return bite; + + // 7. If byte is 0x80, return code point U+20AC. + if (bite === 0x80) + return 0x20AC; + + // 8. If byte is in the range 0x81 to 0xFE, inclusive, set + // gb18030 first to byte and return continue. + if (inRange(bite, 0x81, 0xFE)) { + gb18030_first = bite; + return null; + } + + // 9. Return error. + return decoderError(fatal); + }; + } + + // 11.2.2 gb18030 encoder + /** + * @constructor + * @implements {Encoder} + * @param {{fatal: boolean}} options + * @param {boolean=} gbk_flag + */ + function GB18030Encoder(options, gbk_flag) { + var fatal = options.fatal; + // gb18030's decoder has an associated gbk flag (initially unset). + /** + * @param {Stream} stream Input stream. + * @param {number} code_point Next code point read from the stream. + * @return {(number|!Array.)} Byte(s) to emit. + */ + this.handler = function(stream, code_point) { + // 1. If code point is end-of-stream, return finished. + if (code_point === end_of_stream) + return finished; + + // 2. If code point is an ASCII code point, return a byte whose + // value is code point. + if (isASCIICodePoint(code_point)) + return code_point; + + // 3. If code point is U+E5E5, return error with code point. + if (code_point === 0xE5E5) + return encoderError(code_point); + + // 4. If the gbk flag is set and code point is U+20AC, return + // byte 0x80. + if (gbk_flag && code_point === 0x20AC) + return 0x80; + + // 5. Let pointer be the index pointer for code point in index + // gb18030. + var pointer = indexPointerFor(code_point, index('gb18030')); + + // 6. If pointer is not null, run these substeps: + if (pointer !== null) { + + // 1. Let lead be floor(pointer / 190) + 0x81. + var lead = floor(pointer / 190) + 0x81; + + // 2. Let trail be pointer % 190. + var trail = pointer % 190; + + // 3. Let offset be 0x40 if trail is less than 0x3F and 0x41 otherwise. + var offset = trail < 0x3F ? 0x40 : 0x41; + + // 4. Return two bytes whose values are lead and trail + offset. + return [lead, trail + offset]; + } + + // 7. If gbk flag is set, return error with code point. + if (gbk_flag) + return encoderError(code_point); + + // 8. Set pointer to the index gb18030 ranges pointer for code + // point. + pointer = indexGB18030RangesPointerFor(code_point); + + // 9. Let byte1 be floor(pointer / 10 / 126 / 10). + var byte1 = floor(pointer / 10 / 126 / 10); + + // 10. Set pointer to pointer − byte1 × 10 × 126 × 10. + pointer = pointer - byte1 * 10 * 126 * 10; + + // 11. Let byte2 be floor(pointer / 10 / 126). + var byte2 = floor(pointer / 10 / 126); + + // 12. Set pointer to pointer − byte2 × 10 × 126. + pointer = pointer - byte2 * 10 * 126; + + // 13. Let byte3 be floor(pointer / 10). + var byte3 = floor(pointer / 10); + + // 14. Let byte4 be pointer − byte3 × 10. + var byte4 = pointer - byte3 * 10; + + // 15. Return four bytes whose values are byte1 + 0x81, byte2 + + // 0x30, byte3 + 0x81, byte4 + 0x30. + return [byte1 + 0x81, + byte2 + 0x30, + byte3 + 0x81, + byte4 + 0x30]; + }; + } + + /** @param {{fatal: boolean}} options */ + encoders['gb18030'] = function(options) { + return new GB18030Encoder(options); + }; + /** @param {{fatal: boolean}} options */ + decoders['gb18030'] = function(options) { + return new GB18030Decoder(options); + }; + + + // + // 12. Legacy multi-byte Chinese (traditional) encodings + // + + // 12.1 Big5 + + // 12.1.1 Big5 decoder + /** + * @constructor + * @implements {Decoder} + * @param {{fatal: boolean}} options + */ + function Big5Decoder(options) { + var fatal = options.fatal; + // Big5's decoder has an associated Big5 lead (initially 0x00). + var /** @type {number} */ Big5_lead = 0x00; + + /** + * @param {Stream} stream The stream of bytes being decoded. + * @param {number} bite The next byte read from the stream. + * @return {?(number|!Array.)} The next code point(s) + * decoded, or null if not enough data exists in the input + * stream to decode a complete code point. + */ + this.handler = function(stream, bite) { + // 1. If byte is end-of-stream and Big5 lead is not 0x00, set + // Big5 lead to 0x00 and return error. + if (bite === end_of_stream && Big5_lead !== 0x00) { + Big5_lead = 0x00; + return decoderError(fatal); + } + + // 2. If byte is end-of-stream and Big5 lead is 0x00, return + // finished. + if (bite === end_of_stream && Big5_lead === 0x00) + return finished; + + // 3. If Big5 lead is not 0x00, let lead be Big5 lead, let + // pointer be null, set Big5 lead to 0x00, and then run these + // substeps: + if (Big5_lead !== 0x00) { + var lead = Big5_lead; + var pointer = null; + Big5_lead = 0x00; + + // 1. Let offset be 0x40 if byte is less than 0x7F and 0x62 + // otherwise. + var offset = bite < 0x7F ? 0x40 : 0x62; + + // 2. If byte is in the range 0x40 to 0x7E, inclusive, or 0xA1 + // to 0xFE, inclusive, set pointer to (lead − 0x81) × 157 + + // (byte − offset). + if (inRange(bite, 0x40, 0x7E) || inRange(bite, 0xA1, 0xFE)) + pointer = (lead - 0x81) * 157 + (bite - offset); + + // 3. If there is a row in the table below whose first column + // is pointer, return the two code points listed in its second + // column + // Pointer | Code points + // --------+-------------- + // 1133 | U+00CA U+0304 + // 1135 | U+00CA U+030C + // 1164 | U+00EA U+0304 + // 1166 | U+00EA U+030C + switch (pointer) { + case 1133: return [0x00CA, 0x0304]; + case 1135: return [0x00CA, 0x030C]; + case 1164: return [0x00EA, 0x0304]; + case 1166: return [0x00EA, 0x030C]; + } + + // 4. Let code point be null if pointer is null and the index + // code point for pointer in index Big5 otherwise. + var code_point = (pointer === null) ? null : + indexCodePointFor(pointer, index('big5')); + + // 5. If code point is null and byte is an ASCII byte, prepend + // byte to stream. + if (code_point === null && isASCIIByte(bite)) + stream.prepend(bite); + + // 6. If code point is null, return error. + if (code_point === null) + return decoderError(fatal); + + // 7. Return a code point whose value is code point. + return code_point; + } + + // 4. If byte is an ASCII byte, return a code point whose value + // is byte. + if (isASCIIByte(bite)) + return bite; + + // 5. If byte is in the range 0x81 to 0xFE, inclusive, set Big5 + // lead to byte and return continue. + if (inRange(bite, 0x81, 0xFE)) { + Big5_lead = bite; + return null; + } + + // 6. Return error. + return decoderError(fatal); + }; + } + + // 12.1.2 Big5 encoder + /** + * @constructor + * @implements {Encoder} + * @param {{fatal: boolean}} options + */ + function Big5Encoder(options) { + var fatal = options.fatal; + /** + * @param {Stream} stream Input stream. + * @param {number} code_point Next code point read from the stream. + * @return {(number|!Array.)} Byte(s) to emit. + */ + this.handler = function(stream, code_point) { + // 1. If code point is end-of-stream, return finished. + if (code_point === end_of_stream) + return finished; + + // 2. If code point is an ASCII code point, return a byte whose + // value is code point. + if (isASCIICodePoint(code_point)) + return code_point; + + // 3. Let pointer be the index Big5 pointer for code point. + var pointer = indexBig5PointerFor(code_point); + + // 4. If pointer is null, return error with code point. + if (pointer === null) + return encoderError(code_point); + + // 5. Let lead be floor(pointer / 157) + 0x81. + var lead = floor(pointer / 157) + 0x81; + + // 6. If lead is less than 0xA1, return error with code point. + if (lead < 0xA1) + return encoderError(code_point); + + // 7. Let trail be pointer % 157. + var trail = pointer % 157; + + // 8. Let offset be 0x40 if trail is less than 0x3F and 0x62 + // otherwise. + var offset = trail < 0x3F ? 0x40 : 0x62; + + // Return two bytes whose values are lead and trail + offset. + return [lead, trail + offset]; + }; + } + + /** @param {{fatal: boolean}} options */ + encoders['Big5'] = function(options) { + return new Big5Encoder(options); + }; + /** @param {{fatal: boolean}} options */ + decoders['Big5'] = function(options) { + return new Big5Decoder(options); + }; + + + // + // 13. Legacy multi-byte Japanese encodings + // + + // 13.1 euc-jp + + // 13.1.1 euc-jp decoder + /** + * @constructor + * @implements {Decoder} + * @param {{fatal: boolean}} options + */ + function EUCJPDecoder(options) { + var fatal = options.fatal; + + // euc-jp's decoder has an associated euc-jp jis0212 flag + // (initially unset) and euc-jp lead (initially 0x00). + var /** @type {boolean} */ eucjp_jis0212_flag = false, + /** @type {number} */ eucjp_lead = 0x00; + + /** + * @param {Stream} stream The stream of bytes being decoded. + * @param {number} bite The next byte read from the stream. + * @return {?(number|!Array.)} The next code point(s) + * decoded, or null if not enough data exists in the input + * stream to decode a complete code point. + */ + this.handler = function(stream, bite) { + // 1. If byte is end-of-stream and euc-jp lead is not 0x00, set + // euc-jp lead to 0x00, and return error. + if (bite === end_of_stream && eucjp_lead !== 0x00) { + eucjp_lead = 0x00; + return decoderError(fatal); + } + + // 2. If byte is end-of-stream and euc-jp lead is 0x00, return + // finished. + if (bite === end_of_stream && eucjp_lead === 0x00) + return finished; + + // 3. If euc-jp lead is 0x8E and byte is in the range 0xA1 to + // 0xDF, inclusive, set euc-jp lead to 0x00 and return a code + // point whose value is 0xFF61 − 0xA1 + byte. + if (eucjp_lead === 0x8E && inRange(bite, 0xA1, 0xDF)) { + eucjp_lead = 0x00; + return 0xFF61 - 0xA1 + bite; + } + + // 4. If euc-jp lead is 0x8F and byte is in the range 0xA1 to + // 0xFE, inclusive, set the euc-jp jis0212 flag, set euc-jp lead + // to byte, and return continue. + if (eucjp_lead === 0x8F && inRange(bite, 0xA1, 0xFE)) { + eucjp_jis0212_flag = true; + eucjp_lead = bite; + return null; + } + + // 5. If euc-jp lead is not 0x00, let lead be euc-jp lead, set + // euc-jp lead to 0x00, and run these substeps: + if (eucjp_lead !== 0x00) { + var lead = eucjp_lead; + eucjp_lead = 0x00; + + // 1. Let code point be null. + var code_point = null; + + // 2. If lead and byte are both in the range 0xA1 to 0xFE, + // inclusive, set code point to the index code point for (lead + // − 0xA1) × 94 + byte − 0xA1 in index jis0208 if the euc-jp + // jis0212 flag is unset and in index jis0212 otherwise. + if (inRange(lead, 0xA1, 0xFE) && inRange(bite, 0xA1, 0xFE)) { + code_point = indexCodePointFor( + (lead - 0xA1) * 94 + (bite - 0xA1), + index(!eucjp_jis0212_flag ? 'jis0208' : 'jis0212')); + } + + // 3. Unset the euc-jp jis0212 flag. + eucjp_jis0212_flag = false; + + // 4. If byte is not in the range 0xA1 to 0xFE, inclusive, + // prepend byte to stream. + if (!inRange(bite, 0xA1, 0xFE)) + stream.prepend(bite); + + // 5. If code point is null, return error. + if (code_point === null) + return decoderError(fatal); + + // 6. Return a code point whose value is code point. + return code_point; + } + + // 6. If byte is an ASCII byte, return a code point whose value + // is byte. + if (isASCIIByte(bite)) + return bite; + + // 7. If byte is 0x8E, 0x8F, or in the range 0xA1 to 0xFE, + // inclusive, set euc-jp lead to byte and return continue. + if (bite === 0x8E || bite === 0x8F || inRange(bite, 0xA1, 0xFE)) { + eucjp_lead = bite; + return null; + } + + // 8. Return error. + return decoderError(fatal); + }; + } + + // 13.1.2 euc-jp encoder + /** + * @constructor + * @implements {Encoder} + * @param {{fatal: boolean}} options + */ + function EUCJPEncoder(options) { + var fatal = options.fatal; + /** + * @param {Stream} stream Input stream. + * @param {number} code_point Next code point read from the stream. + * @return {(number|!Array.)} Byte(s) to emit. + */ + this.handler = function(stream, code_point) { + // 1. If code point is end-of-stream, return finished. + if (code_point === end_of_stream) + return finished; + + // 2. If code point is an ASCII code point, return a byte whose + // value is code point. + if (isASCIICodePoint(code_point)) + return code_point; + + // 3. If code point is U+00A5, return byte 0x5C. + if (code_point === 0x00A5) + return 0x5C; + + // 4. If code point is U+203E, return byte 0x7E. + if (code_point === 0x203E) + return 0x7E; + + // 5. If code point is in the range U+FF61 to U+FF9F, inclusive, + // return two bytes whose values are 0x8E and code point − + // 0xFF61 + 0xA1. + if (inRange(code_point, 0xFF61, 0xFF9F)) + return [0x8E, code_point - 0xFF61 + 0xA1]; + + // 6. If code point is U+2212, set it to U+FF0D. + if (code_point === 0x2212) + code_point = 0xFF0D; + + // 7. Let pointer be the index pointer for code point in index + // jis0208. + var pointer = indexPointerFor(code_point, index('jis0208')); + + // 8. If pointer is null, return error with code point. + if (pointer === null) + return encoderError(code_point); + + // 9. Let lead be floor(pointer / 94) + 0xA1. + var lead = floor(pointer / 94) + 0xA1; + + // 10. Let trail be pointer % 94 + 0xA1. + var trail = pointer % 94 + 0xA1; + + // 11. Return two bytes whose values are lead and trail. + return [lead, trail]; + }; + } + + /** @param {{fatal: boolean}} options */ + encoders['EUC-JP'] = function(options) { + return new EUCJPEncoder(options); + }; + /** @param {{fatal: boolean}} options */ + decoders['EUC-JP'] = function(options) { + return new EUCJPDecoder(options); + }; + + // 13.2 iso-2022-jp + + // 13.2.1 iso-2022-jp decoder + /** + * @constructor + * @implements {Decoder} + * @param {{fatal: boolean}} options + */ + function ISO2022JPDecoder(options) { + var fatal = options.fatal; + /** @enum */ + var states = { + ASCII: 0, + Roman: 1, + Katakana: 2, + LeadByte: 3, + TrailByte: 4, + EscapeStart: 5, + Escape: 6 + }; + // iso-2022-jp's decoder has an associated iso-2022-jp decoder + // state (initially ASCII), iso-2022-jp decoder output state + // (initially ASCII), iso-2022-jp lead (initially 0x00), and + // iso-2022-jp output flag (initially unset). + var /** @type {number} */ iso2022jp_decoder_state = states.ASCII, + /** @type {number} */ iso2022jp_decoder_output_state = states.ASCII, + /** @type {number} */ iso2022jp_lead = 0x00, + /** @type {boolean} */ iso2022jp_output_flag = false; + /** + * @param {Stream} stream The stream of bytes being decoded. + * @param {number} bite The next byte read from the stream. + * @return {?(number|!Array.)} The next code point(s) + * decoded, or null if not enough data exists in the input + * stream to decode a complete code point. + */ + this.handler = function(stream, bite) { + // switching on iso-2022-jp decoder state: + switch (iso2022jp_decoder_state) { + default: + case states.ASCII: + // ASCII + // Based on byte: + + // 0x1B + if (bite === 0x1B) { + // Set iso-2022-jp decoder state to escape start and return + // continue. + iso2022jp_decoder_state = states.EscapeStart; + return null; + } + + // 0x00 to 0x7F, excluding 0x0E, 0x0F, and 0x1B + if (inRange(bite, 0x00, 0x7F) && bite !== 0x0E + && bite !== 0x0F && bite !== 0x1B) { + // Unset the iso-2022-jp output flag and return a code point + // whose value is byte. + iso2022jp_output_flag = false; + return bite; + } + + // end-of-stream + if (bite === end_of_stream) { + // Return finished. + return finished; + } + + // Otherwise + // Unset the iso-2022-jp output flag and return error. + iso2022jp_output_flag = false; + return decoderError(fatal); + + case states.Roman: + // Roman + // Based on byte: + + // 0x1B + if (bite === 0x1B) { + // Set iso-2022-jp decoder state to escape start and return + // continue. + iso2022jp_decoder_state = states.EscapeStart; + return null; + } + + // 0x5C + if (bite === 0x5C) { + // Unset the iso-2022-jp output flag and return code point + // U+00A5. + iso2022jp_output_flag = false; + return 0x00A5; + } + + // 0x7E + if (bite === 0x7E) { + // Unset the iso-2022-jp output flag and return code point + // U+203E. + iso2022jp_output_flag = false; + return 0x203E; + } + + // 0x00 to 0x7F, excluding 0x0E, 0x0F, 0x1B, 0x5C, and 0x7E + if (inRange(bite, 0x00, 0x7F) && bite !== 0x0E && bite !== 0x0F + && bite !== 0x1B && bite !== 0x5C && bite !== 0x7E) { + // Unset the iso-2022-jp output flag and return a code point + // whose value is byte. + iso2022jp_output_flag = false; + return bite; + } + + // end-of-stream + if (bite === end_of_stream) { + // Return finished. + return finished; + } + + // Otherwise + // Unset the iso-2022-jp output flag and return error. + iso2022jp_output_flag = false; + return decoderError(fatal); + + case states.Katakana: + // Katakana + // Based on byte: + + // 0x1B + if (bite === 0x1B) { + // Set iso-2022-jp decoder state to escape start and return + // continue. + iso2022jp_decoder_state = states.EscapeStart; + return null; + } + + // 0x21 to 0x5F + if (inRange(bite, 0x21, 0x5F)) { + // Unset the iso-2022-jp output flag and return a code point + // whose value is 0xFF61 − 0x21 + byte. + iso2022jp_output_flag = false; + return 0xFF61 - 0x21 + bite; + } + + // end-of-stream + if (bite === end_of_stream) { + // Return finished. + return finished; + } + + // Otherwise + // Unset the iso-2022-jp output flag and return error. + iso2022jp_output_flag = false; + return decoderError(fatal); + + case states.LeadByte: + // Lead byte + // Based on byte: + + // 0x1B + if (bite === 0x1B) { + // Set iso-2022-jp decoder state to escape start and return + // continue. + iso2022jp_decoder_state = states.EscapeStart; + return null; + } + + // 0x21 to 0x7E + if (inRange(bite, 0x21, 0x7E)) { + // Unset the iso-2022-jp output flag, set iso-2022-jp lead + // to byte, iso-2022-jp decoder state to trail byte, and + // return continue. + iso2022jp_output_flag = false; + iso2022jp_lead = bite; + iso2022jp_decoder_state = states.TrailByte; + return null; + } + + // end-of-stream + if (bite === end_of_stream) { + // Return finished. + return finished; + } + + // Otherwise + // Unset the iso-2022-jp output flag and return error. + iso2022jp_output_flag = false; + return decoderError(fatal); + + case states.TrailByte: + // Trail byte + // Based on byte: + + // 0x1B + if (bite === 0x1B) { + // Set iso-2022-jp decoder state to escape start and return + // continue. + iso2022jp_decoder_state = states.EscapeStart; + return decoderError(fatal); + } + + // 0x21 to 0x7E + if (inRange(bite, 0x21, 0x7E)) { + // 1. Set the iso-2022-jp decoder state to lead byte. + iso2022jp_decoder_state = states.LeadByte; + + // 2. Let pointer be (iso-2022-jp lead − 0x21) × 94 + byte − 0x21. + var pointer = (iso2022jp_lead - 0x21) * 94 + bite - 0x21; + + // 3. Let code point be the index code point for pointer in + // index jis0208. + var code_point = indexCodePointFor(pointer, index('jis0208')); + + // 4. If code point is null, return error. + if (code_point === null) + return decoderError(fatal); + + // 5. Return a code point whose value is code point. + return code_point; + } + + // end-of-stream + if (bite === end_of_stream) { + // Set the iso-2022-jp decoder state to lead byte, prepend + // byte to stream, and return error. + iso2022jp_decoder_state = states.LeadByte; + stream.prepend(bite); + return decoderError(fatal); + } + + // Otherwise + // Set iso-2022-jp decoder state to lead byte and return + // error. + iso2022jp_decoder_state = states.LeadByte; + return decoderError(fatal); + + case states.EscapeStart: + // Escape start + + // 1. If byte is either 0x24 or 0x28, set iso-2022-jp lead to + // byte, iso-2022-jp decoder state to escape, and return + // continue. + if (bite === 0x24 || bite === 0x28) { + iso2022jp_lead = bite; + iso2022jp_decoder_state = states.Escape; + return null; + } + + // 2. Prepend byte to stream. + stream.prepend(bite); + + // 3. Unset the iso-2022-jp output flag, set iso-2022-jp + // decoder state to iso-2022-jp decoder output state, and + // return error. + iso2022jp_output_flag = false; + iso2022jp_decoder_state = iso2022jp_decoder_output_state; + return decoderError(fatal); + + case states.Escape: + // Escape + + // 1. Let lead be iso-2022-jp lead and set iso-2022-jp lead to + // 0x00. + var lead = iso2022jp_lead; + iso2022jp_lead = 0x00; + + // 2. Let state be null. + var state = null; + + // 3. If lead is 0x28 and byte is 0x42, set state to ASCII. + if (lead === 0x28 && bite === 0x42) + state = states.ASCII; + + // 4. If lead is 0x28 and byte is 0x4A, set state to Roman. + if (lead === 0x28 && bite === 0x4A) + state = states.Roman; + + // 5. If lead is 0x28 and byte is 0x49, set state to Katakana. + if (lead === 0x28 && bite === 0x49) + state = states.Katakana; + + // 6. If lead is 0x24 and byte is either 0x40 or 0x42, set + // state to lead byte. + if (lead === 0x24 && (bite === 0x40 || bite === 0x42)) + state = states.LeadByte; + + // 7. If state is non-null, run these substeps: + if (state !== null) { + // 1. Set iso-2022-jp decoder state and iso-2022-jp decoder + // output state to states. + iso2022jp_decoder_state = iso2022jp_decoder_state = state; + + // 2. Let output flag be the iso-2022-jp output flag. + var output_flag = iso2022jp_output_flag; + + // 3. Set the iso-2022-jp output flag. + iso2022jp_output_flag = true; + + // 4. Return continue, if output flag is unset, and error + // otherwise. + return !output_flag ? null : decoderError(fatal); + } + + // 8. Prepend lead and byte to stream. + stream.prepend([lead, bite]); + + // 9. Unset the iso-2022-jp output flag, set iso-2022-jp + // decoder state to iso-2022-jp decoder output state and + // return error. + iso2022jp_output_flag = false; + iso2022jp_decoder_state = iso2022jp_decoder_output_state; + return decoderError(fatal); + } + }; + } + + // 13.2.2 iso-2022-jp encoder + /** + * @constructor + * @implements {Encoder} + * @param {{fatal: boolean}} options + */ + function ISO2022JPEncoder(options) { + var fatal = options.fatal; + // iso-2022-jp's encoder has an associated iso-2022-jp encoder + // state which is one of ASCII, Roman, and jis0208 (initially + // ASCII). + /** @enum */ + var states = { + ASCII: 0, + Roman: 1, + jis0208: 2 + }; + var /** @type {number} */ iso2022jp_state = states.ASCII; + /** + * @param {Stream} stream Input stream. + * @param {number} code_point Next code point read from the stream. + * @return {(number|!Array.)} Byte(s) to emit. + */ + this.handler = function(stream, code_point) { + // 1. If code point is end-of-stream and iso-2022-jp encoder + // state is not ASCII, prepend code point to stream, set + // iso-2022-jp encoder state to ASCII, and return three bytes + // 0x1B 0x28 0x42. + if (code_point === end_of_stream && + iso2022jp_state !== states.ASCII) { + stream.prepend(code_point); + iso2022jp_state = states.ASCII; + return [0x1B, 0x28, 0x42]; + } + + // 2. If code point is end-of-stream and iso-2022-jp encoder + // state is ASCII, return finished. + if (code_point === end_of_stream && iso2022jp_state === states.ASCII) + return finished; + + // 3. If ISO-2022-JP encoder state is ASCII or Roman, and code + // point is U+000E, U+000F, or U+001B, return error with U+FFFD. + if ((iso2022jp_state === states.ASCII || + iso2022jp_state === states.Roman) && + (code_point === 0x000E || code_point === 0x000F || + code_point === 0x001B)) { + return encoderError(0xFFFD); + } + + // 4. If iso-2022-jp encoder state is ASCII and code point is an + // ASCII code point, return a byte whose value is code point. + if (iso2022jp_state === states.ASCII && + isASCIICodePoint(code_point)) + return code_point; + + // 5. If iso-2022-jp encoder state is Roman and code point is an + // ASCII code point, excluding U+005C and U+007E, or is U+00A5 + // or U+203E, run these substeps: + if (iso2022jp_state === states.Roman && + ((isASCIICodePoint(code_point) && + code_point !== 0x005C && code_point !== 0x007E) || + (code_point == 0x00A5 || code_point == 0x203E))) { + + // 1. If code point is an ASCII code point, return a byte + // whose value is code point. + if (isASCIICodePoint(code_point)) + return code_point; + + // 2. If code point is U+00A5, return byte 0x5C. + if (code_point === 0x00A5) + return 0x5C; + + // 3. If code point is U+203E, return byte 0x7E. + if (code_point === 0x203E) + return 0x7E; + } + + // 6. If code point is an ASCII code point, and iso-2022-jp + // encoder state is not ASCII, prepend code point to stream, set + // iso-2022-jp encoder state to ASCII, and return three bytes + // 0x1B 0x28 0x42. + if (isASCIICodePoint(code_point) && + iso2022jp_state !== states.ASCII) { + stream.prepend(code_point); + iso2022jp_state = states.ASCII; + return [0x1B, 0x28, 0x42]; + } + + // 7. If code point is either U+00A5 or U+203E, and iso-2022-jp + // encoder state is not Roman, prepend code point to stream, set + // iso-2022-jp encoder state to Roman, and return three bytes + // 0x1B 0x28 0x4A. + if ((code_point === 0x00A5 || code_point === 0x203E) && + iso2022jp_state !== states.Roman) { + stream.prepend(code_point); + iso2022jp_state = states.Roman; + return [0x1B, 0x28, 0x4A]; + } + + // 8. If code point is U+2212, set it to U+FF0D. + if (code_point === 0x2212) + code_point = 0xFF0D; + + // 9. Let pointer be the index pointer for code point in index + // jis0208. + var pointer = indexPointerFor(code_point, index('jis0208')); + + // 10. If pointer is null, return error with code point. + if (pointer === null) + return encoderError(code_point); + + // 11. If iso-2022-jp encoder state is not jis0208, prepend code + // point to stream, set iso-2022-jp encoder state to jis0208, + // and return three bytes 0x1B 0x24 0x42. + if (iso2022jp_state !== states.jis0208) { + stream.prepend(code_point); + iso2022jp_state = states.jis0208; + return [0x1B, 0x24, 0x42]; + } + + // 12. Let lead be floor(pointer / 94) + 0x21. + var lead = floor(pointer / 94) + 0x21; + + // 13. Let trail be pointer % 94 + 0x21. + var trail = pointer % 94 + 0x21; + + // 14. Return two bytes whose values are lead and trail. + return [lead, trail]; + }; + } + + /** @param {{fatal: boolean}} options */ + encoders['ISO-2022-JP'] = function(options) { + return new ISO2022JPEncoder(options); + }; + /** @param {{fatal: boolean}} options */ + decoders['ISO-2022-JP'] = function(options) { + return new ISO2022JPDecoder(options); + }; + + // 13.3 Shift_JIS + + // 13.3.1 Shift_JIS decoder + /** + * @constructor + * @implements {Decoder} + * @param {{fatal: boolean}} options + */ + function ShiftJISDecoder(options) { + var fatal = options.fatal; + // Shift_JIS's decoder has an associated Shift_JIS lead (initially + // 0x00). + var /** @type {number} */ Shift_JIS_lead = 0x00; + /** + * @param {Stream} stream The stream of bytes being decoded. + * @param {number} bite The next byte read from the stream. + * @return {?(number|!Array.)} The next code point(s) + * decoded, or null if not enough data exists in the input + * stream to decode a complete code point. + */ + this.handler = function(stream, bite) { + // 1. If byte is end-of-stream and Shift_JIS lead is not 0x00, + // set Shift_JIS lead to 0x00 and return error. + if (bite === end_of_stream && Shift_JIS_lead !== 0x00) { + Shift_JIS_lead = 0x00; + return decoderError(fatal); + } + + // 2. If byte is end-of-stream and Shift_JIS lead is 0x00, + // return finished. + if (bite === end_of_stream && Shift_JIS_lead === 0x00) + return finished; + + // 3. If Shift_JIS lead is not 0x00, let lead be Shift_JIS lead, + // let pointer be null, set Shift_JIS lead to 0x00, and then run + // these substeps: + if (Shift_JIS_lead !== 0x00) { + var lead = Shift_JIS_lead; + var pointer = null; + Shift_JIS_lead = 0x00; + + // 1. Let offset be 0x40, if byte is less than 0x7F, and 0x41 + // otherwise. + var offset = (bite < 0x7F) ? 0x40 : 0x41; + + // 2. Let lead offset be 0x81, if lead is less than 0xA0, and + // 0xC1 otherwise. + var lead_offset = (lead < 0xA0) ? 0x81 : 0xC1; + + // 3. If byte is in the range 0x40 to 0x7E, inclusive, or 0x80 + // to 0xFC, inclusive, set pointer to (lead − lead offset) × + // 188 + byte − offset. + if (inRange(bite, 0x40, 0x7E) || inRange(bite, 0x80, 0xFC)) + pointer = (lead - lead_offset) * 188 + bite - offset; + + // 4. If pointer is in the range 8836 to 10715, inclusive, + // return a code point whose value is 0xE000 − 8836 + pointer. + if (inRange(pointer, 8836, 10715)) + return 0xE000 - 8836 + pointer; + + // 5. Let code point be null, if pointer is null, and the + // index code point for pointer in index jis0208 otherwise. + var code_point = (pointer === null) ? null : + indexCodePointFor(pointer, index('jis0208')); + + // 6. If code point is null and byte is an ASCII byte, prepend + // byte to stream. + if (code_point === null && isASCIIByte(bite)) + stream.prepend(bite); + + // 7. If code point is null, return error. + if (code_point === null) + return decoderError(fatal); + + // 8. Return a code point whose value is code point. + return code_point; + } + + // 4. If byte is an ASCII byte or 0x80, return a code point + // whose value is byte. + if (isASCIIByte(bite) || bite === 0x80) + return bite; + + // 5. If byte is in the range 0xA1 to 0xDF, inclusive, return a + // code point whose value is 0xFF61 − 0xA1 + byte. + if (inRange(bite, 0xA1, 0xDF)) + return 0xFF61 - 0xA1 + bite; + + // 6. If byte is in the range 0x81 to 0x9F, inclusive, or 0xE0 + // to 0xFC, inclusive, set Shift_JIS lead to byte and return + // continue. + if (inRange(bite, 0x81, 0x9F) || inRange(bite, 0xE0, 0xFC)) { + Shift_JIS_lead = bite; + return null; + } + + // 7. Return error. + return decoderError(fatal); + }; + } + + // 13.3.2 Shift_JIS encoder + /** + * @constructor + * @implements {Encoder} + * @param {{fatal: boolean}} options + */ + function ShiftJISEncoder(options) { + var fatal = options.fatal; + /** + * @param {Stream} stream Input stream. + * @param {number} code_point Next code point read from the stream. + * @return {(number|!Array.)} Byte(s) to emit. + */ + this.handler = function(stream, code_point) { + // 1. If code point is end-of-stream, return finished. + if (code_point === end_of_stream) + return finished; + + // 2. If code point is an ASCII code point or U+0080, return a + // byte whose value is code point. + if (isASCIICodePoint(code_point) || code_point === 0x0080) + return code_point; + + // 3. If code point is U+00A5, return byte 0x5C. + if (code_point === 0x00A5) + return 0x5C; + + // 4. If code point is U+203E, return byte 0x7E. + if (code_point === 0x203E) + return 0x7E; + + // 5. If code point is in the range U+FF61 to U+FF9F, inclusive, + // return a byte whose value is code point − 0xFF61 + 0xA1. + if (inRange(code_point, 0xFF61, 0xFF9F)) + return code_point - 0xFF61 + 0xA1; + + // 6. If code point is U+2212, set it to U+FF0D. + if (code_point === 0x2212) + code_point = 0xFF0D; + + // 7. Let pointer be the index Shift_JIS pointer for code point. + var pointer = indexShiftJISPointerFor(code_point); + + // 8. If pointer is null, return error with code point. + if (pointer === null) + return encoderError(code_point); + + // 9. Let lead be floor(pointer / 188). + var lead = floor(pointer / 188); + + // 10. Let lead offset be 0x81, if lead is less than 0x1F, and + // 0xC1 otherwise. + var lead_offset = (lead < 0x1F) ? 0x81 : 0xC1; + + // 11. Let trail be pointer % 188. + var trail = pointer % 188; + + // 12. Let offset be 0x40, if trail is less than 0x3F, and 0x41 + // otherwise. + var offset = (trail < 0x3F) ? 0x40 : 0x41; + + // 13. Return two bytes whose values are lead + lead offset and + // trail + offset. + return [lead + lead_offset, trail + offset]; + }; + } + + /** @param {{fatal: boolean}} options */ + encoders['Shift_JIS'] = function(options) { + return new ShiftJISEncoder(options); + }; + /** @param {{fatal: boolean}} options */ + decoders['Shift_JIS'] = function(options) { + return new ShiftJISDecoder(options); + }; + + // + // 14. Legacy multi-byte Korean encodings + // + + // 14.1 euc-kr + + // 14.1.1 euc-kr decoder + /** + * @constructor + * @implements {Decoder} + * @param {{fatal: boolean}} options + */ + function EUCKRDecoder(options) { + var fatal = options.fatal; + + // euc-kr's decoder has an associated euc-kr lead (initially 0x00). + var /** @type {number} */ euckr_lead = 0x00; + /** + * @param {Stream} stream The stream of bytes being decoded. + * @param {number} bite The next byte read from the stream. + * @return {?(number|!Array.)} The next code point(s) + * decoded, or null if not enough data exists in the input + * stream to decode a complete code point. + */ + this.handler = function(stream, bite) { + // 1. If byte is end-of-stream and euc-kr lead is not 0x00, set + // euc-kr lead to 0x00 and return error. + if (bite === end_of_stream && euckr_lead !== 0) { + euckr_lead = 0x00; + return decoderError(fatal); + } + + // 2. If byte is end-of-stream and euc-kr lead is 0x00, return + // finished. + if (bite === end_of_stream && euckr_lead === 0) + return finished; + + // 3. If euc-kr lead is not 0x00, let lead be euc-kr lead, let + // pointer be null, set euc-kr lead to 0x00, and then run these + // substeps: + if (euckr_lead !== 0x00) { + var lead = euckr_lead; + var pointer = null; + euckr_lead = 0x00; + + // 1. If byte is in the range 0x41 to 0xFE, inclusive, set + // pointer to (lead − 0x81) × 190 + (byte − 0x41). + if (inRange(bite, 0x41, 0xFE)) + pointer = (lead - 0x81) * 190 + (bite - 0x41); + + // 2. Let code point be null, if pointer is null, and the + // index code point for pointer in index euc-kr otherwise. + var code_point = (pointer === null) + ? null : indexCodePointFor(pointer, index('euc-kr')); + + // 3. If code point is null and byte is an ASCII byte, prepend + // byte to stream. + if (pointer === null && isASCIIByte(bite)) + stream.prepend(bite); + + // 4. If code point is null, return error. + if (code_point === null) + return decoderError(fatal); + + // 5. Return a code point whose value is code point. + return code_point; + } + + // 4. If byte is an ASCII byte, return a code point whose value + // is byte. + if (isASCIIByte(bite)) + return bite; + + // 5. If byte is in the range 0x81 to 0xFE, inclusive, set + // euc-kr lead to byte and return continue. + if (inRange(bite, 0x81, 0xFE)) { + euckr_lead = bite; + return null; + } + + // 6. Return error. + return decoderError(fatal); + }; + } + + // 14.1.2 euc-kr encoder + /** + * @constructor + * @implements {Encoder} + * @param {{fatal: boolean}} options + */ + function EUCKREncoder(options) { + var fatal = options.fatal; + /** + * @param {Stream} stream Input stream. + * @param {number} code_point Next code point read from the stream. + * @return {(number|!Array.)} Byte(s) to emit. + */ + this.handler = function(stream, code_point) { + // 1. If code point is end-of-stream, return finished. + if (code_point === end_of_stream) + return finished; + + // 2. If code point is an ASCII code point, return a byte whose + // value is code point. + if (isASCIICodePoint(code_point)) + return code_point; + + // 3. Let pointer be the index pointer for code point in index + // euc-kr. + var pointer = indexPointerFor(code_point, index('euc-kr')); + + // 4. If pointer is null, return error with code point. + if (pointer === null) + return encoderError(code_point); + + // 5. Let lead be floor(pointer / 190) + 0x81. + var lead = floor(pointer / 190) + 0x81; + + // 6. Let trail be pointer % 190 + 0x41. + var trail = (pointer % 190) + 0x41; + + // 7. Return two bytes whose values are lead and trail. + return [lead, trail]; + }; + } + + /** @param {{fatal: boolean}} options */ + encoders['EUC-KR'] = function(options) { + return new EUCKREncoder(options); + }; + /** @param {{fatal: boolean}} options */ + decoders['EUC-KR'] = function(options) { + return new EUCKRDecoder(options); + }; + + + // + // 15. Legacy miscellaneous encodings + // + + // 15.1 replacement + + // Not needed - API throws RangeError + + // 15.2 Common infrastructure for utf-16be and utf-16le + + /** + * @param {number} code_unit + * @param {boolean} utf16be + * @return {!Array.} bytes + */ + function convertCodeUnitToBytes(code_unit, utf16be) { + // 1. Let byte1 be code unit >> 8. + var byte1 = code_unit >> 8; + + // 2. Let byte2 be code unit & 0x00FF. + var byte2 = code_unit & 0x00FF; + + // 3. Then return the bytes in order: + // utf-16be flag is set: byte1, then byte2. + if (utf16be) + return [byte1, byte2]; + // utf-16be flag is unset: byte2, then byte1. + return [byte2, byte1]; + } + + // 15.2.1 shared utf-16 decoder + /** + * @constructor + * @implements {Decoder} + * @param {boolean} utf16_be True if big-endian, false if little-endian. + * @param {{fatal: boolean}} options + */ + function UTF16Decoder(utf16_be, options) { + var fatal = options.fatal; + var /** @type {?number} */ utf16_lead_byte = null, + /** @type {?number} */ utf16_lead_surrogate = null; + /** + * @param {Stream} stream The stream of bytes being decoded. + * @param {number} bite The next byte read from the stream. + * @return {?(number|!Array.)} The next code point(s) + * decoded, or null if not enough data exists in the input + * stream to decode a complete code point. + */ + this.handler = function(stream, bite) { + // 1. If byte is end-of-stream and either utf-16 lead byte or + // utf-16 lead surrogate is not null, set utf-16 lead byte and + // utf-16 lead surrogate to null, and return error. + if (bite === end_of_stream && (utf16_lead_byte !== null || + utf16_lead_surrogate !== null)) { + return decoderError(fatal); + } + + // 2. If byte is end-of-stream and utf-16 lead byte and utf-16 + // lead surrogate are null, return finished. + if (bite === end_of_stream && utf16_lead_byte === null && + utf16_lead_surrogate === null) { + return finished; + } + + // 3. If utf-16 lead byte is null, set utf-16 lead byte to byte + // and return continue. + if (utf16_lead_byte === null) { + utf16_lead_byte = bite; + return null; + } + + // 4. Let code unit be the result of: + var code_unit; + if (utf16_be) { + // utf-16be decoder flag is set + // (utf-16 lead byte << 8) + byte. + code_unit = (utf16_lead_byte << 8) + bite; + } else { + // utf-16be decoder flag is unset + // (byte << 8) + utf-16 lead byte. + code_unit = (bite << 8) + utf16_lead_byte; + } + // Then set utf-16 lead byte to null. + utf16_lead_byte = null; + + // 5. If utf-16 lead surrogate is not null, let lead surrogate + // be utf-16 lead surrogate, set utf-16 lead surrogate to null, + // and then run these substeps: + if (utf16_lead_surrogate !== null) { + var lead_surrogate = utf16_lead_surrogate; + utf16_lead_surrogate = null; + + // 1. If code unit is in the range U+DC00 to U+DFFF, + // inclusive, return a code point whose value is 0x10000 + + // ((lead surrogate − 0xD800) << 10) + (code unit − 0xDC00). + if (inRange(code_unit, 0xDC00, 0xDFFF)) { + return 0x10000 + (lead_surrogate - 0xD800) * 0x400 + + (code_unit - 0xDC00); + } + + // 2. Prepend the sequence resulting of converting code unit + // to bytes using utf-16be decoder flag to stream and return + // error. + stream.prepend(convertCodeUnitToBytes(code_unit, utf16_be)); + return decoderError(fatal); + } + + // 6. If code unit is in the range U+D800 to U+DBFF, inclusive, + // set utf-16 lead surrogate to code unit and return continue. + if (inRange(code_unit, 0xD800, 0xDBFF)) { + utf16_lead_surrogate = code_unit; + return null; + } + + // 7. If code unit is in the range U+DC00 to U+DFFF, inclusive, + // return error. + if (inRange(code_unit, 0xDC00, 0xDFFF)) + return decoderError(fatal); + + // 8. Return code point code unit. + return code_unit; + }; + } + + // 15.2.2 shared utf-16 encoder + /** + * @constructor + * @implements {Encoder} + * @param {boolean} utf16_be True if big-endian, false if little-endian. + * @param {{fatal: boolean}} options + */ + function UTF16Encoder(utf16_be, options) { + var fatal = options.fatal; + /** + * @param {Stream} stream Input stream. + * @param {number} code_point Next code point read from the stream. + * @return {(number|!Array.)} Byte(s) to emit. + */ + this.handler = function(stream, code_point) { + // 1. If code point is end-of-stream, return finished. + if (code_point === end_of_stream) + return finished; + + // 2. If code point is in the range U+0000 to U+FFFF, inclusive, + // return the sequence resulting of converting code point to + // bytes using utf-16be encoder flag. + if (inRange(code_point, 0x0000, 0xFFFF)) + return convertCodeUnitToBytes(code_point, utf16_be); + + // 3. Let lead be ((code point − 0x10000) >> 10) + 0xD800, + // converted to bytes using utf-16be encoder flag. + var lead = convertCodeUnitToBytes( + ((code_point - 0x10000) >> 10) + 0xD800, utf16_be); + + // 4. Let trail be ((code point − 0x10000) & 0x3FF) + 0xDC00, + // converted to bytes using utf-16be encoder flag. + var trail = convertCodeUnitToBytes( + ((code_point - 0x10000) & 0x3FF) + 0xDC00, utf16_be); + + // 5. Return a byte sequence of lead followed by trail. + return lead.concat(trail); + }; + } + + // 15.3 utf-16be + // 15.3.1 utf-16be decoder + /** @param {{fatal: boolean}} options */ + encoders['UTF-16BE'] = function(options) { + return new UTF16Encoder(true, options); + }; + // 15.3.2 utf-16be encoder + /** @param {{fatal: boolean}} options */ + decoders['UTF-16BE'] = function(options) { + return new UTF16Decoder(true, options); + }; + + // 15.4 utf-16le + // 15.4.1 utf-16le decoder + /** @param {{fatal: boolean}} options */ + encoders['UTF-16LE'] = function(options) { + return new UTF16Encoder(false, options); + }; + // 15.4.2 utf-16le encoder + /** @param {{fatal: boolean}} options */ + decoders['UTF-16LE'] = function(options) { + return new UTF16Decoder(false, options); + }; + + // 15.5 x-user-defined + + // 15.5.1 x-user-defined decoder + /** + * @constructor + * @implements {Decoder} + * @param {{fatal: boolean}} options + */ + function XUserDefinedDecoder(options) { + var fatal = options.fatal; + /** + * @param {Stream} stream The stream of bytes being decoded. + * @param {number} bite The next byte read from the stream. + * @return {?(number|!Array.)} The next code point(s) + * decoded, or null if not enough data exists in the input + * stream to decode a complete code point. + */ + this.handler = function(stream, bite) { + // 1. If byte is end-of-stream, return finished. + if (bite === end_of_stream) + return finished; + + // 2. If byte is an ASCII byte, return a code point whose value + // is byte. + if (isASCIIByte(bite)) + return bite; + + // 3. Return a code point whose value is 0xF780 + byte − 0x80. + return 0xF780 + bite - 0x80; + }; + } + + // 15.5.2 x-user-defined encoder + /** + * @constructor + * @implements {Encoder} + * @param {{fatal: boolean}} options + */ + function XUserDefinedEncoder(options) { + var fatal = options.fatal; + /** + * @param {Stream} stream Input stream. + * @param {number} code_point Next code point read from the stream. + * @return {(number|!Array.)} Byte(s) to emit. + */ + this.handler = function(stream, code_point) { + // 1.If code point is end-of-stream, return finished. + if (code_point === end_of_stream) + return finished; + + // 2. If code point is an ASCII code point, return a byte whose + // value is code point. + if (isASCIICodePoint(code_point)) + return code_point; + + // 3. If code point is in the range U+F780 to U+F7FF, inclusive, + // return a byte whose value is code point − 0xF780 + 0x80. + if (inRange(code_point, 0xF780, 0xF7FF)) + return code_point - 0xF780 + 0x80; + + // 4. Return error with code point. + return encoderError(code_point); + }; + } + + /** @param {{fatal: boolean}} options */ + encoders['x-user-defined'] = function(options) { + return new XUserDefinedEncoder(options); + }; + /** @param {{fatal: boolean}} options */ + decoders['x-user-defined'] = function(options) { + return new XUserDefinedDecoder(options); + }; + + if (!global['TextEncoder']) + global['TextEncoder'] = TextEncoder; + if (!global['TextDecoder']) + global['TextDecoder'] = TextDecoder; + + if (typeof module !== "undefined" && module.exports) { + module.exports = { + TextEncoder: global['TextEncoder'], + TextDecoder: global['TextDecoder'], + EncodingIndexes: global["encoding-indexes"] + }; + } + +// For strict environments where `this` inside the global scope +// is `undefined`, take a pure object instead +}(this || {})); \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index cba78935..e57bbe69 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -24,16 +24,19 @@ var Server = require('karma').Server; var paths = { data : './data', - source_js : [ './src/mago3d/*.js', './src/mago3d/**/*.js', '!./src/engine/cesium', '!./src/mago3d/Demo*.js' ], - // source_images : './images/*', - // source_css : './src/css/*', + source_js : [ './src/mago3d/*.js', './src/mago3d/**/*.js', '!./src/engine/cesium', '!./src/mago3d/Demo*.js', '!./src/mago3d/extern/*.js' ], dest_js : './build/mago3d', - // dest_images : './images', - // dest_css : './build/css', - test : './test/*.js', + test : ['./test/*.js', './test/mago3d/*.js', './test/mago3d/**/*.js'], build : './build' }; +var packageJson = require('./package.json'); +var version = packageJson.version; +if (/\.0$/.test(version)) +{ + version = version.substring(0, version.length - 2); +} + function glslToJavaScript(minify, minifyStateFilePath) { fs.writeFileSync(minifyStateFilePath, minify); @@ -107,6 +110,104 @@ define(function() {\n\ }); } +function jsonToJavaScript(minify, minifyStateFilePath) +{ + fs.writeFileSync(minifyStateFilePath, minify); + var minifyStateFileLastModified = fs.existsSync(minifyStateFilePath) ? fs.statSync(minifyStateFilePath).mtime.getTime() : 0; + + // collect all currently existing JS files into a set, later we will remove the ones + // we still are using from the set, then delete any files remaining in the set. + var leftOverJsFiles = {}; + var messageContents = "'use strict';\nvar MessageSource = {};\n"; + + globby.sync(['src/mago3d/message/i18n/**/*.js']).forEach(function(file) + { + leftOverJsFiles[path.normalize(file)] = true; + }); + + var jsonFiles = globby.sync(['src/mago3d/message/i18n/**/*.json']); + jsonFiles.forEach(function(jsonFile) + { + jsonFile = path.normalize(jsonFile); + var baseName = path.basename(jsonFile, '.json'); + var jsFile = path.join(path.dirname(jsonFile), baseName) + '.js'; + + delete leftOverJsFiles[jsFile]; + + var jsFileExists = fs.existsSync(jsFile); + var jsFileModified = jsFileExists ? fs.statSync(jsFile).mtime.getTime() : 0; + var glslFileModified = fs.statSync(jsonFile).mtime.getTime(); + + if (jsFileExists && jsFileModified > glslFileModified && jsFileModified > minifyStateFileLastModified) + { + return; + } + + var contents = fs.readFileSync(jsonFile, 'utf8'); + if (minify) + { + contents = contents.replace(/\s+$/gm, '').replace(/^\s+/gm, '').replace(/\n+/gm, '\n'); + } + + //contents = contents.replace(/\n/gm, '\\n\\\n'); + messageContents += 'MessageSource.' + baseName + ' = ' + contents + ';\n'; + }); + + fs.writeFileSync('src/mago3d/message/MessageSource.js', messageContents); + + // delete any left over JS files from old shaders + Object.keys(leftOverJsFiles).forEach(function(filepath) + { + rimraf.sync(filepath); + }); +} + +function filePathToModuleId(moduleId) +{ + return moduleId.substring(0, moduleId.lastIndexOf('.')).replace(/\\/g, '/'); +} + +function createMago3D(minify, minifyStateFilePath) +{ + fs.writeFileSync(minifyStateFilePath, minify); + var minifyStateFileLastModified = fs.existsSync(minifyStateFilePath) ? fs.statSync(minifyStateFilePath).mtime.getTime() : 0; + + var assignments = []; + var list = paths.source_js.slice(0); + list.push('!./src/mago3d/api/APIGateway.js'); + list.push('!./src/mago3d/domain/Callback.js'); + globby.sync(list).forEach(function(file) + { + file = path.relative('src/mago3d', file); + var parameterName = path.basename(file, path.extname(file)); + var assignmentName = "['" + parameterName + "']"; + assignments.push('_mago3d' + assignmentName + ' = ' + parameterName + ';'); + }); + + var jsFile = path.join(path.normalize(paths.dest_js), 'mago3d.js'); + var jsFileExists = fs.existsSync(jsFile); + var jsFileModified = jsFileExists ? fs.statSync(jsFile).mtime.getTime() : 0; + + if (jsFileExists && jsFileModified > minifyStateFileLastModified) + { + return; + } + + var contents = '\ +\'use strict\';\n\ +var Mago3D = (function() \n\ +{\n\ +'+ fs.readFileSync(jsFile, 'utf8') +'\ + var _mago3d = {\n\ + VERSION: \'' + version + '\',\n\ + };\n\ + '+ assignments.join('\n ') +'\n\ + return _mago3d;\n\ +})();\n'; + fs.writeFileSync(jsFile, contents); +} + + // 삭제가 필요한 디렉토리가 있는 경우 gulp.task('clean', function() { @@ -118,12 +219,31 @@ gulp.task('build', function(done) mkdirp.sync(paths.build); mkdirp.sync(paths.dest_js); glslToJavaScript(false, path.join(path.normalize(paths.build), 'minifyShaders.state')); + jsonToJavaScript(false, path.join(path.normalize(paths.build), 'minifyShaders.state')); done(); }); -gulp.task('combine:js', gulp.series( 'clean', 'build', function() +gulp.task('merge:js', gulp.series( 'clean', 'build', function() +{ + var list = paths.source_js.slice(0); + list.push('!./src/mago3d/api/APIGateway.js'); + list.push('!./src/mago3d/domain/Callback.js'); + return gulp.src(list) + .pipe(concat('mago3d.js')) + .pipe(gulp.dest(paths.dest_js)); +})); + +gulp.task('combine:js', gulp.series( 'merge:js', function() { - return gulp.src(paths.source_js) + createMago3D(false, path.join(path.normalize(paths.build), 'minifyShaders.state')); + + var list = []; + list.push('./src/mago3d/api/APIGateway.js'); + list.push('./src/mago3d/domain/Callback.js'); + list.push('./src/mago3d/extern/*.js'); + list.push(path.join(path.normalize(paths.dest_js), 'mago3d.js')); + + return gulp.src(list) .pipe(concat('mago3d.js')) .pipe(gulp.dest(paths.dest_js)); })); @@ -158,8 +278,8 @@ gulp.task('karma', function (done) // eslint gulp.task('lint', function() { - var list = paths.source_js; - list.push('!./src/mago3d/extern/*.js'); + var list = paths.source_js.slice(0); + list = list.concat(paths.test); return gulp.src(list) .pipe(eslint({fix: true})) .pipe(eslint.format()) diff --git a/locales/common/en.json b/locales/common/en.json new file mode 100644 index 00000000..274e97bd --- /dev/null +++ b/locales/common/en.json @@ -0,0 +1,45 @@ +{ + "language": { + "title": "Language", + "english": "English", + "korean": "Korean" + }, + "menu": { + "issue": { + "title": "Issue", + "tooltip": "Shows the latest 10 issues sorted chronologically from the entire Issue List." + }, + "search": { + "title": "Search", + "tooltip": "Searching such as issue, object, and spatial information." + }, + "api": { + "title": "API", + "tooltip": "APIs to control various functions of mago3D." + }, + "regist": { + "title": "Regist", + "tooltip": "Issue registration for Object." + }, + "tree": { + "title": "Tree", + "tooltip": "Display data hierarchy and Attributes by project." + }, + "chart": { + "title": "Chart", + "tooltip": "Display statistical data by project." + }, + "log": { + "title": "Log", + "tooltip": "Displays the data change log." + }, + "attribute": { + "title": "Attribute", + "tooltip": "Supports data attribute retrieval." + }, + "settings": { + "title": "Settings", + "tooltip": "Settings related to rendering." + } + } +} diff --git a/locales/common/ko.json b/locales/common/ko.json new file mode 100644 index 00000000..1bcd2748 --- /dev/null +++ b/locales/common/ko.json @@ -0,0 +1,45 @@ +{ + "language": { + "title": "언어", + "english": "영어", + "korean": "한국어" + }, + "menu": { + "issue": { + "title": "이슈", + "tooltip": "전체 이슈 목록에서 시간순으로 정렬된 최신 10 가지 이슈를 보여줍니다." + }, + "search": { + "title": "검색", + "tooltip": "이슈, 객체 및 공간 정보와 같은 정보를 검색합니다." + }, + "api": { + "title": "API", + "tooltip": "mago3D 를 조절하기 위한 다양한 API 함수들이 있습니다." + }, + "regist": { + "title": "등록", + "tooltip": "이슈를 등록합니다." + }, + "tree": { + "title": "목록", + "tooltip": "프로젝트별로 데이터 계층 및 속성을 표시합니다." + }, + "chart": { + "title": "차트", + "tooltip": "프로젝트별로 통계 데이터를 표시합니다." + }, + "log": { + "title": "로그", + "tooltip": "데이터 변경 로그를 표시합니다." + }, + "attribute": { + "title": "속성", + "tooltip": "데이터 속성 검색을 지원합니다." + }, + "settings": { + "title": "설정", + "tooltip": "렌더링과 관련된 설정을 합니다." + } + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..c45db3b6 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,9341 @@ +{ + "name": "mago3djs", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz", + "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==", + "dev": true + }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + } + }, + "@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true + }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/node": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.2.tgz", + "integrity": "sha512-5tabW/i+9mhrfEOUcLDu2xBPsHJ+X5Orqy9FKpale3SjDA17j5AEpYq5vfy3oAeAHGcvANRCO3NV3d2D6q3NiA==", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", + "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", + "dev": true + }, + "acorn-jsx": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", + "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", + "dev": true + }, + "acorn-node": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.6.2.tgz", + "integrity": "sha512-rIhNEZuNI8ibQcL7ANm/mGyPukIaZsRNX9psFNQURyJW0nu6k8wjSDld20z6v2mDBWqX13pIEnk9gGZJHIlEXg==", + "dev": true, + "requires": { + "acorn": "^6.0.2", + "acorn-dynamic-import": "^4.0.0", + "acorn-walk": "^6.1.0", + "xtend": "^4.0.1" + } + }, + "acorn-walk": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "dev": true + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", + "dev": true + }, + "ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-colors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", + "dev": true, + "requires": { + "ansi-wrap": "^0.1.0" + } + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", + "dev": true + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "append-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", + "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", + "dev": true, + "requires": { + "buffer-equal": "^1.0.0" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-filter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", + "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=", + "dev": true, + "requires": { + "make-iterator": "^1.0.0" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", + "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=", + "dev": true, + "requires": { + "make-iterator": "^1.0.0" + } + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true + }, + "array-filter": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", + "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", + "dev": true + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, + "array-initial": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", + "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=", + "dev": true, + "requires": { + "array-slice": "^1.0.0", + "is-number": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true + } + } + }, + "array-last": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", + "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", + "dev": true, + "requires": { + "is-number": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true + } + } + }, + "array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=", + "dev": true + }, + "array-reduce": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", + "dev": true + }, + "array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true + }, + "array-sort": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", + "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", + "dev": true, + "requires": { + "default-compare": "^1.0.0", + "get-value": "^2.0.6", + "kind-of": "^5.0.2" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "async-done": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.1.tgz", + "integrity": "sha512-R1BaUeJ4PMoLNJuk+0tLJgjmEqVsdN118+Z8O+alhnQDQgy0kmD5Mqi0DNEmMx2LM0Ed5yekKu+ZXYvIHceicg==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.2", + "process-nextick-args": "^1.0.7", + "stream-exhaust": "^1.0.1" + }, + "dependencies": { + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + } + } + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "dev": true + }, + "async-settle": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", + "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=", + "dev": true, + "requires": { + "async-done": "^1.2.2" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, + "bach": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", + "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=", + "dev": true, + "requires": { + "arr-filter": "^1.1.1", + "arr-flatten": "^1.0.1", + "arr-map": "^2.0.0", + "array-each": "^1.0.0", + "array-initial": "^1.0.0", + "array-last": "^1.1.1", + "async-done": "^1.2.2", + "async-settle": "^1.0.0", + "now-and-later": "^2.0.0" + } + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", + "dev": true + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "dev": true + }, + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", + "dev": true + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "dev": true, + "requires": { + "callsite": "1.0.0" + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", + "dev": true + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-pack": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", + "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "combine-source-map": "~0.8.0", + "defined": "^1.0.0", + "safe-buffer": "^5.1.1", + "through2": "^2.0.0", + "umd": "^3.0.0" + } + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browserify": { + "version": "16.2.3", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.2.3.tgz", + "integrity": "sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "assert": "^1.4.0", + "browser-pack": "^6.0.1", + "browser-resolve": "^1.11.0", + "browserify-zlib": "~0.2.0", + "buffer": "^5.0.2", + "cached-path-relative": "^1.0.0", + "concat-stream": "^1.6.0", + "console-browserify": "^1.1.0", + "constants-browserify": "~1.0.0", + "crypto-browserify": "^3.0.0", + "defined": "^1.0.0", + "deps-sort": "^2.0.0", + "domain-browser": "^1.2.0", + "duplexer2": "~0.1.2", + "events": "^2.0.0", + "glob": "^7.1.0", + "has": "^1.0.0", + "htmlescape": "^1.1.0", + "https-browserify": "^1.0.0", + "inherits": "~2.0.1", + "insert-module-globals": "^7.0.0", + "labeled-stream-splicer": "^2.0.0", + "mkdirp": "^0.5.0", + "module-deps": "^6.0.0", + "os-browserify": "~0.3.0", + "parents": "^1.0.1", + "path-browserify": "~0.0.0", + "process": "~0.11.0", + "punycode": "^1.3.2", + "querystring-es3": "~0.2.0", + "read-only-stream": "^2.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.1.4", + "shasum": "^1.0.0", + "shell-quote": "^1.6.1", + "stream-browserify": "^2.0.0", + "stream-http": "^2.0.0", + "string_decoder": "^1.1.1", + "subarg": "^1.0.0", + "syntax-error": "^1.1.1", + "through2": "^2.0.0", + "timers-browserify": "^1.0.1", + "tty-browserify": "0.0.1", + "url": "~0.11.0", + "util": "~0.10.1", + "vm-browserify": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true + }, + "buffer-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", + "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", + "dev": true + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "dev": true + }, + "buffer-from": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", + "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "cached-path-relative": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz", + "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==", + "dev": true + }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", + "dev": true + }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", + "dev": true + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "catharsis": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.10.tgz", + "integrity": "sha512-l2OUaz/3PU3MZylspVFJvwHCVfWyvcduPq4lv3AzZ2pJzZCo7kNKFNyatwujD7XgvGkNAE/Jhhbh2uARNwNkfw==", + "dev": true, + "requires": { + "lodash": "^4.17.11" + }, + "dependencies": { + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + } + } + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "chokidar": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", + "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + } + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cli": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", + "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", + "dev": true, + "requires": { + "exit": "0.1.2", + "glob": "^7.1.1" + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + }, + "dependencies": { + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + } + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "dependencies": { + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + }, + "clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", + "dev": true + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "cloneable-readable": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.2.tgz", + "integrity": "sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "process-nextick-args": "^2.0.0", + "readable-stream": "^2.3.5" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "collection-map": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", + "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=", + "dev": true, + "requires": { + "arr-map": "^2.0.2", + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", + "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", + "dev": true, + "requires": { + "color-name": "1.1.1" + } + }, + "color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=", + "dev": true + }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, + "combine-source-map": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", + "dev": true, + "requires": { + "convert-source-map": "~1.1.0", + "inline-source-map": "~0.6.0", + "lodash.memoize": "~3.0.3", + "source-map": "~0.5.3" + } + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", + "dev": true + }, + "compressible": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", + "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", + "dev": true, + "requires": { + "mime-db": ">= 1.40.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "concat-with-sourcemaps": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz", + "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + } + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "^0.1.4" + } + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "convert-source-map": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "copy-props": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz", + "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==", + "dev": true, + "requires": { + "each-props": "^1.3.0", + "is-plain-object": "^2.0.1" + } + }, + "core-js": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.8.tgz", + "integrity": "sha512-RWlREFU74TEkdXzyl1bka66O3kYp8jeTXrvJZDzVVMH8AiHUSOFpL1yfhQJ+wHocAm1m+4971W1PPzfLuCv1vg==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "dev": true + }, + "dash-ast": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", + "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "date-format": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.0.0.tgz", + "integrity": "sha512-M6UqVvZVgFYqZL1SfHsRGIQSz3ZL+qgbsV5Lp1Vj61LZVYuEwcMXYay7DRDtYs2HQQBK5hQtQ0fD9aEJ89V0LA==", + "dev": true + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "default-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", + "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", + "dev": true, + "requires": { + "kind-of": "^5.0.2" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "default-resolution": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", + "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "dependencies": { + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "deps-sort": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", + "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "shasum": "^1.0.0", + "subarg": "^1.0.0", + "through2": "^2.0.0" + } + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "detective": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", + "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", + "dev": true, + "requires": { + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" + } + }, + "di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "requires": { + "path-type": "^3.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "dev": true, + "requires": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "dev": true, + "requires": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "duplexify": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz", + "integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + } + } + }, + "each-props": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", + "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.1", + "object.defaults": "^1.1.0" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "elliptic": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "engine.io": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz", + "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.0", + "ws": "~3.3.1" + }, + "dependencies": { + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "engine.io-client": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", + "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~3.3.1", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "engine.io-parser": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", + "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", + "dev": true, + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "dev": true + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es5-ext": { + "version": "0.10.45", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.45.tgz", + "integrity": "sha512-FkfM6Vxxfmztilbxxz5UKSD4ICMf5tSpRFtDNtkAhOxZ0EKtX6qwmXNyH/sFyIbX2P/nU5AMiA9jilWsUGJzCQ==", + "dev": true, + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.1", + "next-tick": "1" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + }, + "dependencies": { + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "^0.10.9" + } + } + } + }, + "es6-promise": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", + "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", + "dev": true + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + }, + "dependencies": { + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "^0.10.9" + } + } + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "eslint-plugin-react": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.13.0.tgz", + "integrity": "sha512-uA5LrHylu8lW/eAH3bEQe9YdzpPaFd9yAJTwTi/i/BKTD7j6aQMKVAdGM/ML72zD6womuSK7EiGtMKuK06lWjQ==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.1.0", + "object.fromentries": "^2.0.0", + "prop-types": "^15.7.2", + "resolve": "^1.10.1" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + } + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, + "espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "dev": true, + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "dev": true + }, + "events": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", + "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "express": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.0.tgz", + "integrity": "sha512-1Z7/t3Z5ZnBG252gKUPyItc4xdeaA0X934ca2ewckAsVsw9EG71i++ZHZPYnus8g/s5Bty8IMpSVEuRkmwwPRQ==", + "dev": true, + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "external-editor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extract-zip": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", + "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", + "dev": true, + "requires": { + "concat-stream": "1.6.2", + "debug": "2.6.9", + "mkdirp": "0.5.1", + "yauzl": "2.4.1" + }, + "dependencies": { + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "dev": true, + "requires": { + "fd-slicer": "~1.0.1" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fancy-log": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", + "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", + "dev": true, + "requires": { + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "parse-node-version": "^1.0.0", + "time-stamp": "^1.0.0" + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + } + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "fined": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + } + }, + "flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "dev": true + }, + "flat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "dev": true, + "requires": { + "is-buffer": "~2.0.3" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", + "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==", + "dev": true + } + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", + "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", + "dev": true + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "follow-redirects": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.7.0.tgz", + "integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==", + "dev": true, + "requires": { + "debug": "^3.2.6" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "fork-stream": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/fork-stream/-/fork-stream-0.0.4.tgz", + "integrity": "sha1-24Sfznf2cIpfjzhq5TOgkHtUrnA=", + "dev": true + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "fs-access": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", + "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", + "dev": true, + "requires": { + "null-check": "^1.0.0" + } + }, + "fs-extra": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", + "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0" + }, + "dependencies": { + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } + } + } + }, + "fs-mkdirp-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", + "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "through2": "^2.0.3" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-assigned-identifiers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", + "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + }, + "dependencies": { + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", + "dev": true, + "requires": { + "extend": "^3.0.0", + "glob": "^7.1.1", + "glob-parent": "^3.1.0", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.0", + "pumpify": "^1.3.5", + "readable-stream": "^2.1.5", + "remove-trailing-separator": "^1.0.1", + "to-absolute-glob": "^2.0.0", + "unique-stream": "^2.0.2" + }, + "dependencies": { + "to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + } + } + } + }, + "glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", + "dev": true + }, + "glob-watcher": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.3.tgz", + "integrity": "sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-done": "^1.2.0", + "chokidar": "^2.0.0", + "is-negated-glob": "^1.0.0", + "just-debounce": "^1.0.0", + "object.defaults": "^1.1.0" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "globby": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" + } + }, + "glogg": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", + "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", + "dev": true, + "requires": { + "sparkles": "^1.0.0" + } + }, + "glsl-strip-comments": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/glsl-strip-comments/-/glsl-strip-comments-1.0.0.tgz", + "integrity": "sha1-v40SHtt0gsll0kuNpggDEOVaUaU=", + "dev": true, + "requires": { + "glsl-tokenizer": "^2.1.2" + } + }, + "glsl-tokenizer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/glsl-tokenizer/-/glsl-tokenizer-2.1.2.tgz", + "integrity": "sha1-cgMHUi4DxXrzXABVGVDEpw7y37k=", + "dev": true, + "requires": { + "through2": "^0.6.3" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + } + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "gulp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", + "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", + "dev": true, + "requires": { + "glob-watcher": "^5.0.3", + "gulp-cli": "^2.2.0", + "undertaker": "^1.2.1", + "vinyl-fs": "^3.0.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "gulp-cli": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.2.0.tgz", + "integrity": "sha512-rGs3bVYHdyJpLqR0TUBnlcZ1O5O++Zs4bA0ajm+zr3WFCfiSLjGwoCBqFs18wzN+ZxahT9DkOK5nDf26iDsWjA==", + "dev": true, + "requires": { + "ansi-colors": "^1.0.1", + "archy": "^1.0.0", + "array-sort": "^1.0.0", + "color-support": "^1.1.3", + "concat-stream": "^1.6.0", + "copy-props": "^2.0.1", + "fancy-log": "^1.3.2", + "gulplog": "^1.0.0", + "interpret": "^1.1.0", + "isobject": "^3.0.1", + "liftoff": "^3.1.0", + "matchdep": "^2.0.0", + "mute-stdout": "^1.0.0", + "pretty-hrtime": "^1.0.0", + "replace-homedir": "^1.0.0", + "semver-greatest-satisfied-range": "^1.1.0", + "v8flags": "^3.0.1", + "yargs": "^7.1.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "yargs": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", + "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "dev": true, + "requires": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^5.0.0" + } + } + } + }, + "gulp-concat": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz", + "integrity": "sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M=", + "dev": true, + "requires": { + "concat-with-sourcemaps": "^1.0.0", + "through2": "^2.0.0", + "vinyl": "^2.0.0" + }, + "dependencies": { + "clone": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", + "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", + "dev": true + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true + }, + "vinyl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "dev": true, + "requires": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + } + } + } + }, + "gulp-eslint": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/gulp-eslint/-/gulp-eslint-5.0.0.tgz", + "integrity": "sha512-9GUqCqh85C7rP9120cpxXuZz2ayq3BZc85pCTuPJS03VQYxne0aWPIXWx6LSvsGPa3uRqtSO537vaugOh+5cXg==", + "dev": true, + "requires": { + "eslint": "^5.0.1", + "fancy-log": "^1.3.2", + "plugin-error": "^1.0.1" + } + }, + "gulp-if": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/gulp-if/-/gulp-if-2.0.2.tgz", + "integrity": "sha1-pJe351cwBQQcqivIt92jyARE1ik=", + "dev": true, + "requires": { + "gulp-match": "^1.0.3", + "ternary-stream": "^2.0.1", + "through2": "^2.0.1" + } + }, + "gulp-jsdoc3": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/gulp-jsdoc3/-/gulp-jsdoc3-2.0.0.tgz", + "integrity": "sha512-R0US0cHc5v/u8/g9oQ4/4hXEl/QqFcU3/sladKWlTpDUJPDIkeLNHZpq9PFqnuNvC2yZ/Pegs2KpgUmFghZUIg==", + "dev": true, + "requires": { + "ansi-colors": "^1.1.0", + "beeper": "^1.1.1", + "bluebird": "^3.1.1", + "debug": "^3.1.0", + "fancy-log": "^1.3.2", + "ink-docstrap": "^1.1.4", + "jsdoc": "^3.4.1", + "map-stream": "0.0.7", + "tmp": "0.0.33" + }, + "dependencies": { + "bluebird": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.4.tgz", + "integrity": "sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw==", + "dev": true + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "map-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", + "integrity": "sha1-ih8HiW2CsQkmvTdEokIACfiJdKg=", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "gulp-match": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/gulp-match/-/gulp-match-1.0.3.tgz", + "integrity": "sha1-kcfA1/Kb7NZgbVfYCn+Hdqh6uo4=", + "dev": true, + "requires": { + "minimatch": "^3.0.3" + } + }, + "gulp-rename": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.4.0.tgz", + "integrity": "sha512-swzbIGb/arEoFK89tPY58vg3Ok1bw+d35PfUNwWqdo7KM4jkmuGA78JiDNqR+JeZFaeeHnRg9N7aihX3YPmsyg==", + "dev": true + }, + "gulp-uglify": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gulp-uglify/-/gulp-uglify-3.0.2.tgz", + "integrity": "sha512-gk1dhB74AkV2kzqPMQBLA3jPoIAPd/nlNzP2XMDSG8XZrqnlCiDGAqC+rZOumzFvB5zOphlFh6yr3lgcAb/OOg==", + "dev": true, + "requires": { + "array-each": "^1.0.1", + "extend-shallow": "^3.0.2", + "gulplog": "^1.0.0", + "has-gulplog": "^0.1.0", + "isobject": "^3.0.1", + "make-error-cause": "^1.1.1", + "safe-buffer": "^5.1.2", + "through2": "^2.0.0", + "uglify-js": "^3.0.5", + "vinyl-sourcemaps-apply": "^0.2.0" + }, + "dependencies": { + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "uglify-js": { + "version": "3.5.15", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.15.tgz", + "integrity": "sha512-fe7aYFotptIddkwcm6YuA0HmknBZ52ZzOsUxZEdhhkSsz7RfjHDX2QDxwKTiv4JQ5t5NhfmpgAK+J7LiDhKSqg==", + "dev": true, + "requires": { + "commander": "~2.20.0", + "source-map": "~0.6.1" + } + } + } + }, + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "dev": true, + "requires": { + "glogg": "^1.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "dev": true, + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "dev": true, + "requires": { + "sparkles": "^1.0.0" + } + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hasha": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", + "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=", + "dev": true, + "requires": { + "is-stream": "^1.0.1", + "pinkie-promise": "^2.0.0" + } + }, + "hat": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/hat/-/hat-0.0.3.tgz", + "integrity": "sha1-uwFKnmSzeIrtgAWRdBPU/z1QLYo=", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hosted-git-info": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.1.tgz", + "integrity": "sha512-Ba4+0M4YvIDUUsprMjhVTU1yN9F2/LJSAl69ZpzaLT4l4j5mwTS6jqqW9Ojvj6lKz/veqPzpJBqGbXspOb533A==", + "dev": true + }, + "htmlescape": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", + "dev": true + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.3.0.tgz", + "integrity": "sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "http-proxy": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "dev": true, + "requires": { + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", + "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "ink-docstrap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/ink-docstrap/-/ink-docstrap-1.3.2.tgz", + "integrity": "sha512-STx5orGQU1gfrkoI/fMU7lX6CSP7LBGO10gXNgOZhwKhUqbtNjCkYSewJtNnLmWP1tAGN6oyEpG1HFPw5vpa5Q==", + "dev": true, + "requires": { + "moment": "^2.14.1", + "sanitize-html": "^1.13.0" + } + }, + "inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", + "dev": true, + "requires": { + "source-map": "~0.5.3" + } + }, + "inquirer": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz", + "integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.11", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "insert-module-globals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz", + "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "acorn-node": "^1.5.2", + "combine-source-map": "^0.8.0", + "concat-stream": "^1.6.1", + "is-buffer": "^1.1.0", + "path-is-absolute": "^1.0.1", + "process": "~0.11.0", + "through2": "^2.0.0", + "undeclared-identifiers": "^1.1.2", + "xtend": "^4.0.0" + } + }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "dev": true + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==", + "dev": true + }, + "irregular-plurals": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.4.0.tgz", + "integrity": "sha1-LKmwM2UREYVUEvFr5dd8YqRYp2Y=", + "dev": true + }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-path-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.1.0.tgz", + "integrity": "sha512-Sc5j3/YnM8tDeyCsVeKlm/0p95075DyLmDEIkSgQ7mXkrOX+uTCtmQFm0CYzVyJwcCCmO3k8qfJt17SxQwB5Zw==", + "dev": true + }, + "is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dev": true, + "requires": { + "is-path-inside": "^2.1.0" + } + }, + "is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dev": true, + "requires": { + "path-is-inside": "^1.0.2" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "requires": { + "is-unc-path": "^1.0.0" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isbinaryfile": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz", + "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==", + "dev": true, + "requires": { + "buffer-alloc": "^1.2.0" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "jasmine-core": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.4.0.tgz", + "integrity": "sha512-HU/YxV4i6GcmiH4duATwAbJQMlE0MsDIR5XmSVxURxKHn3aGAdbY1/ZJFmVRbKtnLwIxxMJD7gYaPsypcbYimg==", + "dev": true + }, + "js-string-escape": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", + "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "js2xmlparser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.0.tgz", + "integrity": "sha512-WuNgdZOXVmBk5kUPMcTcVUpbGRzLfNkv7+7APq7WiDihpXVKrgxo6wwRpRl9OQeEBgKCVk9mR7RbzrnNWC8oBw==", + "dev": true, + "requires": { + "xmlcreate": "^2.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsdoc": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.2.tgz", + "integrity": "sha512-S2vzg99C5+gb7FWlrK4TVdyzVPGGkdvpDkCEJH1JABi2PKzPeLu5/zZffcJUifgWUJqXWl41Hoc+MmuM2GukIg==", + "dev": true, + "requires": { + "@babel/parser": "^7.4.4", + "bluebird": "^3.5.4", + "catharsis": "^0.8.10", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.0", + "klaw": "^3.0.0", + "markdown-it": "^8.4.2", + "markdown-it-anchor": "^5.0.2", + "marked": "^0.6.2", + "mkdirp": "^0.5.1", + "requizzle": "^0.2.2", + "strip-json-comments": "^3.0.1", + "taffydb": "2.6.2", + "underscore": "~1.9.1" + }, + "dependencies": { + "bluebird": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.4.tgz", + "integrity": "sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw==", + "dev": true + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true + } + } + }, + "jshint": { + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.10.2.tgz", + "integrity": "sha512-e7KZgCSXMJxznE/4WULzybCMNXNAd/bf5TSrvVEq78Q/K8ZwFpmBqQeDtNiHc3l49nV4E/+YeHU/JZjSUIrLAA==", + "dev": true, + "requires": { + "cli": "~1.0.0", + "console-browserify": "1.1.x", + "exit": "0.1.x", + "htmlparser2": "3.8.x", + "lodash": "~4.17.11", + "minimatch": "~3.0.2", + "shelljs": "0.3.x", + "strip-json-comments": "1.0.x" + }, + "dependencies": { + "domhandler": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "entities": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", + "dev": true + }, + "htmlparser2": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", + "dev": true, + "requires": { + "domelementtype": "1", + "domhandler": "2.3", + "domutils": "1.5", + "entities": "1.0", + "readable-stream": "1.1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "strip-json-comments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", + "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", + "dev": true + } + } + }, + "jshint-stylish": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/jshint-stylish/-/jshint-stylish-2.2.1.tgz", + "integrity": "sha1-JCCCosA1rgP9gQROBXDMQgjPbmE=", + "dev": true, + "requires": { + "beeper": "^1.1.0", + "chalk": "^1.0.0", + "log-symbols": "^1.0.0", + "plur": "^2.1.0", + "string-length": "^1.0.0", + "text-table": "^0.2.0" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", + "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", + "dev": true, + "requires": { + "jsonify": "~0.0.0" + } + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "jsx-ast-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.1.0.tgz", + "integrity": "sha512-yDGDG2DS4JcqhA6blsuYbtsT09xL8AoLuUR2Gb5exrw7UEM19sBcOTq+YBBhrNbl0PUC4R4LnFu+dHg2HKeVvA==", + "dev": true, + "requires": { + "array-includes": "^3.0.3" + } + }, + "just-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz", + "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=", + "dev": true + }, + "karma": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/karma/-/karma-4.1.0.tgz", + "integrity": "sha512-xckiDqyNi512U4dXGOOSyLKPwek6X/vUizSy2f3geYevbLj+UIdvNwbn7IwfUIL2g1GXEPWt/87qFD1fBbl/Uw==", + "dev": true, + "requires": { + "bluebird": "^3.3.0", + "body-parser": "^1.16.1", + "braces": "^2.3.2", + "chokidar": "^2.0.3", + "colors": "^1.1.0", + "connect": "^3.6.0", + "core-js": "^2.2.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.0", + "flatted": "^2.0.0", + "glob": "^7.1.1", + "graceful-fs": "^4.1.2", + "http-proxy": "^1.13.0", + "isbinaryfile": "^3.0.0", + "lodash": "^4.17.11", + "log4js": "^4.0.0", + "mime": "^2.3.1", + "minimatch": "^3.0.2", + "optimist": "^0.6.1", + "qjobs": "^1.1.4", + "range-parser": "^1.2.0", + "rimraf": "^2.6.0", + "safe-buffer": "^5.0.1", + "socket.io": "2.1.1", + "source-map": "^0.6.1", + "tmp": "0.0.33", + "useragent": "2.3.0" + }, + "dependencies": { + "bluebird": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.4.tgz", + "integrity": "sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw==", + "dev": true + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "mime": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.3.tgz", + "integrity": "sha512-QgrPRJfE+riq5TPZMcHZOtm8c6K/yYrMbKIoRfapfiGLxS8OTeIfRhUGW5LU7MlRa52KOAGCfUNruqLrIBvWZw==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "karma-browserify": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/karma-browserify/-/karma-browserify-6.0.0.tgz", + "integrity": "sha512-G3dGjoy1/6P8I6qTp799fbcAxs4P+1JcyEKUzy9g1/xMakqf9FFPwW2T9iEtCbWoH5WIKD3z+YwGL5ysBhzrsg==", + "dev": true, + "requires": { + "convert-source-map": "^1.1.3", + "hat": "^0.0.3", + "js-string-escape": "^1.0.0", + "lodash": "^4.17.10", + "minimatch": "^3.0.0", + "os-shim": "^0.1.3" + } + }, + "karma-chai": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/karma-chai/-/karma-chai-0.1.0.tgz", + "integrity": "sha1-vuWtQEAFF4Ea40u5RfdikJEIt5o=", + "dev": true + }, + "karma-chrome-launcher": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", + "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", + "dev": true, + "requires": { + "fs-access": "^1.0.0", + "which": "^1.2.1" + } + }, + "karma-firefox-launcher": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-1.1.0.tgz", + "integrity": "sha512-LbZ5/XlIXLeQ3cqnCbYLn+rOVhuMIK9aZwlP6eOLGzWdo1UVp7t6CN3DP4SafiRLjexKwHeKHDm0c38Mtd3VxA==", + "dev": true + }, + "karma-ie-launcher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/karma-ie-launcher/-/karma-ie-launcher-1.0.0.tgz", + "integrity": "sha1-SXmGhCxJAZA0bNifVJTKmDDG1Zw=", + "dev": true, + "requires": { + "lodash": "^4.6.1" + } + }, + "karma-jasmine": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-2.0.1.tgz", + "integrity": "sha512-iuC0hmr9b+SNn1DaUD2QEYtUxkS1J+bSJSn7ejdEexs7P8EYvA1CWkEdrDQ+8jVH3AgWlCNwjYsT1chjcNW9lA==", + "dev": true, + "requires": { + "jasmine-core": "^3.3" + } + }, + "karma-mocha": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-1.3.0.tgz", + "integrity": "sha1-7qrH/8DiAetjxGdEDStpx883eL8=", + "dev": true, + "requires": { + "minimist": "1.2.0" + } + }, + "karma-mocha-reporter": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz", + "integrity": "sha1-FRIAlejtgZGG5HoLAS8810GJVWA=", + "dev": true, + "requires": { + "chalk": "^2.1.0", + "log-symbols": "^2.1.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + } + } + }, + "karma-phantomjs-launcher": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/karma-phantomjs-launcher/-/karma-phantomjs-launcher-1.0.4.tgz", + "integrity": "sha1-0jyjSAG9qYY60xjju0vUBisTrNI=", + "dev": true, + "requires": { + "lodash": "^4.0.1", + "phantomjs-prebuilt": "^2.1.7" + } + }, + "karma-spec-reporter": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/karma-spec-reporter/-/karma-spec-reporter-0.0.32.tgz", + "integrity": "sha1-LpxyB+pyZ3EmAln4K+y1QyCeRAo=", + "dev": true, + "requires": { + "colors": "^1.1.2" + } + }, + "kew": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", + "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } + }, + "labeled-stream-splicer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz", + "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "isarray": "^2.0.4", + "stream-splicer": "^2.0.0" + }, + "dependencies": { + "isarray": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", + "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==", + "dev": true + } + } + }, + "last-run": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", + "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=", + "dev": true, + "requires": { + "default-resolution": "^2.0.0", + "es6-weak-map": "^2.0.1" + }, + "dependencies": { + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "^0.10.9" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.14", + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" + } + } + } + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dev": true, + "requires": { + "readable-stream": "^2.0.5" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "lead": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", + "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", + "dev": true, + "requires": { + "flush-write-stream": "^1.0.2" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "liftoff": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", + "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", + "dev": true, + "requires": { + "extend": "^3.0.0", + "findup-sync": "^3.0.0", + "fined": "^1.0.1", + "flagged-respawn": "^1.0.0", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.0", + "rechoir": "^0.6.2", + "resolve": "^1.1.7" + } + }, + "linkify-it": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.1.0.tgz", + "integrity": "sha512-4REs8/062kV2DSHxNfq5183zrqXMl7WP0WzABH9IeJI+NLm429FgE1PDecltYfnOoFDFlZGh2T8PfZn0r+GTRg==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + }, + "dependencies": { + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + } + } + } + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=", + "dev": true + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", + "dev": true + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", + "dev": true + }, + "lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", + "dev": true + }, + "lodash.mergewith": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", + "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", + "dev": true + }, + "log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "dev": true, + "requires": { + "chalk": "^1.0.0" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "log4js": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-4.3.0.tgz", + "integrity": "sha512-ivqZBkBvWLJ8rXfhb4E0979olSwnYBPSZy/5WhLNXwntqRgUhxHnqcXGmVw0t+XmLNTr3GAWEzjqHMzu4KM7rA==", + "dev": true, + "requires": { + "date-format": "^2.0.0", + "debug": "^4.1.1", + "flatted": "^2.0.0", + "rfdc": "^1.1.2", + "streamroller": "^1.0.5" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "make-error-cause": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz", + "integrity": "sha1-3wOI/NCzeBbf8KX7gQiTl3fcvJ0=", + "dev": true, + "requires": { + "make-error": "^1.2.0" + } + }, + "make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "markdown-it": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", + "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "entities": "~1.1.1", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + }, + "markdown-it-anchor": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.0.2.tgz", + "integrity": "sha512-AFM/woBI8QDJMS/9+MmsBMT5/AR+ImfOsunQZTZhzcTmna3rIzAzbOh5E0l6mlFM/i9666BpUtkqQ9bS7WApCg==", + "dev": true + }, + "marked": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.6.2.tgz", + "integrity": "sha512-LqxwVH3P/rqKX4EKGz7+c2G9r98WeM/SW34ybhgNGhUQNKtf1GmmSkJ6cDGJ/t6tiyae49qRkpyTw2B9HOrgUA==", + "dev": true + }, + "matchdep": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", + "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=", + "dev": true, + "requires": { + "findup-sync": "^2.0.0", + "micromatch": "^3.0.4", + "resolve": "^1.4.0", + "stack-trace": "0.0.10" + }, + "dependencies": { + "findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + }, + "dependencies": { + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + } + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, + "merge2": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz", + "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "dev": true + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "dev": true, + "requires": { + "mime-db": "1.40.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, + "mocha": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.1.4.tgz", + "integrity": "sha512-PN8CIy4RXsIoxoFJzS4QNnCH4psUCPWc4/rPrst/ecSJJbLBkubMiyGCP2Kj/9YnWbotFqAoeXyXMucj7gwCFg==", + "dev": true, + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "2.2.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "ms": "2.1.1", + "node-environment-flags": "1.0.5", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.2.2", + "yargs-parser": "13.0.0", + "yargs-unparser": "1.5.0" + }, + "dependencies": { + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + } + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz", + "integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.0.0" + } + }, + "yargs-parser": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz", + "integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "module-deps": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.0.tgz", + "integrity": "sha512-hKPmO06so6bL/ZvqVNVqdTVO8UAYsi3tQWlCa+z9KuWhoN4KDQtb5hcqQQv58qYiDE21wIvnttZEPiDgEbpwbA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "browser-resolve": "^1.7.0", + "cached-path-relative": "^1.0.0", + "concat-stream": "~1.6.0", + "defined": "^1.0.0", + "detective": "^5.0.2", + "duplexer2": "^0.1.2", + "inherits": "^2.0.1", + "parents": "^1.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.4.0", + "stream-combiner2": "^1.1.1", + "subarg": "^1.0.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mute-stdout": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", + "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-environment-flags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", + "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "now-and-later": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", + "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", + "dev": true, + "requires": { + "once": "^1.3.2" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "null-check": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", + "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, + "requires": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "object.fromentries": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz", + "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.11.0", + "function-bind": "^1.1.1", + "has": "^1.0.1" + } + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "object.reduce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", + "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=", + "dev": true, + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + } + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "^1.0.0" + } + }, + "os-shim": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", + "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "outpipe": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/outpipe/-/outpipe-1.1.1.tgz", + "integrity": "sha1-UM+GFjZeh+Ax4ppeyTOaPaRyX6I=", + "dev": true, + "requires": { + "shell-quote": "^1.4.2" + } + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pako": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", + "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "dev": true, + "requires": { + "path-platform": "~0.11.15" + } + }, + "parse-asn1": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", + "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", + "dev": true + }, + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "requires": { + "path-root-regex": "^0.1.0" + } + }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "phantomjs-prebuilt": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz", + "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=", + "dev": true, + "requires": { + "es6-promise": "^4.0.3", + "extract-zip": "^1.6.5", + "fs-extra": "^1.0.0", + "hasha": "^2.2.0", + "kew": "^0.7.0", + "progress": "^1.1.8", + "request": "^2.81.0", + "request-progress": "^2.0.1", + "which": "^1.2.10" + }, + "dependencies": { + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + } + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "plugin-error": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", + "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", + "dev": true, + "requires": { + "ansi-colors": "^1.0.1", + "arr-diff": "^4.0.0", + "arr-union": "^3.1.0", + "extend-shallow": "^3.0.2" + } + }, + "plur": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", + "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", + "dev": true, + "requires": { + "irregular-plurals": "^1.0.0" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "postcss": { + "version": "7.0.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", + "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "proxy-addr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "dev": true, + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + } + } + }, + "react-is": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", + "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==", + "dev": true + }, + "read-only-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", + "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "dependencies": { + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, + "remove-bom-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", + "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5", + "is-utf8": "^0.2.1" + } + }, + "remove-bom-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", + "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", + "dev": true, + "requires": { + "remove-bom-buffer": "^3.0.0", + "safe-buffer": "^5.1.0", + "through2": "^2.0.3" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true + }, + "replace-homedir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", + "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1", + "is-absolute": "^1.0.0", + "remove-trailing-separator": "^1.1.0" + } + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + } + } + }, + "request-progress": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", + "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=", + "dev": true, + "requires": { + "throttleit": "^1.0.0" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "requirejs": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz", + "integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "requizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.2.tgz", + "integrity": "sha512-oJ6y7JcUJkblRGhMByGNcszeLgU0qDxNKFCiUZR1XyzHyVsev+Mxb1tyygxLd1ORsKee1SA5BInFdUwY64GE/A==", + "dev": true, + "requires": { + "lodash": "^4.17.11" + }, + "dependencies": { + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + } + } + }, + "resolve": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", + "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "resolve-options": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", + "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", + "dev": true, + "requires": { + "value-or-function": "^3.0.0" + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rfdc": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.4.tgz", + "integrity": "sha512-5C9HXdzK8EAqN7JDif30jqsBzavB7wLpaubisuQIGHWf2gUXSpzy6ArX/+Da8RjFpagWsCn+pIgxTMAmKw9Zug==", + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", + "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sanitize-html": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.20.1.tgz", + "integrity": "sha512-txnH8TQjaQvg2Q0HY06G6CDJLVYCpbnxrdO0WN8gjCKaU5J0KbyGYhZxx5QJg3WLZ1lB7XU9kDkfrCXUozqptA==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "htmlparser2": "^3.10.0", + "lodash.clonedeep": "^4.5.0", + "lodash.escaperegexp": "^4.1.2", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.mergewith": "^4.6.1", + "postcss": "^7.0.5", + "srcset": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + }, + "semver-greatest-satisfied-range": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", + "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=", + "dev": true, + "requires": { + "sver-compat": "^1.5.0" + } + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shasum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", + "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", + "dev": true, + "requires": { + "json-stable-stringify": "~0.0.0", + "sha.js": "~2.4.4" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shell-quote": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", + "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", + "dev": true, + "requires": { + "array-filter": "~0.0.0", + "array-map": "~0.0.0", + "array-reduce": "~0.0.0", + "jsonify": "~0.0.0" + } + }, + "shelljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", + "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", + "dev": true + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + } + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "socket.io": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz", + "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==", + "dev": true, + "requires": { + "debug": "~3.1.0", + "engine.io": "~3.2.0", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.1.1", + "socket.io-parser": "~3.2.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "socket.io-adapter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", + "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=", + "dev": true + }, + "socket.io-client": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", + "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==", + "dev": true, + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "engine.io-client": "~3.2.0", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.2.0", + "to-array": "0.1.4" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "socket.io-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", + "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "sparkles": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", + "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", + "dev": true + }, + "spdx-correct": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", + "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", + "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", + "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "srcset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/srcset/-/srcset-1.0.0.tgz", + "integrity": "sha1-pWad4StC87HV6D7QPHEEb8SPQe8=", + "dev": true, + "requires": { + "array-uniq": "^1.0.2", + "number-is-nan": "^1.0.0" + } + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "requires": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "stream-exhaust": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", + "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", + "dev": true + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "dev": true + }, + "stream-splicer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", + "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" + } + }, + "streamroller": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-1.0.5.tgz", + "integrity": "sha512-iGVaMcyF5PcUY0cPbW3xFQUXnr9O4RZXNBBjhuLZgrjLO4XCLLGfx4T2sGqygSeylUjwgWRsnNbT9aV0Zb8AYw==", + "dev": true, + "requires": { + "async": "^2.6.2", + "date-format": "^2.0.0", + "debug": "^3.2.6", + "fs-extra": "^7.0.1", + "lodash": "^4.17.11" + }, + "dependencies": { + "async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "dev": true, + "requires": { + "lodash": "^4.17.11" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "string-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", + "integrity": "sha1-VpcPscOFWOnnC3KL894mmsRa36w=", + "dev": true, + "requires": { + "strip-ansi": "^3.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + } + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "subarg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", + "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", + "dev": true, + "requires": { + "minimist": "^1.1.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "sver-compat": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", + "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=", + "dev": true, + "requires": { + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" + } + }, + "syntax-error": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", + "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", + "dev": true, + "requires": { + "acorn-node": "^1.2.0" + } + }, + "table": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/table/-/table-5.3.3.tgz", + "integrity": "sha512-3wUNCgdWX6PNpOe3amTTPWPuF6VGvgzjKCaO1snFj0z7Y3mUPWf5+zDtxUVGispJkDECPmR29wbzh6bVMOHbcw==", + "dev": true, + "requires": { + "ajv": "^6.9.1", + "lodash": "^4.17.11", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "taffydb": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", + "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", + "dev": true + }, + "ternary-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ternary-stream/-/ternary-stream-2.0.1.tgz", + "integrity": "sha1-Bk5Im0tb9gumpre8fy9cJ07Pgmk=", + "dev": true, + "requires": { + "duplexify": "^3.5.0", + "fork-stream": "^0.0.4", + "merge-stream": "^1.0.0", + "through2": "^2.0.1" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "throttleit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", + "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + } + }, + "time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", + "dev": true + }, + "timers-browserify": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", + "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", + "dev": true, + "requires": { + "process": "~0.11.0" + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", + "dev": true + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "to-through": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", + "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", + "dev": true, + "requires": { + "through2": "^2.0.3" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, + "tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, + "uglify-es": { + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", + "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==", + "dev": true, + "requires": { + "commander": "~2.13.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", + "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true + }, + "umd": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", + "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", + "dev": true + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, + "undeclared-identifiers": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz", + "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==", + "dev": true, + "requires": { + "acorn-node": "^1.3.0", + "dash-ast": "^1.0.0", + "get-assigned-identifiers": "^1.2.0", + "simple-concat": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "underscore": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", + "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==", + "dev": true + }, + "undertaker": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz", + "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1", + "arr-map": "^2.0.0", + "bach": "^1.0.0", + "collection-map": "^1.0.0", + "es6-weak-map": "^2.0.1", + "last-run": "^1.1.0", + "object.defaults": "^1.0.0", + "object.reduce": "^1.0.0", + "undertaker-registry": "^1.0.0" + }, + "dependencies": { + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "^0.10.9" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.14", + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" + } + } + } + }, + "undertaker-registry": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", + "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=", + "dev": true + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unique-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "dev": true, + "requires": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + }, + "dependencies": { + "through2-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", + "dev": true, + "requires": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + } + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "upath": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "useragent": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", + "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==", + "dev": true, + "requires": { + "lru-cache": "4.1.x", + "tmp": "0.0.x" + } + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "v8flags": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", + "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "validate-npm-package-license": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", + "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "value-or-function": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", + "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vinyl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "dev": true, + "requires": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + } + }, + "vinyl-fs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", + "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", + "dev": true, + "requires": { + "fs-mkdirp-stream": "^1.0.0", + "glob-stream": "^6.1.0", + "graceful-fs": "^4.0.0", + "is-valid-glob": "^1.0.0", + "lazystream": "^1.0.0", + "lead": "^1.0.0", + "object.assign": "^4.0.4", + "pumpify": "^1.3.5", + "readable-stream": "^2.3.3", + "remove-bom-buffer": "^3.0.0", + "remove-bom-stream": "^1.2.0", + "resolve-options": "^1.1.0", + "through2": "^2.0.0", + "to-through": "^2.0.0", + "value-or-function": "^3.0.0", + "vinyl": "^2.0.0", + "vinyl-sourcemap": "^1.1.0" + }, + "dependencies": { + "is-valid-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", + "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", + "dev": true + } + } + }, + "vinyl-sourcemap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", + "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", + "dev": true, + "requires": { + "append-buffer": "^1.0.2", + "convert-source-map": "^1.5.0", + "graceful-fs": "^4.1.6", + "normalize-path": "^2.1.1", + "now-and-later": "^2.0.0", + "remove-bom-buffer": "^3.0.0", + "vinyl": "^2.0.0" + }, + "dependencies": { + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + } + } + }, + "vinyl-sourcemaps-apply": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", + "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", + "dev": true, + "requires": { + "source-map": "^0.5.1" + } + }, + "vm-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", + "dev": true + }, + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", + "dev": true + }, + "watchify": { + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/watchify/-/watchify-3.11.1.tgz", + "integrity": "sha512-WwnUClyFNRMB2NIiHgJU9RQPQNqVeFk7OmZaWf5dC5EnNa0Mgr7imBydbaJ7tGTuPM2hz1Cb4uiBvK9NVxMfog==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "browserify": "^16.1.0", + "chokidar": "^2.1.1", + "defined": "^1.0.0", + "outpipe": "^1.1.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + }, + "xmlcreate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.1.tgz", + "integrity": "sha512-MjGsXhKG8YjTKrDCXseFo3ClbMGvUD4en29H2Cev1dv4P/chlpw6KdYmlCWDkhosBVKRDjM836+3e3pm1cBNJA==", + "dev": true + }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "13.2.4", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", + "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs-parser": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.0.tgz", + "integrity": "sha512-Yq+32PrijHRri0vVKQEm+ys8mbqWjLiwQkMFNXEENutzLPP0bE4Lcd4iA3OQY5HF+GD3xXxf0MEHb8E4/SA3AA==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "yargs-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "dev": true, + "requires": { + "camelcase": "^3.0.0" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + } + } + }, + "yargs-unparser": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.5.0.tgz", + "integrity": "sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw==", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.11", + "yargs": "^12.0.5" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", + "dev": true + } + } +} diff --git a/package.json b/package.json index 929edce7..9ca045ec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mago3djs", - "version": "1.0.0", + "version": "2.0.0", "description": "Generated with Eclipse npm Tools", "main": "mago3d.js", "scripts": { diff --git a/sample/cesium.html b/sample/cesium.html index 991c3d1d..989815c6 100644 --- a/sample/cesium.html +++ b/sample/cesium.html @@ -13,31 +13,36 @@ + + + -