mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 11:24:00 +00:00
refactor(installations): inject engine renderer adapter
This commit is contained in:
1 parent
f4f0088814
commit
965a82144c
7 files changed
+90
-18
No files matched your search
@@ -1252,6 +1252,7 @@
|
|||||||
"src/layers/installations/lifecycle.js",
|
"src/layers/installations/lifecycle.js",
|
||||||
"src/layers/installations/model.js",
|
"src/layers/installations/model.js",
|
||||||
"src/layers/installations/policy.js",
|
"src/layers/installations/policy.js",
|
||||||
|
"src/layers/installations/render/cesium.js",
|
||||||
"src/layers/installations/rendering.js",
|
"src/layers/installations/rendering.js",
|
||||||
"src/layers/installations/selection.js",
|
"src/layers/installations/selection.js",
|
||||||
"src/layers/installations/source.js",
|
"src/layers/installations/source.js",
|
||||||
@@ -2130,6 +2131,7 @@
|
|||||||
"src/layers/installations/lifecycle.js",
|
"src/layers/installations/lifecycle.js",
|
||||||
"src/layers/installations/model.js",
|
"src/layers/installations/model.js",
|
||||||
"src/layers/installations/policy.js",
|
"src/layers/installations/policy.js",
|
||||||
|
"src/layers/installations/render/cesium.js",
|
||||||
"src/layers/installations/rendering.js",
|
"src/layers/installations/rendering.js",
|
||||||
"src/layers/installations/selection.js",
|
"src/layers/installations/selection.js",
|
||||||
"src/layers/installations/source.js",
|
"src/layers/installations/source.js",
|
||||||
@@ -2968,6 +2970,7 @@
|
|||||||
"src/layers/installations/lifecycle.js",
|
"src/layers/installations/lifecycle.js",
|
||||||
"src/layers/installations/model.js",
|
"src/layers/installations/model.js",
|
||||||
"src/layers/installations/policy.js",
|
"src/layers/installations/policy.js",
|
||||||
|
"src/layers/installations/render/cesium.js",
|
||||||
"src/layers/installations/rendering.js",
|
"src/layers/installations/rendering.js",
|
||||||
"src/layers/installations/selection.js",
|
"src/layers/installations/selection.js",
|
||||||
"src/layers/installations/source.js",
|
"src/layers/installations/source.js",
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { overlayHost } from './overlayHost.js';
|
import { overlayHost } from './overlayHost.js';
|
||||||
import * as credits from '../../data/dataCredits.js';
|
import * as credits from '../../data/dataCredits.js';
|
||||||
import { createInstallationsLayer } from '../../layers/installations/index.js';
|
import { createInstallationsLayer } from '../../layers/installations/index.js';
|
||||||
|
import { createInstallationsCesiumRenderer } from '../../layers/installations/render/cesium.js';
|
||||||
|
import { rendererFor } from './renderers.js';
|
||||||
import * as render from '../../renderGovernor.js';
|
import * as render from '../../renderGovernor.js';
|
||||||
import * as context from '../../data/contextStore.js';
|
import * as context from '../../data/contextStore.js';
|
||||||
import * as picking from '../../data/pickRegistry.js';
|
import * as picking from '../../data/pickRegistry.js';
|
||||||
@@ -11,6 +13,10 @@ export function createApplicationInstallations({ surface, source }) {
|
|||||||
return createInstallationsLayer({
|
return createInstallationsLayer({
|
||||||
source,
|
source,
|
||||||
overlayHost,
|
overlayHost,
|
||||||
|
rendererFactory: ({ engine, ...context }) =>
|
||||||
|
engine?.kind === 'navara'
|
||||||
|
? rendererFor('military-installations', engine, context)
|
||||||
|
: createInstallationsCesiumRenderer(context),
|
||||||
services: {
|
services: {
|
||||||
credits,
|
credits,
|
||||||
render,
|
render,
|
||||||
|
|||||||
Vendored
+12
-6
@@ -144,21 +144,27 @@ export function createControls({ state: layerState, services, parts, source }) {
|
|||||||
*/
|
*/
|
||||||
focusById(id) {
|
focusById(id) {
|
||||||
const record = layerState.recordById.get(String(id));
|
const record = layerState.recordById.get(String(id));
|
||||||
if (!record || !layerState.engine?.camera?.flyToSphere) return false;
|
const camera = layerState.engine?.camera;
|
||||||
|
const flyToSphere = camera?.flyToSphere;
|
||||||
|
const flyToBoundingSphere =
|
||||||
|
layerState.viewer?.camera?.flyToBoundingSphere;
|
||||||
|
if (!record || (!flyToSphere && !flyToBoundingSphere)) return false;
|
||||||
// No camera flight without a real selection: a flight plus a stale subject
|
// No camera flight without a real selection: a flight plus a stale subject
|
||||||
// reads as success to Context navigation and strands NEXT on this item.
|
// reads as success to Context navigation and strands NEXT on this item.
|
||||||
if (!parts.selection.selectRecord(record.id)) return false;
|
if (!parts.selection.selectRecord(record.id)) return false;
|
||||||
layerState.engine.camera.flyToSphere(
|
const sphere = {
|
||||||
{
|
|
||||||
center: geo.cartesian3.fromDegrees(
|
center: geo.cartesian3.fromDegrees(
|
||||||
record.longitude,
|
record.longitude,
|
||||||
record.latitude,
|
record.latitude,
|
||||||
parts.rendering.installationSurfaceHeightM(record),
|
parts.rendering.installationSurfaceHeightM(record),
|
||||||
),
|
),
|
||||||
radius: 18000,
|
radius: 18000,
|
||||||
},
|
};
|
||||||
{ duration: 1.4 },
|
if (flyToSphere) flyToSphere.call(camera, sphere, { duration: 1.4 });
|
||||||
);
|
else
|
||||||
|
flyToBoundingSphere.call(layerState.viewer.camera, sphere, {
|
||||||
|
duration: 1.4,
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +1,73 @@
|
|||||||
import { createNamedMarkers } from './namedMarkers.js';
|
|
||||||
import { createModel } from './model.js';
|
|
||||||
import { createRendering } from './rendering.js';
|
|
||||||
import { createIngestion } from './ingestion.js';
|
import { createIngestion } from './ingestion.js';
|
||||||
import { createViewport } from './viewport.js';
|
import { createViewport } from './viewport.js';
|
||||||
import { createSelection } from './selection.js';
|
|
||||||
import { createControls } from './controls.js';
|
import { createControls } from './controls.js';
|
||||||
import { createLifecycle } from './lifecycle.js';
|
|
||||||
import { createState } from './state.js';
|
import { createState } from './state.js';
|
||||||
|
import { createModel } from './model.js';
|
||||||
|
|
||||||
/** Construct one layer with its own scene state and supplied application services. */
|
/** Construct one layer with its own scene state and supplied application services. */
|
||||||
export function createInstallationsLayer({ services, source, overlayHost }) {
|
export function createInstallationsLayer({
|
||||||
|
services,
|
||||||
|
source,
|
||||||
|
overlayHost,
|
||||||
|
rendererFactory,
|
||||||
|
}) {
|
||||||
if (
|
if (
|
||||||
typeof source?.getMappedSites !== 'function' ||
|
typeof source?.getMappedSites !== 'function' ||
|
||||||
typeof source?.searchNearby !== 'function'
|
typeof source?.searchNearby !== 'function'
|
||||||
)
|
)
|
||||||
throw new TypeError('An installation source is required');
|
throw new TypeError('An installation source is required');
|
||||||
|
if (typeof rendererFactory !== 'function')
|
||||||
|
throw new TypeError('An installation renderer factory is required');
|
||||||
const state = createState({ services });
|
const state = createState({ services });
|
||||||
const parts = {};
|
const parts = {};
|
||||||
const context = { state, services, parts, source, overlayHost };
|
const context = { state, services, parts, source, overlayHost };
|
||||||
parts.model = createModel(context);
|
parts.model = createModel(context);
|
||||||
parts.rendering = createRendering(context);
|
|
||||||
parts.namedMarkers = createNamedMarkers(context);
|
|
||||||
parts.ingestion = createIngestion(context);
|
parts.ingestion = createIngestion(context);
|
||||||
parts.viewport = createViewport(context);
|
parts.viewport = createViewport(context);
|
||||||
parts.selection = createSelection(context);
|
|
||||||
parts.controls = createControls(context);
|
parts.controls = createControls(context);
|
||||||
parts.lifecycle = createLifecycle(context);
|
let renderer = null;
|
||||||
|
const lifecycle = {
|
||||||
|
init(viewer, options = {}) {
|
||||||
|
if (renderer)
|
||||||
|
throw new Error('Installations layer is already initialized');
|
||||||
|
const engine = options.engine ?? null;
|
||||||
|
renderer = rendererFactory({ ...context, viewer, engine });
|
||||||
|
if (!renderer?.lifecycle?.methods)
|
||||||
|
throw new Error('Installation renderer is unavailable');
|
||||||
|
Object.assign(parts, renderer);
|
||||||
|
return renderer.lifecycle.methods.init(viewer, options);
|
||||||
|
},
|
||||||
|
enable(...args) {
|
||||||
|
return renderer?.lifecycle?.methods.enable(...args);
|
||||||
|
},
|
||||||
|
disable(...args) {
|
||||||
|
return renderer?.lifecycle?.methods.disable(...args);
|
||||||
|
},
|
||||||
|
destroy(...args) {
|
||||||
|
try {
|
||||||
|
return renderer?.lifecycle?.methods.destroy(...args);
|
||||||
|
} finally {
|
||||||
|
renderer = null;
|
||||||
|
for (const key of [
|
||||||
|
'rendering',
|
||||||
|
'namedMarkers',
|
||||||
|
'selection',
|
||||||
|
'lifecycle',
|
||||||
|
])
|
||||||
|
delete parts[key];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
return Object.assign(
|
return Object.assign(
|
||||||
{},
|
{},
|
||||||
parts.controls.methods,
|
parts.controls.methods,
|
||||||
parts.lifecycle.methods,
|
lifecycle,
|
||||||
parts.ingestion?.methods,
|
parts.ingestion?.methods,
|
||||||
{
|
{
|
||||||
approximateSurfaceDistanceM: parts.model.approximateSurfaceDistanceM,
|
approximateSurfaceDistanceM: parts.model.approximateSurfaceDistanceM,
|
||||||
classifyGoogleMilitaryPlace: parts.model.classifyGoogleMilitaryPlace,
|
classifyGoogleMilitaryPlace: parts.model.classifyGoogleMilitaryPlace,
|
||||||
installationSourceLabel: parts.model.installationSourceLabel,
|
installationSourceLabel: parts.model.installationSourceLabel,
|
||||||
installationSurfaceHeightM: parts.rendering.installationSurfaceHeightM,
|
installationSurfaceHeightM: parts.model.installationSurfaceHeightM,
|
||||||
installationWithinViewport: parts.model.installationWithinViewport,
|
installationWithinViewport: parts.model.installationWithinViewport,
|
||||||
installationResponseSaturated: parts.model.installationResponseSaturated,
|
installationResponseSaturated: parts.model.installationResponseSaturated,
|
||||||
installationRetryDelayMs: parts.viewport.installationRetryDelayMs,
|
installationRetryDelayMs: parts.viewport.installationRetryDelayMs,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import * as Cesium from 'cesium';
|
import * as Cesium from 'cesium';
|
||||||
import { LAYER_ID } from './policy.js';
|
import { LAYER_ID } from './policy.js';
|
||||||
|
import { engineFromViewer } from '../../globe/cesium/engineFromViewer.js';
|
||||||
import {
|
import {
|
||||||
claimCameraSensitivity,
|
claimCameraSensitivity,
|
||||||
releaseCameraSensitivity,
|
releaseCameraSensitivity,
|
||||||
@@ -16,6 +17,7 @@ export function createLifecycle({
|
|||||||
|
|
||||||
const methods = {
|
const methods = {
|
||||||
init(viewer, { engine = null } = {}) {
|
init(viewer, { engine = null } = {}) {
|
||||||
|
engine ||= engineFromViewer(viewer);
|
||||||
layerState.viewer = viewer;
|
layerState.viewer = viewer;
|
||||||
layerState.engine = engine;
|
layerState.engine = engine;
|
||||||
layerState.dataSource = new Cesium.CustomDataSource(
|
layerState.dataSource = new Cesium.CustomDataSource(
|
||||||
|
|||||||
@@ -43,6 +43,14 @@ export function createModel({ state: layerState, services, parts, source }) {
|
|||||||
return rgbaFromCss(COLOR_BY_CLASS[record.class] || '#9ca6b0');
|
return rgbaFromCss(COLOR_BY_CLASS[record.class] || '#9ca6b0');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function installationSurfaceHeightM(record) {
|
||||||
|
const floor = services.ground?.cachedGroundFloor?.(
|
||||||
|
record?.latitude,
|
||||||
|
record?.longitude,
|
||||||
|
);
|
||||||
|
return services.ground?.floorAltitudeM?.(null, floor) ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Classify a Places text-search result without turning a name match into a
|
* Classify a Places text-search result without turning a name match into a
|
||||||
* mapped military-land claim. Google currently has no documented military
|
* mapped military-land claim. Google currently has no documented military
|
||||||
@@ -144,6 +152,7 @@ export function createModel({ state: layerState, services, parts, source }) {
|
|||||||
return {
|
return {
|
||||||
approximateSurfaceDistanceM,
|
approximateSurfaceDistanceM,
|
||||||
colorFor,
|
colorFor,
|
||||||
|
installationSurfaceHeightM,
|
||||||
classifyGoogleMilitaryPlace,
|
classifyGoogleMilitaryPlace,
|
||||||
installationSourceLabel,
|
installationSourceLabel,
|
||||||
installationWithinViewport,
|
installationWithinViewport,
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { createLifecycle } from '../lifecycle.js';
|
||||||
|
import { createNamedMarkers } from '../namedMarkers.js';
|
||||||
|
import { createRendering } from '../rendering.js';
|
||||||
|
import { createSelection } from '../selection.js';
|
||||||
|
|
||||||
|
/** Compose the existing Cesium-owned scene, input and entity adapters. */
|
||||||
|
export function createInstallationsCesiumRenderer(context) {
|
||||||
|
return {
|
||||||
|
lifecycle: createLifecycle(context),
|
||||||
|
namedMarkers: createNamedMarkers(context),
|
||||||
|
rendering: createRendering(context),
|
||||||
|
selection: createSelection(context),
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in new issue
Block a user