Skip to content

Commit

Permalink
wip: slicing
Browse files Browse the repository at this point in the history
  • Loading branch information
vladyslav-tk committed Dec 16, 2024
1 parent 0bb9a4e commit 806d7fc
Show file tree
Hide file tree
Showing 9 changed files with 216 additions and 9 deletions.
4 changes: 2 additions & 2 deletions src/apps/permits/demoPermitConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ export const config: IPermitsConfig = {
'@demo': () => import('../../catalogs/demoCatalog.js'),
},
layers: {
// tilesets: ['@cesium/googlePhotorealistic'],
models: ['@demo/sofa', '@demo/thatopensmall'],
tiles3d: ['@cesium/googlePhotorealistic'],
// models: ['@demo/sofa', '@demo/thatopensmall'],
imageries: ['@geoadmin/pixel-karte-farbe'],
// terrain: '@geoadmin/terrain',
},
Expand Down
2 changes: 2 additions & 0 deletions src/apps/permits/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export class NgvAppPermits extends ABaseApp<IPermitsConfig> {
.viewer="${this.viewer}"
.dataSourceCollection="${this.dataSourceCollection}"
.primitiveCollection="${this.collections.models}"
.tiles3dCollection="${this.collections.tiles3d}"
.options="${{listTitle: 'Catalog'}}"
></ngv-plugin-cesium-model-interact>
<div
Expand All @@ -69,6 +70,7 @@ export class NgvAppPermits extends ABaseApp<IPermitsConfig> {
.viewer="${this.viewer}"
.dataSourceCollection="${this.dataSourceCollection}"
.primitiveCollection="${this.uploadedModelsCollection}"
.tiles3dCollection="${this.collections.tiles3d}"
.storeOptions="${this.storeOptions}"
.options="${{listTitle: 'Uploaded models'}}"
></ngv-plugin-cesium-model-interact>
Expand Down
4 changes: 4 additions & 0 deletions src/interfaces/cesium/ingv-layers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type {
Cesium3DTileset,
ClippingPolygon,
UrlTemplateImageryProvider,
WebMapServiceImageryProvider,
WebMapTileServiceImageryProvider,
Expand Down Expand Up @@ -42,6 +43,9 @@ export interface INGVCesiumModel extends Model {
id: {
dimensions?: Cartesian3;
name: string;
terrainClipping?: boolean;
tilesClipping?: boolean;
clippingPolygon?: ClippingPolygon;
};
}

Expand Down
100 changes: 99 additions & 1 deletion src/plugins/cesium/interactionHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import type {CustomDataSource, Model, Scene} from '@cesium/engine';
import {
Cesium3DTileset,
ClippingPolygonCollection,
CustomDataSource, Globe,
Model,
PrimitiveCollection,
Scene
} from '@cesium/engine';
import {
ArcType,
Axis,
Expand All @@ -7,6 +14,7 @@ import {
Cartesian2,
Cartesian3,
Cartographic,
ClippingPolygon,
Color,
Ellipsoid,
HeadingPitchRoll,
Expand Down Expand Up @@ -505,3 +513,93 @@ export function getDimensions(model: Model): Cartesian3 {

return Cartesian3.subtract(max, min, new Cartesian3());
}

export function getClippingPolygon(model: INGVCesiumModel): ClippingPolygon {
const positions = LOCAL_EDGES.map((edge) => {
const position = new Cartesian3();
const matrix = getTranslationRotationDimensionsMatrix(model);
Matrix4.multiplyByPoint(matrix, edge[0], position);
const centerDiff = getModelCenterDiff(model);
Cartesian3.add(position, centerDiff, position);
return position;
});
return new ClippingPolygon({
positions,
});
}

export function applyClippingTo3dTileset(tileset: Cesium3DTileset, models: INGVCesiumModel[]): void {
const polygons: ClippingPolygon[] = [];
models.forEach((m) => {
if (m.id.tilesClipping) {
polygons.push(getClippingPolygon(m));
}
});
tileset.clippingPolygons = new ClippingPolygonCollection({
polygons,
});
}

export function updateModelClipping(model: INGVCesiumModel, tiles3dCollection: PrimitiveCollection, globe: Globe): void {
if ((!tiles3dCollection?.length && !globe) || !model?.ready) return;
const polygon = model.id.clippingPolygon;
const newPolygon = getClippingPolygon(model);

// apply to 3d tiles
if (tiles3dCollection?.length) {
for (let i = 0; i < tiles3dCollection.length; i++) {
const tileset: Cesium3DTileset = tiles3dCollection.get(
i,
) as Cesium3DTileset;
if (polygon && tileset.clippingPolygons?.contains(polygon)) {
tileset.clippingPolygons.remove(polygon);
}
if (model.id.tilesClipping) {
if (!tileset.clippingPolygons) {
tileset.clippingPolygons = new ClippingPolygonCollection({
polygons: [newPolygon],
});
} else {
tileset.clippingPolygons.add(newPolygon);
}
}
}
}

// apply to terrain
if (globe) {
if (polygon && globe?.clippingPolygons?.contains(polygon)) {
globe.clippingPolygons.remove(polygon);
}
if (model.id.terrainClipping) {
if (!globe.clippingPolygons) {
globe.clippingPolygons = new ClippingPolygonCollection({
polygons: [newPolygon],
});
} else {
globe.clippingPolygons.add(newPolygon);
}
}
}

model.id.clippingPolygon = newPolygon;
}

export function removeClippingFrom3dTilesets(model: INGVCesiumModel, tiles3dCollection: PrimitiveCollection, globe: Globe): void {
if ((!tiles3dCollection?.length && !globe) || !model.ready) return;
const polygon = model.id.clippingPolygon;
if (tiles3dCollection?.length) {
for (let i = 0; i < tiles3dCollection.length; i++) {
const tileset: Cesium3DTileset = tiles3dCollection.get(
i,
) as Cesium3DTileset;
if (tileset.clippingPolygons?.contains(polygon)) {
tileset.clippingPolygons.remove(polygon);
}
}
}

if (globe?.clippingPolygons?.contains(polygon)) {
globe.clippingPolygons.remove(polygon);
}
}
4 changes: 4 additions & 0 deletions src/plugins/cesium/localStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ export type StoredModel = {
translation: number[];
rotation: number[];
scale: number[];
terrainClipping: boolean;
tilesClipping: boolean;
};

export function updateModelsInLocalStore(
Expand All @@ -136,6 +138,8 @@ export function updateModelsInLocalStore(
translation: [translation.x, translation.y, translation.z],
rotation: [rotation.x, rotation.y, rotation.z, rotation.w],
scale: [scale.x, scale.y, scale.z],
tilesClipping: model.id.tilesClipping,
terrainClipping: model.id.terrainClipping,
});
});
localStorage.setItem(storeKey, JSON.stringify(localStoreModels));
Expand Down
4 changes: 3 additions & 1 deletion src/plugins/cesium/ngv-cesium-factories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
HeadingPitchRoll,
Transforms,
Ellipsoid,
ClippingPolygon,
} from '@cesium/engine';

import type {
Expand All @@ -31,7 +32,7 @@ import {
} from '@cesium/engine';
import type {IngvCesiumContext} from '../../interfaces/cesium/ingv-cesium-context.js';
import type {INGVCatalog} from '../../interfaces/cesium/ingv-catalog.js';
import {getDimensions} from './interactionHelpers.js';
import {getClippingPolygon, getDimensions} from './interactionHelpers.js';

function withExtra<T>(options: T, extra: Record<string, any>): T {
if (!extra) {
Expand Down Expand Up @@ -67,6 +68,7 @@ export async function instantiateModel(
);
model.readyEvent.addEventListener(() => {
model.id.dimensions = getDimensions(model);
model.id.clippingPolygon = getClippingPolygon(model);
});
return model;
}
Expand Down
50 changes: 45 additions & 5 deletions src/plugins/cesium/ngv-plugin-cesium-model-interact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {
PrimitiveCollection,
DataSourceCollection,
Cartesian2,
Cesium3DTileset
} from '@cesium/engine';
import {
Model,
Expand Down Expand Up @@ -34,6 +35,11 @@ import {
import '../ui/ngv-layer-details.js';
import '../ui/ngv-layers-list.js';
import type {BBoxStyles} from './interactionHelpers.js';
import {
applyClippingTo3dTileset,
removeClippingFrom3dTilesets,
updateModelClipping
} from './interactionHelpers.js';
import {
getHorizontalMoveVector,
getTranslationFromMatrix,
Expand All @@ -43,6 +49,7 @@ import {
showModelBBox,
} from './interactionHelpers.js';
import type {INGVCesiumModel} from '../../interfaces/cesium/ingv-layers.js';
import type {ClippingChangeDetail} from '../ui/ngv-layer-details.js';

type GrabType = 'side' | 'top' | 'edge' | 'corner' | undefined;

Expand All @@ -53,6 +60,8 @@ export class NgvPluginCesiumModelInteract extends LitElement {
@property({type: Object})
private primitiveCollection: PrimitiveCollection;
@property({type: Object})
private tiles3dCollection: PrimitiveCollection;
@property({type: Object})
private dataSourceCollection: DataSourceCollection;
@property({type: Object})
private bboxStyle: BBoxStyles | undefined;
Expand Down Expand Up @@ -111,9 +120,12 @@ export class NgvPluginCesiumModelInteract extends LitElement {
ScreenSpaceEventType.LEFT_UP,
);

this.primitiveCollection.primitiveAdded.addEventListener(() => {
this.onPrimitivesChanged();
});
this.primitiveCollection.primitiveAdded.addEventListener(
(model: INGVCesiumModel) => {
this.onPrimitivesChanged();
updateModelClipping(model, this.tiles3dCollection, this.viewer.scene.globe);
},
);
this.primitiveCollection.primitiveRemoved.addEventListener(
(p: INGVCesiumModel) => {
if (this.storeOptions) {
Expand All @@ -125,6 +137,11 @@ export class NgvPluginCesiumModelInteract extends LitElement {
}
},
);
this.tiles3dCollection?.primitiveAdded.addEventListener(
(tileset: Cesium3DTileset) => {
applyClippingTo3dTileset(tileset, this.models);
},
);
}

removeEvents(): void {
Expand Down Expand Up @@ -180,10 +197,17 @@ export class NgvPluginCesiumModelInteract extends LitElement {

const normal = Ellipsoid.WGS84.geodeticSurfaceNormal(this.moveStart);
this.movePlane = Plane.fromPointNormal(this.moveStart, normal);

if (this.chosenModel?.id.tilesClipping || this.chosenModel?.id.terrainClipping) {
removeClippingFrom3dTilesets(this.chosenModel, this.tiles3dCollection, this.viewer.scene.globe);
}
}
}
onLeftUp(): void {
if (this.grabType) {
if (this.chosenModel?.id.tilesClipping || this.chosenModel?.id.terrainClipping) {
updateModelClipping(this.chosenModel, this.tiles3dCollection, this.viewer.scene.globe);
}
this.viewer.scene.screenSpaceCameraController.enableInputs = true;
this.grabType = undefined;
}
Expand Down Expand Up @@ -368,7 +392,7 @@ export class NgvPluginCesiumModelInteract extends LitElement {
this.storeOptions.indexDbName,
m.name,
);
const model = await instantiateModel({
const model: INGVCesiumModel = await instantiateModel({
type: 'model',
options: {
url: URL.createObjectURL(blob),
Expand All @@ -383,10 +407,15 @@ export class NgvPluginCesiumModelInteract extends LitElement {
id: {
name: m.name,
dimensions: new Cartesian3(...Object.values(m.dimensions)),
terrainClipping: m.terrainClipping,
tilesClipping: m.tilesClipping,
},
},
});
this.primitiveCollection.add(model);
model.readyEvent.addEventListener(() =>
updateModelClipping(model, this.tiles3dCollection, this.viewer.scene.globe),
);
}),
);
this.onPrimitivesChanged();
Expand All @@ -410,7 +439,18 @@ export class NgvPluginCesiumModelInteract extends LitElement {
if (!this.chosenModel && !this.models?.length) return '';
return this.chosenModel
? html` <ngv-layer-details
.layer="${{name: this.chosenModel.id.name}}"
.layer="${{
name: this.chosenModel.id.name,
clippingOptions: {
terrainClipping: this.chosenModel.id.terrainClipping,
tilesClipping: this.chosenModel.id.tilesClipping,
},
}}"
@clippingChange=${(evt: {detail: ClippingChangeDetail}) => {
this.chosenModel.id.terrainClipping = evt.detail.terrainClipping;
this.chosenModel.id.tilesClipping = evt.detail.tilesClipping;
updateModelClipping(this.chosenModel, this.tiles3dCollection, this.viewer.scene.globe);
}}
@done="${() => {
this.chosenModel = undefined;
this.sidePlanesDataSource.entities.removeAll();
Expand Down
1 change: 1 addition & 0 deletions src/plugins/cesium/ngv-plugin-cesium-upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
Cartesian3,
Cartographic,
HeadingPitchRoll,
HeightReference,
Math as CesiumMath,
Matrix4,
Quaternion,
Expand Down
Loading

0 comments on commit 806d7fc

Please sign in to comment.