Skip to content

Commit ee5dcdd

Browse files
committed
Add DRAFT texture coordinate computation function
1 parent 72e0276 commit ee5dcdd

File tree

2 files changed

+237
-1
lines changed

2 files changed

+237
-1
lines changed

packages/engine/Source/Scene/Model/ImageryCoverage.js

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ class ImageryCoverage {
459459
x = rawX % numTilesX;
460460
/// XXX_DRAPING Debug log
461461
console.log(
462-
`Wrapping ${rawX} to ${x} for ${numTilesX} tiles on level ${imageryLevel}`,
462+
`ImageryCoverage._computeImageryCoverages: Wrapping ${rawX} to ${x} for ${numTilesX} tiles on level ${imageryLevel}`,
463463
);
464464
}
465465

@@ -491,6 +491,20 @@ class ImageryCoverage {
491491
undefined,
492492
);
493493

494+
// XXX_DRAPING Debug log...
495+
Rectangle.debugPrintDirectly(
496+
"ImageryCoverage._computeImageryCoverages: clippedImageryRectangleV",
497+
clippedImageryRectangleV,
498+
);
499+
Rectangle.debugPrintDirectly(
500+
"ImageryCoverage._computeImageryCoverages: nativeInputRectangle",
501+
nativeInputRectangle,
502+
);
503+
console.log(
504+
"ImageryCoverage._computeImageryCoverages: textureCoordinateRectangle",
505+
textureCoordinateRectangle,
506+
);
507+
494508
// Note: The getImageryFromCache function will create the whole "chain"
495509
// of ancestor imageries, up to the root, and increases the reference
496510
// counter for each of them, even though it is not called
@@ -512,6 +526,10 @@ class ImageryCoverage {
512526
}
513527

514528
/**
529+
* XXX_DRAPING This function does not work for rectangles that have
530+
* been converted to the "native" representation, because
531+
* Rectangle.computeWidth is broken for these rectangles
532+
*
515533
* Compute the coordinates of the first rectangle relative to the
516534
* second rectangle.
517535
*
@@ -541,6 +559,96 @@ class ImageryCoverage {
541559
result.maxY = (rectangleA.north - rectangleB.south) * invY;
542560
return result;
543561
}
562+
563+
/**
564+
* XXX_DRAPING This function should replace _localizeToCartesianRectangle,
565+
* but operates on Rectangles that are proper Cartographic rectangles,
566+
* which is often not the case for the imagery-related computations that
567+
* have been extracted from _createTileImagerySkeletons
568+
*
569+
* Compute the coordinates of the first rectangle relative to the
570+
* second rectangle.
571+
*
572+
* The result will describe the bounds of the first rectangle
573+
* in coordinates that are relative to the (west, south) and
574+
* (width, height) of the second rectangle, wrapping the
575+
* longitude at the antimeridian. This is suitable for
576+
* describing the texture coordinates of the first
577+
* rectangle within the second one.
578+
*
579+
* The result will be stored in the given result parameter, or
580+
* in a new rectangle if the result was undefined.
581+
*
582+
* @param {Rectangle} rectangleA The first rectangle
583+
* @param {Rectangle} rectangleB The second rectangle
584+
* @param {CartesianRectangle} [result] The result
585+
* @returns {CartesianRectangle} The result
586+
*/
587+
static _localizeCartographicRectanglesToCartesianRectangle(
588+
rectangleA,
589+
rectangleB,
590+
result,
591+
) {
592+
if (!defined(result)) {
593+
result = new CartesianRectangle();
594+
}
595+
const invX = 1.0 / rectangleB.width;
596+
const invY = 1.0 / rectangleB.height;
597+
598+
const wa = CesiumMath.zeroToTwoPi(rectangleA.west);
599+
const ea = CesiumMath.zeroToTwoPi(rectangleA.east);
600+
const wb = CesiumMath.zeroToTwoPi(rectangleB.west);
601+
602+
const rawMinX = ImageryCoverage.wrappedDifference(
603+
wa,
604+
wb,
605+
CesiumMath.TWO_PI,
606+
);
607+
const rawMaxX = ImageryCoverage.wrappedDifference(
608+
ea,
609+
wb,
610+
CesiumMath.TWO_PI,
611+
);
612+
613+
result.minX = rawMinX * invX;
614+
result.minY = (rectangleA.south - rectangleB.south) * invY;
615+
result.maxX = rawMaxX * invX;
616+
result.maxY = (rectangleA.north - rectangleB.south) * invY;
617+
return result;
618+
}
619+
620+
/**
621+
* Computes the difference between the given values, wrapped to
622+
* the given wrapping value.
623+
*
624+
* The values will be brought into the range [0, wrap]. The
625+
* result will be the signed (!) difference between both values,
626+
* considering the wrapping of the values.
627+
*
628+
* For example:
629+
* <code>wrappedDifference(0.9, 0.7, 1.0) = 0.2</code>
630+
* <code>wrappedDifference(0.7, 0.9, 1.0) = -0.2</code>
631+
* <code>wrappedDifference(1.1, 0.9, 1.0) = 0.2</code>
632+
* <code>wrappedDifference(0.9, 1.1, 1.0) = -0.2</code>
633+
*
634+
* @param {number} a The first value
635+
* @param {number} b The second value
636+
* @param {number} wrap The wrapping value
637+
* @returns The wrapped difference
638+
*/
639+
static wrappedDifference(a, b, wrap) {
640+
const wrappedA = (a %= wrap);
641+
const wrappedB = (b %= wrap);
642+
const diff = wrappedA - wrappedB;
643+
const absDiff = Math.abs(diff);
644+
if (absDiff < wrap - absDiff) {
645+
return diff;
646+
}
647+
if (diff < 0) {
648+
return diff + wrap;
649+
}
650+
return diff - wrap;
651+
}
544652
}
545653

546654
export default ImageryCoverage;
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import {
2+
Rectangle,
3+
ImageryCoverage,
4+
CartesianRectangle,
5+
Math as CesiumMath,
6+
} from "../../../index.js";
7+
8+
describe("Scene/Model/ImageryCoverage", function () {
9+
it("_localizeCartographicRectanglesToCartesianRectangle returns unit rectangle for equal inputs", async function () {
10+
const ra = Rectangle.fromDegrees(10, 10, 20, 20);
11+
const rb = Rectangle.fromDegrees(10, 10, 20, 20);
12+
const actual = new CartesianRectangle();
13+
const expected = new CartesianRectangle(0, 0, 1, 1);
14+
ImageryCoverage._localizeCartographicRectanglesToCartesianRectangle(
15+
ra,
16+
rb,
17+
actual,
18+
);
19+
expect(actual).toEqualEpsilon(expected, CesiumMath.EPSILON8);
20+
});
21+
22+
it("_localizeCartographicRectanglesToCartesianRectangle computes offset for overlapping inputs", async function () {
23+
const ra = Rectangle.fromDegrees(15, 15, 25, 25);
24+
const rb = Rectangle.fromDegrees(10, 10, 20, 20);
25+
const actual = new CartesianRectangle();
26+
const expected = new CartesianRectangle(0.5, 0.5, 1.5, 1.5);
27+
ImageryCoverage._localizeCartographicRectanglesToCartesianRectangle(
28+
ra,
29+
rb,
30+
actual,
31+
);
32+
expect(actual).toEqualEpsilon(expected, CesiumMath.EPSILON8);
33+
});
34+
35+
it("_localizeCartographicRectanglesToCartesianRectangle computes offset for non-overlapping inputs", async function () {
36+
const ra = Rectangle.fromDegrees(30, 30, 50, 50);
37+
const rb = Rectangle.fromDegrees(10, 10, 20, 20);
38+
const actual = new CartesianRectangle();
39+
const expected = new CartesianRectangle(2, 2, 4, 4);
40+
ImageryCoverage._localizeCartographicRectanglesToCartesianRectangle(
41+
ra,
42+
rb,
43+
actual,
44+
);
45+
expect(actual).toEqualEpsilon(expected, CesiumMath.EPSILON8);
46+
});
47+
48+
it("_localizeCartographicRectanglesToCartesianRectangle works when inner rectangle is left of antimeridian", async function () {
49+
const ra = Rectangle.fromDegrees(160, 10, 170, 50);
50+
const rb = Rectangle.fromDegrees(155, 10, -155, 50);
51+
const actual = new CartesianRectangle();
52+
const expected = new CartesianRectangle(0.1, 0, 0.3, 1);
53+
ImageryCoverage._localizeCartographicRectanglesToCartesianRectangle(
54+
ra,
55+
rb,
56+
actual,
57+
);
58+
expect(actual).toEqualEpsilon(expected, CesiumMath.EPSILON8);
59+
});
60+
61+
it("_localizeCartographicRectanglesToCartesianRectangle works when inner rectangle is right of antimeridian", async function () {
62+
const ra = Rectangle.fromDegrees(-175, 10, -165, 50);
63+
const rb = Rectangle.fromDegrees(155, 10, -155, 50);
64+
const actual = new CartesianRectangle();
65+
const expected = new CartesianRectangle(0.6, 0, 0.8, 1);
66+
ImageryCoverage._localizeCartographicRectanglesToCartesianRectangle(
67+
ra,
68+
rb,
69+
actual,
70+
);
71+
expect(actual).toEqualEpsilon(expected, CesiumMath.EPSILON8);
72+
});
73+
74+
it("_localizeCartographicRectanglesToCartesianRectangle works when inner rectangle crosses antimeridian", async function () {
75+
const ra = Rectangle.fromDegrees(175, 10, -175, 50);
76+
const rb = Rectangle.fromDegrees(155, 10, -155, 50);
77+
const actual = new CartesianRectangle();
78+
const expected = new CartesianRectangle(0.4, 0, 0.6, 1);
79+
80+
console.log(actual);
81+
82+
ImageryCoverage._localizeCartographicRectanglesToCartesianRectangle(
83+
ra,
84+
rb,
85+
actual,
86+
);
87+
expect(actual).toEqualEpsilon(expected, CesiumMath.EPSILON8);
88+
});
89+
90+
it("_localizeCartographicRectanglesToCartesianRectangle works when inner is left and outer is right of antimeridian", async function () {
91+
const ra = Rectangle.fromDegrees(-175, 10, -165, 50);
92+
const rb = Rectangle.fromDegrees(165, 10, 175, 50);
93+
const actual = new CartesianRectangle();
94+
const expected = new CartesianRectangle(2, 0, 3, 1);
95+
ImageryCoverage._localizeCartographicRectanglesToCartesianRectangle(
96+
ra,
97+
rb,
98+
actual,
99+
);
100+
expect(actual).toEqualEpsilon(expected, CesiumMath.EPSILON8);
101+
});
102+
103+
it("_localizeCartographicRectanglesToCartesianRectangle works when inner is right and outer is left or antimeridian", async function () {
104+
const ra = Rectangle.fromDegrees(165, 10, 175, 50);
105+
const rb = Rectangle.fromDegrees(-175, 10, -165, 50);
106+
const actual = new CartesianRectangle();
107+
const expected = new CartesianRectangle(-2, 0, -1, 1);
108+
ImageryCoverage._localizeCartographicRectanglesToCartesianRectangle(
109+
ra,
110+
rb,
111+
actual,
112+
);
113+
expect(actual).toEqualEpsilon(expected, CesiumMath.EPSILON8);
114+
});
115+
116+
it("_localizeCartographicRectanglesToCartesianRectangle works when inner is left or meridian and outer is right of meridian", async function () {
117+
const ra = Rectangle.fromDegrees(-20, 10, -10, 20);
118+
const rb = Rectangle.fromDegrees(10, 10, 20, 20);
119+
const actual = new CartesianRectangle();
120+
const expected = new CartesianRectangle(-3, 0, -2, 1);
121+
ImageryCoverage._localizeCartographicRectanglesToCartesianRectangle(
122+
ra,
123+
rb,
124+
actual,
125+
);
126+
expect(actual).toEqualEpsilon(expected, CesiumMath.EPSILON8);
127+
});
128+
});

0 commit comments

Comments
 (0)