Skip to content

Commit

Permalink
Add support for resolving transform defined by "links" scene graph
Browse files Browse the repository at this point in the history
  • Loading branch information
twojtasz committed Nov 8, 2019
1 parent 07f2f74 commit 428373f
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 17 deletions.
4 changes: 3 additions & 1 deletion modules/core/src/components/log-viewer/core-3d-viewer.js
Expand Up @@ -269,6 +269,7 @@ export default class Core3DViewer extends PureComponent {
const stream = lookAheads[streamName] || streams[streamName];
const coordinateProps = resolveCoordinateTransform(
frame,
streamName,
streamsMetadata[streamName],
getTransformMatrix
);
Expand Down Expand Up @@ -317,6 +318,7 @@ export default class Core3DViewer extends PureComponent {
additionalProps,
resolveCoordinateTransform(
frame,
props.streamName,
streamsMetadata[props.streamName],
getTransformMatrix
),
Expand All @@ -328,7 +330,7 @@ export default class Core3DViewer extends PureComponent {
// Apply log-specific coordinate props
Object.assign(
additionalProps,
resolveCoordinateTransform(frame, props, getTransformMatrix)
resolveCoordinateTransform(frame, null, props, getTransformMatrix) // TODO: is 'null' correct?
);
} else {
return layer;
Expand Down
Expand Up @@ -74,7 +74,12 @@ export default class ObjectLabelsOverlay extends PureComponent {
}

const {frame, streamsMetadata, getTransformMatrix} = this.props;
result = resolveCoordinateTransform(frame, streamsMetadata[streamName], getTransformMatrix);
result = resolveCoordinateTransform(
frame,
streamName,
streamsMetadata[streamName],
getTransformMatrix
);
// cache calculated coordinate props by stream name
coordinateProps[streamName] = result;

Expand Down
51 changes: 48 additions & 3 deletions modules/core/src/utils/transform.js
Expand Up @@ -18,6 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

/* eslint-disable camelcase */
import {COORDINATE_SYSTEM} from '@deck.gl/core';
import {_Pose as Pose, Matrix4} from 'math.gl';
import {addMetersToLngLat} from 'viewport-mercator-project';
Expand All @@ -27,8 +28,47 @@ import {COORDINATE} from '../constants';
// keep in sync with core-3d-viewer.js
const DEFAULT_ORIGIN = [0, 0, 0];

export function resolveCoordinateTransform(frame, streamMetadata = {}, getTransformMatrix) {
const {origin, transforms = {}, vehicleRelativeTransform} = frame;
// Export only for testing
export function resolveLinksTransform(links, streams, streamName) {
const transforms = [];
let parentPose = links[streamName] && links[streamName].target_pose;

// TODO: we could cache the resulting transform based on the entry
// into the link structure.

let missingPose = false;

// Collect all poses from child to root
while (parentPose) {
if (!streams[parentPose]) {
missingPose = true;
break;
}
transforms.push(streams[parentPose]);
parentPose = links[parentPose] && links[parentPose].target_pose;
}

// Resolve pose transforms. If missingPose is true, which can happen if a
// persistent link is defined before normal state has been sent, ignore it
// TODO(twojtasz): Flag stream affected by missingPose so it can be reported
// by application
if (!missingPose && transforms.length) {
// process from root to child
return transforms.reduceRight((acc, val) => {
return acc.multiplyRight(new Pose(val).getTransformationMatrix());
}, new Matrix4());
}

return null;
}

export function resolveCoordinateTransform(
frame,
streamName,
streamMetadata = {},
getTransformMatrix
) {
const {origin, links, streams, transforms = {}, vehicleRelativeTransform} = frame;
const {coordinate, transform, pose} = streamMetadata;

let coordinateSystem = COORDINATE_SYSTEM.METER_OFFSETS;
Expand All @@ -41,6 +81,7 @@ export function resolveCoordinateTransform(frame, streamMetadata = {}, getTransf
break;

case COORDINATE.DYNAMIC:
// TODO: this should work with links and needs streamName passed
// cache calculated transform matrix for each frame
transforms[transform] = transforms[transform] || getTransformMatrix(transform, frame);
modelMatrix = transforms[transform];
Expand All @@ -49,18 +90,22 @@ export function resolveCoordinateTransform(frame, streamMetadata = {}, getTransf
break;

case COORDINATE.VEHICLE_RELATIVE:
// TODO: this should work with links
modelMatrix = vehicleRelativeTransform;
break;

case COORDINATE.IDENTITY:
default:
case COORDINATE.IDENTITY:
modelMatrix = resolveLinksTransform(links, streams, streamName);
break;
}

if (pose) {
// TODO - remove when builder updates
streamTransform = new Pose(pose).getTransformationMatrix();
}
if (streamTransform && streamTransform.length > 0) {
// TODO: this needs tested with links
modelMatrix = modelMatrix
? new Matrix4(modelMatrix).multiplyRight(streamTransform)
: streamTransform;
Expand Down
14 changes: 2 additions & 12 deletions test/apps/viewer/webpack.config.js
Expand Up @@ -47,18 +47,8 @@ const CONFIG = {
// Compile ES2015 using bable
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: BABEL_CONFIG
}
]
},
{
// Unfortunately, webpack doesn't import library sourcemaps on its own...
test: /\.js$/,
use: ['source-map-loader'],
enforce: 'pre'
loader: 'babel-loader',
options: BABEL_CONFIG
}
]
},
Expand Down
1 change: 1 addition & 0 deletions test/modules/core/utils/index.js
Expand Up @@ -24,3 +24,4 @@ import './buffer-range.spec';
import './image-buffer.spec';
import './metrics-helper.spec';
import './style.spec';
import './transform.spec';
139 changes: 139 additions & 0 deletions test/modules/core/utils/transform.spec.js
@@ -0,0 +1,139 @@
// Copyright (c) 2019 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

/* eslint-disable camelcase */
import test from 'tape';

import {resolveLinksTransform} from '@streetscape.gl/core/utils/transform';

test('resolveLinksTransform', t => {
// transation links
// A -> B -> C
// A -> D
//
// rotation links
// r90 -> m10 -> DD
// rn90 -> m20 -> CC
const links = {
C: {
target_pose: 'B'
},
B: {
target_pose: 'A'
},
D: {
target_pose: 'A'
},
CC: {
target_pose: 'm20'
},
DD: {
target_pose: 'm10'
},
m10: {
target_pose: 'r90'
},
m20: {
target_pose: 'rn90'
}
};

const streams = {
A: {
yaw: 0,
pitch: 0,
roll: 0,
x: 10,
y: 10,
z: 0
},
B: {
yaw: 0,
pitch: 0,
roll: 0,
x: 20,
y: 20,
z: 0
},
r90: {
yaw: Math.PI / 2,
pitch: 0,
roll: 0,
x: 0,
y: 0,
z: 0
},
rn90: {
yaw: -Math.PI / 2,
pitch: 0,
roll: 0,
x: 0,
y: 0,
z: 0
},
m10: {
yaw: 0,
pitch: 0,
roll: 0,
x: 10,
y: 10,
z: 0
},
m20: {
yaw: 0,
pitch: 0,
roll: 0,
x: 20,
y: 20,
z: 0
}
};

const testCases = [
{stream: 'C', expected: [30, 30, 0]},
{stream: 'D', expected: [10, 10, 0]},
{stream: 'E', expected: null},
{stream: 'CC', expected: [20, -20, 0]},
{stream: 'DD', expected: [-10, 10, 0]}
];

for (const testcase of testCases) {
const transformTo = resolveLinksTransform(links, streams, testcase.stream);
if (transformTo) {
const resultOrigin = transformTo.transformVector([0, 0, 0]);

t.comment(typeof resultOrigin);
t.comment(typeof testcase.expected);
t.deepEqual(
testcase.expected,
resultOrigin,
`transformed origin of ${testcase.stream} matches expected result ${testcase.expected}`
);
} else {
t.equal(
transformTo,
testcase.expected,
`missing links entry matches expected '${testcase.expected}'`
);
}
}

t.end();
});

0 comments on commit 428373f

Please sign in to comment.