Compare commits

...

8 Commits

Author SHA1 Message Date
Jesse Mazzella
55b8a4142c fix: don't delete imagery size, update related telemetry on focusedImage change 2023-02-10 14:29:47 -08:00
David Tsay
622e6044a4 avoid -0 2023-02-10 07:30:07 -08:00
David Tsay
2aa757c6b7 rotate function needs to work with numbers 2023-02-10 07:27:47 -08:00
David Tsay
a350c8e584 fix unit tests 2023-02-09 16:53:44 -08:00
David Tsay
0c111f5fa2 enable hud for non-gimbling cameras 2023-02-09 16:39:44 -08:00
David Tsay
a82e78365d reorganize shared props passing 2023-02-09 16:23:51 -08:00
David Tsay
0476466441 fix non-gimbling camera azimuth
correct pan to azimuth
2023-02-09 16:11:09 -08:00
David Tsay
ae623b8552 won't mount if cameraAngleOfView undefined 2023-02-08 12:48:39 -08:00
7 changed files with 105 additions and 70 deletions

View File

@@ -275,7 +275,7 @@ function pointForTimestamp(timestamp, name, imageSamples, delay) {
local: Math.floor(timestamp / delay) * delay,
url,
sunOrientation: getCompassValues(0, 360),
cameraPan: getCompassValues(0, 360),
cameraAzimuth: getCompassValues(0, 360),
heading: getCompassValues(0, 360),
transformations: navCamTransformations,
imageDownloadName

View File

@@ -26,18 +26,23 @@
:style="`width: 100%; height: 100%`"
>
<CompassHUD
v-if="showCompassHUD"
:sun-heading="sunHeading"
:camera-angle-of-view="cameraAngleOfView"
:camera-pan="cameraPan"
:heading="heading"
:camera-azimuth="cameraAzimuth"
:transformations="transformations"
:has-gimble="hasGimble"
:normalized-camera-azimuth="normalizedCameraAzimuth"
:sun-heading="sunHeading"
/>
<CompassRose
v-if="showCompassRose"
:camera-pan="cameraPan"
:camera-angle-of-view="cameraAngleOfView"
:heading="heading"
:sized-image-dimensions="sizedImageDimensions"
:sun-heading="sunHeading"
:camera-azimuth="cameraAzimuth"
:transformations="transformations"
:has-gimble="hasGimble"
:normalized-camera-azimuth="normalizedCameraAzimuth"
:sun-heading="sunHeading"
:sized-image-dimensions="sizedImageDimensions"
/>
</div>
</template>
@@ -45,6 +50,7 @@
<script>
import CompassHUD from './CompassHUD.vue';
import CompassRose from './CompassRose.vue';
import { rotate } from './utils';
export default {
components: {
@@ -62,11 +68,14 @@ export default {
}
},
computed: {
showCompassHUD() {
return this.hasCameraPan && this.cameraAngleOfView > 0;
hasGimble() {
return this.cameraAzimuth !== undefined;
},
showCompassRose() {
return (this.hasCameraPan || this.hasHeading) && this.cameraAngleOfView > 0;
// compass ordinal orientation of camera
normalizedCameraAzimuth() {
return this.hasGimble
? rotate(this.cameraAzimuth)
: rotate(this.heading, -this.transformations.rotation || 0);
},
// horizontal rotation from north in degrees
heading() {
@@ -80,14 +89,11 @@ export default {
return this.image.sunOrientation;
},
// horizontal rotation from north in degrees
cameraPan() {
cameraAzimuth() {
return this.image.cameraPan;
},
hasCameraPan() {
return this.cameraPan !== undefined;
},
cameraAngleOfView() {
return this.transformations?.cameraAngleOfView;
return this.transformations.cameraAngleOfView;
},
transformations() {
return this.image.transformations;

View File

@@ -94,17 +94,33 @@ const COMPASS_POINTS = [
export default {
props: {
cameraAngleOfView: {
type: Number,
required: true
},
heading: {
type: Number,
required: true
},
cameraAzimuth: {
type: Number,
default: undefined
},
transformations: {
type: Object,
required: true
},
hasGimble: {
type: Boolean,
required: true
},
normalizedCameraAzimuth: {
type: Number,
required: true
},
sunHeading: {
type: Number,
default: undefined
},
cameraAngleOfView: {
type: Number,
default: undefined
},
cameraPan: {
type: Number,
required: true
}
},
computed: {
@@ -130,10 +146,13 @@ export default {
left: `${ percentage * 100 }%`
};
},
cameraRotation() {
return this.transformations?.rotation;
},
visibleRange() {
return [
rotate(this.cameraPan, -this.cameraAngleOfView / 2),
rotate(this.cameraPan, this.cameraAngleOfView / 2)
rotate(this.normalizedCameraAzimuth, -this.cameraAngleOfView / 2),
rotate(this.normalizedCameraAzimuth, this.cameraAngleOfView / 2)
];
}
}

View File

@@ -75,7 +75,6 @@
:style="sunHeadingStyle"
/>
<!-- Camera FOV -->
<mask
id="mask2"
class="c-cr__cam-fov-l-mask"
@@ -117,10 +116,10 @@
class="cr-vrover"
:style="camAngleAndPositionStyle"
>
<!-- Equipment body. Rotates relative to the camera pan value for cams that gimbal. -->
<!-- Equipment body. Rotates relative to the camera pan value for cameras that gimble. -->
<path
class="cr-vrover__body"
:style="camGimbalAngleStyle"
:style="gimbledCameraPanStyle"
x
fill-rule="evenodd"
clip-rule="evenodd"
@@ -128,6 +127,7 @@
/>
</g>
<!-- Camera FOV -->
<g
class="c-cr__cam-fov"
>
@@ -160,7 +160,7 @@
<!-- NSEW and ticks -->
<g
class="c-cr__nsew"
:style="compassRoseStyle"
:style="compassDialStyle"
>
<g class="c-cr__ticks-major">
<path d="M50 3L43 10H57L50 3Z" />
@@ -259,23 +259,32 @@ import { throttle } from 'lodash';
export default {
props: {
cameraAngleOfView: {
type: Number,
required: true
},
heading: {
type: Number,
required: true,
default() {
return 0;
}
required: true
},
sunHeading: {
type: Number,
default: undefined
},
cameraPan: {
cameraAzimuth: {
type: Number,
default: undefined
},
transformations: {
type: Object,
required: true
},
hasGimble: {
type: Boolean,
required: true
},
normalizedCameraAzimuth: {
type: Number,
required: true
},
sunHeading: {
type: Number,
default: undefined
},
sizedImageDimensions: {
@@ -289,18 +298,6 @@ export default {
};
},
computed: {
cameraHeading() {
return this.cameraPan ?? this.heading;
},
cameraAngleOfView() {
const cameraAngleOfView = this.transformations?.cameraAngleOfView;
if (!cameraAngleOfView) {
console.warn('No Camera Angle of View provided');
}
return cameraAngleOfView;
},
camAngleAndPositionStyle() {
const translateX = this.transformations?.translateX;
const translateY = this.transformations?.translateY;
@@ -309,18 +306,22 @@ export default {
return { transform: `translate(${translateX}%, ${translateY}%) rotate(${rotation}deg) scale(${scale})` };
},
camGimbalAngleStyle() {
const rotation = rotate(this.heading);
gimbledCameraPanStyle() {
if (!this.hasGimble) {
return;
}
const gimbledCameraPan = rotate(this.normalizedCameraAzimuth, -this.heading);
return {
transform: `rotate(${ rotation }deg)`
transform: `rotate(${ -gimbledCameraPan }deg)`
};
},
compassRoseStyle() {
compassDialStyle() {
return { transform: `rotate(${ this.north }deg)` };
},
north() {
return this.lockCompass ? rotate(-this.cameraHeading) : 0;
return this.lockCompass ? rotate(-this.normalizedCameraAzimuth) : 0;
},
cardinalTextRotateN() {
return { transform: `translateY(-27%) rotate(${ -this.north }deg)` };
@@ -348,7 +349,7 @@ export default {
};
},
cameraHeadingStyle() {
const rotation = rotate(this.north, this.cameraHeading);
const rotation = rotate(this.north, this.normalizedCameraAzimuth);
return {
transform: `rotate(${ rotation }deg)`

View File

@@ -35,8 +35,15 @@ describe("The Compass component", () => {
roll: 90,
pitch: 90,
cameraTilt: 100,
cameraPan: 90,
sunAngle: 30
cameraAzimuth: 90,
sunAngle: 30,
transformations: {
translateX: 0,
translateY: 18,
rotation: 0,
scale: 0.3,
cameraAngleOfView: 70
}
};
let propsData = {
naturalAspectRatio: 0.9,
@@ -44,8 +51,7 @@ describe("The Compass component", () => {
sizedImageDimensions: {
width: 100,
height: 100
},
compassRoseSizingClasses: '--rose-small --rose-min'
}
};
app = new Vue({
@@ -54,7 +60,6 @@ describe("The Compass component", () => {
return propsData;
},
template: `<Compass
:compass-rose-sizing-classes="compassRoseSizingClasses"
:image="image"
:natural-aspect-ratio="naturalAspectRatio"
:sized-image-dimensions="sizedImageDimensions"
@@ -67,7 +72,7 @@ describe("The Compass component", () => {
app.$destroy();
});
describe("when a heading value exists on the image", () => {
describe("when a heading value and cameraAngleOfView exists on the image", () => {
it("should display a compass rose", () => {
let compassRoseElement = instance.$el.querySelector(COMPASS_ROSE_CLASS

View File

@@ -430,9 +430,12 @@ export default {
&& imageHeightAndWidth
&& this.zoomFactor === 1
&& this.imagePanned !== true;
const hasCameraConfigurations = this.focusedImage?.transformations !== undefined;
const hasHeading = this.focusedImage?.heading !== undefined;
const hasCameraAngleOfView = this.focusedImage?.transformations?.cameraAngleOfView > 0;
return display && hasCameraConfigurations;
return display
&& hasCameraAngleOfView
&& hasHeading;
},
isSpacecraftPositionFresh() {
let isFresh = undefined;
@@ -585,7 +588,6 @@ export default {
focusedImageIndex() {
this.trackDuration();
this.resetAgeCSS();
this.updateRelatedTelemetryForFocusedImage();
this.getImageNaturalDimensions();
},
bounds() {
@@ -771,6 +773,10 @@ export default {
this.layers = layersMetadata;
if (this.domainObject.configuration) {
const persistedLayers = this.domainObject.configuration.layers;
if (!persistedLayers) {
return;
}
layersMetadata.forEach((layer) => {
const persistedLayer = persistedLayers.find(object => object.name === layer.name);
if (persistedLayer) {
@@ -957,6 +963,7 @@ export default {
}
this.focusedImageIndex = index;
this.updateRelatedTelemetryForFocusedImage();
},
trackDuration() {
if (this.canTrackDuration) {

View File

@@ -153,9 +153,6 @@ export default {
return;
}
// forcibly reset the imageContainer size to prevent an aspect ratio distortion
delete this.imageContainerWidth;
delete this.imageContainerHeight;
this.bounds = bounds; // setting bounds for ImageryView watcher
},
timeSystemChange() {