Skip to content

Commit afb90a9

Browse files
author
Jeshurun Hembd
committed
Use local coordinates instead of UV for voxel transforms
1 parent e437bd5 commit afb90a9

11 files changed

+219
-282
lines changed

packages/engine/Source/Scene/VoxelBoxShape.js

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ function VoxelBoxShape() {
7777
this._renderBoundPlanes = new VoxelBoundCollection({ planes: boundPlanes });
7878

7979
this._shaderUniforms = {
80-
boxUvToShapeUvScale: new Cartesian3(),
81-
boxUvToShapeUvTranslate: new Cartesian3(),
80+
boxLocalToShapeUvScale: new Cartesian3(),
81+
boxLocalToShapeUvTranslate: new Cartesian3(),
8282
};
8383

8484
this._shaderDefines = {
@@ -315,17 +315,19 @@ VoxelBoxShape.prototype.update = function (
315315
const max = maxBounds;
316316

317317
// Compute scale and translation to transform from UV space to bounded UV space
318-
shaderUniforms.boxUvToShapeUvScale = Cartesian3.fromElements(
319-
2.0 / (min.x === max.x ? 1.0 : max.x - min.x),
320-
2.0 / (min.y === max.y ? 1.0 : max.y - min.y),
321-
2.0 / (min.z === max.z ? 1.0 : max.z - min.z),
322-
shaderUniforms.boxUvToShapeUvScale,
318+
const boxLocalToShapeUvScale = Cartesian3.fromElements(
319+
1.0 / (min.x === max.x ? 1.0 : max.x - min.x),
320+
1.0 / (min.y === max.y ? 1.0 : max.y - min.y),
321+
1.0 / (min.z === max.z ? 1.0 : max.z - min.z),
322+
shaderUniforms.boxLocalToShapeUvScale,
323323
);
324-
shaderUniforms.boxUvToShapeUvTranslate = Cartesian3.fromElements(
325-
-shaderUniforms.boxUvToShapeUvScale.x * (min.x * 0.5 + 0.5),
326-
-shaderUniforms.boxUvToShapeUvScale.y * (min.y * 0.5 + 0.5),
327-
-shaderUniforms.boxUvToShapeUvScale.z * (min.z * 0.5 + 0.5),
328-
shaderUniforms.boxUvToShapeUvTranslate,
324+
shaderUniforms.boxLocalToShapeUvTranslate = Cartesian3.negate(
325+
Cartesian3.multiplyComponents(
326+
boxLocalToShapeUvScale,
327+
min,
328+
shaderUniforms.boxLocalToShapeUvTranslate,
329+
),
330+
shaderUniforms.boxLocalToShapeUvTranslate,
329331
);
330332

331333
this._shaderMaximumIntersectionsLength = intersectionCount;
@@ -343,26 +345,26 @@ VoxelBoxShape.prototype.updateViewTransforms = function (frameState) {
343345
}
344346

345347
/**
346-
* Convert a UV coordinate to the shape's UV space.
348+
* Convert a local coordinate to the shape's UV space.
347349
* @private
348-
* @param {Cartesian3} positionUV The UV coordinate to convert.
350+
* @param {Cartesian3} positionLocal The local coordinate to convert.
349351
* @param {Cartesian3} result The Cartesian3 to store the result in.
350352
* @returns {Cartesian3} The converted UV coordinate.
351353
*/
352-
VoxelBoxShape.prototype.convertUvToShapeUvSpace = function (
353-
positionUV,
354+
VoxelBoxShape.prototype.convertLocalToShapeUvSpace = function (
355+
positionLocal,
354356
result,
355357
) {
356358
//>>includeStart('debug', pragmas.debug);
357-
Check.typeOf.object("positionUV", positionUV);
359+
Check.typeOf.object("positionLocal", positionLocal);
358360
Check.typeOf.object("result", result);
359361
//>>includeEnd('debug');
360362

361-
const { boxUvToShapeUvScale, boxUvToShapeUvTranslate } = this._shaderUniforms;
363+
const { boxLocalToShapeUvScale, boxLocalToShapeUvTranslate } = this._shaderUniforms;
362364

363365
return Cartesian3.add(
364-
Cartesian3.multiplyComponents(positionUV, boxUvToShapeUvScale, result),
365-
boxUvToShapeUvTranslate,
366+
Cartesian3.multiplyComponents(positionLocal, boxLocalToShapeUvScale, result),
367+
boxLocalToShapeUvTranslate,
366368
result,
367369
);
368370
};

packages/engine/Source/Scene/VoxelCylinderShape.js

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ function VoxelCylinderShape() {
5858
cylinderEcToRadialTangentUp: new Matrix3(),
5959
cylinderRenderRadiusMinMax: new Cartesian2(),
6060
cylinderRenderAngleMinMax: new Cartesian2(),
61-
cylinderUvToShapeUvRadius: new Cartesian2(),
62-
cylinderUvToShapeUvAngle: new Cartesian2(),
63-
cylinderUvToShapeUvHeight: new Cartesian2(),
61+
cylinderLocalToShapeUvRadius: new Cartesian2(),
62+
cylinderLocalToShapeUvAngle: new Cartesian2(),
63+
cylinderLocalToShapeUvHeight: new Cartesian2(),
6464
cylinderShapeUvAngleRangeOrigin: 0.0,
6565
};
6666

@@ -360,29 +360,25 @@ VoxelCylinderShape.prototype.update = function (
360360
let radialOffset = 1.0;
361361
if (radiusRange !== 0.0) {
362362
radialScale = 1.0 / radiusRange;
363-
radialOffset = -minBounds.x / radiusRange;
363+
radialOffset = -minBounds.x * radialScale;
364364
}
365-
shaderUniforms.cylinderUvToShapeUvRadius = Cartesian2.fromElements(
365+
shaderUniforms.cylinderLocalToShapeUvRadius = Cartesian2.fromElements(
366366
radialScale,
367367
radialOffset,
368-
shaderUniforms.cylinderUvToShapeUvRadius,
368+
shaderUniforms.cylinderLocalToShapeUvRadius,
369369
);
370370

371371
const heightRange = maxBounds.z - minBounds.z; // Default 2.0
372372
let heightScale = 0.0;
373373
let heightOffset = 1.0;
374374
if (heightRange !== 0.0) {
375375
heightScale = 1.0 / heightRange;
376-
// TODO: drop all this UV stuff. We are now using physical bounds in meters.
377-
// offset = -minHeightUv / (maxHeightUv - minHeightUv)
378-
// offset = -(minHeight * 0.5 + 0.5) / ((maxHeight * 0.5 + 0.5) - (minHeight * 0.5 + 0.5))
379-
// offset = -(minHeight + 1.0) / (maxHeight - minHeight)
380-
heightOffset = -(minBounds.z + 1.0) / heightRange;
376+
heightOffset = -minBounds.z * heightScale;
381377
}
382-
shaderUniforms.cylinderUvToShapeUvHeight = Cartesian2.fromElements(
378+
shaderUniforms.cylinderLocalToShapeUvHeight = Cartesian2.fromElements(
383379
heightScale,
384380
heightOffset,
385-
shaderUniforms.cylinderUvToShapeUvHeight,
381+
shaderUniforms.cylinderLocalToShapeUvHeight,
386382
);
387383

388384
if (renderHasAngle) {
@@ -416,19 +412,19 @@ VoxelCylinderShape.prototype.update = function (
416412
shaderUniforms.cylinderShapeUvAngleRangeOrigin = uvAngleRangeOrigin;
417413

418414
if (shapeAngleRange <= epsilonAngle) {
419-
shaderUniforms.cylinderUvToShapeUvAngle = Cartesian2.fromElements(
415+
shaderUniforms.cylinderLocalToShapeUvAngle = Cartesian2.fromElements(
420416
0.0,
421417
1.0,
422-
shaderUniforms.cylinderUvToShapeUvAngle,
418+
shaderUniforms.cylinderLocalToShapeUvAngle,
423419
);
424420
} else {
425421
const scale = defaultAngleRange / shapeAngleRange;
426422
const shiftedMinAngle = uvMinAngle - uvAngleRangeOrigin;
427423
const offset = -scale * (shiftedMinAngle - Math.floor(shiftedMinAngle));
428-
shaderUniforms.cylinderUvToShapeUvAngle = Cartesian2.fromElements(
424+
shaderUniforms.cylinderLocalToShapeUvAngle = Cartesian2.fromElements(
429425
scale,
430426
offset,
431-
shaderUniforms.cylinderUvToShapeUvAngle,
427+
shaderUniforms.cylinderLocalToShapeUvAngle,
432428
);
433429
}
434430

@@ -512,48 +508,40 @@ function updateRtuTransform(shape, frameState) {
512508
/**
513509
* Convert a UV coordinate to the shape's UV space.
514510
* @private
515-
* @param {Cartesian3} positionUV The UV coordinate to convert.
511+
* @param {Cartesian3} positionLocal The local coordinate to convert.
516512
* @param {Cartesian3} result The Cartesian3 to store the result in.
517513
* @returns {Cartesian3} The converted UV coordinate.
518514
*/
519-
VoxelCylinderShape.prototype.convertUvToShapeUvSpace = function (
520-
positionUV,
515+
VoxelCylinderShape.prototype.convertLocalToShapeUvSpace = function (
516+
positionLocal,
521517
result,
522518
) {
523519
//>>includeStart('debug', pragmas.debug);
524-
Check.typeOf.object("positionUV", positionUV);
520+
Check.typeOf.object("positionLocal", positionLocal);
525521
Check.typeOf.object("result", result);
526522
//>>includeEnd('debug');
527523

528-
// Convert from Cartesian UV space [0, 1] to Cartesian local space [-1, 1]
529-
const positionLocal = Cartesian3.fromElements(
530-
positionUV.x * 2.0 - 1.0,
531-
positionUV.y * 2.0 - 1.0,
532-
positionUV.z * 2.0 - 1.0,
533-
result,
534-
);
535-
536524
let radius = Math.hypot(positionLocal.x, positionLocal.y);
537525
let angle = Math.atan2(positionLocal.y, positionLocal.x);
538526
let height = positionLocal.z;
539527

540528
const {
541-
cylinderUvToShapeUvRadius,
542-
cylinderUvToShapeUvAngle,
529+
cylinderLocalToShapeUvRadius,
530+
cylinderLocalToShapeUvAngle,
543531
cylinderShapeUvAngleRangeOrigin,
544-
cylinderUvToShapeUvHeight,
532+
cylinderLocalToShapeUvHeight,
545533
} = this._shaderUniforms;
546534

547-
radius = radius * cylinderUvToShapeUvRadius.x + cylinderUvToShapeUvRadius.y;
535+
radius = radius * cylinderLocalToShapeUvRadius.x + cylinderLocalToShapeUvRadius.y;
548536

549537
// Convert angle to a "UV" in [0,1] with 0 defined at the center of the unoccupied space.
550538
angle = (angle + Math.PI) / (2.0 * Math.PI);
551539
angle -= cylinderShapeUvAngleRangeOrigin;
552540
angle = angle - Math.floor(angle);
553541
// Scale and shift so [0,1] covers the occupied space.
554-
angle = angle * cylinderUvToShapeUvAngle.x + cylinderUvToShapeUvAngle.y;
542+
angle = angle * cylinderLocalToShapeUvAngle.x + cylinderLocalToShapeUvAngle.y;
555543

556-
height = height * cylinderUvToShapeUvHeight.x + cylinderUvToShapeUvHeight.y;
544+
height = height * cylinderLocalToShapeUvHeight.x + cylinderLocalToShapeUvHeight.y;
557545

558546
return Cartesian3.fromElements(radius, angle, height, result);
559547
};

packages/engine/Source/Scene/VoxelEllipsoidShape.js

Lines changed: 14 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ function VoxelEllipsoidShape() {
7676
ellipsoidInverseRadiiSquared: new Cartesian3(),
7777
ellipsoidRenderLongitudeMinMax: new Cartesian2(),
7878
ellipsoidShapeUvLongitudeMinMaxMid: new Cartesian3(),
79-
ellipsoidUvToShapeUvLongitude: new Cartesian2(),
80-
ellipsoidUvToShapeUvLatitude: new Cartesian2(),
79+
ellipsoidLocalToShapeUvLongitude: new Cartesian2(),
80+
ellipsoidLocalToShapeUvLatitude: new Cartesian2(),
8181
ellipsoidRenderLatitudeSinMinMax: new Cartesian2(),
8282
ellipsoidInverseHeightDifference: 0.0,
8383
clipMinMaxHeight: new Cartesian2(),
@@ -558,29 +558,20 @@ VoxelEllipsoidShape.prototype.update = function (
558558
true;
559559
}
560560

561-
// delerp(longitudeUv, minLongitudeUv, maxLongitudeUv)
562-
// (longitudeUv - minLongitudeUv) / (maxLongitudeUv - minLongitudeUv)
563-
// longitudeUv / (maxLongitudeUv - minLongitudeUv) - minLongitudeUv / (maxLongitudeUv - minLongitudeUv)
564-
// scale = 1.0 / (maxLongitudeUv - minLongitudeUv)
565-
// scale = 1.0 / (((maxLongitude - pi) / (2.0 * pi)) - ((minLongitude - pi) / (2.0 * pi)))
566-
// scale = 2.0 * pi / (maxLongitude - minLongitude)
567-
// offset = -minLongitudeUv / (maxLongitudeUv - minLongitudeUv)
568-
// offset = -((minLongitude - pi) / (2.0 * pi)) / (((maxLongitude - pi) / (2.0 * pi)) - ((minLongitude - pi) / (2.0 * pi)))
569-
// offset = -(minLongitude - pi) / (maxLongitude - minLongitude)
570561
if (shapeLongitudeRange <= epsilonLongitude) {
571-
shaderUniforms.ellipsoidUvToShapeUvLongitude = Cartesian2.fromElements(
562+
shaderUniforms.ellipsoidLocalToShapeUvLongitude = Cartesian2.fromElements(
572563
0.0,
573564
1.0,
574-
shaderUniforms.ellipsoidUvToShapeUvLongitude,
565+
shaderUniforms.ellipsoidLocalToShapeUvLongitude,
575566
);
576567
} else {
577568
const scale = defaultLongitudeRange / shapeLongitudeRange;
578569
const offset =
579570
-(shapeMinBounds.x - DefaultMinBounds.x) / shapeLongitudeRange;
580-
shaderUniforms.ellipsoidUvToShapeUvLongitude = Cartesian2.fromElements(
571+
shaderUniforms.ellipsoidLocalToShapeUvLongitude = Cartesian2.fromElements(
581572
scale,
582573
offset,
583-
shaderUniforms.ellipsoidUvToShapeUvLongitude,
574+
shaderUniforms.ellipsoidLocalToShapeUvLongitude,
584575
);
585576
}
586577
}
@@ -680,31 +671,21 @@ VoxelEllipsoidShape.prototype.update = function (
680671
if (shapeHasLatitude) {
681672
shaderDefines["ELLIPSOID_HAS_SHAPE_BOUNDS_LATITUDE"] = true;
682673

683-
// delerp(latitudeUv, minLatitudeUv, maxLatitudeUv)
684-
// (latitudeUv - minLatitudeUv) / (maxLatitudeUv - minLatitudeUv)
685-
// latitudeUv / (maxLatitudeUv - minLatitudeUv) - minLatitudeUv / (maxLatitudeUv - minLatitudeUv)
686-
// scale = 1.0 / (maxLatitudeUv - minLatitudeUv)
687-
// scale = 1.0 / (((maxLatitude - pi) / (2.0 * pi)) - ((minLatitude - pi) / (2.0 * pi)))
688-
// scale = 2.0 * pi / (maxLatitude - minLatitude)
689-
// offset = -minLatitudeUv / (maxLatitudeUv - minLatitudeUv)
690-
// offset = -((minLatitude - -pi) / (2.0 * pi)) / (((maxLatitude - pi) / (2.0 * pi)) - ((minLatitude - pi) / (2.0 * pi)))
691-
// offset = -(minLatitude - -pi) / (maxLatitude - minLatitude)
692-
// offset = (-pi - minLatitude) / (maxLatitude - minLatitude)
693674
if (shapeLatitudeRange < epsilonLatitude) {
694-
shaderUniforms.ellipsoidUvToShapeUvLatitude = Cartesian2.fromElements(
675+
shaderUniforms.ellipsoidLocalToShapeUvLatitude = Cartesian2.fromElements(
695676
0.0,
696677
1.0,
697-
shaderUniforms.ellipsoidUvToShapeUvLatitude,
678+
shaderUniforms.ellipsoidLocalToShapeUvLatitude,
698679
);
699680
} else {
700681
const defaultLatitudeRange = DefaultMaxBounds.y - DefaultMinBounds.y;
701682
const scale = defaultLatitudeRange / shapeLatitudeRange;
702683
const offset =
703684
(DefaultMinBounds.y - shapeMinBounds.y) / shapeLatitudeRange;
704-
shaderUniforms.ellipsoidUvToShapeUvLatitude = Cartesian2.fromElements(
685+
shaderUniforms.ellipsoidLocalToShapeUvLatitude = Cartesian2.fromElements(
705686
scale,
706687
offset,
707-
shaderUniforms.ellipsoidUvToShapeUvLatitude,
688+
shaderUniforms.ellipsoidLocalToShapeUvLatitude,
708689
);
709690
}
710691
}
@@ -922,26 +903,19 @@ const scratchNormal2d = new Cartesian2();
922903
/**
923904
* Convert a UV coordinate to the shape's UV space.
924905
* @private
925-
* @param {Cartesian3} positionUV The UV coordinate to convert.
906+
* @param {Cartesian3} positionLocal The local position to convert.
926907
* @param {Cartesian3} result The Cartesian3 to store the result in.
927908
* @returns {Cartesian3} The converted UV coordinate.
928909
*/
929-
VoxelEllipsoidShape.prototype.convertUvToShapeUvSpace = function (
930-
positionUV,
910+
VoxelEllipsoidShape.prototype.convertLocalToShapeUvSpace = function (
911+
positionLocal,
931912
result,
932913
) {
933914
//>>includeStart('debug', pragmas.debug);
934-
Check.typeOf.object("positionUV", positionUV);
915+
Check.typeOf.object("positionLocal", positionLocal);
935916
Check.typeOf.object("result", result);
936917
//>>includeEnd('debug');
937918

938-
// Convert from Cartesian UV space [0, 1] to Cartesian local space [-1, 1]
939-
const positionLocal = Cartesian3.fromElements(
940-
positionUV.x * 2.0 - 1.0,
941-
positionUV.y * 2.0 - 1.0,
942-
positionUV.z * 2.0 - 1.0,
943-
result,
944-
);
945919
let longitude = Math.atan2(positionLocal.y, positionLocal.x);
946920

947921
const {

0 commit comments

Comments
 (0)