Skip to content

Commit

Permalink
Merge pull request CesiumGS#1498 from AnalyticalGraphicsInc/ellipsoidST
Browse files Browse the repository at this point in the history
EllipsoidGeometry texture coordinates
  • Loading branch information
pjcozzi committed Feb 24, 2014
2 parents 353e825 + 2006642 commit da40347
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 64 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ Beta Releases
* `ConstantProperty` is now mutable; it's value can be updated via `ConstantProperty.setValue`.
* Added `AssociativeArray`, which is a helper class for maintaining a hash of objects that also needs to be iterated often.
* Added `TimeIntervalCollection.getChangedEvent` which returns an event that will be raised whenever intervals are updated.
* Fixed `EllipsoidGeometry` texture coordinates. [#1454](https://github.com/AnalyticalGraphicsInc/cesium/issues/1454)

### b25 - 2014-02-03

Expand Down
97 changes: 49 additions & 48 deletions Source/Core/EllipsoidGeometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
define([
'./defaultValue',
'./DeveloperError',
'./Cartesian2',
'./Cartesian3',
'./Math',
'./Ellipsoid',
Expand All @@ -16,6 +17,7 @@ define([
], function(
defaultValue,
DeveloperError,
Cartesian2,
Cartesian3,
CesiumMath,
Ellipsoid,
Expand All @@ -33,6 +35,7 @@ define([
var scratchNormal = new Cartesian3();
var scratchTangent = new Cartesian3();
var scratchBinormal = new Cartesian3();
var scratchNormalST = new Cartesian3();
var defaultRadii = new Cartesian3(1.0, 1.0, 1.0);

var cos = Math.cos;
Expand Down Expand Up @@ -95,14 +98,18 @@ define([
EllipsoidGeometry.createGeometry = function(ellipsoidGeometry) {
var radii = ellipsoidGeometry._radii;
var ellipsoid = Ellipsoid.fromCartesian3(radii);
var stackPartitions = ellipsoidGeometry._stackPartitions;
var slicePartitions = ellipsoidGeometry._slicePartitions;
var vertexFormat = ellipsoidGeometry._vertexFormat;

var vertexCount = 2 + (stackPartitions - 1) * slicePartitions;
// The extra slice and stack are for duplicating points at the x axis and poles.
// We need the texture coordinates to interpolate from (2 * pi - delta) to 2 * pi instead of
// (2 * pi - delta) to 0.
var slicePartitions = ellipsoidGeometry._slicePartitions + 1;
var stackPartitions = ellipsoidGeometry._stackPartitions + 1;

var vertexCount = stackPartitions * slicePartitions;
var positions = new Float64Array(vertexCount * 3);

var numIndices = 6 * slicePartitions * (stackPartitions - 1);
var numIndices = 6 * (slicePartitions - 1) * (stackPartitions - 1);
var indices = IndexDatatype.createTypedArray(vertexCount, numIndices);

var normals = (vertexFormat.normal) ? new Float32Array(vertexCount * 3) : undefined;
Expand All @@ -115,19 +122,22 @@ define([

var i;
var j;
var index = 0;

for (i = 0; i < slicePartitions; i++) {
var theta = CesiumMath.TWO_PI * i / slicePartitions;
var theta = CesiumMath.TWO_PI * i / (slicePartitions - 1);
cosTheta[i] = cos(theta);
sinTheta[i] = sin(theta);
}

var index = 0;
positions[index++] = 0; // first point
positions[index++] = 0;
positions[index++] = radii.z;
// duplicate first point for correct
// texture coordinates at the north pole.
positions[index++] = 0.0;
positions[index++] = 0.0;
positions[index++] = radii.z;
}

for (i = 1; i < stackPartitions; i++) {
var phi = Math.PI * i / stackPartitions;
for (i = 1; i < stackPartitions - 1; i++) {
var phi = Math.PI * i / (stackPartitions - 1);
var sinPhi = sin(phi);

var xSinPhi = radii.x * sinPhi;
Expand All @@ -140,9 +150,14 @@ define([
positions[index++] = zCosPhi;
}
}
positions[index++] = 0; // last point
positions[index++] = 0;
positions[index++] = -radii.z;

for (i = 0; i < slicePartitions; i++) {
// duplicate first point for correct
// texture coordinates at the north pole.
positions[index++] = 0.0;
positions[index++] = 0.0;
positions[index++] = -radii.z;
}

var attributes = new GeometryAttributes();

Expand All @@ -165,7 +180,21 @@ define([
var normal = ellipsoid.geodeticSurfaceNormal(position, scratchNormal);

if (vertexFormat.st) {
st[stIndex++] = (Math.atan2(normal.y, normal.x) / CesiumMath.TWO_PI) + 0.5;
var normalST = Cartesian2.negate(normal, scratchNormalST);

// if the point is at or close to the pole, find a point along the same longitude
// close to the xy-plane for the s coordinate.
if (Cartesian2.magnitude(normalST) < CesiumMath.EPSILON6) {
index = (i + slicePartitions * Math.floor(stackPartitions * 0.5)) * 3;
if (index > positions.length) {
index = (i - slicePartitions * Math.floor(stackPartitions * 0.5)) * 3;
}
Cartesian3.fromArray(positions, index, normalST);
ellipsoid.geodeticSurfaceNormal(normalST, normalST);
Cartesian2.negate(normalST, normalST);
}

st[stIndex++] = (Math.atan2(normalST.y, normalST.x) / CesiumMath.TWO_PI) + 0.5;
st[stIndex++] = (Math.asin(normal.z) / Math.PI) + 0.5;
}

Expand All @@ -177,7 +206,7 @@ define([

if (vertexFormat.tangent || vertexFormat.binormal) {
var tangent = scratchTangent;
if (i === 0 || i === vertexCount - 1) {
if (i < slicePartitions || i > vertexCount - slicePartitions - 1) {
Cartesian3.cross(Cartesian3.UNIT_X, normal, tangent);
Cartesian3.normalize(tangent, tangent);
} else {
Expand Down Expand Up @@ -236,19 +265,9 @@ define([
}

index = 0;
for (i = 1; i < slicePartitions; i++) { //top row
indices[index++] = 0;
indices[index++] = i;
indices[index++] = i + 1;
}

indices[index++] = 0;
indices[index++] = slicePartitions;
indices[index++] = 1;

for (i = 0; i < stackPartitions - 2; i++) {
var topOffset = (i * slicePartitions) + 1;
var bottomOffset = ((i + 1) * slicePartitions) + 1;
for (i = 0; i < stackPartitions; i++) {
var topOffset = i * slicePartitions;
var bottomOffset = (i + 1) * slicePartitions;

for (j = 0; j < slicePartitions - 1; j++) {
indices[index++] = bottomOffset + j;
Expand All @@ -259,26 +278,8 @@ define([
indices[index++] = topOffset + j + 1;
indices[index++] = topOffset + j;
}

indices[index++] = bottomOffset + slicePartitions - 1;
indices[index++] = bottomOffset;
indices[index++] = topOffset;
indices[index++] = bottomOffset + slicePartitions - 1;
indices[index++] = topOffset;
indices[index++] = topOffset + slicePartitions - 1;
}

var lastPos = vertexCount - 1;
for (i = lastPos - 1; i > lastPos - slicePartitions; i--) {
indices[index++] = lastPos;
indices[index++] = i;
indices[index++] = i - 1;
}

indices[index++] = lastPos;
indices[index++] = lastPos - slicePartitions;
indices[index++] = lastPos - 1;

return new Geometry({
attributes : attributes,
indices : indices,
Expand Down
16 changes: 8 additions & 8 deletions Specs/Core/EllipsoidGeometrySpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ defineSuite([
stackPartitions: 3
}));

expect(m.attributes.position.values.length).toEqual(3 * 8);
expect(m.indices.length).toEqual(12 * 3);
expect(m.attributes.position.values.length).toEqual(3 * 16);
expect(m.indices.length).toEqual(6 * 9);
expect(m.boundingSphere.radius).toEqual(1);
});

Expand All @@ -47,12 +47,12 @@ defineSuite([
stackPartitions: 3
}));

expect(m.attributes.position.values.length).toEqual(3 * 8);
expect(m.attributes.st.values.length).toEqual(2 * 8);
expect(m.attributes.normal.values.length).toEqual(3 * 8);
expect(m.attributes.tangent.values.length).toEqual(3 * 8);
expect(m.attributes.binormal.values.length).toEqual(3 * 8);
expect(m.indices.length).toEqual(3 * 12);
expect(m.attributes.position.values.length).toEqual(3 * 16);
expect(m.attributes.st.values.length).toEqual(2 * 16);
expect(m.attributes.normal.values.length).toEqual(3 * 16);
expect(m.attributes.tangent.values.length).toEqual(3 * 16);
expect(m.attributes.binormal.values.length).toEqual(3 * 16);
expect(m.indices.length).toEqual(6 * 9);
});

it('computes attributes for a unit sphere', function() {
Expand Down
16 changes: 8 additions & 8 deletions Specs/Core/SphereGeometrySpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ defineSuite([
slicePartitions: 3
}));

expect(m.attributes.position.values.length).toEqual(3 * 8);
expect(m.indices.length).toEqual(12 * 3);
expect(m.attributes.position.values.length).toEqual(3 * 16);
expect(m.indices.length).toEqual(6 * 9);
expect(m.boundingSphere.radius).toEqual(1);
});

Expand All @@ -49,12 +49,12 @@ defineSuite([
slicePartitions: 3
}));

expect(m.attributes.position.values.length).toEqual(3 * 8);
expect(m.attributes.st.values.length).toEqual(2 * 8);
expect(m.attributes.normal.values.length).toEqual(3 * 8);
expect(m.attributes.tangent.values.length).toEqual(3 * 8);
expect(m.attributes.binormal.values.length).toEqual(3 * 8);
expect(m.indices.length).toEqual(3 * 12);
expect(m.attributes.position.values.length).toEqual(3 * 16);
expect(m.attributes.st.values.length).toEqual(2 * 16);
expect(m.attributes.normal.values.length).toEqual(3 * 16);
expect(m.attributes.tangent.values.length).toEqual(3 * 16);
expect(m.attributes.binormal.values.length).toEqual(3 * 16);
expect(m.indices.length).toEqual(6 * 9);
});

it('computes attributes for a unit sphere', function() {
Expand Down

0 comments on commit da40347

Please sign in to comment.