{"_id":"@cooljapan/oxihuman","_rev":"4-d1d0dc5edba61782505cf6fc60135d0d","name":"@cooljapan/oxihuman","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@cooljapan/oxihuman","version":"0.1.0","keywords":["wasm","webassembly","human","browser","makehuman"],"license":"Apache-2.0","_id":"@cooljapan/oxihuman@0.1.0","maintainers":[{"name":"kitasan","email":"info@kitasan.io"}],"homepage":"https://github.com/cool-japan/oxihuman","bugs":{"url":"https://github.com/cool-japan/oxihuman/issues"},"dist":{"shasum":"693115ad7a9596ba5dc7cdbe6259bbd9740446a1","tarball":"https://registry.npmjs.org/@cooljapan/oxihuman/-/oxihuman-0.1.0.tgz","fileCount":6,"integrity":"sha512-RJ7M9DyH/rKBcswQ1nx1t2xEpK4UwMRGXOYWmAa7Whmj0Sdo1KTK1wgwPWlRM2MIHfpbgY7/9dcqJ+9VRy05Jw==","signatures":[{"sig":"MEUCIQDxjMQOGaqk9/Ck9ESJafX3ybb94B8cwZr3aMdJZRk5/gIgckuwlsZFDgLf3TcN9PBONc+nxIPfZ5zubJYkh8awStw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":485617},"main":"oxihuman_wasm.js","type":"module","types":"oxihuman_wasm.d.ts","_npmUser":{"name":"kitasan","email":"info@kitasan.io"},"repository":{"url":"git+https://github.com/cool-japan/oxihuman.git","type":"git"},"_npmVersion":"10.9.4","description":"WebAssembly bindings for OxiHuman — full browser-ready API","directories":{},"sideEffects":["./oxihuman_wasm.js","./snippets/*"],"_nodeVersion":"22.22.0","collaborators":["COOLJAPAN OU (Team KitaSan)"],"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/oxihuman_0.1.0_1773217189561_0.464301469594125","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@cooljapan/oxihuman","version":"0.1.1","keywords":["wasm","webassembly","human","browser","makehuman"],"license":"Apache-2.0","_id":"@cooljapan/oxihuman@0.1.1","maintainers":[{"name":"kitasan","email":"info@kitasan.io"}],"homepage":"https://github.com/cool-japan/oxihuman","bugs":{"url":"https://github.com/cool-japan/oxihuman/issues"},"dist":{"shasum":"50bee2049ed6e6fedcc0674dcd909d40744ba7b1","tarball":"https://registry.npmjs.org/@cooljapan/oxihuman/-/oxihuman-0.1.1.tgz","fileCount":6,"integrity":"sha512-4/PRR1iumOgjhIbove4diniOVIfjLam6lT7LAeZJlU9+UE1n0KYcSutbm7P5ISMDnstJeRV5M+CImQoGSOMbRw==","signatures":[{"sig":"MEYCIQCs9NtS5OJkYyCzAwHefqgH51jsW1loxhaUaa31pFXZ3gIhAPz5CgTf0vGK3oj5keFTLZXWxbT69BWcTGZtOdObS2AI","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":487912},"main":"oxihuman_wasm.js","type":"module","types":"oxihuman_wasm.d.ts","_npmUser":{"name":"kitasan","email":"info@kitasan.io"},"repository":{"url":"git+https://github.com/cool-japan/oxihuman.git","type":"git"},"_npmVersion":"10.9.4","description":"WebAssembly bindings for OxiHuman — full browser-ready API","directories":{},"sideEffects":["./oxihuman_wasm.js","./snippets/*"],"_nodeVersion":"22.22.0","collaborators":["COOLJAPAN OU (Team KitaSan)"],"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/oxihuman_0.1.1_1773446471859_0.7032876437328148","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@cooljapan/oxihuman","version":"0.1.2","keywords":["wasm","webassembly","human","browser","makehuman"],"license":"Apache-2.0","_id":"@cooljapan/oxihuman@0.1.2","maintainers":[{"name":"kitasan","email":"info@kitasan.io"}],"homepage":"https://github.com/cool-japan/oxihuman","bugs":{"url":"https://github.com/cool-japan/oxihuman/issues"},"dist":{"shasum":"561b1e13c8b4b359360b1557c84bf849e39e9caa","tarball":"https://registry.npmjs.org/@cooljapan/oxihuman/-/oxihuman-0.1.2.tgz","fileCount":6,"integrity":"sha512-VPuGRfGZgw0GbcFK0+Z8VIBv0SyduSKabmofgFmHpmhGAMzAwBzIiiQDzarVAxdZ/+LMu29ZvYvWdBBk2t//cQ==","signatures":[{"sig":"MEQCIE9qnaSVbJlITpU6I2q4Pg3/q/eYVllDK08rV9UutlHJAiAvBZ6qRVHXqYwxc8ZqeDU4jbrkmG/HA02VoxQFaC3H4g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":511107},"main":"oxihuman_wasm.js","type":"module","types":"oxihuman_wasm.d.ts","_npmUser":{"name":"kitasan","email":"info@kitasan.io"},"repository":{"url":"git+https://github.com/cool-japan/oxihuman.git","type":"git"},"_npmVersion":"10.9.7","description":"WebAssembly bindings for OxiHuman — full browser-ready API","directories":{},"sideEffects":["./oxihuman_wasm.js","./snippets/*"],"_nodeVersion":"22.22.2","collaborators":["COOLJAPAN OU (Team KitaSan)"],"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/oxihuman_0.1.2_1777987221733_0.3764581108365683","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@cooljapan/oxihuman","type":"module","collaborators":["COOLJAPAN OU (Team KitaSan)"],"description":"WebAssembly bindings for OxiHuman — full browser-ready API","version":"0.2.0","license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/cool-japan/oxihuman.git"},"main":"oxihuman_wasm.js","homepage":"https://github.com/cool-japan/oxihuman","types":"oxihuman_wasm.d.ts","sideEffects":["./oxihuman_wasm.js","./snippets/*"],"keywords":["wasm","webassembly","human","browser","makehuman"],"_id":"@cooljapan/oxihuman@0.2.0","bugs":{"url":"https://github.com/cool-japan/oxihuman/issues"},"_nodeVersion":"22.22.3","_npmVersion":"10.9.8","dist":{"integrity":"sha512-MTbAVxl/PpER9IB38ONvsO2yOZwgXdtWRghAuXOSasXxp/ryzJhoWYnzE2f6Qw9uYzgq9uCGVvCZ+xXOjAWFTg==","shasum":"225da24911c9d501f8508719173b0379387bd51c","tarball":"https://registry.npmjs.org/@cooljapan/oxihuman/-/oxihuman-0.2.0.tgz","fileCount":6,"unpackedSize":505361,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIA3yUfwyQI3cKEuuzZUumXVH+cC3O/z/2lo/BwEeQepEAiEA+bOV3QIj5M5/LWC8BaPAHJBJoWYMy1kVBHq+2ap8UMU="}]},"_npmUser":{"name":"kitasan","email":"info@kitasan.io"},"directories":{},"maintainers":[{"name":"kitasan","email":"info@kitasan.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/oxihuman_0.2.0_1781861093001_0.2776177776269533"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-11T08:19:49.498Z","modified":"2026-06-19T09:24:53.283Z","0.1.0":"2026-03-11T08:19:49.710Z","0.1.1":"2026-03-14T00:01:12.021Z","0.1.2":"2026-05-05T13:20:21.973Z","0.2.0":"2026-06-19T09:24:53.175Z"},"bugs":{"url":"https://github.com/cool-japan/oxihuman/issues"},"license":"Apache-2.0","homepage":"https://github.com/cool-japan/oxihuman","keywords":["wasm","webassembly","human","browser","makehuman"],"repository":{"type":"git","url":"git+https://github.com/cool-japan/oxihuman.git"},"description":"WebAssembly bindings for OxiHuman — full browser-ready API","maintainers":[{"name":"kitasan","email":"info@kitasan.io"}],"readme":"# oxihuman-wasm\n\nPart of the [OxiHuman](../../README.md) workspace — privacy-first, client-side human body generator in pure Rust.\n\n**Status:** Stable | **Tests:** 168 passing | **API:** 68 WasmEngine methods | **Version:** 0.2.0 | **Updated:** 2026-06-19\n\nWebAssembly bindings for OxiHuman — full browser-ready API via wasm-bindgen. A single `WasmEngine` struct exposes the entire OxiHuman pipeline to JavaScript/TypeScript, enabling privacy-preserving, client-side human body generation with no server round-trips.\n\n---\n\n## Feature Flags\n\n```toml\n[features]\ndefault = []\nwasm = [\"dep:wasm-bindgen\", \"dep:js-sys\"]\n```\n\nThe `wasm` feature is optional. Enable it when targeting browser/Node.js environments via wasm-bindgen. Without it, the crate still compiles for testing and native use.\n\n---\n\n## Installation\n\n```toml\n[dependencies]\noxihuman-wasm = { version = \"0.2.0\", features = [\"wasm\"] }\n```\n\n---\n\n## Structs\n\n### `WasmEngine`\n\nMain body generator. Exposes the full OxiHuman pipeline as 68 public `#[wasm_bindgen]` methods. Holds base mesh data, loaded morph targets, parameter state, physics proxies, and animation frame buffer.\n\n### `ParticleSystem`\n\nPoint particle system with configurable `emit_rate` and `lifetime` control. Created via `WasmEngine::create_particle_system()` and stepped via `step_particles()`.\n\n### `Particle`\n\nRepresents a single active particle. Carries `position` (Float32Array), `velocity` (Float32Array), and `age` (f32).\n\n---\n\n## WasmEngine API — 68 Methods\n\n### Initialization (4)\n\n| Method | Description |\n|--------|-------------|\n| `new_from_obj_bytes(bytes)` | Create engine from raw OBJ mesh bytes |\n| `new_strict()` | Create engine with strict validation policy profile |\n| `load_target_bytes(name, bytes)` | Load a morph target from raw `.target` file bytes |\n| `load_zip_pack_bytes(bytes)` | Load a ZIP asset pack; returns the number of targets loaded |\n\n### Target Management (8)\n\n| Method | Description |\n|--------|-------------|\n| `list_loaded_targets()` | Return JSON array of all loaded target names |\n| `loaded_target_count()` | Return count of currently loaded targets |\n| `load_target_from_json(json)` | Load a morph target from JSON descriptor |\n| `unload_target(name)` | Remove a named target from the engine |\n| `set_target_weight_by_name(name, weight)` | Set blend weight [0.0–1.0] for a named target |\n| `get_target_weight_by_name(name)` | Get current blend weight for a named target |\n| `target_count()` | Total number of registered targets (loaded + unloaded) |\n| `get_loaded_target_names()` | Return JS array of loaded target name strings |\n\n### Parameter Control (7)\n\n| Method | Description |\n|--------|-------------|\n| `set_height(value)` | Set body height parameter (metres) |\n| `set_weight(value)` | Set body weight parameter (normalized) |\n| `set_muscle(value)` | Set musculature parameter |\n| `set_age(value)` | Set age parameter |\n| `set_param(key, value)` | Set any named parameter by string key |\n| `reset_params()` | Reset all body parameters to defaults |\n| `reset_all_weights()` | Reset all morph target blend weights to zero |\n\n### JSON Import/Export (4)\n\n| Method | Description |\n|--------|-------------|\n| `export_params_json()` | Serialize current parameter state to JSON |\n| `import_params_json(json)` | Restore parameter state from JSON |\n| `get_measurements_json()` | Return computed body measurements (height, circumferences, etc.) as JSON |\n| `export_anim_json()` | Serialize recorded animation frames to JSON |\n\n### Mesh Building (3)\n\n| Method | Description |\n|--------|-------------|\n| `build_mesh_bytes()` | Build binary mesh buffer containing positions, normals, UVs, and indices |\n| `export_quantized_bytes()` | Export mesh in QMSH quantized binary format (compact, lossy) |\n| `get_scene_json()` | Return scene description JSON (nodes, cameras, lights) |\n\n### Physics (5)\n\n| Method | Description |\n|--------|-------------|\n| `get_physics_proxies_json()` | Return collision proxy shapes as JSON |\n| `get_physics_rig_json()` | Return full physics rig descriptor as JSON |\n| `get_capsule_chains_json()` | Return capsule chain descriptors for limbs as JSON |\n| `step_physics(dt)` | Step physics simulation by `dt` seconds (stub) |\n| `set_wind(x, y, z)` | Set wind force vector for cloth/particle systems (stub) |\n\n### Animation (7)\n\n| Method | Description |\n|--------|-------------|\n| `record_anim_frame()` | Record current parameter state as an animation frame |\n| `clear_anim_frames()` | Clear all recorded animation frames |\n| `anim_frame_count()` | Return number of recorded frames |\n| `seek_anim_frame(index)` | Restore parameter state to a recorded frame by index |\n| `play_anim_step()` | Advance playback by one frame, wrapping at end |\n| `get_anim_fps()` | Get current animation playback rate (frames per second) |\n| `set_anim_fps(fps)` | Set animation playback rate |\n\n### Query & Analysis (6)\n\n| Method | Description |\n|--------|-------------|\n| `get_vertex_count()` | Return number of vertices in the built mesh |\n| `get_index_count()` | Return number of triangle indices in the built mesh |\n| `get_curvature_map()` | Return per-vertex curvature values as Float32Array |\n| `get_geodesic_distances(origin_index)` | Return geodesic distances from origin vertex as Float32Array |\n| `query_sphere_near_point(x, y, z, radius)` | Return JSON array of vertex indices within sphere |\n| `get_mesh_segments()` | Return JSON segment map (body part regions by vertex range) |\n\n### Presets & Proportions (5)\n\n| Method | Description |\n|--------|-------------|\n| `set_params_from_preset(preset_name)` | Apply a named parameter preset (e.g., `\"athletic\"`, `\"average\"`) |\n| `apply_preset_by_name(name)` | Apply preset including morph target weights |\n| `get_body_proportions_json()` | Return computed proportional ratios as JSON |\n| `get_param_summary_json()` | Return a summary of all parameters and their current values as JSON |\n| `set_allowlist(names)` | Restrict which targets are eligible for blending |\n\n### LOD & Shaders (2)\n\n| Method | Description |\n|--------|-------------|\n| `get_lod_scene_json()` | Return multi-LOD scene JSON (LOD0–LOD3 meshes) |\n| `list_builtin_shaders()` | Return JSON array of built-in shader descriptor names |\n\n### Cache (2)\n\n| Method | Description |\n|--------|-------------|\n| `has_cached_mesh()` | Return `true` if a built mesh is cached and parameters are unchanged |\n| `reset_incremental_cache()` | Invalidate the incremental mesh build cache |\n\n### Particles (2)\n\n| Method | Description |\n|--------|-------------|\n| `create_particle_system(emit_rate, lifetime)` | Create a new `ParticleSystem` with given parameters |\n| `step_particles(system, dt)` | Advance a particle system by `dt` seconds |\n\n### Expressions (2)\n\n| Method | Description |\n|--------|-------------|\n| `apply_expression_blend(expression_json)` | Apply a facial expression blend from JSON descriptor |\n| `get_cloth_state()` | Return current cloth simulation state as JSON (stub) |\n\n---\n\n## Free Functions\n\n| Function | Description |\n|----------|-------------|\n| `parse_mesh_bytes_header(buffer)` | Parse the format header from a binary mesh buffer; returns JSON with format version and field offsets |\n\n---\n\n## JavaScript/TypeScript Usage\n\n```js\nimport init, { WasmEngine } from \"oxihuman-wasm\";\n\nawait init();\n\n// Load base mesh from an OBJ file\nconst objBytes = new Uint8Array(await fetch(\"human_base.obj\").then(r => r.arrayBuffer()));\nconst engine = WasmEngine.new_from_obj_bytes(objBytes);\n\n// Load a ZIP asset pack with morph targets\nconst packBytes = new Uint8Array(await fetch(\"targets.zip\").then(r => r.arrayBuffer()));\nconst count = engine.load_zip_pack_bytes(packBytes);\nconsole.log(`Loaded ${count} targets`);\n\n// Set body parameters\nengine.set_height(1.75);\nengine.set_weight(0.4);\nengine.set_muscle(0.6);\nengine.set_age(30.0);\n\n// Build mesh and use binary data\nconst meshBytes = engine.build_mesh_bytes();\n\n// Export parameters\nconst paramsJson = engine.export_params_json();\nconsole.log(JSON.parse(paramsJson));\n\n// Query measurements\nconst measurements = JSON.parse(engine.get_measurements_json());\nconsole.log(measurements);\n```\n\n---\n\n## Architecture Notes\n\n- All heavy computation runs in the browser's WebAssembly sandbox — no server communication, no data leakage.\n- `WasmEngine` is `!Send` and single-threaded by design. For parallel workloads, use multiple instances in separate Web Workers.\n- Physics methods (`step_physics`, `set_wind`) and `get_cloth_state` are currently stubs returning placeholder data; full simulation is implemented in `oxihuman-physics`.\n- The `wasm` feature gate keeps native builds free of wasm-bindgen overhead, allowing the crate to be used in test harnesses and CLI pipelines without a browser target.\n\n### v0.1.2 Internal Refactor\n\n`engine.rs` is now a thin re-export module (7 lines). The implementation has been split into four focused source files with no public API changes:\n\n| File | Contents |\n|------|----------|\n| `engine_core.rs` | `WasmEngine`, `ParticleSystem`, `Particle` struct definitions and initialization |\n| `engine_anim.rs` | Animation recording, playback, and frame management methods |\n| `engine_targets.rs` | Morph target loading, unloading, and weight management methods |\n| `engine_io.rs` | JSON import/export, mesh building, physics, query, and preset methods |\n\nTests were moved to `wasm_tests.rs`. All public `#[wasm_bindgen]` method signatures are unchanged.\n\n---\n\n## License\n\nApache-2.0 — Copyright (C) 2026 COOLJAPAN OU (Team KitaSan)\n","readmeFilename":"README.md"}