393 lines
10 KiB
JavaScript
393 lines
10 KiB
JavaScript
import {
|
|
Cartesian3,
|
|
Math as CesiumMath,
|
|
Check,
|
|
destroyObject,
|
|
Ellipsoid,
|
|
getElement,
|
|
VoxelShapeType,
|
|
} from "@cesium/engine";
|
|
import knockout from "../ThirdParty/knockout.js";
|
|
import InspectorShared from "../InspectorShared.js";
|
|
import VoxelInspectorViewModel from "./VoxelInspectorViewModel.js";
|
|
|
|
/**
|
|
* Inspector widget to aid in debugging voxels
|
|
*
|
|
* @alias VoxelInspector
|
|
* @constructor
|
|
*
|
|
* @param {Element|string} container The DOM element or ID that will contain the widget.
|
|
* @param {Scene} scene the Scene instance to use.
|
|
*/
|
|
function VoxelInspector(container, scene) {
|
|
//>>includeStart('debug', pragmas.debug);
|
|
Check.defined("container", container);
|
|
Check.typeOf.object("scene", scene);
|
|
//>>includeEnd('debug');
|
|
|
|
container = getElement(container);
|
|
const element = document.createElement("div");
|
|
const viewModel = new VoxelInspectorViewModel(scene);
|
|
|
|
this._viewModel = viewModel;
|
|
this._container = container;
|
|
this._element = element;
|
|
|
|
const text = document.createElement("div");
|
|
text.textContent = "Voxel Inspector";
|
|
text.className = "cesium-cesiumInspector-button";
|
|
text.setAttribute("data-bind", "click: toggleInspector");
|
|
element.appendChild(text);
|
|
element.className = "cesium-cesiumInspector cesium-VoxelInspector";
|
|
element.setAttribute(
|
|
"data-bind",
|
|
'css: { "cesium-cesiumInspector-visible" : inspectorVisible, "cesium-cesiumInspector-hidden" : !inspectorVisible}'
|
|
);
|
|
container.appendChild(element);
|
|
|
|
const panel = document.createElement("div");
|
|
panel.className = "cesium-cesiumInspector-dropDown";
|
|
element.appendChild(panel);
|
|
|
|
const createSection = InspectorShared.createSection;
|
|
const createCheckbox = InspectorShared.createCheckbox;
|
|
const createRangeInput = InspectorShared.createRangeInput;
|
|
const createButton = InspectorShared.createButton;
|
|
|
|
const displayPanelContents = createSection(
|
|
panel,
|
|
"Display",
|
|
"displayVisible",
|
|
"toggleDisplay"
|
|
);
|
|
|
|
const transformPanelContents = createSection(
|
|
panel,
|
|
"Transform",
|
|
"transformVisible",
|
|
"toggleTransform"
|
|
);
|
|
|
|
const boundsPanelContents = createSection(
|
|
panel,
|
|
"Bounds",
|
|
"boundsVisible",
|
|
"toggleBounds"
|
|
);
|
|
|
|
const clippingPanelContents = createSection(
|
|
panel,
|
|
"Clipping",
|
|
"clippingVisible",
|
|
"toggleClipping"
|
|
);
|
|
|
|
const shaderPanelContents = createSection(
|
|
panel,
|
|
"Shader",
|
|
"shaderVisible",
|
|
"toggleShader"
|
|
);
|
|
|
|
// Display
|
|
displayPanelContents.appendChild(createCheckbox("Depth Test", "depthTest"));
|
|
displayPanelContents.appendChild(createCheckbox("Show", "show"));
|
|
displayPanelContents.appendChild(
|
|
createCheckbox("Disable Update", "disableUpdate")
|
|
);
|
|
displayPanelContents.appendChild(createCheckbox("Debug Draw", "debugDraw"));
|
|
displayPanelContents.appendChild(createCheckbox("Jitter", "jitter"));
|
|
displayPanelContents.appendChild(
|
|
createCheckbox("Nearest Sampling", "nearestSampling")
|
|
);
|
|
|
|
displayPanelContents.appendChild(
|
|
createRangeInput("Screen Space Error", "screenSpaceError", 0, 128)
|
|
);
|
|
|
|
displayPanelContents.appendChild(
|
|
createRangeInput("Step Size", "stepSize", 0.0, 2.0)
|
|
);
|
|
|
|
// Transform
|
|
const maxTrans = 10.0;
|
|
const maxScale = 10.0;
|
|
const maxAngle = CesiumMath.PI;
|
|
|
|
transformPanelContents.appendChild(
|
|
createRangeInput("Translation X", "translationX", -maxTrans, +maxTrans)
|
|
);
|
|
transformPanelContents.appendChild(
|
|
createRangeInput("Translation Y", "translationY", -maxTrans, +maxTrans)
|
|
);
|
|
transformPanelContents.appendChild(
|
|
createRangeInput("Translation Z", "translationZ", -maxTrans, +maxTrans)
|
|
);
|
|
transformPanelContents.appendChild(
|
|
createRangeInput("Scale X", "scaleX", 0, +maxScale)
|
|
);
|
|
transformPanelContents.appendChild(
|
|
createRangeInput("Scale Y", "scaleY", 0, +maxScale)
|
|
);
|
|
transformPanelContents.appendChild(
|
|
createRangeInput("Scale Z", "scaleZ", 0, +maxScale)
|
|
);
|
|
transformPanelContents.appendChild(
|
|
createRangeInput("Heading", "angleX", -maxAngle, +maxAngle)
|
|
);
|
|
transformPanelContents.appendChild(
|
|
createRangeInput("Pitch", "angleY", -maxAngle, +maxAngle)
|
|
);
|
|
transformPanelContents.appendChild(
|
|
createRangeInput("Roll", "angleZ", -maxAngle, +maxAngle)
|
|
);
|
|
|
|
// Bounds
|
|
const boxMinBounds = VoxelShapeType.getMinBounds(VoxelShapeType.BOX);
|
|
const boxMaxBounds = VoxelShapeType.getMaxBounds(VoxelShapeType.BOX);
|
|
|
|
const ellipsoidMinBounds = Cartesian3.fromElements(
|
|
VoxelShapeType.getMinBounds(VoxelShapeType.ELLIPSOID).x,
|
|
VoxelShapeType.getMinBounds(VoxelShapeType.ELLIPSOID).y,
|
|
-Ellipsoid.WGS84.maximumRadius,
|
|
new Cartesian3()
|
|
);
|
|
const ellipsoidMaxBounds = Cartesian3.fromElements(
|
|
VoxelShapeType.getMaxBounds(VoxelShapeType.ELLIPSOID).x,
|
|
VoxelShapeType.getMaxBounds(VoxelShapeType.ELLIPSOID).y,
|
|
+10000000.0,
|
|
new Cartesian3()
|
|
);
|
|
|
|
const cylinderMinBounds = VoxelShapeType.getMinBounds(
|
|
VoxelShapeType.CYLINDER
|
|
);
|
|
const cylinderMaxBounds = VoxelShapeType.getMaxBounds(
|
|
VoxelShapeType.CYLINDER
|
|
);
|
|
|
|
makeCoordinateRange(
|
|
"Max X",
|
|
"Min X",
|
|
"Max Y",
|
|
"Min Y",
|
|
"Max Z",
|
|
"Min Z",
|
|
"boundsBoxMaxX",
|
|
"boundsBoxMinX",
|
|
"boundsBoxMaxY",
|
|
"boundsBoxMinY",
|
|
"boundsBoxMaxZ",
|
|
"boundsBoxMinZ",
|
|
boxMinBounds,
|
|
boxMaxBounds,
|
|
"shapeIsBox",
|
|
boundsPanelContents
|
|
);
|
|
|
|
makeCoordinateRange(
|
|
"Max Longitude",
|
|
"Min Longitude",
|
|
"Max Latitude",
|
|
"Min Latitude",
|
|
"Max Height",
|
|
"Min Height",
|
|
"boundsEllipsoidMaxLongitude",
|
|
"boundsEllipsoidMinLongitude",
|
|
"boundsEllipsoidMaxLatitude",
|
|
"boundsEllipsoidMinLatitude",
|
|
"boundsEllipsoidMaxHeight",
|
|
"boundsEllipsoidMinHeight",
|
|
ellipsoidMinBounds,
|
|
ellipsoidMaxBounds,
|
|
"shapeIsEllipsoid",
|
|
boundsPanelContents
|
|
);
|
|
|
|
makeCoordinateRange(
|
|
"Max Radius",
|
|
"Min Radius",
|
|
"Max Height",
|
|
"Min Height",
|
|
"Max Angle",
|
|
"Min Angle",
|
|
"boundsCylinderMaxRadius",
|
|
"boundsCylinderMinRadius",
|
|
"boundsCylinderMaxHeight",
|
|
"boundsCylinderMinHeight",
|
|
"boundsCylinderMaxAngle",
|
|
"boundsCylinderMinAngle",
|
|
cylinderMinBounds,
|
|
cylinderMaxBounds,
|
|
"shapeIsCylinder",
|
|
boundsPanelContents
|
|
);
|
|
|
|
// Clipping
|
|
makeCoordinateRange(
|
|
"Max X",
|
|
"Min X",
|
|
"Max Y",
|
|
"Min Y",
|
|
"Max Z",
|
|
"Min Z",
|
|
"clippingBoxMaxX",
|
|
"clippingBoxMinX",
|
|
"clippingBoxMaxY",
|
|
"clippingBoxMinY",
|
|
"clippingBoxMaxZ",
|
|
"clippingBoxMinZ",
|
|
boxMinBounds,
|
|
boxMaxBounds,
|
|
"shapeIsBox",
|
|
clippingPanelContents
|
|
);
|
|
|
|
makeCoordinateRange(
|
|
"Max Longitude",
|
|
"Min Longitude",
|
|
"Max Latitude",
|
|
"Min Latitude",
|
|
"Max Height",
|
|
"Min Height",
|
|
"clippingEllipsoidMaxLongitude",
|
|
"clippingEllipsoidMinLongitude",
|
|
"clippingEllipsoidMaxLatitude",
|
|
"clippingEllipsoidMinLatitude",
|
|
"clippingEllipsoidMaxHeight",
|
|
"clippingEllipsoidMinHeight",
|
|
ellipsoidMinBounds,
|
|
ellipsoidMaxBounds,
|
|
"shapeIsEllipsoid",
|
|
clippingPanelContents
|
|
);
|
|
|
|
makeCoordinateRange(
|
|
"Max Radius",
|
|
"Min Radius",
|
|
"Max Height",
|
|
"Min Height",
|
|
"Max Angle",
|
|
"Min Angle",
|
|
"clippingCylinderMaxRadius",
|
|
"clippingCylinderMinRadius",
|
|
"clippingCylinderMaxHeight",
|
|
"clippingCylinderMinHeight",
|
|
"clippingCylinderMaxAngle",
|
|
"clippingCylinderMinAngle",
|
|
cylinderMinBounds,
|
|
cylinderMaxBounds,
|
|
"shapeIsCylinder",
|
|
clippingPanelContents
|
|
);
|
|
|
|
// Shader
|
|
const shaderPanelEditor = document.createElement("div");
|
|
shaderPanelContents.appendChild(shaderPanelEditor);
|
|
|
|
const shaderEditor = document.createElement("textarea");
|
|
shaderEditor.setAttribute(
|
|
"data-bind",
|
|
"textInput: shaderString, event: { keydown: shaderEditorKeyPress }"
|
|
);
|
|
shaderPanelEditor.className = "cesium-cesiumInspector-styleEditor";
|
|
shaderPanelEditor.appendChild(shaderEditor);
|
|
const compileShaderButton = createButton(
|
|
"Compile (Ctrl+Enter)",
|
|
"compileShader"
|
|
);
|
|
shaderPanelEditor.appendChild(compileShaderButton);
|
|
|
|
const compilationText = document.createElement("label");
|
|
compilationText.style.display = "block";
|
|
compilationText.setAttribute(
|
|
"data-bind",
|
|
"text: shaderCompilationMessage, style: {color: shaderCompilationSuccess ? 'green' : 'red'}"
|
|
);
|
|
shaderPanelEditor.appendChild(compilationText);
|
|
|
|
knockout.applyBindings(viewModel, element);
|
|
}
|
|
|
|
Object.defineProperties(VoxelInspector.prototype, {
|
|
/**
|
|
* Gets the parent container.
|
|
* @memberof VoxelInspector.prototype
|
|
*
|
|
* @type {Element}
|
|
*/
|
|
container: {
|
|
get: function () {
|
|
return this._container;
|
|
},
|
|
},
|
|
|
|
/**
|
|
* Gets the view model.
|
|
* @memberof VoxelInspector.prototype
|
|
*
|
|
* @type {VoxelInspectorViewModel}
|
|
*/
|
|
viewModel: {
|
|
get: function () {
|
|
return this._viewModel;
|
|
},
|
|
},
|
|
});
|
|
|
|
/**
|
|
* @returns {boolean} true if the object has been destroyed, false otherwise.
|
|
*/
|
|
VoxelInspector.prototype.isDestroyed = function () {
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* Destroys the widget. Should be called if permanently
|
|
* removing the widget from layout.
|
|
*/
|
|
VoxelInspector.prototype.destroy = function () {
|
|
knockout.cleanNode(this._element);
|
|
this._container.removeChild(this._element);
|
|
this.viewModel.destroy();
|
|
|
|
return destroyObject(this);
|
|
};
|
|
|
|
function makeCoordinateRange(
|
|
maxXTitle,
|
|
minXTitle,
|
|
maxYTitle,
|
|
minYTitle,
|
|
maxZTitle,
|
|
minZTitle,
|
|
maxXVar,
|
|
minXVar,
|
|
maxYVar,
|
|
minYVar,
|
|
maxZVar,
|
|
minZVar,
|
|
defaultMinBounds,
|
|
defaultMaxBounds,
|
|
allowedShape,
|
|
parentContainer
|
|
) {
|
|
const createRangeInput = InspectorShared.createRangeInput;
|
|
|
|
const min = defaultMinBounds;
|
|
const max = defaultMaxBounds;
|
|
const boundsElement = parentContainer.appendChild(
|
|
document.createElement("div")
|
|
);
|
|
boundsElement.setAttribute("data-bind", `if: ${allowedShape}`);
|
|
boundsElement.appendChild(createRangeInput(maxXTitle, maxXVar, min.x, max.x));
|
|
boundsElement.appendChild(createRangeInput(minXTitle, minXVar, min.x, max.x));
|
|
boundsElement.appendChild(createRangeInput(maxYTitle, maxYVar, min.y, max.y));
|
|
boundsElement.appendChild(createRangeInput(minYTitle, minYVar, min.y, max.y));
|
|
boundsElement.appendChild(createRangeInput(maxZTitle, maxZVar, min.z, max.z));
|
|
boundsElement.appendChild(createRangeInput(minZTitle, minZVar, min.z, max.z));
|
|
}
|
|
|
|
export default VoxelInspector;
|