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.
// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// 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
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// 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/core/ChRandom.h"
#include "chrono_irrlicht/ChVisualSystemIrrlicht.h"
// Use the namespace of Chrono
using namespace chrono;
using namespace chrono::irrlicht;
#include <Eigen/Core>
int main(int argc, char* argv[]) {
    std::cout << "Copyright (c) 2017 projectchrono.org\nChrono version: " << CHRONO_VERSION << std::endl;
    // Create a Chrono system
    ChSystemNSC sys;
    Eigen::MatrixXf a;
    a.resize(3,3);
    // EXAMPLE 1:
    // 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>();
    floor->SetFixed(true);
    // Contact material
    auto floor_mat = chrono_types::make_shared<ChContactMaterialNSC>();
    // Define a collision shape
    auto floor_shape = chrono_types::make_shared<ChCollisionShapeBox>(floor_mat, 20, 1, 20);
    floor->EnableCollision(true);
    // Add body to system
    sys.Add(floor);
    // 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));
    // Attach a 'path' shape populated with segments and arcs.
    auto pathfloor = chrono_types::make_shared<ChVisualShapePath>();
    pathfloor->GetPathGeometry()->AddSubLine(mseg1);
    pathfloor->GetPathGeometry()->AddSubLine(mseg2);
    pathfloor->GetPathGeometry()->AddSubLine(marc1);
    pathfloor->SetColor(ChColor(0.0f, 0.5f, 0.8f));
    floor->AddVisualShape(pathfloor);
    // 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<ChVector3d> controlpoints = {ChVector3d(1, 2, -1), ChVector3d(1, 3, -1), ChVector3d(1, 3, -2),
                                             ChVector3d(1, 4, -2)};
    nurbs->Setup(3, controlpoints);
    auto nurbsasset = chrono_types::make_shared<ChVisualShapeLine>();
    nurbsasset->SetLineGeometry(nurbs);
    nurbsasset->SetColor(ChColor(0.0f, 0.3f, 1.0f));
    floor->AddVisualShape(nurbsasset);
    // Attach a 'nurbs surface' shape:
    // First create the ChSurfaceNurbs geometry, then put it inside a ChVisualShapeSurface
    auto surf = chrono_types::make_shared<ChSurfaceNurbs>();
    ChMatrixDynamic<ChVector3d> surfpoints(4, 2);  // u points, v points
    surfpoints(0, 0) = ChVector3d(1, 2, 3);
    surfpoints(1, 0) = ChVector3d(1, 3, 3);
    surfpoints(2, 0) = ChVector3d(2, 3, 3);
    surfpoints(3, 0) = ChVector3d(2, 4, 3);
    surfpoints(0, 1) = ChVector3d(1, 2, 1);
    surfpoints(1, 1) = ChVector3d(1, 3, 1);
    surfpoints(2, 1) = ChVector3d(3, 3, 1);
    surfpoints(3, 1) = ChVector3d(2, 4, 1);
    surf->Setup(3, 1, surfpoints);
    auto surfasset = chrono_types::make_shared<ChVisualShapeSurface>();
    surfasset->SetSurfaceGeometry(surf);
    surfasset->SetWireframe(true);
    surfasset->SetColor(ChColor(0.2f, 0.8f, 0.3f));
    // EXAMPLE 2:
    // Create the rigid body (this won't move, it is only for visualization tests)
    auto body = chrono_types::make_shared<ChBody>();
    body->SetFixed(true);
    sys.Add(body);
    // 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>();
    pink_mat->SetKdTexture(GetChronoDataFile("textures/pinkwhite.png"));
    // Attach a sphere shape
    auto sphere = chrono_types::make_shared<ChVisualShapeSphere>(0.5);
    sphere->AddMaterial(orange_mat);
    // Attach a box shape
    auto box = chrono_types::make_shared<ChVisualShapeBox>(0.6, 1.0, 0.2);
    box->AddMaterial(orange_mat);
    // Attach a cylinder shape
    auto cyl = chrono_types::make_shared<ChVisualShapeCylinder>(0.3, 0.7);
    cyl->AddMaterial(orange_mat);
    body->AddVisualShape(chrono_types::make_shared<ChVisualShapeSphere>(0.03),
    body->AddVisualShape(chrono_types::make_shared<ChVisualShapeSphere>(0.03),
    // Attach a capsule shape
    auto capsule = chrono_types::make_shared<ChVisualShapeCapsule>(0.5, 2);
    capsule->AddMaterial(orange_mat);
    body->AddVisualShape(chrono_types::make_shared<ChVisualShapeSphere>(0.03),
    body->AddVisualShape(chrono_types::make_shared<ChVisualShapeSphere>(0.03),
    // Attach a cone shape
    auto cone = chrono_types::make_shared<ChVisualShapeCone>(0.3, 1.0);
    cone->SetMaterial(0, pink_mat);
    // Attach three instances of the same 'triangle mesh' shape
    auto mesh = chrono_types::make_shared<ChVisualShapeTriangleMesh>();
    mesh->GetMesh()->GetCoordsVertices().push_back(ChVector3d(0, 0, 0));
    mesh->GetMesh()->GetCoordsVertices().push_back(ChVector3d(0, 1, 0));
    mesh->GetMesh()->GetCoordsVertices().push_back(ChVector3d(1, 0, 0));
    mesh->GetMesh()->GetIndicesVertexes().push_back(ChVector3i(0, 1, 2));
    mesh->AddMaterial(orange_mat);
    // Attach a 'Wavefront mesh' asset, referencing a .obj file and offset it.
    auto objmesh = chrono_types::make_shared<ChVisualShapeModelFile>();
    objmesh->SetFilename(GetChronoDataFile("models/forklift/body.obj"));
    // 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(QuatFromAngleY(j * 21 * CH_DEG_TO_RAD));
        body->AddVisualShape(smallbox, ChFrame<>(pos, rot));
    }
    // EXAMPLE 3:
    // 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);
    particles->AddVisualShape(particle_vis);
    // 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<ChContactMaterialNSC>();
    auto particle_shape = chrono_types::make_shared<ChCollisionShapeSphere>(particle_mat, 0.05);
    particles->AddCollisionShape(particle_shape);
    particles->EnableCollision(true);
    // Create the random particles
    for (int np = 0; np < 100; ++np)
        particles->AddParticle(ChCoordsys<>(ChVector3d(ChRandom::Get() - 2, 1.5, ChRandom::Get() + 2)));
    // Mass and inertia properties.
    // This will be shared among all particles in the ChParticleCloud.
    particles->SetMass(0.1);
    particles->SetInertiaXX(ChVector3d(0.001, 0.001, 0.001));
    // Do not forget to add the particle cluster to the system:
    sys.Add(particles);
    // EXAMPLE 4:
    // Create a convex hull shape
    ChVector3d displ(1, 0.0, 0);
    std::vector<ChVector3d> points;
    points.push_back(ChVector3d(0.8, 0.0, 0.0) + displ);
    points.push_back(ChVector3d(0.8, 0.3, 0.0) + displ);
    points.push_back(ChVector3d(0.8, 0.3, 0.3) + displ);
    points.push_back(ChVector3d(0.0, 0.3, 0.3) + displ);
    points.push_back(ChVector3d(0.0, 0.0, 0.3) + displ);
    points.push_back(ChVector3d(0.8, 0.0, 0.3) + displ);
    auto hull = chrono_types::make_shared<ChBodyEasyConvexHullAuxRef>(
        points, 1000, true, true, chrono_types::make_shared<ChContactMaterialNSC>());
    hull->Move(ChVector3d(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);
    sys.Add(hull);
    // Create the Irrlicht visualization system
    auto vis = chrono_types::make_shared<ChVisualSystemIrrlicht>();
    vis->AttachSystem(&sys);
    vis->SetWindowSize(800, 600);
    vis->SetWindowTitle("Chrono::Irrlicht visualization");
    vis->Initialize();
    vis->AddLogo();
    vis->AddSkyBox();
    vis->AddCamera(ChVector3d(-2, 3, -4));
    vis->AddTypicalLights();
                 ChColor(0.31f, 0.43f, 0.43f));
    // Rendering loop
    while (vis->Run()) {
        vis->BeginScene();
        vis->Render();
        vis->EndScene();
        sys.DoStepDynamics(0.01);
    }
    return 0;
}
std::string GetChronoDataFile(const std::string &filename)
Get the full path to the specified filename, given relative to the Chrono data directory (thread safe...
Definition: ChDataPath.cpp:37
ChQuaterniond QuatFromAngleX(double angle)
Convert from a rotation about X axis to a quaternion.
Definition: ChRotation.cpp:188
void Add(std::shared_ptr< ChPhysicsItem > item)
Attach an arbitrary ChPhysicsItem (e.g.
Definition: ChSystem.cpp:214
virtual void BeginScene() override
Perform any necessary operations at the beginning of each rendering frame.
Definition: ChVisualSystemVSG.h:101
Representation of a transform with translation and rotation.
Definition: ChCoordsys.h:28
Geometric object representing an arc or a circle in 3D space.
Definition: ChLineArc.h:29
const ChQuaterniond QUNIT(1., 0., 0., 0.)
Constant unit quaternion: {1, 0, 0, 0} , corresponds to no rotation (diagonal rotation matrix)
Definition: ChQuaternion.h:431
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:75
virtual void EndScene() override
End the scene draw at the end of each animation frame.
Definition: ChVisualSystemVSG.h:111
Definition of a 3x3 fixed-size matrix to represent 3D rotations and inertia tensors.
Definition: ChMatrix33.h:31
virtual int AddCamera(const ChVector3d &pos, ChVector3d targ=VNULL) override
Add a camera to the VSG scene.
Definition: ChVisualSystemVSG.cpp:961
ChQuaterniond QuatFromAngleY(double angle)
Convert from a rotation about Y axis to a quaternion.
Definition: ChRotation.cpp:192
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: ChVisualSystemVSG.cpp:2974
Geometric object representing a segment in 3D space with two end points.
Definition: ChLineSegment.h:29
virtual void Render() override
Draw all 3D shapes and GUI elements at the current frame.
Definition: ChVisualSystemVSG.cpp:1356
int DoStepDynamics(double step_size)
Advance the dynamics simulation by a single time step of given length.
Definition: ChSystem.cpp:1651
Bullet-based collision detection system.
ChVector3< double > ChVector3d
Alias for double-precision vectors.
Definition: ChVector3.h:287
virtual void Initialize() override
Initialize the visualization system.
Definition: ChVisualSystemVSG.cpp:1054
virtual void AttachSystem(ChSystem *sys)
Attach a Chrono system to this visualization system.
Definition: ChVisualSystem.cpp:34
virtual void SetCollisionSystemType(ChCollisionSystem::Type type)
Set the collision detection system used by this Chrono system to the specified type.
Definition: ChSystem.cpp:342
Class for a physical system in which contact is modeled using a non-smooth (complementarity-based) me...
Definition: ChSystemNSC.h:29
virtual bool Run() override
Check if rendering is running.
Definition: ChVisualSystemVSG.cpp:1352
