diff --git a/CHANGES.md b/CHANGES.md
index 2e065a5c24d6..fcfa67f43159 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -2,10 +2,15 @@
### 1.74 - 2020-10-01
+##### Additions :tada:
+
+- Added `Matrix3.inverseTranspose` and `Matrix4.inverseTranspose`. [#9135](https://github.com/CesiumGS/cesium/pull/9135)
+
##### Fixes :wrench:
- Fixed an issue where the camera zooming is stuck when looking up. [#9126](https://github.com/CesiumGS/cesium/pull/9126)
- Fixed an issue where Plane doesn't rotate correctly around the main local axis. [#8268](https://github.com/CesiumGS/cesium/issues/8268)
+- Fixed clipping planes with non-uniform scale. [#9135](https://github.com/CesiumGS/cesium/pull/9135)
- Fixed an issue where ground primitives would get clipped at certain camera angles. [#9114](https://github.com/CesiumGS/cesium/issues/9114)
### 1.73 - 2020-09-01
diff --git a/Source/Core/Matrix3.js b/Source/Core/Matrix3.js
index f01c549fc61c..b8fc4076c343 100644
--- a/Source/Core/Matrix3.js
+++ b/Source/Core/Matrix3.js
@@ -1363,6 +1363,27 @@ Matrix3.inverse = function (matrix, result) {
return Matrix3.multiplyByScalar(result, scale, result);
};
+var scratchTransposeMatrix = new Matrix3();
+
+/**
+ * Computes the inverse transpose of a matrix.
+ *
+ * @param {Matrix3} matrix The matrix to transpose and invert.
+ * @param {Matrix3} result The object onto which to store the result.
+ * @returns {Matrix3} The modified result parameter.
+ */
+Matrix3.inverseTranspose = function (matrix, result) {
+ //>>includeStart('debug', pragmas.debug);
+ Check.typeOf.object("matrix", matrix);
+ Check.typeOf.object("result", result);
+ //>>includeEnd('debug');
+
+ return Matrix3.inverse(
+ Matrix3.transpose(matrix, scratchTransposeMatrix),
+ result
+ );
+};
+
/**
* Compares the provided matrices componentwise and returns
* true
if they are equal, false
otherwise.
diff --git a/Source/Core/Matrix4.js b/Source/Core/Matrix4.js
index 1d9d53620814..af38c33918c1 100644
--- a/Source/Core/Matrix4.js
+++ b/Source/Core/Matrix4.js
@@ -2647,6 +2647,27 @@ Matrix4.inverseTransformation = function (matrix, result) {
return result;
};
+var scratchTransposeMatrix = new Matrix4();
+
+/**
+ * Computes the inverse transpose of a matrix.
+ *
+ * @param {Matrix4} matrix The matrix to transpose and invert.
+ * @param {Matrix4} result The object onto which to store the result.
+ * @returns {Matrix4} The modified result parameter.
+ */
+Matrix4.inverseTranspose = function (matrix, result) {
+ //>>includeStart('debug', pragmas.debug);
+ Check.typeOf.object("matrix", matrix);
+ Check.typeOf.object("result", result);
+ //>>includeEnd('debug');
+
+ return Matrix4.inverse(
+ Matrix4.transpose(matrix, scratchTransposeMatrix),
+ result
+ );
+};
+
/**
* An immutable Matrix4 instance initialized to the identity matrix.
*
diff --git a/Source/Core/Plane.js b/Source/Core/Plane.js
index 5638d11b9b5d..db0d5392a8e9 100644
--- a/Source/Core/Plane.js
+++ b/Source/Core/Plane.js
@@ -1,4 +1,5 @@
import Cartesian3 from "./Cartesian3.js";
+import Cartesian4 from "./Cartesian4.js";
import Check from "./Check.js";
import defined from "./defined.js";
import DeveloperError from "./DeveloperError.js";
@@ -192,7 +193,9 @@ Plane.projectPointOntoPlane = function (plane, point, result) {
return Cartesian3.subtract(point, scaledNormal, result);
};
-var scratchPosition = new Cartesian3();
+var scratchInverseTranspose = new Matrix4();
+var scratchPlaneCartesian4 = new Cartesian4();
+var scratchTransformNormal = new Cartesian3();
/**
* Transforms the plane by the given transformation matrix.
*
@@ -207,13 +210,38 @@ Plane.transform = function (plane, transform, result) {
Check.typeOf.object("transform", transform);
//>>includeEnd('debug');
- Matrix4.multiplyByPointAsVector(transform, plane.normal, scratchNormal);
- Cartesian3.normalize(scratchNormal, scratchNormal);
+ var normal = plane.normal;
+ var distance = plane.distance;
+ var inverseTranspose = Matrix4.inverseTranspose(
+ transform,
+ scratchInverseTranspose
+ );
+ var planeAsCartesian4 = Cartesian4.fromElements(
+ normal.x,
+ normal.y,
+ normal.z,
+ distance,
+ scratchPlaneCartesian4
+ );
+ planeAsCartesian4 = Matrix4.multiplyByVector(
+ inverseTranspose,
+ planeAsCartesian4,
+ planeAsCartesian4
+ );
- Cartesian3.multiplyByScalar(plane.normal, -plane.distance, scratchPosition);
- Matrix4.multiplyByPoint(transform, scratchPosition, scratchPosition);
+ // Convert the transformed plane to Hessian Normal Form
+ var transformedNormal = Cartesian3.fromCartesian4(
+ planeAsCartesian4,
+ scratchTransformNormal
+ );
+
+ planeAsCartesian4 = Cartesian4.divideByScalar(
+ planeAsCartesian4,
+ Cartesian3.magnitude(transformedNormal),
+ planeAsCartesian4
+ );
- return Plane.fromPointNormal(scratchPosition, scratchNormal, result);
+ return Plane.fromCartesian4(planeAsCartesian4, result);
};
/**
diff --git a/Source/Scene/Batched3DModel3DTileContent.js b/Source/Scene/Batched3DModel3DTileContent.js
index 5e38ecf48cce..102e51b0e69c 100644
--- a/Source/Scene/Batched3DModel3DTileContent.js
+++ b/Source/Scene/Batched3DModel3DTileContent.js
@@ -545,7 +545,7 @@ Batched3DModel3DTileContent.prototype.update = function (tileset, frameState) {
// Update clipping planes
var tilesetClippingPlanes = this._tileset.clippingPlanes;
- this._model.clippingPlanesOriginMatrix = this._tileset.clippingPlanesOriginMatrix;
+ this._model.referenceMatrix = this._tileset.clippingPlanesOriginMatrix;
if (defined(tilesetClippingPlanes) && this._tile.clippingPlanesDirty) {
// Dereference the clipping planes from the model if they are irrelevant.
// Link/Dereference directly to avoid ownership checks.
diff --git a/Source/Scene/GlobeSurfaceTileProvider.js b/Source/Scene/GlobeSurfaceTileProvider.js
index 92f97c25d4a3..bcbbe12737ef 100644
--- a/Source/Scene/GlobeSurfaceTileProvider.js
+++ b/Source/Scene/GlobeSurfaceTileProvider.js
@@ -1501,7 +1501,8 @@ GlobeSurfaceTileProvider.prototype._onLayerShownOrHidden = function (
}
};
-var scratchClippingPlaneMatrix = new Matrix4();
+var scratchClippingPlanesMatrix = new Matrix4();
+var scratchInverseTransposeClippingPlanesMatrix = new Matrix4();
function createTileUniformMap(frameState, globeSurfaceTileProvider) {
var uniformMap = {
u_initialColor: function () {
@@ -1634,13 +1635,18 @@ function createTileUniformMap(frameState, globeSurfaceTileProvider) {
},
u_clippingPlanesMatrix: function () {
var clippingPlanes = globeSurfaceTileProvider._clippingPlanes;
- return defined(clippingPlanes)
+ var transform = defined(clippingPlanes)
? Matrix4.multiply(
frameState.context.uniformState.view,
clippingPlanes.modelMatrix,
- scratchClippingPlaneMatrix
+ scratchClippingPlanesMatrix
)
: Matrix4.IDENTITY;
+
+ return Matrix4.inverseTranspose(
+ transform,
+ scratchInverseTransposeClippingPlanesMatrix
+ );
},
u_clippingPlanesEdgeStyle: function () {
var style = this.properties.clippingPlanesEdgeColor;
diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js
index bc4cf26acdd5..747e3aff4ff2 100644
--- a/Source/Scene/Instanced3DModel3DTileContent.js
+++ b/Source/Scene/Instanced3DModel3DTileContent.js
@@ -624,7 +624,7 @@ Instanced3DModel3DTileContent.prototype.update = function (
if (defined(model)) {
// Update for clipping planes
var tilesetClippingPlanes = this._tileset.clippingPlanes;
- model.clippingPlanesOriginMatrix = this._tileset.clippingPlanesOriginMatrix;
+ model.referenceMatrix = this._tileset.clippingPlanesOriginMatrix;
if (defined(tilesetClippingPlanes) && this._tile.clippingPlanesDirty) {
// Dereference the clipping planes from the model if they are irrelevant - saves on shading
// Link/Dereference directly to avoid ownership checks.
diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js
index 796351610425..2ac7e08e7872 100644
--- a/Source/Scene/Model.js
+++ b/Source/Scene/Model.js
@@ -489,10 +489,12 @@ function Model(options) {
this.clippingPlanes = options.clippingPlanes;
// Used for checking if shaders need to be regenerated due to clipping plane changes.
this._clippingPlanesState = 0;
- // If defined, use this matrix to position the clipping planes instead of the modelMatrix.
- // This is so that when models are part of a tileset they all get clipped relative
- // to the root tile.
- this.clippingPlanesOriginMatrix = undefined;
+
+ // If defined, use this matrix to transform miscellaneous properties like
+ // clipping planes and IBL instead of the modelMatrix. This is so that when
+ // models are part of a tileset these properties get transformed relative to
+ // a common reference (such as the root).
+ this.referenceMatrix = undefined;
/**
* Whether to cull back-facing geometry. When true, back face culling is
@@ -564,7 +566,8 @@ function Model(options) {
this.opaquePass = defaultValue(options.opaquePass, Pass.OPAQUE);
this._computedModelMatrix = new Matrix4(); // Derived from modelMatrix and scale
- this._clippingPlaneModelViewMatrix = Matrix4.clone(Matrix4.IDENTITY); // Derived from modelMatrix, scale, and the current view matrix
+ this._clippingPlanesMatrix = Matrix4.clone(Matrix4.IDENTITY); // Derived from reference matrix and the current view matrix
+ this._iblReferenceFrameMatrix = Matrix3.clone(Matrix3.IDENTITY); // Derived from reference matrix and the current view matrix
this._initialRadius = undefined; // Radius without model's scale property, model-matrix scale, animations, or skins
this._boundingSphere = undefined;
this._scaledBoundingSphere = new BoundingSphere();
@@ -2489,7 +2492,7 @@ function createProgram(programToCreate, model, context) {
model._useDefaultSpecularMaps;
var addMatrix = usesSH || usesSM || useIBL;
if (addMatrix) {
- drawFS = "uniform mat4 gltf_clippingPlanesMatrix; \n" + drawFS;
+ drawFS = "uniform mat3 gltf_iblReferenceFrameMatrix; \n" + drawFS;
}
if (defined(model._sphericalHarmonicCoefficients)) {
@@ -2605,9 +2608,9 @@ function recreateProgram(programToCreate, model, context) {
(defined(model._specularEnvironmentMapAtlas) &&
model._specularEnvironmentMapAtlas.ready) ||
model._useDefaultSpecularMaps;
- var addMatrix = !addClippingPlaneCode && (usesSH || usesSM || useIBL);
+ var addMatrix = usesSH || usesSM || useIBL;
if (addMatrix) {
- drawFS = "uniform mat4 gltf_clippingPlanesMatrix; \n" + drawFS;
+ drawFS = "uniform mat3 gltf_iblReferenceFrameMatrix; \n" + drawFS;
}
if (defined(model._sphericalHarmonicCoefficients)) {
@@ -3659,25 +3662,15 @@ function createColorFunction(model) {
};
}
-var scratchClippingPlaneMatrix = new Matrix4();
function createClippingPlanesMatrixFunction(model) {
return function () {
- var clippingPlanes = model.clippingPlanes;
- if (
- !defined(clippingPlanes) &&
- !defined(model._sphericalHarmonicCoefficients) &&
- !defined(model._specularEnvironmentMaps)
- ) {
- return Matrix4.IDENTITY;
- }
- var modelMatrix = defined(clippingPlanes)
- ? clippingPlanes.modelMatrix
- : Matrix4.IDENTITY;
- return Matrix4.multiply(
- model._clippingPlaneModelViewMatrix,
- modelMatrix,
- scratchClippingPlaneMatrix
- );
+ return model._clippingPlanesMatrix;
+ };
+}
+
+function createIBLReferenceFrameMatrixFunction(model) {
+ return function () {
+ return model._iblReferenceFrameMatrix;
};
}
@@ -3859,6 +3852,9 @@ function createCommand(model, gltfNode, runtimeNode, context, scene3DOnly) {
model
),
gltf_clippingPlanesMatrix: createClippingPlanesMatrixFunction(model),
+ gltf_iblReferenceFrameMatrix: createIBLReferenceFrameMatrixFunction(
+ model
+ ),
gltf_iblFactor: createIBLFactorFunction(model),
gltf_lightColor: createLightColorFunction(model),
gltf_sphericalHarmonicCoefficients: createSphericalHarmonicCoefficientsFunction(
@@ -5101,6 +5097,10 @@ function distanceDisplayConditionVisible(model, frameState) {
return distance2 >= nearSquared && distance2 <= farSquared;
}
+var scratchClippingPlanesMatrix = new Matrix4();
+var scratchIBLReferenceFrameMatrix4 = new Matrix4();
+var scratchIBLReferenceFrameMatrix3 = new Matrix3();
+
/**
* Called when {@link Viewer} or {@link CesiumWidget} render the scene to
* get the draw commands needed to render this primitive.
@@ -5507,6 +5507,32 @@ Model.prototype.update = function (frameState) {
defined(clippingPlanes) &&
clippingPlanes.enabled &&
clippingPlanes.length > 0;
+
+ // If defined, use the reference matrix to transform miscellaneous properties like
+ // clipping planes and IBL instead of the modelMatrix. This is so that when
+ // models are part of a tileset these properties get transformed relative to
+ // a common reference (such as the root).
+ var referenceMatrix = defaultValue(this.referenceMatrix, modelMatrix);
+
+ if (useClippingPlanes) {
+ var clippingPlanesMatrix = scratchClippingPlanesMatrix;
+ clippingPlanesMatrix = Matrix4.multiply(
+ context.uniformState.view3D,
+ referenceMatrix,
+ clippingPlanesMatrix
+ );
+ clippingPlanesMatrix = Matrix4.multiply(
+ clippingPlanesMatrix,
+ clippingPlanes.modelMatrix,
+ clippingPlanesMatrix
+ );
+ this._clippingPlanesMatrix = Matrix4.inverseTranspose(
+ clippingPlanesMatrix,
+ this._clippingPlanesMatrix
+ );
+ currentClippingPlanesState = clippingPlanes.clippingPlanesState;
+ }
+
var usesSH =
defined(this._sphericalHarmonicCoefficients) ||
this._useDefaultSphericalHarmonics;
@@ -5514,20 +5540,28 @@ Model.prototype.update = function (frameState) {
(defined(this._specularEnvironmentMapAtlas) &&
this._specularEnvironmentMapAtlas.ready) ||
this._useDefaultSpecularMaps;
- if (useClippingPlanes || usesSH || usesSM) {
- var clippingPlanesOriginMatrix = defaultValue(
- this.clippingPlanesOriginMatrix,
- modelMatrix
- );
- Matrix4.multiply(
+
+ if (usesSH || usesSM) {
+ var iblReferenceFrameMatrix3 = scratchIBLReferenceFrameMatrix3;
+ var iblReferenceFrameMatrix4 = scratchIBLReferenceFrameMatrix4;
+
+ iblReferenceFrameMatrix4 = Matrix4.multiply(
context.uniformState.view3D,
- clippingPlanesOriginMatrix,
- this._clippingPlaneModelViewMatrix
+ referenceMatrix,
+ iblReferenceFrameMatrix4
+ );
+ iblReferenceFrameMatrix3 = Matrix4.getMatrix3(
+ iblReferenceFrameMatrix4,
+ iblReferenceFrameMatrix3
+ );
+ iblReferenceFrameMatrix3 = Matrix3.getRotation(
+ iblReferenceFrameMatrix3,
+ iblReferenceFrameMatrix3
+ );
+ this._iblReferenceFrameMatrix = Matrix3.transpose(
+ iblReferenceFrameMatrix3,
+ this._iblReferenceFrameMatrix
);
- }
-
- if (useClippingPlanes) {
- currentClippingPlanesState = clippingPlanes.clippingPlanesState;
}
var shouldRegenerateShaders = this._shouldRegenerateShaders;
diff --git a/Source/Scene/PointCloud.js b/Source/Scene/PointCloud.js
index 7a992a0b0658..bb291c67538f 100644
--- a/Source/Scene/PointCloud.js
+++ b/Source/Scene/PointCloud.js
@@ -613,7 +613,8 @@ var normalLocation = 2;
var batchIdLocation = 3;
var numberOfAttributes = 4;
-var scratchClippingPlaneMatrix = new Matrix4();
+var scratchClippingPlanesMatrix = new Matrix4();
+var scratchInverseTransposeClippingPlanesMatrix = new Matrix4();
function createResources(pointCloud, frameState) {
var context = frameState.context;
@@ -939,12 +940,17 @@ function createUniformMap(pointCloud, frameState) {
Matrix4.multiply(
context.uniformState.view3D,
clippingPlanesOriginMatrix,
- scratchClippingPlaneMatrix
+ scratchClippingPlanesMatrix
);
- return Matrix4.multiply(
- scratchClippingPlaneMatrix,
+ var transform = Matrix4.multiply(
+ scratchClippingPlanesMatrix,
clippingPlanes.modelMatrix,
- scratchClippingPlaneMatrix
+ scratchClippingPlanesMatrix
+ );
+
+ return Matrix4.inverseTranspose(
+ transform,
+ scratchInverseTransposeClippingPlanesMatrix
);
},
};
diff --git a/Source/Scene/processPbrMaterials.js b/Source/Scene/processPbrMaterials.js
index 8a72d233062e..edf6f39875c6 100644
--- a/Source/Scene/processPbrMaterials.js
+++ b/Source/Scene/processPbrMaterials.js
@@ -1036,17 +1036,10 @@ function generateTechnique(
// Environment maps were provided, use them for IBL
fragmentShader += "#elif defined(DIFFUSE_IBL) || defined(SPECULAR_IBL) \n";
-
- fragmentShader +=
- " mat3 fixedToENU = mat3(gltf_clippingPlanesMatrix[0][0], gltf_clippingPlanesMatrix[1][0], gltf_clippingPlanesMatrix[2][0], \n";
- fragmentShader +=
- " gltf_clippingPlanesMatrix[0][1], gltf_clippingPlanesMatrix[1][1], gltf_clippingPlanesMatrix[2][1], \n";
- fragmentShader +=
- " gltf_clippingPlanesMatrix[0][2], gltf_clippingPlanesMatrix[1][2], gltf_clippingPlanesMatrix[2][2]); \n";
fragmentShader +=
" const mat3 yUpToZUp = mat3(-1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0); \n";
fragmentShader +=
- " vec3 cubeDir = normalize(yUpToZUp * fixedToENU * normalize(reflect(-v, n))); \n";
+ " vec3 cubeDir = normalize(yUpToZUp * gltf_iblReferenceFrameMatrix * normalize(reflect(-v, n))); \n";
fragmentShader += "#ifdef DIFFUSE_IBL \n";
fragmentShader += "#ifdef CUSTOM_SPHERICAL_HARMONICS \n";
diff --git a/Source/Shaders/Builtin/Functions/transformPlane.glsl b/Source/Shaders/Builtin/Functions/transformPlane.glsl
index 6838805a827b..a4c545e8442f 100644
--- a/Source/Shaders/Builtin/Functions/transformPlane.glsl
+++ b/Source/Shaders/Builtin/Functions/transformPlane.glsl
@@ -1,8 +1,15 @@
-vec4 czm_transformPlane(vec4 clippingPlane, mat4 transform) {
- vec3 transformedDirection = normalize((transform * vec4(clippingPlane.xyz, 0.0)).xyz);
- vec3 transformedPosition = (transform * vec4(clippingPlane.xyz * -clippingPlane.w, 1.0)).xyz;
- vec4 transformedPlane;
- transformedPlane.xyz = transformedDirection;
- transformedPlane.w = -dot(transformedDirection, transformedPosition);
- return transformedPlane;
+/**
+ * Transforms a plane.
+ *
+ * @name czm_transformPlane
+ * @glslFunction
+ *
+ * @param {vec4} plane The plane in Hessian Normal Form.
+ * @param {mat4} transform The inverse-transpose of a transformation matrix.
+ */
+vec4 czm_transformPlane(vec4 plane, mat4 transform) {
+ vec4 transformedPlane = transform * plane;
+ // Convert the transformed plane to Hessian Normal Form
+ float normalMagnitude = length(transformedPlane.xyz);
+ return transformedPlane / normalMagnitude;
}
diff --git a/Specs/Core/Matrix3Spec.js b/Specs/Core/Matrix3Spec.js
index bfd75f43f763..3ed5464c5370 100644
--- a/Specs/Core/Matrix3Spec.js
+++ b/Specs/Core/Matrix3Spec.js
@@ -779,6 +779,17 @@ describe("Core/Matrix3", function () {
expect(result).toEqual(expected);
});
+ it("inverseTranspose works", function () {
+ var matrix = new Matrix3(1.0, 5.0, 2.0, 1.0, 1.0, 7.0, 0.0, -3.0, 4.0);
+ var expectedInverse = Matrix3.inverse(matrix, new Matrix3());
+ var expectedInverseTranspose = Matrix3.transpose(
+ expectedInverse,
+ new Matrix3()
+ );
+ var result = Matrix3.inverseTranspose(matrix, new Matrix3());
+ expect(result).toEqual(expectedInverseTranspose);
+ });
+
it("getRotation returns matrix without scale", function () {
var matrix = new Matrix3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);
var result = new Matrix3();
diff --git a/Specs/Core/Matrix4Spec.js b/Specs/Core/Matrix4Spec.js
index 6fad177a2d8d..bfe20cfd8757 100644
--- a/Specs/Core/Matrix4Spec.js
+++ b/Specs/Core/Matrix4Spec.js
@@ -2341,6 +2341,34 @@ describe("Core/Matrix4", function () {
expect(result).toEqual(expected);
});
+ it("inverseTranspose works", function () {
+ var matrix = new Matrix4(
+ 1.0,
+ 2.0,
+ 6.0,
+ 4.0,
+ 8.0,
+ 6.0,
+ -7.0,
+ 8.0,
+ 9.0,
+ -20.0,
+ -11.0,
+ 12.0,
+ 13.0,
+ -27.0,
+ 15.0,
+ 16.0
+ );
+ var expectedInverse = Matrix4.inverse(matrix, new Matrix4());
+ var expectedInverseTranspose = Matrix4.transpose(
+ expectedInverse,
+ new Matrix4()
+ );
+ var result = Matrix4.inverseTranspose(matrix, new Matrix4());
+ expect(result).toEqual(expectedInverseTranspose);
+ });
+
it("transpose works with a result parameter that is an input result parameter", function () {
var matrix = new Matrix4(
1.0,
diff --git a/Specs/Core/PlaneSpec.js b/Specs/Core/PlaneSpec.js
index e850f9c6933b..91ee904cafb0 100644
--- a/Specs/Core/PlaneSpec.js
+++ b/Specs/Core/PlaneSpec.js
@@ -241,6 +241,37 @@ describe("Core/Plane", function () {
expect(transformedPlane.normal.z).toEqual(-plane.normal.z);
});
+ it("transforms a plane according to a non-uniform scale transform", function () {
+ var normal = new Cartesian3(1.0, 0.0, 1.0);
+ normal = Cartesian3.normalize(normal, normal);
+ var plane = new Plane(normal, 0.0);
+ var planeOrigin = new Cartesian3(0.0, 0.0, 0.0);
+ var planePosition = new Cartesian3(1.0, 0.0, -1.0);
+ var planeDiff = Cartesian3.subtract(
+ planePosition,
+ planeOrigin,
+ new Cartesian3()
+ );
+ expect(Cartesian3.dot(planeDiff, plane.normal)).toEqualEpsilon(
+ 0.0,
+ CesiumMath.EPSILON16
+ );
+
+ var transform = Matrix4.fromScale(
+ new Cartesian3(4.0, 1.0, 10.0),
+ new Matrix4()
+ );
+ var transformPlane = Plane.transform(plane, transform);
+ var transformPlaneDiff = Matrix4.multiplyByPointAsVector(
+ transform,
+ planeDiff,
+ new Cartesian3()
+ );
+ expect(
+ Cartesian3.dot(transformPlaneDiff, transformPlane.normal)
+ ).toEqualEpsilon(0.0, CesiumMath.EPSILON16);
+ });
+
it("transform throws without a plane", function () {
var transform = Matrix4.IDENTITY;
expect(function () {
diff --git a/Specs/Renderer/BuiltinFunctionsSpec.js b/Specs/Renderer/BuiltinFunctionsSpec.js
index 1612009fdfd6..140b0f5c62f7 100644
--- a/Specs/Renderer/BuiltinFunctionsSpec.js
+++ b/Specs/Renderer/BuiltinFunctionsSpec.js
@@ -436,9 +436,9 @@ describe(
it("has czm_transformPlane", function () {
var fs =
"void main() { " +
- " mat4 uniformScale2 = mat4(2.0, 0.0, 0.0, 0.0," +
- " 0.0, 2.0, 0.0, 0.0," +
- " 0.0, 0.0, 2.0, 0.0," +
+ " mat4 uniformScale2 = mat4(0.5, 0.0, 0.0, 0.0," +
+ " 0.0, 0.5, 0.0, 0.0," +
+ " 0.0, 0.0, 0.5, 0.0," +
" 0.0, 0.0, 0.0, 1.0);" +
" gl_FragColor = vec4(all(equal(czm_transformPlane(vec4(1.0, 0.0, 0.0, 10.0), uniformScale2), vec4(1.0, 0.0, 0.0, 20.0))));" +
"}";
diff --git a/Specs/Scene/ModelSpec.js b/Specs/Scene/ModelSpec.js
index c38f7205e342..76cec88648c2 100644
--- a/Specs/Scene/ModelSpec.js
+++ b/Specs/Scene/ModelSpec.js
@@ -3723,8 +3723,6 @@ describe(
scene.renderForSpecs();
var callsBeforeClipping = gl.texImage2D.calls.count();
- expect(model._clippingPlaneModelViewMatrix).toEqual(Matrix4.IDENTITY);
-
model.clippingPlanes = new ClippingPlaneCollection({
planes: [new ClippingPlane(Cartesian3.UNIT_X, 0.0)],
});
diff --git a/Specs/Scene/PointCloud3DTileContentSpec.js b/Specs/Scene/PointCloud3DTileContentSpec.js
index 4f391defe678..001a64f26fe2 100644
--- a/Specs/Scene/PointCloud3DTileContentSpec.js
+++ b/Specs/Scene/PointCloud3DTileContentSpec.js
@@ -1155,7 +1155,7 @@ describe(
tileset.clippingPlanes = new ClippingPlaneCollection({
planes: [
new ClippingPlane(Cartesian3.UNIT_Z, -10.0),
- new ClippingPlane(Cartesian3.UNIT_X, 0.0),
+ new ClippingPlane(Cartesian3.UNIT_X, 1.0),
],
modelMatrix: Transforms.eastNorthUpToFixedFrame(
tileset.boundingSphere.center