Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
vladyslav-tk committed Nov 14, 2024
1 parent a569902 commit 1960bfe
Show file tree
Hide file tree
Showing 2 changed files with 337 additions and 197 deletions.
319 changes: 319 additions & 0 deletions src/plugins/cesium/interactionHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,319 @@
import type {CustomDataSource, Model} from '@cesium/engine';
import {
ArcType,
Axis,
CallbackProperty,
Cartesian2,
Cartesian3,
Color,
Matrix3,
Matrix4,
Plane,
Quaternion,
TranslationRotationScale,
} from '@cesium/engine';
import type {UploadedModel} from './ngv-plugin-cesium-upload.js';

export type PlaneColorOptions = {
material?: Color;
outline?: boolean;
outlineColor?: Color;
};

export type EdgeStyleOptions = {
width?: number;
material?: Color;
};

export type CornerPointStyleOptions = {
radii?: Cartesian3;
material?: Color;
};

const DefaultPlaneColorOptions = {
material: Color.RED.withAlpha(0.1),
outline: true,
outlineColor: Color.WHITE,
};

const DefaultEdgeStyles = {
width: 10,
material: Color.WHITE.withAlpha(0.3),
};

const DefaultCornerPointStyles = {
radii: new Cartesian3(10, 10, 10),
material: Color.BROWN,
};

const SIDE_PLANES: Plane[] = [
new Plane(new Cartesian3(0, 0, 1), 0.5),
new Plane(new Cartesian3(0, 0, -1), 0.5),
new Plane(new Cartesian3(0, 1, 0), 0.5),
new Plane(new Cartesian3(0, -1, 0), 0.5),
new Plane(new Cartesian3(1, 0, 0), 0.5),
new Plane(new Cartesian3(-1, 0, 0), 0.5),
];

const CORNER_POINT_VECTORS = [
new Cartesian3(0.5, 0.5, 0.5),
new Cartesian3(0.5, -0.5, 0.5),
new Cartesian3(-0.5, -0.5, 0.5),
new Cartesian3(-0.5, 0.5, 0.5),
];

const LOCAL_EDGES: [Cartesian3, Cartesian3][] = [];
CORNER_POINT_VECTORS.forEach((vector, i) => {
const upPoint = vector;
const downPoint = Cartesian3.clone(upPoint, new Cartesian3());
downPoint.z *= -1;
const nextUpPoint = CORNER_POINT_VECTORS[(i + 1) % 4];
const nextDownPoint = Cartesian3.clone(nextUpPoint, new Cartesian3());
nextDownPoint.z *= -1;
const verticalEdge: [Cartesian3, Cartesian3] = [upPoint, downPoint];
// const topEdge: [Cartesian3, Cartesian3] = [nextUpPoint, upPoint];
// const bottomEdge: [Cartesian3, Cartesian3] = [nextDownPoint, downPoint];
LOCAL_EDGES.push(verticalEdge);
});

const scaleScratch = new Cartesian3();
export function getScaleFromMatrix(matrix: Matrix4): Cartesian3 {
return Matrix4.getScale(matrix, scaleScratch);
}

const dimensionsScratch = new Cartesian3();
function getScaledDimensions(model: UploadedModel): Cartesian3 {
Cartesian3.clone(model.id.dimensions, dimensionsScratch);
Cartesian3.multiplyComponents(
getScaleFromMatrix(model.modelMatrix),
dimensionsScratch,
dimensionsScratch,
);
return dimensionsScratch;
}

const scratchRotationMatrix = new Matrix3();
const scratchRotationQuaternion = new Quaternion();
export function getRotationQuaternionFromMatrix(matrix: Matrix4): Quaternion {
return Quaternion.fromRotationMatrix(
Matrix4.getRotation(matrix, scratchRotationMatrix),
scratchRotationQuaternion,
);
}

const scratchTranslation = new Cartesian3();
export function getTranslationFromMatrix(matrix: Matrix4): Cartesian3 {
return Matrix4.getTranslation(matrix, scratchTranslation);
}

const scratchTranslationRotationDimensionsMatrix = new Matrix4();
export function getTranslationRotationDimensionsMatrix(
model: UploadedModel,
result = scratchTranslationRotationDimensionsMatrix,
): Matrix4 {
return Matrix4.fromTranslationRotationScale(
new TranslationRotationScale(
getTranslationFromMatrix(model.modelMatrix),
getRotationQuaternionFromMatrix(model.modelMatrix),
getScaledDimensions(model),
),
result,
);
}

const scratchTranslationRotationScaleMatrix = new Matrix4();
export function getTranslationRotationScaleMatrix(
matrix: Matrix4,
result = scratchTranslationRotationScaleMatrix,
): Matrix4 {
return Matrix4.fromTranslationRotationScale(
new TranslationRotationScale(
getTranslationFromMatrix(matrix),
getRotationQuaternionFromMatrix(matrix),
getScaleFromMatrix(matrix),
),
result,
);
}

const centerDiffScratch = new Cartesian3();
export function getModelCenterDiff(model: Model): Cartesian3 {
return Cartesian3.subtract(
model.boundingSphere.center,
getTranslationFromMatrix(model.modelMatrix),
centerDiffScratch,
);
}

const scaleMatrixScratch = new Matrix4();
const planeScaleScratch = new Cartesian3();
function getPlaneScale(model: UploadedModel, normalAxis: Axis) {
const dimensions = getScaledDimensions(model);
if (normalAxis === Axis.Y) {
dimensions.clone(planeScaleScratch);
} else {
let scaleArray: number[] = [];
if (normalAxis === Axis.X) {
scaleArray = [dimensions.x, dimensions.y, dimensions.z];
} else if (normalAxis === Axis.Z) {
scaleArray = [dimensions.y, dimensions.x, dimensions.z];
}
Cartesian3.fromArray(scaleArray, 0, planeScaleScratch);
}

return Matrix4.fromScale(planeScaleScratch, scaleMatrixScratch);
}

const planeDimensionsScratch = new Cartesian2();
function getPlaneDimensions(model: UploadedModel, normalAxis: Axis) {
const dimensions = getScaledDimensions(model);
let dimensionsArray: number[] = [];

if (normalAxis === Axis.X) {
dimensionsArray = [dimensions.y, dimensions.z];
} else if (normalAxis === Axis.Y) {
dimensionsArray = [dimensions.x, dimensions.z];
} else if (normalAxis === Axis.Z) {
dimensionsArray = [dimensions.x, dimensions.y];
}

return Cartesian2.fromArray(dimensionsArray, 0, planeDimensionsScratch);
}

export function createPlaneEntity(
dataSource: CustomDataSource,
plane: Plane,
model: UploadedModel,
colorOptions: PlaneColorOptions = DefaultPlaneColorOptions,
): void {
const normalAxis: Axis = plane.normal.x
? Axis.X
: plane.normal.y
? Axis.Y
: Axis.Z;

dataSource.entities.add({
position: new CallbackProperty(() => model.boundingSphere.center, false),
orientation: new CallbackProperty(
() => getRotationQuaternionFromMatrix(model.modelMatrix),
false,
),
plane: {
plane: new CallbackProperty(
() => Plane.transform(plane, getPlaneScale(model, normalAxis)),
false,
),
dimensions: new CallbackProperty(
() => getPlaneDimensions(model, normalAxis),
false,
),
...colorOptions,
},
});
}
export function createEdge(
dataSource: CustomDataSource,
model: UploadedModel,
edge: Cartesian3[],
styles: EdgeStyleOptions = DefaultEdgeStyles,
): void {
const positions = [new Cartesian3(), new Cartesian3()];
dataSource.entities.add({
polyline: {
show: true,
positions: new CallbackProperty(() => {
const matrix = getTranslationRotationDimensionsMatrix(model);
Matrix4.multiplyByPoint(matrix, edge[0], positions[0]);
Matrix4.multiplyByPoint(matrix, edge[1], positions[1]);
const centerDiff = getModelCenterDiff(model);
Cartesian3.add(positions[0], centerDiff, positions[0]);
Cartesian3.add(positions[1], centerDiff, positions[1]);
return positions;
}, false),
width: styles.width,
material: styles.material,
arcType: ArcType.NONE,
},
});
}

export function createCornerPoint(
dataSource: CustomDataSource,
model: UploadedModel,
edges: Cartesian3[],
styles: CornerPointStyleOptions = DefaultCornerPointStyles,
): void {
const position = new Cartesian3();
edges.forEach((localEdge) => {
dataSource.entities.add({
position: new CallbackProperty(() => {
const matrix = getTranslationRotationDimensionsMatrix(model);
Matrix4.multiplyByPoint(matrix, localEdge, position);
const centerDiff = getModelCenterDiff(model);
Cartesian3.add(position, centerDiff, position);
return position;
}, false),
ellipsoid: {
show: true,
radii: styles.radii,
material: styles.material,
},
});
});
}

export function showModelBBox(
dataSources: {
topDownPlanesDataSource?: CustomDataSource;
sidePlanesDataSource?: CustomDataSource;
edgeLinesDataSource?: CustomDataSource;
cornerPointsDataSource?: CustomDataSource;
},
model: UploadedModel,
styles: {
planeColorOptions?: PlaneColorOptions;
edgeStyleOptions?: EdgeStyleOptions;
cornerPointStyleOptions: CornerPointStyleOptions;
} = {
planeColorOptions: DefaultPlaneColorOptions,
edgeStyleOptions: DefaultEdgeStyles,
cornerPointStyleOptions: DefaultCornerPointStyles,
},
): void {
const topDownPlanesDataSource = dataSources.topDownPlanesDataSource;
const sidePlanesDataSource = dataSources.sidePlanesDataSource;
if (topDownPlanesDataSource || sidePlanesDataSource) {
SIDE_PLANES.forEach((plane) => {
const normalAxis: Axis = plane.normal.x
? Axis.X
: plane.normal.y
? Axis.Y
: Axis.Z;

const dataSource =
normalAxis === Axis.Z ? topDownPlanesDataSource : sidePlanesDataSource;
if (dataSource)
createPlaneEntity(dataSource, plane, model, styles.planeColorOptions);
});
}
if (dataSources.edgeLinesDataSource) {
LOCAL_EDGES.forEach((edge) =>
createEdge(
dataSources.edgeLinesDataSource,
model,
edge,
styles.edgeStyleOptions,
),
);
}
if (dataSources.cornerPointsDataSource) {
LOCAL_EDGES.forEach((edge) =>
createCornerPoint(
dataSources.cornerPointsDataSource,
model,
edge,
styles.cornerPointStyleOptions,
),
);
}
}
Loading

0 comments on commit 1960bfe

Please sign in to comment.