Commit Graph

79 Commits

Author SHA1 Message Date
Syoyo Fujita
c6ace402dc Add granular coroutine yield phases for Tydra conversion
- Remove debug console.log statements from coroutine helpers
- Split Tydra conversion into multiple phases with yields:
  - detecting: Format detection
  - parsing: USD parsing
  - setup: Converter environment setup
  - assets: Asset resolution setup
  - meshes: Tydra mesh conversion
  - complete: Done

- Each phase yields to event loop, allowing browser repaints
- Update progress-demo.js phase mapping with descriptive messages
- The Tydra ConvertToRenderScene call is still blocking, but yields
  occur before and after it

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 04:13:51 +09:00
Syoyo Fujita
f6c9ad1d44 Use coroutine async loading in progress-demo.js with debug logging
- Add console.log debug prints at yield points in binding.cc:
  - Log when yielding to event loop
  - Log when resuming from yield (rAF or setTimeout)
  - Log phase name and progress percentage

- Add hasAsyncSupport() method to TinyUSDZLoader.js:
  - Checks if loadFromBinaryAsync is available
  - Returns true if WASM was built with TINYUSDZ_WASM_COROUTINE=ON

- Update progress-demo.js to use coroutine async when available:
  - Check hasAsyncSupport() before loading
  - Use parseAsync() for file and URL loading when available
  - Fall back to standard Promise-based loading if not
  - Map coroutine phases to progress UI stages
  - Manual fetch with progress for URL loading in async mode

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 03:40:00 +09:00
Syoyo Fujita
c66a71428e Add TINYUSDZ_WASM_COROUTINE cmake option for C++20 coroutine async loading
- Add CMake option TINYUSDZ_WASM_COROUTINE (default OFF) to enable/disable
  C++20 coroutine-based async loading
- Add TINYUSDZ_USE_COROUTINE compile definition for conditional compilation
- Wrap coroutine helper functions (yieldToEventLoop, reportAsyncPhaseStart)
  with #if defined(TINYUSDZ_USE_COROUTINE)
- Wrap loadFromBinaryAsync method with #if defined(TINYUSDZ_USE_COROUTINE)
- Wrap EMSCRIPTEN_BINDINGS registration with same guard

To enable coroutine support:
  cmake .. -DTINYUSDZ_WASM_COROUTINE=ON

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 00:40:52 +09:00
Syoyo Fujita
9d58ccc7ed Add C++20 coroutine-based async USD loading with browser yield support
- Add yieldToEventLoop() helper using EM_JS that returns a Promise for requestAnimationFrame
- Implement loadFromBinaryAsync() coroutine that yields between processing phases:
  - detecting: format detection
  - parsing: USD parsing
  - converting: Tydra conversion
  - complete: done
- Add reportAsyncPhaseStart() EM_JS callback for JS progress tracking
- Add parseAsync() and loadAsync() methods to TinyUSDZLoader.js
- Parameters passed by value (not reference) to survive co_await suspension points
- No ASYNCIFY required - uses native LLVM coroutine transform

This allows the browser to repaint between processing phases, improving
perceived loading performance for large USD files.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 00:22:07 +09:00
Syoyo Fujita
d04efdf8d3 Add EM_JS synchronous progress callbacks for Tydra conversion
- Add EM_JS functions in binding.cc for direct C++ to JS progress reporting
  - reportTydraProgress: mesh conversion progress (current/total, stage, name)
  - reportTydraStage: conversion stage changes
  - reportTydraComplete: conversion completion with counts
- Update TinyUSDZLoader.js with callback options:
  - onTydraProgress, onTydraStage, onTydraComplete
  - setTydraProgressCallback/setTydraStageCallback/setTydraCompleteCallback methods
- Integrate callbacks in progress-demo.js for real-time UI updates
- Add design document for JS/WASM synchronous event update patterns

This enables real-time progress updates during Tydra scene conversion
without requiring ASYNCIFY, using Emscripten's EM_JS for synchronous
JavaScript calls from C++.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 22:41:47 +09:00
Syoyo Fujita
c1913a6a69 Add detailed mesh progress logging and memory cleanup for progress demo
- Add DetailedProgressInfo struct with mesh/material counts and stage tracking
- Add printf progress logging during Tydra mesh conversion (visible in console)
- Count GeomMesh, GeomCube, and GeomSphere for accurate total mesh count
- Add cleanupScene() function to free Three.js and WASM memory before loading
- Add Fit to Scene button for camera adjustment
- Add multi-mesh test model for progress testing

Console output shows real-time progress:
[Tydra] Found N meshes (X mesh, Y cube, Z sphere), M materials
[Tydra] Mesh 1/N: /path/to/mesh
[Tydra] Conversion complete: N meshes, M materials, T textures

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 07:26:45 +09:00
Syoyo Fujita
141501ec22 Add HDR (Radiance RGBE) image loading support and benchmark
Core image-loader:
- Add DecodeImageHDR using stbi_loadf_from_memory for float32 RGBA output
- Add IsHDRFromMemory and GetImageInfoHDR functions
- HDR detection runs before STB fallback to ensure float output

WASM binding:
- Update decodeHDR to use stbi_loadf_from_memory instead of image-loader
- Default output format changed to float16 (Uint16Array) for memory savings
- Add TINYUSDZ_WITH_EXR compile definition to binding target

Benchmark (web/js/benchmark-exr.js):
- Compare TinyUSDZ vs Three.js HDRLoader/EXRLoader performance
- Support float32 and float16 output formats
- JSON output mode for automation
- TinyUSDZ is 2.7-3x faster than Three.js for HDR decoding

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 05:43:45 +09:00
Syoyo Fujita
e64c409a97 Add FP16 support and SIMD for WASM image decoding
- Add IEEE 754 half-precision float conversion utilities (float32ToFloat16, float16ToFloat32)
- Update decodeEXR/decodeHDR/decodeImage to accept outputFormat parameter ("float32", "float16", "auto")
- Add convertFloat32ToFloat16Array and convertFloat16ToFloat32Array utility functions
- Enable WebAssembly SIMD (-msimd128) by default for better performance
- Add optional Relaxed SIMD support via TINYUSDZ_WASM_RELAXED_SIMD flag
- FP16 output returns Uint16Array for direct WebGL HALF_FLOAT texture upload
- 50% memory savings when using FP16 format for HDR/EXR textures

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 12:58:26 +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
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
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
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
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
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
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
e901a5029c Merge branch 'anim-mtlx-phase2' of github.com:lighttransport/tinyusdz into anim-mtlx-phase2 2025-12-01 00:48:25 +09:00
Syoyo Fujita
da1faef387 Expose RenderLight info to JS/WASM binding
- Add numLights(), getLight(), getAllLights() functions
- Export all RenderLight properties: type, color, intensity, transform, etc.
- Include LTE SpectralAPI spectral emission data when available
- Support all light types: point, sphere, disk, rect, cylinder, distant, dome

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 04:42:00 +09:00
Syoyo Fujita
de47bc8f07 Merge branch 'anim-mtlx-phase2' of github.com:lighttransport/tinyusdz into anim-mtlx-phase2 2025-11-30 04:26:18 +09:00
Syoyo Fujita
9e698ead2f Refactor UsdLux mesh lights to use direct RenderMesh properties
Implements "Option B" architecture where MeshLightAPI properties are stored
directly in RenderMesh rather than creating separate RenderLight objects. This
eliminates indirection, provides a single source of truth, and improves cache
locality for area light queries.

Changes:
- Add RectLight and GeometryLight prim parsing to USDA/USDC readers
- Store all MeshLightAPI properties in RenderMesh (color, intensity, exposure,
  normalize, materialSyncMode)
- Add get_effective_light_color() helper for emission calculations
- Remove separate RenderLight creation for mesh lights (breaking change)
- Export area light properties via WASM bindings
- Update JavaScript tests to validate mesh-based area lights
- Add comprehensive renderer integration documentation

All tests passing (4/4 test suites, 18/18 assertions).

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 02:52:35 +09:00
Syoyo Fujita
ab0ef8900c Add comprehensive UsdLux parsing and conversion system with test suite
Implements complete UsdLux light parsing and conversion pipeline:

Core Infrastructure:
- RenderLight data structure supporting 6 UsdLux light types (Point/Sphere, Directional, Rect, Disk, Cylinder, Dome)
- MeshLightAPI support for emissive geometry lights
- Full property extraction: color, intensity, exposure, shadows, shaping, IES profiles
- Color temperature support with Kelvin-based specification

JSON Serialization:
- Complete light data serialization in material-serializer.cc
- Geometry light mesh references with geometryMeshId
- Material sync mode for mesh lights

Three.js Exporter:
- Light type conversion to Three.js equivalents
- Shadow map configuration
- Directional/Point/Spot/Rect/Hemisphere light export

WASM Bindings:
- numLights() API for light count
- getLightWithFormat() supporting JSON/YAML output
- Node.js CLI tool (dump-usdlux-cli.js) for testing

Test Suite:
- Comprehensive test files in tests/usda/:
  * usdlux_basic_lights.usda - 6 light types
  * usdlux_advanced_features.usda - IES, shaping, textures
  * usdlux_mesh_lights_simple.usda - MeshLightAPI
- Automated test suite (test-usdlux-parsing.js)
- npm test:usdlux script for CI/CD integration
- All tests passing (4/4)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 03:27:19 +09:00
Syoyo Fujita
eb3c64b618 Merge branch 'mtlx-2025' into skinning 2025-11-17 02:11:52 +09:00
Syoyo Fujita
f9e030d6bf Add texture colorspace support and colorspace test USDA files
- Enhanced material-serializer to include texture asset identifiers and colorspace metadata
  * Added colorSpaceToString() helper for 15+ colorspace enum values
  * Pass RenderScene to serializeMaterial() for texture information access
  * Include texture metadata (width, height, channels, colorSpace, usdColorSpace)
  * Reorganize OpenPBR parameters into grouped layers (base, specular, transmission, etc.)

- Added 8 MaterialX + USDA test files with colorspace variations:
  * materialx-textured-simple.usda - basic textured material
  * materialx-srgb-ldr.usda - standard sRGB color texture
  * materialx-linear-srgb.usda - raw colorspace (non-color data)
  * materialx-aces-cg.usda - ACES CG for HDR VFX workflows
  * materialx-aces2065-1.usda - ACES 2065-1 for DCI cinema
  * materialx-rec709-linear.usda - linear Rec.709 for broadcast video
  * materialx-rec709-gamma22.usda - gamma 2.2 Rec.709 (sRGB-like)
  * materialx-displayp3.usda - Display P3 for modern displays

- Verified colorspace information correctly passes from C++ to JavaScript/WASM
  * All test files export via dump-materialx-cli.js with proper colorSpace values
  * JSON includes both colorSpace (processed) and usdColorSpace (original intent) fields

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 06:23:07 +09:00
Syoyo Fujita
88a6b424c6 Add material serializer and enhance MaterialX web demo with Three.js integration
- Add Tydra material serializer for WASM/JS bindings (JSON/XML export)
- Enhance MaterialX web demo with Three.js module imports and improved material handling
- Add support for normal visualization, bounding boxes, and up-axis conversion in demo
- Update CMakeLists to include new material serializer in Tydra build
- Minor updates to shape-to-mesh header and web bindings

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 11:29:08 +09:00
Syoyo Fujita
960e235348 Fix MaterialX config attribute parsing and add WASM material query API
Fixes parsing of MaterialX config attributes (config:mtlx:*) that are
defined without explicit 'uniform' variability keyword. These attributes
are implicitly uniform by nature but Blender and other exporters may
not add the uniform keyword explicitly.

Changes:
- Allow config:* attributes to be parsed without uniform variability
- Add numMaterials() method to WASM binding for material count queries
- Fix dump-materialx-cli.js to use parse() instead of loadTestAsync()
  to ensure proper Stage->RenderScene conversion

Tested:
- polysphere-materialx-001.usda now loads successfully
- Material data properly flows from C++ through WASM to JS
- JSON serialization working correctly for all material types

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 00:05:18 +09:00
Syoyo Fujita
be2ba77cf6 Add support for static SkelAnimation values and expose skeletal animation data in WASM
Extended SkelAnimation conversion to handle static (non-time-sampled) animation
values in addition to time-sampled data. Static values are now converted to single
keyframes at time 0.0 for translations, rotations, and scales.

Enhanced WASM binding to expose raw animation channels and samplers arrays with
full skeletal animation metadata including target_type, skeleton_id, joint_id, and
path information. This enables JavaScript consumers to properly access and render
skeletal animations that target skeleton joints rather than scene nodes.

Changes:
- src/tydra/render-data.cc: Add has_value() branches for static animation data
- web/binding.cc: Expose channels and samplers arrays with skeletal metadata

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 22:11:19 +09:00
Syoyo Fujita
99e05822cc Merge branch 'release' into mtlx-2025 with compilation fixes
Resolved merge conflicts and fixed compilation errors introduced by animation system refactoring and API changes:
- Updated AnimationClip API usage in threejs-exporter (channels/samplers)
- Fixed PropertyMap const-correctness in MaterialX shader reconstructors
- Fixed 32-bit build warnings (sign conversion, variable shadowing)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 21:55:27 +09:00
Syoyo Fujita
a09c3fd19e expose skin info to WASM. 2025-11-04 06:58:05 +09:00
Syoyo Fujita
c27c1dbe7e Add USD metadata support and enhance animation viewer
This commit adds comprehensive USD metadata reading and multiple viewer enhancements:

Backend changes:
- Populate RenderScene.meta with USD Stage metadata (upAxis, metersPerUnit, FPS, timecodes, time ranges, autoPlay, comment, copyright)
- Add getUpAxis() and getSceneMetadata() methods to WASM bindings
- Extract copyright from customLayerData dictionary

Animation viewer enhancements:
- Fix upAxis conversion to only apply when file is Z-up (not blindly to all files)
- Add Scene Metadata UI folder displaying all USD metadata
- Change Speed to directly represent FPS from metadata (default 24)
- Rename time labels to use TimeCode terminology (Begin/End TimeCode, Duration)
- Scale default scene 10x for meter-based USD files (camera, grid, shadows, light)
- Add "Fit to Scene" feature that auto-adjusts camera, grid, and shadow frustum based on bounding box
- Apply metersPerUnit scaling with toggle option
- Set animation time range from startTimeCode/endTimeCode metadata

The viewer now properly respects USD metadata and provides better defaults for typical meter-based models.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-02 11:19:43 +09:00
Syoyo Fujita
8e136d13fc support multiple UVs in MaterialX 2025-11-02 08:11:45 +09:00
Syoyo Fujita
8b5f51a802 Expose bone reduction to JavaScript/WASM bindings and skinning demo
Adds complete JavaScript API for bone reduction configuration with UI controls
in the skeletal animation viewer.

WASM Bindings (web/binding.cc):
- Added setEnableBoneReduction/getEnableBoneReduction methods
- Added setTargetBoneCount/getTargetBoneCount methods (1-64 range)
- Applied configuration to RenderSceneConverterEnv.mesh_config
- Exposed methods via EMSCRIPTEN_BINDINGS

TinyUSDZLoader.js API:
- Added setEnableBoneReduction(enabled) method
- Added getEnableBoneReduction() method
- Added setTargetBoneCount(count) method with validation
- Added getTargetBoneCount() method
- Applied configuration in parse(), loadAsLayerFromBinary(), and loadTest()
- Configurations passed to native module before USD loading

Skinning Demo UI (web/js/skining-anim.js):
- Added "Bone Reduction (Next Load)" GUI folder with controls:
  * Enable Reduction checkbox
  * Target Bone Count slider (1-8 bones)
- Settings applied on next file load (requires reload to take effect)
- Console logging for user feedback on configuration changes
- Defaults: disabled, 4 bones (standard for WebGL/Three.js)

Usage Example:
```javascript
const loader = new TinyUSDZLoader();
await loader.init();
loader.setEnableBoneReduction(true);
loader.setTargetBoneCount(4);  // 4 bones per vertex
const scene = await loader.loadFromBinary(data, filename);
```

The feature is opt-in (disabled by default) for backward compatibility.
Users can enable it through GUI or programmatically for optimized
GPU skinning performance.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-01 02:50:23 +09:00
Syoyo Fujita
53a21e0331 Add matrix decomposition support for Transform xformOp animations
Implement TRS decomposition to enable animated matrix transforms in Tydra
render-scene conversion. Transform xformOps with time samples are now
decomposed into separate Translation/Rotation/Scale animation channels
compatible with glTF and Three.js.

Changes:
- Add decompose() function to xform.cc using Shepperd's method for stable
  quaternion extraction from rotation matrices
- Extend ExtractXformOpAnimation() to handle Transform xformOps by
  decomposing each matrix time sample into TRS components
- Fix TimeSamples API usage: change ts.get_as<T>() to sample_value.as<T>()
  for correct access pattern with FOREACH_TIMESAMPLES_BEGIN macro
- Fix atomic library linking in CMakeLists.txt for Emscripten builds
- Fix AnimationChannel validation method call (valid -> is_valid)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-27 23:34:51 +09:00
Syoyo Fujita
95e700bdfa Add JavaScript bindings for RenderScene animation data
- Add animation extraction methods to web/binding.cc:
  - numAnimations(): Get total number of animation clips
  - getAnimation(id): Get animation as Three.js compatible JSON
  - getAllAnimations(): Get all animations as array
  - getAnimationInfo(id): Get animation summary without full data
  - getAllAnimationInfos(): Get all animation summaries

- Animation data format is Three.js/glTF compatible with:
  - Track names in Three.js format (e.g. "nodeName.position")
  - Support for vector3, quaternion, and number track types
  - LINEAR, STEP, and CUBICSPLINE interpolation modes
  - Efficient typed array access for keyframe data

- Update web/js/animation.js with USD animation extraction:
  - Add convertUSDAnimationsToThreeJS() function
  - Support loading USD files from ArrayBuffer
  - Integrate USD animations with existing animation system
  - Add GUI controls for USD animation playback

- Enhance web/js/animation.html with:
  - File upload controls for custom USD files
  - Animation information display
  - Reset to default model functionality

The implementation leverages existing AnimationClip structures in
TinyUSDZ's RenderScene which are already glTF/Three.js compatible,
making the conversion straightforward and efficient.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 12:21:17 +09:00
Syoyo Fujita
b3c1afd163 Fix WASM build compatibility
- Fix chrono time_point precision mismatch in logger.hh
- Fix const qualifier issue in web/binding.cc for LayerToStage call

The logger fix adds time_point_cast to handle duration conversion between
system_clock and high_resolution_clock. The binding fix creates a copy of
the Layer before moving it to LayerToStage since the function expects an
rvalue reference.

WASM build now completes successfully with emscripten.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-18 23:29:09 +09:00
Syoyo Fujita
483787e54b Add OpenPBR material serialization for JavaScript/WASM binding
Implement comprehensive serialization system to extract OpenPBR material
properties from Tydra RenderMaterial and convert to JSON or XML format
for use in JavaScript/Three.js applications.

New files:
- web/openpbr-serializer.hh: Core serialization implementation
  - JSON serialization for all OpenPBR parameters
  - XML (MaterialX 1.38) output for MaterialX tools/renderers
  - Support for UsdPreviewSurface materials
- web/test-openpbr-material.js: Usage examples and Three.js integration
- web/BUILD_STATUS.md: Build documentation and API reference

Modified files:
- web/binding.cc: Updated getMaterial() method
  - New getMaterialWithFormat(id, format) method for "json"/"xml" output
  - Legacy getMaterial(id) maintained for backward compatibility
  - Proper error handling and format validation

Features:
- Complete OpenPBR support: base, specular, transmission, subsurface,
  sheen, coat, emission, and geometry modifiers
- Handles both value and texture parameters
- Dual format output (JSON for JS, XML for MaterialX)
- C++14/17/20 compatible implementation

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-14 02:49:52 +09:00
Syoyo Fujita
f8da11794c BuildVertexIndices fast experiment. 2025-09-19 13:19:47 +09:00
Syoyo Fujita
82d7e66c73 prefer_non_indexed experience. 2025-09-17 11:21:01 +09:00
Syoyo Fujita
a7f6fcdc71 optimize mem usage. 2025-09-08 11:14:36 +09:00
Syoyo Fujita
e29a3f5648 move operator experiment. 2025-09-05 11:55:51 +09:00
Syoyo Fujita
17a9dc99c5 js mem test. 2025-09-05 03:10:15 +09:00
Syoyo Fujita
b636acf973 memusage for value::Value. 2025-09-04 23:32:34 +09:00
Syoyo Fujita
90e1855b04 Merge branch 'js_mem_reduction' into async 2025-09-04 06:40:00 +09:00
Syoyo Fujita
143cdcbc09 async experiment 2025-09-02 23:00:49 +09:00
Syoyo Fujita
30497b2a75 JS/WASM memory usage reduction experiment. 2025-08-27 12:53:50 +09:00
Syoyo Fujita
14ec29a86a fix compile. 2025-08-23 08:52:42 +09:00
Syoyo Fujita
44314c7cd6 Add memory limit support for web binding with architecture-specific defaults
- Add USDLoadOptions with memory limits to web binding C++ code
- Implement architecture-specific defaults: 2GB for WASM32, 8GB for WASM64
- Add TINYUSDZ_WASM_MEMORY64 preprocessor define for WASM64 builds
- Update JavaScript wrapper with memory limit configuration API
- Add getNativeDefaultMemoryLimitMB() method to query architecture defaults
- Support per-operation memory limit overrides in load/parse methods
- Update documentation and examples for both build architectures
- Add build examples script for WASM32/WASM64 configurations

Security enhancement to prevent memory exhaustion attacks when loading
potentially malicious USD files in web environments.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-22 02:36:44 +09:00
Syoyo Fujita
9e1c785ec5 Add zero-copy asset loading and memory view support to EMAssetResolver
This commit enhances the WebAssembly bindings with two major improvements:

1. **Zero-Copy Asset Loading** (`setAssetFromRawPointer`):
   - Direct Uint8Array access using raw pointers
   - Eliminates intermediate copying during JS↔C++ transfer
   - 67% reduction in memory copies (from 3 to 1)
   - Optimal performance for large binary assets (textures, meshes, USD files)

2. **Memory View Access** (`getAssetCacheDataAsMemoryView`):
   - Direct typed memory view of cached asset data
   - Returns Uint8Array for existing assets, undefined otherwise
   - Consistent with existing getAsset method

**Technical Details:**
- Added AssetCacheEntry struct with SHA-256 hash validation
- Implemented raw pointer method with emscripten::allow_raw_pointers()
- Enhanced error handling and data integrity checks
- Backward compatible with existing setAsset/getAsset methods

**JavaScript Usage:**
```javascript
// Zero-copy loading
const dataPtr = Module.HEAPU8.subarray(uint8Array.byteOffset,
                  uint8Array.byteOffset + uint8Array.byteLength).byteOffset;
loader.setAssetFromRawPointer('texture.jpg', dataPtr, uint8Array.length);

// Direct memory view
const memView = loader.getAssetCacheDataAsMemoryView('texture.jpg');
```

**Testing:**
- Comprehensive Node.js test suite with mock implementations
- Performance benchmarking utilities
- Data integrity validation
- Zero-copy helper functions for real-world usage

Ideal for USD workflows with large textures, geometry data, and binary scene files.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-21 02:17:24 +09:00
Syoyo Fujita
c0a1fa0c5d Add JSON <-> USD Layer conversion methods to web binding
- Add layerToJSON() method for basic Layer to JSON conversion with pretty printing
- Add layerToJSONWithOptions() method with configurable buffer embedding and array serialization modes
- Add loadLayerFromJSON() method for loading USD Layer from JSON string
- Include proper error handling and state management for all conversion methods
- Add Emscripten bindings to expose methods to JavaScript interface

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-13 03:19:11 +09:00