mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
refactor(installations): inject engine renderer adapter
This commit is contained in:
1 parent
f4f0088814
commit
965a82144c
7 files changed
+96
-24
No files matched your search
@@ -1252,6 +1252,7 @@
|
||||
"src/layers/installations/lifecycle.js",
|
||||
"src/layers/installations/model.js",
|
||||
"src/layers/installations/policy.js",
|
||||
"src/layers/installations/render/cesium.js",
|
||||
"src/layers/installations/rendering.js",
|
||||
"src/layers/installations/selection.js",
|
||||
"src/layers/installations/source.js",
|
||||
@@ -2130,6 +2131,7 @@
|
||||
"src/layers/installations/lifecycle.js",
|
||||
"src/layers/installations/model.js",
|
||||
"src/layers/installations/policy.js",
|
||||
"src/layers/installations/render/cesium.js",
|
||||
"src/layers/installations/rendering.js",
|
||||
"src/layers/installations/selection.js",
|
||||
"src/layers/installations/source.js",
|
||||
@@ -2968,6 +2970,7 @@
|
||||
"src/layers/installations/lifecycle.js",
|
||||
"src/layers/installations/model.js",
|
||||
"src/layers/installations/policy.js",
|
||||
"src/layers/installations/render/cesium.js",
|
||||
"src/layers/installations/rendering.js",
|
||||
"src/layers/installations/selection.js",
|
||||
"src/layers/installations/source.js",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { overlayHost } from './overlayHost.js';
|
||||
import * as credits from '../../data/dataCredits.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 context from '../../data/contextStore.js';
|
||||
import * as picking from '../../data/pickRegistry.js';
|
||||
@@ -11,6 +13,10 @@ export function createApplicationInstallations({ surface, source }) {
|
||||
return createInstallationsLayer({
|
||||
source,
|
||||
overlayHost,
|
||||
rendererFactory: ({ engine, ...context }) =>
|
||||
engine?.kind === 'navara'
|
||||
? rendererFor('military-installations', engine, context)
|
||||
: createInstallationsCesiumRenderer(context),
|
||||
services: {
|
||||
credits,
|
||||
render,
|
||||
|
||||
Vendored
+18
-12
@@ -144,21 +144,27 @@ export function createControls({ state: layerState, services, parts, source }) {
|
||||
*/
|
||||
focusById(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
|
||||
// reads as success to Context navigation and strands NEXT on this item.
|
||||
if (!parts.selection.selectRecord(record.id)) return false;
|
||||
layerState.engine.camera.flyToSphere(
|
||||
{
|
||||
center: geo.cartesian3.fromDegrees(
|
||||
record.longitude,
|
||||
record.latitude,
|
||||
parts.rendering.installationSurfaceHeightM(record),
|
||||
),
|
||||
radius: 18000,
|
||||
},
|
||||
{ duration: 1.4 },
|
||||
);
|
||||
const sphere = {
|
||||
center: geo.cartesian3.fromDegrees(
|
||||
record.longitude,
|
||||
record.latitude,
|
||||
parts.rendering.installationSurfaceHeightM(record),
|
||||
),
|
||||
radius: 18000,
|
||||
};
|
||||
if (flyToSphere) flyToSphere.call(camera, sphere, { duration: 1.4 });
|
||||
else
|
||||
flyToBoundingSphere.call(layerState.viewer.camera, sphere, {
|
||||
duration: 1.4,
|
||||
});
|
||||
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 { createViewport } from './viewport.js';
|
||||
import { createSelection } from './selection.js';
|
||||
import { createControls } from './controls.js';
|
||||
import { createLifecycle } from './lifecycle.js';
|
||||
import { createState } from './state.js';
|
||||
import { createModel } from './model.js';
|
||||
|
||||
/** 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 (
|
||||
typeof source?.getMappedSites !== 'function' ||
|
||||
typeof source?.searchNearby !== 'function'
|
||||
)
|
||||
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 parts = {};
|
||||
const context = { state, services, parts, source, overlayHost };
|
||||
parts.model = createModel(context);
|
||||
parts.rendering = createRendering(context);
|
||||
parts.namedMarkers = createNamedMarkers(context);
|
||||
parts.ingestion = createIngestion(context);
|
||||
parts.viewport = createViewport(context);
|
||||
parts.selection = createSelection(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(
|
||||
{},
|
||||
parts.controls.methods,
|
||||
parts.lifecycle.methods,
|
||||
lifecycle,
|
||||
parts.ingestion?.methods,
|
||||
{
|
||||
approximateSurfaceDistanceM: parts.model.approximateSurfaceDistanceM,
|
||||
classifyGoogleMilitaryPlace: parts.model.classifyGoogleMilitaryPlace,
|
||||
installationSourceLabel: parts.model.installationSourceLabel,
|
||||
installationSurfaceHeightM: parts.rendering.installationSurfaceHeightM,
|
||||
installationSurfaceHeightM: parts.model.installationSurfaceHeightM,
|
||||
installationWithinViewport: parts.model.installationWithinViewport,
|
||||
installationResponseSaturated: parts.model.installationResponseSaturated,
|
||||
installationRetryDelayMs: parts.viewport.installationRetryDelayMs,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as Cesium from 'cesium';
|
||||
import { LAYER_ID } from './policy.js';
|
||||
import { engineFromViewer } from '../../globe/cesium/engineFromViewer.js';
|
||||
import {
|
||||
claimCameraSensitivity,
|
||||
releaseCameraSensitivity,
|
||||
@@ -16,6 +17,7 @@ export function createLifecycle({
|
||||
|
||||
const methods = {
|
||||
init(viewer, { engine = null } = {}) {
|
||||
engine ||= engineFromViewer(viewer);
|
||||
layerState.viewer = viewer;
|
||||
layerState.engine = engine;
|
||||
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');
|
||||
}
|
||||
|
||||
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
|
||||
* mapped military-land claim. Google currently has no documented military
|
||||
@@ -144,6 +152,7 @@ export function createModel({ state: layerState, services, parts, source }) {
|
||||
return {
|
||||
approximateSurfaceDistanceM,
|
||||
colorFor,
|
||||
installationSurfaceHeightM,
|
||||
classifyGoogleMilitaryPlace,
|
||||
installationSourceLabel,
|
||||
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