cesium 0.22.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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;