Irrlicht assets example (demo_IRR_assets.cpp)

Use the assets system to create shapes that can be shown in the Irrlicht 3D view.

This tutorial shows how to:

  • add geometric visualization shapes to an object.
  • visualize them in the realtime view of Irrlicht.

Note: the same assets that you use for Irrlicht display can be used for postprocessing, ex. with POVray as explained in demo_POST_povray.

// =============================================================================
// Copyright (c) 2014
// All rights reserved.
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// =============================================================================
// Authors: Alessandro Tasora, Radu Serban
// =============================================================================
// Demosntration of the Chrono::Irrlicht run-time visualization system
// =============================================================================
#include "chrono/physics/ChSystemNSC.h"
#include "chrono/physics/ChParticleCloud.h"
#include "chrono/physics/ChBodyEasy.h"
#include "chrono/geometry/ChLineNurbs.h"
#include "chrono/geometry/ChSurfaceNurbs.h"
#include "chrono/assets/ChVisualShapeSurface.h"
#include "chrono/assets/ChVisualShapeCone.h"
#include "chrono_irrlicht/ChVisualSystemIrrlicht.h"
// Use the namespace of Chrono
using namespace chrono;
using namespace chrono::geometry;
using namespace chrono::irrlicht;
int main(int argc, char* argv[]) {
GetLog() << "Copyright (c) 2017\nChrono version: " << CHRONO_VERSION << "\n\n";
// Create a Chrono system
// Create a ChBody, and attach assets that define 3D shapes for visualization purposes.
// Note: these assets are independent from collision shapes!
// Create a rigid body and add it to the physical system:
auto floor = chrono_types::make_shared<ChBody>();
// Contact material
auto floor_mat = chrono_types::make_shared<ChMaterialSurfaceNSC>();
// Define a collision shape
auto floor_shape = chrono_types::make_shared<ChCollisionShapeBox>(floor_mat, 20, 1, 20);
floor->AddCollisionShape(floor_shape, ChFrame<>(ChVector<>(0, -1, 0), QUNIT));
// Add body to system
// Attach a 'box' shape.
// Note that assets are managed via shared pointer, so they can also be shared).
auto boxfloor = chrono_types::make_shared<ChVisualShapeBox>(20, 1, 20);
boxfloor->SetColor(ChColor(0.2f, 0.3f, 1.0f));
floor->AddVisualShape(boxfloor, ChFrame<>(ChVector<>(0, -1, 0), QUNIT));
// Attach a 'path' shape populated with segments and arcs.
auto pathfloor = chrono_types::make_shared<ChVisualShapePath>();
ChLineSegment mseg1(ChVector<>(1, 2, 0), ChVector<>(1, 3, 0));
ChLineSegment mseg2(ChVector<>(1, 3, 0), ChVector<>(2, 3, 0));
ChLineArc marc1(ChCoordsys<>(ChVector<>(2, 3.5, 0)), 0.5, -CH_C_PI_2, CH_C_PI_2);
pathfloor->SetColor(ChColor(0.0f, 0.5f, 0.8f));
// Attach a 'nurbs line' shape:
// First create the ChLineNurbs geometry, then put it inside a ChVisualShapeLine
auto nurbs = chrono_types::make_shared<ChLineNurbs>();
std::vector<ChVector<>> controlpoints = {ChVector<>(1, 2, -1), ChVector<>(1, 3, -1), ChVector<>(1, 3, -2),
ChVector<>(1, 4, -2)};
nurbs->SetupData(3, controlpoints);
auto nurbsasset = chrono_types::make_shared<ChVisualShapeLine>();
nurbsasset->SetColor(ChColor(0.0f, 0.3f, 1.0f));
// Attach a 'nurbs surface' shape:
// First create the ChSurfaceNurbs geometry, then put it inside a ChVisualShapeSurface
auto surf = chrono_types::make_shared<ChSurfaceNurbs>();
ChMatrixDynamic<ChVector<>> surfpoints(4, 2); // u points, v points
surfpoints(0, 0) = ChVector<>(1, 2, 3);
surfpoints(1, 0) = ChVector<>(1, 3, 3);
surfpoints(2, 0) = ChVector<>(2, 3, 3);
surfpoints(3, 0) = ChVector<>(2, 4, 3);
surfpoints(0, 1) = ChVector<>(1, 2, 1);
surfpoints(1, 1) = ChVector<>(1, 3, 1);
surfpoints(2, 1) = ChVector<>(3, 3, 1);
surfpoints(3, 1) = ChVector<>(2, 4, 1);
surf->SetupData(3, 1, surfpoints);
auto surfasset = chrono_types::make_shared<ChVisualShapeSurface>();
surfasset->SetColor(ChColor(0.2f, 0.8f, 0.3f));
floor->AddVisualShape(surfasset, ChFrame<>(ChVector<>(3, -1, 3), QUNIT));
// Create the rigid body (this won't move, it is only for visualization tests)
auto body = chrono_types::make_shared<ChBody>();
// Create shared visualization materials
auto orange_mat = chrono_types::make_shared<ChVisualMaterial>();
orange_mat->SetDiffuseColor(ChColor(0.9f, 0.4f, 0.2f));
auto pink_mat = chrono_types::make_shared<ChVisualMaterial>();
// Attach a sphere shape
auto sphere = chrono_types::make_shared<ChVisualShapeSphere>(0.5);
body->AddVisualShape(sphere, ChFrame<>(ChVector<>(-1, 0, 0), QUNIT));
// Attach a box shape
auto box = chrono_types::make_shared<ChVisualShapeBox>(0.6, 1.0, 0.2);
body->AddVisualShape(box, ChFrame<>(ChVector<>(1, 1, 0), QUNIT));
// Attach a cylinder shape
auto cyl = chrono_types::make_shared<ChVisualShapeCylinder>(0.3, 0.7);
body->AddVisualShape(cyl, ChFrame<>(ChVector<>(2, 0.15, 0), Q_from_AngX(CH_C_PI_2)));
ChFrame<>(ChVector<>(2, -0.2, 0), QUNIT));
ChFrame<>(ChVector<>(2, +0.5, 0), QUNIT));
// Attach a capsule shape
auto capsule = chrono_types::make_shared<ChVisualShapeCapsule>(0.5, 2);
body->AddVisualShape(capsule, ChFrame<>(ChVector<>(-3, 1, -1), QUNIT));
ChFrame<>(ChVector<>(-3, 1, -2.5), QUNIT));
ChFrame<>(ChVector<>(-3, 1, +0.5), QUNIT));
// Attach a cone shape (NOT YET SUPPORTED)
auto cone = chrono_types::make_shared<ChVisualShapeCone>(0.3, 1.0);
cone->SetMaterial(0, pink_mat);
body->AddVisualShape(cone, ChFrame<>(ChVector<>(-4, 1.5, -1), QUNIT));
// Attach three instances of the same 'triangle mesh' shape
auto mesh = chrono_types::make_shared<ChVisualShapeTriangleMesh>();
mesh->GetMesh()->getCoordsVertices().push_back(ChVector<>(0, 0, 0));
mesh->GetMesh()->getCoordsVertices().push_back(ChVector<>(0, 1, 0));
mesh->GetMesh()->getCoordsVertices().push_back(ChVector<>(1, 0, 0));
mesh->GetMesh()->getIndicesVertexes().push_back(ChVector<int>(0, 1, 2));
body->AddVisualShape(mesh, ChFrame<>(ChVector<>(2, 0, 2), QUNIT));
body->AddVisualShape(mesh, ChFrame<>(ChVector<>(3, 0, 2), QUNIT));
body->AddVisualShape(mesh, ChFrame<>(ChVector<>(2, 1, 2), QUNIT));
// Attach a 'Wavefront mesh' asset, referencing a .obj file and offset it.
auto objmesh = chrono_types::make_shared<ChVisualShapeModelFile>();
body->AddVisualShape(objmesh, ChFrame<>(ChVector<>(0, 0, 2), QUNIT));
// Attach an array of boxes, each rotated to make a spiral
for (int j = 0; j < 20; j++) {
auto smallbox = chrono_types::make_shared<ChVisualShapeBox>(0.2, 0.2, 0.02);
smallbox->SetColor(ChColor(j * 0.05f, 1 - j * 0.05f, 0.0f));
ChMatrix33<> rot(Q_from_AngY(j * 21 * CH_C_DEG_TO_RAD));
ChVector<> pos = rot * ChVector<>(0.4, 0, 0) + ChVector<>(0, j * 0.02, 0);
body->AddVisualShape(smallbox, ChFrame<>(pos, rot));
// Create a ChParticleCloud cluster, and attach 'assets' that define a single "sample" 3D shape.
// Create the ChParticleCloud, populate it with some random particles, and add it to physical system:
auto particles = chrono_types::make_shared<ChParticleCloud>();
double particle_radius = 0.05;
// Add visualization (shared by all particles in the cloud)
auto particle_vis = chrono_types::make_shared<ChVisualShapeSphere>(particle_radius);
// Note: the collision shape, if needed, must be specified before creating particles.
// This will be shared among all particles in the ChParticleCloud.
auto particle_mat = chrono_types::make_shared<ChMaterialSurfaceNSC>();
auto particle_shape = chrono_types::make_shared<ChCollisionShapeSphere>(particle_mat, 0.05);
// Create the random particles
for (int np = 0; np < 100; ++np)
particles->AddParticle(ChCoordsys<>(ChVector<>(ChRandom() - 2, 1.5, ChRandom() + 2)));
// Mass and inertia properties.
// This will be shared among all particles in the ChParticleCloud.
particles->SetInertiaXX(ChVector<>(0.001, 0.001, 0.001));
// Do not forget to add the particle cluster to the system:
// Create a convex hull shape
ChVector<> displ(1, 0.0, 0);
std::vector<ChVector<>> points;
points.push_back(ChVector<>(0.8, 0.0, 0.0) + displ);
points.push_back(ChVector<>(0.8, 0.3, 0.0) + displ);
points.push_back(ChVector<>(0.8, 0.3, 0.3) + displ);
points.push_back(ChVector<>(0.0, 0.3, 0.3) + displ);
points.push_back(ChVector<>(0.0, 0.0, 0.3) + displ);
points.push_back(ChVector<>(0.8, 0.0, 0.3) + displ);
auto hull = chrono_types::make_shared<ChBodyEasyConvexHullAuxRef>(
points, 1000, true, true, chrono_types::make_shared<ChMaterialSurfaceNSC>());
hull->Move(ChVector<>(2, 0.3, 0));
// Create a visualization material
auto cadet_blue = chrono_types::make_shared<ChVisualMaterial>();
cadet_blue->SetDiffuseColor(ChColor(0.37f, 0.62f, 0.62f));
hull->GetVisualShape(0)->SetMaterial(0, cadet_blue);
// Create the Irrlicht visualization system
auto vis = chrono_types::make_shared<ChVisualSystemIrrlicht>();
vis->SetWindowSize(800, 600);
vis->SetWindowTitle("Chrono::Irrlicht visualization");
vis->AddCamera(ChVector<>(-2, 3, -4));
vis->AddGrid(0.5, 0.5, 12, 12, ChCoordsys<>(ChVector<>(0, -0.5, 0), Q_from_AngX(CH_C_PI_2)),
ChColor(0.31f, 0.43f, 0.43f));
// Rendering loop
while (vis->Run()) {
return 0;
void AddTypicalLights()
Simple shortcut to set two point lights in the scene.
Definition: ChVisualSystemIrrlicht.cpp:337
std::string GetChronoDataFile(const std::string &filename)
Obtain the complete path to the specified filename, given relative to the Chrono data directory (thre...
Definition: ChGlobal.cpp:95
void Add(std::shared_ptr< ChPhysicsItem > item)
Attach an arbitrary ChPhysicsItem (e.g.
Definition: ChSystem.cpp:210
virtual void Render() override
Draw all 3D shapes and GUI elements at the current frame.
Definition: ChVisualSystemIrrlicht.cpp:623
Definition: ChCoordsys.h:38
void AddSkyBox(const std::string &texture_dir=GetChronoDataFile("skybox/"))
Add a sky box in a 3D scene.
Definition: ChVisualSystemIrrlicht.cpp:350
virtual void Initialize()
Initialize the visualization system.
Definition: ChVisualSystemIrrlicht.cpp:181
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > ChMatrixDynamic
Dense matrix with dynamic size (i.e., with unknown at compile time) and row-major storage.
Definition: ChMatrix.h:73
ChLog & GetLog()
Global function to get the current ChLog object.
Definition: ChLog.cpp:39
Geometric object representing a segment in 3D space with two end points.
Definition: ChLineSegment.h:27
virtual int AddCamera(const ChVector<> &pos, ChVector<> targ=VNULL) override
Add a camera in an Irrlicht 3D scene.
Definition: ChVisualSystemIrrlicht.cpp:287
Definition of a 3x3 fixed size matrix to represent 3D rotations and inertia tensors.
Definition: ChMatrix33.h:31
Representation of a 3D transform.
Definition: ChFrame.h:34
Namespace with classes for the Irrlicht module.
Definition: ChApiIrr.h:47
Namespace for classes which represent basic geometric objects.
Definition: ChBasisToolsBspline.h:24
virtual void EndScene() override
End the scene draw at the end of each animation frame.
Definition: ChVisualSystemIrrlicht.cpp:613
Definition of a visual color.
Definition: ChColor.h:30
virtual void BeginScene() override
Perform any necessary operations at the beginning of each rendering frame.
Definition: ChVisualSystemIrrlicht.cpp:564
const ChQuaternion< double > QUNIT(1., 0., 0., 0.)
Constant unit quaternion: {1, 0, 0, 0} , corresponds to no rotation (diagonal rotation matrix)
Definition: ChQuaternion.h:457
Definition of general purpose 3d vector variables, such as points in 3D.
Definition: ChVector.h:35
int DoStepDynamics(double step_size)
Advances the dynamical simulation for a single step, of length step_size.
Definition: ChSystem.cpp:1590
Bullet-based collision detection system.
void SetWindowTitle(const std::string &win_title)
Set the windoiw title (default "").
Definition: ChVisualSystemIrrlicht.cpp:138
double ChRandom()
Returns random value in (0..1) interval with Park-Miller method.
Definition: ChMathematics.cpp:62
virtual void AttachSystem(ChSystem *sys) override
Attach another Chrono system to the run-time visualization system.
Definition: ChVisualSystemIrrlicht.cpp:165
virtual bool Run() override
Run the Irrlicht device.
Definition: ChVisualSystemIrrlicht.cpp:240
virtual void AddGrid(double x_step, double y_step, int nx, int ny, ChCoordsys<> pos=CSYSNORM, ChColor col=ChColor(0.1f, 0.1f, 0.1f)) override
Add a grid with specified parameters in the x-y plane of the given frame.
Definition: ChVisualSystemIrrlicht.cpp:307
Main namespace for the Chrono package.
Definition: ChCamera.cpp:17
void AddLogo(const std::string &logo_filename=GetChronoDataFile("logo_chronoengine_alpha.png"))
Add a logo in a 3D scene.
Definition: ChVisualSystemIrrlicht.cpp:329
virtual void SetCollisionSystemType(ChCollisionSystem::Type type)
Set the collision detection system used by this Chrono system to the specified type.
Definition: ChSystem.cpp:375
Geometric object representing an arc or a circle in 3D space.
Definition: ChLineArc.h:27
Class for a physical system in which contact is modeled using a non-smooth (complementarity-based) me...
Definition: ChSystemNSC.h:29
void SetWindowSize(unsigned int width, unsigned int height)
Set the window size (default 640x480).
Definition: ChVisualSystemIrrlicht.cpp:134