Skip to content

Commit

Permalink
Merge pull request #7411 from geoscan/geometric-error-scale
Browse files Browse the repository at this point in the history
scale geometric error with tileset
  • Loading branch information
Hannah authored Sep 19, 2019
2 parents b97488a + 36e569a commit 2ea3899
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Source/Core/GeometryPipeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,7 @@ define([

Matrix4.inverse(modelMatrix, inverseTranspose);
Matrix4.transpose(inverseTranspose, inverseTranspose);
Matrix4.getRotation(inverseTranspose, normalMatrix);
Matrix4.getMatrix3(inverseTranspose, normalMatrix);

transformVector(normalMatrix, attributes.normal);
transformVector(normalMatrix, attributes.tangent);
Expand Down
21 changes: 21 additions & 0 deletions Source/Core/Matrix3.js
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,27 @@ define([
return result;
};

var UNIT = new Cartesian3(1, 1, 1);

/**
* Extracts the rotation assuming the matrix is an affine transformation.
*
* @param {Matrix3} matrix The matrix.
* @param {Matrix3} result The object onto which to store the result.
* @returns {Cartesian3} The modified result parameter
*/
Matrix3.getRotation = function(matrix, result) {
//>>includeStart('debug', pragmas.debug);
Check.typeOf.object('matrix', matrix);
Check.typeOf.object('result', result);
//>>includeEnd('debug');

var inverseScale = Cartesian3.divideComponents(UNIT, Matrix3.getScale(matrix, scratchScale), scratchScale);
result = Matrix3.multiplyByScale(matrix, inverseScale, result);

return result;
};

function computeFrobeniusNorm(matrix) {
var norm = 0.0;
for (var i = 0; i < 9; ++i) {
Expand Down
15 changes: 11 additions & 4 deletions Source/Core/Matrix4.js
Original file line number Diff line number Diff line change
Expand Up @@ -2149,6 +2149,13 @@ define([
return result;
};

/**
* @deprecated moved to Matrix4.getMatrix3
*/
Matrix4.getRotation = function(matrix, result) {
return Matrix4.getMatrix3(matrix, result);
};

/**
* Gets the upper left 3x3 rotation matrix of the provided matrix, assuming the matrix is a affine transformation matrix.
*
Expand All @@ -2165,13 +2172,13 @@ define([
* // [13.0, 17.0, 21.0, 25.0]
*
* var b = new Cesium.Matrix3();
* Cesium.Matrix4.getRotation(m,b);
* Cesium.Matrix4.getMatrix3(m,b);
*
* // b = [10.0, 14.0, 18.0]
* // [11.0, 15.0, 19.0]
* // [12.0, 16.0, 20.0]
*/
Matrix4.getRotation = function(matrix, result) {
Matrix4.getMatrix3 = function(matrix, result) {
//>>includeStart('debug', pragmas.debug);
Check.typeOf.object('matrix', matrix);
Check.typeOf.object('result', result);
Expand Down Expand Up @@ -2286,7 +2293,7 @@ define([
if (Math.abs(det) < CesiumMath.EPSILON21) {
// Special case for a zero scale matrix that can occur, for example,
// when a model's node has a [0, 0, 0] scale.
if (Matrix3.equalsEpsilon(Matrix4.getRotation(matrix, scratchInverseRotation), scratchMatrix3Zero, CesiumMath.EPSILON7) &&
if (Matrix3.equalsEpsilon(Matrix4.getMatrix3(matrix, scratchInverseRotation), scratchMatrix3Zero, CesiumMath.EPSILON7) &&
Cartesian4.equals(Matrix4.getRow(matrix, 3, scratchBottomRow), scratchExpectedBottomRow)) {

result[0] = 0.0;
Expand Down Expand Up @@ -2353,7 +2360,7 @@ define([
//>>includeEnd('debug');

//This function is an optimized version of the below 4 lines.
//var rT = Matrix3.transpose(Matrix4.getRotation(matrix));
//var rT = Matrix3.transpose(Matrix4.getMatrix3(matrix));
//var rTN = Matrix3.negate(rT);
//var rTT = Matrix3.multiplyByVector(rTN, Matrix4.getTranslation(matrix));
//return Matrix4.fromRotationTranslation(rT, rTT, result);
Expand Down
6 changes: 3 additions & 3 deletions Source/Core/Transforms.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ define([
//>>includeEnd('debug');

var transform = Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, scratchENUMatrix4);
var rotation = Matrix4.getRotation(transform, scratchHPRMatrix3);
var rotation = Matrix4.getMatrix3(transform, scratchHPRMatrix3);
return Quaternion.fromRotationMatrix(rotation, result);
};

Expand Down Expand Up @@ -421,7 +421,7 @@ define([
transformCopy = Matrix4.setTranslation(transformCopy, Cartesian3.ZERO, transformCopy);

toFixedFrame = Matrix4.multiply(toFixedFrame, transformCopy, toFixedFrame);
var quaternionRotation = Quaternion.fromRotationMatrix(Matrix4.getRotation(toFixedFrame, hprRotationScratch), hprQuaternionScratch);
var quaternionRotation = Quaternion.fromRotationMatrix(Matrix4.getMatrix3(toFixedFrame, hprRotationScratch), hprQuaternionScratch);
quaternionRotation = Quaternion.normalize(quaternionRotation, quaternionRotation);

return HeadingPitchRoll.fromQuaternion(quaternionRotation, result);
Expand Down Expand Up @@ -878,7 +878,7 @@ define([
// Assuming the instance are positioned in WGS84, invert the WGS84 transform to get the local transform and then convert to 2D
var fromENU = Transforms.eastNorthUpToFixedFrame(rtcCenter, ellipsoid, scratchFromENU);
var toENU = Matrix4.inverseTransformation(fromENU, scratchToENU);
var rotation = Matrix4.getRotation(matrix, scratchRotation);
var rotation = Matrix4.getMatrix3(matrix, scratchRotation);
var local = Matrix4.multiplyByMatrix3(toENU, rotation, result);
Matrix4.multiply(swizzleMatrix, local, result); // Swap x, y, z for 2D
Matrix4.setTranslation(result, projectedPosition, result); // Use the projected center
Expand Down
24 changes: 13 additions & 11 deletions Source/Renderer/UniformState.js
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ define([
if (this._inverseTransposeModelDirty) {
this._inverseTransposeModelDirty = false;

Matrix4.getRotation(this.inverseModel, m);
Matrix4.getMatrix3(this.inverseModel, m);
Matrix3.transpose(m, m);
}

Expand Down Expand Up @@ -979,7 +979,7 @@ define([

function setView(uniformState, matrix) {
Matrix4.clone(matrix, uniformState._view);
Matrix4.getRotation(matrix, uniformState._viewRotation);
Matrix4.getMatrix3(matrix, uniformState._viewRotation);

uniformState._view3DDirty = true;
uniformState._inverseView3DDirty = true;
Expand All @@ -1001,7 +1001,7 @@ define([

function setInverseView(uniformState, matrix) {
Matrix4.clone(matrix, uniformState._inverseView);
Matrix4.getRotation(matrix, uniformState._inverseViewRotation);
Matrix4.getMatrix3(matrix, uniformState._inverseViewRotation);
}

function setProjection(uniformState, matrix) {
Expand Down Expand Up @@ -1314,7 +1314,8 @@ define([
uniformState._normalDirty = false;

var m = uniformState._normal;
Matrix4.getRotation(uniformState.inverseModelView, m);
Matrix4.getMatrix3(uniformState.inverseModelView, m);
Matrix3.getRotation(m, m);
Matrix3.transpose(m, m);
}
}
Expand All @@ -1324,24 +1325,25 @@ define([
uniformState._normal3DDirty = false;

var m = uniformState._normal3D;
Matrix4.getRotation(uniformState.inverseModelView3D, m);
Matrix4.getMatrix3(uniformState.inverseModelView3D, m);
Matrix3.getRotation(m, m);
Matrix3.transpose(m, m);
}
}

function cleanInverseNormal(uniformState) {
if (uniformState._inverseNormalDirty) {
uniformState._inverseNormalDirty = false;

Matrix4.getRotation(uniformState.inverseModelView, uniformState._inverseNormal);
Matrix4.getMatrix3(uniformState.inverseModelView, uniformState._inverseNormal);
Matrix3.getRotation(uniformState._inverseNormal, uniformState._inverseNormal);
}
}

function cleanInverseNormal3D(uniformState) {
if (uniformState._inverseNormal3DDirty) {
uniformState._inverseNormal3DDirty = false;

Matrix4.getRotation(uniformState.inverseModelView3D, uniformState._inverseNormal3D);
Matrix4.getMatrix3(uniformState.inverseModelView3D, uniformState._inverseNormal3D);
Matrix3.getRotation(uniformState._inverseNormal3D, uniformState._inverseNormal3D);
}
}

Expand Down Expand Up @@ -1444,15 +1446,15 @@ define([
} else {
view2Dto3D(that._cameraPosition, that._cameraDirection, that._cameraRight, that._cameraUp, that._frustum2DWidth, that._mode, that._mapProjection, that._view3D);
}
Matrix4.getRotation(that._view3D, that._viewRotation3D);
Matrix4.getMatrix3(that._view3D, that._viewRotation3D);
that._view3DDirty = false;
}
}

function updateInverseView3D(that){
if (that._inverseView3DDirty) {
Matrix4.inverseTransformation(that.view3D, that._inverseView3D);
Matrix4.getRotation(that._inverseView3D, that._inverseViewRotation3D);
Matrix4.getMatrix3(that._inverseView3D, that._inverseViewRotation3D);
that._inverseView3DDirty = false;
}
}
Expand Down
19 changes: 15 additions & 4 deletions Source/Scene/Cesium3DTile.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,15 @@ define([
* @readonly
*/
this.geometricError = header.geometricError;
this._geometricError = header.geometricError;

if (!defined(this.geometricError)) {
this.geometricError = defined(parent) ? parent.geometricError : tileset._geometricError;
if (!defined(this._geometricError)) {
this._geometricError = defined(parent) ? parent.geometricError : tileset._geometricError;
Cesium3DTile._deprecationWarning('geometricErrorUndefined', 'Required property geometricError is undefined for this tile. Using parent\'s geometric error instead.');
}

this.updateGeometricErrorScale();

var refine;
if (defined(header.refine)) {
if (header.refine === 'replace' || header.refine === 'add') {
Expand Down Expand Up @@ -1107,7 +1110,7 @@ define([

// Find the transformed center and halfAxes
center = Matrix4.multiplyByPoint(transform, center, center);
var rotationScale = Matrix4.getRotation(transform, scratchMatrix);
var rotationScale = Matrix4.getMatrix3(transform, scratchMatrix);
halfAxes = Matrix3.multiply(rotationScale, halfAxes, halfAxes);

if (defined(result)) {
Expand All @@ -1131,7 +1134,7 @@ define([
// This is why the transform is calculated as the difference between the initial transform and the current transform.
transform = Matrix4.multiplyTransformation(transform, Matrix4.inverseTransformation(initialTransform, scratchTransform), scratchTransform);
center = Matrix4.multiplyByPoint(transform, center, center);
var rotationScale = Matrix4.getRotation(transform, scratchMatrix);
var rotationScale = Matrix4.getMatrix3(transform, scratchMatrix);
halfAxes = Matrix3.multiply(rotationScale, halfAxes, halfAxes);

if (defined(result) && (result instanceof TileOrientedBoundingBox)) {
Expand Down Expand Up @@ -1231,12 +1234,20 @@ define([
this._viewerRequestVolume = this.createBoundingVolume(header.viewerRequestVolume, this.computedTransform, this._viewerRequestVolume);
}

this.updateGeometricErrorScale();

// Destroy the debug bounding volumes. They will be generated fresh.
this._debugBoundingVolume = this._debugBoundingVolume && this._debugBoundingVolume.destroy();
this._debugContentBoundingVolume = this._debugContentBoundingVolume && this._debugContentBoundingVolume.destroy();
this._debugViewerRequestVolume = this._debugViewerRequestVolume && this._debugViewerRequestVolume.destroy();
};

Cesium3DTile.prototype.updateGeometricErrorScale = function() {
var scale = Matrix4.getScale(this.computedTransform, scratchScale);
var uniformScale = Cartesian3.maximumComponent(scale);
this.geometricError = this._geometricError * uniformScale;
};

function applyDebugSettings(tile, tileset, frameState) {
if (!frameState.passes.render) {
return;
Expand Down
2 changes: 1 addition & 1 deletion Source/Scene/Instanced3DModel3DTileContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ define([
hasCustomOrientation = true;
} else if (eastNorthUp) {
Transforms.eastNorthUpToFixedFrame(instancePosition, Ellipsoid.WGS84, instanceTransform);
Matrix4.getRotation(instanceTransform, instanceRotation);
Matrix4.getMatrix3(instanceTransform, instanceRotation);
} else {
Matrix3.clone(Matrix3.IDENTITY, instanceRotation);
}
Expand Down
4 changes: 2 additions & 2 deletions Source/Scene/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -3159,7 +3159,7 @@ define([
var mInverseTranspose = new Matrix3();
return function() {
Matrix4.inverse(runtimeNode.computedMatrix, mInverse);
Matrix4.getRotation(mInverse, mInverseTranspose);
Matrix4.getMatrix3(mInverse, mInverseTranspose);
return Matrix3.transpose(mInverseTranspose, mInverseTranspose);
};
},
Expand All @@ -3170,7 +3170,7 @@ define([
return function() {
Matrix4.multiplyTransformation(uniformState.view, runtimeNode.computedMatrix, mv);
Matrix4.inverse(mv, mvInverse);
Matrix4.getRotation(mvInverse, mvInverseTranspose);
Matrix4.getMatrix3(mvInverse, mvInverseTranspose);
return Matrix3.transpose(mvInverseTranspose, mvInverseTranspose);
};
},
Expand Down
35 changes: 35 additions & 0 deletions Specs/Core/Matrix3Spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,41 @@ describe('Core/Matrix3', function() {
expect(result).toEqual(expected);
});

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();
var expected = Matrix3.fromArray([
0.12309149097933272, 0.4923659639173309, 0.8616404368553291,
0.20739033894608505, 0.5184758473652127, 0.8295613557843402,
0.26726124191242440, 0.5345224838248488, 0.8017837257372732
]);
var scale = new Cartesian3();
var expectedScale = new Cartesian3(1.0, 1.0, 1.0);
result = Matrix3.getRotation(matrix, result);
console.log(result);
var resultScale = Matrix3.getScale(result, scale);
expect(resultScale).toEqualEpsilon(expectedScale, CesiumMath.EPSILON14);
expect(result).toEqualEpsilon(expected, CesiumMath.EPSILON14);
});

it('getRotation does not modify rotation matrix', function() {
var tmp = new Matrix3();
var result = new Matrix3();
var rotation = Matrix3.clone(Matrix3.IDENTITY, new Matrix3());
Matrix3.multiply(rotation, Matrix3.fromRotationX(1.0, tmp), rotation);
Matrix3.multiply(rotation, Matrix3.fromRotationY(2.0, tmp), rotation);
Matrix3.multiply(rotation, Matrix3.fromRotationZ(3.0, tmp), rotation);
result = Matrix3.getRotation(rotation, result);
expect(rotation).toEqualEpsilon(result, CesiumMath.EPSILON14);
expect(rotation).not.toBe(result);
});

it('getRotation throws without a matrix', function() {
expect(function() {
return Matrix3.getRotation();
}).toThrowDeveloperError();
});

it('transpose works with a result parameter that is an input result parameter', function() {
var matrix = new Matrix3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);
var expected = new Matrix3(1.0, 4.0, 7.0, 2.0, 5.0, 8.0, 3.0, 6.0, 9.0);
Expand Down

0 comments on commit 2ea3899

Please sign in to comment.