/** * Cesium - https://github.com/CesiumGS/cesium * * Copyright 2011-2020 Cesium Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Columbus View (Pat. Pend.) * * Portions licensed separately. * See https://github.com/CesiumGS/cesium/blob/master/LICENSE.md for full licensing details. */ define(['exports', './when-8d13db60', './Math-61ede240', './Cartographic-f2a06374', './BoundingSphere-d018a565', './Transforms-cd52cbaf', './EllipsoidTangentPlane-33ed15f1', './PolygonPipeline-01a00202', './PolylinePipeline-f937854b'], function (exports, when, _Math, Cartographic, BoundingSphere, Transforms, EllipsoidTangentPlane, PolygonPipeline, PolylinePipeline) { 'use strict'; /** * private */ var WallGeometryLibrary = {}; function latLonEquals(c0, c1) { return ((_Math.CesiumMath.equalsEpsilon(c0.latitude, c1.latitude, _Math.CesiumMath.EPSILON14)) && (_Math.CesiumMath.equalsEpsilon(c0.longitude, c1.longitude, _Math.CesiumMath.EPSILON14))); } var scratchCartographic1 = new Cartographic.Cartographic(); var scratchCartographic2 = new Cartographic.Cartographic(); function removeDuplicates(ellipsoid, positions, topHeights, bottomHeights) { var length = positions.length; if (length < 2) { return; } var hasBottomHeights = when.defined(bottomHeights); var hasTopHeights = when.defined(topHeights); var hasAllZeroHeights = true; var cleanedPositions = new Array(length); var cleanedTopHeights = new Array(length); var cleanedBottomHeights = new Array(length); var v0 = positions[0]; cleanedPositions[0] = v0; var c0 = ellipsoid.cartesianToCartographic(v0, scratchCartographic1); if (hasTopHeights) { c0.height = topHeights[0]; } hasAllZeroHeights = hasAllZeroHeights && c0.height == 0; cleanedTopHeights[0] = c0.height; if (hasBottomHeights) { cleanedBottomHeights[0] = bottomHeights[0]; } else { cleanedBottomHeights[0] = 0.0; } var index = 1; for (var i = 1; i < length; ++i) { var v1 = positions[i]; var c1 = ellipsoid.cartesianToCartographic(v1, scratchCartographic2); if (hasTopHeights) { c1.height = topHeights[i]; } hasAllZeroHeights = hasAllZeroHeights && c1.height == 0; if (!latLonEquals(c0, c1)) { cleanedPositions[index] = v1; // Shallow copy! cleanedTopHeights[index] = c1.height; if (hasBottomHeights) { cleanedBottomHeights[index] = bottomHeights[i]; } else { cleanedBottomHeights[index] = 0.0; } Cartographic.Cartographic.clone(c1, c0); ++index; } else if (c0.height < c1.height) { cleanedTopHeights[index - 1] = c1.height; } } if (hasAllZeroHeights || index < 2) { return; } cleanedPositions.length = index; cleanedTopHeights.length = index; cleanedBottomHeights.length = index; return { positions: cleanedPositions, topHeights: cleanedTopHeights, bottomHeights: cleanedBottomHeights }; } var positionsArrayScratch = new Array(2); var heightsArrayScratch = new Array(2); var generateArcOptionsScratch = { positions : undefined, height : undefined, granularity : undefined, ellipsoid : undefined }; /** * @private */ WallGeometryLibrary.computePositions = function(ellipsoid, wallPositions, maximumHeights, minimumHeights, granularity, duplicateCorners, enuCenter) { var o = removeDuplicates(ellipsoid, wallPositions, maximumHeights, minimumHeights); if (!when.defined(o)) { return; } var enu = Transforms.Transforms.eastNorthUpToFixedFrame(o.positions[0], ellipsoid, new BoundingSphere.Matrix4()); var enuInverse = BoundingSphere.Matrix4.inverse(enu, new BoundingSphere.Matrix4()); wallPositions = o.positions; maximumHeights = o.topHeights; minimumHeights = o.bottomHeights; if (wallPositions.length >= 3) { // Order positions counter-clockwise var tangentPlane = EllipsoidTangentPlane.EllipsoidTangentPlane.fromPoints(wallPositions, ellipsoid); var positions2D = tangentPlane.projectPointsOntoPlane(wallPositions); if (PolygonPipeline.PolygonPipeline.computeWindingOrder2D(positions2D) === PolygonPipeline.WindingOrder.CLOCKWISE) { wallPositions.reverse(); maximumHeights.reverse(); minimumHeights.reverse(); } } var length = wallPositions.length; var numCorners = length - 2; var topPositions; var bottomPositions; var localTopPositions; var localBottomPositions; var minDistance = _Math.CesiumMath.chordLength(granularity, ellipsoid.maximumRadius); var generateArcOptions = generateArcOptionsScratch; generateArcOptions.minDistance = minDistance; generateArcOptions.ellipsoid = ellipsoid; if (duplicateCorners) { var count = 0; var i; for (i = 0; i < length - 1; i++) { count += PolylinePipeline.PolylinePipeline.numberOfPoints(wallPositions[i], wallPositions[i+1], minDistance) + 1; } topPositions = new Float64Array(count * 3); bottomPositions = new Float64Array(count * 3); if(when.defined(enuCenter)) { localTopPositions = new Float64Array(count * 3); localBottomPositions = new Float64Array(count * 3); } var generateArcPositions = positionsArrayScratch; var generateArcHeights = heightsArrayScratch; generateArcOptions.positions = generateArcPositions; generateArcOptions.height = generateArcHeights; var offset = 0; for (i = 0; i < length - 1; i++) { generateArcPositions[0] = wallPositions[i]; generateArcPositions[1] = wallPositions[i + 1]; generateArcHeights[0] = maximumHeights[i]; generateArcHeights[1] = maximumHeights[i + 1]; var pos = PolylinePipeline.PolylinePipeline.generateArc(generateArcOptions); topPositions.set(pos, offset); if(when.defined(enuCenter)) { localTopPositions.set(transformToENU(pos, enuInverse), offset); } generateArcHeights[0] = minimumHeights[i]; generateArcHeights[1] = minimumHeights[i + 1]; bottomPositions.set(PolylinePipeline.PolylinePipeline.generateArc(generateArcOptions), offset); if(when.defined(enuCenter)) { localBottomPositions.set(transformToENU(PolylinePipeline.PolylinePipeline.generateArc(generateArcOptions), enuInverse), offset); } offset += pos.length; } } else { generateArcOptions.positions = wallPositions; generateArcOptions.height = maximumHeights; topPositions = new Float64Array(PolylinePipeline.PolylinePipeline.generateArc(generateArcOptions)); if(when.defined(enuCenter)) { localTopPositions = new Float64Array(transformToENU(PolylinePipeline.PolylinePipeline.generateArc(generateArcOptions))); } generateArcOptions.height = minimumHeights; bottomPositions = new Float64Array(PolylinePipeline.PolylinePipeline.generateArc(generateArcOptions)); if(when.defined(enuCenter)) { localBottomPositions = new Float64Array(transformToENU(PolylinePipeline.PolylinePipeline.generateArc(generateArcOptions))); } } var posObj = { pos: { bottomPositions: bottomPositions, topPositions: topPositions, numCorners: numCorners } }; if(when.defined(enuCenter)) { posObj.localPos = { bottomPositions: localBottomPositions, topPositions: localTopPositions, numCorners: numCorners }; } return posObj; }; function transformToENU(pos, enuInverse) { var localPos = new Array(pos.length); for(var j = 0; j < pos.length; j += 3) { var cartesian = new Cartographic.Cartesian3(pos[j], pos[j + 1], pos[j + 2]); BoundingSphere.Matrix4.multiplyByPoint(enuInverse, cartesian, cartesian); localPos[j] = cartesian.x; localPos[j + 1] = cartesian.y; localPos[j + 2] = cartesian.z; } return localPos; } exports.WallGeometryLibrary = WallGeometryLibrary; });