Skip to content

Commit

Permalink
Enable composeModelMatrix for meshlayers (#3977)
Browse files Browse the repository at this point in the history
  • Loading branch information
Xintong Xia committed Dec 10, 2019
1 parent 9ee1804 commit d4a6199
Show file tree
Hide file tree
Showing 25 changed files with 245 additions and 63 deletions.
4 changes: 2 additions & 2 deletions docs/layers/scenegraph-layer.md
Expand Up @@ -151,7 +151,7 @@ The color of each object, in `r, g, b, [a]`. Each component is in the 0-255 rang

- Default: `[0, 0, 0]`

Object orientation defined as a vec3 of Euler angles, `[pitch, yaw, roll]` in degrees.
Object orientation defined as a vec3 of Euler angles, `[pitch, yaw, roll]` in degrees. This will be composed with layer's [`modelMatrix`](https://github.com/uber/deck.gl/blob/master/docs/api-reference/layer.md#modelmatrix-number16-optional).

* If an array is provided, it is used as the orientation for all objects.
* If a function is provided, it is called on each object to retrieve its orientation.
Expand Down Expand Up @@ -179,7 +179,7 @@ Translation of the mesh along each axis. Offset from the center position given b
- Default: `null`

Explicitly define a 4x4 column-major model matrix for the mesh. If provided, will override
`getOrientation`, `getScale`, `getTranslation`.
`getOrientation`, `getScale`, `getTranslation`. This will be composed with layer's [`modelMatrix`](https://github.com/uber/deck.gl/blob/master/docs/api-reference/layer.md#modelmatrix-number16-optional).

* If an array is provided, it is used as the transform matrix for all objects.
* If a function is provided, it is called on each object to retrieve its transform matrix.
Expand Down
7 changes: 4 additions & 3 deletions docs/layers/simple-mesh-layer.md
Expand Up @@ -121,6 +121,7 @@ Whether to render the mesh in wireframe mode.
This is an object that contains material props for [lighting effect](/docs/effects/lighting-effect.md) applied on extruded polygons.
Check [the lighting guide](/docs/developer-guide/using-lighting.md#constructing-a-material-instance) for configurable settings.


### Data Accessors


Expand All @@ -144,9 +145,9 @@ The color of each object, in `r, g, b, [a]`. Each component is in the 0-255 rang

- Default: `[0, 0, 0]`

Object orientation defined as a vec3 of Euler angles, `[pitch, yaw, roll]` in degrees.
Object orientation defined as a vec3 of Euler angles, `[pitch, yaw, roll]` in degrees. This will be composed with layer's [modelMatrix](https://github.com/uber/deck.gl/blob/master/docs/api-reference/layer.md#modelmatrix-number16-optional).

* If an array is provided, it is used as the orientation for all objects.
* If an array is provided, it is used as the orientation for all objects.
* If a function is provided, it is called on each object to retrieve its orientation.

##### `getScale` ([Function](/docs/developer-guide/using-layers.md#accessors)|Array, optional)
Expand All @@ -162,7 +163,7 @@ Scaling factor on the mesh along each axis.

- Default: `[0, 0, 0]`

Translation of the mesh along each axis. Offset from the center position given by `getPosition`. `[x, y, z]` in meters.
Translation of the mesh along each axis. Offset from the center position given by `getPosition`. `[x, y, z]` in meters. This will be composed with layer's [modelMatrix](https://github.com/uber/deck.gl/blob/master/docs/api-reference/layer.md#modelmatrix-number16-optional).

* If an array is provided, it is used as the offset for all objects.
* If a function is provided, it is called on each object to retrieve its offset.
Expand Down
1 change: 1 addition & 0 deletions docs/upgrade-guide.md
Expand Up @@ -7,6 +7,7 @@
##### Defaults

- The `opacity` prop of all layers is now default to `1` (used to be `0.8`).
- [`SimpleMeshLayer`](/docs/layers/simple-mesh-layer.md) and [`ScenegraphLayer`](/docs/layers/scenegraph-layer.md): `modelMatrix` will be composed to instance transformation matrix (derived from layer props `getOrientation`, `getScale`, `getTranslation` and `getTransformMatrix`) under `CARTESIAN` and `METER_OFFSETS` [coordinates](/docs/developer-guide/coordinate-systems.md).

##### Removed

Expand Down
16 changes: 16 additions & 0 deletions examples/layer-browser/src/data-samples.js
Expand Up @@ -265,3 +265,19 @@ export function getMultiPointFeatures100K() {
_multiPointFeatures100K = _multiPointFeatures100K || generateMultiPointFeatures(1e5, 10);
return _multiPointFeatures100K;
}

function getMeshSampleData([xCount, yCount], spacing) {
const data = [];
for (let x = 0; x < xCount; x++) {
for (let y = 0; y < yCount; y++) {
data.push({
position: [(x - (xCount - 1) / 2) * spacing, (y - (yCount - 1) / 2) * spacing],
color: [(x / (xCount - 1)) * 255, 128, (y / (yCount - 1)) * 255],
orientation: [(x / (xCount - 1)) * 60 - 30, 0, -90]
});
}
}
return data;
}

export const meshSampleData = getMeshSampleData([10, 10], 120);
33 changes: 33 additions & 0 deletions examples/website/mesh/app.js
@@ -1,3 +1,4 @@
/* global window */
import React, {PureComponent} from 'react';
import {render} from 'react-dom';
import DeckGL from '@deck.gl/react';
Expand All @@ -11,6 +12,7 @@ import {
import {SolidPolygonLayer} from '@deck.gl/layers';
import {SimpleMeshLayer} from '@deck.gl/mesh-layers';

import {Matrix4} from 'math.gl';
import {OBJLoader} from '@loaders.gl/obj';
import {registerLoaders} from '@loaders.gl/core';

Expand Down Expand Up @@ -62,12 +64,42 @@ const background = [
];

export default class App extends PureComponent {
constructor(props) {
super(props);
this.state = {
modelMatrix: new Matrix4()
};
this._frameId = null;
this._rotate = this._rotate.bind(this);
}

componentDidMount() {
this._frameId = window.requestAnimationFrame(this._rotate);
}

componentWillUnmount() {
if (this._frameId) {
window.cancelAnimationFrame(this._frameId);
}
}

_rotate() {
const matrix = new Matrix4(this.state.modelMatrix);
matrix.rotateX((0.005 / 180) * Math.PI);
this.setState({
modelMatrix: matrix
});
window.requestAnimationFrame(this._rotate);
}

render() {
const {modelMatrix} = this.state;
const layers = [
new SimpleMeshLayer({
id: 'mini-coopers',
data: SAMPLE_DATA,
mesh: MESH_URL,
modelMatrix,
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
getPosition: d => d.position,
getColor: d => d.color,
Expand All @@ -78,6 +110,7 @@ export default class App extends PureComponent {
id: 'background',
data: background,
extruded: false,
modelMatrix,
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
getPolygon: f => f,
getFillColor: [0, 0, 0, 0]
Expand Down
3 changes: 2 additions & 1 deletion examples/website/mesh/package.json
Expand Up @@ -10,7 +10,8 @@
"@loaders.gl/obj": "^1.3.3",
"deck.gl": "^7.3.0-beta",
"react": "^16.3.0",
"react-dom": "^16.3.0"
"react-dom": "^16.3.0",
"math.gl": "^3.0.0"
},
"devDependencies": {
"@babel/core": "^7.4.0",
Expand Down
1 change: 0 additions & 1 deletion modules/geo-layers/src/tile-3d-layer/tile-3d-layer.js
Expand Up @@ -189,7 +189,6 @@ export default class Tile3DLayer extends CompositeLayer {
coordinateSystem: COORDINATE_SYSTEM.METER_OFFSETS,
coordinateOrigin: cartographicOrigin,
modelMatrix,
_composeModelMatrix: true,
getTransformMatrix: instance => instance.modelMatrix,
getPosition: instance => [0, 0, 0]
}
Expand Down
Expand Up @@ -20,7 +20,7 @@ uniform float sizeScale;
uniform float sizeMinPixels;
uniform float sizeMaxPixels;
uniform mat4 sceneModelMatrix;
uniform bool enableOffsetModelMatrix;
uniform bool composeModelMatrix;
// Attributes
_attribute vec4 POSITION;
Expand Down Expand Up @@ -74,8 +74,7 @@ void main(void) {
float clampedSize = clamp(originalSize, sizeMinPixels, sizeMaxPixels);
vec3 pos = (instanceModelMatrix * (sceneModelMatrix * POSITION).xyz) * sizeScale * (clampedSize / originalSize) + instanceTranslation;
if(enableOffsetModelMatrix) {
if(composeModelMatrix) {
DECKGL_FILTER_SIZE(pos, geometry);
gl_Position = project_position_to_clipspace(pos + instancePositions, instancePositions64Low, vec3(0.0), geometry.position);
}
Expand Down
8 changes: 4 additions & 4 deletions modules/mesh-layers/src/scenegraph-layer/scenegraph-layer.js
Expand Up @@ -24,7 +24,7 @@ import {ScenegraphNode, createGLTFObjects} from '@luma.gl/experimental';
import GL from '@luma.gl/constants';
import {waitForGLTFAssets} from './gltf-utils';

import {MATRIX_ATTRIBUTES} from '../utils/matrix';
import {MATRIX_ATTRIBUTES, shouldComposeModelMatrix} from '../utils/matrix';

import vs from './scenegraph-layer-vertex.glsl';
import fs from './scenegraph-layer-fragment.glsl';
Expand Down Expand Up @@ -52,7 +52,6 @@ const defaultProps = {

// flat or pbr
_lighting: 'flat',
_composeModelMatrix: false,
// _lighting must be pbr for this to work
_imageBasedLightingEnvironment: null,

Expand Down Expand Up @@ -252,7 +251,8 @@ export default class ScenegraphLayer extends Layer {
this.state.animator.animate(context.animationProps.time);
}

const {sizeScale, sizeMinPixels, sizeMaxPixels, opacity, _composeModelMatrix} = this.props;
const {viewport} = this.context;
const {sizeScale, sizeMinPixels, sizeMaxPixels, opacity, coordinateSystem} = this.props;
const numInstances = this.getNumInstances();
this.state.scenegraph.traverse((model, {worldMatrix}) => {
model.model.setInstanceCount(numInstances);
Expand All @@ -264,7 +264,7 @@ export default class ScenegraphLayer extends Layer {
opacity,
sizeMinPixels,
sizeMaxPixels,
enableOffsetModelMatrix: _composeModelMatrix,
composeModelMatrix: shouldComposeModelMatrix(viewport, coordinateSystem),
sceneModelMatrix: worldMatrix,
// Needed for PBR (TODO: find better way to get it)
u_Camera: model.model.getUniforms().project_uCameraPosition
Expand Down
Expand Up @@ -3,6 +3,7 @@ export default `#version 300 es
// Scale the model
uniform float sizeScale;
uniform bool composeModelMatrix;
// Primitive attributes
in vec3 positions;
Expand Down Expand Up @@ -36,11 +37,17 @@ void main(void) {
geometry.normal = normals_commonspace;
vec3 pos = (instanceModelMatrix * positions) * sizeScale + instanceTranslation;
pos = project_size(pos);
DECKGL_FILTER_SIZE(pos, geometry);
gl_Position = project_position_to_clipspace(instancePositions, instancePositions64Low, pos, position_commonspace);
geometry.position = position_commonspace;
if (composeModelMatrix) {
DECKGL_FILTER_SIZE(pos, geometry);
gl_Position = project_position_to_clipspace(pos + instancePositions, instancePositions64Low, vec3(0.0), geometry.position);
}
else {
pos = project_size(pos);
DECKGL_FILTER_SIZE(pos, geometry);
gl_Position = project_position_to_clipspace(instancePositions, instancePositions64Low, pos, geometry.position);
}
DECKGL_FILTER_GL_POSITION(gl_Position, geometry);
DECKGL_FILTER_COLOR(vColor, geometry);
Expand Down
Expand Up @@ -3,6 +3,7 @@ export default `
// Scale the model
uniform float sizeScale;
uniform bool composeModelMatrix;
// Primitive attributes
attribute vec3 positions;
Expand Down Expand Up @@ -36,11 +37,17 @@ void main(void) {
geometry.normal = normals_commonspace;
vec3 pos = (instanceModelMatrix * positions) * sizeScale + instanceTranslation;
pos = project_size(pos);
DECKGL_FILTER_SIZE(pos, geometry);
if (composeModelMatrix) {
DECKGL_FILTER_SIZE(pos, geometry);
gl_Position = project_position_to_clipspace(pos + instancePositions, instancePositions64Low, vec3(0.0), geometry.position);
}
else {
pos = project_size(pos);
DECKGL_FILTER_SIZE(pos, geometry);
gl_Position = project_position_to_clipspace(instancePositions, instancePositions64Low, pos, geometry.position);
}
gl_Position = project_position_to_clipspace(instancePositions, instancePositions64Low, pos, position_commonspace);
geometry.position = position_commonspace;
DECKGL_FILTER_GL_POSITION(gl_Position, geometry);
DECKGL_FILTER_COLOR(vColor, geometry);
Expand Down
Expand Up @@ -22,11 +22,11 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import {Layer, project32, phongLighting, picking} from '@deck.gl/core';
import {Layer, project32, phongLighting, picking, COORDINATE_SYSTEM} from '@deck.gl/core';
import GL from '@luma.gl/constants';
import {Model, Geometry, Texture2D, isWebGL2} from '@luma.gl/core';

import {MATRIX_ATTRIBUTES} from '../utils/matrix';
import {MATRIX_ATTRIBUTES, shouldComposeModelMatrix} from '../utils/matrix';

// NOTE(Tarek): Should eventually phase out the glsl1 versions.
import vs1 from './simple-mesh-layer-vertex.glsl1';
Expand Down Expand Up @@ -194,11 +194,13 @@ export default class SimpleMeshLayer extends Layer {
return;
}

const {sizeScale} = this.props;
const {viewport} = this.context;
const {sizeScale, coordinateSystem} = this.props;

this.state.model.draw({
uniforms: Object.assign({}, uniforms, {
sizeScale,
composeModelMatrix: shouldComposeModelMatrix(viewport, coordinateSystem),
flatShade: !this.state.hasNormals
})
});
Expand Down
14 changes: 13 additions & 1 deletion modules/mesh-layers/src/utils/matrix.js
@@ -1,4 +1,4 @@
import {createIterable} from '@deck.gl/core';
import {COORDINATE_SYSTEM, createIterable} from '@deck.gl/core';

/* eslint-disable max-statements, complexity */
const RADIAN_PER_DEGREE = Math.PI / 180;
Expand Down Expand Up @@ -153,3 +153,15 @@ export const MATRIX_ATTRIBUTES = {
}
}
};

// only apply composeModelMatrix when in cartesian or meter_offsets coordinate system
// with `composeModelMatrix` enabled, the rotation part of the layer's modelMatrix will be composed to instance's transformations
// since rotating latitude and longitude can not provide meaningful results, hence `composeModelMatrix` is disabled
// when in LNGLAT and LNGLAT_OFFSET coordinates.
export function shouldComposeModelMatrix(viewport, coordinateSystem) {
return (
coordinateSystem === COORDINATE_SYSTEM.CARTESIAN ||
coordinateSystem === COORDINATE_SYSTEM.METER_OFFSETS ||
(coordinateSystem === COORDINATE_SYSTEM.DEFAULT && !viewport.isGeospatial)
);
}
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -45,8 +45,8 @@
"@luma.gl/test-utils": "^8.0.0-beta.2",
"@probe.gl/bench": "^3.2.0-beta.3",
"@probe.gl/test-utils": "^3.2.0-beta.3",
"@loaders.gl/csv": "^1.3.3",
"@loaders.gl/polyfills": "^1.3.3",
"@loaders.gl/csv": "^1.3.4",
"@loaders.gl/polyfills": "^1.3.4",
"babel-loader": "^8.0.0",
"babel-plugin-inline-webgl-constants": "^1.0.1",
"babel-plugin-remove-glsl-comments": "^0.1.0",
Expand Down
1 change: 1 addition & 0 deletions test/modules/index.js
Expand Up @@ -24,6 +24,7 @@ import './core';
import './layers';
import './aggregation-layers';
import './geo-layers';
import './mesh-layers';

import './google-maps';
import './mapbox';
Expand Down
2 changes: 0 additions & 2 deletions test/modules/layers/index.js
Expand Up @@ -26,8 +26,6 @@ import './polygon-layer.spec';
import './geojson.spec';
import './geojson-layer.spec';
import './point-cloud-layer.spec';
import './simple-mesh-layer.spec';
import './scenegraph-layer.spec';
import './path-layer/path-layer-vertex.spec';
import './icon-manager.spec';
import './text-layer/utils.spec';
Expand Down
3 changes: 3 additions & 0 deletions test/modules/mesh-layers/index.js
@@ -0,0 +1,3 @@
import './simple-mesh-layer.spec';
import './scenegraph-layer.spec';
import './utils.spec';
28 changes: 28 additions & 0 deletions test/modules/mesh-layers/utils.spec.js
@@ -0,0 +1,28 @@
import test from 'tape-catch';
import {shouldComposeModelMatrix} from '@deck.gl/mesh-layers/utils/matrix';
import {COORDINATE_SYSTEM} from '@deck.gl/core';

test('shouldComposeModelMatrix', t => {
t.ok(
shouldComposeModelMatrix({isGeospatial: false}, COORDINATE_SYSTEM.DEFAULT),
'Should composeModelMatrix for cartesian.'
);
t.notOk(
shouldComposeModelMatrix({isGeospatial: true}, COORDINATE_SYSTEM.DEFAULT),
'Should not composeModelMatrix for lnglat.'
);
t.ok(
shouldComposeModelMatrix({}, COORDINATE_SYSTEM.IDENTITY),
'Should composeModelMatrix for identity.'
);
t.ok(
shouldComposeModelMatrix({}, COORDINATE_SYSTEM.METER_OFFSETS),
'Should composeModelMatrix for meter_offsets.'
);
t.notOk(
shouldComposeModelMatrix({}, COORDINATE_SYSTEM.LNGLAT_OFFSETS),
'Should not composeModelMatrix for lnglat_offsets.'
);

t.end();
});
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit d4a6199

Please sign in to comment.