-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Inspector v2: GLTF Import tools #17580
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
Merged
alexchuber
merged 23 commits into
BabylonJS:master
from
alexchuber:inspector-v2-import-tools
Jan 27, 2026
Merged
Changes from 10 commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
604286e
Make MessageBar title/message optional
alexchuber cf332d7
Update author and leave note
alexchuber ea859ad
Add GLTF tools (settings, validator) to Import Tools
alexchuber 5f7abe7
Refactor
alexchuber 70004e5
Fix validation results being discarded whenever Inspector is recreated
alexchuber d937a5e
Nits for validation tool
alexchuber 30e0d55
Move validationResult state to GLTFValidation
alexchuber 8a0a1c6
Lazy initialize results history
alexchuber 5cb4f79
Simplify loader options state mgmt
alexchuber e6880ea
Naming & comment nits
alexchuber d56f476
Add "indentExpandedContent" option to ExpandableProperty props
alexchuber 8fc86ac
Missed a spot for indentExpandedContent
alexchuber 12f2d6e
Loop through extensionOptions to create components
alexchuber 05fc2f8
Use child window for glTF validation results
alexchuber 27da23d
Fix MessageBar optional props
alexchuber ebca3fa
Keep all weird GLTFValidation statics internal
alexchuber c7f4fee
Simplify lo-fi GLTFValidation solution
alexchuber 36f03d4
Forgot to remove import
alexchuber a95bcae
Merge branch 'master' of https://github.com/BabylonJS/Babylon.js into…
alexchuber 0523353
Merge remote-tracking branch 'origin/master' into inspector-v2-import…
ryantrem 9fb6e8b
Use ChildWindow
ryantrem 68d853e
Use GLTFLoaderDefaultOptions
ryantrem 6192840
Merge remote-tracking branch 'origin/master' into inspector-v2-import…
ryantrem File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
173 changes: 173 additions & 0 deletions
173
packages/dev/inspector-v2/src/components/tools/import/gltfLoaderOptionsTool.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,173 @@ | ||
| import type { FunctionComponent } from "react"; | ||
| import { GLTFLoaderCoordinateSystemMode, GLTFLoaderAnimationStartMode } from "loaders/glTF/glTFFileLoader"; | ||
| import type { DropdownOption } from "shared-ui-components/fluent/primitives/dropdown"; | ||
| import { SwitchPropertyLine } from "shared-ui-components/fluent/hoc/propertyLines/switchPropertyLine"; | ||
| import { NumberDropdownPropertyLine } from "shared-ui-components/fluent/hoc/propertyLines/dropdownPropertyLine"; | ||
| import { SyncedSliderPropertyLine } from "shared-ui-components/fluent/hoc/propertyLines/syncedSliderPropertyLine"; | ||
| import type { GLTFExtensionOptionsType, GLTFLoaderOptionsType } from "../../../services/panes/tools/import/gltfLoaderOptionsService"; | ||
| import { PropertyLine } from "shared-ui-components/fluent/hoc/propertyLines/propertyLine"; | ||
| import { tokens } from "@fluentui/react-components"; | ||
| import { BoundProperty } from "../../properties/boundProperty"; | ||
|
|
||
| const AnimationStartModeOptions: DropdownOption<number>[] = [ | ||
| { label: "None", value: GLTFLoaderAnimationStartMode.NONE }, | ||
| { label: "First", value: GLTFLoaderAnimationStartMode.FIRST }, | ||
| { label: "All", value: GLTFLoaderAnimationStartMode.ALL }, | ||
| ]; | ||
|
|
||
| const CoordinateSystemModeOptions: DropdownOption<number>[] = [ | ||
| { label: "Auto", value: GLTFLoaderCoordinateSystemMode.AUTO }, | ||
| { label: "Right Handed", value: GLTFLoaderCoordinateSystemMode.FORCE_RIGHT_HANDED }, | ||
| ]; | ||
|
|
||
| export const GLTFLoaderOptionsTool: FunctionComponent<{ | ||
| loaderOptions: GLTFLoaderOptionsType; | ||
| }> = ({ loaderOptions }) => { | ||
| return ( | ||
| <PropertyLine | ||
| label="Loader Options" | ||
| expandByDefault={false} | ||
| expandedContent={ | ||
| <div style={{ paddingLeft: tokens.spacingHorizontalM }}> | ||
| <BoundProperty component={SwitchPropertyLine} label="Always compute bounding box" target={loaderOptions} propertyKey="alwaysComputeBoundingBox" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="Always compute skeleton root node" target={loaderOptions} propertyKey="alwaysComputeSkeletonRootNode" /> | ||
| <BoundProperty | ||
| component={NumberDropdownPropertyLine} | ||
| label="Animation start mode" | ||
| options={AnimationStartModeOptions} | ||
| target={loaderOptions} | ||
| propertyKey="animationStartMode" | ||
| /> | ||
| <BoundProperty component={SwitchPropertyLine} label="Capture performance counters" target={loaderOptions} propertyKey="capturePerformanceCounters" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="Compile materials" target={loaderOptions} propertyKey="compileMaterials" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="Compile shadow generators" target={loaderOptions} propertyKey="compileShadowGenerators" /> | ||
| <BoundProperty | ||
| component={NumberDropdownPropertyLine} | ||
| label="Coordinate system" | ||
| options={CoordinateSystemModeOptions} | ||
| target={loaderOptions} | ||
| propertyKey="coordinateSystemMode" | ||
| /> | ||
| <BoundProperty component={SwitchPropertyLine} label="Create instances" target={loaderOptions} propertyKey="createInstances" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="Enable logging" target={loaderOptions} propertyKey="loggingEnabled" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="Load all materials" target={loaderOptions} propertyKey="loadAllMaterials" /> | ||
| <BoundProperty component={SyncedSliderPropertyLine} label="Target FPS" target={loaderOptions} propertyKey="targetFps" min={1} max={120} step={1} /> | ||
| <BoundProperty component={SwitchPropertyLine} label="Transparency as coverage" target={loaderOptions} propertyKey="transparencyAsCoverage" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="Use clip plane" target={loaderOptions} propertyKey="useClipPlane" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="Use sRGB buffers" target={loaderOptions} propertyKey="useSRGBBuffers" /> | ||
| </div> | ||
| } | ||
| /> | ||
| ); | ||
| }; | ||
|
|
||
| export const GLTFExtensionOptionsTool: FunctionComponent<{ | ||
| extensionOptions: GLTFExtensionOptionsType; | ||
| }> = ({ extensionOptions }) => { | ||
| return ( | ||
| <PropertyLine | ||
| label="Extension Options" | ||
| expandByDefault={false} | ||
| expandedContent={ | ||
| <div style={{ paddingLeft: tokens.spacingHorizontalM }}> | ||
| <BoundProperty | ||
|
alexchuber marked this conversation as resolved.
Outdated
|
||
| label="EXT_lights_image_based" | ||
| component={SwitchPropertyLine} | ||
| key="EXT_lights_image_based_enabled" | ||
| target={extensionOptions["EXT_lights_image_based"]} | ||
|
alexchuber marked this conversation as resolved.
Outdated
|
||
| propertyKey="enabled" | ||
| /> | ||
| <BoundProperty | ||
| label="EXT_mesh_gpu_instancing" | ||
| component={SwitchPropertyLine} | ||
| key="EXT_mesh_gpu_instancing_enabled" | ||
| target={extensionOptions["EXT_mesh_gpu_instancing"]} | ||
| propertyKey="enabled" | ||
| /> | ||
| <BoundProperty component={SwitchPropertyLine} label="EXT_texture_webp" target={extensionOptions["EXT_texture_webp"]} propertyKey="enabled" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="EXT_texture_avif" target={extensionOptions["EXT_texture_avif"]} propertyKey="enabled" /> | ||
| <BoundProperty | ||
| component={SwitchPropertyLine} | ||
| label="KHR_draco_mesh_compression" | ||
| target={extensionOptions["KHR_draco_mesh_compression"]} | ||
| propertyKey="enabled" | ||
| /> | ||
| <BoundProperty | ||
| component={SwitchPropertyLine} | ||
| label="KHR_materials_pbrSpecularGlossiness" | ||
| target={extensionOptions["KHR_materials_pbrSpecularGlossiness"]} | ||
| propertyKey="enabled" | ||
| /> | ||
| <BoundProperty component={SwitchPropertyLine} label="KHR_materials_clearcoat" target={extensionOptions["KHR_materials_clearcoat"]} propertyKey="enabled" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="KHR_materials_iridescence" target={extensionOptions["KHR_materials_iridescence"]} propertyKey="enabled" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="KHR_materials_anisotropy" target={extensionOptions["KHR_materials_anisotropy"]} propertyKey="enabled" /> | ||
| <BoundProperty | ||
| component={SwitchPropertyLine} | ||
| label="KHR_materials_emissive_strength" | ||
| target={extensionOptions["KHR_materials_emissive_strength"]} | ||
| propertyKey="enabled" | ||
| /> | ||
| <BoundProperty component={SwitchPropertyLine} label="KHR_materials_ior" target={extensionOptions["KHR_materials_ior"]} propertyKey="enabled" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="KHR_materials_sheen" target={extensionOptions["KHR_materials_sheen"]} propertyKey="enabled" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="KHR_materials_specular" target={extensionOptions["KHR_materials_specular"]} propertyKey="enabled" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="KHR_materials_unlit" target={extensionOptions["KHR_materials_unlit"]} propertyKey="enabled" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="KHR_materials_variants" target={extensionOptions["KHR_materials_variants"]} propertyKey="enabled" /> | ||
| <BoundProperty | ||
| component={SwitchPropertyLine} | ||
| key="KHR_materials_transmission" | ||
| label="KHR_materials_transmission" | ||
| target={extensionOptions["KHR_materials_transmission"]} | ||
| propertyKey="enabled" | ||
| /> | ||
| <BoundProperty | ||
| component={SwitchPropertyLine} | ||
| label="KHR_materials_diffuse_transmission" | ||
| target={extensionOptions["KHR_materials_diffuse_transmission"]} | ||
| propertyKey="enabled" | ||
| /> | ||
| <BoundProperty | ||
| component={SwitchPropertyLine} | ||
| key="KHR_materials_volume" | ||
| label="KHR_materials_volume" | ||
| target={extensionOptions["KHR_materials_volume"]} | ||
| propertyKey="enabled" | ||
| /> | ||
| <BoundProperty | ||
| component={SwitchPropertyLine} | ||
| key="KHR_materials_dispersion" | ||
| label="KHR_materials_dispersion" | ||
| target={extensionOptions["KHR_materials_dispersion"]} | ||
| propertyKey="enabled" | ||
| /> | ||
| <BoundProperty | ||
| component={SwitchPropertyLine} | ||
| label="KHR_materials_diffuse_roughness" | ||
| target={extensionOptions["KHR_materials_diffuse_roughness"]} | ||
| propertyKey="enabled" | ||
| /> | ||
| <BoundProperty component={SwitchPropertyLine} label="KHR_mesh_quantization" target={extensionOptions["KHR_mesh_quantization"]} propertyKey="enabled" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="KHR_lights_punctual" target={extensionOptions["KHR_lights_punctual"]} propertyKey="enabled" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="EXT_lights_area" target={extensionOptions["EXT_lights_area"]} propertyKey="enabled" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="KHR_texture_basisu" target={extensionOptions["KHR_texture_basisu"]} propertyKey="enabled" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="KHR_texture_transform" target={extensionOptions["KHR_texture_transform"]} propertyKey="enabled" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="KHR_xmp_json_ld" target={extensionOptions["KHR_xmp_json_ld"]} propertyKey="enabled" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="MSFT_lod" target={extensionOptions["MSFT_lod"]} propertyKey="enabled" /> | ||
| <div style={{ paddingLeft: tokens.spacingHorizontalM }}> | ||
| <BoundProperty | ||
| component={SyncedSliderPropertyLine} | ||
| label="Maximum LODs" | ||
| target={extensionOptions["MSFT_lod"]} | ||
| propertyKey="maxLODsToLoad" | ||
| min={1} | ||
| max={10} | ||
| step={1} | ||
| /> | ||
| </div> | ||
| <BoundProperty component={SwitchPropertyLine} label="MSFT_minecraftMesh" target={extensionOptions["MSFT_minecraftMesh"]} propertyKey="enabled" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="MSFT_sRGBFactors" target={extensionOptions["MSFT_sRGBFactors"]} propertyKey="enabled" /> | ||
| <BoundProperty component={SwitchPropertyLine} label="MSFT_audio_emitter" target={extensionOptions["MSFT_audio_emitter"]} propertyKey="enabled" /> | ||
| </div> | ||
| } | ||
| /> | ||
| ); | ||
| }; | ||
40 changes: 40 additions & 0 deletions
40
packages/dev/inspector-v2/src/components/tools/import/gltfValidationTool.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| import { useCallback } from "react"; | ||
| import type { FunctionComponent } from "react"; | ||
| import { ButtonLine } from "shared-ui-components/fluent/hoc/buttonLine"; | ||
| import { StringifiedPropertyLine } from "shared-ui-components/fluent/hoc/propertyLines/stringifiedPropertyLine"; | ||
| import { MessageBar } from "shared-ui-components/fluent/primitives/messageBar"; | ||
| import type { IGLTFValidationResults } from "babylonjs-gltf2interface"; | ||
|
|
||
| export const GLTFValidationTool: FunctionComponent<{ validationResults: IGLTFValidationResults }> = ({ validationResults }) => { | ||
| const openValidationDetails = useCallback(() => { | ||
|
ryantrem marked this conversation as resolved.
Outdated
|
||
| const win = window.open("", "_blank"); | ||
| if (win) { | ||
| // TODO: format this better and use generator registry (https://github.com/KhronosGroup/glTF-Generator-Registry) | ||
|
ryantrem marked this conversation as resolved.
Outdated
|
||
| win.document.title = `${validationResults.uri} - glTF Validation Results`; | ||
| win.document.body.style.backgroundColor = "#322e2eff"; | ||
| win.document.body.style.color = "#fff"; | ||
| win.document.body.style.padding = "1rem"; | ||
| const pre = win.document.createElement("pre"); | ||
| const code = win.document.createElement("code"); | ||
| const textNode = win.document.createTextNode(JSON.stringify(validationResults, null, 2)); | ||
| code.append(textNode); | ||
| pre.append(code); | ||
| win.document.body.append(pre); | ||
| win.focus(); | ||
| } | ||
| }, [validationResults]); | ||
|
|
||
| const issues = validationResults.issues; | ||
| const hasErrors = issues.numErrors > 0; | ||
|
|
||
| return ( | ||
| <> | ||
| <MessageBar intent={hasErrors ? "error" : "success"} message={hasErrors ? "Your file has validation issues" : "Your file is a valid glTF file"} /> | ||
| <StringifiedPropertyLine key="NumErrors" label="Errors" value={issues.numErrors} /> | ||
| <StringifiedPropertyLine key="NumWarnings" label="Warnings" value={issues.numWarnings} /> | ||
| <StringifiedPropertyLine key="NumInfos" label="Infos" value={issues.numInfos} /> | ||
| <StringifiedPropertyLine key="NumHints" label="Hints" value={issues.numHints} /> | ||
| <ButtonLine label="View Report Details" onClick={openValidationDetails} /> | ||
| </> | ||
| ); | ||
| }; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
packages/dev/inspector-v2/src/services/panes/tools/import/gltfAnimationImportService.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| import type { ServiceDefinition } from "../../../../modularity/serviceDefinition"; | ||
| import { ToolsServiceIdentity } from "../../toolsService"; | ||
| import type { IToolsService } from "../../toolsService"; | ||
| import { GLTFAnimationImportTool } from "../../../../components/tools/import/gltfAnimationImportTool"; | ||
|
|
||
| export const GLTFAnimationImportServiceDefinition: ServiceDefinition<[], [IToolsService]> = { | ||
| friendlyName: "GLTF Animation Import", | ||
| consumes: [ToolsServiceIdentity], | ||
| factory: (toolsService) => { | ||
| const contentRegistration = toolsService.addSectionContent({ | ||
| key: "AnimationImport", | ||
| order: 40, | ||
| section: "GLTF Animation Import", | ||
| component: ({ context }) => <GLTFAnimationImportTool scene={context} />, | ||
| }); | ||
|
|
||
| return { | ||
| dispose: () => { | ||
| contentRegistration.dispose(); | ||
| }, | ||
| }; | ||
| }, | ||
| }; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.