From 709048c46a1eb22cb62c78075e774cfa08f48dcf Mon Sep 17 00:00:00 2001 From: hpinkos Date: Mon, 26 Aug 2013 17:50:34 -0400 Subject: [PATCH 1/9] init outline --- Source/Core/CorridorGeometry.js | 167 ++------- Source/Core/CorridorGeometryLibrary.js | 167 +++++++++ Source/Core/CorridorOutlineGeometry.js | 455 +++++++++++++++++++++++++ 3 files changed, 651 insertions(+), 138 deletions(-) create mode 100644 Source/Core/CorridorGeometryLibrary.js create mode 100644 Source/Core/CorridorOutlineGeometry.js diff --git a/Source/Core/CorridorGeometry.js b/Source/Core/CorridorGeometry.js index 08fa9d747915..c4b14420cd13 100644 --- a/Source/Core/CorridorGeometry.js +++ b/Source/Core/CorridorGeometry.js @@ -5,6 +5,7 @@ define([ './Cartesian2', './Cartesian3', './CornerType', + './CorridorGeometryLibrary', './ComponentDatatype', './Ellipsoid', './EllipsoidTangentPlane', @@ -26,6 +27,7 @@ define([ Cartesian2, Cartesian3, CornerType, + CorridorGeometryLibrary, ComponentDatatype, Ellipsoid, EllipsoidTangentPlane, @@ -57,135 +59,24 @@ define([ var scratch1= new Cartesian3(); var scratch2 = new Cartesian3(); - var originScratch = new Cartesian2(); - var nextScratch = new Cartesian2(); - var prevScratch = new Cartesian2(); - function angleIsGreaterThanPi (forward, backward, position, ellipsoid) { - var tangentPlane = new EllipsoidTangentPlane(position, ellipsoid); - var origin = tangentPlane.projectPointOntoPlane(position, originScratch); - var next = tangentPlane.projectPointOntoPlane(Cartesian3.add(position, forward, nextScratch), nextScratch); - var prev = tangentPlane.projectPointOntoPlane(Cartesian3.add(position, backward, prevScratch), prevScratch); - - prev = prev.subtract(origin, prev); - next = next.subtract(origin, next); - - return ((prev.x * next.y) - (prev.y * next.x)) >= 0.0; - } - - function addAttribute(attribute, value, front, back) { - var x = value.x; - var y = value.y; - var z = value.z; - if (defined(front)) { - attribute[front] = x; - attribute[front+1] = y; - attribute[front+2] = z; - } - if (defined(back)) { - attribute[back] = z; - attribute[back-1] = y; - attribute[back-2] = x; - } - - return attribute; - } - function addNormals(attr, normal, left, front, back, vertexFormat) { var normals = attr.normals; var tangents = attr.tangents; var binormals = attr.binormals; var forward = Cartesian3.cross(left, normal, scratch1).normalize(scratch1); if (vertexFormat.normal) { - normals = addAttribute(normals, normal, front, back); + normals = CorridorGeometryLibrary.addAttribute(normals, normal, front, back); } if (vertexFormat.tangent) { - tangents = addAttribute(tangents, left, front, back); + tangents = CorridorGeometryLibrary.addAttribute(tangents, left, front, back); } if (vertexFormat.binormal) { - binormals = addAttribute(binormals, forward, front, back); + binormals = CorridorGeometryLibrary.addAttribute(binormals, forward, front, back); } return attr; } - var quaterion = new Quaternion(); - var rotMatrix = new Matrix3(); - function computeRoundCorner(cornerPoint, startPoint, endPoint, cornerType, leftIsOutside) { - var angle = Cartesian3.angleBetween(startPoint.subtract(cornerPoint, scratch1), endPoint.subtract(cornerPoint, scratch2)); - var granularity = (cornerType.value === CornerType.BEVELED.value) ? 0 : Math.ceil(angle/CesiumMath.toRadians(5)); - - var size = (granularity + 1)*3; - var array = new Array(size); - - array[size - 3] = endPoint.x; - array[size - 2] = endPoint.y; - array[size - 1] = endPoint.z; - - var m; - if (leftIsOutside) { - m = Matrix3.fromQuaternion(Quaternion.fromAxisAngle(cornerPoint, angle/(granularity+1), quaterion), rotMatrix); - } else { - m = Matrix3.fromQuaternion(Quaternion.fromAxisAngle(cornerPoint.negate(scratch1), angle/(granularity+1), quaterion), rotMatrix); - } - - var index = 0; - startPoint = startPoint.clone(scratch1); - for (var i = 0; i < granularity + 1; i++) { - startPoint = m.multiplyByVector(startPoint, startPoint); - array[index++] = startPoint.x; - array[index++] = startPoint.y; - array[index++] = startPoint.z; - } - - if (leftIsOutside) { - return { - leftPositions: array - }; - } - return { - rightPositions: array - }; - } - - function addEndCaps(calculatedPositions, width) { - var cornerPoint = cartesian1; - var startPoint = cartesian2; - var endPoint = cartesian3; - - var leftEdge = calculatedPositions[1]; - startPoint = Cartesian3.fromArray(calculatedPositions[1], leftEdge.length - 3, startPoint); - endPoint = Cartesian3.fromArray(calculatedPositions[0], 0, endPoint); - cornerPoint = startPoint.add(endPoint, cornerPoint).multiplyByScalar(0.5, cornerPoint); - var firstEndCap = computeRoundCorner(cornerPoint, startPoint, endPoint, false, false); - - var length = calculatedPositions.length - 1; - var rightEdge = calculatedPositions[length - 1]; - leftEdge = calculatedPositions[length]; - startPoint = Cartesian3.fromArray(rightEdge, rightEdge.length - 3, startPoint); - endPoint = Cartesian3.fromArray(leftEdge, 0, endPoint); - cornerPoint = startPoint.add(endPoint, cornerPoint).multiplyByScalar(0.5, cornerPoint); - var lastEndCap = computeRoundCorner(cornerPoint, startPoint, endPoint, false, false); - - return [firstEndCap, lastEndCap]; - } - - function computeMiteredCorner(position, leftCornerDirection, lastPoint, leftIsOutside) { - if (leftIsOutside) { - var leftPos = Cartesian3.add(position, leftCornerDirection); - var leftArray = [leftPos.x, leftPos.y, leftPos.z, lastPoint.x, lastPoint.y, lastPoint.z]; - return { - leftPositions: leftArray - }; - } - - leftCornerDirection = leftCornerDirection.negate(leftCornerDirection); - var rightPos = Cartesian3.add(position, leftCornerDirection); - var rightArray = [rightPos.x, rightPos.y, rightPos.z, lastPoint.x, lastPoint.y, lastPoint.z]; - return { - rightPositions: rightArray - }; - } - function combine(positions, corners, computedLefts, computedNormals, vertexFormat, endPositions, ellipsoid) { var attributes = new GeometryAttributes(); var corner; @@ -243,8 +134,8 @@ define([ for (i = 0; i < halfLength; i++) { leftPos = Cartesian3.fromArray(firstEndPositions, (halfLength - 1 - i) * 3, leftPos); rightPos = Cartesian3.fromArray(firstEndPositions, (halfLength + i) * 3, rightPos); - finalPositions = addAttribute(finalPositions, rightPos, front); - finalPositions = addAttribute(finalPositions, leftPos, undefined, back); + finalPositions = CorridorGeometryLibrary.addAttribute(finalPositions, rightPos, front); + finalPositions = CorridorGeometryLibrary.addAttribute(finalPositions, leftPos, undefined, back); attr = addNormals(attr, normal, left, front, back, vertexFormat); LL = front/3; @@ -306,7 +197,7 @@ define([ for (j = 0; j < l.length/3; j++) { outsidePoint = Cartesian3.fromArray(l, j*3, outsidePoint); indices.push(pivot, start - j - 1, start - j); - finalPositions = addAttribute(finalPositions, outsidePoint, undefined, back); + finalPositions = CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, undefined, back); previousPoint = Cartesian3.fromArray(finalPositions, (start - j - 1)*3, previousPoint); nextPoint = Cartesian3.fromArray(finalPositions, pivot*3, nextPoint); left = previousPoint.subtract(nextPoint, left).normalize(left); @@ -327,7 +218,7 @@ define([ for (j = 0; j < r.length/3; j++) { outsidePoint = Cartesian3.fromArray(r, j*3, outsidePoint); indices.push(pivot, start + j, start + j + 1); - finalPositions = addAttribute(finalPositions, outsidePoint, front); + finalPositions = CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, front); previousPoint = Cartesian3.fromArray(finalPositions, pivot*3, previousPoint); nextPoint = Cartesian3.fromArray(finalPositions, (start + j)*3, nextPoint); left = previousPoint.subtract(nextPoint, left).normalize(left); @@ -380,8 +271,8 @@ define([ for (i = 0; i < halfLength; i++) { leftPos = Cartesian3.fromArray(lastEndPositions, (endPositionLength - i - 1) * 3, leftPos); rightPos = Cartesian3.fromArray(lastEndPositions, i * 3, rightPos); - finalPositions = addAttribute(finalPositions, leftPos, undefined, back); - finalPositions = addAttribute(finalPositions, rightPos, front); + finalPositions = CorridorGeometryLibrary.addAttribute(finalPositions, leftPos, undefined, back); + finalPositions = CorridorGeometryLibrary.addAttribute(finalPositions, rightPos, front); attr = addNormals(attr, normal, left, front, back, vertexFormat); LR = front/3; @@ -539,7 +430,7 @@ define([ cornerDirection = cornerDirection.cross(normal, cornerDirection); cornerDirection = normal.cross(cornerDirection, cornerDirection); var scalar = width / Math.max(0.25, (Cartesian3.cross(cornerDirection, backward, scratch1).magnitude())); - var leftIsOutside = angleIsGreaterThanPi(forward, backward, position, ellipsoid); + var leftIsOutside = CorridorGeometryLibrary.angleIsGreaterThanPi(forward, backward, position, ellipsoid); cornerDirection = cornerDirection.multiplyByScalar(scalar, cornerDirection, cornerDirection); if (leftIsOutside) { rightPos = Cartesian3.add(position, cornerDirection, rightPos); @@ -552,9 +443,9 @@ define([ left = normal.cross(forward, left).normalize(left); leftPos = rightPos.add(left.multiplyByScalar(width*2, leftPos), leftPos); if (cornerType.value === CornerType.ROUNDED.value || cornerType.value === CornerType.BEVELED.value) { - corners.push(computeRoundCorner(rightPos, startPoint, leftPos, cornerType, leftIsOutside)); + corners.push(CorridorGeometryLibrary.computeRoundCorner(rightPos, startPoint, leftPos, cornerType, leftIsOutside, ellipsoid)); } else { - corners.push(computeMiteredCorner(position, cornerDirection.negate(cornerDirection), leftPos, leftIsOutside)); + corners.push(CorridorGeometryLibrary.computeMiteredCorner(position, startPoint, cornerDirection.negate(cornerDirection), leftPos, leftIsOutside, granularity, ellipsoid)); } previousRightPos = rightPos.clone(previousRightPos); previousLeftPos = leftPos.clone(previousLeftPos); @@ -569,9 +460,9 @@ define([ left = normal.cross(forward, left).normalize(left); rightPos = leftPos.add(left.multiplyByScalar(width*2, rightPos).negate(rightPos), rightPos); if (cornerType.value === CornerType.ROUNDED.value || cornerType.value === CornerType.BEVELED.value) { - corners.push(computeRoundCorner(leftPos, startPoint, rightPos, cornerType, leftIsOutside)); + corners.push(CorridorGeometryLibrary.computeRoundCorner(leftPos, startPoint, rightPos, cornerType, leftIsOutside, ellipsoid)); } else { - corners.push(computeMiteredCorner(position, cornerDirection, rightPos, leftIsOutside)); + corners.push(CorridorGeometryLibrary.computeMiteredCorner(position, startPoint, cornerDirection, rightPos, leftIsOutside, granularity, ellipsoid)); } previousRightPos = rightPos.clone(previousRightPos); previousLeftPos = leftPos.clone(previousLeftPos); @@ -591,7 +482,7 @@ define([ var endPositions; if (cornerType.value === CornerType.ROUNDED.value) { - endPositions = addEndCaps(calculatedPositions, width); + endPositions = CorridorGeometryLibrary.addEndCaps(calculatedPositions, width, ellipsoid); } return combine(calculatedPositions, corners, calculatedLefts, calculatedNormals, params.vertexFormat, endPositions, ellipsoid); @@ -642,26 +533,26 @@ define([ previousPosition = previousPosition.subtract(topPosition, previousPosition); normal = bottomPosition.cross(previousPosition, normal).normalize(normal); if (vertexFormat.normal) { - normals = addAttribute(normals, normal, attrIndexOffset); - normals = addAttribute(normals, normal, attrIndexOffset + 3); - normals = addAttribute(normals, normal, attrIndex); - normals = addAttribute(normals, normal, attrIndex + 3); + normals = CorridorGeometryLibrary.addAttribute(normals, normal, attrIndexOffset); + normals = CorridorGeometryLibrary.addAttribute(normals, normal, attrIndexOffset + 3); + normals = CorridorGeometryLibrary.addAttribute(normals, normal, attrIndex); + normals = CorridorGeometryLibrary.addAttribute(normals, normal, attrIndex + 3); } if (vertexFormat.tangent || vertexFormat.binormal) { tangent = Cartesian3.fromArray(topNormals, i, tangent); if (vertexFormat.tangent) { - tangents = addAttribute(tangents, tangent, attrIndexOffset); - tangents = addAttribute(tangents, tangent, attrIndexOffset + 3); - tangents = addAttribute(tangents, tangent, attrIndex); - tangents = addAttribute(tangents, tangent, attrIndex + 3); + tangents = CorridorGeometryLibrary.addAttribute(tangents, tangent, attrIndexOffset); + tangents = CorridorGeometryLibrary.addAttribute(tangents, tangent, attrIndexOffset + 3); + tangents = CorridorGeometryLibrary.addAttribute(tangents, tangent, attrIndex); + tangents = CorridorGeometryLibrary.addAttribute(tangents, tangent, attrIndex + 3); } if (vertexFormat.binormal) { binormal = tangent.cross(normal, binormal).normalize(binormal); - binormals = addAttribute(binormals, binormal, attrIndexOffset); - binormals = addAttribute(binormals, binormal, attrIndexOffset + 3); - binormals = addAttribute(binormals, binormal, attrIndex); - binormals = addAttribute(binormals, binormal, attrIndex + 3); + binormals = CorridorGeometryLibrary.addAttribute(binormals, binormal, attrIndexOffset); + binormals = CorridorGeometryLibrary.addAttribute(binormals, binormal, attrIndexOffset + 3); + binormals = CorridorGeometryLibrary.addAttribute(binormals, binormal, attrIndex); + binormals = CorridorGeometryLibrary.addAttribute(binormals, binormal, attrIndex + 3); } } attrIndex += 6; diff --git a/Source/Core/CorridorGeometryLibrary.js b/Source/Core/CorridorGeometryLibrary.js new file mode 100644 index 000000000000..c473fe20e9ab --- /dev/null +++ b/Source/Core/CorridorGeometryLibrary.js @@ -0,0 +1,167 @@ +/*global define*/ +define([ + './defined', + './Cartesian2', + './Cartesian3', + './CornerType', + './EllipsoidTangentPlane', + './Matrix3', + './Quaternion', + './PolylinePipeline', + './Math' + ], function( + defined, + Cartesian2, + Cartesian3, + CornerType, + EllipsoidTangentPlane, + Matrix3, + Quaternion, + PolylinePipeline, + CesiumMath) { + "use strict"; + + /** + * private + */ + var CorridorGeometryLibrary = {}; + + var posScratch = new Cartesian3(); + function scaleToSurface (positions, ellipsoid){ + for (var i = 0; i < positions.length; i += 3) { + posScratch = Cartesian3.fromArray(positions, i, posScratch); + posScratch = ellipsoid.scaleToGeodeticSurface(posScratch, posScratch); + positions[i] = posScratch.x; + positions[i + 1] = posScratch.y; + positions[i + 2] = posScratch.z; + } + + return positions; + } + + + var originScratch = new Cartesian2(); + var nextScratch = new Cartesian2(); + var prevScratch = new Cartesian2(); + CorridorGeometryLibrary.angleIsGreaterThanPi = function (forward, backward, position, ellipsoid) { + var tangentPlane = new EllipsoidTangentPlane(position, ellipsoid); + var origin = tangentPlane.projectPointOntoPlane(position, originScratch); + var next = tangentPlane.projectPointOntoPlane(Cartesian3.add(position, forward, nextScratch), nextScratch); + var prev = tangentPlane.projectPointOntoPlane(Cartesian3.add(position, backward, prevScratch), prevScratch); + + prev = prev.subtract(origin, prev); + next = next.subtract(origin, next); + + return ((prev.x * next.y) - (prev.y * next.x)) >= 0.0; + }; + + var quaterion = new Quaternion(); + var rotMatrix = new Matrix3(); + var scratch1 = new Cartesian3(); + var scratch2 = new Cartesian3(); + CorridorGeometryLibrary.computeRoundCorner = function (cornerPoint, startPoint, endPoint, cornerType, leftIsOutside, ellipsoid) { + var angle = Cartesian3.angleBetween(startPoint.subtract(cornerPoint, scratch1), endPoint.subtract(cornerPoint, scratch2)); + var granularity = (cornerType.value === CornerType.BEVELED.value) ? 0 : Math.ceil(angle/CesiumMath.toRadians(5)); + + var size = (granularity + 1)*3; + var array = new Array(size); + + array[size - 3] = endPoint.x; + array[size - 2] = endPoint.y; + array[size - 1] = endPoint.z; + + var m; + if (leftIsOutside) { + m = Matrix3.fromQuaternion(Quaternion.fromAxisAngle(cornerPoint, angle/(granularity+1), quaterion), rotMatrix); + } else { + m = Matrix3.fromQuaternion(Quaternion.fromAxisAngle(cornerPoint.negate(scratch1), angle/(granularity+1), quaterion), rotMatrix); + } + + var index = 0; + startPoint = startPoint.clone(scratch1); + for (var i = 0; i < granularity + 1; i++) { + startPoint = m.multiplyByVector(startPoint, startPoint); + array[index++] = startPoint.x; + array[index++] = startPoint.y; + array[index++] = startPoint.z; + } + array = scaleToSurface(array, ellipsoid); + + if (leftIsOutside) { + return { + leftPositions: array + }; + } + return { + rightPositions: array + }; + }; + + var cartesian1 = new Cartesian3(); + var cartesian2 = new Cartesian3(); + var cartesian3 = new Cartesian3(); + CorridorGeometryLibrary.addEndCaps = function (calculatedPositions, width, ellipsoid) { + var cornerPoint = cartesian1; + var startPoint = cartesian2; + var endPoint = cartesian3; + + var leftEdge = calculatedPositions[1]; + startPoint = Cartesian3.fromArray(calculatedPositions[1], leftEdge.length - 3, startPoint); + endPoint = Cartesian3.fromArray(calculatedPositions[0], 0, endPoint); + cornerPoint = startPoint.add(endPoint, cornerPoint).multiplyByScalar(0.5, cornerPoint); + var firstEndCap = CorridorGeometryLibrary.computeRoundCorner(cornerPoint, startPoint, endPoint, false, false, ellipsoid); + + var length = calculatedPositions.length - 1; + var rightEdge = calculatedPositions[length - 1]; + leftEdge = calculatedPositions[length]; + startPoint = Cartesian3.fromArray(rightEdge, rightEdge.length - 3, startPoint); + endPoint = Cartesian3.fromArray(leftEdge, 0, endPoint); + cornerPoint = startPoint.add(endPoint, cornerPoint).multiplyByScalar(0.5, cornerPoint); + var lastEndCap = CorridorGeometryLibrary.computeRoundCorner(cornerPoint, startPoint, endPoint, false, false, ellipsoid); + + return [firstEndCap, lastEndCap]; + }; + + CorridorGeometryLibrary.computeMiteredCorner = function (position, startPoint, leftCornerDirection, lastPoint, leftIsOutside, granularity, ellipsoid) { + if (leftIsOutside) { + var leftPos = Cartesian3.add(position, leftCornerDirection); + var leftArray = PolylinePipeline.scaleToSurface([startPoint, leftPos, lastPoint], granularity, ellipsoid); + leftArray.shift(); + leftArray.shift(); + leftArray.shift(); + return { + leftPositions: leftArray + }; + } + + leftCornerDirection = leftCornerDirection.negate(leftCornerDirection); + var rightPos = Cartesian3.add(position, leftCornerDirection); + var rightArray = PolylinePipeline.scaleToSurface([startPoint, rightPos, lastPoint], granularity, ellipsoid); + rightArray.shift(); + rightArray.shift(); + rightArray.shift(); + return { + rightPositions: rightArray + }; + }; + + CorridorGeometryLibrary.addAttribute = function (attribute, value, front, back) { + var x = value.x; + var y = value.y; + var z = value.z; + if (defined(front)) { + attribute[front] = x; + attribute[front+1] = y; + attribute[front+2] = z; + } + if (defined(back)) { + attribute[back] = z; + attribute[back-1] = y; + attribute[back-2] = x; + } + + return attribute; + }; + + return CorridorGeometryLibrary; +}); \ No newline at end of file diff --git a/Source/Core/CorridorOutlineGeometry.js b/Source/Core/CorridorOutlineGeometry.js new file mode 100644 index 000000000000..1bc34b4f6527 --- /dev/null +++ b/Source/Core/CorridorOutlineGeometry.js @@ -0,0 +1,455 @@ +/*global define*/ +define([ + './defined', + './DeveloperError', + './Cartesian2', + './Cartesian3', + './CornerType', + './CorridorGeometryLibrary', + './ComponentDatatype', + './Ellipsoid', + './EllipsoidTangentPlane', + './Geometry', + './IndexDatatype', + './Math', + './Matrix3', + './PolylinePipeline', + './PrimitiveType', + './Quaternion', + './defaultValue', + './BoundingSphere', + './GeometryAttribute', + './GeometryAttributes', + './VertexFormat' + ], function( + defined, + DeveloperError, + Cartesian2, + Cartesian3, + CornerType, + CorridorGeometryLibrary, + ComponentDatatype, + Ellipsoid, + EllipsoidTangentPlane, + Geometry, + IndexDatatype, + CesiumMath, + Matrix3, + PolylinePipeline, + PrimitiveType, + Quaternion, + defaultValue, + BoundingSphere, + GeometryAttribute, + GeometryAttributes, + VertexFormat) { + "use strict"; + + var cartesian1 = new Cartesian3(); + var cartesian2 = new Cartesian3(); + var cartesian3 = new Cartesian3(); + var cartesian4 = new Cartesian3(); + var cartesian5 = new Cartesian3(); + var cartesian6 = new Cartesian3(); + var cartesian7 = new Cartesian3(); + var cartesian8 = new Cartesian3(); + var cartesian9 = new Cartesian3(); + var cartesian10 = new Cartesian3(); + + var scratch1= new Cartesian3(); + + function combine(positions, corners, endPositions, ellipsoid) { + var attributes = new GeometryAttributes(); + var corner; + var leftCount = 0; + var rightCount = 0; + var i; + for (i = 0; i < positions.length; i+=2) { + leftCount += positions[i].length - 3; //subtracting 3 to account for duplicate points at corners + rightCount += positions[i+1].length - 3; + } + leftCount += 3; //add back count for end positions + rightCount += 3; + for (i = 0; i < corners.length; i++) { + corner = corners[i]; + var leftSide = corners[i].leftPositions; + if (defined(leftSide)) { + leftCount += leftSide.length; + } else { + rightCount += corners[i].rightPositions.length; + } + } + + var addEndPositions = defined(endPositions); + var endPositionLength; + if (addEndPositions) { + endPositionLength = endPositions[0].rightPositions.length - 3; + leftCount += endPositionLength; + rightCount += endPositionLength; + endPositionLength /= 3; + } + var size = leftCount + rightCount; + var finalPositions = new Float64Array(size); + var front = 0; + var back = size - 1; + var indices = []; + var UL, LL, UR, LR; + var rightPos, leftPos; + var halfLength = endPositionLength/2; + indices.push(front/3, (back-2)/3); + if (addEndPositions) { // add rounded end + leftPos = cartesian3; + rightPos = cartesian4; + var firstEndPositions = endPositions[0].rightPositions; + for (i = 0; i < halfLength; i++) { + leftPos = Cartesian3.fromArray(firstEndPositions, (halfLength - 1 - i) * 3, leftPos); + rightPos = Cartesian3.fromArray(firstEndPositions, (halfLength + i) * 3, rightPos); + finalPositions = CorridorGeometryLibrary.addAttribute(finalPositions, rightPos, front); + finalPositions = CorridorGeometryLibrary.addAttribute(finalPositions, leftPos, undefined, back); + + LL = front/3; + LR = LL + 1; + UL = (back-2)/3; + UR = UL - 1; + indices.push(UL, UR, LL, LR); + front += 3; + back -= 3; + } + } + + var posIndex = 0; + var rightEdge = positions[posIndex++]; //add first two edges + var leftEdge = positions[posIndex++]; + finalPositions.set(rightEdge, front); + finalPositions.set(leftEdge, back - leftEdge.length + 1); + + var length = leftEdge.length - 3; + for(i = 0; i < length; i+=3) { + LL = front/3; + LR = LL + 1; + UL = (back-2)/3; + UR = UL - 1; + indices.push(UL, UR, LL, LR); + front += 3; + back -= 3; + } + + for (i = 0; i < corners.length; i++) { + var j; + corner = corners[i]; + var l = corner.leftPositions; + var r = corner.rightPositions; + var start; + var outsidePoint = cartesian6; + if (defined(l)) { + back -= 3; + start = UR; + for (j = 0; j < l.length/3; j++) { + outsidePoint = Cartesian3.fromArray(l, j*3, outsidePoint); + indices.push(start - j - 1, start - j); + finalPositions = CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, undefined, back); + back -= 3; + } + front += 3; + } else { + front += 3; + start = LR; + for (j = 0; j < r.length/3; j++) { + outsidePoint = Cartesian3.fromArray(r, j*3, outsidePoint); + indices.push(start + j, start + j + 1); + finalPositions = CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, front); + front += 3; + } + back -= 3; + } + rightEdge = positions[posIndex++]; + leftEdge = positions[posIndex++]; + rightEdge.splice(0, 3); //remove duplicate points added by corner + leftEdge.splice(leftEdge.length - 3, 3); + finalPositions.set(rightEdge, front); + finalPositions.set(leftEdge, back - leftEdge.length + 1); + length = leftEdge.length - 3; + + for(j = 0; j < leftEdge.length; j+=3) { + LR = front/3; + LL = LR - 1; + UR = (back-2)/3; + UL = UR + 1; + indices.push(UL, UR, LL, LR); + front += 3; + back -= 3; + } + front -= 3; + back += 3; + } + + if (addEndPositions) { // add rounded end + front += 3; + back -= 3; + leftPos = cartesian3; + rightPos = cartesian4; + var lastEndPositions = endPositions[1].rightPositions; + for (i = 0; i < halfLength; i++) { + leftPos = Cartesian3.fromArray(lastEndPositions, (endPositionLength - i - 1) * 3, leftPos); + rightPos = Cartesian3.fromArray(lastEndPositions, i * 3, rightPos); + finalPositions = CorridorGeometryLibrary.addAttribute(finalPositions, leftPos, undefined, back); + finalPositions = CorridorGeometryLibrary.addAttribute(finalPositions, rightPos, front); + + LR = front/3; + LL = LR - 1; + UR = (back-2)/3; + UL = UR + 1; + indices.push(UL, UR, LL, LR); + front += 3; + back -= 3; + } + } + indices.push(front/3, (back-2)/3); + + attributes.position = new GeometryAttribute({ + componentDatatype : ComponentDatatype.DOUBLE, + componentsPerAttribute : 3, + values : finalPositions + }); + + return { + attributes: attributes, + indices: indices, + boundingSphere: BoundingSphere.fromVertices(finalPositions), + rightCount: rightCount + }; + } + + function computePositions(params) { + var granularity = params.granularity; + var positions = params.positions; + var width = params.width/2; + var ellipsoid = params.ellipsoid; + var cornerType = params.cornerType; + var normal = cartesian1; + var forward = cartesian2; + var backward = cartesian3; + var left = cartesian4; + var cornerDirection = cartesian5; + var startPoint = cartesian6; + var previousLeftPos = cartesian7; + var previousRightPos = cartesian8; + var rightPos = cartesian9; + var leftPos = cartesian10; + var calculatedPositions = []; + var position = positions[0]; //add first point + var nextPosition = positions[1]; + + forward = Cartesian3.subtract(nextPosition, position, forward).normalize(forward); + normal = ellipsoid.geodeticSurfaceNormal(position, normal); + left = normal.cross(forward, left).normalize(left); + previousLeftPos = Cartesian3.add(position, left.multiplyByScalar(width, previousLeftPos), previousLeftPos); + previousRightPos = Cartesian3.add(position, left.multiplyByScalar(width, previousRightPos).negate(previousRightPos), previousRightPos); + position = nextPosition; + backward = forward.negate(backward); + + var corners = []; + var i; + var length = positions.length; + for (i = 1; i < length-1; i++) { // add middle points and corners + normal = ellipsoid.geodeticSurfaceNormal(position, normal); + nextPosition = positions[i+1]; + forward = Cartesian3.subtract(nextPosition, position, forward).normalize(forward); + cornerDirection = forward.add(backward, cornerDirection).normalize(cornerDirection); + var doCorner = !Cartesian3.equalsEpsilon(cornerDirection.negate(scratch1), normal, CesiumMath.EPSILON2); + if (doCorner) { + cornerDirection = cornerDirection.cross(normal, cornerDirection); + cornerDirection = normal.cross(cornerDirection, cornerDirection); + var scalar = width / Math.max(0.25, (Cartesian3.cross(cornerDirection, backward, scratch1).magnitude())); + var leftIsOutside = CorridorGeometryLibrary.angleIsGreaterThanPi(forward, backward, position, ellipsoid); + cornerDirection = cornerDirection.multiplyByScalar(scalar, cornerDirection, cornerDirection); + if (leftIsOutside) { + rightPos = Cartesian3.add(position, cornerDirection, rightPos); + leftPos = rightPos.add(left.multiplyByScalar(width*2, leftPos), leftPos); + calculatedPositions.push(PolylinePipeline.scaleToSurface([previousRightPos, rightPos], granularity)); + calculatedPositions.push(PolylinePipeline.scaleToSurface([leftPos, previousLeftPos], granularity)); + startPoint = leftPos.clone(startPoint); + left = normal.cross(forward, left).normalize(left); + leftPos = rightPos.add(left.multiplyByScalar(width*2, leftPos), leftPos); + if (cornerType.value === CornerType.ROUNDED.value || cornerType.value === CornerType.BEVELED.value) { + corners.push(CorridorGeometryLibrary.computeRoundCorner(rightPos, startPoint, leftPos, cornerType, leftIsOutside, ellipsoid)); + } else { + corners.push(CorridorGeometryLibrary.computeMiteredCorner(position, startPoint, cornerDirection.negate(cornerDirection), leftPos, leftIsOutside, granularity, ellipsoid)); + } + previousRightPos = rightPos.clone(previousRightPos); + previousLeftPos = leftPos.clone(previousLeftPos); + } else { + leftPos = Cartesian3.add(position, cornerDirection, leftPos); + rightPos = leftPos.add(left.multiplyByScalar(width*2, rightPos).negate(rightPos), rightPos); + calculatedPositions.push(PolylinePipeline.scaleToSurface([previousRightPos, rightPos], granularity)); + calculatedPositions.push(PolylinePipeline.scaleToSurface([leftPos, previousLeftPos], granularity)); + startPoint = rightPos.clone(startPoint); + left = normal.cross(forward, left).normalize(left); + rightPos = leftPos.add(left.multiplyByScalar(width*2, rightPos).negate(rightPos), rightPos); + if (cornerType.value === CornerType.ROUNDED.value || cornerType.value === CornerType.BEVELED.value) { + corners.push(CorridorGeometryLibrary.computeRoundCorner(leftPos, startPoint, rightPos, cornerType, leftIsOutside, ellipsoid)); + } else { + corners.push(CorridorGeometryLibrary.computeMiteredCorner(position, startPoint, cornerDirection, rightPos, leftIsOutside, granularity, ellipsoid)); + } + previousRightPos = rightPos.clone(previousRightPos); + previousLeftPos = leftPos.clone(previousLeftPos); + } + backward = forward.negate(backward); + } + position = nextPosition; + } + + normal = ellipsoid.geodeticSurfaceNormal(position, normal); + leftPos = Cartesian3.add(position, left.multiplyByScalar(width, leftPos), leftPos); // add last position + rightPos = Cartesian3.add(position, left.multiplyByScalar(width, rightPos).negate(rightPos), rightPos); + calculatedPositions.push(PolylinePipeline.scaleToSurface([previousRightPos, rightPos], granularity)); + calculatedPositions.push(PolylinePipeline.scaleToSurface([leftPos, previousLeftPos], granularity)); + + var endPositions; + if (cornerType.value === CornerType.ROUNDED.value) { + endPositions = CorridorGeometryLibrary.addEndCaps(calculatedPositions, width, ellipsoid); + } + + return combine(calculatedPositions, corners, endPositions, ellipsoid); + } + + function computePositionsExtruded(params) { + var attr = computePositions(params); + var height = params.height; + var extrudedHeight = params.extrudedHeight; + var ellipsoid = params.ellipsoid; + var attributes = attr.attributes; + var indices = attr.indices; + var boundingSphere = attr.boundingSphere; + var positions = Array.apply([], attributes.position.values); + var extrudedPositions = positions.slice(0); + var length = positions.length/3; + + positions = PolylinePipeline.scaleToGeodeticHeight(positions, height, ellipsoid); + extrudedPositions = PolylinePipeline.scaleToGeodeticHeight(extrudedPositions, extrudedHeight, ellipsoid); + positions = positions.concat(extrudedPositions); + boundingSphere = BoundingSphere.fromVertices(positions, undefined, 3, boundingSphere); + attributes.position.values = new Float64Array(positions); + + var i; + var iLength = indices.length; + for (i = 0; i < iLength; i+=2) { // bottom indices + var v0 = indices[i]; + var v1 = indices[i + 1]; + indices.push(v0 + length, v1 + length); + } + + var UL, LL; + for (i = 0; i < length; i++) { //wall indices + UL = i; + LL = UL + length; + indices.push(UL, LL); + } + + return { + attributes: attributes, + indices: indices, + boundingSphere: boundingSphere + }; + } + + /** + * A description of a corridor. + * + * @alias CorridorOutlineGeometry + * @constructor + * + * @param {Array} options.positions An array of {Cartesain3} positions that define the center of the corridor. + * @param {Number} options.width The distance between the edges of the corridor. + * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. + * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. + * @param {Number} [options.height=0] The distance between the ellipsoid surface and the positions. + * @param {Number} [options.extrudedHeight] The distance between the ellipsoid surface and the extrusion. + * @param {Boolean} [options.cornerType = CornerType.ROUNDED] Determines the style of the corners. + * + * @exception {DeveloperError} options.positions is required. + * @exception {DeveloperError} options.width is required. + * + * @see CorridorOutlineGeometry#createGeometry + * + * @example + * var corridor = new CorridorOutlineGeometry({ + * positions : ellipsoid.cartographicArrayToCartesianArray([ + * Cartographic.fromDegrees(-72.0, 40.0), + * Cartographic.fromDegrees(-70.0, 35.0) + * ]), + * width : 100000 + * }); + */ + var CorridorOutlineGeometry = function(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + var positions = options.positions; + if (!defined(positions)) { + throw new DeveloperError('options.positions is required.'); + } + var width = options.width; + if (!defined(width)) { + throw new DeveloperError('options.width is required.'); + } + + this._positions = positions; + this._width = width; + this._ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); + this._height = defaultValue(options.height, 0); + this._extrudedHeight = defaultValue(options.extrudedHeight, this._height); + this._cornerType = defaultValue(options.cornerType, CornerType.ROUNDED); + this._granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE); + this._workerName = 'createCorridorOutlineGeometry'; + }; + + /** + * Computes the geometric representation of a corridor, including its vertices, indices, and a bounding sphere. + * @memberof CorridorOutlineGeometry + * + * @param {CorridorOutlineGeometry} corridorOutlineGeometry A description of the corridor. + * + * @returns {Geometry} The computed vertices and indices. + * + * @exception {DeveloperError} Count of unique positions must be greater than 1. + */ + CorridorOutlineGeometry.createGeometry = function(corridorOutlineGeometry) { + var positions = corridorOutlineGeometry._positions; + var height = corridorOutlineGeometry._height; + var extrudedHeight = corridorOutlineGeometry._extrudedHeight; + var extrude = (height !== extrudedHeight); + var cleanPositions = PolylinePipeline.removeDuplicates(positions); + if (cleanPositions.length < 2) { + throw new DeveloperError('Count of unique positions must be greater than 1.'); + } + var ellipsoid = corridorOutlineGeometry._ellipsoid; + var params = { + ellipsoid: ellipsoid, + positions: cleanPositions, + width: corridorOutlineGeometry._width, + cornerType: corridorOutlineGeometry._cornerType, + granularity: corridorOutlineGeometry._granularity + }; + var attr; + if (extrude) { + var h = Math.max(height, extrudedHeight); + extrudedHeight = Math.min(height, extrudedHeight); + height = h; + params.height = height; + params.extrudedHeight = extrudedHeight; + attr = computePositionsExtruded(params); + } else { + attr = computePositions(params); + attr.attributes.position.values = new Float64Array(PolylinePipeline.scaleToGeodeticHeight(attr.attributes.position.values, height, ellipsoid)); + } + var attributes = attr.attributes; + + return new Geometry({ + attributes : attributes, + indices : IndexDatatype.createTypedArray(attributes.position.values.length/3, attr.indices), + primitiveType : PrimitiveType.LINES, + boundingSphere : attr.boundingSphere + }); + }; + + return CorridorOutlineGeometry; +}); \ No newline at end of file From 9824643c7e4680b33699a4587ed0f1816d94fd9a Mon Sep 17 00:00:00 2001 From: hpinkos Date: Fri, 30 Aug 2013 11:41:29 -0400 Subject: [PATCH 2/9] finish merge --- Source/Core/CorridorGeometry.js | 139 ++-------------- Source/Core/CorridorGeometryLibrary.js | 140 +++++++++++++++- Source/Core/CorridorOutlineGeometry.js | 151 +++--------------- .../Workers/createCorridorOutlineGeometry.js | 28 ++++ 4 files changed, 205 insertions(+), 253 deletions(-) create mode 100644 Source/Workers/createCorridorOutlineGeometry.js diff --git a/Source/Core/CorridorGeometry.js b/Source/Core/CorridorGeometry.js index 27bc53770e33..0e65942e922b 100644 --- a/Source/Core/CorridorGeometry.js +++ b/Source/Core/CorridorGeometry.js @@ -37,18 +37,12 @@ define([ VertexFormat) { "use strict"; - var scaleArray2 = [new Cartesian3(), new Cartesian3()]; - var cartesian1 = new Cartesian3(); var cartesian2 = new Cartesian3(); var cartesian3 = new Cartesian3(); var cartesian4 = new Cartesian3(); var cartesian5 = new Cartesian3(); var cartesian6 = new Cartesian3(); - var cartesian7 = new Cartesian3(); - var cartesian8 = new Cartesian3(); - var cartesian9 = new Cartesian3(); - var cartesian10 = new Cartesian3(); var scratch1 = new Cartesian3(); var scratch2 = new Cartesian3(); @@ -69,7 +63,12 @@ define([ } } - function combine(positions, corners, computedLefts, computedNormals, vertexFormat, endPositions, ellipsoid) { + function combine(computedPositions, vertexFormat, ellipsoid) { + var positions = computedPositions.positions; + var corners = computedPositions.corners; + var endPositions = computedPositions.endCaps; + var computedLefts = computedPositions.lefts; + var computedNormals = computedPositions.normals; var attributes = new GeometryAttributes(); var corner; var leftCount = 0; @@ -416,113 +415,6 @@ define([ }; } - function computePositions(params) { - var granularity = params.granularity; - var positions = params.positions; - var width = params.width / 2; - var ellipsoid = params.ellipsoid; - var cornerType = params.cornerType; - var normal = cartesian1; - var forward = cartesian2; - var backward = cartesian3; - var left = cartesian4; - var cornerDirection = cartesian5; - var startPoint = cartesian6; - var previousPos = cartesian7; - var rightPos = cartesian8; - var leftPos = cartesian9; - var center = cartesian10; - var calculatedPositions = []; - var calculatedLefts = []; - var calculatedNormals = []; - var position = positions[0]; //add first point - var nextPosition = positions[1]; - - forward = Cartesian3.subtract(nextPosition, position, forward).normalize(forward); - normal = ellipsoid.geodeticSurfaceNormal(position, normal); - left = normal.cross(forward, left).normalize(left); - calculatedLefts.push(left.x, left.y, left.z); - calculatedNormals.push(normal.x, normal.y, normal.z); - previousPos = Cartesian3.clone(position, previousPos); - position = nextPosition; - backward = forward.negate(backward); - - var subdividedPositions; - var corners = []; - var i; - var length = positions.length; - for (i = 1; i < length - 1; i++) { // add middle points and corners - normal = ellipsoid.geodeticSurfaceNormal(position, normal); - nextPosition = positions[i + 1]; - forward = Cartesian3.subtract(nextPosition, position, forward).normalize(forward); - cornerDirection = forward.add(backward, cornerDirection).normalize(cornerDirection); - var doCorner = !Cartesian3.equalsEpsilon(cornerDirection.negate(scratch1), normal, CesiumMath.EPSILON2); - if (doCorner) { - cornerDirection = cornerDirection.cross(normal, cornerDirection); - cornerDirection = normal.cross(cornerDirection, cornerDirection); - var scalar = width / Math.max(0.25, (Cartesian3.cross(cornerDirection, backward, scratch1).magnitude())); - var leftIsOutside = CorridorGeometryLibrary.angleIsGreaterThanPi(forward, backward, position, ellipsoid); - cornerDirection = cornerDirection.multiplyByScalar(scalar, cornerDirection, cornerDirection); - if (leftIsOutside) { - rightPos = Cartesian3.add(position, cornerDirection, rightPos); - center = rightPos.add(left.multiplyByScalar(width, center), center); - leftPos = rightPos.add(left.multiplyByScalar(width * 2, leftPos), leftPos); - scaleArray2[0] = Cartesian3.clone(previousPos, scaleArray2[0]); - scaleArray2[1] = Cartesian3.clone(center, scaleArray2[1]); - subdividedPositions = PolylinePipeline.scaleToSurface(scaleArray2, granularity, ellipsoid); - calculatedPositions = CorridorGeometryLibrary.addShiftedPositions(subdividedPositions, left, width, calculatedPositions); - calculatedLefts.push(left.x, left.y, left.z); - calculatedNormals.push(normal.x, normal.y, normal.z); - startPoint = leftPos.clone(startPoint); - left = normal.cross(forward, left).normalize(left); - leftPos = rightPos.add(left.multiplyByScalar(width * 2, leftPos), leftPos); - previousPos = rightPos.add(left.multiplyByScalar(width, previousPos), previousPos); - if (cornerType.value === CornerType.ROUNDED.value || cornerType.value === CornerType.BEVELED.value) { - corners.push({leftPositions : CorridorGeometryLibrary.computeRoundCorner(rightPos, startPoint, leftPos, cornerType, leftIsOutside, ellipsoid)}); - } else { - corners.push({leftPositions : CorridorGeometryLibrary.computeMiteredCorner(position, startPoint, cornerDirection.negate(cornerDirection), leftPos, leftIsOutside, granularity, ellipsoid)}); - } - } else { - leftPos = Cartesian3.add(position, cornerDirection, leftPos); - center = leftPos.add(left.multiplyByScalar(width, center).negate(center), center); - rightPos = leftPos.add(left.multiplyByScalar(width * 2, rightPos).negate(rightPos), rightPos); - scaleArray2[0] = Cartesian3.clone(previousPos, scaleArray2[0]); - scaleArray2[1] = Cartesian3.clone(center, scaleArray2[1]); - subdividedPositions = PolylinePipeline.scaleToSurface(scaleArray2, granularity, ellipsoid); - calculatedPositions = CorridorGeometryLibrary.addShiftedPositions(subdividedPositions, left, width, calculatedPositions); - calculatedLefts.push(left.x, left.y, left.z); - calculatedNormals.push(normal.x, normal.y, normal.z); - startPoint = rightPos.clone(startPoint); - left = normal.cross(forward, left).normalize(left); - rightPos = leftPos.add(left.multiplyByScalar(width * 2, rightPos).negate(rightPos), rightPos); - previousPos = leftPos.add(left.multiplyByScalar(width, previousPos).negate(previousPos), previousPos); - if (cornerType.value === CornerType.ROUNDED.value || cornerType.value === CornerType.BEVELED.value) { - corners.push({rightPositions : CorridorGeometryLibrary.computeRoundCorner(leftPos, startPoint, rightPos, cornerType, leftIsOutside, ellipsoid)}); - } else { - corners.push({rightPositions : CorridorGeometryLibrary.computeMiteredCorner(position, startPoint, cornerDirection, rightPos, leftIsOutside, granularity, ellipsoid)}); - } - } - backward = forward.negate(backward); - } - position = nextPosition; - } - - normal = ellipsoid.geodeticSurfaceNormal(position, normal); - scaleArray2[0] = Cartesian3.clone(previousPos, scaleArray2[0]); - scaleArray2[1] = Cartesian3.clone(position, scaleArray2[1]); - subdividedPositions = PolylinePipeline.scaleToSurface(scaleArray2, granularity, ellipsoid); - calculatedPositions = CorridorGeometryLibrary.addShiftedPositions(subdividedPositions, left, width, calculatedPositions); - calculatedLefts.push(left.x, left.y, left.z); - calculatedNormals.push(normal.x, normal.y, normal.z); - - var endPositions; - if (cornerType.value === CornerType.ROUNDED.value) { - endPositions = CorridorGeometryLibrary.addEndCaps(calculatedPositions, width, ellipsoid); - } - - return combine(calculatedPositions, corners, calculatedLefts, calculatedNormals, params.vertexFormat, endPositions, ellipsoid); - } - function extrudedAttributes(attributes, vertexFormat) { if (!vertexFormat.normal && !vertexFormat.binormal && !vertexFormat.tangent && !vertexFormat.st) { return attributes; @@ -660,19 +552,19 @@ define([ return wallPositions; } - function computePositionsExtruded(params) { - var vertexFormat = params.vertexFormat; - params.vertexFormat = new VertexFormat({ + function computePositionsExtruded(params, vertexFormat) { + var topVertexFormat = new VertexFormat({ position : vertexFormat.positon, normal : (vertexFormat.normal || vertexFormat.binormal), tangent : vertexFormat.tangent, binormal : (vertexFormat.normal || vertexFormat.binormal), st : vertexFormat.st }); - var attr = computePositions(params); + var ellipsoid = params.ellipsoid; + var computedPositions = CorridorGeometryLibrary.computePositions(params); + var attr = combine(computedPositions, topVertexFormat, ellipsoid); var height = params.height; var extrudedHeight = params.extrudedHeight; - var ellipsoid = params.ellipsoid; var attributes = attr.attributes; var indices = attr.indices; var boundingSphere = attr.boundingSphere; @@ -807,11 +699,11 @@ define([ var vertexFormat = corridorGeometry._vertexFormat; var params = { ellipsoid : ellipsoid, - vertexFormat : vertexFormat, positions : cleanPositions, width : corridorGeometry._width, cornerType : corridorGeometry._cornerType, - granularity : corridorGeometry._granularity + granularity : corridorGeometry._granularity, + saveAttributes: true }; var attr; if (extrude) { @@ -820,9 +712,10 @@ define([ height = h; params.height = height; params.extrudedHeight = extrudedHeight; - attr = computePositionsExtruded(params); + attr = computePositionsExtruded(params, vertexFormat); } else { - attr = computePositions(params); + var computedPositions = CorridorGeometryLibrary.computePositions(params); + attr = combine(computedPositions, vertexFormat, ellipsoid); if (!vertexFormat.position) { attr.attributes.position.values = undefined; } else { diff --git a/Source/Core/CorridorGeometryLibrary.js b/Source/Core/CorridorGeometryLibrary.js index 07547c1eb6fa..2fa3a4a7270b 100644 --- a/Source/Core/CorridorGeometryLibrary.js +++ b/Source/Core/CorridorGeometryLibrary.js @@ -5,6 +5,7 @@ define([ './Cartesian3', './CornerType', './EllipsoidTangentPlane', + './PolylinePipeline', './Matrix3', './Quaternion', './Math' @@ -14,6 +15,7 @@ define([ Cartesian3, CornerType, EllipsoidTangentPlane, + PolylinePipeline, Matrix3, Quaternion, CesiumMath) { @@ -29,6 +31,19 @@ define([ var scratch3 = new Cartesian3(); var scratch4 = new Cartesian3(); + var scaleArray2 = [new Cartesian3(), new Cartesian3()]; + + var cartesian1 = new Cartesian3(); + var cartesian2 = new Cartesian3(); + var cartesian3 = new Cartesian3(); + var cartesian4 = new Cartesian3(); + var cartesian5 = new Cartesian3(); + var cartesian6 = new Cartesian3(); + var cartesian7 = new Cartesian3(); + var cartesian8 = new Cartesian3(); + var cartesian9 = new Cartesian3(); + var cartesian10 = new Cartesian3(); + var originScratch = new Cartesian3(); var nextScratch = new Cartesian3(); var prevScratch = new Cartesian3(); @@ -76,9 +91,6 @@ define([ return array; }; - var cartesian1 = new Cartesian3(); - var cartesian2 = new Cartesian3(); - var cartesian3 = new Cartesian3(); CorridorGeometryLibrary.addEndCaps = function (calculatedPositions, width, ellipsoid) { var cornerPoint = cartesian1; var startPoint = cartesian2; @@ -153,5 +165,127 @@ define([ return calculatedPositions; }; + CorridorGeometryLibrary.computePositions = function (params) { + var granularity = params.granularity; + var positions = params.positions; + var width = params.width / 2; + var ellipsoid = params.ellipsoid; + var cornerType = params.cornerType; + var saveAttributes = params.saveAttributes; + var normal = cartesian1; + var forward = cartesian2; + var backward = cartesian3; + var left = cartesian4; + var cornerDirection = cartesian5; + var startPoint = cartesian6; + var previousPos = cartesian7; + var rightPos = cartesian8; + var leftPos = cartesian9; + var center = cartesian10; + var calculatedPositions = []; + var calculatedLefts = (saveAttributes) ? [] : undefined; + var calculatedNormals = (saveAttributes) ? [] : undefined; + var position = positions[0]; //add first point + var nextPosition = positions[1]; + + forward = Cartesian3.subtract(nextPosition, position, forward).normalize(forward); + normal = ellipsoid.geodeticSurfaceNormal(position, normal); + left = normal.cross(forward, left).normalize(left); + if (saveAttributes) { + calculatedLefts.push(left.x, left.y, left.z); + calculatedNormals.push(normal.x, normal.y, normal.z); + } + previousPos = Cartesian3.clone(position, previousPos); + position = nextPosition; + backward = forward.negate(backward); + + var subdividedPositions; + var corners = []; + var i; + var length = positions.length; + for (i = 1; i < length - 1; i++) { // add middle points and corners + normal = ellipsoid.geodeticSurfaceNormal(position, normal); + nextPosition = positions[i + 1]; + forward = Cartesian3.subtract(nextPosition, position, forward).normalize(forward); + cornerDirection = forward.add(backward, cornerDirection).normalize(cornerDirection); + var doCorner = !Cartesian3.equalsEpsilon(cornerDirection.negate(scratch1), normal, CesiumMath.EPSILON2); + if (doCorner) { + cornerDirection = cornerDirection.cross(normal, cornerDirection); + cornerDirection = normal.cross(cornerDirection, cornerDirection); + var scalar = width / Math.max(0.25, (Cartesian3.cross(cornerDirection, backward, scratch1).magnitude())); + var leftIsOutside = CorridorGeometryLibrary.angleIsGreaterThanPi(forward, backward, position, ellipsoid); + cornerDirection = cornerDirection.multiplyByScalar(scalar, cornerDirection, cornerDirection); + if (leftIsOutside) { + rightPos = Cartesian3.add(position, cornerDirection, rightPos); + center = rightPos.add(left.multiplyByScalar(width, center), center); + leftPos = rightPos.add(left.multiplyByScalar(width * 2, leftPos), leftPos); + scaleArray2[0] = Cartesian3.clone(previousPos, scaleArray2[0]); + scaleArray2[1] = Cartesian3.clone(center, scaleArray2[1]); + subdividedPositions = PolylinePipeline.scaleToSurface(scaleArray2, granularity, ellipsoid); + calculatedPositions = CorridorGeometryLibrary.addShiftedPositions(subdividedPositions, left, width, calculatedPositions); + if (saveAttributes) { + calculatedLefts.push(left.x, left.y, left.z); + calculatedNormals.push(normal.x, normal.y, normal.z); + } + startPoint = leftPos.clone(startPoint); + left = normal.cross(forward, left).normalize(left); + leftPos = rightPos.add(left.multiplyByScalar(width * 2, leftPos), leftPos); + previousPos = rightPos.add(left.multiplyByScalar(width, previousPos), previousPos); + if (cornerType.value === CornerType.ROUNDED.value || cornerType.value === CornerType.BEVELED.value) { + corners.push({leftPositions : CorridorGeometryLibrary.computeRoundCorner(rightPos, startPoint, leftPos, cornerType, leftIsOutside, ellipsoid)}); + } else { + corners.push({leftPositions : CorridorGeometryLibrary.computeMiteredCorner(position, startPoint, cornerDirection.negate(cornerDirection), leftPos, leftIsOutside, granularity, ellipsoid)}); + } + } else { + leftPos = Cartesian3.add(position, cornerDirection, leftPos); + center = leftPos.add(left.multiplyByScalar(width, center).negate(center), center); + rightPos = leftPos.add(left.multiplyByScalar(width * 2, rightPos).negate(rightPos), rightPos); + scaleArray2[0] = Cartesian3.clone(previousPos, scaleArray2[0]); + scaleArray2[1] = Cartesian3.clone(center, scaleArray2[1]); + subdividedPositions = PolylinePipeline.scaleToSurface(scaleArray2, granularity, ellipsoid); + calculatedPositions = CorridorGeometryLibrary.addShiftedPositions(subdividedPositions, left, width, calculatedPositions); + if (saveAttributes) { + calculatedLefts.push(left.x, left.y, left.z); + calculatedNormals.push(normal.x, normal.y, normal.z); + } + startPoint = rightPos.clone(startPoint); + left = normal.cross(forward, left).normalize(left); + rightPos = leftPos.add(left.multiplyByScalar(width * 2, rightPos).negate(rightPos), rightPos); + previousPos = leftPos.add(left.multiplyByScalar(width, previousPos).negate(previousPos), previousPos); + if (cornerType.value === CornerType.ROUNDED.value || cornerType.value === CornerType.BEVELED.value) { + corners.push({rightPositions : CorridorGeometryLibrary.computeRoundCorner(leftPos, startPoint, rightPos, cornerType, leftIsOutside, ellipsoid)}); + } else { + corners.push({rightPositions : CorridorGeometryLibrary.computeMiteredCorner(position, startPoint, cornerDirection, rightPos, leftIsOutside, granularity, ellipsoid)}); + } + } + backward = forward.negate(backward); + } + position = nextPosition; + } + + normal = ellipsoid.geodeticSurfaceNormal(position, normal); + scaleArray2[0] = Cartesian3.clone(previousPos, scaleArray2[0]); + scaleArray2[1] = Cartesian3.clone(position, scaleArray2[1]); + subdividedPositions = PolylinePipeline.scaleToSurface(scaleArray2, granularity, ellipsoid); + calculatedPositions = CorridorGeometryLibrary.addShiftedPositions(subdividedPositions, left, width, calculatedPositions); + if (saveAttributes) { + calculatedLefts.push(left.x, left.y, left.z); + calculatedNormals.push(normal.x, normal.y, normal.z); + } + + var endPositions; + if (cornerType.value === CornerType.ROUNDED.value) { + endPositions = CorridorGeometryLibrary.addEndCaps(calculatedPositions, width, ellipsoid); + } + + return { + positions: calculatedPositions, + corners: corners, + lefts: calculatedLefts, + normals: calculatedNormals, + endPositions: endPositions + }; + }; + return CorridorGeometryLibrary; }); \ No newline at end of file diff --git a/Source/Core/CorridorOutlineGeometry.js b/Source/Core/CorridorOutlineGeometry.js index 6bf2997edc48..d99fccdfc566 100644 --- a/Source/Core/CorridorOutlineGeometry.js +++ b/Source/Core/CorridorOutlineGeometry.js @@ -48,19 +48,11 @@ define([ var cartesian1 = new Cartesian3(); var cartesian2 = new Cartesian3(); var cartesian3 = new Cartesian3(); - var cartesian4 = new Cartesian3(); - var cartesian5 = new Cartesian3(); - var cartesian6 = new Cartesian3(); - var cartesian7 = new Cartesian3(); - var cartesian8 = new Cartesian3(); - var cartesian9 = new Cartesian3(); - var cartesian10 = new Cartesian3(); - var scratch1= new Cartesian3(); - - var scaleArray2 = [new Cartesian3(), new Cartesian3()]; - - function combine(positions, corners, endPositions, ellipsoid) { + function combine(computedPositions, ellipsoid) { + var positions = computedPositions.positions; + var corners = computedPositions.corners; + var endPositions = computedPositions.endPositions; var attributes = new GeometryAttributes(); var corner; var leftCount = 0; @@ -71,7 +63,7 @@ define([ for (i = 0; i < positions.length; i += 2) { length = positions[i].length - 3; leftCount += length; //subtracting 3 to account for duplicate points at corners - indicesLength += length*2; + indicesLength += length/3*4; rightCount += positions[i + 1].length - 3; } leftCount += 3; //add back count for end positions @@ -82,11 +74,11 @@ define([ if (defined(leftSide)) { length = leftSide.length; leftCount += length; - indicesLength += length; + indicesLength += length/3*2; } else { length = corners[i].rightPositions.length; rightCount += length; - indicesLength += length; + indicesLength += length/3*2; } } @@ -97,7 +89,7 @@ define([ leftCount += endPositionLength; rightCount += endPositionLength; endPositionLength /= 3; - indicesLength += endPositionLength * 6; + indicesLength += endPositionLength * 4; } var size = leftCount + rightCount; var finalPositions = new Float64Array(size); @@ -107,14 +99,14 @@ define([ var rightPos, leftPos; var halfLength = endPositionLength/2; - var indices = IndexDatatype.createTypedArray(size/3, indicesLength); + var indices = IndexDatatype.createTypedArray(size/3, indicesLength + 4); var index = 0; indices[index++] = front/3; indices[index++] = (back-2)/3; if (addEndPositions) { // add rounded end - leftPos = cartesian3; - rightPos = cartesian4; + leftPos = cartesian1; + rightPos = cartesian2; var firstEndPositions = endPositions[0]; for (i = 0; i < halfLength; i++) { leftPos = Cartesian3.fromArray(firstEndPositions, (halfLength - 1 - i) * 3, leftPos); @@ -164,7 +156,7 @@ define([ var l = corner.leftPositions; var r = corner.rightPositions; var start; - var outsidePoint = cartesian6; + var outsidePoint = cartesian3; if (defined(l)) { back -= 3; start = UR; @@ -201,7 +193,6 @@ define([ LL = LR - 1; UR = (back-2)/3; UL = UR + 1; - indices.push(UL, UR, LL, LR); indices[index++] = UL; indices[index++] = UR; indices[index++] = LL; @@ -216,8 +207,8 @@ define([ if (addEndPositions) { // add rounded end front += 3; back -= 3; - leftPos = cartesian3; - rightPos = cartesian4; + leftPos = cartesian1; + rightPos = cartesian2; var lastEndPositions = endPositions[1]; for (i = 0; i < halfLength; i++) { leftPos = Cartesian3.fromArray(lastEndPositions, (endPositionLength - i - 1) * 3, leftPos); @@ -255,108 +246,12 @@ define([ }; } - function computePositions(params) { - var granularity = params.granularity; - var positions = params.positions; - var width = params.width/2; - var ellipsoid = params.ellipsoid; - var cornerType = params.cornerType; - var normal = cartesian1; - var forward = cartesian2; - var backward = cartesian3; - var left = cartesian4; - var cornerDirection = cartesian5; - var startPoint = cartesian6; - var previousPos = cartesian7; - var rightPos = cartesian8; - var leftPos = cartesian9; - var center = cartesian10; - var calculatedPositions = []; - var position = positions[0]; //add first point - var nextPosition = positions[1]; - - forward = Cartesian3.subtract(nextPosition, position, forward).normalize(forward); - normal = ellipsoid.geodeticSurfaceNormal(position, normal); - left = normal.cross(forward, left).normalize(left); - previousPos = Cartesian3.clone(position, previousPos); - position = nextPosition; - backward = forward.negate(backward); - - var subdividedPositions; - var corners = []; - var i; - var length = positions.length; - for (i = 1; i < length-1; i++) { // add middle points and corners - normal = ellipsoid.geodeticSurfaceNormal(position, normal); - nextPosition = positions[i+1]; - forward = Cartesian3.subtract(nextPosition, position, forward).normalize(forward); - cornerDirection = forward.add(backward, cornerDirection).normalize(cornerDirection); - var doCorner = !Cartesian3.equalsEpsilon(cornerDirection.negate(scratch1), normal, CesiumMath.EPSILON2); - if (doCorner) { - cornerDirection = cornerDirection.cross(normal, cornerDirection); - cornerDirection = normal.cross(cornerDirection, cornerDirection); - var scalar = width / Math.max(0.25, (Cartesian3.cross(cornerDirection, backward, scratch1).magnitude())); - var leftIsOutside = CorridorGeometryLibrary.angleIsGreaterThanPi(forward, backward, position, ellipsoid); - cornerDirection = cornerDirection.multiplyByScalar(scalar, cornerDirection, cornerDirection); - if (leftIsOutside) { - rightPos = Cartesian3.add(position, cornerDirection, rightPos); - center = rightPos.add(left.multiplyByScalar(width, center), center); - leftPos = rightPos.add(left.multiplyByScalar(width*2, leftPos), leftPos); - scaleArray2[0] = Cartesian3.clone(previousPos, scaleArray2[0]); - scaleArray2[1] = Cartesian3.clone(center, scaleArray2[1]); - subdividedPositions = PolylinePipeline.scaleToSurface(scaleArray2, granularity, ellipsoid); - calculatedPositions = CorridorGeometryLibrary.addShiftedPositions(subdividedPositions, left, width, calculatedPositions); - startPoint = leftPos.clone(startPoint); - left = normal.cross(forward, left).normalize(left); - leftPos = rightPos.add(left.multiplyByScalar(width*2, leftPos), leftPos); - previousPos = rightPos.add(left.multiplyByScalar(width, previousPos), previousPos); - if (cornerType.value === CornerType.ROUNDED.value || cornerType.value === CornerType.BEVELED.value) { - corners.push({leftPositions : CorridorGeometryLibrary.computeRoundCorner(rightPos, startPoint, leftPos, cornerType, leftIsOutside, ellipsoid)}); - } else { - corners.push({leftPositions : CorridorGeometryLibrary.computeMiteredCorner(position, startPoint, cornerDirection.negate(cornerDirection), leftPos, leftIsOutside, granularity, ellipsoid)}); - } - } else { - leftPos = Cartesian3.add(position, cornerDirection, leftPos); - center = leftPos.add(left.multiplyByScalar(width, center).negate(center), center); - rightPos = leftPos.add(left.multiplyByScalar(width*2, rightPos).negate(rightPos), rightPos); - scaleArray2[0] = Cartesian3.clone(previousPos, scaleArray2[0]); - scaleArray2[1] = Cartesian3.clone(center, scaleArray2[1]); - subdividedPositions = PolylinePipeline.scaleToSurface(scaleArray2, granularity, ellipsoid); - calculatedPositions = CorridorGeometryLibrary.addShiftedPositions(subdividedPositions, left, width, calculatedPositions); - startPoint = rightPos.clone(startPoint); - left = normal.cross(forward, left).normalize(left); - rightPos = leftPos.add(left.multiplyByScalar(width*2, rightPos).negate(rightPos), rightPos); - previousPos = leftPos.add(left.multiplyByScalar(width, previousPos).negate(previousPos), previousPos); - if (cornerType.value === CornerType.ROUNDED.value || cornerType.value === CornerType.BEVELED.value) { - corners.push({rightPositions : CorridorGeometryLibrary.computeRoundCorner(leftPos, startPoint, rightPos, cornerType, leftIsOutside, ellipsoid)}); - } else { - corners.push({rightPositions : CorridorGeometryLibrary.computeMiteredCorner(position, startPoint, cornerDirection, rightPos, leftIsOutside, granularity, ellipsoid)}); - } - } - backward = forward.negate(backward); - } - position = nextPosition; - } - - normal = ellipsoid.geodeticSurfaceNormal(position, normal); - scaleArray2[0] = Cartesian3.clone(previousPos, scaleArray2[0]); - scaleArray2[1] = Cartesian3.clone(position, scaleArray2[1]); - subdividedPositions = PolylinePipeline.scaleToSurface(scaleArray2, granularity, ellipsoid); - calculatedPositions = CorridorGeometryLibrary.addShiftedPositions(subdividedPositions, left, width, calculatedPositions); - - var endPositions; - if (cornerType.value === CornerType.ROUNDED.value) { - endPositions = CorridorGeometryLibrary.addEndCaps(calculatedPositions, width, ellipsoid); - } - - return combine(calculatedPositions, corners, endPositions, ellipsoid); - } - function computePositionsExtruded(params) { - var attr = computePositions(params); + var ellipsoid = params.ellipsoid; + var computedPositions = CorridorGeometryLibrary.computePositions(params); + var attr = combine(computedPositions, ellipsoid); var height = params.height; var extrudedHeight = params.extrudedHeight; - var ellipsoid = params.ellipsoid; var attributes = attr.attributes; var indices = attr.indices; var boundingSphere = attr.boundingSphere; @@ -368,7 +263,6 @@ define([ positions = PolylinePipeline.scaleToGeodeticHeight(positions, height, ellipsoid, positions); extrudedPositions = PolylinePipeline.scaleToGeodeticHeight(extrudedPositions, extrudedHeight, ellipsoid); - positions = positions.concat(extrudedPositions); newPositions.set(positions); newPositions.set(extrudedPositions, length); boundingSphere = BoundingSphere.fromVertices(positions, undefined, 3, boundingSphere); @@ -378,7 +272,8 @@ define([ var i; var iLength = indices.length; var newIndices = IndexDatatype.createTypedArray(newPositions.length / 3, (iLength + length) * 2); - var index = 0; + newIndices.set(indices); + var index = iLength; for (i = 0; i < iLength; i+=2) { // bottom indices var v0 = indices[i]; var v1 = indices[i + 1]; @@ -396,7 +291,7 @@ define([ return { attributes: attributes, - indices: indices, + indices: newIndices, boundingSphere: boundingSphere }; } @@ -475,7 +370,8 @@ define([ positions: cleanPositions, width: corridorOutlineGeometry._width, cornerType: corridorOutlineGeometry._cornerType, - granularity: corridorOutlineGeometry._granularity + granularity: corridorOutlineGeometry._granularity, + saveAttributes: false }; var attr; if (extrude) { @@ -486,7 +382,8 @@ define([ params.extrudedHeight = extrudedHeight; attr = computePositionsExtruded(params); } else { - attr = computePositions(params); + var computedPositions = CorridorGeometryLibrary.computePositions(params); + attr = combine(computedPositions, ellipsoid); attr.attributes.position.values = new Float64Array(PolylinePipeline.scaleToGeodeticHeight(attr.attributes.position.values, height, ellipsoid)); } var attributes = attr.attributes; diff --git a/Source/Workers/createCorridorOutlineGeometry.js b/Source/Workers/createCorridorOutlineGeometry.js new file mode 100644 index 000000000000..14d5bedb6bd6 --- /dev/null +++ b/Source/Workers/createCorridorOutlineGeometry.js @@ -0,0 +1,28 @@ +/*global define*/ +define([ + '../Core/CorridorOutlineGeometry', + '../Core/Ellipsoid', + '../Scene/PrimitivePipeline', + './createTaskProcessorWorker' + ], function( + CorridorOutlineGeometry, + Ellipsoid, + PrimitivePipeline, + createTaskProcessorWorker) { + "use strict"; + + function createCorridorOutlineGeometry(parameters, transferableObjects) { + var corridorOutlineGeometry = parameters.geometry; + corridorOutlineGeometry._ellipsoid = Ellipsoid.clone(corridorOutlineGeometry._ellipsoid); + + var geometry = CorridorOutlineGeometry.createGeometry(corridorOutlineGeometry); + PrimitivePipeline.transferGeometry(geometry, transferableObjects); + + return { + geometry : geometry, + index : parameters.index + }; + } + + return createTaskProcessorWorker(createCorridorOutlineGeometry); +}); From 138dc515ac478dc32d4302441a1b5e7b06b3a9b1 Mon Sep 17 00:00:00 2001 From: hpinkos Date: Fri, 30 Aug 2013 14:05:15 -0400 Subject: [PATCH 3/9] clean up wall indices, add tests --- Source/Core/CorridorGeometry.js | 2 +- Source/Core/CorridorOutlineGeometry.js | 35 +++--- Specs/Core/CorridorOutlineGeometrySpec.js | 144 ++++++++++++++++++++++ 3 files changed, 164 insertions(+), 17 deletions(-) create mode 100644 Specs/Core/CorridorOutlineGeometrySpec.js diff --git a/Source/Core/CorridorGeometry.js b/Source/Core/CorridorGeometry.js index 0e65942e922b..707e91cab1a9 100644 --- a/Source/Core/CorridorGeometry.js +++ b/Source/Core/CorridorGeometry.js @@ -66,7 +66,7 @@ define([ function combine(computedPositions, vertexFormat, ellipsoid) { var positions = computedPositions.positions; var corners = computedPositions.corners; - var endPositions = computedPositions.endCaps; + var endPositions = computedPositions.endPositions; var computedLefts = computedPositions.lefts; var computedNormals = computedPositions.normals; var attributes = new GeometryAttributes(); diff --git a/Source/Core/CorridorOutlineGeometry.js b/Source/Core/CorridorOutlineGeometry.js index d99fccdfc566..d0cd9c939748 100644 --- a/Source/Core/CorridorOutlineGeometry.js +++ b/Source/Core/CorridorOutlineGeometry.js @@ -2,47 +2,37 @@ define([ './defined', './DeveloperError', - './Cartesian2', './Cartesian3', './CornerType', './CorridorGeometryLibrary', './ComponentDatatype', './Ellipsoid', - './EllipsoidTangentPlane', './Geometry', './IndexDatatype', './Math', - './Matrix3', './PolylinePipeline', './PrimitiveType', - './Quaternion', './defaultValue', './BoundingSphere', './GeometryAttribute', - './GeometryAttributes', - './VertexFormat' + './GeometryAttributes' ], function( defined, DeveloperError, - Cartesian2, Cartesian3, CornerType, CorridorGeometryLibrary, ComponentDatatype, Ellipsoid, - EllipsoidTangentPlane, Geometry, IndexDatatype, CesiumMath, - Matrix3, PolylinePipeline, PrimitiveType, - Quaternion, defaultValue, BoundingSphere, GeometryAttribute, - GeometryAttributes, - VertexFormat) { + GeometryAttributes) { "use strict"; var cartesian1 = new Cartesian3(); @@ -50,6 +40,7 @@ define([ var cartesian3 = new Cartesian3(); function combine(computedPositions, ellipsoid) { + var wallIndices = []; var positions = computedPositions.positions; var corners = computedPositions.corners; var endPositions = computedPositions.endPositions; @@ -105,6 +96,7 @@ define([ indices[index++] = front/3; indices[index++] = (back-2)/3; if (addEndPositions) { // add rounded end + wallIndices.push(front/3); leftPos = cartesian1; rightPos = cartesian2; var firstEndPositions = endPositions[0]; @@ -135,6 +127,7 @@ define([ finalPositions.set(leftEdge, back - leftEdge.length + 1); length = leftEdge.length - 3; + wallIndices.push(front/3, (back-2)/3); for(i = 0; i < length; i+=3) { LL = front/3; LR = LL + 1; @@ -160,6 +153,7 @@ define([ if (defined(l)) { back -= 3; start = UR; + wallIndices.push(start, LR); for (j = 0; j < l.length/3; j++) { outsidePoint = Cartesian3.fromArray(l, j*3, outsidePoint); indices[index++] = start - j - 1; @@ -167,10 +161,12 @@ define([ CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, undefined, back); back -= 3; } + wallIndices.push(start - Math.floor(l.length/6), (back-2)/3 + 1); front += 3; } else { front += 3; start = LR; + wallIndices.push(start, UR); for (j = 0; j < r.length/3; j++) { outsidePoint = Cartesian3.fromArray(r, j*3, outsidePoint); indices[index++] = start + j; @@ -178,6 +174,7 @@ define([ CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, front); front += 3; } + wallIndices.push(start + Math.floor(r.length/6), front/3 - 1); back -= 3; } rightEdge = positions[posIndex++]; @@ -202,6 +199,7 @@ define([ } front -= 3; back += 3; + wallIndices.push(front/3, (back-2)/3); } if (addEndPositions) { // add rounded end @@ -232,6 +230,9 @@ define([ indices[index++] = front/3; indices[index++] = (back-2)/3; + if (i === 0) { + wallIndices.push(front/3, (back-2)/3); + } attributes.position = new GeometryAttribute({ componentDatatype : ComponentDatatype.DOUBLE, @@ -242,7 +243,8 @@ define([ return { attributes: attributes, indices: indices, - boundingSphere: BoundingSphere.fromVertices(finalPositions) + boundingSphere: BoundingSphere.fromVertices(finalPositions), + wallIndices: wallIndices }; } @@ -250,6 +252,7 @@ define([ var ellipsoid = params.ellipsoid; var computedPositions = CorridorGeometryLibrary.computePositions(params); var attr = combine(computedPositions, ellipsoid); + var wallIndices = attr.wallIndices; var height = params.height; var extrudedHeight = params.extrudedHeight; var attributes = attr.attributes; @@ -271,7 +274,7 @@ define([ length /= 3; var i; var iLength = indices.length; - var newIndices = IndexDatatype.createTypedArray(newPositions.length / 3, (iLength + length) * 2); + var newIndices = IndexDatatype.createTypedArray(newPositions.length / 3, (iLength + wallIndices.length) * 2); newIndices.set(indices); var index = iLength; for (i = 0; i < iLength; i+=2) { // bottom indices @@ -282,8 +285,8 @@ define([ } var UL, LL; - for (i = 0; i < length; i++) { //wall indices - UL = i; + for (i = 0; i < wallIndices.length; i++) { //wall indices + UL = wallIndices[i]; LL = UL + length; newIndices[index++] = UL; newIndices[index++] = LL; diff --git a/Specs/Core/CorridorOutlineGeometrySpec.js b/Specs/Core/CorridorOutlineGeometrySpec.js new file mode 100644 index 000000000000..a6a67ccf0fd7 --- /dev/null +++ b/Specs/Core/CorridorOutlineGeometrySpec.js @@ -0,0 +1,144 @@ +/*global defineSuite*/ +defineSuite([ + 'Core/CorridorOutlineGeometry', + 'Core/CornerType', + 'Core/Cartesian3', + 'Core/Cartographic', + 'Core/Ellipsoid', + 'Core/Math' + ], function( + CorridorOutlineGeometry, + CornerType, + Cartesian3, + Cartographic, + Ellipsoid, + CesiumMath) { + "use strict"; + /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ + + it('throws without positions', function() { + expect(function() { + return new CorridorOutlineGeometry({}); + }).toThrow(); + }); + + it('throws without 2 unique positions', function() { + expect(function() { + var ellipsoid = Ellipsoid.WGS84; + return CorridorOutlineGeometry.createGeometry(new CorridorOutlineGeometry({ + positions : ellipsoid.cartographicArrayToCartesianArray([ + Cartographic.fromDegrees(90.0, -30.0), + Cartographic.fromDegrees(90.0, -30.0) + ]), + width: 10000 + })); + }).toThrow(); + }); + + it('throws without width', function() { + expect(function() { + return new CorridorOutlineGeometry({ + positions: [new Cartesian3()] + }); + }).toThrow(); + }); + + it('computes positions', function() { + var ellipsoid = Ellipsoid.WGS84; + var m = CorridorOutlineGeometry.createGeometry(new CorridorOutlineGeometry({ + positions : ellipsoid.cartographicArrayToCartesianArray([ + Cartographic.fromDegrees(90.0, -30.0), + Cartographic.fromDegrees(90.0, -35.0) + ]), + cornerType: CornerType.MITERED, + width : 30000 + })); + + expect(m.attributes.position.values.length).toEqual(3 * 12); + expect(m.indices.length).toEqual(2 * 12); + }); + + it('computes positions extruded', function() { + var ellipsoid = Ellipsoid.WGS84; + var m = CorridorOutlineGeometry.createGeometry(new CorridorOutlineGeometry({ + positions : ellipsoid.cartographicArrayToCartesianArray([ + Cartographic.fromDegrees(90.0, -30.0), + Cartographic.fromDegrees(90.0, -35.0) + ]), + cornerType: CornerType.MITERED, + width : 30000, + extrudedHeight: 30000 + })); + + expect(m.attributes.position.values.length).toEqual(3 * 24); + expect(m.indices.length).toEqual(2 * 12 * 2 + 8); + }); + + it('computes right turn', function() { + var ellipsoid = Ellipsoid.WGS84; + var m = CorridorOutlineGeometry.createGeometry(new CorridorOutlineGeometry({ + positions : ellipsoid.cartographicArrayToCartesianArray([ + Cartographic.fromDegrees(90.0, -30.0), + Cartographic.fromDegrees(90.0, -31.0), + Cartographic.fromDegrees(91.0, -31.0) + ]), + cornerType: CornerType.MITERED, + width : 30000 + })); + + expect(m.attributes.position.values.length).toEqual(3 * 8); + expect(m.indices.length).toEqual(2 * 8); + }); + + it('computes left turn', function() { + var ellipsoid = Ellipsoid.WGS84; + var m = CorridorOutlineGeometry.createGeometry(new CorridorOutlineGeometry({ + positions : ellipsoid.cartographicArrayToCartesianArray([ + Cartographic.fromDegrees(90.0, -30.0), + Cartographic.fromDegrees(90.0, -31.0), + Cartographic.fromDegrees(89.0, -31.0) + ]), + cornerType: CornerType.MITERED, + width : 30000 + })); + + expect(m.attributes.position.values.length).toEqual(3 * 8); + expect(m.indices.length).toEqual(2 * 8); + }); + + it('computes with rounded corners', function() { + var ellipsoid = Ellipsoid.WGS84; + var m = CorridorOutlineGeometry.createGeometry(new CorridorOutlineGeometry({ + positions : ellipsoid.cartographicArrayToCartesianArray([ + Cartographic.fromDegrees(90.0, -30.0), + Cartographic.fromDegrees(90.0, -31.0), + Cartographic.fromDegrees(89.0, -31.0), + Cartographic.fromDegrees(89.0, -32.0) + ]), + cornerType: CornerType.ROUNDED, + width : 30000 + })); + + var endCaps = 180/5*2; + var corners = 90/5*2; + expect(m.attributes.position.values.length).toEqual(3 * (11 + endCaps + corners)); + expect(m.indices.length).toEqual(2 * (11 + endCaps + corners)); + }); + + it('computes with beveled corners', function() { + var ellipsoid = Ellipsoid.WGS84; + var m = CorridorOutlineGeometry.createGeometry(new CorridorOutlineGeometry({ + positions : ellipsoid.cartographicArrayToCartesianArray([ + Cartographic.fromDegrees(90.0, -30.0), + Cartographic.fromDegrees(90.0, -31.0), + Cartographic.fromDegrees(89.0, -31.0), + Cartographic.fromDegrees(89.0, -32.0) + ]), + cornerType: CornerType.BEVELED, + width : 30000 + })); + + expect(m.attributes.position.values.length).toEqual(3 * 10); + expect(m.indices.length).toEqual(2 * 10); + }); +}); \ No newline at end of file From c4f5d89d7e3289b0cc1c36276044c19391ba19a7 Mon Sep 17 00:00:00 2001 From: hpinkos Date: Fri, 30 Aug 2013 14:17:28 -0400 Subject: [PATCH 4/9] sandcastle example --- .../gallery/Geometry and Appearances.html | 77 +++++++++++++------ CHANGES.md | 2 +- 2 files changed, 55 insertions(+), 24 deletions(-) diff --git a/Apps/Sandcastle/gallery/Geometry and Appearances.html b/Apps/Sandcastle/gallery/Geometry and Appearances.html index f52debae95d7..d37d62e0db13 100644 --- a/Apps/Sandcastle/gallery/Geometry and Appearances.html +++ b/Apps/Sandcastle/gallery/Geometry and Appearances.html @@ -778,49 +778,80 @@ }) })); - var corridor = new Cesium.CorridorGeometry({ - positions : ellipsoid.cartographicArrayToCartesianArray([ - Cesium.Cartographic.fromDegrees(-120.0, 45.0), - Cesium.Cartographic.fromDegrees(-125.0, 50.0), - Cesium.Cartographic.fromDegrees(-125.0, 55.0) - ]), - width : 100000, - vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT + positions = ellipsoid.cartographicArrayToCartesianArray([ + Cesium.Cartographic.fromDegrees(-120.0, 45.0), + Cesium.Cartographic.fromDegrees(-125.0, 50.0), + Cesium.Cartographic.fromDegrees(-125.0, 55.0) + ]); + var width = 100000; + + var corridor = new Cesium.GeometryInstance({ + geometry: new Cesium.CorridorGeometry({ + positions : positions, + width : width, + vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT + }), + attributes : { + color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromRandom({alpha : 1.0})) + } }); - var corridorInstance = new Cesium.GeometryInstance({ - geometry: corridor, + var extrudedCorridor = new Cesium.GeometryInstance({ + geometry: new Cesium.CorridorGeometry({ + positions : positions, + width : width, + vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, + height: 300000, + extrudedHeight: 400000 + }), attributes : { color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromRandom({alpha : 1.0})) } }); - var extrudedCorridor = new Cesium.CorridorGeometry({ - positions : ellipsoid.cartographicArrayToCartesianArray([ - Cesium.Cartographic.fromDegrees(-120.0, 45.0), - Cesium.Cartographic.fromDegrees(-125.0, 50.0), - Cesium.Cartographic.fromDegrees(-125.0, 55.0) - ]), - width : 100000, - vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, - height: 300000, - extrudedHeight: 400000 + var corridorOutline = new Cesium.GeometryInstance({ + geometry: new Cesium.CorridorOutlineGeometry( { + positions: positions, + width: width, + height: 700000 + }), + attributes: { + color : solidWhite + } }); - var extrudedCorridorInstance = new Cesium.GeometryInstance({ - geometry: extrudedCorridor, + var corridorFill = new Cesium.GeometryInstance({ + geometry: new Cesium.CorridorGeometry({ + positions : positions, + width : width, + vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT, + height: 700000 + }), attributes : { color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromRandom({alpha : 1.0})) } }); primitives.add(new Cesium.Primitive({ - geometryInstances : [corridorInstance, extrudedCorridorInstance], + geometryInstances : [corridor, extrudedCorridor, corridorFill], appearance : new Cesium.PerInstanceColorAppearance({ translucent : false, closed : true }) })); + + primitives.add(new Cesium.Primitive({ + geometryInstances : corridorOutline, + appearance : new Cesium.PerInstanceColorAppearance({ + flat : true, + renderState : { + depthTest : { + enabled : true + }, + lineWidth : Math.min(4.0, scene.getContext().getMaximumAliasedLineWidth()) + } + }) + })); Sandcastle.finishedLoading(); }); diff --git a/CHANGES.md b/CHANGES.md index 5a8b46362473..5efeb86c7fa5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -81,7 +81,7 @@ var geometry = BoxGeometry.createGeometry(box); * Fixed triangulation for polygons that cross the international date line. * Fixed `EllipsoidPrimitive` rendering for some oblate ellipsoids. [#1067](https://github.com/AnalyticalGraphicsInc/cesium/pull/1067). * Upgraded Knockout from version 2.2.1 to 2.3.0. -* Added `CorridorGeometry`. +* Added `CorridorGeometry` and `CorridorGeometryOutline. ### b19 - 2013-08-01 From 110a0520ac0fa7cb3f7d7c1a6d6965ad7588104f Mon Sep 17 00:00:00 2001 From: hpinkos Date: Fri, 30 Aug 2013 16:36:55 -0400 Subject: [PATCH 5/9] clean up from merge --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index ec5a2c5de9fa..57d5c65a0b24 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -83,7 +83,7 @@ var geometry = BoxGeometry.createGeometry(box); * Fixed triangulation for polygons that cross the international date line. * Fixed `EllipsoidPrimitive` rendering for some oblate ellipsoids. [#1067](https://github.com/AnalyticalGraphicsInc/cesium/pull/1067). * Upgraded Knockout from version 2.2.1 to 2.3.0. -* Added `CorridorGeometry`. + ### b19 - 2013-08-01 * Breaking changes: From eaecef1d63b3d26c89a515d148bbcca210787cc5 Mon Sep 17 00:00:00 2001 From: hpinkos Date: Tue, 3 Sep 2013 13:51:07 -0400 Subject: [PATCH 6/9] fix bounding spheres --- CHANGES.md | 5 +- Source/Core/CorridorGeometry.js | 21 ++--- Source/Core/CorridorGeometryLibrary.js | 30 ++++++-- Source/Core/CorridorOutlineGeometry.js | 102 ++++++++++++------------- 4 files changed, 85 insertions(+), 73 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 01f042c81fed..f85e84649901 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,9 @@ Change Log Beta Releases ------------- +### b21 - 2013-10-01 +* Added `CorridorOutlineGeometry`. + ### b20 - 2013-09-03 _This releases fixes 2D and other issues with Chrome 29.0.1547.57 ([#1002](https://github.com/AnalyticalGraphicsInc/cesium/issues/1002) and [#1047](https://github.com/AnalyticalGraphicsInc/cesium/issues/1047))._ @@ -59,7 +62,7 @@ var geometry = BoxGeometry.createGeometry(box); * Replaced `createPickFragmentShaderSource` with `createShaderSource`. * Renamed `PolygonPipeline.earClip2D` to `PolygonPipeline.triangulate`. * Added outline geometries. [#1021](https://github.com/AnalyticalGraphicsInc/cesium/pull/1021). -* Added `CorridorGeometry` and `CorridorOutlineGeometry`. +* Added `CorridorGeometry`. * Added `Billboard.scaleByDistance` and `NearFarScalar` to control billboard minimum/maximum scale based on camera distance. * Added `EllipsoidGeodesic`. * Added `PolylinePipeline.scaleToSurface`. diff --git a/Source/Core/CorridorGeometry.js b/Source/Core/CorridorGeometry.js index 707e91cab1a9..be95084c17c1 100644 --- a/Source/Core/CorridorGeometry.js +++ b/Source/Core/CorridorGeometry.js @@ -410,8 +410,7 @@ define([ return { attributes : attributes, - indices : indices, - boundingSphere : BoundingSphere.fromVertices(finalPositions) + indices : indices }; } @@ -567,7 +566,6 @@ define([ var extrudedHeight = params.extrudedHeight; var attributes = attr.attributes; var indices = attr.indices; - var boundingSphere = attr.boundingSphere; var positions = attributes.position.values; var length = positions.length; var newPositions = new Float64Array(length * 6); @@ -582,7 +580,6 @@ define([ newPositions.set(positions); newPositions.set(extrudedPositions, length); newPositions.set(wallPositions, length * 2); - boundingSphere = BoundingSphere.fromVertices(positions, undefined, 3, boundingSphere); attributes.position.values = newPositions; length /= 3; @@ -619,8 +616,7 @@ define([ return { attributes : attributes, - indices : newIndices, - boundingSphere : boundingSphere + indices : newIndices }; } @@ -716,20 +712,19 @@ define([ } else { var computedPositions = CorridorGeometryLibrary.computePositions(params); attr = combine(computedPositions, vertexFormat, ellipsoid); - if (!vertexFormat.position) { - attr.attributes.position.values = undefined; - } else { - attr.attributes.position.values = new Float64Array(PolylinePipeline.scaleToGeodeticHeight(attr.attributes.position.values, height, ellipsoid, attr.attributes.position.values)); - } - + attr.attributes.position.values = new Float64Array(PolylinePipeline.scaleToGeodeticHeight(attr.attributes.position.values, height, ellipsoid, attr.attributes.position.values)); } var attributes = attr.attributes; + var boundingSphere = BoundingSphere.fromVertices(attributes.position.values, undefined, 3); + if (!vertexFormat.position) { + attr.attributes.position.values = undefined; + } return new Geometry({ attributes : attributes, indices : attr.indices, primitiveType : PrimitiveType.TRIANGLES, - boundingSphere : attr.boundingSphere + boundingSphere : boundingSphere }); }; diff --git a/Source/Core/CorridorGeometryLibrary.js b/Source/Core/CorridorGeometryLibrary.js index 2fa3a4a7270b..5389bb904c22 100644 --- a/Source/Core/CorridorGeometryLibrary.js +++ b/Source/Core/CorridorGeometryLibrary.js @@ -22,7 +22,7 @@ define([ "use strict"; /** - * private + * @private */ var CorridorGeometryLibrary = {}; @@ -47,6 +47,9 @@ define([ var originScratch = new Cartesian3(); var nextScratch = new Cartesian3(); var prevScratch = new Cartesian3(); + /** + * @private + */ CorridorGeometryLibrary.angleIsGreaterThanPi = function(forward, backward, position, ellipsoid) { var tangentPlane = new EllipsoidTangentPlane(position, ellipsoid); var origin = tangentPlane.projectPointOntoPlane(position, originScratch); @@ -61,6 +64,9 @@ define([ var quaterion = new Quaternion(); var rotMatrix = new Matrix3(); + /** + * @private + */ CorridorGeometryLibrary.computeRoundCorner = function (cornerPoint, startPoint, endPoint, cornerType, leftIsOutside, ellipsoid) { var angle = Cartesian3.angleBetween(startPoint.subtract(cornerPoint, scratch1), endPoint.subtract(cornerPoint, scratch2)); var granularity = (cornerType.value === CornerType.BEVELED.value) ? 1 : Math.ceil(angle / CesiumMath.toRadians(5)) + 1; @@ -91,6 +97,9 @@ define([ return array; }; + /** + * @private + */ CorridorGeometryLibrary.addEndCaps = function (calculatedPositions, width, ellipsoid) { var cornerPoint = cartesian1; var startPoint = cartesian2; @@ -113,6 +122,9 @@ define([ return [firstEndCap, lastEndCap]; }; + /** + * @private + */ CorridorGeometryLibrary.computeMiteredCorner = function (position, startPoint, leftCornerDirection, lastPoint, leftIsOutside, granularity, ellipsoid) { var cornerPoint = scratch1; if (leftIsOutside) { @@ -124,6 +136,9 @@ define([ return [cornerPoint.x, cornerPoint.y, cornerPoint.z, lastPoint.x, lastPoint.y, lastPoint.z]; }; + /** + * @private + */ CorridorGeometryLibrary.addAttribute = function (attribute, value, front, back) { var x = value.x; var y = value.y; @@ -140,7 +155,7 @@ define([ } }; - CorridorGeometryLibrary.addShiftedPositions = function(positions, left, scalar, calculatedPositions) { + function addShiftedPositions (positions, left, scalar, calculatedPositions) { var rightPositions = new Array(positions.length); var leftPositions = new Array(positions.length); var scaledLeft = left.multiplyByScalar(scalar, scratch1); @@ -163,8 +178,11 @@ define([ calculatedPositions.push(rightPositions, leftPositions); return calculatedPositions; - }; + } + /** + * @private + */ CorridorGeometryLibrary.computePositions = function (params) { var granularity = params.granularity; var positions = params.positions; @@ -222,7 +240,7 @@ define([ scaleArray2[0] = Cartesian3.clone(previousPos, scaleArray2[0]); scaleArray2[1] = Cartesian3.clone(center, scaleArray2[1]); subdividedPositions = PolylinePipeline.scaleToSurface(scaleArray2, granularity, ellipsoid); - calculatedPositions = CorridorGeometryLibrary.addShiftedPositions(subdividedPositions, left, width, calculatedPositions); + calculatedPositions = addShiftedPositions(subdividedPositions, left, width, calculatedPositions); if (saveAttributes) { calculatedLefts.push(left.x, left.y, left.z); calculatedNormals.push(normal.x, normal.y, normal.z); @@ -243,7 +261,7 @@ define([ scaleArray2[0] = Cartesian3.clone(previousPos, scaleArray2[0]); scaleArray2[1] = Cartesian3.clone(center, scaleArray2[1]); subdividedPositions = PolylinePipeline.scaleToSurface(scaleArray2, granularity, ellipsoid); - calculatedPositions = CorridorGeometryLibrary.addShiftedPositions(subdividedPositions, left, width, calculatedPositions); + calculatedPositions = addShiftedPositions(subdividedPositions, left, width, calculatedPositions); if (saveAttributes) { calculatedLefts.push(left.x, left.y, left.z); calculatedNormals.push(normal.x, normal.y, normal.z); @@ -267,7 +285,7 @@ define([ scaleArray2[0] = Cartesian3.clone(previousPos, scaleArray2[0]); scaleArray2[1] = Cartesian3.clone(position, scaleArray2[1]); subdividedPositions = PolylinePipeline.scaleToSurface(scaleArray2, granularity, ellipsoid); - calculatedPositions = CorridorGeometryLibrary.addShiftedPositions(subdividedPositions, left, width, calculatedPositions); + calculatedPositions = addShiftedPositions(subdividedPositions, left, width, calculatedPositions); if (saveAttributes) { calculatedLefts.push(left.x, left.y, left.z); calculatedNormals.push(normal.x, normal.y, normal.z); diff --git a/Source/Core/CorridorOutlineGeometry.js b/Source/Core/CorridorOutlineGeometry.js index d0cd9c939748..05cc1623d462 100644 --- a/Source/Core/CorridorOutlineGeometry.js +++ b/Source/Core/CorridorOutlineGeometry.js @@ -54,7 +54,7 @@ define([ for (i = 0; i < positions.length; i += 2) { length = positions[i].length - 3; leftCount += length; //subtracting 3 to account for duplicate points at corners - indicesLength += length/3*4; + indicesLength += length / 3 * 4; rightCount += positions[i + 1].length - 3; } leftCount += 3; //add back count for end positions @@ -65,11 +65,11 @@ define([ if (defined(leftSide)) { length = leftSide.length; leftCount += length; - indicesLength += length/3*2; + indicesLength += length / 3 * 2; } else { length = corners[i].rightPositions.length; rightCount += length; - indicesLength += length/3*2; + indicesLength += length / 3 * 2; } } @@ -88,15 +88,15 @@ define([ var back = size - 1; var UL, LL, UR, LR; var rightPos, leftPos; - var halfLength = endPositionLength/2; + var halfLength = endPositionLength / 2; - var indices = IndexDatatype.createTypedArray(size/3, indicesLength + 4); + var indices = IndexDatatype.createTypedArray(size / 3, indicesLength + 4); var index = 0; - indices[index++] = front/3; - indices[index++] = (back-2)/3; + indices[index++] = front / 3; + indices[index++] = (back - 2) / 3; if (addEndPositions) { // add rounded end - wallIndices.push(front/3); + wallIndices.push(front / 3); leftPos = cartesian1; rightPos = cartesian2; var firstEndPositions = endPositions[0]; @@ -106,9 +106,9 @@ define([ CorridorGeometryLibrary.addAttribute(finalPositions, rightPos, front); CorridorGeometryLibrary.addAttribute(finalPositions, leftPos, undefined, back); - LL = front/3; + LL = front / 3; LR = LL + 1; - UL = (back-2)/3; + UL = (back - 2) / 3; UR = UL - 1; indices[index++] = UL; indices[index++] = UR; @@ -121,24 +121,23 @@ define([ } var posIndex = 0; - var rightEdge = positions[posIndex++]; //add first two edges + var rightEdge = positions[posIndex++]; //add first two edges var leftEdge = positions[posIndex++]; finalPositions.set(rightEdge, front); finalPositions.set(leftEdge, back - leftEdge.length + 1); length = leftEdge.length - 3; - wallIndices.push(front/3, (back-2)/3); - for(i = 0; i < length; i+=3) { - LL = front/3; + wallIndices.push(front / 3, (back - 2) / 3); + for (i = 0; i < length; i += 3) { + LL = front / 3; LR = LL + 1; - UL = (back-2)/3; + UL = (back - 2) / 3; UR = UL - 1; indices[index++] = UL; indices[index++] = UR; indices[index++] = LL; indices[index++] = LR; - front += 3; back -= 3; } @@ -154,27 +153,27 @@ define([ back -= 3; start = UR; wallIndices.push(start, LR); - for (j = 0; j < l.length/3; j++) { - outsidePoint = Cartesian3.fromArray(l, j*3, outsidePoint); + for (j = 0; j < l.length / 3; j++) { + outsidePoint = Cartesian3.fromArray(l, j * 3, outsidePoint); indices[index++] = start - j - 1; indices[index++] = start - j; CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, undefined, back); back -= 3; } - wallIndices.push(start - Math.floor(l.length/6), (back-2)/3 + 1); + wallIndices.push(start - Math.floor(l.length / 6), (back - 2) / 3 + 1); front += 3; } else { front += 3; start = LR; wallIndices.push(start, UR); - for (j = 0; j < r.length/3; j++) { - outsidePoint = Cartesian3.fromArray(r, j*3, outsidePoint); + for (j = 0; j < r.length / 3; j++) { + outsidePoint = Cartesian3.fromArray(r, j * 3, outsidePoint); indices[index++] = start + j; indices[index++] = start + j + 1; CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, front); front += 3; } - wallIndices.push(start + Math.floor(r.length/6), front/3 - 1); + wallIndices.push(start + Math.floor(r.length / 6), front / 3 - 1); back -= 3; } rightEdge = positions[posIndex++]; @@ -185,10 +184,10 @@ define([ finalPositions.set(leftEdge, back - leftEdge.length + 1); length = leftEdge.length - 3; - for(j = 0; j < leftEdge.length; j+=3) { - LR = front/3; + for (j = 0; j < leftEdge.length; j += 3) { + LR = front / 3; LL = LR - 1; - UR = (back-2)/3; + UR = (back - 2) / 3; UL = UR + 1; indices[index++] = UL; indices[index++] = UR; @@ -199,10 +198,10 @@ define([ } front -= 3; back += 3; - wallIndices.push(front/3, (back-2)/3); + wallIndices.push(front / 3, (back - 2) / 3); } - if (addEndPositions) { // add rounded end + if (addEndPositions) { // add rounded end front += 3; back -= 3; leftPos = cartesian1; @@ -214,9 +213,9 @@ define([ CorridorGeometryLibrary.addAttribute(finalPositions, leftPos, undefined, back); CorridorGeometryLibrary.addAttribute(finalPositions, rightPos, front); - LR = front/3; + LR = front / 3; LL = LR - 1; - UR = (back-2)/3; + UR = (back - 2) / 3; UL = UR + 1; indices[index++] = UL; indices[index++] = UR; @@ -227,11 +226,11 @@ define([ back -= 3; } } - indices[index++] = front/3; - indices[index++] = (back-2)/3; + indices[index++] = front / 3; + indices[index++] = (back - 2) / 3; if (i === 0) { - wallIndices.push(front/3, (back-2)/3); + wallIndices.push(front / 3, (back - 2) / 3); } attributes.position = new GeometryAttribute({ @@ -241,10 +240,9 @@ define([ }); return { - attributes: attributes, - indices: indices, - boundingSphere: BoundingSphere.fromVertices(finalPositions), - wallIndices: wallIndices + attributes : attributes, + indices : indices, + wallIndices : wallIndices }; } @@ -257,7 +255,6 @@ define([ var extrudedHeight = params.extrudedHeight; var attributes = attr.attributes; var indices = attr.indices; - var boundingSphere = attr.boundingSphere; var positions = attributes.position.values; var length = positions.length; var extrudedPositions = new Float64Array(length); @@ -268,7 +265,6 @@ define([ extrudedPositions = PolylinePipeline.scaleToGeodeticHeight(extrudedPositions, extrudedHeight, ellipsoid); newPositions.set(positions); newPositions.set(extrudedPositions, length); - boundingSphere = BoundingSphere.fromVertices(positions, undefined, 3, boundingSphere); attributes.position.values = newPositions; length /= 3; @@ -277,7 +273,7 @@ define([ var newIndices = IndexDatatype.createTypedArray(newPositions.length / 3, (iLength + wallIndices.length) * 2); newIndices.set(indices); var index = iLength; - for (i = 0; i < iLength; i+=2) { // bottom indices + for (i = 0; i < iLength; i += 2) { // bottom indices var v0 = indices[i]; var v1 = indices[i + 1]; newIndices[index++] = v0 + length; @@ -293,20 +289,19 @@ define([ } return { - attributes: attributes, - indices: newIndices, - boundingSphere: boundingSphere + attributes : attributes, + indices : newIndices }; } /** - * A description of a corridor. + * A description of a corridor outline. * * @alias CorridorOutlineGeometry * @constructor * - * @param {Array} options.positions An array of {Cartesain3} positions that define the center of the corridor. - * @param {Number} options.width The distance between the edges of the corridor. + * @param {Array} options.positions An array of {Cartesain3} positions that define the center of the corridor outline. + * @param {Number} options.width The distance between the edges of the corridor outline. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference. * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer. * @param {Number} [options.height=0] The distance between the ellipsoid surface and the positions. @@ -369,12 +364,12 @@ define([ } var ellipsoid = corridorOutlineGeometry._ellipsoid; var params = { - ellipsoid: ellipsoid, - positions: cleanPositions, - width: corridorOutlineGeometry._width, - cornerType: corridorOutlineGeometry._cornerType, - granularity: corridorOutlineGeometry._granularity, - saveAttributes: false + ellipsoid : ellipsoid, + positions : cleanPositions, + width : corridorOutlineGeometry._width, + cornerType : corridorOutlineGeometry._cornerType, + granularity : corridorOutlineGeometry._granularity, + saveAttributes : false }; var attr; if (extrude) { @@ -390,12 +385,13 @@ define([ attr.attributes.position.values = new Float64Array(PolylinePipeline.scaleToGeodeticHeight(attr.attributes.position.values, height, ellipsoid)); } var attributes = attr.attributes; + var boundingSphere = BoundingSphere.fromVertices(attributes.position.values, undefined, 3); return new Geometry({ attributes : attributes, - indices : IndexDatatype.createTypedArray(attributes.position.values.length/3, attr.indices), + indices : attr.indices, primitiveType : PrimitiveType.LINES, - boundingSphere : attr.boundingSphere + boundingSphere : boundingSphere }); }; From ad44696fe3f576467d6eefa9c4f648279d0ace7e Mon Sep 17 00:00:00 2001 From: hpinkos Date: Tue, 3 Sep 2013 14:33:11 -0400 Subject: [PATCH 7/9] corner type doc, change extruded lines --- Source/Core/CornerType.js | 15 ++++++++++++++ Source/Core/CorridorOutlineGeometry.js | 28 ++++++++++++++++---------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/Source/Core/CornerType.js b/Source/Core/CornerType.js index 63eeb7ccc65e..8029fa6ff164 100644 --- a/Source/Core/CornerType.js +++ b/Source/Core/CornerType.js @@ -7,6 +7,11 @@ define(['../Core/Enumeration'], function(Enumeration) { */ var CornerType = { /** + * ___ + * ( ___ + * | | + * + * Corner is circular. * @type {Enumeration} * @constant * @default 0 @@ -14,6 +19,11 @@ define(['../Core/Enumeration'], function(Enumeration) { ROUNDED : new Enumeration(0, 'ROUNDED'), /** + * ______ + * | ___ + * | | + * + * Corner point is the intersection of adjacent edges. * @type {Enumeration} * @constant * @default 1 @@ -21,6 +31,11 @@ define(['../Core/Enumeration'], function(Enumeration) { MITERED : new Enumeration(1, 'MITERED'), /** + * ___ + * / ___ + * | | + * + * Corner is clipped. * @type {Enumeration} * @constant * @default 2 diff --git a/Source/Core/CorridorOutlineGeometry.js b/Source/Core/CorridorOutlineGeometry.js index 05cc1623d462..dd714c7a5995 100644 --- a/Source/Core/CorridorOutlineGeometry.js +++ b/Source/Core/CorridorOutlineGeometry.js @@ -39,7 +39,7 @@ define([ var cartesian2 = new Cartesian3(); var cartesian3 = new Cartesian3(); - function combine(computedPositions, ellipsoid) { + function combine(computedPositions, ellipsoid, cornerType) { var wallIndices = []; var positions = computedPositions.positions; var corners = computedPositions.corners; @@ -152,7 +152,7 @@ define([ if (defined(l)) { back -= 3; start = UR; - wallIndices.push(start, LR); + wallIndices.push(LR); for (j = 0; j < l.length / 3; j++) { outsidePoint = Cartesian3.fromArray(l, j * 3, outsidePoint); indices[index++] = start - j - 1; @@ -160,12 +160,15 @@ define([ CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, undefined, back); back -= 3; } - wallIndices.push(start - Math.floor(l.length / 6), (back - 2) / 3 + 1); + wallIndices.push(start - Math.floor(l.length / 6)); + if (cornerType.value === CornerType.BEVELED.value) { + wallIndices.push((back - 2) / 3 + 1); + } front += 3; } else { front += 3; start = LR; - wallIndices.push(start, UR); + wallIndices.push(UR); for (j = 0; j < r.length / 3; j++) { outsidePoint = Cartesian3.fromArray(r, j * 3, outsidePoint); indices[index++] = start + j; @@ -173,7 +176,10 @@ define([ CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, front); front += 3; } - wallIndices.push(start + Math.floor(r.length / 6), front / 3 - 1); + wallIndices.push(start + Math.floor(r.length / 6)); + if (cornerType.value === CornerType.BEVELED.value) { + wallIndices.push(front / 3 - 1); + } back -= 3; } rightEdge = positions[posIndex++]; @@ -225,13 +231,13 @@ define([ front += 3; back -= 3; } - } - indices[index++] = front / 3; - indices[index++] = (back - 2) / 3; - if (i === 0) { + wallIndices.push(front / 3); + } else { wallIndices.push(front / 3, (back - 2) / 3); } + indices[index++] = front / 3; + indices[index++] = (back - 2) / 3; attributes.position = new GeometryAttribute({ componentDatatype : ComponentDatatype.DOUBLE, @@ -249,7 +255,7 @@ define([ function computePositionsExtruded(params) { var ellipsoid = params.ellipsoid; var computedPositions = CorridorGeometryLibrary.computePositions(params); - var attr = combine(computedPositions, ellipsoid); + var attr = combine(computedPositions, ellipsoid, params.cornerType); var wallIndices = attr.wallIndices; var height = params.height; var extrudedHeight = params.extrudedHeight; @@ -381,7 +387,7 @@ define([ attr = computePositionsExtruded(params); } else { var computedPositions = CorridorGeometryLibrary.computePositions(params); - attr = combine(computedPositions, ellipsoid); + attr = combine(computedPositions, ellipsoid, params.cornerType); attr.attributes.position.values = new Float64Array(PolylinePipeline.scaleToGeodeticHeight(attr.attributes.position.values, height, ellipsoid)); } var attributes = attr.attributes; From ed1b20182ae7e3035fc15245ac5a7f7ec57ab47e Mon Sep 17 00:00:00 2001 From: hpinkos Date: Tue, 3 Sep 2013 15:24:22 -0400 Subject: [PATCH 8/9] correct scale to height --- Source/Core/CorridorGeometry.js | 2 +- Source/Core/CorridorOutlineGeometry.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Core/CorridorGeometry.js b/Source/Core/CorridorGeometry.js index be95084c17c1..40144bb74be4 100644 --- a/Source/Core/CorridorGeometry.js +++ b/Source/Core/CorridorGeometry.js @@ -712,7 +712,7 @@ define([ } else { var computedPositions = CorridorGeometryLibrary.computePositions(params); attr = combine(computedPositions, vertexFormat, ellipsoid); - attr.attributes.position.values = new Float64Array(PolylinePipeline.scaleToGeodeticHeight(attr.attributes.position.values, height, ellipsoid, attr.attributes.position.values)); + attr.attributes.position.values = PolylinePipeline.scaleToGeodeticHeight(attr.attributes.position.values, height, ellipsoid, attr.attributes.position.values); } var attributes = attr.attributes; var boundingSphere = BoundingSphere.fromVertices(attributes.position.values, undefined, 3); diff --git a/Source/Core/CorridorOutlineGeometry.js b/Source/Core/CorridorOutlineGeometry.js index dd714c7a5995..16d6ad6768da 100644 --- a/Source/Core/CorridorOutlineGeometry.js +++ b/Source/Core/CorridorOutlineGeometry.js @@ -268,7 +268,7 @@ define([ var newPositions = new Float64Array(length * 2); positions = PolylinePipeline.scaleToGeodeticHeight(positions, height, ellipsoid, positions); - extrudedPositions = PolylinePipeline.scaleToGeodeticHeight(extrudedPositions, extrudedHeight, ellipsoid); + extrudedPositions = PolylinePipeline.scaleToGeodeticHeight(extrudedPositions, extrudedHeight, ellipsoid, extrudedPositions); newPositions.set(positions); newPositions.set(extrudedPositions, length); attributes.position.values = newPositions; @@ -388,7 +388,7 @@ define([ } else { var computedPositions = CorridorGeometryLibrary.computePositions(params); attr = combine(computedPositions, ellipsoid, params.cornerType); - attr.attributes.position.values = new Float64Array(PolylinePipeline.scaleToGeodeticHeight(attr.attributes.position.values, height, ellipsoid)); + attr.attributes.position.values = PolylinePipeline.scaleToGeodeticHeight(attr.attributes.position.values, height, ellipsoid, attr.attributes.position.values); } var attributes = attr.attributes; var boundingSphere = BoundingSphere.fromVertices(attributes.position.values, undefined, 3); From 81eda88f89c4f72d3d0ca61e400e62e75f29cea2 Mon Sep 17 00:00:00 2001 From: hpinkos Date: Tue, 3 Sep 2013 15:29:15 -0400 Subject: [PATCH 9/9] change functions to file scope --- Source/Core/CorridorGeometryLibrary.js | 82 +++++++++++--------------- 1 file changed, 35 insertions(+), 47 deletions(-) diff --git a/Source/Core/CorridorGeometryLibrary.js b/Source/Core/CorridorGeometryLibrary.js index 5389bb904c22..ca85eba490da 100644 --- a/Source/Core/CorridorGeometryLibrary.js +++ b/Source/Core/CorridorGeometryLibrary.js @@ -47,10 +47,7 @@ define([ var originScratch = new Cartesian3(); var nextScratch = new Cartesian3(); var prevScratch = new Cartesian3(); - /** - * @private - */ - CorridorGeometryLibrary.angleIsGreaterThanPi = function(forward, backward, position, ellipsoid) { + function angleIsGreaterThanPi (forward, backward, position, ellipsoid) { var tangentPlane = new EllipsoidTangentPlane(position, ellipsoid); var origin = tangentPlane.projectPointOntoPlane(position, originScratch); var next = tangentPlane.projectPointOntoPlane(Cartesian3.add(position, forward, nextScratch), nextScratch); @@ -60,14 +57,11 @@ define([ next = Cartesian2.subtract(next, origin, next); return ((prev.x * next.y) - (prev.y * next.x)) >= 0.0; - }; + } var quaterion = new Quaternion(); var rotMatrix = new Matrix3(); - /** - * @private - */ - CorridorGeometryLibrary.computeRoundCorner = function (cornerPoint, startPoint, endPoint, cornerType, leftIsOutside, ellipsoid) { + function computeRoundCorner (cornerPoint, startPoint, endPoint, cornerType, leftIsOutside, ellipsoid) { var angle = Cartesian3.angleBetween(startPoint.subtract(cornerPoint, scratch1), endPoint.subtract(cornerPoint, scratch2)); var granularity = (cornerType.value === CornerType.BEVELED.value) ? 1 : Math.ceil(angle / CesiumMath.toRadians(5)) + 1; @@ -95,12 +89,9 @@ define([ } return array; - }; + } - /** - * @private - */ - CorridorGeometryLibrary.addEndCaps = function (calculatedPositions, width, ellipsoid) { + function addEndCaps (calculatedPositions, width, ellipsoid) { var cornerPoint = cartesian1; var startPoint = cartesian2; var endPoint = cartesian3; @@ -109,7 +100,7 @@ define([ startPoint = Cartesian3.fromArray(calculatedPositions[1], leftEdge.length - 3, startPoint); endPoint = Cartesian3.fromArray(calculatedPositions[0], 0, endPoint); cornerPoint = startPoint.add(endPoint, cornerPoint).multiplyByScalar(0.5, cornerPoint); - var firstEndCap = CorridorGeometryLibrary.computeRoundCorner(cornerPoint, startPoint, endPoint, CornerType.ROUNDED, false, ellipsoid); + var firstEndCap = computeRoundCorner(cornerPoint, startPoint, endPoint, CornerType.ROUNDED, false, ellipsoid); var length = calculatedPositions.length - 1; var rightEdge = calculatedPositions[length - 1]; @@ -117,15 +108,12 @@ define([ startPoint = Cartesian3.fromArray(rightEdge, rightEdge.length - 3, startPoint); endPoint = Cartesian3.fromArray(leftEdge, 0, endPoint); cornerPoint = startPoint.add(endPoint, cornerPoint).multiplyByScalar(0.5, cornerPoint); - var lastEndCap = CorridorGeometryLibrary.computeRoundCorner(cornerPoint, startPoint, endPoint, CornerType.ROUNDED, false, ellipsoid); + var lastEndCap = computeRoundCorner(cornerPoint, startPoint, endPoint, CornerType.ROUNDED, false, ellipsoid); return [firstEndCap, lastEndCap]; - }; + } - /** - * @private - */ - CorridorGeometryLibrary.computeMiteredCorner = function (position, startPoint, leftCornerDirection, lastPoint, leftIsOutside, granularity, ellipsoid) { + function computeMiteredCorner (position, startPoint, leftCornerDirection, lastPoint, leftIsOutside, granularity, ellipsoid) { var cornerPoint = scratch1; if (leftIsOutside) { cornerPoint = Cartesian3.add(position, leftCornerDirection, cornerPoint); @@ -134,26 +122,7 @@ define([ cornerPoint = Cartesian3.add(position, leftCornerDirection, cornerPoint); } return [cornerPoint.x, cornerPoint.y, cornerPoint.z, lastPoint.x, lastPoint.y, lastPoint.z]; - }; - - /** - * @private - */ - CorridorGeometryLibrary.addAttribute = function (attribute, value, front, back) { - var x = value.x; - var y = value.y; - var z = value.z; - if (defined(front)) { - attribute[front] = x; - attribute[front + 1] = y; - attribute[front + 2] = z; - } - if (defined(back)) { - attribute[back] = z; - attribute[back - 1] = y; - attribute[back - 2] = x; - } - }; + } function addShiftedPositions (positions, left, scalar, calculatedPositions) { var rightPositions = new Array(positions.length); @@ -180,6 +149,25 @@ define([ return calculatedPositions; } + /** + * @private + */ + CorridorGeometryLibrary.addAttribute = function (attribute, value, front, back) { + var x = value.x; + var y = value.y; + var z = value.z; + if (defined(front)) { + attribute[front] = x; + attribute[front + 1] = y; + attribute[front + 2] = z; + } + if (defined(back)) { + attribute[back] = z; + attribute[back - 1] = y; + attribute[back - 2] = x; + } + }; + /** * @private */ @@ -231,7 +219,7 @@ define([ cornerDirection = cornerDirection.cross(normal, cornerDirection); cornerDirection = normal.cross(cornerDirection, cornerDirection); var scalar = width / Math.max(0.25, (Cartesian3.cross(cornerDirection, backward, scratch1).magnitude())); - var leftIsOutside = CorridorGeometryLibrary.angleIsGreaterThanPi(forward, backward, position, ellipsoid); + var leftIsOutside = angleIsGreaterThanPi(forward, backward, position, ellipsoid); cornerDirection = cornerDirection.multiplyByScalar(scalar, cornerDirection, cornerDirection); if (leftIsOutside) { rightPos = Cartesian3.add(position, cornerDirection, rightPos); @@ -250,9 +238,9 @@ define([ leftPos = rightPos.add(left.multiplyByScalar(width * 2, leftPos), leftPos); previousPos = rightPos.add(left.multiplyByScalar(width, previousPos), previousPos); if (cornerType.value === CornerType.ROUNDED.value || cornerType.value === CornerType.BEVELED.value) { - corners.push({leftPositions : CorridorGeometryLibrary.computeRoundCorner(rightPos, startPoint, leftPos, cornerType, leftIsOutside, ellipsoid)}); + corners.push({leftPositions : computeRoundCorner(rightPos, startPoint, leftPos, cornerType, leftIsOutside, ellipsoid)}); } else { - corners.push({leftPositions : CorridorGeometryLibrary.computeMiteredCorner(position, startPoint, cornerDirection.negate(cornerDirection), leftPos, leftIsOutside, granularity, ellipsoid)}); + corners.push({leftPositions : computeMiteredCorner(position, startPoint, cornerDirection.negate(cornerDirection), leftPos, leftIsOutside, granularity, ellipsoid)}); } } else { leftPos = Cartesian3.add(position, cornerDirection, leftPos); @@ -271,9 +259,9 @@ define([ rightPos = leftPos.add(left.multiplyByScalar(width * 2, rightPos).negate(rightPos), rightPos); previousPos = leftPos.add(left.multiplyByScalar(width, previousPos).negate(previousPos), previousPos); if (cornerType.value === CornerType.ROUNDED.value || cornerType.value === CornerType.BEVELED.value) { - corners.push({rightPositions : CorridorGeometryLibrary.computeRoundCorner(leftPos, startPoint, rightPos, cornerType, leftIsOutside, ellipsoid)}); + corners.push({rightPositions : computeRoundCorner(leftPos, startPoint, rightPos, cornerType, leftIsOutside, ellipsoid)}); } else { - corners.push({rightPositions : CorridorGeometryLibrary.computeMiteredCorner(position, startPoint, cornerDirection, rightPos, leftIsOutside, granularity, ellipsoid)}); + corners.push({rightPositions : computeMiteredCorner(position, startPoint, cornerDirection, rightPos, leftIsOutside, granularity, ellipsoid)}); } } backward = forward.negate(backward); @@ -293,7 +281,7 @@ define([ var endPositions; if (cornerType.value === CornerType.ROUNDED.value) { - endPositions = CorridorGeometryLibrary.addEndCaps(calculatedPositions, width, ellipsoid); + endPositions = addEndCaps(calculatedPositions, width, ellipsoid); } return {