Commit Graph

3129 Commits

Author SHA1 Message Date
Syoyo Fujita
01df70a7ce Add async WASM support: Asyncify, JSPI, and C++20 coroutines
- Add LIGHTUSD_WASM_ASYNCIFY option for universal async JS calls
- Add LIGHTUSD_WASM_JSPI option for efficient WebAssembly stack switching
  (Chrome 109+, Firefox 121+, Safari behind flag)
- Add LIGHTUSD_COROUTINE option for C++20 coroutine API
- Create async_fetch.hh/cc with sync-style fetch using Asyncify/JSPI
- Create coro_fetch.hh with Task<T>, FetchAwaiter, and Generator<T>
- Add asyncify-imports.js and jspi-imports.js for JS glue code
- Fix StreamingLoader message serialization (5 TODOs)
- Add Mat4 rotation methods and xformOp transform extraction
- Update TypeScript declarations for async fetch support

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 06:51:10 +09:00
Syoyo Fujita
21da2d7e45 Add USDZ support and progressive loading for LightUSD WASM
Implements two major features for LightUSD WebAssembly builds:

1. USDZ Archive Support:
   - Hand-written ZIP parser (uncompressed, 64-byte aligned)
   - UsdzArchive class for reading assets from USDZ files
   - Asset resolution callbacks compatible with TinyUSDZ
   - High-level load_usdz() and usdz_to_render_scene() APIs

2. Progressive/Streaming Loader:
   - Two-phase loading: structure first, geometry on-demand
   - StreamingLoader C++ class with priority queue
   - PrimSkeleton for lightweight prim representation
   - Web Worker support for non-blocking parsing
   - Time-budgeted processing per frame

3. JavaScript/TypeScript API:
   - ProgressiveScene for Three.js integration
   - WorkerBridge for main thread ↔ worker communication
   - PrimProxy with toThreeMesh() helper
   - Transferable ArrayBuffer support for zero-copy geometry

Architecture enables loading large USD scenes without blocking
the render loop, with frustum-based priority for visible-first loading.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 08:31:49 +09:00
Syoyo Fujita
016bf6478a Merge branch 'value-opt': resolve conflicts with zero-copy RoleTypeCast
- primvar.hh: Merged preprocessor-based approach for new/old Value with
  special value::Value overloads
- value-types.cc: Keep compile-time validation macros in old impl guard,
  restore zero-copy RoleTypeCast
- value-types.hh, value-types-new.hh: Add get_raw_mutable() and
  unsafe_reinterpret_as<T>() for zero-copy role type casting
- unit-value-types.cc: Update tests to use as<T>() instead of
  get_raw().cast<T>() for compatibility with both Value implementations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 08:27:44 +09:00
Syoyo Fujita
584bb9f356 Fix build errors on macOS 26.2 SDK with C++14
- timesamples.hh: Split add_pod_sample into two SFINAE-enabled overloads
  using std::enable_if to avoid -Wfortify-source memcpy overflow errors
  for types larger than 8 bytes
- logger.hh: Add duration_cast to fix chrono time_point type mismatch
  between system_clock and high_resolution_clock

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 01:25:34 +09:00
Syoyo Fujita
02e8090da0 Merge branch 'anim-mtlx-phase2-fix' into anim-mtlx-phase2 2025-12-17 06:33:19 +09:00
Syoyo Fujita
952547a75a Use TinyUSDZLoaderUtils to setup envmap. 2025-12-17 06:31:52 +09:00
Syoyo Fujita
350bbd9312 Disable animation code and update material UI for multi-object scenes
- Block comment all animation-related code (UI, controls, extraction)
- Remove Animation folder from GUI
- Change material UI to show nothing for scenes with multiple objects
- Single mesh scenes still auto-show materials
- User must click to select object before seeing its materials

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 05:28:52 +09:00
Syoyo Fujita
f7f651cc43 Merge branch 'anim-mtlx-phase2-fix' of github.com:lighttransport/tinyusdz into anim-mtlx-phase2-fix 2025-12-17 05:04:03 +09:00
Syoyo Fujita
18404bdb87 suppress compiler warning. 2025-12-17 04:33:51 +09:00
Syoyo Fujita
f44cd761fd Add USD scene graph hierarchy and object picking features
- Use buildThreeNode for proper USD Prim xformOps hierarchy instead of flat mesh iteration
- Add object picking with raycaster to select meshes in scene
- Filter material UI to show only selected object's materials
- Add "Fit to Scene" button to adjust camera to scene bounds
- Auto-detect Z-up axis and enable Y-up conversion at startup
- Add material name display in Material Parameters UI
- Add GUI scrolling support (maxHeight/overflowY)
- Move Animation folder to bottom of UI
- Add filename to error messages in TinyUSDZLoader
- Store material metadata (rawData, typeInfo) in setupMesh for UI access

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 04:32:12 +09:00
Syoyo Fujita
4e37545c9b add test scene with envmap(DomeLight) 2025-12-17 02:16:46 +09:00
Syoyo Fujita
b32038cd73 Add primvar support and JSON schema validation to LightUSD
- Upgrade to C++17 for std::optional, std::string_view, std::variant
- Add primvar support with interpolation modes (Constant, Uniform,
  Vertex, FaceVarying, Varying) and indexed primvar handling
- Add dependency-free JSON parser using std::variant
- Add schema validation system with PropertySchema and PrimSchema
- Add SchemaRegistry singleton with 24 built-in schemas:
  - Base: Imageable, Boundable, Gprim, Light
  - Geometry: Mesh, Points, BasisCurves, Cube, Sphere, Cylinder,
    Cone, Capsule
  - Scene: Xform, Scope, Camera
  - Materials: Material, Shader
  - Lights: SphereLight, DistantLight, DomeLight
  - Skeletal: SkelRoot, Skeleton, SkelAnimation, BlendShape
- Support user-supplied JSON schemas for custom prim types
- Add STATUS.md documenting current features

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 22:59:55 +09:00
Syoyo Fujita
0ee30cf681 Fix DomeLight envmap loading for small textures in PMREM
- Add HDR file extension support to USDZ asset resolution
- Fix PMREM minimum texture size requirement (64x64) by upscaling
  small textures to CanvasTexture with extracted average color
- Add ensureMinPMREMSize helper function in both materialx.js and
  animation.js to handle tiny EXR/HDR textures from USDZ files
- Capture converter warnings in binding.cc without printing to stderr
- Add numTextures() and numImages() methods to JS/WASM bindings
- Default exposure to 1.0 when not set for proper intensity boost

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 13:19:28 +09:00
Syoyo Fujita
7e02a9e267 Merge branch 'usdlux-2025' into anim-mtlx-phase2-fix 2025-12-16 11:14:42 +09:00
Syoyo Fujita
825728b2ad Add USD DomeLight support and EXR/HDR fallback loading
- Add DomeLight detection and environment map loading from USD files
- Support both texture-based and color-based DomeLights
- Add fallback loading for EXR/HDR textures when WASM layer fails
- Replace deprecated RGBELoader with HDRLoader
- Add 'usd_dome' preset to environment combobox (auto-selected when DomeLight present)
- Add GUI controller refresh when USD DomeLight is loaded
- Implement memory cleanup (WASM, textures, geometries, materials) when reloading USD
- Stop animation playback when reloading USD files
- Add constant color environment support with sRGB/linear colorspace options
- Store loader and scene references for proper cleanup
- Add extensive debug logging for texture loading

Technical details:
- Use EXRLoader for .exr files, HDRLoader for .hdr files
- Apply USD DomeLight intensity and exposure (intensity × 2^exposure)
- Update envPresetController.updateDisplay() to sync GUI
- Clear usdDomeLightData on scene reload
- Implement proper Three.js resource disposal pattern

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-16 11:13:56 +09:00
Syoyo Fujita
97ab77b434 Add UsdPreviewSurface PBR material support to WebGPU demo
- Update render_data.cc to extract materials during scene conversion
  and bind them to meshes via material:binding relationship
- Implement PBR shader in WGSL with GGX/Cook-Torrance BRDF
  - Supports baseColor, metallic, roughness, emissive
  - Includes Fresnel, distribution (GGX), and geometry (Smith) functions
  - ACES tone mapping and gamma correction
- Add material uniform buffer to WebGPU renderer
- Update demo USDA example with gold metallic material
- Display material properties in scene info panel
  (color swatch, metallic, roughness)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 01:23:41 +09:00
Syoyo Fujita
95300a38c5 Add WebGPU rendering and PCP composition for LightUSD
WebGPU Rendering:
- RenderConverter: Convert USD Stage to GPU-ready mesh data
- Mesh triangulation (quads/ngons to triangles)
- Normal computation (flat and smooth)
- Tangent computation for normal mapping
- Texture loading with three decode modes (Browser/WebGPU/Native)
- Material extraction from UsdPreviewSurface

PCP (Prim Cache Populate):
- PcpCache: Main composition query interface with caching
- PcpLayerStack: Resolved layer stack with sublayers
- PcpPrimIndex: Cached composition result per prim
- PcpNode: Composition tree node structure
- LayerRegistry: Layer loading and caching

WebAssembly:
- Emscripten build configuration with three modes (Release/Debug/WASM64)
- JavaScript/TypeScript bindings via embind
- TypedArray support for zero-copy GPU buffer upload
- TypeScript type definitions

Demos:
- Interactive USDA parser demo (demo/index.html)
- WebGPU 3D viewer with orbit controls (demo/webgpu.html)
- Pure JavaScript WebGPU renderer (no three.js dependency)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 01:02:51 +09:00
Syoyo Fujita
2c10f05829 Add USDC reader with fetch-on-demand API
Implement USDC (Crate format) binary reader for LightUSD with streaming
fetch-on-demand capability for web/WASM and large production USD scenes.

Key features:
- Complete USDC reader supporting all 190 test files
- C-compatible callback API for progressive section loading
- State machine pattern for async-ready streaming reads
- Preset fetch handlers:
  - Mmap handler for PC/desktop (zero-copy via OS paging)
  - Cached handler for web/WASM (LRU eviction, configurable size)
- RAII context wrappers for safe handler lifetime management
- LZ4 decompression and integer coding support

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 12:20:08 +09:00
Syoyo Fujita
22f292c3dc Evaluate xformOps at startTimeCode for static viewers
Set env.timecode to startTimeCode (if authored) when converting Stage to
RenderScene. This ensures xformOps with TimeSamples are evaluated at the
initial pose for static viewers like materialx.js that don't support
animation playback.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 11:42:04 +09:00
Syoyo Fujita
6f3fcdf835 Add memory management and load-only options for JS/WASM
- Add reset() and getMemoryStats() to TinyUSDZLoaderNative (binding.cc)
  - reset() clears render scene, layers, assets, and all cached data
  - getMemoryStats() returns memory usage statistics for debugging

- Update clearScene() in materialx.js to properly free memory on reload
  - Dispose Three.js geometries, materials, and textures
  - Call nativeLoader.reset() to free WASM memory
  - Reset GUI state for normal display mode

- Add command line argument support to load-test-node.js

- Add new options to test-stream-load.js:
  - --load-only: Load USD as Layer only (no scene conversion)
  - --compare-modes: Compare load-only vs full load performance
  - Fix --compare to clear memory between tests with reset() and GC
  - Add memory usage reporting to all examples

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 05:20:53 +09:00
Syoyo Fujita
a8030af492 some move optimizations. 2025-12-14 06:22:30 +09:00
Syoyo Fujita
bee9a9b86c Fix WebGPU demo shader errors and add IBL support
- Fix implicit conversion warning in timesamples.hh (uint64_t to size_t)
- Fix WGSL shader error: sample all textures unconditionally to satisfy
  uniform control flow requirement for textureSample
- Add IBL (Image-Based Lighting) shader with PBR support
- Add BRDF LUT generation using compute shader (rgba16float format)
- Add HDR environment map loading with robust parser
- Add fallback environment when HDR loading fails
- Fix environment map paths to use actual assets
- Add float-to-half conversion for HDR textures

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 06:20:57 +09:00
Syoyo Fujita
5b74bb09aa Add YAML and JSON output formats for DumpRenderScene in Tydra
- Add --yaml and --json command-line options to tydra_to_renderscene
- Implement YAML format (human-readable, now default) with metadata header
- Implement JSON format (machine-readable) with metadata header
- Both formats include: format_version, generator, source_file, scene settings
  (upAxis, metersPerUnit, framesPerSecond, etc.), and summary counts
- Add configuration info output as comments (YAML: #, JSON: //)
- Config info includes: loading_method, input_file, triangulate,
  triangulation_method, build_vertex_indices, asset_resolver, timecode, etc.
- Keep original KDL format available via API with format="kdl"

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 05:26:28 +09:00
Syoyo Fujita
1e837447c6 Replace POD array storage with value::Value dedup system for all TimeSamples array types
- Add _value_array_storage and _value_array_refs offset table for dedup
- Add add_value_array_sample() with move semantics (no copy)
- Update add_dedup_sample() to use offset table when _use_value_array
- Convert all array type handlers to use unified approach:
  - int32[], uint32[], int64[], uint64[]
  - half[], half2[], half3[], half4[]
  - float[], float2[], float3[], float4[]
  - double[], double2[], double3[], double4[]
  - quatf[], quath[], quatd[]
  - matrix2d[], matrix3d[], matrix4d[]
  - bool[]

Benefits:
- Dedup samples only store time + reference index (no data copy)
- New samples use move semantics (no copy)
- Unified handling for all array types (removes POD-specific paths)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 03:58:39 +09:00
Syoyo Fujita
e4af68d251 Add move semantics to set_timesamples and bool array dedup support
- Fix set_timesamples move overloads in prim-types.hh to use std::move()
- Add std::move() at call sites in ascii-parser.cc and scene-access.cc
- Add _dedup_bool_array cache in crate-reader.hh for bool array dedup
- Add add_dedup_bool_array_sample_pod() method in timesamples.hh
- Update UnpackTimeSampleValue_BOOL to use dedup cache for bool arrays

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 03:31:23 +09:00
Syoyo Fujita
0ba4ffa43a Optimize traversal and reduce string allocations in Stage and Tydra APIs
Performance optimizations for path traversal and prim lookup:

Stage (stage.cc):
- Replace recursive GetPrimAtPathRec with iterative GetPrimAtPathIterative
- Avoid string concatenation by using compare() with indices
- Direct path component parsing without intermediate allocations

Scene Access (scene-access.cc):
- Replace recursive TraverseRec with iterative TraverseIterative
- Use explicit stack with StackVector to avoid recursion overhead
- Reuse path buffer across traversal to minimize string allocations
- Reserve capacity for path buffer (256) and stack (64)

Additional optimizations:
- layer.cc: Improved path handling
- prim-types.cc: Optimized type operations
- usd-to-json.cc: Better JSON serialization
- usdGeom.cc, usdMtlx.cc: Enhanced prim reconstruction

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 02:45:18 +09:00
Syoyo Fujita
b1aafd6436 Optimize memory allocation with reusable buffers, move semantics, and zero-copy RoleTypeCast
Memory optimizations to reduce allocation overhead and eliminate redundant copies:

USDC Reading:
- Add reusable decompression buffers (_decomp_comp_buffer, _decomp_working_buffer)
  to CrateReader class to avoid repeated allocation across ReadCompressedInts,
  ReadCompressedPaths, ReadFieldSets, and ReadSpecs calls
- Original implementations preserved with #if 0 for comparison

Move Semantics for Attribute Parsing:
- Add move overloads to Animatable::set() and set_default()
- Add move overloads to TypedAttribute::set_value() and operator=
- Add move overload to TypedAttributeWithFallback::set_value()
- Update ParseTypedAttribute call sites in prim-reconstruct.cc to use
  std::move() for large array assignments (faceVertexIndices, points, normals)

Zero-Copy RoleTypeCast:
- Add unsafe_reinterpret_as<T>() to linb::any for vtable-only type changes
- Add get_raw_mutable() accessor to value::Value
- Rewrite ROLE_TYPE_CAST macro to swap vtable pointers instead of copying
- Add VALIDATE_ROLE_TYPE_CAST macro with static_asserts for all 22 role
  type combinations (float2->texcoord2f, float3->normal3f/point3f/etc.)
- Add comprehensive unit tests for RoleTypeCast in unit-value-types.cc

Tydra Render Conversion:
- Add _tmp_points_buffer to RenderSceneConverter for BuildVertexIndicesFastImpl
- Add reserve() to TriangulatePolygon output vectors
- Add reserve() to ConvertMesh usdFaceVertexIndices and usdFaceVertexCounts
- Fix VertexAttribute copies to use const references and std::move()

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 02:44:19 +09:00
Syoyo Fujita
ccd4c913be Add move semantics and reduce string allocations in property parsing
Performance optimizations:

DumpNode (src/tydra/render-scene-dump.cc):
- Refactor recursive DumpNode to reuse single stringstream
- Pass stringstream by reference to avoid allocation per node
- ~22% reduction in ostream operations

Property parsing (src/usdc-reader.cc):
- Add std::move() for AttrMeta assignments to avoid deep copies
- Add std::move() for Relationship and Property construction
- Add std::move() for PrimSpec storage in variant maps
- ~10% reduction in memory allocations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 10:50:27 +09:00
Syoyo Fujita
e9c8a3ee9a Optimize TimeSamples sorting and vertex attribute conversion
Performance optimizations based on profiling:

TimeSamples (src/timesamples.cc):
- Add std::is_sorted() fast path for already-sorted data
- Implement adaptive insertion sort for nearly-sorted data (O(n) vs O(n log n))
- Pre-compute source offsets in sort_with_compact_values (O(n) vs O(n²))
- Use memcpy instead of std::copy for POD types

Vertex attribute conversion (src/tydra/render-data.cc):
- Pre-allocate buffers with exact size using resize()
- Use direct memcpy instead of vector::insert() loops
- Eliminate intermediate buffer allocations in TriangulateVertexAttribute
- Optimize VertexToFaceVarying with pre-allocated destination

Profiling results show elimination of sorting overhead (~6% of runtime)
and 63% reduction in triangulation/conversion function time.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 10:03:58 +09:00
Syoyo Fujita
f7cb0ff4d4 Optimize USDC Prim reconstruction with iterative traversal and move semantics
- Rewrite ReconstructPrimRecursively to use iterative stack-based traversal
  to avoid stack overflow for deeply nested prim hierarchies
- Change ReconstructPrimNode output parameter from nonstd::optional<Prim>
  to std::unique_ptr<Prim> for move-friendly semantics (no Prim copies)
- Use std::move when emplacing variantPrim to _variantPrims map
- Add switchable macro TINYUSDZ_USE_ITERATIVE_RECONSTRUCT_PRIM (default on)
- Rewrite StackVector in tiny-container.hh with proper small vector optimization
- Add comprehensive unit tests for StackVector

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 08:36:35 +09:00
Syoyo Fujita
4c6a78770e make no texture load and no usd print default.
add release build script.
2025-12-13 07:22:33 +09:00
Syoyo Fujita
d0ad32d3c1 Add parser support for assetInfo and sublayers
Parser now handles:
- assetInfo = { ... } in prim metadata
- subLayers = [...] with layer offsets in stage metadata

Added parser roundtrip tests for both features.

All 66 tests pass with 404 assertions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 23:02:27 +09:00
Syoyo Fujita
69f06364c9 Add AssetInfo metadata and Sublayers support
Prim AssetInfo:
- New methods: has_asset_info(), get_asset_info(), set_asset_info()
- asset_info_keys(), asset_info_count()
- Convenience: asset_identifier(), asset_name(), asset_version()
- Writer outputs assetInfo = { ... } in prim metadata

Stage Sublayers:
- New SubLayer struct with asset_path and LayerOffset
- Methods: sublayer_count(), sublayer(), sublayers()
- add_sublayer(), insert_sublayer(), remove_sublayer()
- clear_sublayers(), set_sublayers()
- Writer outputs subLayers = [...] with layer offsets

All 64 tests pass with 389 assertions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 10:33:34 +09:00
Syoyo Fujita
65f063ebd8 Add property and child ordering support to Prim
Properties and children now preserve insertion order by default.
New methods for explicit reordering:

For properties:
- property_names() returns insertion order (was sorted)
- set_property_order() for explicit ordering
- reorder_properties_lexicographic() for OpenUSD-style sorting

For children:
- set_child_order() for explicit ordering
- reorder_children_lexicographic() for OpenUSD-style sorting

The writer's sort_properties and sort_children options still work
to sort at output time when enabled.

All 60 tests pass with 357 assertions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 10:23:33 +09:00
Syoyo Fujita
492330bbdd Add LightUSD library with USD composition framework
LightUSD is a new lightweight USD library with:
- No C++ exceptions, no RTTI
- Minimal templates for fast compile time
- C++14 compatible

Core types implemented:
- TypeId enum and TypeDescriptor registry
- Value class (32-byte type-erased container)
- Token (interned strings), Path, TimeSamples
- Attribute, Relationship, Property
- Prim and Stage classes

Composition framework (PCP-like):
- Variant and VariantSet classes
- Reference, Payload with LayerOffset
- ReferenceList, PayloadList, PathList with list edit operations
- Layer class for single data sources
- PrimIndex and CompositionNode for composition graphs
- PrimIndexCache for caching composed prims

USDA support:
- Lexer with full token support including AssetPath and PathRef
- Recursive descent parser with composition metadata parsing
- Writer with composition arc and variantSet output

All 58 tests pass with 333 assertions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 09:12:46 +09:00
Syoyo Fujita
327e39e288 Add WebGPU + OpenPBR demo with UBO-based material batching
Implement high-performance USD viewer using native WebGPU:
- OpenPBR uber shader in WGSL with full material model support
- UBO/Storage buffer based material parameters (256 materials)
- Bindless texture arrays for efficient texture access
- Instance-based rendering with per-instance material index
- PBR lighting with GGX, Smith geometry, Fresnel-Schlick
- Multiple tone mapping options (ACES, Reinhard, AgX, Linear)
- Orbit camera controls with drag & drop USD file loading

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 06:58:00 +09:00
Syoyo Fujita
7ad63007de Optimize GeomSubset rendering with triangle reordering by material
- Reorder triangles by material in WASM binding to create contiguous
  submesh groups (e.g., 3 groups instead of 383 for a 3-material mesh)
- Fix float-to-double promotion warnings in TransformPoint/TransformNormal
- Fix sign-conversion warnings in MergeMeshesImpl
- Add dump-geomsubset.js CLI tool for debugging geometry/material grouping

This significantly reduces draw calls in Three.js for meshes with
GeomSubsets by ensuring each material has exactly one contiguous
draw group instead of many fragmented ranges.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 11:32:03 +09:00
Syoyo Fujita
6781ceabae Add mesh merging and texture image caching for RenderScene conversion
Performance optimizations for Tydra RenderScene converter:

1. Mesh Merging (merge_meshes option):
   - Merge static meshes with the same material into single mesh
   - Reduces draw calls in Three.js/WebGL/Vulkan renderers
   - Configurable via RenderSceneConverterConfig::merge_meshes
   - Optional transform baking (merge_meshes_bake_transform)
   - Skips meshes with skeletal animation, blend shapes, or per-face materials

2. Texture Image Caching:
   - Cache loaded texture images by asset path in imageMap
   - Reuse existing images when same texture file is used by multiple materials
   - Avoids redundant disk I/O and reduces memory usage
   - Addresses TODO comment about sharing image data

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-10 10:06:10 +09:00
Syoyo Fujita
0b25083fce revert initial USD filename. 2025-12-09 11:38:57 +09:00
Syoyo Fujita
9e531184de Optimize multi-material mesh rendering with WASM-computed submeshes
Improve rendering performance for meshes with per-face materials (GeomSubsets)
by pre-computing optimized submesh groups in C++ instead of JavaScript.

Changes:
- WASM: Pre-compute contiguous face ranges per material in binding.cc
  Export minimal submesh data: {start, count, materialId}
- JS: Use pre-computed submeshes directly, eliminating expensive sorting/grouping
- Fix stack overflow with large arrays by removing spread operator usage

Performance: 100x-1000x faster for large meshes with multiple materials
  Before: JS processing thousands of face indices (browser hang)
  After: C++ pre-computation, JS just creates geometry groups

Tydra improvements:
- Change texture nullptr errors to warnings with debug info (Prim path)
- Change normals conversion errors to warnings, clear invalid normals
- Allow mesh conversion to continue with missing textures/normals

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-09 11:06:56 +09:00
Syoyo Fujita
6e98332bcf Add UsdLux light support documentation to web/js README
- Document supported light types and Three.js equivalents
- Add API examples for accessing light data
- Document DomeLight environment map support with code examples
- Add Three.js PMREMGenerator integration guide
- Include complete light properties reference table
- Document dump-usdlux-cli.js usage

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 02:49:08 +09:00
Syoyo Fujita
0957dc79a3 Add envmap texture support for DomeLight
C++ (render-data.cc):
- Load envmap texture from DomeLight inputs:file asset
- Use DefaultTextureImageLoaderFunction for HDR/EXR loading
- Store loaded image in images array and set envmap_texture_id
- Support both decoded texture loading and raw asset storage modes

JavaScript (usdlux.js):
- Add createTextureFromImageData() to convert loaded image to Three.js texture
- Support both HDR (float32) and LDR (uint8) image formats
- Configure texture for equirectangular environment mapping
- Update loadLightsFromUSD() to load envmap texture for dome lights
- Update convertUSDLightToThreeJS() to apply envmap using PMREMGenerator
- Set scene.environment for PBR environment lighting

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 02:24:06 +09:00
Syoyo Fujita
d821b57bb6 Rename NodeKind to NodeCategory across codebase
- Rename enum NodeKind -> NodeCategory
- Rename Node::kind -> Node::category
- Update to_string(NodeKind) -> to_string(NodeCategory)
- Update GetNodeKindFromType -> GetNodeCategoryFromType
- Update dump output from "kind" to "category"
- Update web binding to use nodeCategory
- Update JavaScript dump-usdlux-cli.js to use nodeCategory

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 07:46:40 +09:00
Syoyo Fujita
4018d2455f Add nodeKind support to web/js dump and WASM binding
- Add nodeKind field to buildNodeRec in binding.cc for WASM node output
- Add --show-nodes option to dump-usdlux-cli.js to display node hierarchy
- Add formatNodeRec and formatNodeHierarchy functions for node display
- Support node hierarchy in JSON and YAML output formats with --show-nodes
- Update help text with examples for node hierarchy dumping

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 06:17:44 +09:00
Syoyo Fujita
1ee036a049 Add NodeKind enum and fix light type support in Tydra RenderScene
- Add NodeKind enum to categorize USD Prim types (Group, Geom, Light, Camera, Material, Skeleton)
- Add 'kind' member to Node struct for high-level categorization
- Add new NodeType values: RectLight, DiskLight, CylinderLight, GeometryLight
- Fix missing RegisterReconstructCallback for RectLight and GeometryLight in usda-reader.cc
- Update dump output to show both kind and type for each node
- Update threejs-exporter.cc to handle new NodeType values

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 05:48:39 +09:00
Syoyo Fujita
dbb4507824 Add streaming transfer for memory-efficient JS to WASM data loading
Implements zero-copy streaming buffer mechanism to transfer USD data from
JS to WASM memory with minimal memory overhead. Key features:

- Pre-allocate WASM buffer upfront, write chunks directly via HEAPU8.set()
- Use UUID as buffer key, asset_name stored for cache lookup on finalize
- Support ReadableStreamBYOBReader when available for better performance
- Fallback to default reader when BYOB is unavailable
- AbortController support for cancellation
- Progress callback for transfer monitoring

New JS methods:
- streamFetchToWasm() - Stream fetch data directly to WASM
- streamFileToWasm() - Stream Node.js file to WASM (fs.createReadStream)
- streamFetchMultipleToWasm() - Parallel streaming with concurrency control
- loadWithStreaming() - High-level method combining streaming + parsing

C++ changes:
- ZeroCopyStreamingBuffer struct with UUID-based buffer management
- allocateZeroCopyBuffer/finalizeZeroCopyBuffer/cancelZeroCopyBuffer
- loadFromCachedAsset/loadAsLayerFromCachedAsset methods
- Export HEAPU8 for direct WASM heap access

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 08:14:56 +09:00
Syoyo Fujita
1b732f5136 Add comprehensive type handlers for 32-byte Value implementation
- Add DestroyModelValue and CopyModelValue handlers in prim-types.cc for:
  - CustomDataType, Payload, Reference, Path types
  - std::vector<Payload>, std::vector<Reference>, std::vector<LayerOffset>
  - ListOp types (token, string, path, reference, payload)
  - VariantSelectionMap, TimeSamples
  - All MODEL types (Xform, GeomMesh, lights, shaders, skeleton, etc.)
  - MaterialX types (MtlxStandardSurface, MtlxOpenPBRSurface, etc.)
  - Imaging types (ShaderNode, UsdPreviewSurface, UsdUVTexture, etc.)

- Add TYPE_ID_TOKEN_VECTOR and TYPE_ID_PATH_VECTOR to GetTypeName map
  in value-types.cc to fix type name resolution for dedicated vector types

- Add MaterialXConfigAPI to supported API schemas list in ascii-parser.cc

- Extend copy_data_from() and destroy() conditions in value-types.cc to
  call helper functions for prim-types defined types

These changes fix memory leaks and type name resolution issues when using
the new 32-byte Value implementation (TUSDZ_NEW_32BYTE_VALUE).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 08:06:36 +09:00
Syoyo Fujita
982e36047b Add progress reporting support for JS/WASM parsing
Implement polling-based progress reporting for USD parsing in the web/WASM
environment. Since C++ cannot call async JS functions without Asyncify,
this uses a state-based approach where JS polls progress and can request
cancellation.

C++ changes (binding.cc):
- Add ParsingProgress struct with stage tracking and atomic cancellation
- Add getProgress(), cancelParsing(), wasCancelled(), isParsingInProgress()
- Add loadFromBinaryWithProgress() and loadAsLayerFromBinaryWithProgress()
- Wire up native progress_callback to update ParsingProgress state
- Export new methods via Emscripten bindings

JavaScript changes (TinyUSDZLoader.js):
- Add parseWithProgress() with AbortController support
- Add loadWithProgress() combining fetch and parse progress
- Add static getProgress() and cancelParsing() helpers
- Progress includes: stage, percentage, bytesProcessed, currentOperation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 07:23:56 +09:00
Syoyo Fujita
39fbeca468 Add --inspect option to tusdcat for USD Layer/Stage inspection
Adds a new inspection feature similar to pxrUSD's sdfdump, providing
YAML-like tree output of USD Layer structure. New files:
- src/usd-dump.hh/cc: InspectLayer/InspectStage implementation
- GlobMatch/GlobMatchPath functions in str-util for pattern matching

New CLI options:
- --inspect: YAML-like Layer inspection output
- --inspect-json: JSON output (placeholder, not yet implemented)
- --value=MODE: Value printing mode (none/snip/full)
- --snip=N: Number of items to show in snip mode
- --path=PATTERN: Filter prims by path glob pattern (supports **)
- --attr=PATTERN: Filter attributes by name glob pattern
- --time=T or --time=S:E: TimeSamples time query

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 06:35:17 +09:00
Syoyo Fujita
887804bba8 Add --progress option to tusdcat for ASCII progress bar display
- Add progress_callback and progress_userptr to USDLoadOptions
- Add SetProgressCallback to USDAReader to forward to AsciiParser
- Integrate progress callback in LoadUSDCFromMemory and LoadUSDAFromMemory
- Implement ASCII progress bar [=====>    ] with percentage display
- Only show progress bar if loading takes > 3 seconds
- Reformat tusdcat help message to 80 character lines

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-06 05:54:01 +09:00