-
Notifications
You must be signed in to change notification settings - Fork 46
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
glTF model references separate files but no resourceDirectory is supplied
Error when upgrading legacy 3d tiles
#109
Comments
A few first analysis steps: 1. The error message is indeed coming from However, this can be solved by passing in the 2.. But... There seems to be something wrong with one of the input B3DMs. All of them seem to use a really old legacy version of B3DM. And that's ... "ok-ish". The upgrade should be capable of handling exactly that. But the 3. The bounding volume is waaay off Loading the original (legacy) tileset in CesiumJS and showing the bounding volume gives this: The fact that the content is not contained in the bounding volume will cause all sorts of rendering glitches, eventually. And ... this is not fixed via the There are some potential options for fixing the bounding volumes. But for now, this would only be a quick workaround for something that could/should be addressed more holistically via something like #106 |
@javagl is it possible for 3d-tiles-tools to internally pass through |
EDIT: Maybe I misunderstood this. Maybe you meant to always pass the @lilleyse It does pass through the It does not (yet?) pass it through when the |
Yes, that's what I was suggesting |
Yeah, this might be doable, but ... may be a bit awkward, and often not make sense. Literally none of the code works with "files". It obtains a (We might consider changing the So .... it might be technically possible, for the case of input files .... the question is then rather: Can it be implemented in a form that isn't toooo ugly. |
Thank you so much for the details! I'll try it out on Monday when I have access to my work computer with other models. We have very old and off-specification 3d tiles and people who write the generators didn't try to upgrade them. Sigh. I'll inform them about the bounding volume bug. It's a relief the tool works on our model (I tested it on the test tiles I uploaded). I appreciate you guys' work. |
If there are any problems with the other/full models (beyond the root B3DM file, which apparently is ~"broken"), then just drop a note here, preferably with further infos and maybe example data. Even when the |
@javagl I tried the workaround with a full 3d tiles model, and sadly, that didn't work. I have to pass
I seems like this kind of problem can only be solved by the |
I see. When there are multiple B3DM files in different subdirectories, and each of them would require a different (I'm more and more strongly considering to just open a PR into I'll have a close look at the example that you attached ASAP, and ...
|
I had a short look at the latest attachment. It still seems to have a structure that could be processed with the I therefore tried to create a test data set, based on the initial one, where I just moved two of the tiles into Now, as I said, it should be possble to do the update manually, with a small workaround script. Based on the current state of the It essentially does what is usually done by the The upgrade of the The upgrade of the B3DM files is "carved out", into a (Note: Adjust the import path from "path";
import { ContentDataTypes } from "./src/base";
import { Tileset } from "./src/structure";
import { Schema } from "./src/structure";
import { TilesetEntry } from "./src/tilesets";
import { BasicTilesetProcessor } from "./src/tools/tilesetProcessing/BasicTilesetProcessor";
import { TilesetObjectUpgrader } from "./src/tools/tilesetProcessing/upgrade/TilesetObjectUpgrader";
import { TilesetUpgradeOptions } from "./src/tools/tilesetProcessing/upgrade/TilesetUpgradeOptions";
import { ContentUpgrades } from "./src/tools/contentProcessing/ContentUpgrades";
const sourceDirectoryRoot = "D:/manual/";
const targetDirectoryRoot = "D:/manual-out/";
const sourceName = path.resolve(sourceDirectoryRoot, "tileset.json");
const targetName = path.resolve(targetDirectoryRoot, "tileset.json");
// Process a single entry of the input. This is called for all files
// of the input tileset that appear as content URI.
//
// The 'sourceEntry' a structure with these properties:
// - key: string // The name of the content, like "/example/tile.b3dm"
// - value: Buffer // The content of that file, as a buffer
//
// The 'type' is one of the strings defined in 'ContentDataTypes'.
//
// The function returns a 'target entry', which contains
// - key: string // The same as the source entry key
// - value: Buffer // The upgraded file contents
//
// For most file types, the target entry will be the same as the
// source entry. ONLY for B3DM files, the target entry value
// will be a buffer that contains the upgraded B3DM data.
//
const processEntry = async (
sourceEntry: TilesetEntry,
type: string | undefined
) => {
// All files except for B3DM files remain unmodified
if (type !== ContentDataTypes.CONTENT_TYPE_B3DM) {
return sourceEntry;
}
// For B3DM files, determine the 'resourceDirectory' for
// the gltf-pipeline, based on the source root directory
// and the (relative) path that of the URI that points
// to the B3DM
const b3dmPath = path.resolve(sourceDirectoryRoot, sourceEntry.key);
const b3dmDir = path.dirname(b3dmPath);
const gltfUpgradeOptions = {
resourceDirectory: b3dmDir,
};
console.log(
"Upgrade " + sourceEntry.key + " with resource directory " + b3dmDir
);
const targetValue = await ContentUpgrades.upgradeB3dmGltf1ToGltf2(
sourceEntry.value,
gltfUpgradeOptions
);
return {
key: sourceEntry.key,
value: targetValue,
};
};
async function run(tilesetSourceName: string, tilesetTargetName: string) {
const overwrite = true;
const processExternalTilesets = true;
const tilesetProcessor = new BasicTilesetProcessor(processExternalTilesets);
await tilesetProcessor.begin(tilesetSourceName, tilesetTargetName, overwrite);
// The default options for the upgrade. (These mainly
// refer to the tileset JSON upgrades)
const upgradeOptions: TilesetUpgradeOptions = {
upgradeExternalTilesets: true,
upgradedAssetVersionNumber: "1.0",
upgradeRefineCase: true,
upgradeContentUrlToUri: true,
upgradeEmptyChildrenToUndefined: true,
upgradeContentGltfExtensionDeclarations: false,
upgradeB3dmGltf1ToGltf2: true,
upgradeI3dmGltf1ToGltf2: true,
upgradePntsToGlb: false,
upgradeB3dmToGlb: false,
upgradeI3dmToGlb: false,
};
// Perform theu upgrade of the tileset JSON with the default options
await tilesetProcessor.forTileset(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async (tileset: Tileset, schema: Schema | undefined) => {
const tilesetObjectUpgrader = new TilesetObjectUpgrader(upgradeOptions);
await tilesetObjectUpgrader.upgradeTilesetObject(tileset);
return tileset;
}
);
// Process all entries (files) in the input that are
// considered to be "tile content". In "processEntry",
// only B3DM files will be considered
await tilesetProcessor.processTileContentEntries(
(uri: string) => uri,
processEntry
);
await tilesetProcessor.end();
}
run(sourceName, targetName); When running this locally, based on the test data, then the output is something like
showing that it seems to pick up the right So if this works in principle, we can think about how to make this part of the standard (Technically, this should be easy, but this snippet uses the global |
I run the script and an I set the I'll have a deeper look at the error and send you a feedback tomorrow. |
From the message, a first debugging step could be to either insert a log like
or run it in a debugger. (If you can share data where the error happens, I can have another look as well) |
Sorry for the late reply. I was quite busy yesterday. I found out the error occured because of Thanks a lot for the help. |
That's a bit surprising: There is a flag for that, |
As I said above: The cases where a Two steps for analyzing that further could be: One could add
(I have to check whether this might not work as expected in the case of external tilesets. These should just undergo the same upgrade process, but maybe there's a corner case that is not considered) The other step (already mentioned above) would be to add the log statement at
and if this receives |
Command:
3d-tiles-tools upgrade -i ./tiles/tileset.json -o output -f
Error:
ERROR (upgrade): Failed to upgrade Tile_+000_+000_+000_L20_00000.b3dm: RuntimeError: glTF model references separate files but no resourceDirectory is supplied
test tiles
I tried to read the source code and found out the error is thrown by
gltf-pipeline
code. Theoptions
param doesn't have aresourceDirectory
field so the program don't know where to find the separated shader and image files. I don't know how to fix it though.The text was updated successfully, but these errors were encountered: