.rscene File
.rscene is the text scene format written by RaiSim Engine 2, the internal
world-authoring tool (see RaiSim Engine 2). RaiSim builds the physics
world from it, and rayrai shows the rest of the scene the way Engine 2’s editor
viewport shows it: render settings and sky, lights, local fog, reflection
probes, visual-only objects, instanced visuals, terrain foliage and textures,
and the camera. This page describes the format as these two readers see it:
the syntax, every record and field they read, how references to other files
are resolved, and what they reject or ignore.
Availability
The reader is new in v2.8.0. XML includes, a RayraiWindow that shows its
world’s scene by itself, raisin::setRsceneRenderSettings and
raisin::rsceneVisuals are new in v2.8.2, which is not released yet; v2.8.0
and v2.8.1 show a scene with raisin::applyRscene (see
Changelog: v2.8). It is part of the RaiSim and rayrai libraries:
raisim/Rscene.hpp(RaiSim):raisim::World(path)for a path that ends in.rscene(in any letter case),<include value="scene.rscene"/>in a RaiSim XML world configuration file,World::getRscene(), and the lower-levelraisim::rscene::load,rscene::applyPhysicsandrscene::addToWorld.rayrai/RayraiWindow.hpp(rayrai): araisin::RayraiWindowon such a world shows the scene.rayrai/RsceneVisuals.hpp:raisin::rsceneRenderSettings,raisin::setRsceneRenderSettingsandraisin::rsceneVisuals.
The v2.7.0 package has neither the reader nor rayrai/RsceneVisuals.hpp,
so code that uses them does not compile against it. Its World(path) constructor does not recognize the
extension either: it searches the file for a <raisim> or <mujoco>
element, finds neither, and returns an empty world without an error.
Engine 2 itself is not public, so scenes reach you as files, for example
rsc/forest/rayrai_forest.rscene or rsc/rayrai/blue_wall/blue_wall.rscene.
You can also write a file by hand or generate one from a script; the rules on
this page are what the readers enforce. Example file is a complete scene
that loads.
Loading a scene
Physics only
#include "raisim/World.hpp"
raisim::World world("scene.rscene");
for (int i = 0; i < 1000; ++i) world.integrate();
World(path) parses and checks the whole file first, then applies the solver
settings and contact materials and adds the terrain, the bodies and the wires.
The parsed scene stays available through world.getRscene(), which returns
nullptr for a world built any other way, except from a RaiSim XML world
configuration file that includes the scene (see A robot in a scene). A file that the reader rejects is
a RaiSim fatal error, which exits the process unless you install a fatal
callback (see Logging System). If the callback returns instead of
throwing, the world keeps the bodies added before the error and
getRscene() returns nullptr.
To add a scene to a world you already have, or to receive errors as exceptions, call the steps yourself:
#include "raisim/Rscene.hpp"
#include "raisim/World.hpp"
raisim::World world;
try {
const auto scene = raisim::rscene::load("scene.rscene"); // parse and check
const auto report = raisim::rscene::addToWorld(scene, world); // settings and bodies
std::cout << report.bodies.size() << " bodies, " << report.colliders << " colliders\n";
} catch (const std::exception& error) {
std::cerr << error.what() << '\n'; // e.g. "scene.rscene: line 12 (object): ..."
}
rscene::load reads and checks the file without touching a world.
rscene::addToWorld calls rscene::applyPhysics(scene.physics, world),
which overwrites the world’s solver settings and sets the contact material
pairs, then adds one height map per terrain_region record, one body per
object record that has a physics body (one body per collision shape for a
.rasset object; report.bodies holds its first part and
report.colliders counts them all) and one spatial tendon per wire
record (report.wires). A world filled this way does not keep the scene, so
world.getRscene() stays nullptr: keep the Scene yourself if you
also want to render it.
Physics and rayrai rendering
#include "raisim/World.hpp"
#include "rayrai/RayraiWindow.hpp"
auto world = std::make_shared<raisim::World>("scene.rscene");
raisin::RayraiWindow viewer(world, 1280, 800); // shows the whole scene
while (running) {
world->integrate();
viewer.update(1280, 800, false, 0, 0, false);
}
A RayraiWindow whose world holds a scene (world->getRscene()) applies
it when it is constructed, and again when swapWorld gives it a new world;
no call is needed. It applies, in this order, the quality preset and render settings
(rayrai_render and environment), the background (a plain color, an
HDR image, or the rayrai sky configured by weather), the objects the RaiSim
world does not draw (visual-only objects and the visual meshes of visible
.rasset objects), the lights, the local fog volumes, the reflection probes,
one InstancedVisuals batch per enabled instanced_visual record (in file
order), the terrain foliage, the terrain textures and the first enabled
camera. Bodies and height maps are drawn from the world like any other RaiSim
object; the hidden .rasset colliders are not drawn.
raisin::rsceneVisuals(viewer) returns the visuals and batches it created
(objects, instancedVisuals and foliage).
Meshes load asynchronously, as for any other visual. A visual appears once its mesh is ready;
viewer.pendingAsyncMeshLoadCount()counts the rest, for example to show a loading bar.viewer.setAsyncMeshLoadingEnabled(false)loads the remaining meshes before it returns, for example before rendering a sensor image, and loads later meshes synchronously.Settings changed after construction (
setRenderQualitySettings,getLight,getCamera) override the scene’s.A scene rayrai cannot show, for example one with a missing texture, mesh or HDR file (see Rejected content), is a RaiSim fatal error in the constructor. A render record the file omits, and every key it omits, takes Engine 2’s default, so a file without
environment,weatherorrayrai_renderrecords still applies. RaiSim stores these records without interpreting them, so rayrai is the first to check their keys.
To change the file’s render settings in C++, start from the file’s own and pass
them to setRsceneRenderSettings (rayrai/RsceneVisuals.hpp). The viewer
applies the scene again with them, in place of the constructor’s application:
the previous visuals, batches and reflection probes are removed, and their
meshes are reused. It is a fatal error when the viewer’s world holds no scene.
#include "rayrai/RsceneVisuals.hpp"
auto render = raisin::rsceneRenderSettings(*world->getRscene());
render.quality.addViewerFillLights = false;
render.weather.timeOfDayHours = 18;
raisin::setRsceneRenderSettings(viewer, render);
With weather enabled, rayrai derives exposure, environment intensity, fog and
shadow strength from the base settings and the sky. Change the base values in
render.quality and render.weather this way instead of reading them back
from the viewer and setting them again. Applying the scene replaces the
viewer’s additional lights, local fog volumes, projected decals and irradiance
volumes, so add your own afterwards.
Rayrai Example: Forest From .rscene loads the shipped forest scene
this way. Every .rscene file in the RaiSim and raisim2Lib repositories
loads, and the image matches Engine 2’s viewport; only two Engine 2 test
inputs, which are deliberately not loadable, are excluded.
Physics on a server, rendering in the TCP viewer
#include "raisim/RaisimServer.hpp"
raisim::World world("scene.rscene");
raisim::RaisimServer server(&world);
server.launchServer();
while (running) server.integrateWorldThreadSafe();
rayrai_tcp_viewer draws the bodies the server streams. It also applies the
scene, from the same file on the server’s computer or from a copy elsewhere, so
it shows what the in-process viewer above shows. A viewer
on another computer that lacks the scene’s files asks its user, then
downloads them from the server (see Raisim Server and
RaiSim Engine scenes).
Server Example: Rscene Server serves the forest scene.
A robot in a scene
A RaiSim world configuration file (World Configuration File) can include
a scene. The robot, its initial state and its controller gains stay in the XML
file, and the scene it runs in stays in the .rscene file, so either can be
swapped without editing the other:
<raisim>
<include value="[THIS_DIR]/../../city/rayrai_city.rscene"/>
<objects>
<articulated_system name="anymal" urdf_path="[THIS_DIR]/../../anymal_c/urdf/anymal.urdf" convexify_meshes="1">
<state qpos="-36, -1.6, 0.56, 0.2675, 0, 0, 0.9636, 0.03, 0.4, -0.8, -0.03, 0.4, -0.8, 0.03, -0.4, 0.8, -0.03, -0.4, 0.8"
qvel="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"/>
</articulated_system>
</objects>
</raisim>
auto world = std::make_shared<raisim::World>("anymal_in_city.xml");
raisin::RayraiWindow viewer(world, 1280, 800); // the robot and the whole scene
anymal_in_city.xml
is this file with joint PD gains. Rayrai Example: City From XML
loads it in process, and rayrai_tcp_viewer --simulate anymal_in_city.xml
runs and shows it, the scene included.
An
<include>whose path ends in.rscene(in any letter case) loads the scene with the same checks asWorld(path). Like any include, it loads before the including file’s own content, so the scene’s bodies precede the robot in the world’s object list. A relative path names a file in the working directory or, if there is none, a file relative to the folder of the including XML file.[THIS_DIR]in front of the path selects the folder explicitly.The scene’s solver settings and contact materials apply first. Elements in the XML file (
timeStep,gravity,erp,simulation,material) override them; the settings the XML file does not name stay as the scene set them.world.getRscene()returns the included scene, so aRayraiWindowand the TCP viewer show its render records as for a scene loaded directly.A world holds at most one scene. A second
.rsceneinclude, also one in a nested XML include, is a fatal error.The path can be a template parameter: with
<include value="@@scene"/>,raisim::World world("robot.xml", {{"scene", "/path/to/forest.rscene"}})puts the same robot in another scene.
The world is the one the scene and C++ code build together: loading the scene
with World(path) and adding the robot with addArticulatedSystem gives
the same objects, settings and trajectories.
File syntax
A .rscene file is text with one record per line. A trailing \r
(Windows line ending) is treated as white space.
tag positional0 positional1 ... key=value key=value ...
Header. The first record must be
raisim_engine_scene 2or, in an older file,raisim_engine_scene 1(see Versioning). Blank lines and comments may come before it.Tokens are separated by spaces, tabs or carriage returns. The first token is the record tag. A token without
=is a positional field; a token with=is akey=valuefield, split at its first=. All positional fields must come before the firstkey=valuefield, and a key may appear only once in a record. This page numbers positional fields from#0, the first field after the tag.Escaping.
%XX(two hexadecimal digits, in either case) encodes one byte, for exampleForest%20mudforForest mud. Spaces and tabs must be escaped because they separate tokens. A value that is exactly-is the empty string, and so is nothing after=; a value that really is a dash is written%2D. Engine 2 escapes every byte up to0x20as well as%,=and;, and writes a lone dash as%2D.Comments. A line whose first character other than white space is
#is a comment and is skipped without being split into tokens, so it may contain any text. There are no end-of-line comments: a#after a record’s fields is read as another field. Engine 2 only accepts a#in the first column, so start comments there in files Engine 2 must also read.Order. After the header, records may appear in any order, except that a
terrain_splat_layerorterrain_foliage_layerrecord must follow theterrain_regionit names. A repeatedtime_step,gravity,solver,asset_root,scene_graph,environment,weatherorrayrai_renderrecord replaces the earlier one; the other records accumulate.Required and optional fields. The positional fields listed for a record are required; a few records accept the shorter layouts of older files, as noted. Every
key=valuefield is optional: a key that is absent or empty takes Engine 2’s default, listed with the record, exactly as Engine 2’s own loader does. A present value of the wrong type is an error, where Engine 2 would silently keep its default. Keys the readers do not use, and positional fields after the ones they use, are ignored.
Value types
Type |
Syntax |
|---|---|
number |
A finite decimal floating-point number in the C locale, such as |
integer |
A number without a fractional part, in the 32-bit signed range. |
flag |
|
group |
An unsigned 64-bit decimal integer, used for collision groups and masks.
|
vec2, vec3 |
Two or three positional numbers ( |
quat |
Four positional numbers in |
color |
Three or four comma-separated numbers, |
list |
Numbers separated by |
name |
One of the names listed with the field. Names are matched in any letter case, and the aliases Engine 2 accepts are accepted too; any other name is an error. |
text |
Any escaped string. |
Versioning
The number in the header is the format version. Engine 2 writes version 2 and reads versions 1 and 2; the RaiSim reader reads both as well. Within a version, Engine 2 has added keys over time; a file that lacks a newer key takes the default listed here.
The two versions differ in one place, the base of asset_root:
Version 2:
asset_rootis relative to the directory that contains the.rscenefile (or absolute), in Engine 2 and in RaiSim. See Paths and assets.Version 1: Engine 2 read
asset_rootrelative to the scene file, except for a scene inside an Engine 2 project, where it was relative to the project root (with.meaning the project’s asset directory) and Engine 2 also looked for references in the project root. The RaiSim reader does not read Engine 2 project files, so it accepts a version-1 file only when itsasset_rootis absent,.or absolute, which means the same in both cases. Any other version-1asset_rootis an error. Open and save such a scene in Engine 2, which writes version 2, or change the header to version 2 if the path is relative to the scene file.
Every scene shipped in the repositories is a version-1 file with
asset_root . whose references are relative to the scene file, so both
versions read them the same way.
Conventions
Units are SI: metres, kilograms and seconds, and m/s for speeds. Camera fields of view, cone angles and the weather’s angles are in degrees.
Frame. Poses are in RaiSim’s world frame: right-handed with
+zup.Rotations are quaternions in
w x y zorder. Primitive bodies normalize them; a.rassetobject needs a unit quaternion (squared norm within1e-5of 1); instanced-visual quaternions are normalized by rayrai.Node paths such as
/World/Props/Crateare names. The path becomes the RaiSim object name (world.getObject("/World/Props/Crate")) or the rayrai visual or batch name. A node also has anid(default: a record-specific prefix and the path, such asobject_/World/Props/Crate); other records refer to it by id or path.Folders and parents.
grouprecords are folders: they organize the scene tree and carry no transform. A node’sparentGroupIdnames its parent by id or path. A node in a folder, or whose parent does not exist, is placed in the world frame, as in Engine 2. A node whose parent is another node (an object, light, terrain and so on) would inherit that node’s transform, which the readers do not evaluate, so it is an error, unless thescene_graphrecord setsinheritedTransforms=false.Colors are linear RGB or RGBA with components in [0, 1].
Primitive sizes come from an
objectrecord’s scale, radius and height; see object record.Height maps store
xSamples * ySamplesheights row by row: the sample at grid index(x, y)isheights[y * xSamples + x], located atcenterX - xSize/2 + x * xSize/(xSamples - 1)andcenterY - ySize/2 + y * ySize/(ySamples - 1). Heights are relative to the record’s centerz. Per-sample paint lists use the same order. See Height Map.Cameras look along their local
+xaxis with local+zup, so the identity quaternion looks along world+x.Light directions point the way the light travels, from the light toward the scene. They need not be unit length.
Paths and assets
File references (meshes, .rasset descriptors, textures and HDR images) are
resolved by Scene::resolve, with the same rule Engine 2 uses for a
version-2 scene:
An empty or absolute path is used as it is.
A relative path is first tried against the directory that contains the
.rscenefile, and used if that file exists.Otherwise the path is resolved against
<scene directory>/<asset_root>, whether or not the file exists there; a missing file is reported when it is opened. An absoluteasset_rootreplaces the scene directory.
Without an asset_root record, or with asset_root ., both steps use the
scene directory. Forward slashes work on every platform.
When Engine 2 saves a scene to a file, it makes the file resolve on its own:
It writes version 2, with
asset_rootrelative to the saved file.Inside an Engine 2 project, it first copies assets from outside the project into the project’s asset directory, and
asset_rootnames that directory (for example../assetsfor a scene in<project>/scenes) unless the scene has its own asset root.It rewrites every reference that would no longer resolve to the same file, for example a path relative to the project root or to the directory the scene was loaded from, as a path relative to the saved file.
A scene saved by Engine 2, inside a project or not, therefore loads in RaiSim and rayrai with the same files Engine 2 uses. A version-1 scene saved by an older Engine 2 inside a project may need to be saved again (see Versioning).
To copy a scene, raisim::rscene::referencedFiles(scene) lists every file
RaiSim or rayrai reads for it, as sorted absolute paths: the scene file; each
existing file a record references; the visual and collision meshes of
.rasset descriptors; the buffers and images a glTF, GLB, OBJ (through its
.mtl files) or COLLADA mesh references; and the images in a mesh’s
textures, materials and materials/textures folders, which rayrai
uses for a mesh whose materials name no texture. A reference to a missing file
is left out, so loading the scene still reports it. Keeping the files’ layout
below their deepest common directory keeps relative references working.
raisim::rscene::forEachFileReference(scene, visit) visits every reference
as written in the file and can rewrite it, for example to point an absolute
path at a local copy. RaisimServer uses both to share a scene with a
remote TCP viewer.
.rasset descriptors
A mesh object can refer to a .rasset file, a small XML descriptor that
pairs one visual mesh with collision shapes in the mesh’s local frame
(raisim/Rasset.hpp):
<rasset version="1">
<visual file="model.gltf"/>
<collision type="capsule" radius="0.027" height="0.99"
position="0.001 0.002 0.495" quaternion="1 0 0 0"/>
</rasset>
Paths inside a descriptor are relative to the descriptor. Collision types are
box (size: three full side lengths), sphere (radius),
cylinder and capsule (radius and height; a capsule’s height is
the distance between its hemisphere centers), and convex_mesh (file,
whose convex hull is used). position defaults to zero and quaternion
(w x y z) to identity.
For a mesh object with a descriptor, RaiSim creates one hidden static body
per collision shape, placed by the object’s position, rotation and scale. The
first body is named after the object path and the others
<path> collision <i>. RaiSim never loads the visual mesh: rayrai draws it
for a visible object, and an instanced_visual batch whose meshPath
names the descriptor draws many copies at once. The forest scene draws its
2,068 hidden tree and rock colliders this way with nine batches; seven more
batches draw ground plants from plain glTF files that have no colliders.
Records
Record |
RaiSim |
rayrai |
|---|---|---|
|
Header (required, first record). |
|
|
Solver, contact and sleeping settings. |
|
|
A material pair of the world. |
|
|
Resolves mesh and |
Resolves mesh, texture and HDR paths. |
|
Whether parents pass on their transforms. |
|
|
A folder; no transform. |
|
|
Color of the bodies and terrain that reference it. |
The material of the objects rayrai draws. |
|
Nothing. |
The default material of its objects. |
|
Tints that color the height map. |
Albedo, normal and displacement textures. |
|
A static height map, colored by its paint. |
Drawn from the world. |
|
Weights that color the height map. |
|
|
Stored. |
Scattered instanced foliage. |
|
A ground, box, sphere, cylinder, capsule or mesh body, unless visual-only. |
Visual-only objects and visible |
|
A spatial tendon between two bodies. |
Drawn from the world. |
|
Nothing (see sensor record). |
|
|
Stored (enabled batches only). |
One instanced batch each. |
|
Stored (visible lights only). |
The main light and additional lights. |
|
Stored (enabled volumes only). |
Local fog volumes. |
|
Stored (enabled probes only). |
Reflection probes. |
|
Stored (enabled cameras only). |
The first one becomes the viewer camera. |
|
Stored. |
Render settings and background. |
|
Stored. |
Sky and weather. |
|
Stored. |
Quality preset and renderer settings. |
|
Engine 2 editor state; skipped without being checked. |
Every other record tag is an error (see Rejected content). In the tables
below, RaiSim means the field is applied by World(path) or
rscene::addToWorld, rayrai that a RayraiWindow applies it,
check that the value is checked but not applied, and ignored that
Engine 2 writes it but neither reader uses it. The default column lists the
value of an absent key.
Header record
raisim_engine_scene <version>: exactly one positional field, 1 or
2 (see Versioning).
time_step record
time_step <dt>: the integration time step in seconds (number, RaiSim,
World::setTimeStep). Without the record, the time step is 0.0025.
gravity record
gravity <x> <y> <z>: gravity in m/s² (vec3, RaiSim,
World::setGravity). Without the record, gravity is 0 0 -9.81.
solver record
solver <iterations> <tolerance> <erp> <mode> key=value .... Without the
record, the reader applies the Engine 2 defaults below, not those of
raisim::World; see Solver defaults.
Field |
Type |
Default |
Use (RaiSim unless noted) |
|---|---|---|---|
|
integer |
|
Contact-solver iteration limit, see |
|
number |
|
Contact-solver termination threshold, see |
|
number |
|
|
|
text |
|
ignored |
|
number |
|
Second argument of |
|
number |
|
|
|
number |
|
Passed to |
|
integer |
|
Contact-solver iteration limit, but only when it differs from |
|
number |
|
Termination threshold, but only when it differs from |
|
integer, number |
|
GJK and EPA limits in |
|
integer |
|
Contact points kept per colliding pair. |
|
flag, number |
|
Swept continuous collision detection (m/s, m). |
|
name |
|
|
|
vec3 |
|
Multi-box-prune grid bounds and cell size (m). |
|
flag, number, integer |
|
Multi-box-prune settings. |
|
flag |
|
|
|
number, integer |
|
|
|
number |
|
|
|
flag |
|
|
Solver defaults
Engine 2’s solver defaults, which the reader also uses for a file without a
solver record, differ from those of a default-constructed
raisim::World. A scene that should simulate exactly like C++ code that
uses raisim::World’s defaults must store the right column; the shipped
forest scene does.
Setting |
Engine 2 default |
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
All other solver keys have the same defaults in both. The Example file
uses the raisim::World values.
contact_material record
contact_material <materialA> <materialB> <friction> <restitution> <threshold> <staticFriction> <staticVelocity> <rolling> <spinning>:
the properties of a pair of RaiSim contact materials (RaiSim,
World::setMaterialPairProp with these nine arguments, applied in file
order after the default material). The thresholds are in m/s; see
Material System. id is ignored.
asset_root record
asset_root <path>: the directory, relative to the scene file or absolute,
that is searched for references not found next to the scene file (text). A
version-1 file accepts only . or an absolute path. See Paths and assets
and Versioning.
scene_graph record
scene_graph key=value ...: inheritedTransforms (flag, default
true) says whether a node parented to another node inherits its
transform; see Conventions. The other keys are Engine 2 editor settings and
are ignored.
group record
group <path> key=value ...: a folder of the scene tree. id (default
folder_<path>) is how nodes refer to it in parentGroupId. A folder
carries no transform. parentId, visible, locked and expanded
are editor state and are ignored, as in Engine 2’s viewport.
material record
material <name> <r> <g> <b> <a> <metallic> <roughness> [<er> <eg> <eb> <emissiveStrength> <doubleSided> <six textures>] key=value ....
The first seven positional fields are required; the next eleven are read when
the record has all of them. A scene without material records gets
Engine 2’s default material engine_default (color 0.55, 0.62, 0.72, 1,
roughness 0.55).
RaiSim uses only the color: a body or terrain that references the material
gets the appearance string "r, g, b, a", and one whose material is empty or
names an unknown id gets 0.55, 0.62, 0.72, 1.0. rayrai builds a full
material from the fields below for the objects it draws itself (see
object record), as Engine 2 does; bodies in the physics world are drawn
with their appearance color.
Field |
Type |
Default |
Use |
|---|---|---|---|
|
text |
Display name, and the default id. |
|
|
numbers |
RaiSim, rayrai: base color RGBA. |
|
|
number |
rayrai |
|
|
numbers, flag |
|
rayrai |
|
text |
rayrai, Engine 2: albedo, normal, metallic, roughness, AO and emissive images. Additional material texture keys are preserved and resolved too. |
|
|
text |
|
The identifier that |
|
name |
|
rayrai: |
|
name |
|
rayrai: |
|
name |
|
rayrai: |
|
name |
|
rayrai: |
|
name |
|
rayrai: |
|
name |
|
rayrai: |
|
flag |
|
rayrai |
|
number |
|
rayrai: the |
|
color |
|
rayrai |
|
text (path) |
none |
rayrai: texture that blends the material over the mesh’s own. |
|
flag, vec2, number |
not authored |
rayrai: UV transforms of those texture slots. |
The other material keys (more than a hundred PBR settings) are ignored, as in Engine 2’s viewport.
asset record
asset <name> <primitive> <mesh> key=value ...: an importable asset of the
Engine 2 library. It creates nothing. id (default #0) and
defaultMaterial (default engine_default) decide whether an object
placed from it (assetId) keeps its mesh’s own materials (see
object record); every other field is ignored.
terrain_texture record
terrain_texture <slot> <id> <name> key=value ...: one texture layer. A
scene without terrain_texture records gets Engine 2’s two default layers:
terrain_grass (slot 0, color 0.28,0.43,0.20) and terrain_rock
(slot 1, color 0.42,0.40,0.36, roughness 0.92).
Field |
Type |
Default |
Use |
|---|---|---|---|
|
integer |
Layer index that the terrain’s |
|
|
text |
ignored |
|
|
color |
|
RaiSim: the layer’s tint in the height map’s vertex colors (see
|
|
text (path) |
none |
rayrai: albedo and normal textures. |
|
text (path) |
none |
rayrai: height texture for parallax mapping. |
|
number |
|
rayrai: normal-map strength (negative values act as 0). |
|
number |
|
rayrai: roughness, clamped to [0.04, 1]. |
|
number |
|
rayrai: tiling of the two layers when a second layer is blended in
(the texture repeats every |
aoStrength, detile and displacement are ignored.
rayrai gives every height map one terrain material, as Engine 2 does: the base layer of the first terrain whose base layer has an albedo provides the albedo, normal and displacement textures, normal strength and roughness. When no base layer has one, the first layer with an albedo provides only the albedo. The first layer with an albedo and a slot other than the base slot is blended over the base layer where the terrain’s per-sample paint shows it (see terrain_region record).
terrain_region record
terrain_region <path> <xSamples> <ySamples> <xSize> <ySize> <cx> <cy> <cz> key=value ...:
a sampled height map. RaiSim adds it with World::addHeightMap as a static
height map in collision group 1 << 63 (bit 63) that collides with every
group, so an object whose mask clears bit 63 passes through the terrain.
Field |
Type |
Default |
Use |
|---|---|---|---|
|
text |
RaiSim: the height map’s name. |
|
|
integer |
RaiSim: samples along x and y, at least 2 each, at most 16384 each and 64 Mi in total. |
|
|
number (m) |
RaiSim: extent along x and y, positive. |
|
|
vec3 (m) |
RaiSim: center x and y, and the height offset added to every sample. |
|
|
list (m) |
all |
RaiSim: |
|
text |
|
RaiSim: |
|
text |
|
RaiSim: RaiSim material name for contacts (see Material System). |
|
integer |
|
RaiSim, rayrai: slot of the base |
|
list of slots (0 to 255) |
the base slot |
RaiSim, rayrai: per-sample paint: the two layers a sample shows. |
|
list |
all |
RaiSim, rayrai: per-sample blend from the primary to the secondary layer, clamped to [0, 1]. |
|
colors separated by |
all white |
RaiSim: per-sample color multiplier. |
|
list |
all |
RaiSim: per-sample wetness; a wet sample is up to 18 % darker. |
|
list (0 to 255) |
all |
RaiSim: a non-zero sample is colored almost black. The collision surface stays solid, as in Engine 2. |
|
flag |
|
RaiSim: whether the splat layers decide the colors. |
|
name |
|
check: |
|
flag |
|
check: must be |
|
text |
|
See Conventions. |
A paint list has one value per sample or is empty. RaiSim colors each sample
like Engine 2: with splatting enabled, the tints of the splat layers weighted
by their weights and strengths; where the weights add up to zero, or without
splatting, the primary layer’s tint blended toward the secondary layer’s;
then multiplied by the vertex color, darkened by wetness, and holes made dark.
A slot without a terrain_texture layer has the tint 0.28,0.43,0.20.
location, castShadow, receiveShadow, sourcePath,
cloneSource, the png* and procedural* keys, lodLevels and
collisionShapeSize are ignored.
terrain_splat_layer record
terrain_splat_layer <terrain> key=value ...: a weighted texture layer of
the terrain whose path or id is #0; the terrain_region must come
first. Keys: slot (integer, default 0), enabled (flag, true),
strength (number, 1) and weights (list, one weight per sample;
default 1 for the base slot and 0 otherwise). RaiSim uses the
weights for the vertex colors; rayrai’s terrain texture follows the per-sample
paint, as in Engine 2.
Without splat layers a terrain has one base layer of weight 1. The first
terrain_splat_layer of a terrain replaces that default layer. Engine 2
gives a terrain’s only layer the base slot when all its weights are 1, and the
reader does the same.
terrain_foliage_layer record
terrain_foliage_layer <terrain> key=value ...: plants or rocks scattered
over the terrain whose path or id is #0 (the terrain_region must come
first). RaiSim stores the layer; rayrai scatters it exactly as Engine 2
does, so a scene shows the same instances in both.
Key |
Type |
Default |
Use (rayrai) |
|---|---|---|---|
|
text, text, flag |
|
A disabled layer is skipped. |
|
name, text (path) |
|
A mesh file or |
|
vec3, color, color |
|
Base size and the two colors each instance blends. |
|
list |
all |
Per-sample density in [0, 1]. |
|
number, integer |
|
Instances per square metre at density 1, and the limit. |
|
number |
|
Random uniform scale. |
|
number, flag |
|
Random rotation spreads. |
|
number |
|
Where instances are placed. |
|
integer |
|
Random seed. |
|
flag, integer |
|
The matching |
|
flag, number, integer |
|
|
|
number |
|
|
Each terrain sample places density * densityPerSquareMeter * cell area
instances on average, rounded up or down by the seeded random numbers, jittered
within the cell around the sample, scaled and turned by the random spreads. A
mesh layer is first turned 90 degrees about x, for meshes modelled with +y
up. Each instance stands on the terrain surface (its mesh bounds rest on the
ground) unless it falls outside the height range; a sample outside the slope
range gets none. rayrai keeps a layer in one batch named
<terrain path>/Foliage/<id>, or, for large layers, in 16 m chunks named
<terrain path>/Foliage/<id>/Chunk_<x>_<y>.
object record
object has 25 positional fields followed by keys. Older files have 19
positional fields (#17 visible, #18 fixed, meaning a static or dynamic
body) or 17 (a visible dynamic body).
Field |
Type |
Use |
|---|---|---|
|
text |
RaiSim: object name; rayrai: visual name. |
|
name |
|
|
vec3 (m) |
World position. For a |
|
quat |
World orientation. Keep the identity for |
|
vec3 |
|
|
number (m) |
Sphere, cylinder and capsule size before scaling. A capsule’s height is the distance between its hemisphere centers. |
|
number (kg) |
RaiSim: must be positive for a dynamic body; other modes use 1 kg for a non-positive mass. |
|
text |
RaiSim: RaiSim material name for contacts. |
|
text |
|
|
flag |
Used only when |
|
flag |
|
|
text (path) |
The render mesh, unless the |
|
name |
|
|
flag |
|
|
group |
RaiSim: collision group and mask (see Contact and Collision). A ground uses only the mask. |
An object has a physics body unless it is visual-only or not collidable.
RaiSim gives the body the record’s path as its name, its body mode as
BodyType, its position and rotation, and the appearance of its material.
A ground is always a static half space, as in Engine 2. A mesh body
uses collisionMeshPath, or the render mesh when that is empty:
a
.rassetdescriptor makes static bodies from its collision shapes (see .rasset descriptors); a descriptor object must be static;any other mesh file becomes one
World::addMeshbody with the collision mode ofcollisionMode(ormeshCollision):convex_hull(convexhull,convex, andprimitive,noneordefault, which Engine 2 builds as a hull),original_mesh(original,triangle_mesh,trimesh) orconvexify(coacd,convex_decomposition), with thecoacd*keys as theraisim::CoacdOptionsfields of the same names. A dynamic mesh withcustomInertia=trueusesinertiaDiagonalandcenterOfMass.
rayrai draws the objects the RaiSim world does not show: visible visual-only
objects, and the visual mesh of a visible .rasset object (its colliders
are hidden). A primitive is drawn at the size RaiSim would build; a mesh file
or descriptor’s visual mesh at the object’s scale. A mesh keeps its own
materials when #16 is empty, engine_default or the default material of
its assetId; otherwise the scene material replaces them. With
materialRemaps (source:target items separated by ;; -> and
= also separate the pair), each named source material of the mesh is
replaced by the target scene material instead, and the object’s material
replaces the rest. The visual* keys set the drawn visual: visualUseMeshColor,
visualFlatShading, visualTwoSided, visualDetectable,
visualShadowCasting (inherit, on, off, double_sided or
shadows_only; inherit follows castShadow), visualTransparency,
visualRangeBegin, visualRangeEnd, visualRangeBeginMargin,
visualRangeEndMargin, visualRangeFade (disabled, self or
dependencies), visualAutomaticMeshLod, visualAutomaticMeshLodBias,
visualCustomBounds with visualCustomBoundsCenter and
visualCustomBoundsRadius, visualTransparentSortOffset,
visualTransparentSortUsesBoundsCenter, visualMaterialOverlay (a
material id drawn over the visual) and the visualPbrEnv* keys (an HDR
environment, irradiance and prefiltered map and a BRDF table for the visual).
Their defaults are those of raisin::Visuals.
id (default object_<path>) and parentGroupId follow Conventions.
The raisim* tuning keys, semanticClass, instanceId,
segmentationColor and receiveShadow are ignored, as by Engine 2’s
bridges.
wire record
wire <path> <kind> <bodyA> <bodyB> <length> key=value ...: a distance
constraint between two bodies, named by object id or path (a terrain counts
too), that both have physics bodies. RaiSim adds it with
World::addSpatialTendon under the wire’s path, as Engine 2’s bridge does,
from localPositionA on body part localIndexA to localPositionB on
part localIndexB (defaults 0,0,0 and 0):
stiff(stiff_wire): the length is the tendon’s upper limit;compliant(soft,compliant_wire): a spring over[0, length]withstiffness(N/m, default1000);custom(custom_wire): a slack tendon of that rest length; its force comes from user code.
damping (default 0) and compliance (the limit compliance, default
0) apply to every kind. visualizationWidth (default 0.01) is the
drawn width; 0 hides the wire. enabled=false skips the record, and
id is ignored.
sensor record
sensor <path> <kind> <parent> <x> <y> <z> <qw> <qx> <qy> <qz> key=value ...:
a camera, depth camera, lidar or IMU mounted on a node. The record is parsed
and creates nothing. RaiSim sensors live on articulated systems, which the
reader does not create, and Engine 2 also creates nothing for a sensor on a
rigid body; the frames and frusta Engine 2 draws for sensors are editor
overlays.
instanced_visual record
instanced_visual <path> <primitive> key=value ...: render-only copies of
one mesh or primitive, without physics. A record with enabled=false is
skipped.
Field |
Type |
Default |
Use (rayrai) |
|---|---|---|---|
|
text |
Batch name; must be unique in the viewer. |
|
|
name |
|
|
|
text (path) |
none |
For |
|
vec3 |
|
Base size of the batch. |
|
color |
|
The two colors that each instance blends. |
|
list |
none |
Ten numbers per instance: position |
|
list |
none |
Per-instance blend weight between |
|
flag, integer |
|
The matching |
|
flag, number, integer |
|
|
|
flag, number, integer |
|
|
|
flag, number |
|
When enabled, |
|
flag |
|
check: must be |
terrainBinding, terrainFoliageLayer, densityPreview and the
scatter* and other grass* keys are ignored, as in Engine 2’s
viewport. id and parentGroupId follow Conventions. See
Foliage and forest rendering for the level-of-detail and wind settings.
light record
light <path> <dx> <dy> <dz> <intensity> key=value .... A scene may contain
any number of lights. A light with visible=false is skipped. rayrai
makes the best shadow-casting light the viewer’s main light, preferring a
directional light, then an area, a spot and a point light, and the first of
its kind; every other light becomes an additional light (rayrai keeps up to
16). The light’s frame turns its local -z axis onto the direction; the area
axes are given in that frame.
Field |
Type |
Default |
Use (rayrai) |
|---|---|---|---|
|
vec3 |
Travel direction, normalized (directional and spot lights). |
|
|
number |
diffuse = |
|
|
name |
|
|
|
vec3 (m) |
|
Position of a point, spot or area light. |
|
color, color, number |
white, white, |
See |
|
color |
black |
The light’s ambient term. For the main light, black means the
|
|
number |
|
Distance falloff and source size (see |
|
number (deg) |
|
Spot cone half angles. |
|
vec3 |
|
Area-light width and height (x and y of |
|
text (path), number, vec2, vec2 |
none, |
A texture projected by the light. |
|
flag, flag, number (K) |
|
Subtracting light, and a tint by color temperature. |
|
flag, number (m) |
|
Fading by camera distance. |
|
flag |
|
Whether the light casts shadows. |
|
integer (px) |
|
The main light’s shadow-map size; it overrides the render settings’ shadow resolution for this light. |
|
number |
|
The main light’s |
|
number (m) |
|
The main light’s |
|
vec3, vec3, flag |
|
The main light’s shadow-map placement. |
#0 path and id name the light (default id light_<path>), and
parentGroupId follows Conventions. range is ignored: the
attenuation coefficients decide the falloff, in Engine 2 as well.
local_fog record
local_fog <path> <cx> <cy> <cz> <radius> key=value ...: a spherical fog
volume (rayrai, RayraiWindow::addLocalFogVolume). Keys: color
(default 0.72,0.80,0.90), density (0.12), edgeFade
(0.35), noiseScale (5) and noiseStrength (0.55).
enabled=false skips the record.
reflection_probe record
reflection_probe <path> <x> <y> <z> <radius> key=value ...: a local
reflection probe (rayrai, RayraiWindow::addReflectionProbe) with
strength (default 1) and box projection (boxProjection,
boxMin, boxMax; default off, -5,-5,-5, 5,5,5).
enabled=false skips the record.
With captureOnApply=true, rayrai captures the scene into the
probe, after the objects and lights and before the instanced visuals and
foliage, as Engine 2 does: captureCached (default true) uses rayrai’s
capture cache, cubemapSize (256) the cube face size,
captureFiltered (true) also filters the image with the
irradianceResolution, irradianceSamples, prefilteredResolution,
prefilteredMipLevels, prefilteredSamples, brdfLutSize and
brdfLutSamples settings, and the captureDraw*, captureShadows,
captureEnvironmentBackground and captureEnvironmentExposure keys set
what the capture draws. A probe that is not captured on apply holds no image
and has no effect, in Engine 2 as well.
camera record
camera <path> <x> <y> <z> <qw> <qx> <qy> <qz> <vfov> <near> <far> <width> <height> <mode> <enabled> key=value ....
A camera with #14 set to false is skipped. RaiSim stores the enabled
cameras in Scene::cameras; rayrai applies the first one to the viewer
camera.
Field |
Type |
Use |
|---|---|---|
|
vec3 (m), quat |
rayrai: camera pose; it looks along its local |
|
number (deg) |
rayrai: clamped to [1, 175]. |
|
number (m) |
rayrai: clip distances. |
|
integer (px) |
rayrai: only their ratio is used, as the aspect ratio. |
|
text |
ignored (for example |
|
flag |
|
|
number (deg) |
rayrai: when positive, the horizontal field of view; otherwise
derived from the vertical one and the aspect ratio. Default |
|
text |
rayrai: |
id, parentGroupId (see Conventions), the preview* keys and
outputPath are ignored.
environment record
environment <r> <g> <b> <ar> <ag> <ab> <fog> <shadows> <grid> <gridSize> [<hdr>] key=value ....
RaiSim only stores this record. rayrai starts from the preset defaults of
rayrai_render and applies these fields over them; field names on the right
are RenderQualitySettings members (see Render quality, tone mapping, color grading).
Without the record, every field takes its default.
Field |
Type |
Default |
Use (rayrai) |
|---|---|---|---|
|
numbers |
|
Background color (linear RGB), also |
|
numbers |
|
|
|
number (1/m) |
|
|
|
flag |
|
|
|
flag, number |
ignored (Engine 2 editor grid). |
|
|
text (path) |
none |
Equirectangular HDR image for |
|
name |
|
|
|
color |
|
|
|
number |
|
|
|
number |
|
|
|
integer |
|
|
|
name |
|
|
|
color |
|
|
|
number |
|
|
|
flag |
|
|
|
flag, number |
|
Height fog settings of the same names. |
weather record
weather [<enabled>] key=value .... rayrai reads this record when the
environment background is rayrai_sky; without the record, the sky
uses the defaults below. See Weather and atmospherics.
#0 is WeatherSettings::enabled (default true). Each key sets the
WeatherSettings member of the same name, except that timeOfDay sets
timeOfDayHours. The defaults are Engine 2’s: preset clear (or
hazy, overcast, fog, rain, heavy_rain, snow,
storm, night_clear, night_rain or custom), quality
high (or low, medium or ultra), seed 1, timeOfDay
13, latitude 37, longitude 127, year 2026,
month 5, day 8, windDirection 1,0.25,0, windSpeed
1.5, transitionSeconds 0, affectSensors false,
cloudCoverage 0.05, cloudDensity 0.05, precipitationRate
0, rainOcclusionStrength 0, fogDensity 0,
visibilityMeters 10000, fogColor 0.72,0.80,0.90,
fogAnisotropy 0, humidity 0.35, wetness 0,
wetnessAccumulationEnabled true, wetnessAccumulationRate
0.35, wetnessDryingRate 0.1, snowCoverage 0,
lightningRate 0, lightningLocalPointLightEnabled true,
lightningLocalPointDistance 18, lightningLocalPointRadius 28,
lightningLocalPointIntensity 2.2, thunderSpeedOfSound 343,
airTurbidity 2, groundAlbedo 0.35, useExplicitSunAngles
false, sunAzimuthDegrees 180, sunElevationDegrees 42,
sunDiskSize 0.018, moonDiskSize 0.014,
cloudAltitudeMeters 850, cloudThicknessMeters 180,
cloudShadowStrength 0.04, cloudScale 0.18,
cloudAnimationSpeed 0, lensDropletsEnabled false and
lensDropletStrength 1.
The file stores no UTC offset, so rayrai’s default (an explicit offset of
9 hours) applies to timeOfDay. The wind also drives foliage: with the sky
background, a non-zero windDirection sets the render settings’
foliageWindDirection (its x and y), and a positive windSpeed turns on
foliageWindEnabled with that speed.
rayrai_render record
rayrai_render key=value .... RaiSim only stores this record. preset
(default ultra; fast or low, balanced or medium,
high, ultra or custom) selects
RayraiWindow::defaultRenderQualitySettings(preset) as the starting point.
When custom (default false) is true or the preset is custom,
the keys below are applied after the environment record; otherwise they
are ignored and the preset’s values apply, including
addViewerFillLights = true, which adds two viewer fill lights.
Key |
Default |
Use (rayrai) |
|---|---|---|
|
|
A positive value is rounded down to 1, 2, 4 or 8; |
|
|
A positive value is clamped to [1, 16]; |
|
|
Shadow settings; |
|
|
Cascades, clamped to [1, 4], [0, 1] and at least 0 m. |
|
|
Settings of the same names. |
|
|
Replace |
|
none |
Each replaces the value set so far only when present. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
diagnostics is ignored.
Rejected content
The readers refuse content they cannot reproduce instead of dropping it. Errors found while parsing name the file, the line and the record tag; the others name the object or file involved.
While parsing (rscene::load):
a missing or wrong header, or an empty file;
a version-1
asset_rootother than.or an absolute path (see Versioning);a positional field after a
key=valuefield, a repeated key, a missing positional field, or a value of the wrong type, including a name that is not listed for its field;any record tag not listed in Records, for example
articulated_resource,articulated,articulated_ik,compound,compound_child,deformable,granular,projected_decal,irradiance_volumeandpoint_cloud;a node whose
parentGroupIdnames another node while transforms are inherited (see Conventions);a terrain that is not sampled, is hidden or not collidable, has fewer than two samples per axis, a non-positive size, or a list with the wrong number of values, and a
terrain_splat_layerorterrain_foliage_layerwhose terrain does not come before it;a dynamic object without positive mass;
an enabled instanced visual that is a grass patch or a
ground, or whose instance list is not a multiple of ten numbers;an enabled wire with a negative length or body index.
While adding bodies (rscene::addToWorld):
a
meshobject whose mesh file is missing;a
.rassetobject that is not static or hascustomInertia=true, a descriptor that cannot be read or is invalid, or a rotation that is not a unit quaternion;a wire whose body has no physics body, or whose tendon RaiSim rejects.
While applying to rayrai (RayraiWindow and rsceneRenderSettings):
an unknown preset, color mode, background mode, weather preset or weather quality, or a malformed key in these records;
an HDR background without an image, or an image that cannot be loaded, or a sky that cannot be generated;
a missing texture (terrain layer, material blend texture, light projector or visual environment map) or a missing mesh (visual-only object,
.rassetvisual, instanced visual or foliage layer);an unknown material mode,
visualShadowCastingorvisualRangeFadename, or a material thatvisualMaterialOverlayormaterialRemapsnames but the scene does not define;a reflection probe whose capture fails;
a batch or visual name already in use (a fatal error).
rscene::load and rsceneRenderSettings throw std::runtime_error.
rscene::addToWorld throws std::runtime_error, or
std::invalid_argument for an invalid .rasset instance, so catch
std::exception. World(path) reports any of them as a RaiSim fatal
error.
Two RaiSim Engine 2 test inputs in the repository are deliberately not
loadable: raisim_engine2/tests/data/missing_mesh_scene.rscene names a mesh
that does not exist, and
raisim_engine2/tests/data/full_authoring_scene.rscene, a round-trip
fixture of Engine 2’s own loader, uses every node kind, including the
unsupported ones, and names files that do not exist.
Example file
A crate and a ball dropped into a 4 m × 4 m height-map bowl, lit by one sun
and seen from a camera at (-4, 0, 1.5) looking along +x. The solver record stores the
raisim::World defaults (see Solver defaults). Records must stay on one
line, so the long ones run past the right edge of the box:
raisim_engine_scene 2
# A crate and a ball dropped into a small height-map bowl, lit by one sun.
time_step 0.001
gravity 0 0 -9.81
solver 150 1e-08 1.5 accurate erp2=0.002 defaultFriction=0.8 defaultRestitution=0 defaultRestitutionThreshold=0.01 defaultStaticFriction=0.8 defaultStaticFrictionVelocityThreshold=1 defaultRollingFriction=0 defaultSpinningFriction=0 contactAlphaInit=1 contactAlphaMin=1 contactAlphaDecay=1 contactMaxIterations=80 contactThreshold=1e-07 contactGjkMaxIterations=32 contactGjkTolerance=1e-06 contactEpaMaxIterations=64 contactEpaTolerance=1e-04 maxContactsPerPair=8 sweptCcdEnabled=false sweptCcdMinSpeed=0 sweptCcdSpeculativeMargin=1e-04 sleepingEnabled=true sleepingLinearVelocityThreshold=0.002 sleepingAngularVelocityThreshold=0.01 sleepingQuietSteps=5 broadphaseType=sap3_axis broadphaseWorldMin=-100,-100,-100 broadphaseWorldMax=100,100,100 broadphaseCellSize=1,1,1 broadphaseUseWorldBounds=false broadphasePadding=0.5 broadphaseMaxCellsPerAxis=128 broadphaseMaxCellsPerObject=64 worldTime=0 fixedContactSolverIterationOrder=true
asset_root .
environment 0.6 0.7 0.85 0.3 0.3 0.3 0 true true 10 - fogColor=0.6,0.7,0.85 exposure=1 gamma=2.2 bloomIntensity=0 bloomThreshold=0.8 bloomRadius=4 shadowMapSize=2048 shadowedLightBudget=2 backgroundMode=plain_color colorMode=aces_approx pbrEnvironmentLightingTint=1,1,1 pbrEnvironmentIntensity=1 fxaa=true ssao=false heightFogEnabled=false heightFogDensity=0 heightFogBaseHeight=0 heightFogFalloff=0.35
rayrai_render preset=balanced custom=false
material crate 0.8 0.5 0.2 1 0 0.6 id=crate
terrain_texture 0 grass Grass color=0.3,0.45,0.2,1 albedo=- normal=- uvScale=1 normalDepth=1 roughness=0.9
terrain_region /World/Terrain 3 3 4 4 0 0 0 parentGroupId=- material=- contactMaterial=default baseTexture=0 visible=true collidable=true sourceKind=samples texturePrimary=- textureSecondary=- textureBlend=- wetness=- holes=- vertexColors=- heights=0.3,0.15,0.3,0.15,0,0.15,0.3,0.15,0.3
object /World/Crate box 0 0 1 1 0 0 0 0.5 0.5 0.5 0.5 1 2 default crate false true false - dynamic true 1 18446744073709551615 parentGroupId=- renderMeshPath=- collisionMeshPath=- materialRemaps=-
object /World/Ball sphere 1.2 1.2 1 1 0 0 0 1 1 1 0.15 1 0.5 default - false true false - dynamic true 1 18446744073709551615 parentGroupId=- renderMeshPath=- collisionMeshPath=- materialRemaps=-
light /World/Sun -0.4 0.3 -0.85 3 parentGroupId=- type=directional visible=true shadows=true color=1,0.95,0.85 ambientColor=0,0,0 specularColor=1,1,1 specularIntensity=1 shadowResolution=2048 shadowBias=0.0008 shadowStrength=1 shadowPcfRadius=1 shadowOrthoHalfSize=10 shadowNear=0.1 shadowFar=50
camera /World/Camera -4 0 1.5 0.991445 0 0.130526 0 55 0.05 100 1280 800 rgb true parentGroupId=- projection=perspective horizontalFov=0
World(path) on this file creates three objects: the height map
/World/Terrain and the dynamic bodies /World/Crate (a 0.5 m, 2 kg box
colored by the crate material) and /World/Ball (a 0.15 m, 0.5 kg sphere
with the default color). The terrain’s empty material takes the default
id engine_default, which this file does not define, so the terrain has
the default color as well. Because contactMaxIterations and
contactThreshold hold their Engine 2 defaults, the contact solver uses the
#0 and #1 values, 150 iterations and 1e-8. The camera quaternion
is a 15° rotation about +y, which tilts its +x view direction down.
With custom=false, rayrai uses the balanced preset’s settings over the
environment record, including its two viewer fill lights; the C++ snippet
in Physics and rayrai rendering turns them off.
API reference
-
Scene raisim::rscene::load(const std::filesystem::path &file)
Parses a scene file; throws std::runtime_error on unsupported content. The file must start with the header “raisim_engine_scene 1” or “raisim_engine_scene 2”; lines starting with ‘#’ are comments. In version 2, asset_root is relative to the scene file’s directory. A version-1 file may only use asset_root “.” because Engine 2 resolved a version-1 asset_root against its project root when the scene was in a project. Error messages name the file and line.
- Parameters:
file – [in] path to the .rscene file
- Returns:
the parsed scene
-
void raisim::rscene::applyPhysics(const Physics &physics, World &world)
Applies the scene’s solver settings and contact materials to the world.
- Parameters:
physics – [in] solver settings
world – [inout] world to configure
-
WorldReport raisim::rscene::addToWorld(const Scene &scene, World &world)
Applies the solver settings and adds the terrain, the bodies and the wires. Terrains become static height maps in collision group 1 << 63 colliding with everything. Visual-only objects get no body. Throws std::runtime_error for a non-static .rasset object, a missing mesh file or a wire whose body has no physics body. Non-uniform .rasset scale uses its mean for the collision proxies.
- Parameters:
scene – [in] parsed scene
world – [inout] world to populate
- Returns:
the created bodies
-
std::vector<std::filesystem::path> raisim::rscene::referencedFiles(const Scene &scene)
Every file that RaiSim or a viewer reads for the scene, as absolute paths in lexically normal form, sorted and without duplicates. The list holds the scene file, each existing file the scene references (see forEachFileReference(); resolved with Scene::resolve()), the visual and collision meshes of .rasset descriptors, the buffers and images that a glTF, GLB, OBJ (through its .mtl files) or COLLADA mesh references, and the images in a mesh’s texture folders (textures, materials and materials/textures, recursively), which rayrai picks up for a mesh whose materials name no texture. A reference to a missing file or a malformed .rasset descriptor is left out, so loading the scene reports it. Scenes and their dependencies are trusted input: references may name files outside the scene directory. Enable server file sharing only for scenes whose referenced files may be shared with the viewer. Filename extensions do not establish file confidentiality.
- Parameters:
scene – [in] parsed scene
- Returns:
the files
-
void raisim::rscene::forEachFileReference(Scene &scene, const std::function<void(std::string &reference)> &visit)
Calls visit once for each file reference the scene stores, as written in the file (before Scene::resolve()): mesh paths of objects, instanced visuals and foliage layers, terrain texture images, material and light textures, per-object environment images and the environment record’s HDR map. Empty references are skipped. visit may rewrite a reference, e.g. to point an absolute path at a local copy.
- Parameters:
scene – [inout] parsed scene
visit – [in] called with each non-empty reference
-
struct Scene
A parsed .rscene file (see load()).
Public Functions
-
std::filesystem::path resolve(const std::string &reference) const
Resolves a reference against the scene directory, then its asset root.
- Parameters:
reference – [in] file reference from the scene
- Returns:
an empty or absolute reference unchanged; otherwise scene directory / reference if that file exists, else scene directory / assetRoot / reference (lexically normalized)
-
const Material *findMaterial(const std::string &id) const
- Parameters:
id – [in] material id
- Returns:
the material, or nullptr if none has the id. Points into materials
-
const Asset *findAsset(const std::string &id) const
- Parameters:
id – [in] asset id
- Returns:
the asset, or nullptr if none has the id. Points into assets
Public Members
-
std::filesystem::path file
absolute path of the scene file
-
int version
Format version from the header (1 or 2).
-
std::filesystem::path assetRoot
relative to the scene directory, or absolute
-
Physics physics
Solver settings.
-
Record environment
Render settings stay as records; only a viewer interprets them. A record the file omits has an empty tag, and the viewer uses Engine 2’s defaults for it.
-
std::vector<Material> materials
Render materials.
-
std::vector<Asset> assets
Asset records (their default materials).
-
std::vector<TerrainTexture> terrainTextures
Terrain texture layers.
-
std::vector<Terrain> terrains
Height-map terrain regions.
-
std::vector<Light> lights
Visible lights, in file order.
-
std::vector<Camera> cameras
Enabled cameras.
-
std::vector<Wire> wires
Enabled wires.
-
std::vector<InstancedVisual> instancedVisuals
Enabled instanced-visual batches.
-
std::vector<LocalFog> localFogs
Enabled local fog volumes and reflection probes.
-
std::filesystem::path resolve(const std::string &reference) const
-
struct WorldReport
Bodies created by addToWorld.
Public Members
-
std::vector<SingleBodyObject*> bodies
Owned by the world. For a .rasset object, the entry is its first part.
one per object that has a physics body
-
std::size_t colliders
including every .rasset part
-
std::size_t wires
spatial tendons added for wire records
-
std::vector<SingleBodyObject*> bodies
-
RsceneRenderSettings raisin::rsceneRenderSettings(const raisim::rscene::Scene &scene)
Reads the scene’s render settings; throws std::runtime_error when a record is malformed. Omitted records and keys take RaiSim Engine 2’s defaults.
-
void raisin::setRsceneRenderSettings(RayraiWindow &viewer, const RsceneRenderSettings &render)
Shows the viewer’s world scene with these render settings instead of the file’s, usually the file’s own (rsceneRenderSettings()) after C++ changes. The scene is applied again in place of the constructor’s application; its meshes are reused. Fatal when the viewer’s world holds no scene.
-
const RsceneVisuals &raisin::rsceneVisuals(const RayraiWindow &viewer)
The visuals and batches the viewer created for its world’s scene. Empty when the viewer’s world holds no scene.
-
struct RsceneRenderSettings
Render settings stored in a scene’s environment, weather and rayrai_render records, with RaiSim Engine 2’s defaults for what the file omits.
Public Members
-
RenderQualityPreset preset
Preset named by the scene’s rayrai_render record.
-
RenderQualitySettings quality
The preset’s defaults with the scene’s values applied.
-
RayraiWindow::WeatherSettings weather
Applied when the scene’s background is the Rayrai sky.
-
RenderQualityPreset preset
-
struct RsceneVisuals
Viewer objects created for a scene (see rsceneVisuals()).
Public Members
-
std::vector<std::shared_ptr<InstancedVisuals>> instancedVisuals
One batch per enabled instanced_visual record, in file order.
-
std::vector<std::shared_ptr<InstancedVisuals>> foliage
The batches scattered from the terrains’ foliage layers.
-
std::vector<std::shared_ptr<InstancedVisuals>> instancedVisuals
The parsed records (raisim::rscene::Physics, ContactMaterial,
Material, Terrain, Object, Wire, Light, Camera,
LocalFog, ReflectionProbe, InstancedVisual and the others) are
declared in raisim/Rscene.hpp.
Other scene inputs
RaiSim world XML for hand-authored or template-driven worlds (World Configuration File);
MJCF for supported MuJoCo model imports (World);
OpenUSD for USD Physics articulations (OpenUSD Loading); or
the C++ or RaisimPy API to construct a world programmatically.