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

Fix models in 2D near the IDL. #3936

Merged
merged 10 commits into from
May 25, 2016
31 changes: 9 additions & 22 deletions Source/Core/Transforms.js
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,8 @@ define([
var scratchCartesian4NewXAxis = new Cartesian4();
var scratchCartesian4NewYAxis = new Cartesian4();
var scratchCartesian4NewZAxis = new Cartesian4();
var scratchFromENU = new Matrix4();
var scratchToENU = new Matrix4();

/**
* @private
Expand All @@ -852,6 +854,9 @@ define([
var origin = Matrix4.getColumn(matrix, 3, scratchCartesian4Origin);
var cartographic = ellipsoid.cartesianToCartographic(origin, scratchCartographic);

var fromENU = Transforms.eastNorthUpToFixedFrame(origin, ellipsoid, scratchFromENU);
var toENU = Matrix4.inverseTransformation(fromENU, scratchToENU);

var projectedPosition = projection.project(cartographic, scratchCartesian3Projection);
var newOrigin = scratchCartesian4NewOrigin;
newOrigin.x = projectedPosition.z;
Expand All @@ -861,31 +866,13 @@ define([

var xAxis = Matrix4.getColumn(matrix, 0, scratchCartesian3);
var xScale = Cartesian3.magnitude(xAxis);
Cartesian4.add(xAxis, origin, xAxis);
ellipsoid.cartesianToCartographic(xAxis, cartographic);

projection.project(cartographic, projectedPosition);
var newXAxis = scratchCartesian4NewXAxis;
newXAxis.x = projectedPosition.z;
newXAxis.y = projectedPosition.x;
newXAxis.z = projectedPosition.y;
newXAxis.w = 0.0;

Cartesian3.subtract(newXAxis, newOrigin, newXAxis);
var newXAxis = Matrix4.multiplyByVector(toENU, xAxis, scratchCartesian4NewXAxis);
Cartesian4.fromElements(newXAxis.z, newXAxis.x, newXAxis.y, 0.0, newXAxis);

var yAxis = Matrix4.getColumn(matrix, 1, scratchCartesian3);
var yScale = Cartesian3.magnitude(yAxis);
Cartesian4.add(yAxis, origin, yAxis);
ellipsoid.cartesianToCartographic(yAxis, cartographic);

projection.project(cartographic, projectedPosition);
var newYAxis = scratchCartesian4NewYAxis;
newYAxis.x = projectedPosition.z;
newYAxis.y = projectedPosition.x;
newYAxis.z = projectedPosition.y;
newYAxis.w = 0.0;

Cartesian3.subtract(newYAxis, newOrigin, newYAxis);
var newYAxis = Matrix4.multiplyByVector(toENU, yAxis, scratchCartesian4NewYAxis);
Cartesian4.fromElements(newYAxis.z, newYAxis.x, newYAxis.y, 0.0, newYAxis);

var zAxis = Matrix4.getColumn(matrix, 2, scratchCartesian3);
var zScale = Cartesian3.magnitude(zAxis);
Expand Down
67 changes: 59 additions & 8 deletions Source/Scene/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -2520,7 +2520,7 @@ define([
};
}

function createCommand(model, gltfNode, runtimeNode, context) {
function createCommand(model, gltfNode, runtimeNode, context, scene3DOnly) {
var nodeCommands = model._nodeCommands;
var pickIds = model._pickIds;
var allowPicking = model.allowPicking;
Expand Down Expand Up @@ -2660,19 +2660,35 @@ define([
});
}

var command2D;
var pickCommand2D;
if (!scene3DOnly) {
command2D = DrawCommand.shallowClone(command);
command2D.boundingVolume = new BoundingSphere();
command2D.modelMatrix = new Matrix4();

if (allowPicking) {
pickCommand2D = DrawCommand.shallowClone(pickCommand);
pickCommand2D.boundingVolume = new BoundingSphere();
pickCommand2D.modelMatrix = new Matrix4();
}
}

var nodeCommand = {
show : true,
boundingSphere : boundingSphere,
command : command,
pickCommand : pickCommand
pickCommand : pickCommand,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does picking work for models crossing the IDL?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So picking works across the IDL even though there is only one pick command?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never mind, I see.

command2D : command2D,
pickCommand2D : pickCommand2D
};
runtimeNode.commands.push(nodeCommand);
nodeCommands.push(nodeCommand);
}
}
}

function createRuntimeNodes(model, context) {
function createRuntimeNodes(model, context, scene3DOnly) {
var loadResources = model._loadResources;

if (!loadResources.finishedEverythingButTextureCreation()) {
Expand Down Expand Up @@ -2730,7 +2746,7 @@ define([
}

if (defined(gltfNode.meshes)) {
createCommand(model, gltfNode, runtimeNode, context);
createCommand(model, gltfNode, runtimeNode, context, scene3DOnly);
}

var children = gltfNode.children;
Expand All @@ -2751,6 +2767,7 @@ define([

function createResources(model, frameState) {
var context = frameState.context;
var scene3DOnly = frameState.scene3DOnly;

if (model._loadRendererResourcesFromCache) {
var resources = model._rendererResources;
Expand Down Expand Up @@ -2788,8 +2805,8 @@ define([
// Could use copy-on-write if it is worth it. Probably overkill.
}

createUniformMaps(model, context); // using glTF materials/techniques
createRuntimeNodes(model, context); // using glTF scene
createUniformMaps(model, context); // using glTF materials/techniques
createRuntimeNodes(model, context, scene3DOnly); // using glTF scene
}

///////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -2860,6 +2877,23 @@ define([
Matrix4.clone(command.modelMatrix, pickCommand.modelMatrix);
BoundingSphere.clone(command.boundingVolume, pickCommand.boundingVolume);
}

// If the model crosses the IDL in 2D, it will be drawn in one viewport, but part of it
// will be clipped by the viewport. We create a second command that translates the model
// model matrix to the opposite side of the map so the part that was clipped in one viewport
// is drawn in the other.
command = primitiveCommand.command2D;
if (defined(command) && model._mode === SceneMode.SCENE2D) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment about why we are doing this.

Matrix4.clone(nodeMatrix, command.modelMatrix);
command.modelMatrix[13] -= CesiumMath.sign(command.modelMatrix[13]) * 2.0 * CesiumMath.PI * projection.ellipsoid.maximumRadius;
BoundingSphere.transform(primitiveCommand.boundingSphere, command.modelMatrix, command.boundingVolume);

if (allowPicking) {
var pickCommand2D = primitiveCommand.pickCommand2D;
Matrix4.clone(command.modelMatrix, pickCommand2D.modelMatrix);
BoundingSphere.clone(command.boundingVolume, pickCommand2D.boundingVolume);
}
}
}
}
}
Expand Down Expand Up @@ -3394,11 +3428,21 @@ define([
var i;
var nc;

var idl2D = frameState.mapProjection.ellipsoid.maximumRadius * CesiumMath.PI;
var boundingVolume;

if (passes.render) {
for (i = 0; i < length; ++i) {
nc = nodeCommands[i];
if (nc.show) {
commandList.push(nc.command);
var command = nc.command;
commandList.push(command);

boundingVolume = command.boundingVolume;
if (frameState.mode === SceneMode.SCENE2D &&
(boundingVolume.center.y + boundingVolume.radius > idl2D || boundingVolume.center.y - boundingVolume.radius < idl2D)) {
commandList.push(nc.command2D);
}
}
}
}
Expand All @@ -3407,7 +3451,14 @@ define([
for (i = 0; i < length; ++i) {
nc = nodeCommands[i];
if (nc.show) {
commandList.push(nc.pickCommand);
var pickCommand = nc.pickCommand;
commandList.push(pickCommand);

boundingVolume = pickCommand.boundingVolume;
if (frameState.mode === SceneMode.SCENE2D &&
(boundingVolume.center.y + boundingVolume.radius > idl2D || boundingVolume.center.y - boundingVolume.radius < idl2D)) {
commandList.push(nc.pickCommand2D);
}
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions Specs/Scene/ModelSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,14 @@ defineSuite([
verifyRender(texturedBoxModel);
});

it('renders in 2D over the IDL', function() {
return when(loadModel(texturedBoxUrl)).then(function(model) {
model.modelMatrix = Transforms.eastNorthUpToFixedFrame(Cartesian3.fromDegrees(180.0, 0.0, 100.0));
scene.morphTo2D(0.0);
verifyRender(model);
});
});

it('resolves readyPromise', function() {
return texturedBoxModel.readyPromise.then(function(model) {
verifyRender(model);
Expand Down