cesium 0.22.0 → 0.23.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/Cesium.js +5 -2
  3. data/app/assets/javascripts/Core/Cartesian2.js +58 -0
  4. data/app/assets/javascripts/Core/Cartesian3.js +67 -7
  5. data/app/assets/javascripts/Core/Cartesian4.js +63 -0
  6. data/app/assets/javascripts/Core/CatmullRomSpline.js +183 -163
  7. data/app/assets/javascripts/Core/CorridorGeometry.js +2 -2
  8. data/app/assets/javascripts/Core/Ellipsoid.js +16 -0
  9. data/app/assets/javascripts/Core/ExtentGeometry.js +9 -2
  10. data/app/assets/javascripts/Core/ExtentOutlineGeometry.js +2 -2
  11. data/app/assets/javascripts/Core/GeometryPipeline.js +23 -23
  12. data/app/assets/javascripts/Core/HermiteSpline.js +260 -155
  13. data/app/assets/javascripts/Core/IndexDatatype.js +43 -34
  14. data/app/assets/javascripts/Core/LinearSpline.js +118 -0
  15. data/app/assets/javascripts/Core/Math.js +34 -3
  16. data/app/assets/javascripts/Core/Matrix2.js +26 -0
  17. data/app/assets/javascripts/Core/Matrix3.js +98 -0
  18. data/app/assets/javascripts/Core/Matrix4.js +42 -0
  19. data/app/assets/javascripts/Core/ObjectOrientedBoundingBox.js +396 -0
  20. data/app/assets/javascripts/Core/PolygonGeometry.js +87 -47
  21. data/app/assets/javascripts/Core/PolygonGeometryLibrary.js +20 -17
  22. data/app/assets/javascripts/Core/PolygonOutlineGeometry.js +68 -40
  23. data/app/assets/javascripts/Core/PolygonPipeline.js +19 -9
  24. data/app/assets/javascripts/Core/PrimitiveType.js +33 -36
  25. data/app/assets/javascripts/Core/Quaternion.js +147 -1
  26. data/app/assets/javascripts/Core/QuaternionSpline.js +160 -0
  27. data/app/assets/javascripts/Core/Spline.js +121 -0
  28. data/app/assets/javascripts/Core/Transforms.js +0 -2
  29. data/app/assets/javascripts/Core/loadArrayBuffer.js +5 -1
  30. data/app/assets/javascripts/Core/loadBlob.js +5 -1
  31. data/app/assets/javascripts/Core/loadText.js +4 -1
  32. data/app/assets/javascripts/Core/loadWithXhr.js +30 -14
  33. data/app/assets/javascripts/DynamicScene/PolylineOutlineMaterialProperty.js +2 -2
  34. data/app/assets/javascripts/Renderer/AutomaticUniforms.js +41 -41
  35. data/app/assets/javascripts/Renderer/Context.js +171 -201
  36. data/app/assets/javascripts/Renderer/CubeMapFace.js +2 -2
  37. data/app/assets/javascripts/Renderer/DrawCommand.js +2 -2
  38. data/app/assets/javascripts/Renderer/PixelFormat.js +22 -28
  39. data/app/assets/javascripts/Renderer/ShaderProgram.js +65 -46
  40. data/app/assets/javascripts/Renderer/Texture.js +1 -1
  41. data/app/assets/javascripts/Renderer/TextureMagnificationFilter.js +7 -9
  42. data/app/assets/javascripts/Renderer/TextureMinificationFilter.js +19 -25
  43. data/app/assets/javascripts/Renderer/TextureWrap.js +11 -13
  44. data/app/assets/javascripts/Renderer/UniformDatatype.js +29 -29
  45. data/app/assets/javascripts/Renderer/VertexArray.js +43 -35
  46. data/app/assets/javascripts/Scene/ArcGisMapServerImageryProvider.js +1 -2
  47. data/app/assets/javascripts/Scene/BillboardCollection.js +10 -1
  48. data/app/assets/javascripts/Scene/CameraFlightPath.js +58 -101
  49. data/app/assets/javascripts/Scene/CentralBody.js +1 -4
  50. data/app/assets/javascripts/Scene/CentralBodySurface.js +1 -2
  51. data/app/assets/javascripts/Scene/CesiumTerrainProvider.js +1 -2
  52. data/app/assets/javascripts/Scene/CustomSensorVolume.js +17 -3
  53. data/app/assets/javascripts/Scene/EllipsoidPrimitive.js +20 -5
  54. data/app/assets/javascripts/Scene/EllipsoidSurfaceAppearance.js +1 -2
  55. data/app/assets/javascripts/Scene/FrameState.js +1 -3
  56. data/app/assets/javascripts/Scene/GoogleEarthImageryProvider.js +2 -5
  57. data/app/assets/javascripts/Scene/OpenStreetMapImageryProvider.js +1 -2
  58. data/app/assets/javascripts/Scene/OrthographicFrustum.js +1 -2
  59. data/app/assets/javascripts/Scene/PerspectiveOffCenterFrustum.js +1 -2
  60. data/app/assets/javascripts/Scene/Polygon.js +1 -3
  61. data/app/assets/javascripts/Scene/Polyline.js +5 -2
  62. data/app/assets/javascripts/Scene/PolylineCollection.js +4 -6
  63. data/app/assets/javascripts/Scene/Primitive.js +19 -13
  64. data/app/assets/javascripts/Scene/PrimitivePipeline.js +1 -1
  65. data/app/assets/javascripts/Scene/Scene.js +7 -10
  66. data/app/assets/javascripts/Scene/SceneTransforms.js +1 -3
  67. data/app/assets/javascripts/Scene/SceneTransitioner.js +11 -11
  68. data/app/assets/javascripts/Scene/SingleTileImageryProvider.js +1 -2
  69. data/app/assets/javascripts/Scene/TexturePool.js +1 -1
  70. data/app/assets/javascripts/Scene/TileMapServiceImageryProvider.js +1 -2
  71. data/app/assets/javascripts/Scene/VRTheWorldTerrainProvider.js +1 -2
  72. data/app/assets/javascripts/Scene/ViewportQuad.js +1 -3
  73. data/app/assets/javascripts/Scene/WebMapServiceImageryProvider.js +1 -2
  74. data/app/assets/javascripts/ThirdParty/knockout-3.0.0.js +6 -3
  75. data/app/assets/javascripts/Widgets/CesiumWidget/CesiumWidget.js +4 -3
  76. data/app/assets/javascripts/Widgets/SceneModePicker/SceneModePickerViewModel.js +1 -1
  77. data/app/assets/javascripts/Widgets/Viewer/Viewer.js +5 -5
  78. data/app/assets/javascripts/Widgets/Viewer/viewerDragDropMixin.js +13 -13
  79. data/app/assets/javascripts/Widgets/Viewer/viewerDynamicObjectMixin.js +6 -6
  80. data/app/assets/javascripts/Widgets/widgets.css +1 -1
  81. data/lib/cesium/version.rb +1 -1
  82. metadata +6 -3
  83. data/app/assets/javascripts/Core/OrientationInterpolator.js +0 -106
@@ -107,7 +107,7 @@ define(['Core/defaultValue', 'Core/defined', 'Core/DeveloperError', 'Core/Cartes
107
107
  var rightPos, leftPos;
108
108
  var halfLength = endPositionLength / 2;
109
109
 
110
- var indices = IndexDatatype.createTypedArray(size/3, indicesLength);
110
+ var indices = IndexDatatype.createTypedArray(size / 3, indicesLength);
111
111
  var index = 0;
112
112
  if (addEndPositions) { // add rounded end
113
113
  leftPos = cartesian3;
@@ -568,7 +568,7 @@ define(['Core/defaultValue', 'Core/defined', 'Core/DeveloperError', 'Core/Cartes
568
568
  var i;
569
569
  var iLength = indices.length;
570
570
  var twoLength = length + length;
571
- var newIndices = IndexDatatype.createTypedArray(newPositions.length/3, iLength * 2 + twoLength * 3);
571
+ var newIndices = IndexDatatype.createTypedArray(newPositions.length / 3, iLength * 2 + twoLength * 3);
572
572
  newIndices.set(indices);
573
573
  var index = iLength;
574
574
  for (i = 0; i < iLength; i += 3) { // bottom indices
@@ -556,6 +556,22 @@ define(['Core/freezeObject', 'Core/defaultValue', 'Core/defined', 'Core/Develope
556
556
  return Cartesian3.multiplyComponents(position, this._oneOverRadii, result);
557
557
  };
558
558
 
559
+ /**
560
+ * Transforms a Cartesian X, Y, Z position from the ellipsoid-scaled space by multiplying
561
+ * its components by the result of {@link Ellipsoid#getRadii}.
562
+ *
563
+ * @memberof Ellipsoid
564
+ *
565
+ * @param {Cartesian3} position The position to transform.
566
+ * @param {Cartesian3} [result] The position to which to copy the result, or undefined to create and
567
+ * return a new instance.
568
+ * @returns {Cartesian3} The position expressed in the unscaled space. The returned instance is the
569
+ * one passed as the result parameter if it is not undefined, or a new instance of it is.
570
+ */
571
+ Ellipsoid.prototype.transformPositionFromScaledSpace = function(position, result) {
572
+ return Cartesian3.multiplyComponents(position, this._radii, result);
573
+ };
574
+
559
575
  /**
560
576
  * Compares this Ellipsoid against the provided Ellipsoid componentwise and returns
561
577
  * <code>true</code> if they are equal, <code>false</code> otherwise.
@@ -613,8 +613,8 @@ define(['Core/defaultValue', 'Core/defined', 'Core/BoundingSphere', 'Core/Cartes
613
613
  * @exception {DeveloperError} <code>options.extent.south</code> must be in the interval [<code>-Pi/2</code>, <code>Pi/2</code>].
614
614
  * @exception {DeveloperError} <code>options.extent.east</code> must be in the interval [<code>-Pi</code>, <code>Pi</code>].
615
615
  * @exception {DeveloperError} <code>options.extent.west</code> must be in the interval [<code>-Pi</code>, <code>Pi</code>].
616
- * @exception {DeveloperError} <code>options.extent.north</code> must be greater than <code>extent.south</code>.
617
- * @exception {DeveloperError} <code>options.extent.east</code> must be greater than <code>extent.west</code>.
616
+ * @exception {DeveloperError} <code>options.extent.north</code> must be greater than <code>options.extent.south</code>.
617
+ * @exception {DeveloperError} <code>options.extent.east</code> must be greater than <code>options.extent.west</code>.
618
618
  *
619
619
  * @see ExtentGeometry#createGeometry
620
620
  *
@@ -653,6 +653,13 @@ define(['Core/defaultValue', 'Core/defined', 'Core/BoundingSphere', 'Core/Cartes
653
653
  }
654
654
 
655
655
  extent.validate();
656
+ if (extent.east < extent.west) {
657
+ throw new DeveloperError('options.extent.east must be greater than options.extent.west');
658
+ }
659
+
660
+ if (extent.north < extent.south) {
661
+ throw new DeveloperError('options.extent.north must be greater than options.extent.south');
662
+ }
656
663
 
657
664
  this._extent = extent;
658
665
  this._granularity = granularity;
@@ -124,7 +124,7 @@ define(['Core/defaultValue', 'Core/defined', 'Core/BoundingSphere', 'Core/Cartes
124
124
  positions[posIndex++] = position.z;
125
125
  }
126
126
  var indicesSize = positions.length/3 * 2;
127
- var indices = IndexDatatype.createTypedArray(positions.length/3, indicesSize);
127
+ var indices = IndexDatatype.createTypedArray(positions.length / 3, indicesSize);
128
128
 
129
129
  var index = 0;
130
130
  for(var i = 0; i < (positions.length/3)-1; i++) {
@@ -207,7 +207,7 @@ define(['Core/defaultValue', 'Core/defined', 'Core/BoundingSphere', 'Core/Cartes
207
207
  }
208
208
 
209
209
  var indicesSize = positions.length/3 * 2 + 8;
210
- var indices = IndexDatatype.createTypedArray(positions.length/3, indicesSize);
210
+ var indices = IndexDatatype.createTypedArray(positions.length / 3, indicesSize);
211
211
  var length = positions.length/6;
212
212
  var index = 0;
213
213
  for (var i = 0; i < length - 1; i++) {
@@ -121,14 +121,14 @@ define(['Core/barycentricCoordinates', 'Core/defaultValue', 'Core/defined', 'Cor
121
121
 
122
122
  var indices = geometry.indices;
123
123
  if (defined(indices)) {
124
- switch (geometry.primitiveType.value) {
125
- case PrimitiveType.TRIANGLES.value:
124
+ switch (geometry.primitiveType) {
125
+ case PrimitiveType.TRIANGLES:
126
126
  geometry.indices = trianglesToLines(indices);
127
127
  break;
128
- case PrimitiveType.TRIANGLE_STRIP.value:
128
+ case PrimitiveType.TRIANGLE_STRIP:
129
129
  geometry.indices = triangleStripToLines(indices);
130
130
  break;
131
- case PrimitiveType.TRIANGLE_FAN.value:
131
+ case PrimitiveType.TRIANGLE_FAN:
132
132
  geometry.indices = triangleFanToLines(indices);
133
133
  break;
134
134
  default:
@@ -396,7 +396,7 @@ define(['Core/barycentricCoordinates', 'Core/defaultValue', 'Core/defined', 'Cor
396
396
  }
397
397
 
398
398
  var indices = geometry.indices;
399
- if ((geometry.primitiveType.value === PrimitiveType.TRIANGLES.value) && (defined(indices))) {
399
+ if ((geometry.primitiveType === PrimitiveType.TRIANGLES) && (defined(indices))) {
400
400
  var numIndices = indices.length;
401
401
  var maximumIndex = 0;
402
402
  for ( var j = 0; j < numIndices; j++) {
@@ -475,9 +475,9 @@ define(['Core/barycentricCoordinates', 'Core/defaultValue', 'Core/defined', 'Cor
475
475
  }
476
476
 
477
477
  if ((defined(geometry.indices)) &&
478
- ((geometry.primitiveType.value !== PrimitiveType.TRIANGLES.value) &&
479
- (geometry.primitiveType.value !== PrimitiveType.LINES.value) &&
480
- (geometry.primitiveType.value !== PrimitiveType.POINTS.value))) {
478
+ ((geometry.primitiveType !== PrimitiveType.TRIANGLES) &&
479
+ (geometry.primitiveType !== PrimitiveType.LINES) &&
480
+ (geometry.primitiveType !== PrimitiveType.POINTS))) {
481
481
  throw new DeveloperError('geometry.primitiveType must equal to PrimitiveType.TRIANGLES, PrimitiveType.LINES, or PrimitiveType.POINTS.');
482
482
  }
483
483
 
@@ -497,11 +497,11 @@ define(['Core/barycentricCoordinates', 'Core/defaultValue', 'Core/defined', 'Cor
497
497
 
498
498
  var indicesPerPrimitive;
499
499
 
500
- if (geometry.primitiveType.value === PrimitiveType.TRIANGLES.value) {
500
+ if (geometry.primitiveType === PrimitiveType.TRIANGLES) {
501
501
  indicesPerPrimitive = 3;
502
- } else if (geometry.primitiveType.value === PrimitiveType.LINES.value) {
502
+ } else if (geometry.primitiveType === PrimitiveType.LINES) {
503
503
  indicesPerPrimitive = 2;
504
- } else if (geometry.primitiveType.value === PrimitiveType.POINTS.value) {
504
+ } else if (geometry.primitiveType === PrimitiveType.POINTS) {
505
505
  indicesPerPrimitive = 1;
506
506
  }
507
507
 
@@ -923,7 +923,7 @@ define(['Core/barycentricCoordinates', 'Core/defaultValue', 'Core/defined', 'Cor
923
923
  throw new DeveloperError('All instance geometries must have an indices or not have one.');
924
924
  }
925
925
 
926
- if (instances[i].geometry.primitiveType.value !== primitiveType.value) {
926
+ if (instances[i].geometry.primitiveType !== primitiveType) {
927
927
  throw new DeveloperError('All instance geometries must have the same primitiveType.');
928
928
  }
929
929
  }
@@ -1063,7 +1063,7 @@ define(['Core/barycentricCoordinates', 'Core/defaultValue', 'Core/defined', 'Cor
1063
1063
  throw new DeveloperError('geometry.indices length must be greater than 0 and be a multiple of 3.');
1064
1064
  }
1065
1065
 
1066
- if (geometry.primitiveType.value !== PrimitiveType.TRIANGLES.value) {
1066
+ if (geometry.primitiveType !== PrimitiveType.TRIANGLES) {
1067
1067
  throw new DeveloperError('geometry.primitiveType must be PrimitiveType.TRIANGLES.');
1068
1068
  }
1069
1069
 
@@ -1223,7 +1223,7 @@ define(['Core/barycentricCoordinates', 'Core/defaultValue', 'Core/defined', 'Cor
1223
1223
  throw new DeveloperError('geometry.indices length must be greater than 0 and be a multiple of 3.');
1224
1224
  }
1225
1225
 
1226
- if (geometry.primitiveType.value !== PrimitiveType.TRIANGLES.value) {
1226
+ if (geometry.primitiveType !== PrimitiveType.TRIANGLES) {
1227
1227
  throw new DeveloperError('geometry.primitiveType must be PrimitiveType.TRIANGLES.');
1228
1228
  }
1229
1229
 
@@ -1471,18 +1471,18 @@ define(['Core/barycentricCoordinates', 'Core/defaultValue', 'Core/defined', 'Cor
1471
1471
  }
1472
1472
 
1473
1473
  function indexPrimitive(geometry) {
1474
- switch (geometry.primitiveType.value) {
1475
- case PrimitiveType.TRIANGLE_FAN.value:
1474
+ switch (geometry.primitiveType) {
1475
+ case PrimitiveType.TRIANGLE_FAN:
1476
1476
  return indexTriangleFan(geometry);
1477
- case PrimitiveType.TRIANGLE_STRIP.value:
1477
+ case PrimitiveType.TRIANGLE_STRIP:
1478
1478
  return indexTriangleStrip(geometry);
1479
- case PrimitiveType.TRIANGLES.value:
1479
+ case PrimitiveType.TRIANGLES:
1480
1480
  return indexTriangles(geometry);
1481
- case PrimitiveType.LINE_STRIP.value:
1481
+ case PrimitiveType.LINE_STRIP:
1482
1482
  return indexLineStrip(geometry);
1483
- case PrimitiveType.LINE_LOOP.value:
1483
+ case PrimitiveType.LINE_LOOP:
1484
1484
  return indexLineLoop(geometry);
1485
- case PrimitiveType.LINES.value:
1485
+ case PrimitiveType.LINES:
1486
1486
  return indexLines(geometry);
1487
1487
  }
1488
1488
 
@@ -1895,9 +1895,9 @@ define(['Core/barycentricCoordinates', 'Core/defaultValue', 'Core/defined', 'Cor
1895
1895
  }
1896
1896
 
1897
1897
  indexPrimitive(geometry);
1898
- if (geometry.primitiveType.value === PrimitiveType.TRIANGLES.value) {
1898
+ if (geometry.primitiveType === PrimitiveType.TRIANGLES) {
1899
1899
  wrapLongitudeTriangles(geometry);
1900
- } else if (geometry.primitiveType.value === PrimitiveType.LINES.value) {
1900
+ } else if (geometry.primitiveType === PrimitiveType.LINES) {
1901
1901
  wrapLongitudeLines(geometry);
1902
1902
  }
1903
1903
 
@@ -1,14 +1,159 @@
1
1
  /*global define*/
2
- define(['Core/defaultValue', 'Core/defined', 'Core/DeveloperError', 'Core/Cartesian3', 'Core/Matrix4', 'Core/Cartesian4', 'Core/TridiagonalSystemSolver'], function(
2
+ define(['Core/defaultValue', 'Core/defined', 'Core/DeveloperError', 'Core/Cartesian3', 'Core/Matrix4', 'Core/Cartesian4', 'Core/Spline', 'Core/TridiagonalSystemSolver'], function(
3
3
  defaultValue,
4
4
  defined,
5
5
  DeveloperError,
6
6
  Cartesian3,
7
7
  Matrix4,
8
8
  Cartesian4,
9
+ Spline,
9
10
  TridiagonalSystemSolver) {
10
11
  "use strict";
11
12
 
13
+ var scratchLower = [];
14
+ var scratchDiagonal = [];
15
+ var scratchUpper = [];
16
+ var scratchRight = [];
17
+
18
+ function generateClamped(points, firstTangent, lastTangent) {
19
+ var l = scratchLower;
20
+ var u = scratchUpper;
21
+ var d = scratchDiagonal;
22
+ var r = scratchRight;
23
+
24
+ l.length = u.length = points.length - 1;
25
+ d.length = r.length = points.length;
26
+
27
+ var i;
28
+ l[0] = d[0] = 1.0;
29
+ u[0] = 0.0;
30
+
31
+ var right = r[0];
32
+ if (!defined(right)) {
33
+ right = r[0] = new Cartesian3();
34
+ }
35
+ Cartesian3.clone(firstTangent, right);
36
+
37
+ for (i = 1; i < l.length - 1; ++i) {
38
+ l[i] = u[i] = 1.0;
39
+ d[i] = 4.0;
40
+
41
+ right = r[i];
42
+ if (!defined(right)) {
43
+ right = r[i] = new Cartesian3();
44
+ }
45
+ Cartesian3.subtract(points[i + 1], points[i - 1], right);
46
+ Cartesian3.multiplyByScalar(right, 3.0, right);
47
+ }
48
+
49
+ l[i] = 0.0;
50
+ u[i] = 1.0;
51
+ d[i] = 4.0;
52
+
53
+ right = r[i];
54
+ if (!defined(right)) {
55
+ right = r[i] = new Cartesian3();
56
+ }
57
+ Cartesian3.subtract(points[i + 1], points[i - 1], right);
58
+ Cartesian3.multiplyByScalar(right, 3.0, right);
59
+
60
+ d[i + 1] = 1.0;
61
+ right = r[i + 1];
62
+ if (!defined(right)) {
63
+ right = r[i + 1] = new Cartesian3();
64
+ }
65
+ Cartesian3.clone(lastTangent, right);
66
+
67
+ return TridiagonalSystemSolver.solve(l, d, u, r);
68
+ }
69
+
70
+ function generateNatural(points){
71
+ var l = scratchLower;
72
+ var u = scratchUpper;
73
+ var d = scratchDiagonal;
74
+ var r = scratchRight;
75
+
76
+ l.length = u.length = points.length - 1;
77
+ d.length = r.length = points.length;
78
+
79
+ var i;
80
+ l[0] = u[0] = 1.0;
81
+ d[0] = 2.0;
82
+
83
+ var right = r[0];
84
+ if (!defined(right)) {
85
+ right = r[0] = new Cartesian3();
86
+ }
87
+ Cartesian3.subtract(points[1], points[0], right);
88
+ Cartesian3.multiplyByScalar(right, 3.0, right);
89
+
90
+ for (i = 1; i < l.length; ++i) {
91
+ l[i] = u[i] = 1.0;
92
+ d[i] = 4.0;
93
+
94
+ right = r[i];
95
+ if (!defined(right)) {
96
+ right = r[i] = new Cartesian3();
97
+ }
98
+ Cartesian3.subtract(points[i + 1], points[i - 1], right);
99
+ Cartesian3.multiplyByScalar(right, 3.0, right);
100
+ }
101
+
102
+ d[i] = 2.0;
103
+
104
+ right = r[i];
105
+ if (!defined(right)) {
106
+ right = r[i] = new Cartesian3();
107
+ }
108
+ Cartesian3.subtract(points[i], points[i - 1], right);
109
+ Cartesian3.multiplyByScalar(right, 3.0, right);
110
+
111
+ return TridiagonalSystemSolver.solve(l, d, u, r);
112
+ }
113
+
114
+ var scratchTimeVec = new Cartesian4();
115
+ var scratchTemp = new Cartesian3();
116
+
117
+ function createEvaluateFunction(spline) {
118
+ var points = spline.points;
119
+ var times = spline.times;
120
+
121
+ if (points.length < 3) {
122
+ var t0 = times[0];
123
+ var invSpan = 1.0 / (times[1] - t0);
124
+
125
+ var p0 = points[0];
126
+ var p1 = points[1];
127
+
128
+ return function(time, result) {
129
+ var u = (time - t0) * invSpan;
130
+ return Cartesian3.lerp(p0, p1, u, result);
131
+ };
132
+ }
133
+
134
+ var tangents = spline.tangents;
135
+
136
+ return function(time, result) {
137
+ var i = spline._lastTimeIndex = spline.findTimeInterval(time, spline._lastTimeIndex);
138
+ var u = (time - times[i]) / (times[i + 1] - times[i]);
139
+
140
+ var timeVec = scratchTimeVec;
141
+ timeVec.z = u;
142
+ timeVec.y = u * u;
143
+ timeVec.x = timeVec.y * u;
144
+
145
+ var coefs = Matrix4.multiplyByPoint(HermiteSpline.hermiteCoefficientMatrix, timeVec, timeVec);
146
+
147
+ result = Cartesian3.multiplyByScalar(points[i], coefs.x, result);
148
+ Cartesian3.multiplyByScalar(points[i + 1], coefs.y, scratchTemp);
149
+ Cartesian3.add(result, scratchTemp, result);
150
+ Cartesian3.multiplyByScalar(tangents[i], coefs.z, scratchTemp);
151
+ Cartesian3.add(result, scratchTemp, result);
152
+ Cartesian3.multiplyByScalar(tangents[i + 1], coefs.w, scratchTemp);
153
+ return Cartesian3.add(result, scratchTemp, result);
154
+ };
155
+ }
156
+
12
157
  /**
13
158
  * A Hermite spline is a cubic interpolating spline. Positions, tangents, and times must be defined
14
159
  * for each control point. If no tangents are specified by the control points, the end and interior
@@ -21,210 +166,170 @@ define(['Core/defaultValue', 'Core/defined', 'Core/DeveloperError', 'Core/Cartes
21
166
  * @alias HermiteSpline
22
167
  * @constructor
23
168
  *
24
- * @param {Array} controlPoints An array, of at least length 3, of objects with <code>point</code>,
25
- * <code>time</code>, and <code>tangent</code> properties.
169
+ * @param {Array} options.times The array of control point times.
170
+ * @param {Array} options.points The array of control points.
171
+ * @param {Array} [options.tangents] The array of tangents at each control point.
172
+ * @param {Cartesian3} [options.firstTangent] The tangent of the curve at the first control point.
173
+ * If the tangent is not given, it will be estimated.
174
+ * @param {Cartesian3} [options.lastTangent] The tangent of the curve at the last control point.
175
+ * If the tangent is not given, it will be estimated.
26
176
  *
27
- * @exception {DeveloperError} controlPoints is required.
28
- * @exception {DeveloperError} controlPoints must be an array of at least length 3.
177
+ * @exception {DeveloperError} points is required.
178
+ * @exception {DeveloperError} points.length must be greater than or equal to 2.
179
+ * @exception {DeveloperError} times is required.
180
+ * @exception {DeveloperError} times.length must be equal to points.length.
29
181
  *
30
182
  * @see CatmullRomSpline
31
183
  *
32
184
  * @example
33
185
  * // Example 1.
34
186
  * // Create a natural cubic spline above the earth from Philadelphia to Los Angeles.
35
- * var controlPoints = [
36
- * {point: new Cartesian3(1235398.0, -4810983.0, 4146266.0), time: 0.0},
37
- * {point: new Cartesian3(1372574.0, -5345182.0, 4606657.0), time: 1.5},
38
- * {point: new Cartesian3(-757983.0, -5542796.0, 4514323.0), time: 3.0},
39
- * {point: new Cartesian3(-2821260.0, -5248423.0, 4021290.0), time: 4.5},
40
- * {point: new Cartesian3(-2539788.0, -4724797.0, 3620093.0), time: 6.0}
41
- * ];
42
- * var spline = new HermiteSpline(controlPoints);
187
+ * var spline = new HermiteSpline({
188
+ * times : [ 0.0, 1.5, 3.0, 4.5, 6.0 ],
189
+ * points : [
190
+ * new Cartesian3(1235398.0, -4810983.0, 4146266.0),
191
+ * new Cartesian3(1372574.0, -5345182.0, 4606657.0),
192
+ * new Cartesian3(-757983.0, -5542796.0, 4514323.0),
193
+ * new Cartesian3(-2821260.0, -5248423.0, 4021290.0),
194
+ * new Cartesian3(-2539788.0, -4724797.0, 3620093.0)
195
+ * ]
196
+ * });
43
197
  *
44
198
  * // Example 2.
45
199
  * // Create a Catmull-Rom spline above the earth from Philadelphia to Los Angeles.
46
- * var controlPoints = [
47
- * {point: new Cartesian3(1235398.0, -4810983.0, 4146266.0), time: 0.0},
48
- * {point: new Cartesian3(1372574.0, -5345182.0, 4606657.0), time: 1.5},
49
- * {point: new Cartesian3(-757983.0, -5542796.0, 4514323.0), time: 3.0},
50
- * {point: new Cartesian3(-2821260.0, -5248423.0, 4021290.0), time: 4.5},
51
- * {point: new Cartesian3(-2539788.0, -4724797.0, 3620093.0), time: 6.0}
200
+ * var times = [ 0.0, 1.5, 3.0, 4.5, 6.0 ];
201
+ * var points : [
202
+ * new Cartesian3(1235398.0, -4810983.0, 4146266.0),
203
+ * new Cartesian3(1372574.0, -5345182.0, 4606657.0),
204
+ * new Cartesian3(-757983.0, -5542796.0, 4514323.0),
205
+ * new Cartesian3(-2821260.0, -5248423.0, 4021290.0),
206
+ * new Cartesian3(-2539788.0, -4724797.0, 3620093.0)
52
207
  * ];
53
208
  *
54
209
  * // Add tangents
55
- * controlPoints[0].tangent = new Cartesian3(1125196, -161816, 270551);
56
- * for (var i = 1; i < controlPoints.length - 1; ++i) {
57
- * controlPoints[i].tangent = Cartesian3.multiplyByScalar(Cartesian3.subtract(controlPoints[i + 1].point, controlPoints[i - 1].point), 0.5);
210
+ * var tangents = new Array(points.length);
211
+ * tangents[0] = new Cartesian3(1125196, -161816, 270551);
212
+ * for (var i = 1; i < tangents.length - 1; ++i) {
213
+ * tangents[i] = Cartesian3.multiplyByScalar(Cartesian3.subtract(controlPoints[i + 1].point, controlPoints[i - 1].point), 0.5);
58
214
  * }
59
- * controlPoints[controlPoints.length - 1].tangent = new Cartesian3(1165345, 112641, 47281);
215
+ * tangents[tangents.length - 1] = new Cartesian3(1165345, 112641, 47281);
60
216
  *
61
- * var spline = new HermiteSpline(controlPoints);
217
+ * var spline = new HermiteSpline({
218
+ * times : times,
219
+ * points : points,
220
+ * tangents : tangents
221
+ * });
62
222
  */
63
- var HermiteSpline = function(controlPoints) {
64
- if (!defined(controlPoints) || !(controlPoints instanceof Array) || controlPoints.length < 3) {
65
- throw new DeveloperError('controlPoints is required. It must be an array with at least a length of 3.');
66
- }
67
-
68
- this._points = controlPoints;
223
+ var HermiteSpline = function(options) {
224
+ options = defaultValue(options, defaultValue.EMPTY_OBJECT);
69
225
 
70
- this._lastTimeIndex = 0;
226
+ var points = options.points;
227
+ var times = options.times;
228
+ var tangents = options.tangents;
229
+ var firstTangent = options.firstTangent;
230
+ var lastTangent = options.lastTangent;
71
231
 
72
- if (!defined(this._points[0].tangent) || !defined(this._points[this._points.length - 1].tangent)) {
73
- generateNatural(this);
74
- } else if (defined(this._points[0].tangent) && !defined(this._points[1].tangent) && defined(this._points[this._points.length - 1].tangent) && !defined(this._points[this._points.length - 2].tangent)) {
75
- generateClamped(this);
232
+ if (!defined(points)) {
233
+ throw new DeveloperError('points is required.');
76
234
  }
77
- };
78
-
79
- HermiteSpline.hermiteCoefficientMatrix = new Matrix4(
80
- 2.0, -3.0, 0.0, 1.0,
81
- -2.0, 3.0, 0.0, 0.0,
82
- 1.0, -2.0, 1.0, 0.0,
83
- 1.0, -1.0, 0.0, 0.0);
84
235
 
85
- function findIndex(hermiteSpline, time) {
86
- // Take advantage of temporal coherence by checking current, next and previous intervals
87
- // for containment of time.
88
- var i = defaultValue(hermiteSpline._lastTimeIndex, 0);
89
- if (time >= hermiteSpline._points[i].time) {
90
- if (i + 1 < hermiteSpline._points.length && time < hermiteSpline._points[i + 1].time) {
91
- return i;
92
- } else if (i + 2 < hermiteSpline._points.length && time < hermiteSpline._points[i + 2].time) {
93
- hermiteSpline._lastTimeIndex = i + 1;
94
- return hermiteSpline._lastTimeIndex;
95
- }
96
- } else if (i - 1 >= 0 && time >= hermiteSpline._points[i - 1].time) {
97
- hermiteSpline._lastTimeIndex = i - 1;
98
- return hermiteSpline._lastTimeIndex;
236
+ if (points.length < 2) {
237
+ throw new DeveloperError('points.length must be greater than or equal to 2.');
99
238
  }
100
239
 
101
- // The above failed so do a linear search. For the use cases so far, the
102
- // length of the list is less than 10. In the future, if there is a bottle neck,
103
- // it might be here.
104
- for (i = 0; i < hermiteSpline._points.length - 1; ++i) {
105
- if (time >= hermiteSpline._points[i].time && time < hermiteSpline._points[i + 1].time) {
106
- break;
107
- }
240
+ if (!defined(times)) {
241
+ throw new DeveloperError('times is required.');
108
242
  }
109
243
 
110
- if (i === hermiteSpline._points.length - 1) {
111
- i = hermiteSpline._points.length - 2;
244
+ if (times.length !== points.length) {
245
+ throw new DeveloperError('times.length must be equal to points.length.');
112
246
  }
113
247
 
114
- hermiteSpline._lastTimeIndex = i;
115
- return hermiteSpline._lastTimeIndex;
116
- }
117
-
118
- function generateClamped(hermiteSpline) {
119
- var l = [], d = [], u = [], r = [];
120
- l.length = u.length = hermiteSpline._points.length - 1;
121
- d.length = r.length = hermiteSpline._points.length;
122
-
123
- var i;
124
- l[0] = d[0] = 1.0;
125
- u[0] = 0.0;
126
- r[0] = hermiteSpline._points[0].tangent;
127
- for (i = 1; i < l.length - 1; ++i) {
128
- l[i] = u[i] = 1.0;
129
- d[i] = 4.0;
130
- r[i] = Cartesian3.multiplyByScalar(Cartesian3.subtract(hermiteSpline._points[i + 1].point, hermiteSpline._points[i - 1].point), 3.0);
248
+ if (!defined(tangents)) {
249
+ if (defined(firstTangent) && defined(lastTangent)) {
250
+ tangents = generateClamped(points, firstTangent, lastTangent);
251
+ } else {
252
+ tangents = generateNatural(points);
253
+ }
131
254
  }
132
- l[i] = 0.0;
133
- u[i] = 1.0;
134
- d[i] = 4.0;
135
- r[i] = Cartesian3.multiplyByScalar(Cartesian3.subtract(hermiteSpline._points[i + 1].point, hermiteSpline._points[i - 1].point), 3.0);
136
- d[i + 1] = 1.0;
137
- r[i + 1] = hermiteSpline._points[i + 1].tangent;
138
255
 
139
- var tangents = TridiagonalSystemSolver.solve(l, d, u, r);
140
- for (i = 0; i < hermiteSpline._points.length; ++i) {
141
- hermiteSpline._points[i].tangent = tangents[i];
142
- }
143
- }
256
+ /**
257
+ * An array of times for the control points.
258
+ * @type {Array}
259
+ * @readonly
260
+ */
261
+ this.times = times;
144
262
 
145
- function generateNatural(hermiteSpline){
146
- var l = [], d = [], u = [], r = [];
147
- l.length = u.length = hermiteSpline._points.length - 1;
148
- d.length = r.length = hermiteSpline._points.length;
263
+ /**
264
+ * An array of {@link Cartesian3} control points.
265
+ * @type {Array}
266
+ * @readonly
267
+ */
268
+ this.points = points;
149
269
 
150
- var i;
151
- l[0] = u[0] = 1.0;
152
- d[0] = 2.0;
153
- r[0] = Cartesian3.multiplyByScalar(Cartesian3.subtract(hermiteSpline._points[1].point, hermiteSpline._points[0].point), 3.0);
154
- for (i = 1; i < l.length; ++i) {
155
- l[i] = u[i] = 1.0;
156
- d[i] = 4.0;
157
- r[i] = Cartesian3.multiplyByScalar(Cartesian3.subtract(hermiteSpline._points[i + 1].point, hermiteSpline._points[i - 1].point), 3.0);
158
- }
159
- d[i] = 2.0;
160
- r[i] = Cartesian3.multiplyByScalar(Cartesian3.subtract(hermiteSpline._points[i].point, hermiteSpline._points[i - 1].point), 3.0);
270
+ /**
271
+ * An array of {@link Cartesian3} tangents at each control point.
272
+ * @type {Array}
273
+ * @readonly
274
+ */
275
+ this.tangents = tangents;
161
276
 
162
- var tangents = TridiagonalSystemSolver.solve(l, d, u, r);
163
- for (i = 0; i < hermiteSpline._points.length; ++i) {
164
- hermiteSpline._points[i].tangent = tangents[i];
165
- }
166
- }
277
+ this._evaluateFunction = createEvaluateFunction(this);
278
+ this._lastTimeIndex = 0;
279
+ };
280
+
281
+ HermiteSpline.hermiteCoefficientMatrix = new Matrix4(
282
+ 2.0, -3.0, 0.0, 1.0,
283
+ -2.0, 3.0, 0.0, 0.0,
284
+ 1.0, -2.0, 1.0, 0.0,
285
+ 1.0, -1.0, 0.0, 0.0);
167
286
 
168
287
  /**
169
- * Returns the array of control points.
170
- *
288
+ * Finds an index <code>i</code> in <code>times</code> such that the parameter
289
+ * <code>time</code> is in the interval <code>[times[i], times[i + 1]]</code>.
171
290
  * @memberof HermiteSpline
172
- * @returns {Array} The array of control points.
291
+ *
292
+ * @param {Number} time The time.
293
+ * @returns {Number} The index for the element at the start of the interval.
294
+ *
295
+ * @exception {DeveloperError} time is required.
296
+ * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code>
297
+ * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element
298
+ * in the array <code>times</code>.
173
299
  */
174
- HermiteSpline.prototype.getControlPoints = function() {
175
- return this._points;
176
- };
300
+ HermiteSpline.prototype.findTimeInterval = Spline.prototype.findTimeInterval;
177
301
 
178
302
  /**
179
303
  * Evaluates the curve at a given time.
180
- *
181
304
  * @memberof HermiteSpline
182
305
  *
183
306
  * @param {Number} time The time at which to evaluate the curve.
307
+ * @param {Cartesian3} [result] The object onto which to store the result.
308
+ * @returns {Cartesian3} The modified result parameter or a new instance of the point on the curve at the given time.
184
309
  *
185
310
  * @exception {DeveloperError} time is required.
186
- * @exception {DeveloperError} time must be in the range <code>[a<sub>0</sub>, a<sub>n</sub>]</code>,
187
- * where <code>a<sub>0</sub></code> and <code>a<sub>n</sub></code> are the time properties of first and
188
- * last elements in the array given during construction, respectively.
189
- *
190
- * @returns {Cartesian3} The point on the curve at the given <code>time</code>.
311
+ * @exception {DeveloperError} time must be in the range <code>[t<sub>0</sub>, t<sub>n</sub>]</code>, where <code>t<sub>0</sub></code>
312
+ * is the first element in the array <code>times</code> and <code>t<sub>n</sub></code> is the last element
313
+ * in the array <code>times</code>.
191
314
  *
192
315
  * @example
193
316
  * // spline above the earth from Philadelphia to Los Angeles
194
- * var controlPoints = [
195
- * {point: new Cartesian3(1235398.0, -4810983.0, 4146266.0), time: 0.0},
196
- * {point: new Cartesian3(1372574.0, -5345182.0, 4606657.0), time: 1.5},
197
- * {point: new Cartesian3(-757983.0, -5542796.0, 4514323.0), time: 3.0},
198
- * {point: new Cartesian3(-2821260.0, -5248423.0, 4021290.0), time: 4.5},
199
- * {point: new Cartesian3(-2539788.0, -4724797.0, 3620093.0), time: 6.0}
200
- * ];
201
- * var spline = new HermiteSpline(controlPoints);
317
+ * var spline = new HermiteSpline({
318
+ * times : [ 0.0, 1.5, 3.0, 4.5, 6.0 ],
319
+ * points : [
320
+ * new Cartesian3(1235398.0, -4810983.0, 4146266.0),
321
+ * new Cartesian3(1372574.0, -5345182.0, 4606657.0),
322
+ * new Cartesian3(-757983.0, -5542796.0, 4514323.0),
323
+ * new Cartesian3(-2821260.0, -5248423.0, 4021290.0),
324
+ * new Cartesian3(-2539788.0, -4724797.0, 3620093.0)
325
+ * ]
326
+ * });
202
327
  *
203
328
  * // some position above Los Angeles
204
329
  * var position = spline.evaluate(5.0);
205
330
  */
206
- HermiteSpline.prototype.evaluate = function(time) {
207
- if (!defined(time)) {
208
- throw new DeveloperError('time is required.');
209
- }
210
-
211
- if (time < this._points[0].time || time > this._points[this._points.length - 1].time) {
212
- throw new DeveloperError('time is out of range.');
213
- }
214
-
215
- var i = findIndex(this, time);
216
- var u = (time - this._points[i].time) / (this._points[i + 1].time - this._points[i].time);
217
-
218
- var timeVec = new Cartesian4(0.0, u * u, u);
219
- timeVec.x = timeVec.y * u;
220
-
221
- var coefs = Matrix4.multiplyByPoint(HermiteSpline.hermiteCoefficientMatrix, timeVec);
222
- var p0 = Cartesian3.multiplyByScalar(this._points[i].point, coefs.x);
223
- var p1 = Cartesian3.multiplyByScalar(this._points[i + 1].point, coefs.y);
224
- var p2 = Cartesian3.multiplyByScalar(this._points[i].tangent, coefs.z);
225
- var p3 = Cartesian3.multiplyByScalar(this._points[i + 1].tangent, coefs.w);
226
-
227
- return Cartesian3.add(Cartesian3.add(Cartesian3.add(p0, p1), p2), p3);
331
+ HermiteSpline.prototype.evaluate = function(time, result) {
332
+ return this._evaluateFunction(time, result);
228
333
  };
229
334
 
230
335
  return HermiteSpline;