Skip to content

Changelog: v2.13 ​

v2.13.1 (unreleased) ​

Browser (WebAssembly)

  • Camera and sensor readbacks are much cheaper: readbacks wait once for the GPU instead of twice, readbacks in the stored format are plain copies instead of per-channel conversions, and pixel-pack copies with 256-byte rows stay on the GPU. Buffers created for reading (GL_*_READ) keep a mappable copy of each submission that writes them, so fenced or ring readbacks no longer stall the frame. On an RTX 5070 at 1280×720 the RGB and depth camera examples run at 279 and 157 fps (from 72 and 64), the complete showcase at 80 fps (from 28), and the water stream holds 94 fps (from 42, with 47 ms spikes).
  • Draw recording in the WebGPU layer reuses pipeline keys, vertex bindings and resolved texture bindings while the state they depend on is unchanged, writes scalar uniforms without temporary arrays, and binds uniform groups without per-draw allocation: about 10–15% less frame time in draw-heavy scenes such as the city and off-road examples.
  • Browsers whose GPU samples 32 textures per shader stage now run Rayrai's desktop shader profile instead of the 16-unit one: planar ground reflections, height and parallax maps, subsurface maps and the full projected-decal pool. Textures with identical samplers share WebGPU's 16 sampler slots through a per-program assignment, so materials converge on one shader variant. Vertex inputs no bound array supplies read GL's generic attribute value, and every element of a sampler array names a texture unit.
  • The browser names its GPU adapter in the OpenGL renderer string, so the TCP viewer's automatic render quality matches the native choice for the same GPU (High instead of Balanced on discrete GPUs).
  • Touch input: the examples and TCP viewer take one finger as the left mouse button and a pinch as the wheel, and the scene editor adds pinch zoom and two-finger orbit; a second finger never clicks or leaves a drag pressed. Backing stores are capped at twice the CSS size on high-density phone screens, and canvases follow the visible viewport.

v2.13.0 (unreleased) ​

RaiSim

  • Added a Web menu and tools index for the interactive physics examples and browser scene editor. Both tools share the documentation theme, follow light/dark switches without reloading, and resize their embedded views to fit their controls.

  • New force/torque joint load cells and tactile contact-force grids, with original fixed-link boundaries, impulse-averaged sampling, noise, filtering, latency, checkpoint replay, XML and Python support. The TCP viewer displays their measurements. See Sensors.

  • Load sensor streaming negotiates viewer support, preserving scene viewing with older clients. New force/tactile examples, analytical and replay regressions, and single-threaded benchmarks cover rigid, deformable and granular contacts.

  • Force/tactile acquisition now captures fixed-pad rolling/spinning torque, updates implicit force boundaries after reattachment, and preserves loaded readings during valid split-step pad resizing. Disabling a sensor during a split step stops its acquisition.

  • Sparse tactile accumulation reduces work for lightly loaded grids. Body-indexed contact selection, skipped unrelated contacts, lazy slip calculation, and retained fluid/granular scratch reduce sensor collection overhead. New analytical, delayed-grid replay, overflow and split-step regressions accompany expanded scaling benchmarks.

  • Sensor reattachment now discards old acquisition, filter and latency history while preserving the noise stream. Checkpoint replay covers changes to a registered frame, including offset/orientation edits and pending reattachment.

  • Delayed tactile samples use sparse snapshots when smaller than dense grids, with unchanged queue capacity and drop policy. Joint load collection visits external loads and transmission endpoints once per sensor. Mixed-format queue, noise, pin and subtree regressions accompany new multi-sensor loaded-chain benchmarks.

  • Explicit force/tactile updates reset stale samples after forward or backward world-clock jumps. Declared collision names survive fixed-link merging and work alongside legacy generated names in tactile selectors. A validated geometry-index hint reduces repeated scans for many pads. New named-geometry, clock-jump and deformable-terrain force-balance tests accompany expanded loaded and idle scaling benchmarks.

  • Load-sensor clock revisions and collection-step identities detect small discontinuities at large epochs and skipped acquisitions, including time edits away and back. Extreme finite update rates no longer overflow the deadline clock and stop acquisition. New regressions preserve variable-step, substep and checkpoint behavior.

  • Sorted original-link routing reduces per-contact work for many tactile pads while preserving live selectors, empty-link behavior and all joint-load callbacks. Rigid/granular routing, source-toggle and checkpoint regressions accompany expanded many-pad and numerical-edge benchmarks with timestamp freshness checks.

  • Wrench models preserve small readings after large loads and nearly cancelling opposite loads. Stable interpolation, exponent-aware extreme bias/noise arithmetic and safe bandwidth products prevent cancellation, overflow and premature underflow; checkpoint replay covers the extended filter state.

  • Delayed force/tactile delivery decodes only the newest due snapshot, retaining interval, delivery-time and drop-count semantics. Rigid angular calculations skip exactly stationary rotation. New analytical runtime-inertia and burst-delivery regressions accompany a 46-case benchmark matrix with noise, bandwidth and delivery-burst modes.

  • Joint-sensor boundary setup now uses linear link/body passes and retains its cache for model-only edits. Exact zero checks preserve tiny pin reactions and reject ambiguous tiny fixed-cut loads. Registered frame and tactile coordinate checks prevent invalid indexing; custom attachments must match their registered pose. Seven new regressions and cold/reconfiguration timing expand the suite to 59 sensor tests and 49 benchmark configurations.

  • Fixed-cut inertia is accumulated about its center of mass to preserve small intrinsic terms at distant mounts. Frame preflight rejection preserves earlier sensors' acquisition history; large-offset and repeated-failure replay checks cover both corrections.

  • Scaled acquisition preserves representable means across extreme impulse products, contact moments and tactile weights. Granular contacts retain substep durations and tiny rolling couples reach articulated dynamics. Tactile CoP/slip normalize before queueing; compensated phase and latency clocks avoid early delivery and accumulated epoch rounding. Joint-load preparation skips unused fluid scratch construction and repeated activation queries. Eleven new regressions expand force/tactile coverage to 70 tests; 61 benchmark cases include numerical, fluid and shared-taxel workloads.

  • Joint sensors preserve small supported wrenches under large internal pin, tendon and self-contact loads, using actual solver force pairs and moment arms. Partial fixed cuts validate exact initialized merged-body properties, including tiny and pre-acquisition edits; whole-body setup skips unused recomposition. No-contact split stepping now validates and collects sensors and clears removed systems safely. Eight new regressions bring force/tactile coverage to 78 tests; 80 benchmark configurations add merged cuts, COM offsets, rotation, no-contact stepping and internal preloads. Compact whole-body boundary storage and gated fluid/rotation work reduce preparation cost. The socket-audit watchdog also remains armed through reader completion.

  • Add unrestricted WebAssembly physics and a Rayrai WebGL2 browser profile with four interactive documentation examples, stripped release artifacts, packaging audits and browser benchmarks. Native build paths remain separate.

  • Browser examples persist verified WASM bytes by content hash, revalidate versions without downloading matching binaries, and recover from failed downloads or denied storage. New cache, incremental-manifest and C++ WebGL context/unsupported-compound regressions cover the loader and renderer.

  • Browser rendering shares sphere/capsule vertices, skips unchanged instance uploads and shadow passes, and avoids paused redraw and sensor-UI work. Exact geometry/pixel/metric comparisons and serial static, orbit and moving-scene benchmarks cover the changes. Correct WebAssembly dynamic-array allocation fixes joint-state corruption; shared native/WASM allocation and reference-pendulum regressions cover the fix.

  • Add an interactive browser scene editor with primitive placement, viewport selection/dragging, a transform/size/mass/color inspector, undo/redo, local drafts, physics previews and desktop-compatible .rscene downloads. A separate cached WASM module, shared stream parser, native round-trip checks and browser interaction/scaling benchmarks cover the editor.

  • Browser review fixes preserve WASM state across cached-page restoration, recover coupled rotations at exact pitch singularities, bound and canonicalize local drafts, preserve failed drafts for recovery, and reject underflowing numeric literals before they become zero. Raw editor loads accept only the supported solver/profile settings. New lifecycle, draft, format-boundary and rotation regressions accompany 128-object contact-pile benchmarks.

  • Linux releases add a separate architecture-neutral webassembly-<version>.zip, containing only audited browser assets, manifests, notices and preview instructions. Web prerequisites are checked before version edits; the prepared bundle is reused for documentation. Archive integrity, deterministic/atomic packaging and failed-upload rollback regressions accompany a serial packaging benchmark.

  • A local linux_install.sh installs the complete documentation website in raisim2Lib/web, with the browser examples and editor in its web-examples directory, so web/serve.py opens the home page and the Web menu leads to the tools. update_doc.sh --install-root refreshes only the website. Releases publish the website whether or not the version changes, and keep their documentation and browser build caches apart from local installs.

  • The browser examples and scene editor are full-screen tools in the website's style: the scene fills the window, with the menu, controls and readings floating over it. A progress bar shows the simulator download, the compile and scene stages, and robot asset downloads. A render panel exposes every renderer setting the browser supports, with Fast, Balanced, High and Ultra presets.

  • The browser scene editor adds robots: a library of raisim2Lib's robots with a preview of each, and drag and drop of a local URDF with its meshes or folder. Previews are saved next to each URDF as <name>.preview.png, and the browser loads web-optimized copies of the robot meshes and textures. Exported scenes store robots as Engine 2 articulated_resource and articulated records.

  • raisim::World(path) and rscene::addToWorld now build the articulated systems of .rscene files, as Engine 2 does: the record's pose sets the base, then its joint state applies. rscene::referencedFiles includes their URDF and meshes.

  • The browser examples page is now rayrai_tcp_viewer itself, compiled to WebAssembly. Every RaiSim example built with RaisimServer runs in it, from its unchanged source, each in a worker of its own; example pages and their tiles in the example gallery have a Run on web button. The viewer also connects to RaisimServers on this computer, and through a local web/serve.py copy, on the local network.

  • The documented rayrai examples run in the browser too, each on a page of its own (web-examples/example.html?example=rayrai_offroad_buggy) and from its unchanged source: ExampleApp draws on the page's canvas through WebGPU. Their example pages and gallery tiles have the same Run on web button. Before an example downloads its models and textures, the page asks, naming their size; a declined download fetches nothing. The visitor can keep the files in the browser (checked by default): the example then starts without downloading next time, files are checked against the manifest's SHA-256 and replaced when a release changes them, and a footer button removes them. The viewer, the scene editor and the example pages also keep the shader programs they compile (Cache Storage, one simulator build at a time): the City example's second visit starts drawing after about 4 s instead of 9 s.

  • ExampleApp (rayrai/example_common.hpp) has beginViewport() and endViewport() for an example that handles the pointer itself between the two, and renderViewer() now draws the viewer's image after updating it: its first frame was a blank texture, and a frame after a window resize drew a deleted one.

  • The rayrai examples share their screenshot, sensor-panel and conversion code (examples/include/rayrai_example_utils.hpp), and rayrai_city and rayrai_warehouse one program (photoreal_scene.hpp). rayrai_forest finds rsc/forest with exampleRscPath() like the other examples instead of a path compiled into it.

  • RaisimServer accepts browser viewers on its TCP port over WebSocket. It serves pages from https://raisim.com and from this computer; RaisimServer::allowWebViewerOrigin() adds others, so a web site cannot drive a local simulation. Discovery beacons now carry the server's process id. RaisimServer also compiles for WebAssembly, where a channel in shared memory replaces the socket.

  • rayrai_tcp_viewer lists the server examples built next to it (raisim_server_examples.tsv, written by the examples build) and starts one with a click or --example NAME, then connects to it over loopback. The example's name, state, output and Stop example button are on an Example output tab of their own; the example ends with its session (disconnecting, the server dropping the connection, or starting another session in the pane), and the tab keeps the output of an example that ended until it is cleared. Terminal color codes are removed from the output. --examples-dir DIR lists the examples of another folder.

  • linux_install.sh and web/build_examples.py install Emscripten 4.0.0 themselves when it is not set up, and keep it, OpenUSD and the shader compiler sources in ~/.cache/raisim/web (RAISIM_WEB_CACHE_DIR) instead of the system temporary folder. The OpenUSD build rebuilds itself when the compiler or recipe changes, and the browser modules no longer contain build-machine paths. A browser build directory configured with another Emscripten SDK, such as the one that used to live in the temporary folder, is configured again with the current SDK; it used to keep the old SDK and stop with "Build the Emscripten zlib port with embuilder before configuring". When Emscripten is not set up, the browser build installs emsdk from its 4.0.0 release tag: the latest emsdk script needs Python 3.10, so the install stopped on Ubuntu 20.04 (Python 3.8), which the release image uses. linux_install.sh builds with 16 jobs, the documentation and browser builds included; run on their own, update_doc.sh and web/build_examples.py use RAISIM_BUILD_JOBS (6 when unset).

  • RaiSim's messages (RSINFO, RSWARN, ...) are flushed as they are printed. When standard output went to a pipe or a file, such as the log of an example started from rayrai_tcp_viewer or a CI log, they used to appear only when the buffer filled or the program exited, and were lost in a crash.

  • The browser tools are smaller and faster. Each WebAssembly module is about 3 MB smaller: the web build reads only the mesh formats the tools use (OBJ, STL, COLLADA, glTF, PLY, FBX, 3DS). Physics and rendering use WebAssembly SIMD, with results identical to the scalar build. GL calls reach the WebGPU renderer by operation number instead of by name, state queries no longer rebuild a table, unchanged framebuffer and draw-buffer bindings and new buffers no longer end a render pass, and texture uploads whose layout already matches are copied row by row; 8-bit uploads that change layout (RGB images stored as RGBA) are packed straight into the frame's staging buffer, 4.5 times faster than before (101 ms to 22 ms for a 2048 × 2048 RGB image). The volumetric cloud noise shares its slices with the decode workers already running, instead of filling them on the page's main thread alone. Together with the loading fix below, the City and Warehouse examples finish loading in about 12 s instead of 23–30 s on the test machine (NVIDIA RTX 2070 SUPER, Chrome). A draw reuses its texture views, samplers, vertex layouts and bind groups while they are unchanged and binds the uniform block at a dynamic offset, and a render pass is sent only the pipeline, bind group, buffer, viewport and scissor changes, not the calls that repeat its current state: the browser renderer's CPU time per draw dropped about five times, with identical pixels. Each in-browser example starts two threads instead of six, and the viewer downloads the server examples and the example's assets while it starts, six files at a time.

  • Fixed in the browser viewer: water (Fluid Stream, Fluid Stream with ANYmal and the other fluid examples) stopped the viewer with "Unsupported Rayrai WebGPU operation: glCopyTexSubImage2D" and then on depth clamping; both now render. A vertex shader input the shader never reads no longer fails WebGPU pipeline validation (Sensor Suite, Synchronous Server Update), and examples whose robots load sensor or actuator files next to their URDF (Sensor Suite) download those files with their assets. rayrai_tcp_viewer --render-quality fast|balanced|high|ultra (in the browser, ?quality=) picks a render preset. The browser modules link without "loop not unrolled" warnings: the small loop-constraint groups now check their apparent inverse mass after the loop, so the loop can be unrolled under WebAssembly exception handling as on desktop, with identical results. The browser viewer keeps its settings (render quality and every other render, camera and UI setting, recent connections) in the page's local storage; it used to start with --no-save-settings, and its files lasted only as long as the page, so every visit started from the defaults.

  • Fixed in the browser tools: a file written into the viewer or the editor could fail after another thread had grown WebAssembly memory, and generating mesh tangents on the page's main thread could hang when every pooled worker thread was busy (more likely on computers with many cores).

  • Fixed in the browser renderer: a depth texture read through a regular sampler (FXAA and other post effects) failed WebGPU validation, volumetric clouds froze the page when the computer has more cores than the module's thread pool (the High and Ultra presets), the TCP viewer could draw a render target that its update had just replaced, an untextured shadow or depth draw failed when a previous pass had left a depth texture on its diffuse unit, and clears limited to a scissor rectangle or to some channels were rejected (shadow cascade and atlas tiles). Both stopped the scene editor at the Ultra preset.

  • Fixed in the browser viewer: the Balanced, High and Ultra render presets stopped it with "Browser render quality requires unbiased texture sampling". WebGPU samplers have no texture LOD bias, so the browser applies the presets without their small one (0.05 to 0.28 mip levels). Point clouds, such as the lidar scan of Sensor Suite, and rain or snow stopped the viewer once they appeared ("RayRai shader 'pointcloud' failed to compile or link"): WebGPU draws points one pixel wide, so the browser renderer now draws GL point sprites as quads of the point size, with gl_PointCoord, per-point sizes and glPointSize as in OpenGL. Texture copies between sRGB and linear or integer textures keep their values, and a copy into an RGB texture keeps its alpha of one. The High and Ultra presets also stopped a new viewer with "Rayrai texture is unbound: uBloomTexture" (then bloomDirtTexture); the post-processing pass now gives every sampler it declares a texture, a neutral one for effects that are off. Scenes with large foliage groups (RScene Server) stopped with "Unsupported Rayrai WebGPU operation: glGenQueries": in the browser, the group draws instead of waiting for an occlusion query, which a browser returns only after a GPU round trip. Volumetric cloud textures could freeze the page (Underwater ROV) when the page's worker threads were busy; the browser now builds them on the calling thread. The forest of RScene Server then stopped the viewer on GPU timer queries (the foliage depth-pass tuner, which the browser now leaves at its deferred-depth mode; both modes render the same image) and on a texture alpha-size query while loading its tree models; both now render.

  • Fixed in the browser: the photoreal examples (City, Warehouse, Forest and others) sometimes froze while loading. Rayrai saved mesh-preparation caches beside the assets with a temporary file and a rename, and the browser's file system (WASMFS) can deadlock a rename against path lookups on other threads. The browser no longer writes these caches; its files last only as long as the page, so they were never read back.

  • Fixed in the browser renderer: a texture uploaded in BGRA order (the raw camera images of the Complete Showcase) was rejected, a sky drawn from a baked weather environment left the procedural sky's lookup textures unbound (Deformable Terrain), the glass trace shader (Nested Glass) failed to translate to WGSL (the shader compiler no longer applies the SPIR-V pass that produced it, and every program's WGSL is slightly smaller without it), the camera frustum guides stopped the RGB Camera, Depth Camera and Complete Showcase twice (their line-width range query was unsupported, and their lines took the depth offset GL applies to filled polygons only, which WebGPU rejects for lines), and the water flow's four float render targets exceeded WebGPU's default per-pixel output budget (Water Stream); the browser now asks the adapter for its full budget.

  • Rayrai builds its procedural cloud textures about four times faster (in the browser, 2 s instead of 9 s, which had held the page long enough for a server to drop the viewer of Underwater ROV), with identical texels: the noise reads per-octave lattice tables instead of hashing every sample.

  • Fixed in rayrai_tcp_viewer: when the left panel collapsed, its logo chip was drawn for one frame at the size of the open panel, a large light rectangle; in the browser at the High and Ultra presets it stayed for seconds while the first scene frame rendered.

  • Rayrai draws a URDF primitive visual without a material in RaiSim's default opaque gray; it was transparent, so robots such as the chain examples showed only their shadows.

  • The browser examples render two to four times as fast, with the same images: on an RTX 2070 SUPER, City went from 9 to 40 frames per second, Offroad Buggy from 17 to 48, Forest from 19 to 30 and Warehouse from 25 to the display's 60. The browser renderer sends glFlush and glFenceSync to the GPU without starting a new frame, so the processor no longer waits for the GPU's previous frames; it reuses the storage of a buffer glBufferData gave new contents of the same size, and fills new buffers with queue writes instead of mapping them, which cost the browser a shared-memory allocation per buffer; it keeps a bind group for every set of resources a draw binds, and names render pipelines by the GL state they depend on without building their descriptors. Large uniform arrays, such as the lights and the shadow cascades, move into uniform blocks of their own, so a draw copies only the uniforms that changed (2 KB instead of 5 KB for a PBR mesh), and a uniform block that did not change keeps the copy an earlier draw made.

  • The browser examples load faster: Offroad Buggy in about 17 s instead of 28 s on a first visit (14 s instead of 25 s after), City, Warehouse and Forest in 9 to 15 s instead of 14 to 30 s on a first visit (4 to 7 s after). The browser renderer no longer waits for the GPU at every fence of a mesh upload or maps every new buffer, and compiling a shader program no longer validates its SPIR-V twice.

  • World::integrate() visits, in each step phase, only the objects that phase acts on: the moving objects, and the articulated systems, granular systems, deformables and deformable terrains it updates. Worlds with many static colliders step faster with the same results; the Offroad Buggy's track (2006 static colliders) takes 144 µs per step instead of 253 µs (205 µs instead of 363 µs in the browser).

  • "Remove files saved in this browser" also stops the page from saving the shader programs it compiles afterwards; they were saved again, and the button came back.

RaiSim — physics for robotics and AI.