Flatlogic Bot 055d24df95 WORKING
2025-10-14 02:37:44 +00:00

224 lines
7.7 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
/>
<meta name="description" content="For debugging voxel picking." />
<meta name="cesium-sandcastle-labels" content="Showcases, 3D Tiles" />
<title>Cesium Demo</title>
<script type="text/javascript" src="../Sandcastle-header.js"></script>
<script type="module" src="../load-cesium-es6.js"></script>
</head>
<body
class="sandcastle-loading"
data-sandcastle-bucket="bucket-requirejs.html"
>
<style>
@import url(../templates/bucket.css);
#pickReport {
background-color: rgba(0, 0, 0, 0.5);
}
#pickedCoordinate {
display: inline-block;
padding: 1ch 1ch 1ch 3ch;
}
#pickedColor {
display: inline-block;
width: 1em;
height: 1em;
background-color: white;
margin-left: 1ch;
}
</style>
<div id="cesiumContainer" class="fullSize"></div>
<div id="loadingOverlay"><h1>Loading...</h1></div>
<div id="toolbar">
<div id="pickReport">
<div id="pickedCoordinate">Sample center</div>
<div id="pickedColor"></div>
</div>
</div>
<script id="cesium_sandcastle_script">
window.startup = async function (Cesium) {
"use strict";
//Sandcastle_Begin
const viewer = new Cesium.Viewer("cesiumContainer", {
baseLayer: Cesium.ImageryLayer.fromProviderAsync(
Cesium.TileMapServiceImageryProvider.fromUrl(
Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII")
)
),
baseLayerPicker: false,
geocoder: false,
timeline: false,
animation: false,
});
const { scene, camera } = viewer;
scene.debugShowFramesPerSecond = true;
const scratchColor = new Cesium.Color();
function ProceduralMultiTileVoxelProvider(shape) {
this.shape = shape;
this.dimensions = new Cesium.Cartesian3(4, 4, 4);
this.names = ["color"];
this.types = [Cesium.MetadataType.VEC4];
this.componentTypes = [Cesium.MetadataComponentType.FLOAT32];
this._levelCount = 3;
}
ProceduralMultiTileVoxelProvider.prototype.requestData = function (
options
) {
const { tileLevel, tileX, tileY, tileZ } = options;
if (tileLevel >= this._levelCount) {
return undefined;
}
const dimensions = this.dimensions;
const type = this.types[0];
const randomSeed =
tileZ * dimensions.y * dimensions.x + tileY * dimensions.x + tileX;
const dataTile = constructRandomTileData(
dimensions,
type,
randomSeed
);
return Promise.resolve([dataTile]);
};
function constructRandomTileData(dimensions, type, randomSeed) {
Cesium.Math.setRandomNumberSeed(randomSeed);
const voxelCount = dimensions.x * dimensions.y * dimensions.z;
const channelCount = Cesium.MetadataType.getComponentCount(type);
const dataColor = new Float32Array(voxelCount * channelCount);
for (let z = 0; z < dimensions.z; z++) {
const indexZ = z * dimensions.y * dimensions.x;
for (let y = 0; y < dimensions.y; y++) {
const indexZY = indexZ + y * dimensions.x;
for (let x = 0; x < dimensions.x; x++) {
const lerperX = x / (dimensions.x - 1);
const lerperY = y / (dimensions.y - 1);
const lerperZ = z / (dimensions.z - 1);
const h = Cesium.Math.nextRandomNumber();
const s = 1.0 - lerperY * 0.2;
const l = 0.5;
const color = Cesium.Color.fromHsl(h, s, l, 1.0, scratchColor);
const random2 = Cesium.Math.nextRandomNumber();
const alphaRandom = Math.floor(random2 + 0.5);
const index = (indexZY + x) * channelCount;
dataColor[index + 0] = color.red;
dataColor[index + 1] = color.green;
dataColor[index + 2] = color.blue;
dataColor[index + 3] = alphaRandom;
}
}
}
return dataColor;
}
const provider = new ProceduralMultiTileVoxelProvider(
Cesium.VoxelShapeType.BOX
);
const customShader = new Cesium.CustomShader({
fragmentShaderText: `void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material)
{
vec3 voxelNormal = normalize(czm_normal * fsInput.voxel.surfaceNormal);
float diffuse = max(0.0, dot(voxelNormal, czm_lightDirectionEC));
float lighting = 0.5 + 0.5 * diffuse;
int tileIndex = fsInput.voxel.tileIndex;
int sampleIndex = fsInput.voxel.sampleIndex;
vec3 cellColor = fsInput.metadata.color.rgb * lighting;
if (tileIndex == u_selectedTile && sampleIndex == u_selectedSample) {
material.diffuse = mix(cellColor, vec3(1.0), 0.5);
material.alpha = fsInput.metadata.color.a;
} else {
material.diffuse = cellColor;
material.alpha = fsInput.metadata.color.a;
}
}`,
uniforms: {
u_selectedTile: {
type: Cesium.UniformType.INT,
value: -1.0,
},
u_selectedSample: {
type: Cesium.UniformType.INT,
value: -1.0,
},
},
});
const modelMatrix = Cesium.Matrix4.fromScale(
Cesium.Cartesian3.fromElements(
Cesium.Ellipsoid.WGS84.maximumRadius,
Cesium.Ellipsoid.WGS84.maximumRadius,
Cesium.Ellipsoid.WGS84.maximumRadius
)
);
const voxelPrimitive = scene.primitives.add(
new Cesium.VoxelPrimitive({
provider: provider,
customShader: customShader,
modelMatrix: modelMatrix,
})
);
voxelPrimitive.nearestSampling = true;
camera.flyToBoundingSphere(voxelPrimitive.boundingSphere, {
duration: 0.0,
});
const handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
const pickedCoordinate = document.getElementById("pickedCoordinate");
const pickedColor = document.getElementById("pickedColor");
handler.setInputAction(function (movement) {
const mousePosition = movement.endPosition;
const voxelCell = scene.pickVoxel(mousePosition);
if (!Cesium.defined(voxelCell)) {
return;
}
const { tileIndex, sampleIndex, orientedBoundingBox } = voxelCell;
const [x, y, z] = Object.values(orientedBoundingBox.center).map(
Math.round
);
pickedCoordinate.innerHTML = `Sample center x = ${x}, y = ${y}, z = ${z}`;
const rgbaValues = voxelCell.getProperty("color");
const color = new Cesium.Color(...rgbaValues);
pickedColor.style.backgroundColor = color.toCssColorString();
const { customShader } = voxelCell.primitive;
customShader.setUniform("u_selectedTile", tileIndex);
customShader.setUniform("u_selectedSample", sampleIndex);
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
//Sandcastle_End
Sandcastle.finishedLoading();
};
if (typeof Cesium !== "undefined") {
window.startupCalled = true;
window.startup(Cesium).catch((error) => {
"use strict";
console.error(error);
});
}
</script>
</body>
</html>