Comments (1)
For evaluation here
Mesh Features Sandcastle Demo
const viewer = new Cesium.Viewer("cesiumContainer");
// Stores the tileset that is currently selected
let currentTileset;
// Creates a custom fragment shader for visualizing the feature IDs.
// This fetches the feature ID for the fragment from the
// fsInput.featureIds.featureId_0 structure, and just assigns
// a color to the fragment, based on this feature ID
function createCustomShader() {
const customShader = new Cesium.CustomShader({
fragmentShaderText: `
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
int id = fsInput.featureIds.featureId_0;
vec3 color = vec3(0.0, 0.0, 0.0);
if (id == 0) {
color = vec3(0.0, 1.0, 0.0);
} else if (id == 1) {
color = vec3(0.5, 0.5, 0.5);
} else if (id == 2) {
color = vec3(1.0, 0.0, 0.0);
} else if (id == 3) {
color = vec3(0.0, 0.0, 1.0);
}
material.diffuse = color;
}
`,
});
return customShader;
}
// Creates the tileset from the tileset.json in the given subdirectory
async function createTileset(subdirectory) {
if (Cesium.defined(currentTileset)) {
viewer.scene.primitives.remove(currentTileset);
currentTileset = undefined;
}
// Create the tileset, and move it to a certain position on the globe
currentTileset = viewer.scene.primitives.add(
await Cesium.Cesium3DTileset.fromUrl(
`https://raw.githubusercontent.com/CesiumGS/3d-tiles-samples/main/${subdirectory}/tileset.json`,
{
debugShowBoundingVolume: true,
}
)
);
currentTileset.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(-75.152325, 39.94704, 0)
);
const offset = new Cesium.HeadingPitchRange(
0,
Cesium.Math.toRadians(-22.5),
4.0
);
viewer.zoomTo(currentTileset, offset);
// Assign the custom shader that visualizes the feature IDs to the tileset
currentTileset.customShader = createCustomShader();
}
//============================================================================
// Sandcastle UI setup:
// Create a label that will show some information for
// the currently selected example
function createInfoTextDisplay() {
const infoTextDisplay = document.createElement("div");
infoTextDisplay.style.background = "rgba(42, 42, 42, 0.7)";
infoTextDisplay.style.padding = "5px 10px";
infoTextDisplay.style.marginTop = "5px";
return infoTextDisplay;
}
const infoTextDisplay = createInfoTextDisplay();
function setInfoText(infoText) {
infoTextDisplay.textContent = infoText;
}
// Create one entry for the list of examples that can
// be selected in the dropdown menu. Selecting one of
// these will load the tileset for the sample in the
// given directory, and display the given info text in
// the infoTextDisplay
function createSampleOption(name, directory, infoText) {
return {
text: name,
onselect: async function () {
await createTileset(directory);
setInfoText(infoText);
},
};
}
// Create the list of available samples, and add them
// to the sandcastle toolbar
const sampleOptions = [
createSampleOption(
"FeatureIdAttribute",
"glTF/EXT_mesh_features/FeatureIdAttribute",
"Feature IDs for the vertices, using a feature ID attribute"
),
createSampleOption(
"FeatureIdTexture",
"glTF/EXT_mesh_features/FeatureIdTexture",
"Feature IDs for texels, using a feature ID texture"
),
];
Sandcastle.addToolbarMenu(sampleOptions);
// Add a toggle button to the toolbar, for selecting whether
// feature IDs should be visualized. When it is selected,
// then the tileset receives the custom shader that visualizes
// the feature IDs. Otherwise, the custom shader of the tileset
// is set to 'undefined', causing it to be rendered with the
// default shader.
Sandcastle.addToggleButton("Visualize Feature IDs", true, function (checked) {
if (checked) {
currentTileset.customShader = createCustomShader();
} else {
currentTileset.customShader = undefined;
}
});
// Add the component that will dispplay the info text
// to the sandcastle toolbar
document.getElementById("toolbar").appendChild(infoTextDisplay);
Structural Metadata Example
const viewer = new Cesium.Viewer("cesiumContainer");
// Stores the tileset that is currently selected
let currentTileset;
// Stores the currently selected feature ID label, which
// is the index of `FEATURE_ID_n`
let currentActiveFeatureIdLabel = 0;
// Creates the tileset from the tileset.json in the given subdirectory
async function createTileset(subdirectory) {
if (Cesium.defined(currentTileset)) {
viewer.scene.primitives.remove(currentTileset);
currentTileset = undefined;
}
// Create the tileset, and move it to a certain position on the globe
currentTileset = viewer.scene.primitives.add(
await Cesium.Cesium3DTileset.fromUrl(
`https://raw.githubusercontent.com/CesiumGS/3d-tiles-samples/main/${subdirectory}/tileset.json`,
{
debugShowBoundingVolume: true,
}
)
);
currentTileset.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(-75.152325, 39.94704, 0)
);
const offset = new Cesium.HeadingPitchRange(
0,
Cesium.Math.toRadians(-22.5),
4.0
);
viewer.zoomTo(currentTileset, offset);
// Make sure that picking refers to the FEATURE_ID index that
// is currently selected in the UI
currentTileset.featureIdLabel = currentActiveFeatureIdLabel;
}
// Create an HTML element that will serve as the
// tooltip that displays the feature information
function createTooltip() {
const tooltip = document.createElement("div");
viewer.container.appendChild(tooltip);
tooltip.style.backgroundColor = "black";
tooltip.style.position = "absolute";
tooltip.style.left = "0";
tooltip.style.top = "0";
tooltip.style.padding = "14px";
tooltip.style["pointer-events"] = "none";
tooltip.style["block-size"] = "fit-content";
return tooltip;
}
const tooltip = createTooltip();
// Show the given HTML content in the tooltip
// at the given screen position
function showTooltip(screenX, screenY, htmlContent) {
tooltip.style.display = "block";
tooltip.style.left = `${screenX}px`;
tooltip.style.top = `${screenY}px`;
tooltip.innerHTML = htmlContent;
}
// Create an HTML string that contains information
// about the given feature, under the given title
function createFeatureHtml(title, feature) {
if (!Cesium.defined(feature)) {
return `(No ${title})<br>`;
}
const propertyKeys = feature.getPropertyIds();
if (!Cesium.defined(propertyKeys)) {
return `(No properties for ${title})<br>`;
}
let html = `<b>${title}:</b><br>`;
for (let i = 0; i < propertyKeys.length; i++) {
const propertyKey = propertyKeys[i];
const propertyValue = feature.getProperty(propertyKey);
html += ` ${propertyKey} : ${propertyValue}<br>`;
}
return html;
}
// Given an object that was obtained via Scene#pick: If it is
// a Cesium3DTileFeature, then it is returned.
// Otherwise, 'undefined' is returned.
function obtainFeature(picked) {
if (!Cesium.defined(picked)) {
return undefined;
}
const isFeature = picked instanceof Cesium.Cesium3DTileFeature;
if (!isFeature) {
return undefined;
}
return picked;
}
// Install the handler that will perform picking when the
// mouse is moved, and update the label entity when the
// mouse is over a Cesium3DTileFeature
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function (movement) {
let tooltipText = "";
const picked = viewer.scene.pick(movement.endPosition);
const feature = obtainFeature(picked);
tooltipText += createFeatureHtml("Feature", feature);
const screenX = movement.endPosition.x;
const screenY = movement.endPosition.y;
showTooltip(screenX, screenY, tooltipText);
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
//============================================================================
// Sandcastle UI setup:
// Create a label that will show some information for
// the currently selected example
function createInfoTextDisplay() {
const infoTextDisplay = document.createElement("div");
infoTextDisplay.style.background = "rgba(42, 42, 42, 0.7)";
infoTextDisplay.style.padding = "5px 10px";
infoTextDisplay.style.marginTop = "5px";
return infoTextDisplay;
}
const infoTextDisplay = createInfoTextDisplay();
function setInfoText(infoText) {
infoTextDisplay.textContent = infoText;
}
// Create one entry for the list of examples that can
// be selected in the dropdown menu. Selecting one of
// these will load the tileset for the sample in the
// given directory, and display the given info text in
// the infoTextDisplay
function createSampleOption(name, directory, infoText) {
return {
text: name,
onselect: async function () {
await createTileset(directory);
setInfoText(infoText);
},
};
}
// Create the list of available samples, and add them
// to the sandcastle toolbar
const sampleOptions = [
createSampleOption(
"FeatureIdAttributeAndPropertyTable",
"glTF/EXT_structural_metadata/FeatureIdAttributeAndPropertyTable",
"Feature IDs for vertices, based on a feature ID attribute, and a simple property table containing metadata"
),
createSampleOption(
"FeatureIdTextureAndPropertyTable",
"glTF/EXT_structural_metadata/FeatureIdTextureAndPropertyTable",
"Feature IDs for vertices, based on a feature ID texture, and a simple property table containing metadata"
),
createSampleOption(
"MultipleFeatureIdsAndProperties",
"glTF/EXT_structural_metadata/MultipleFeatureIdsAndProperties",
"A mesh primitive with two sets of feature IDs, each associated with metadata with multiple properties"
),
createSampleOption(
"SharedPropertyTable",
"glTF/EXT_structural_metadata/SharedPropertyTable",
"A mesh with two mesh primitives, each having a set of feature IDs, that refer to the same property table"
),
createSampleOption(
"MultipleClasses",
"glTF/EXT_structural_metadata/MultipleClasses",
"A mesh primitive with multiple feature ID sets that can be activated separately, and are associated with different metadata classes"
),
createSampleOption(
"ComplexTypes",
"glTF/EXT_structural_metadata/ComplexTypes",
"A mesh primitive with fetaure IDs that are associated with metadata that contains complex, structured types"
),
];
Sandcastle.addToolbarMenu(sampleOptions);
// Creates an option for selecting the active feature ID
// with the given index
function createFeatureIdSetOption(index) {
return {
text: `Active feature ID: FEATURE_ID_${index}`,
onselect: function () {
currentActiveFeatureIdLabel = index;
currentTileset.featureIdLabel = index;
},
};
}
// Create the list of available feature IDs, and add them
// to the sandcastle toolbar
const featureIdSetOptions = [
createFeatureIdSetOption(0),
createFeatureIdSetOption(1),
];
Sandcastle.addToolbarMenu(featureIdSetOptions);
// Add the component that will dispplay the info text
// to the sandcastle toolbar
document.getElementById("toolbar").appendChild(infoTextDisplay);
Property Texture Demo
const viewer = new Cesium.Viewer("cesiumContainer");
// Create the tileset, and move it to a certain position on the globe
const tileset = viewer.scene.primitives.add(
await Cesium.Cesium3DTileset.fromUrl(
`https://raw.githubusercontent.com/CesiumGS/3d-tiles-samples/main/glTF/EXT_structural_metadata/SimplePropertyTexture/tileset.json`,
{
debugShowBoundingVolume: true,
}
)
);
tileset.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(-75.152325, 39.94704, 0)
);
const offset = new Cesium.HeadingPitchRange(
0,
Cesium.Math.toRadians(-22.5),
4.0
);
viewer.zoomTo(tileset, offset);
// Create a custom (fragment) shader that accesses the metadata value with the
// given property name, normalizes it to a value in [0,1] based on the given
// source range, and uses that value as the brightness for the fragment.
function createShader(propertyName, sourceMin, sourceMax) {
const shader = new Cesium.CustomShader({
fragmentShaderText: `
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material)
{
float value = float(fsInput.metadata.${propertyName});
float range = float(${sourceMax}) - float(${sourceMin});
float brightness = (value - float(${sourceMin})) / range;
material.diffuse = vec3(brightness);
}
`,
});
return shader;
}
// Create one entry for the list of shaders that can
// be selected in the dropdown menu.
function createShaderOption(title, propertyName, sourceMin, sourceMax) {
return {
text: title,
onselect: function () {
if (!Cesium.defined(propertyName)) {
tileset.customShader = undefined;
} else {
tileset.customShader = createShader(propertyName, sourceMin, sourceMax);
}
},
};
}
const shaderOptions = [
createShaderOption("Default Shading", undefined, 0.0, 1.0),
createShaderOption("Inside Temperature", "insideTemperature", 0.0, 255.0),
createShaderOption("Outside Temperature", "outsideTemperature", 0.0, 255.0),
createShaderOption("Insulation Thickness", "insulation", 0.0, 1.0),
];
Sandcastle.addToolbarMenu(shaderOptions);
from 3dtilesrendererjs.
Related Issues (20)
- GoogleCloudAuthPlugin, CesiumIonAuthPlugin: Optionally auto refresh token when it expires HOT 2
- Couldn't load ktx2 texture HOT 9
- GlobeControls: Document why camera far is set to horizonDist * 3
- Request for Project Use Cases HOT 2
- `clock.getDelta()` sometimes returns `0` which leads to division by `0` issues HOT 3
- Testing maxByteSize does not work HOT 9
- Overfilling the cache can result in tile gaps due to eviction HOT 1
- Re-add children-in-frustum optimization HOT 2
- Tiles raycasting: Tiles at this URL is loading tall set of tiles HOT 2
- GlobeControls: Orthographic camera can get into a bad state HOT 1
- Globe Tiles: Hide tiles based on facing direction
- Quality difference between Google 3D Photorealistic Tiles and Google Maps HOT 3
- Understanding elevation (Google 3D Tiles) HOT 6
- GlobeControls: Camera can shift unexpectedly depending on ellipsoid surface orientation as camera is dragged
- Not loading tiles intersecting the camera view frustum + tile-loading performance improvements HOT 1
- Lunar tiles: loading seems to stop at boundaries HOT 1
- How to parse the scaling ratio and horizontal rotation angle of 3dtiles data HOT 3
- Automate release HOT 3
- WebGLRenderTarget not found when using with WebGPU HOT 5
- [REGRESSION] Implicit Tiling Repeating request HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from 3dtilesrendererjs.