-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Upgraded New York City b3dm tiles, but data not rendered using CesiumJS v1.113 #95
Comments
If the data set has a "reasonable" size and can be shared, then this would be good (preferably the input data set with the B3DMs, to see where the upgrade went wrong). But... the error message that you received with the original data might indicate that the data is "invalid" in one way or another. (The message looks familar, and I think that I saw this in a case where normal data was stored in a strange way (quantized into two floats, but without information about the quantization itself), but that would have to be verified...) |
Hi @javagl , I did the following:
Here are my two datasets:
Thank you for looking into this! |
There are several issues coming together here. First of all, the context is https://community.cesium.com/t/3dtiles-error-when-upgrade-cesium-to-1-97/20477/11 : CesiumJS did some internal changes that caused certain ... very old ... features of glTF 1.0 (!) to no longer be supported. This includes a special form of
error. The Now... the glTF 2.0 data that is created by This can be fixed, with a special processing step. And I created a short script for that, locally. But... there's another caveat: There's a small bug in the B3DM metadata conversion. This is fixed via #96 So the upgrade path for now is a bit clumsy:
After that, the data can be loaded and shown in CesiumJS: We'll consider
There are some aspects that still have to be decided This is the script for "fixing" the upgraded tileset, to no longer contain the invalid normals. This is only quickly written down. No warranties. Just added here for completeness. import { Document } from "@gltf-transform/core";
import { Accessor } from "@gltf-transform/core";
import { prune } from "@gltf-transform/functions";
import { TileContentProcessing } from "@3d-tiles-tools/tools";
import { TileContentProcessorsGltfTransform } from "@3d-tiles-tools/tools";
// "Ported" from CesiumJS octDecode.glsl
function octDecode(encoded: number[], range: number): number[] {
let x = encoded[0];
let y = encoded[1];
if (x === 0.0 && y === 0.0) {
return [0.0, 0.0, 1.0]; // Unit-length
}
x = (x / range) * 2.0 - 1.0;
y = (y / range) * 2.0 - 1.0;
const v = [x, y, 1.0 - Math.abs(x) - Math.abs(y)];
if (v[2] < 0.0) {
v[0] = (1.0 - Math.abs(v[0])) * (v[0] >= 0.0 ? 1.0 : -1.0);
v[1] = (1.0 - Math.abs(v[1])) * (v[1] >= 0.0 ? 1.0 : -1.0);
}
const len = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
const invLen = 1.0 / len;
v[0] *= invLen;
v[1] *= invLen;
v[2] *= invLen;
return v;
}
function octDecodeAccessor(
document: Document,
encodedAccessor: Accessor,
range: number
) {
const decodedData: number[] = [];
const count = encodedAccessor.getCount();
for (let i = 0; i < count; i++) {
const encoded = [0, 0];
encodedAccessor.getElement(i, encoded);
const decoded = octDecode(encoded, range);
decodedData.push(...decoded);
}
const decodedAccessor = document.createAccessor();
decodedAccessor.setType("VEC3");
decodedAccessor.setArray(new Float32Array(decodedData));
return decodedAccessor;
}
async function runConversion() {
const tilesetSourceName =
"D:/Data/NewYork-upgraded/tileset.json";
const tilesetTargetName =
"D:/Data/NewYork-upgraded-fixed/tileset.json";
const overwrite = true;
const transform = (document: Document) => {
const root = document.getRoot();
const meshes = root.listMeshes();
for (const mesh of meshes) {
const primitives = mesh.listPrimitives();
for (const primitive of primitives) {
const normalAccessor = primitive.getAttribute("NORMAL");
if (normalAccessor) {
const type = normalAccessor.getType();
const componentType = normalAccessor.getComponentType();
const GL_BYTE = 5120;
const GL_SHORT = 5122;
if (type === "VEC2" && componentType === GL_BYTE) {
console.log("Decoding BYTE normals...");
const decodedNormalsAccessor = octDecodeAccessor(
document,
normalAccessor,
255.0
);
primitive.setAttribute("NORMAL", decodedNormalsAccessor);
} else if (type === "VEC2" && componentType === GL_SHORT) {
console.log("Decoding SHORT normals...");
const decodedNormalsAccessor = octDecodeAccessor(
document,
normalAccessor,
65535.0
);
primitive.setAttribute("NORMAL", decodedNormalsAccessor);
}
}
}
}
};
const tileContentProcessor = TileContentProcessorsGltfTransform.create(
transform,
prune()
);
await TileContentProcessing.process(
tilesetSourceName,
tilesetTargetName,
overwrite,
tileContentProcessor
);
}
runConversion(); |
Hi @javagl , thank you so much for the quick fix! I tried to run your code after putting it into folder 3d-tiles-tools/src/fixup.ts (I had edited the in/out file paths accordingly), but got below error: My commandline was: I must have missed something since I am not familiar with NodeJS/TS. Could you please tell me how to run your code to fix the upgraded data? Or you put the fixed data somewhere so I can download it? Thank you for your assistance! |
The script is based on the branch behind #96 (An aside: There has been a refactoring for the 3D Tiles Tools, to break it into smaller packages. This is not merged yet, but should be merged in the next few days, so the bugfix in this PR is already based on this refactored state) In order to check out this branch and use it locally, you'll have to do go into that directory with EDIT: NOTE That you'll also have to re-run the I just put the It should then not be necessary to edit any config files or so. Running (If it doesn't work (then I'd be curious about the error messages, and), I'll try to upload the resulting data, but will have to ask internally where/how I may do that) |
Thank you @javagl for the quick response. |
Hm. I tried out out locally while writing that answer. I'll try it again and look into it. |
I just tried out the process that you went through, namely doing the Deleting the |
Great. Now, another small disclaimer: This "fixup" was a first shot. I tried the tileset in the latest version of CesiumJS, and it appeared to work, but if there is any problem with it (that I didn't notice yet), just drop a note here. |
Yes, I will. I will try to display the new dataset with (Using the latest CesiumJS version, i.e., v1.113, breaks our code, because Will update you (either all works or I get questions). Thank you @javagl for your prompt response and your professionalism is very impressive!! |
Hi @javagl , this is to confirm that the upgraded dataset works like a charm in our App (using CesiumJS v1.106.1): In a separate standalone test, it also works nicely using CesiumJS v1.113. Thank you again for your great help!! |
Great. I assume that this can be closed then. Feel free to reopen (or open a new issue) if necessary. |
Yes, the issue is resolved! Thank you! |
When using CesiumJS v1.113 for New York City b3dm dataset, I ran into this issue:
Then I used this tool and upgraded the dataset with this command:
npx ts-node src/main.ts upgrade -i ..\\NewYork\\tileset.json -o ..\\upgradedNY --targetVersion 1.1
The RuntimeError is gone, glb tiles are fetched, but no 3d buildings rendered on the map.
Below is my code (if you need the dataset, please let me know):
`
`
The text was updated successfully, but these errors were encountered: