yzt
2023-05-26 de4278af2fd46705a40bac58ec01122db6b7f3d7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
import { Cartesian3 } from "../../Source/Cesium.js";
import { Color } from "../../Source/Cesium.js";
import { Ellipsoid } from "../../Source/Cesium.js";
import { Intersect } from "../../Source/Cesium.js";
import { Math as CesiumMath } from "../../Source/Cesium.js";
import { Plane } from "../../Source/Cesium.js";
import { S2Cell } from "../../Source/Cesium.js";
import { TileBoundingS2Cell } from "../../Source/Cesium.js";
import createFrameState from "../createFrameState.js";
 
describe("Scene/TileBoundingS2Cell", function () {
  var s2Cell = S2Cell.fromToken("1");
  var s2Options = {
    token: "1",
    minimumHeight: 0,
    maximumHeight: 100000,
  };
 
  var tileS2Cell = new TileBoundingS2Cell(s2Options);
 
  var frameState;
  var camera;
 
  beforeEach(function () {
    frameState = createFrameState();
    camera = frameState.camera;
  });
 
  it("throws when options.token is undefined", function () {
    expect(function () {
      return new TileBoundingS2Cell();
    }).toThrowDeveloperError();
  });
 
  it("can be instantiated with S2 cell", function () {
    var tS2Cell = new TileBoundingS2Cell({
      token: "1",
    });
    expect(tS2Cell).toBeDefined();
    expect(tS2Cell.boundingVolume).toBeDefined();
    expect(tS2Cell.boundingSphere).toBeDefined();
    expect(tS2Cell.s2Cell).toBeDefined();
    expect(tS2Cell.center).toBeDefined();
    expect(tS2Cell.minimumHeight).toBeDefined();
    expect(tS2Cell.maximumHeight).toBeDefined();
  });
 
  it("can be instantiated with S2 cell and heights", function () {
    var tS2Cell = new TileBoundingS2Cell(s2Options);
    expect(tS2Cell).toBeDefined();
    expect(tS2Cell.boundingVolume).toBeDefined();
    expect(tS2Cell.boundingSphere).toBeDefined();
    expect(tS2Cell.s2Cell).toBeDefined();
    expect(tS2Cell.center).toBeDefined();
    expect(tS2Cell.minimumHeight).toBeDefined();
    expect(tS2Cell.maximumHeight).toBeDefined();
  });
 
  it("distanceToCamera throws when frameState is undefined", function () {
    expect(function () {
      return tileS2Cell.distanceToCamera();
    }).toThrowDeveloperError();
  });
 
  it("distance to camera is 0 when camera is inside bounding volume", function () {
    camera.position = s2Cell.getCenter();
    expect(tileS2Cell.distanceToCamera(frameState)).toEqual(0.0);
  });
 
  var edgeOneScratch = new Cartesian3();
  var edgeTwoScratch = new Cartesian3();
  var faceCenterScratch = new Cartesian3();
  var topPlaneScratch = new Plane(Cartesian3.UNIT_X, 0.0, 0.0);
  var sidePlane0Scratch = new Plane(Cartesian3.UNIT_X, 0.0, 0.0);
  // Testing for Case I
  it("distanceToCamera works when camera is facing only one plane", function () {
    var testDistance = 100;
 
    // Test against the top plane.
    var topPlane = Plane.clone(tileS2Cell._boundingPlanes[0], topPlaneScratch);
    topPlane.distance -= testDistance;
    camera.position = Plane.projectPointOntoPlane(topPlane, tileS2Cell.center);
    expect(tileS2Cell.distanceToCamera(frameState)).toEqualEpsilon(
      testDistance,
      CesiumMath.EPSILON7
    );
 
    // Test against the first side plane.
    var sidePlane0 = Plane.clone(
      tileS2Cell._boundingPlanes[2],
      sidePlane0Scratch
    );
    var edgeOne = Cartesian3.midpoint(
      tileS2Cell._vertices[0],
      tileS2Cell._vertices[1],
      edgeOneScratch
    );
 
    var edgeTwo = Cartesian3.midpoint(
      tileS2Cell._vertices[4],
      tileS2Cell._vertices[5],
      edgeTwoScratch
    );
 
    var faceCenter = Cartesian3.midpoint(edgeOne, edgeTwo, faceCenterScratch);
 
    sidePlane0.distance -= testDistance;
    camera.position = Plane.projectPointOntoPlane(sidePlane0, faceCenter);
    expect(tileS2Cell.distanceToCamera(frameState)).toEqualEpsilon(
      testDistance,
      CesiumMath.EPSILON7
    );
  });
 
  var edgeMidpointScratch = new Cartesian3();
  // Testing for Case II
  it("distanceToCamera works when camera is facing two planes", function () {
    var testDistance = 5;
 
    // Test with the top plane and the first side plane.
    camera.position = Cartesian3.midpoint(
      tileS2Cell._vertices[0],
      tileS2Cell._vertices[1],
      edgeMidpointScratch
    );
    camera.position.z -= testDistance;
    expect(tileS2Cell.distanceToCamera(frameState)).toEqualEpsilon(
      testDistance,
      CesiumMath.EPSILON7
    );
 
    // Test with first and second side planes.
    camera.position = Cartesian3.midpoint(
      tileS2Cell._vertices[0],
      tileS2Cell._vertices[4],
      edgeMidpointScratch
    );
    camera.position.x -= 1;
    camera.position.z -= 1;
    expect(tileS2Cell.distanceToCamera(frameState)).toEqualEpsilon(
      Math.SQRT2,
      CesiumMath.EPSILON7
    );
 
    // Test with bottom plane and second side plane. Handles the obtuse dihedral angle case.
    camera.position = Cartesian3.midpoint(
      tileS2Cell._vertices[5],
      tileS2Cell._vertices[6],
      edgeMidpointScratch
    );
    camera.position.x -= 10000;
    camera.position.y -= 1;
    expect(tileS2Cell.distanceToCamera(frameState)).toEqualEpsilon(
      10000,
      CesiumMath.EPSILON7
    );
  });
 
  var vertex2Scratch = new Cartesian3();
  // Testing for Case III
  it("distanceToCamera works when camera is facing three planes", function () {
    camera.position = Cartesian3.clone(tileS2Cell._vertices[2], vertex2Scratch);
    camera.position.x += 1;
    camera.position.y += 1;
    camera.position.z += 1;
    expect(tileS2Cell.distanceToCamera(frameState)).toEqualEpsilon(
      Math.sqrt(3),
      CesiumMath.EPSILON7
    );
  });
 
  // Testing for Case IV
  it("distanceToCamera works when camera is facing more than three planes", function () {
    camera.position = new Cartesian3(-Ellipsoid.WGS84.maximumRadius, 0, 0);
    expect(tileS2Cell.distanceToCamera(frameState)).toEqualEpsilon(
      Ellipsoid.WGS84.maximumRadius + tileS2Cell._boundingPlanes[1].distance,
      CesiumMath.EPSILON7
    );
  });
 
  it("can create a debug volume", function () {
    var debugVolume = tileS2Cell.createDebugVolume(Color.BLUE);
    expect(debugVolume).toBeDefined();
  });
 
  it("createDebugVolume throws when color is undefined", function () {
    expect(function () {
      return tileS2Cell.createDebugVolume();
    }).toThrowDeveloperError();
  });
 
  it("intersectPlane throws when plane is undefined", function () {
    expect(function () {
      return tileS2Cell.intersectPlane();
    }).toThrowDeveloperError();
  });
 
  it("intersects plane", function () {
    expect(tileS2Cell.intersectPlane(Plane.ORIGIN_ZX_PLANE)).toEqual(
      Intersect.INTERSECTING
    );
 
    var outsidePlane = Plane.clone(Plane.ORIGIN_YZ_PLANE);
    outsidePlane.distance -= 2 * Ellipsoid.WGS84.maximumRadius;
    expect(tileS2Cell.intersectPlane(outsidePlane)).toEqual(Intersect.OUTSIDE);
 
    expect(tileS2Cell.intersectPlane(Plane.ORIGIN_YZ_PLANE)).toEqual(
      Intersect.INSIDE
    );
  });
});