You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1267 lines
40 KiB
JavaScript
1267 lines
40 KiB
JavaScript
import MockTerrainProvider from "../MockTerrainProvider.js";
|
|
import TerrainTileProcessor from "../TerrainTileProcessor.js";
|
|
import { Cartesian2 } from "../../Source/Cesium.js";
|
|
import { Cartesian3 } from "../../Source/Cesium.js";
|
|
import { GeographicProjection } from "../../Source/Cesium.js";
|
|
import { HeightmapTerrainData } from "../../Source/Cesium.js";
|
|
import { Intersect } from "../../Source/Cesium.js";
|
|
import { Math as CesiumMath } from "../../Source/Cesium.js";
|
|
import { Camera } from "../../Source/Cesium.js";
|
|
import { GlobeSurfaceTileProvider } from "../../Source/Cesium.js";
|
|
import { ImageryLayerCollection } from "../../Source/Cesium.js";
|
|
import { QuadtreePrimitive } from "../../Source/Cesium.js";
|
|
import { SceneMode } from "../../Source/Cesium.js";
|
|
import { TerrainFillMesh } from "../../Source/Cesium.js";
|
|
import { TileBoundingRegion } from "../../Source/Cesium.js";
|
|
import { TileSelectionResult } from "../../Source/Cesium.js";
|
|
|
|
describe("Scene/TerrainFillMesh", function () {
|
|
var processor;
|
|
var scene;
|
|
var camera;
|
|
var frameState;
|
|
var imageryLayerCollection;
|
|
var surfaceShaderSet;
|
|
var mockTerrain;
|
|
var tileProvider;
|
|
var quadtree;
|
|
var rootTiles;
|
|
|
|
var center;
|
|
var west;
|
|
var south;
|
|
var east;
|
|
var north;
|
|
var southwest;
|
|
var southeast;
|
|
var northwest;
|
|
var northeast;
|
|
|
|
beforeEach(function () {
|
|
scene = {
|
|
mapProjection: new GeographicProjection(),
|
|
drawingBufferWidth: 1000,
|
|
drawingBufferHeight: 1000,
|
|
};
|
|
|
|
camera = new Camera(scene);
|
|
|
|
frameState = {
|
|
frameNumber: 0,
|
|
passes: {
|
|
render: true,
|
|
},
|
|
camera: camera,
|
|
fog: {
|
|
enabled: false,
|
|
},
|
|
context: {
|
|
drawingBufferWidth: scene.drawingBufferWidth,
|
|
drawingBufferHeight: scene.drawingBufferHeight,
|
|
},
|
|
mode: SceneMode.SCENE3D,
|
|
commandList: [],
|
|
cullingVolume: jasmine.createSpyObj("CullingVolume", [
|
|
"computeVisibility",
|
|
]),
|
|
afterRender: [],
|
|
};
|
|
|
|
frameState.cullingVolume.computeVisibility.and.returnValue(
|
|
Intersect.INTERSECTING
|
|
);
|
|
|
|
imageryLayerCollection = new ImageryLayerCollection();
|
|
surfaceShaderSet = jasmine.createSpyObj("SurfaceShaderSet", [
|
|
"getShaderProgram",
|
|
]);
|
|
mockTerrain = new MockTerrainProvider();
|
|
tileProvider = new GlobeSurfaceTileProvider({
|
|
terrainProvider: mockTerrain,
|
|
imageryLayers: imageryLayerCollection,
|
|
surfaceShaderSet: surfaceShaderSet,
|
|
});
|
|
quadtree = new QuadtreePrimitive({
|
|
tileProvider: tileProvider,
|
|
});
|
|
|
|
processor = new TerrainTileProcessor(
|
|
frameState,
|
|
mockTerrain,
|
|
imageryLayerCollection
|
|
);
|
|
processor.mockWebGL();
|
|
|
|
quadtree.render(frameState);
|
|
rootTiles = quadtree._levelZeroTiles;
|
|
|
|
center =
|
|
rootTiles[0].northeastChild.southwestChild.northeastChild.southwestChild;
|
|
west = center.findTileToWest(rootTiles);
|
|
south = center.findTileToSouth(rootTiles);
|
|
east = center.findTileToEast(rootTiles);
|
|
north = center.findTileToNorth(rootTiles);
|
|
southwest = west.findTileToSouth(rootTiles);
|
|
southeast = east.findTileToSouth(rootTiles);
|
|
northwest = west.findTileToNorth(rootTiles);
|
|
northeast = east.findTileToNorth(rootTiles);
|
|
|
|
mockTerrain
|
|
.requestTileGeometryWillSucceedWith(
|
|
new HeightmapTerrainData({
|
|
width: 3,
|
|
height: 3,
|
|
createdByUpsampling: false,
|
|
buffer: new Float32Array([
|
|
15.0,
|
|
16.0,
|
|
17.0,
|
|
22.0,
|
|
23.0,
|
|
24.0,
|
|
29.0,
|
|
30.0,
|
|
31.0,
|
|
]),
|
|
}),
|
|
west
|
|
)
|
|
.createMeshWillSucceed(west);
|
|
|
|
mockTerrain
|
|
.requestTileGeometryWillSucceedWith(
|
|
new HeightmapTerrainData({
|
|
width: 3,
|
|
height: 3,
|
|
createdByUpsampling: false,
|
|
buffer: new Float32Array([
|
|
31.0,
|
|
32.0,
|
|
33.0,
|
|
38.0,
|
|
39.0,
|
|
40.0,
|
|
45.0,
|
|
46.0,
|
|
47.0,
|
|
]),
|
|
}),
|
|
south
|
|
)
|
|
.createMeshWillSucceed(south);
|
|
|
|
mockTerrain
|
|
.requestTileGeometryWillSucceedWith(
|
|
new HeightmapTerrainData({
|
|
width: 3,
|
|
height: 3,
|
|
createdByUpsampling: false,
|
|
buffer: new Float32Array([
|
|
19.0,
|
|
20.0,
|
|
21.0,
|
|
26.0,
|
|
27.0,
|
|
28.0,
|
|
33.0,
|
|
34.0,
|
|
35.0,
|
|
]),
|
|
}),
|
|
east
|
|
)
|
|
.createMeshWillSucceed(east);
|
|
|
|
mockTerrain
|
|
.requestTileGeometryWillSucceedWith(
|
|
new HeightmapTerrainData({
|
|
width: 3,
|
|
height: 3,
|
|
createdByUpsampling: false,
|
|
buffer: new Float32Array([
|
|
3.0,
|
|
4.0,
|
|
5.0,
|
|
10.0,
|
|
11.0,
|
|
12.0,
|
|
17.0,
|
|
18.0,
|
|
19.0,
|
|
]),
|
|
}),
|
|
north
|
|
)
|
|
.createMeshWillSucceed(north);
|
|
|
|
mockTerrain
|
|
.requestTileGeometryWillSucceedWith(
|
|
new HeightmapTerrainData({
|
|
width: 3,
|
|
height: 3,
|
|
createdByUpsampling: false,
|
|
buffer: new Float32Array([
|
|
29.0,
|
|
30.0,
|
|
31.0,
|
|
36.0,
|
|
37.0,
|
|
38.0,
|
|
43.0,
|
|
44.0,
|
|
45.0,
|
|
]),
|
|
}),
|
|
southwest
|
|
)
|
|
.createMeshWillSucceed(southwest);
|
|
|
|
mockTerrain
|
|
.requestTileGeometryWillSucceedWith(
|
|
new HeightmapTerrainData({
|
|
width: 3,
|
|
height: 3,
|
|
createdByUpsampling: false,
|
|
buffer: new Float32Array([
|
|
33.0,
|
|
34.0,
|
|
35.0,
|
|
40.0,
|
|
41.0,
|
|
42.0,
|
|
47.0,
|
|
48.0,
|
|
49.0,
|
|
]),
|
|
}),
|
|
southeast
|
|
)
|
|
.createMeshWillSucceed(southeast);
|
|
|
|
mockTerrain
|
|
.requestTileGeometryWillSucceedWith(
|
|
new HeightmapTerrainData({
|
|
width: 3,
|
|
height: 3,
|
|
createdByUpsampling: false,
|
|
buffer: new Float32Array([
|
|
1.0,
|
|
2.0,
|
|
3.0,
|
|
8.0,
|
|
9.0,
|
|
10.0,
|
|
15.0,
|
|
16.0,
|
|
17.0,
|
|
]),
|
|
}),
|
|
northwest
|
|
)
|
|
.createMeshWillSucceed(northwest);
|
|
|
|
mockTerrain
|
|
.requestTileGeometryWillSucceedWith(
|
|
new HeightmapTerrainData({
|
|
width: 3,
|
|
height: 3,
|
|
createdByUpsampling: false,
|
|
buffer: new Float32Array([
|
|
5.0,
|
|
6.0,
|
|
7.0,
|
|
12.0,
|
|
13.0,
|
|
14.0,
|
|
19.0,
|
|
20.0,
|
|
21.0,
|
|
]),
|
|
}),
|
|
northeast
|
|
)
|
|
.createMeshWillSucceed(northeast);
|
|
});
|
|
|
|
describe("updateFillTiles", function () {
|
|
it("does nothing if no rendered tiles are provided", function () {
|
|
expect(function () {
|
|
TerrainFillMesh.updateFillTiles(tileProvider, [], frameState);
|
|
}).not.toThrow();
|
|
});
|
|
|
|
it("propagates edges and corners to an unloaded tile", function () {
|
|
var tiles = [
|
|
center,
|
|
west,
|
|
south,
|
|
east,
|
|
north,
|
|
southwest,
|
|
southeast,
|
|
northwest,
|
|
northeast,
|
|
];
|
|
|
|
tiles.forEach(mockTerrain.createMeshWillSucceed.bind(mockTerrain));
|
|
|
|
return processor.process(tiles).then(function () {
|
|
tiles.forEach(markRendered);
|
|
|
|
TerrainFillMesh.updateFillTiles(tileProvider, tiles, frameState);
|
|
|
|
var fill = center.data.fill;
|
|
expect(fill).toBeDefined();
|
|
expect(fill.westTiles).toEqual([west]);
|
|
expect(fill.westMeshes).toEqual([west.data.mesh]);
|
|
expect(fill.southTiles).toEqual([south]);
|
|
expect(fill.southMeshes).toEqual([south.data.mesh]);
|
|
expect(fill.eastTiles).toEqual([east]);
|
|
expect(fill.eastMeshes).toEqual([east.data.mesh]);
|
|
expect(fill.northTiles).toEqual([north]);
|
|
expect(fill.northMeshes).toEqual([north.data.mesh]);
|
|
expect(fill.southwestTile).toEqual(southwest);
|
|
expect(fill.southwestMesh).toEqual(southwest.data.mesh);
|
|
expect(fill.southeastTile).toEqual(southeast);
|
|
expect(fill.southeastMesh).toEqual(southeast.data.mesh);
|
|
expect(fill.northwestTile).toEqual(northwest);
|
|
expect(fill.northwestMesh).toEqual(northwest.data.mesh);
|
|
expect(fill.northeastTile).toEqual(northeast);
|
|
expect(fill.northeastMesh).toEqual(northeast.data.mesh);
|
|
});
|
|
});
|
|
|
|
it("propagates fill tile edges to an unloaded tile", function () {
|
|
var centerSW = center.southwestChild;
|
|
var centerSE = center.southeastChild;
|
|
var centerNW = center.northwestChild;
|
|
var centerNE = center.northeastChild;
|
|
|
|
var tiles = [
|
|
centerSW,
|
|
centerSE,
|
|
centerNW,
|
|
centerNE,
|
|
west,
|
|
south,
|
|
east,
|
|
north,
|
|
southwest,
|
|
southeast,
|
|
northwest,
|
|
northeast,
|
|
];
|
|
|
|
tiles.forEach(mockTerrain.createMeshWillSucceed.bind(mockTerrain));
|
|
|
|
return processor.process(tiles).then(function () {
|
|
tiles.forEach(markRendered);
|
|
|
|
TerrainFillMesh.updateFillTiles(tileProvider, tiles, frameState);
|
|
|
|
var sw = centerSW.data.fill;
|
|
var se = centerSE.data.fill;
|
|
var nw = centerNW.data.fill;
|
|
var ne = centerNE.data.fill;
|
|
|
|
expect(sw).toBeDefined();
|
|
expect(sw.westTiles).toEqual([west]);
|
|
expect(sw.westMeshes).toEqual([west.data.mesh]);
|
|
expect(sw.southTiles).toEqual([south]);
|
|
expect(sw.southMeshes).toEqual([south.data.mesh]);
|
|
expect(sw.southwestTile).toEqual(southwest);
|
|
expect(sw.southwestMesh).toEqual(southwest.data.mesh);
|
|
expect(sw.southeastTile).toBeUndefined();
|
|
expect(sw.southeastMesh).toBeUndefined();
|
|
expect(sw.northwestTile).toBeUndefined();
|
|
expect(sw.northwestMesh).toBeUndefined();
|
|
|
|
expect(se).toBeDefined();
|
|
expect(se.eastTiles).toEqual([east]);
|
|
expect(se.eastMeshes).toEqual([east.data.mesh]);
|
|
expect(se.southTiles).toEqual([south]);
|
|
expect(se.southMeshes).toEqual([south.data.mesh]);
|
|
expect(se.southeastTile).toEqual(southeast);
|
|
expect(se.southeastMesh).toEqual(southeast.data.mesh);
|
|
expect(se.southwestTile).toBeUndefined();
|
|
expect(se.southwestMesh).toBeUndefined();
|
|
expect(se.northeastTile).toBeUndefined();
|
|
expect(se.northeastMesh).toBeUndefined();
|
|
|
|
expect(nw).toBeDefined();
|
|
expect(nw.westTiles).toEqual([west]);
|
|
expect(nw.westMeshes).toEqual([west.data.mesh]);
|
|
expect(nw.northTiles).toEqual([north]);
|
|
expect(nw.northMeshes).toEqual([north.data.mesh]);
|
|
expect(nw.northwestTile).toEqual(northwest);
|
|
expect(nw.northwestMesh).toEqual(northwest.data.mesh);
|
|
expect(nw.southwestTile).toBeUndefined();
|
|
expect(nw.southwestMesh).toBeUndefined();
|
|
expect(nw.northeastTile).toBeUndefined();
|
|
expect(nw.northeastMesh).toBeUndefined();
|
|
|
|
expect(ne).toBeDefined();
|
|
expect(ne.eastTiles).toEqual([east]);
|
|
expect(ne.eastMeshes).toEqual([east.data.mesh]);
|
|
expect(ne.northTiles).toEqual([north]);
|
|
expect(ne.northMeshes).toEqual([north.data.mesh]);
|
|
expect(ne.northeastTile).toEqual(northeast);
|
|
expect(ne.northeastMesh).toEqual(northeast.data.mesh);
|
|
expect(ne.southeastTile).toBeUndefined();
|
|
expect(ne.southeastMesh).toBeUndefined();
|
|
expect(ne.northwestTile).toBeUndefined();
|
|
expect(ne.northwestMesh).toBeUndefined();
|
|
|
|
expect(
|
|
sw.eastTiles[0] === centerSE || se.westTiles[0] === centerSW
|
|
).toBe(true);
|
|
expect(
|
|
nw.eastTiles[0] === centerNE || ne.westTiles[0] === centerNW
|
|
).toBe(true);
|
|
|
|
expect(
|
|
sw.northTiles[0] === centerNW || nw.southTiles[0] === centerSW
|
|
).toBe(true);
|
|
expect(
|
|
se.northTiles[0] === centerNE || ne.southTiles[0] === centerSE
|
|
).toBe(true);
|
|
|
|
expect(
|
|
sw.northeastTile === centerNE || ne.southwestTile === centerSW
|
|
).toBe(true);
|
|
expect(
|
|
nw.southeastTile === centerSE || se.northwestTile === centerNW
|
|
).toBe(true);
|
|
});
|
|
});
|
|
|
|
it("does not touch disconnected tiles", function () {
|
|
var disconnected = center.southwestChild.northeastChild;
|
|
|
|
var tiles = [
|
|
disconnected,
|
|
west,
|
|
south,
|
|
east,
|
|
north,
|
|
southwest,
|
|
southeast,
|
|
northwest,
|
|
northeast,
|
|
];
|
|
|
|
tiles.forEach(mockTerrain.createMeshWillSucceed.bind(mockTerrain));
|
|
|
|
return processor.process(tiles).then(function () {
|
|
tiles.forEach(markRendered);
|
|
|
|
TerrainFillMesh.updateFillTiles(tileProvider, tiles, frameState);
|
|
|
|
expect(disconnected.data.fill).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
it("propagates multiple adjacent source tiles to a destination edge", function () {
|
|
var tiles = [center, west, south, east, north];
|
|
[west, south, east, north].forEach(function (tile) {
|
|
tile.children.forEach(function (child) {
|
|
mockTerrain.willBeUnavailable(child);
|
|
mockTerrain.upsampleWillSucceed(child);
|
|
tiles.push(child);
|
|
});
|
|
});
|
|
|
|
return processor.process(tiles).then(function () {
|
|
tiles.forEach(markRendered);
|
|
|
|
TerrainFillMesh.updateFillTiles(tileProvider, tiles, frameState);
|
|
|
|
var fill = center.data.fill;
|
|
expect(fill).toBeDefined();
|
|
expect(fill.westTiles).toEqual([
|
|
west.northeastChild,
|
|
west.southeastChild,
|
|
]);
|
|
expect(fill.southTiles).toEqual([
|
|
south.northwestChild,
|
|
south.northeastChild,
|
|
]);
|
|
expect(fill.eastTiles).toEqual([
|
|
east.southwestChild,
|
|
east.northwestChild,
|
|
]);
|
|
expect(fill.northTiles).toEqual([
|
|
north.southeastChild,
|
|
north.southwestChild,
|
|
]);
|
|
});
|
|
});
|
|
|
|
it("adjusts existing fill tiles when adjacent tiles are loaded", function () {
|
|
var tiles = [center, west, south, north];
|
|
|
|
tiles.forEach(mockTerrain.createMeshWillSucceed.bind(mockTerrain));
|
|
|
|
return processor
|
|
.process(tiles)
|
|
.then(function () {
|
|
tiles.forEach(markRendered);
|
|
|
|
TerrainFillMesh.updateFillTiles(tileProvider, tiles, frameState);
|
|
|
|
var fill = center.data.fill;
|
|
expect(fill).toBeDefined();
|
|
expect(fill.westTiles).toEqual([west]);
|
|
expect(fill.westMeshes).toEqual([west.data.mesh]);
|
|
expect(fill.southTiles).toEqual([south]);
|
|
expect(fill.southMeshes).toEqual([south.data.mesh]);
|
|
expect(fill.eastTiles).toEqual([]);
|
|
expect(fill.eastMeshes).toEqual([]);
|
|
expect(fill.northTiles).toEqual([north]);
|
|
expect(fill.northMeshes).toEqual([north.data.mesh]);
|
|
|
|
fill.update(tileProvider, frameState);
|
|
|
|
expectVertexCount(fill, 8);
|
|
|
|
tiles.push(east);
|
|
|
|
return processor.process(tiles);
|
|
})
|
|
.then(function () {
|
|
tiles.forEach(markRendered);
|
|
|
|
TerrainFillMesh.updateFillTiles(tileProvider, tiles, frameState);
|
|
|
|
var fill = center.data.fill;
|
|
expect(fill).toBeDefined();
|
|
expect(fill.westTiles).toEqual([west]);
|
|
expect(fill.westMeshes).toEqual([west.data.mesh]);
|
|
expect(fill.southTiles).toEqual([south]);
|
|
expect(fill.southMeshes).toEqual([south.data.mesh]);
|
|
expect(fill.eastTiles).toEqual([east]);
|
|
expect(fill.eastMeshes).toEqual([east.data.mesh]);
|
|
expect(fill.northTiles).toEqual([north]);
|
|
expect(fill.northMeshes).toEqual([north.data.mesh]);
|
|
|
|
fill.update(tileProvider, frameState);
|
|
|
|
expectVertexCount(fill, 9);
|
|
expectVertex(fill, 1.0, 0.5, 26.0);
|
|
});
|
|
});
|
|
|
|
it("adjusts existing fill tiles when an adjacent fill tile changes", function () {
|
|
var dontLoad = [east, south, southeast];
|
|
dontLoad.forEach(
|
|
mockTerrain.requestTileGeometryWillDefer.bind(mockTerrain)
|
|
);
|
|
|
|
var tiles = [
|
|
center,
|
|
west,
|
|
south,
|
|
east,
|
|
north,
|
|
southwest,
|
|
southeast,
|
|
northwest,
|
|
northeast,
|
|
];
|
|
|
|
return processor
|
|
.process(tiles)
|
|
.then(function () {
|
|
tiles.forEach(markRendered);
|
|
|
|
TerrainFillMesh.updateFillTiles(tileProvider, tiles, frameState);
|
|
center.data.fill.update(tileProvider, frameState);
|
|
south.data.fill.update(tileProvider, frameState);
|
|
east.data.fill.update(tileProvider, frameState);
|
|
southeast.data.fill.update(tileProvider, frameState);
|
|
|
|
expectVertexCount(center.data.fill, 7);
|
|
expectVertex(center.data.fill, 0.0, 0.0, 31.0);
|
|
expectVertex(center.data.fill, 0.0, 0.5, 24.0);
|
|
expectVertex(center.data.fill, 0.0, 1.0, 17.0);
|
|
expectVertex(center.data.fill, 0.5, 1.0, 18.0);
|
|
expectVertex(center.data.fill, 1.0, 1.0, 19.0);
|
|
|
|
expectVertexCount(south.data.fill, 6);
|
|
expectVertex(south.data.fill, 0.0, 1.0, 31.0);
|
|
expectVertex(south.data.fill, 0.0, 0.5, 38.0);
|
|
expectVertex(south.data.fill, 0.0, 0.0, 45.0);
|
|
|
|
expectVertexCount(east.data.fill, 6);
|
|
expectVertex(east.data.fill, 0.0, 1.0, 19.0);
|
|
expectVertex(east.data.fill, 0.5, 1.0, 20.0);
|
|
expectVertex(east.data.fill, 1.0, 1.0, 21.0);
|
|
|
|
expectVertexCount(southeast.data.fill, 5);
|
|
|
|
expect(getHeight(center.data.fill, 1.0, 0.0)).toBe(
|
|
getHeight(southeast.data.fill, 0.0, 1.0)
|
|
);
|
|
expect(getHeight(center.data.fill, 1.0, 0.0)).toBe(
|
|
getHeight(south.data.fill, 1.0, 1.0)
|
|
);
|
|
expect(getHeight(center.data.fill, 1.0, 0.0)).toBe(
|
|
getHeight(east.data.fill, 0.0, 0.0)
|
|
);
|
|
expect(getHeight(center.data.fill, 1.0, 1.0)).toBe(
|
|
getHeight(east.data.fill, 0.0, 1.0)
|
|
);
|
|
expect(getHeight(east.data.fill, 1.0, 0.0)).toBe(
|
|
getHeight(southeast.data.fill, 1.0, 1.0)
|
|
);
|
|
expect(getHeight(south.data.fill, 1.0, 0.0)).toBe(
|
|
getHeight(southeast.data.fill, 0.0, 0.0)
|
|
);
|
|
|
|
// Now load the south tile.
|
|
mockTerrain
|
|
.requestTileGeometryWillSucceedWith(
|
|
new HeightmapTerrainData({
|
|
width: 3,
|
|
height: 3,
|
|
createdByUpsampling: false,
|
|
buffer: new Float32Array([
|
|
31.0,
|
|
32.0,
|
|
33.0,
|
|
38.0,
|
|
39.0,
|
|
40.0,
|
|
45.0,
|
|
46.0,
|
|
47.0,
|
|
]),
|
|
}),
|
|
south
|
|
)
|
|
.createMeshWillSucceed(south);
|
|
|
|
return processor.process(tiles);
|
|
})
|
|
.then(function () {
|
|
tiles.forEach(markRendered);
|
|
|
|
TerrainFillMesh.updateFillTiles(tileProvider, tiles, frameState);
|
|
center.data.fill.update(tileProvider, frameState);
|
|
east.data.fill.update(tileProvider, frameState);
|
|
southeast.data.fill.update(tileProvider, frameState);
|
|
|
|
expect(south.data.fill).toBeUndefined();
|
|
|
|
expectVertexCount(center.data.fill, 8);
|
|
expectVertex(center.data.fill, 0.0, 0.0, 31.0);
|
|
expectVertex(center.data.fill, 0.0, 0.5, 24.0);
|
|
expectVertex(center.data.fill, 0.0, 1.0, 17.0);
|
|
expectVertex(center.data.fill, 0.5, 1.0, 18.0);
|
|
expectVertex(center.data.fill, 1.0, 1.0, 19.0);
|
|
expectVertex(center.data.fill, 1.0, 0.0, 33.0);
|
|
|
|
expectVertexCount(east.data.fill, 6);
|
|
expectVertex(east.data.fill, 0.0, 1.0, 19.0);
|
|
expectVertex(east.data.fill, 0.5, 1.0, 20.0);
|
|
expectVertex(east.data.fill, 1.0, 1.0, 21.0);
|
|
expectVertex(east.data.fill, 0.0, 0.0, 33.0);
|
|
|
|
expectVertexCount(southeast.data.fill, 6);
|
|
expectVertex(southeast.data.fill, 0.0, 0.0, 47.0);
|
|
expectVertex(southeast.data.fill, 0.0, 0.5, 40.0);
|
|
expectVertex(southeast.data.fill, 0.0, 1.0, 33.0);
|
|
|
|
expect(getHeight(east.data.fill, 1.0, 0.0)).toBe(
|
|
getHeight(southeast.data.fill, 1.0, 1.0)
|
|
);
|
|
});
|
|
});
|
|
|
|
// Mark all the tiles rendered.
|
|
function markRendered(tile) {
|
|
quadtree._lastSelectionFrameNumber = frameState.frameNumber;
|
|
tile._lastSelectionResultFrame = frameState.frameNumber;
|
|
tile._lastSelectionResult = TileSelectionResult.RENDERED;
|
|
|
|
var parent = tile.parent;
|
|
while (parent) {
|
|
if (parent._lastSelectionResultFrame !== frameState.frameNumber) {
|
|
parent._lastSelectionResultFrame = frameState.frameNumber;
|
|
parent._lastSelectionResult = TileSelectionResult.REFINED;
|
|
}
|
|
parent = parent.parent;
|
|
}
|
|
}
|
|
});
|
|
|
|
describe("update", function () {
|
|
it("puts a middle height at the four corners and center when there are no adjacent tiles", function () {
|
|
return processor.process([center]).then(function () {
|
|
center.data.tileBoundingRegion = new TileBoundingRegion({
|
|
rectangle: center.rectangle,
|
|
minimumHeight: 1.0,
|
|
maximumHeight: 3.0,
|
|
computeBoundingVolumes: false,
|
|
});
|
|
|
|
var fill = (center.data.fill = new TerrainFillMesh(center));
|
|
fill.update(tileProvider, frameState);
|
|
|
|
expectVertexCount(fill, 5);
|
|
expectVertex(fill, 0.0, 0.0, 2.0);
|
|
expectVertex(fill, 0.0, 1.0, 2.0);
|
|
expectVertex(fill, 1.0, 0.0, 2.0);
|
|
expectVertex(fill, 1.0, 1.0, 2.0);
|
|
expectVertex(fill, 0.5, 0.5, 2.0);
|
|
});
|
|
});
|
|
|
|
it("puts zero height at the four corners and center when there are no adjacent tiles and no bounding region", function () {
|
|
return processor.process([center]).then(function () {
|
|
var fill = (center.data.fill = new TerrainFillMesh(center));
|
|
fill.update(tileProvider, frameState);
|
|
|
|
expectVertexCount(fill, 5);
|
|
expectVertex(fill, 0.0, 0.0, 0.0);
|
|
expectVertex(fill, 0.0, 1.0, 0.0);
|
|
expectVertex(fill, 1.0, 0.0, 0.0);
|
|
expectVertex(fill, 1.0, 1.0, 0.0);
|
|
expectVertex(fill, 0.5, 0.5, 0.0);
|
|
});
|
|
});
|
|
|
|
it("uses adjacent edge heights", function () {
|
|
return processor
|
|
.process([center, west, south, east, north])
|
|
.then(function () {
|
|
var fill = (center.data.fill = new TerrainFillMesh(center));
|
|
|
|
fill.westTiles.push(west);
|
|
fill.westMeshes.push(west.data.mesh);
|
|
fill.southTiles.push(south);
|
|
fill.southMeshes.push(south.data.mesh);
|
|
fill.eastTiles.push(east);
|
|
fill.eastMeshes.push(east.data.mesh);
|
|
fill.northTiles.push(north);
|
|
fill.northMeshes.push(north.data.mesh);
|
|
|
|
fill.update(tileProvider, frameState);
|
|
|
|
expectVertexCount(fill, 9);
|
|
expectVertex(fill, 0.0, 0.0, 31.0);
|
|
expectVertex(fill, 0.5, 0.0, 32.0);
|
|
expectVertex(fill, 1.0, 0.0, 33.0);
|
|
expectVertex(fill, 0.0, 0.5, 24.0);
|
|
expectVertex(fill, 0.5, 0.5, (33.0 + 17.0) / 2);
|
|
expectVertex(fill, 1.0, 0.5, 26.0);
|
|
expectVertex(fill, 0.0, 1.0, 17.0);
|
|
expectVertex(fill, 0.5, 1.0, 18.0);
|
|
expectVertex(fill, 1.0, 1.0, 19.0);
|
|
});
|
|
});
|
|
|
|
it("uses adjacent corner heights if adjacent edges are not available", function () {
|
|
return processor
|
|
.process([center, southwest, southeast, northwest, northeast])
|
|
.then(function () {
|
|
var fill = (center.data.fill = new TerrainFillMesh(center));
|
|
|
|
fill.southwestTile = southwest;
|
|
fill.southwestMesh = southwest.data.mesh;
|
|
fill.southeastTile = southeast;
|
|
fill.southeastMesh = southeast.data.mesh;
|
|
fill.northwestTile = northwest;
|
|
fill.northwestMesh = northwest.data.mesh;
|
|
fill.northeastTile = northeast;
|
|
fill.northeastMesh = northeast.data.mesh;
|
|
|
|
fill.update(tileProvider, frameState);
|
|
|
|
expectVertexCount(fill, 5);
|
|
expectVertex(fill, 0.0, 0.0, 31.0);
|
|
expectVertex(fill, 1.0, 0.0, 33.0);
|
|
expectVertex(fill, 0.0, 1.0, 17.0);
|
|
expectVertex(fill, 1.0, 1.0, 19.0);
|
|
expectVertex(fill, 0.5, 0.5, (17.0 + 33.0) / 2.0);
|
|
});
|
|
});
|
|
|
|
it("finds a suitable corner vertex in a less detailed tile", function () {
|
|
var sw = center.southwestChild;
|
|
var se = center.southeastChild;
|
|
var nw = center.northwestChild;
|
|
var ne = center.northeastChild;
|
|
|
|
return processor
|
|
.process([sw, se, nw, ne, west, south, east, north])
|
|
.then(function () {
|
|
var fillSW = (sw.data.fill = new TerrainFillMesh(sw));
|
|
var fillSE = (se.data.fill = new TerrainFillMesh(se));
|
|
var fillNW = (nw.data.fill = new TerrainFillMesh(nw));
|
|
var fillNE = (ne.data.fill = new TerrainFillMesh(ne));
|
|
|
|
fillSW.westTiles.push(west);
|
|
fillSW.westMeshes.push(west.data.mesh);
|
|
fillSW.southTiles.push(south);
|
|
fillSW.southMeshes.push(south.data.mesh);
|
|
|
|
fillSE.eastTiles.push(east);
|
|
fillSE.eastMeshes.push(east.data.mesh);
|
|
fillSE.southTiles.push(south);
|
|
fillSE.southMeshes.push(south.data.mesh);
|
|
|
|
fillNW.westTiles.push(west);
|
|
fillNW.westMeshes.push(west.data.mesh);
|
|
fillNW.northTiles.push(north);
|
|
fillNW.northMeshes.push(north.data.mesh);
|
|
|
|
fillNE.eastTiles.push(east);
|
|
fillNE.eastMeshes.push(east.data.mesh);
|
|
fillNE.northTiles.push(north);
|
|
fillNE.northMeshes.push(north.data.mesh);
|
|
|
|
fillSW.update(tileProvider, frameState);
|
|
fillSE.update(tileProvider, frameState);
|
|
fillNW.update(tileProvider, frameState);
|
|
fillNE.update(tileProvider, frameState);
|
|
|
|
expectVertexCount(fillSW, 5);
|
|
expectVertex(fillSW, 0.0, 0.0, 31.0);
|
|
expectVertex(fillSW, 1.0, 0.0, 32.0);
|
|
expectVertex(fillSW, 0.0, 1.0, 24.0);
|
|
expectVertex(fillSW, 1.0, 1.0, (24.0 + 32.0) / 2);
|
|
expectVertex(fillSW, 0.5, 0.5, (24.0 + 32.0) / 2);
|
|
|
|
expectVertexCount(fillSE, 5);
|
|
expectVertex(fillSE, 0.0, 0.0, 32.0);
|
|
expectVertex(fillSE, 1.0, 0.0, 33.0);
|
|
expectVertex(fillSE, 0.0, 1.0, (32.0 + 26.0) / 2);
|
|
expectVertex(fillSE, 1.0, 1.0, 26.0);
|
|
expectVertex(fillSE, 0.5, 0.5, (26.0 + 33.0) / 2);
|
|
|
|
expectVertexCount(fillNW, 5);
|
|
expectVertex(fillNW, 0.0, 0.0, 24.0);
|
|
expectVertex(fillNW, 1.0, 0.0, (18.0 + 24.0) / 2);
|
|
expectVertex(fillNW, 0.0, 1.0, 17.0);
|
|
expectVertex(fillNW, 1.0, 1.0, 18.0);
|
|
expectVertex(fillNW, 0.5, 0.5, (17.0 + 24.0) / 2);
|
|
|
|
expectVertexCount(fillNE, 5);
|
|
expectVertex(fillNE, 0.0, 0.0, (18.0 + 26.0) / 2);
|
|
expectVertex(fillNE, 1.0, 0.0, 26.0);
|
|
expectVertex(fillNE, 0.0, 1.0, 18.0);
|
|
expectVertex(fillNE, 1.0, 1.0, 19.0);
|
|
expectVertex(fillNE, 0.5, 0.5, (18.0 + 26.0) / 2);
|
|
});
|
|
});
|
|
|
|
it("interpolates a suitable corner vertex from a less detailed tile", function () {
|
|
var sw = center.southwestChild.southwestChild;
|
|
var se = center.southeastChild.southeastChild;
|
|
var nw = center.northwestChild.northwestChild;
|
|
var ne = center.northeastChild.northeastChild;
|
|
|
|
return processor
|
|
.process([sw, se, nw, ne, west, south, east, north])
|
|
.then(function () {
|
|
var fillSW = (sw.data.fill = new TerrainFillMesh(sw));
|
|
var fillSE = (se.data.fill = new TerrainFillMesh(se));
|
|
var fillNW = (nw.data.fill = new TerrainFillMesh(nw));
|
|
var fillNE = (ne.data.fill = new TerrainFillMesh(ne));
|
|
|
|
fillSW.westTiles.push(west);
|
|
fillSW.westMeshes.push(west.data.mesh);
|
|
fillSW.southTiles.push(south);
|
|
fillSW.southMeshes.push(south.data.mesh);
|
|
|
|
fillSE.eastTiles.push(east);
|
|
fillSE.eastMeshes.push(east.data.mesh);
|
|
fillSE.southTiles.push(south);
|
|
fillSE.southMeshes.push(south.data.mesh);
|
|
|
|
fillNW.westTiles.push(west);
|
|
fillNW.westMeshes.push(west.data.mesh);
|
|
fillNW.northTiles.push(north);
|
|
fillNW.northMeshes.push(north.data.mesh);
|
|
|
|
fillNE.eastTiles.push(east);
|
|
fillNE.eastMeshes.push(east.data.mesh);
|
|
fillNE.northTiles.push(north);
|
|
fillNE.northMeshes.push(north.data.mesh);
|
|
|
|
fillSW.update(tileProvider, frameState);
|
|
fillSE.update(tileProvider, frameState);
|
|
fillNW.update(tileProvider, frameState);
|
|
fillNE.update(tileProvider, frameState);
|
|
|
|
expectVertexCount(fillSW, 5);
|
|
expectVertex(fillSW, 0.0, 0.0, 31.0);
|
|
expectVertex(fillSW, 1.0, 0.0, (31.0 + 32.0) / 2);
|
|
expectVertex(fillSW, 0.0, 1.0, (31.0 + 24.0) / 2);
|
|
expectVertex(
|
|
fillSW,
|
|
1.0,
|
|
1.0,
|
|
((31.0 + 32.0) / 2 + (31.0 + 24.0) / 2) / 2
|
|
);
|
|
expectVertex(
|
|
fillSW,
|
|
0.5,
|
|
0.5,
|
|
((31.0 + 32.0) / 2 + (31.0 + 24.0) / 2) / 2
|
|
);
|
|
|
|
expectVertexCount(fillSE, 5);
|
|
expectVertex(fillSE, 0.0, 0.0, (32.0 + 33.0) / 2);
|
|
expectVertex(fillSE, 1.0, 0.0, 33.0);
|
|
expectVertex(
|
|
fillSE,
|
|
0.0,
|
|
1.0,
|
|
((32.0 + 33.0) / 2 + (33.0 + 26.0) / 2) / 2
|
|
);
|
|
expectVertex(fillSE, 1.0, 1.0, (33.0 + 26.0) / 2);
|
|
expectVertex(fillSE, 0.5, 0.5, (33.0 + (33.0 + 26.0) / 2) / 2);
|
|
|
|
expectVertexCount(fillNW, 5);
|
|
expectVertex(fillNW, 0.0, 0.0, (17.0 + 24.0) / 2);
|
|
expectVertex(
|
|
fillNW,
|
|
1.0,
|
|
0.0,
|
|
((17.0 + 18.0) / 2 + (17.0 + 24.0) / 2) / 2
|
|
);
|
|
expectVertex(fillNW, 0.0, 1.0, 17.0);
|
|
expectVertex(fillNW, 1.0, 1.0, (17.0 + 18.0) / 2);
|
|
expectVertex(fillNW, 0.5, 0.5, (17.0 + (17.0 + 24.0) / 2) / 2);
|
|
|
|
expectVertexCount(fillNE, 5);
|
|
expectVertex(
|
|
fillNE,
|
|
0.0,
|
|
0.0,
|
|
((19.0 + 26.0) / 2 + (18.0 + 19.0) / 2) / 2
|
|
);
|
|
expectVertex(fillNE, 1.0, 0.0, (19.0 + 26.0) / 2);
|
|
expectVertex(fillNE, 0.0, 1.0, (18.0 + 19.0) / 2);
|
|
expectVertex(fillNE, 1.0, 1.0, 19.0);
|
|
expectVertex(
|
|
fillNE,
|
|
0.5,
|
|
0.5,
|
|
((18.0 + 19.0) / 2 + (19.0 + 26.0) / 2) / 2
|
|
);
|
|
});
|
|
});
|
|
|
|
it("uses the height of the closest vertex when an edge does not include the corner", function () {
|
|
var westN = west.northeastChild.southeastChild;
|
|
var westS = west.southeastChild.northeastChild;
|
|
var eastN = east.northwestChild.southwestChild;
|
|
var eastS = east.southwestChild.northwestChild;
|
|
var northW = north.southwestChild.southeastChild;
|
|
var northE = north.southeastChild.southwestChild;
|
|
var southW = south.northwestChild.northeastChild;
|
|
var southE = south.northeastChild.northwestChild;
|
|
|
|
mockTerrain
|
|
.requestTileGeometryWillSucceedWith(
|
|
new HeightmapTerrainData({
|
|
width: 2,
|
|
height: 2,
|
|
createdByUpsampling: false,
|
|
buffer: new Float32Array([1.0, 1.0, 1.5, 1.5]),
|
|
}),
|
|
westN
|
|
)
|
|
.createMeshWillSucceed(westN);
|
|
|
|
mockTerrain
|
|
.requestTileGeometryWillSucceedWith(
|
|
new HeightmapTerrainData({
|
|
width: 2,
|
|
height: 2,
|
|
createdByUpsampling: false,
|
|
buffer: new Float32Array([1.5, 1.5, 2.0, 2.0]),
|
|
}),
|
|
westS
|
|
)
|
|
.createMeshWillSucceed(westS);
|
|
|
|
mockTerrain
|
|
.requestTileGeometryWillSucceedWith(
|
|
new HeightmapTerrainData({
|
|
width: 2,
|
|
height: 2,
|
|
createdByUpsampling: false,
|
|
buffer: new Float32Array([3.0, 3.0, 3.5, 3.5]),
|
|
}),
|
|
eastN
|
|
)
|
|
.createMeshWillSucceed(eastN);
|
|
|
|
mockTerrain
|
|
.requestTileGeometryWillSucceedWith(
|
|
new HeightmapTerrainData({
|
|
width: 2,
|
|
height: 2,
|
|
createdByUpsampling: false,
|
|
buffer: new Float32Array([3.5, 3.5, 4.0, 4.0]),
|
|
}),
|
|
eastS
|
|
)
|
|
.createMeshWillSucceed(eastS);
|
|
|
|
mockTerrain
|
|
.requestTileGeometryWillSucceedWith(
|
|
new HeightmapTerrainData({
|
|
width: 2,
|
|
height: 2,
|
|
createdByUpsampling: false,
|
|
buffer: new Float32Array([5.0, 5.5, 5.0, 5.5]),
|
|
}),
|
|
northW
|
|
)
|
|
.createMeshWillSucceed(northW);
|
|
|
|
mockTerrain
|
|
.requestTileGeometryWillSucceedWith(
|
|
new HeightmapTerrainData({
|
|
width: 2,
|
|
height: 2,
|
|
createdByUpsampling: false,
|
|
buffer: new Float32Array([5.5, 6.0, 6.5, 6.0]),
|
|
}),
|
|
northE
|
|
)
|
|
.createMeshWillSucceed(northE);
|
|
|
|
mockTerrain
|
|
.requestTileGeometryWillSucceedWith(
|
|
new HeightmapTerrainData({
|
|
width: 2,
|
|
height: 2,
|
|
createdByUpsampling: false,
|
|
buffer: new Float32Array([7.0, 7.5, 7.0, 7.5]),
|
|
}),
|
|
southW
|
|
)
|
|
.createMeshWillSucceed(southW);
|
|
|
|
mockTerrain
|
|
.requestTileGeometryWillSucceedWith(
|
|
new HeightmapTerrainData({
|
|
width: 2,
|
|
height: 2,
|
|
createdByUpsampling: false,
|
|
buffer: new Float32Array([7.5, 8.0, 7.5, 8.0]),
|
|
}),
|
|
southE
|
|
)
|
|
.createMeshWillSucceed(southE);
|
|
|
|
return processor
|
|
.process([
|
|
center,
|
|
westN,
|
|
westS,
|
|
eastN,
|
|
eastS,
|
|
northE,
|
|
northW,
|
|
southE,
|
|
southW,
|
|
])
|
|
.then(function () {
|
|
var fill = (center.data.fill = new TerrainFillMesh(center));
|
|
|
|
fill.westTiles.push(westN, westS);
|
|
fill.westMeshes.push(westN.data.mesh, westS.data.mesh);
|
|
fill.eastTiles.push(eastS, eastN);
|
|
fill.eastMeshes.push(eastS.data.mesh, eastN.data.mesh);
|
|
fill.northTiles.push(northE, northW);
|
|
fill.northMeshes.push(northE.data.mesh, northW.data.mesh);
|
|
fill.southTiles.push(southW, southE);
|
|
fill.southMeshes.push(southW.data.mesh, southE.data.mesh);
|
|
|
|
fill.update(tileProvider, frameState);
|
|
|
|
expectVertexCount(fill, 17);
|
|
expectVertex(fill, 0.0, 0.0, (2.0 + 7.0) / 2);
|
|
expectVertex(fill, 0.0, 0.25, 2.0);
|
|
expectVertex(fill, 0.0, 0.5, 1.5);
|
|
expectVertex(fill, 0.0, 0.75, 1.0);
|
|
expectVertex(fill, 0.0, 1.0, (1.0 + 5.0) / 2);
|
|
expectVertex(fill, 1.0, 0.0, (4.0 + 8.0) / 2);
|
|
expectVertex(fill, 1.0, 0.25, 4.0);
|
|
expectVertex(fill, 1.0, 0.5, 3.5);
|
|
expectVertex(fill, 1.0, 0.75, 3.0);
|
|
expectVertex(fill, 1.0, 1.0, (3.0 + 6.0) / 2);
|
|
});
|
|
});
|
|
|
|
describe("correctly transforms texture coordinates across the anti-meridian", function () {
|
|
var westernHemisphere;
|
|
var easternHemisphere;
|
|
|
|
beforeEach(function () {
|
|
westernHemisphere =
|
|
rootTiles[0].southwestChild.northwestChild.southwestChild
|
|
.northwestChild;
|
|
easternHemisphere =
|
|
rootTiles[1].southeastChild.northeastChild.southeastChild
|
|
.northeastChild;
|
|
|
|
// Make sure we have a standard geographic tiling scheme with two root tiles,
|
|
// the first covering the western hemisphere and the second the eastern.
|
|
expect(rootTiles.length).toBe(2);
|
|
expect(westernHemisphere.x).toBe(0);
|
|
expect(easternHemisphere.x).toBe(31);
|
|
});
|
|
|
|
it("western hemisphere to eastern hemisphere", function () {
|
|
mockTerrain.requestTileGeometryWillDefer(easternHemisphere);
|
|
mockTerrain
|
|
.requestTileGeometryWillSucceedWith(
|
|
new HeightmapTerrainData({
|
|
width: 3,
|
|
height: 3,
|
|
createdByUpsampling: false,
|
|
buffer: new Float32Array([
|
|
1.0,
|
|
2.0,
|
|
3.0,
|
|
4.0,
|
|
5.0,
|
|
6.0,
|
|
7.0,
|
|
8.0,
|
|
9.0,
|
|
]),
|
|
}),
|
|
westernHemisphere
|
|
)
|
|
.createMeshWillSucceed(westernHemisphere);
|
|
|
|
return processor
|
|
.process([westernHemisphere, easternHemisphere])
|
|
.then(function () {
|
|
var fill = (easternHemisphere.data.fill = new TerrainFillMesh(
|
|
easternHemisphere
|
|
));
|
|
|
|
fill.eastTiles.push(westernHemisphere);
|
|
fill.eastMeshes.push(westernHemisphere.data.mesh);
|
|
|
|
fill.update(tileProvider, frameState);
|
|
|
|
expectVertexCount(fill, 6);
|
|
expectVertex(fill, 1.0, 0.0, 7.0);
|
|
expectVertex(fill, 1.0, 0.5, 4.0);
|
|
expectVertex(fill, 1.0, 1.0, 1.0);
|
|
});
|
|
});
|
|
|
|
it("eastern hemisphere to western hemisphere", function () {
|
|
mockTerrain
|
|
.requestTileGeometryWillSucceedWith(
|
|
new HeightmapTerrainData({
|
|
width: 3,
|
|
height: 3,
|
|
createdByUpsampling: false,
|
|
buffer: new Float32Array([
|
|
10.0,
|
|
11.0,
|
|
12.0,
|
|
13.0,
|
|
14.0,
|
|
15.0,
|
|
16.0,
|
|
17.0,
|
|
18.0,
|
|
]),
|
|
}),
|
|
easternHemisphere
|
|
)
|
|
.createMeshWillSucceed(easternHemisphere);
|
|
mockTerrain.requestTileGeometryWillDefer(westernHemisphere);
|
|
|
|
return processor
|
|
.process([westernHemisphere, easternHemisphere])
|
|
.then(function () {
|
|
var fill = (westernHemisphere.data.fill = new TerrainFillMesh(
|
|
westernHemisphere
|
|
));
|
|
|
|
fill.westTiles.push(easternHemisphere);
|
|
fill.westMeshes.push(easternHemisphere.data.mesh);
|
|
|
|
fill.update(tileProvider, frameState);
|
|
|
|
expectVertexCount(fill, 6);
|
|
expectVertex(fill, 0.0, 0.0, 18.0);
|
|
expectVertex(fill, 0.0, 0.5, 15.0);
|
|
expectVertex(fill, 0.0, 1.0, 12.0);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
var textureCoordinateScratch = new Cartesian2();
|
|
var positionScratch = new Cartesian3();
|
|
var expectedPositionScratch = new Cartesian3();
|
|
|
|
function getHeight(fill, u, v) {
|
|
var mesh = fill.mesh;
|
|
var rectangle = fill.tile.rectangle;
|
|
var encoding = mesh.encoding;
|
|
var vertices = mesh.vertices;
|
|
var stride = encoding.getStride();
|
|
var count = mesh.vertices.length / stride;
|
|
|
|
for (var i = 0; i < count; ++i) {
|
|
var tc = encoding.decodeTextureCoordinates(
|
|
vertices,
|
|
i,
|
|
textureCoordinateScratch
|
|
);
|
|
var vertexHeight = encoding.decodeHeight(vertices, i);
|
|
var vertexPosition = encoding.decodePosition(
|
|
vertices,
|
|
i,
|
|
positionScratch
|
|
);
|
|
if (
|
|
Math.abs(u - tc.x) < 1e-5 &&
|
|
Math.abs(v - tc.y) < CesiumMath.EPSILON5
|
|
) {
|
|
var longitude = CesiumMath.lerp(rectangle.west, rectangle.east, u);
|
|
var latitude = CesiumMath.lerp(rectangle.south, rectangle.north, v);
|
|
var expectedPosition = Cartesian3.fromRadians(
|
|
longitude,
|
|
latitude,
|
|
vertexHeight,
|
|
undefined,
|
|
expectedPositionScratch
|
|
);
|
|
expect(vertexPosition).toEqualEpsilon(expectedPosition, 1);
|
|
return vertexHeight;
|
|
}
|
|
}
|
|
|
|
fail("Vertex with u=" + u + ", v=" + v + " does not exist.");
|
|
}
|
|
|
|
function expectVertex(fill, u, v, height) {
|
|
var vertexHeight = getHeight(fill, u, v);
|
|
expect(vertexHeight).toEqualEpsilon(height, CesiumMath.EPSILON5);
|
|
}
|
|
|
|
function expectVertexCount(fill, count) {
|
|
expect(fill.mesh.vertices.length).toBe(
|
|
count * fill.mesh.encoding.getStride()
|
|
);
|
|
}
|
|
});
|