Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve CoplanarPolygonGeometry normal calculation #7188

Merged
merged 5 commits into from
Oct 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Change Log
* Fixed entity visibility issue related to setting an entity show property and altering or adding entity geometry [#7156](https://github.com/AnalyticalGraphicsInc/cesium/pull/7156)
* Fixed accuracy of rotation matrix generated by `VelocityOrientationProperty` [#6641](https://github.com/AnalyticalGraphicsInc/cesium/pull/6641)
* Fixed clipping plane crash when adding a plane to an empty collection. [#7168](https://github.com/AnalyticalGraphicsInc/cesium/pull/7168)
* Fixed texture coordinate calculation for polygon entities with `perPositionHeight` [#7188](https://github.com/AnalyticalGraphicsInc/cesium/pull/7188)

### 1.50 - 2018-10-01

Expand Down
42 changes: 34 additions & 8 deletions Source/Core/CoplanarPolygonGeometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ define([
'./CoplanarPolygonGeometryLibrary',
'./defaultValue',
'./defined',
'./Ellipsoid',
'./Geometry',
'./GeometryAttribute',
'./GeometryAttributes',
Expand All @@ -34,6 +35,7 @@ define([
CoplanarPolygonGeometryLibrary,
defaultValue,
defined,
Ellipsoid,
Geometry,
GeometryAttribute,
GeometryAttributes,
Expand Down Expand Up @@ -62,6 +64,7 @@ define([
var quaternionScratch = new Quaternion();
var textureMatrixScratch = new Matrix3();
var tangentRotationScratch = new Matrix3();
var surfaceNormalScratch = new Cartesian3();

function createGeometryFromPolygon(polygon, vertexFormat, boundingRectangle, stRotation, projectPointTo2D, normal, tangent, bitangent) {
var positions = polygon.positions;
Expand Down Expand Up @@ -208,6 +211,7 @@ define([
* @param {PolygonHierarchy} options.polygonHierarchy A polygon hierarchy that can include holes.
* @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise.
* @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed.
* @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference.
*
* @example
* var polygon = new Cesium.CoplanarPolygonGeometry({
Expand All @@ -233,13 +237,14 @@ define([
this._vertexFormat = VertexFormat.clone(vertexFormat);
this._polygonHierarchy = polygonHierarchy;
this._stRotation = defaultValue(options.stRotation, 0.0);
this._ellipsoid = Ellipsoid.clone(defaultValue(options.ellipsoid, Ellipsoid.WGS84));
this._workerName = 'createCoplanarPolygonGeometry';

/**
* The number of elements used to pack the object into an array.
* @type {Number}
*/
this.packedLength = PolygonGeometryLibrary.computeHierarchyPackedLength(polygonHierarchy) + VertexFormat.packedLength + 2;
this.packedLength = PolygonGeometryLibrary.computeHierarchyPackedLength(polygonHierarchy) + VertexFormat.packedLength + Ellipsoid.packedLength + 2;
}

/**
Expand All @@ -249,6 +254,7 @@ define([
* @param {Cartesian3[]} options.positions An array of positions that defined the corner points of the polygon.
* @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed.
* @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise.
* @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference.
* @returns {CoplanarPolygonGeometry}
*
* @example
Expand Down Expand Up @@ -278,7 +284,8 @@ define([
positions : options.positions
},
vertexFormat : options.vertexFormat,
stRotation : options.stRotation
stRotation : options.stRotation,
ellipsoid : options.ellipsoid
};
return new CoplanarPolygonGeometry(newOptions);
};
Expand All @@ -302,6 +309,9 @@ define([

startingIndex = PolygonGeometryLibrary.packPolygonHierarchy(value._polygonHierarchy, array, startingIndex);

Ellipsoid.pack(value._ellipsoid, array, startingIndex);
startingIndex += Ellipsoid.packedLength;

VertexFormat.pack(value._vertexFormat, array, startingIndex);
startingIndex += VertexFormat.packedLength;

Expand All @@ -311,6 +321,7 @@ define([
return array;
};

var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE);
var scratchVertexFormat = new VertexFormat();
var scratchOptions = {
polygonHierarchy : {}
Expand All @@ -334,6 +345,9 @@ define([
startingIndex = polygonHierarchy.startingIndex;
delete polygonHierarchy.startingIndex;

var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid);
startingIndex += Ellipsoid.packedLength;

var vertexFormat = VertexFormat.unpack(array, startingIndex, scratchVertexFormat);
startingIndex += VertexFormat.packedLength;

Expand All @@ -345,6 +359,7 @@ define([
}

result._polygonHierarchy = polygonHierarchy;
result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid);
result._vertexFormat = VertexFormat.clone(vertexFormat, result._vertexFormat);
result._stRotation = stRotation;
result.packedLength = packedLength;
Expand All @@ -371,22 +386,33 @@ define([
var normal = scratchNormal;
var tangent = scratchTangent;
var bitangent = scratchBitangent;
var axis1 = axis1Scratch;
var axis2 = axis2Scratch;

var validGeometry = CoplanarPolygonGeometryLibrary.computeProjectTo2DArguments(outerPositions, centerScratch, axis1Scratch, axis2Scratch);
var validGeometry = CoplanarPolygonGeometryLibrary.computeProjectTo2DArguments(outerPositions, centerScratch, axis1, axis2);
if (!validGeometry) {
return undefined;
}
var projectPoints = CoplanarPolygonGeometryLibrary.createProjectPointsTo2DFunction(centerScratch, axis1Scratch, axis2Scratch);
var projectPoint = CoplanarPolygonGeometryLibrary.createProjectPointTo2DFunction(centerScratch, axis1Scratch, axis2Scratch);

normal = Cartesian3.cross(axis1Scratch, axis2Scratch, normal);
normal = Cartesian3.cross(axis1, axis2, normal);
normal = Cartesian3.normalize(normal, normal);

if (!Cartesian3.equalsEpsilon(centerScratch, Cartesian3.ZERO, CesiumMath.EPSILON6)) {
var surfaceNormal = polygonGeometry._ellipsoid.geodeticSurfaceNormal(centerScratch, surfaceNormalScratch);
if (Cartesian3.dot(normal, surfaceNormal) < 0) {
normal = Cartesian3.negate(normal, normal);
axis1 = Cartesian3.negate(axis1, axis1);
}
}

var projectPoints = CoplanarPolygonGeometryLibrary.createProjectPointsTo2DFunction(centerScratch, axis1, axis2);
var projectPoint = CoplanarPolygonGeometryLibrary.createProjectPointTo2DFunction(centerScratch, axis1, axis2);

if (vertexFormat.tangent) {
tangent = Cartesian3.clone(axis1Scratch, tangent);
tangent = Cartesian3.clone(axis1, tangent);
}
if (vertexFormat.bitangent) {
bitangent = Cartesian3.clone(axis2Scratch, bitangent);
bitangent = Cartesian3.clone(axis2, bitangent);
}

var results = PolygonGeometryLibrary.polygonsFromHierarchy(polygonHierarchy, projectPoints, false);
Expand Down
7 changes: 5 additions & 2 deletions Source/Workers/createCoplanarPolygonOutlineGeometry.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
define([
'../Core/defined',
'../Core/CoplanarPolygonOutlineGeometry'
'../Core/CoplanarPolygonOutlineGeometry',
'../Core/Ellipsoid'
], function(
defined,
CoplanarPolygonOutlineGeometry) {
CoplanarPolygonOutlineGeometry,
Ellipsoid) {
'use strict';

function createCoplanarPolygonOutlineGeometry(polygonGeometry, offset) {
if (defined(offset)) {
polygonGeometry = CoplanarPolygonOutlineGeometry.unpack(polygonGeometry, offset);
}
polygonGeometry._ellipsoid = Ellipsoid.clone(polygonGeometry._ellipsoid);
return CoplanarPolygonOutlineGeometry.createGeometry(polygonGeometry);
}

Expand Down
22 changes: 21 additions & 1 deletion Specs/Core/CoplanarPolygonGeometrySpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,25 @@ defineSuite([
expect(p.indices.length).toEqual(numTriangles * 3);
});

it('flips normal to roughly match surface normal', function() {
var p = CoplanarPolygonGeometry.createGeometry(CoplanarPolygonGeometry.fromPositions({
vertexFormat : VertexFormat.ALL,
positions : Cartesian3.fromDegreesArrayHeights([
90.0, -1.0, 0.0,
90.0, 1.0, 0.0,
92.0, 1.0, 0.0,
92.0, -1.0, 0.0
])
}));

var center = Cartesian3.fromDegrees(91.0, 0.0);
var expectedNormal = Ellipsoid.WGS84.geodeticSurfaceNormal(center);

var actual = Cartesian3.unpack(p.attributes.normal.values);

expect(expectedNormal).toEqualEpsilon(actual, CesiumMath.EPSILON6);
});

var positions = Cartesian3.fromDegreesArray([
-12.4, 3.5,
-12.0, 3.5,
Expand Down Expand Up @@ -148,7 +167,8 @@ defineSuite([
addPositions(packedInstance, holePositions0);
packedInstance.push(3.0, 0.0);
addPositions(packedInstance, holePositions1);
packedInstance.push(1, 0, 0, 0, 0, 0, 0, 41);
packedInstance.push(Ellipsoid.WGS84.radii.x, Ellipsoid.WGS84.radii.y, Ellipsoid.WGS84.radii.z);
packedInstance.push(1, 0, 0, 0, 0, 0, 0, 44);
createPackableSpecs(CoplanarPolygonGeometry, polygon, packedInstance);
});