Falling bricks example (demo_IRR_bricks.cpp) 
  A tutorial about collisions.
Create a stack of bricks and a wrecking ball that collides with them.
Learn about:
- how to enable collisions
- how to use the surface material
- how to impose an initial speed to a body
// =============================================================================
// 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
// =============================================================================
//
//   Demo code about
//     - collisions and contacts
//     - sharing a ChMaterialSurfaceNSC property between bodies
//
// =============================================================================
#include "chrono/physics/ChSystemNSC.h"
#include "chrono/physics/ChBodyEasy.h"
#include "chrono/solver/ChSolverPSOR.h"
#include "chrono/assets/ChTexture.h"
#include "chrono_irrlicht/ChIrrApp.h"
// Use the namespaces of Chrono
using namespace chrono;
using namespace chrono::irrlicht;
// Use the main namespaces of Irrlicht
using namespace irr;
using namespace irr::core;
using namespace irr::scene;
using namespace irr::video;
using namespace irr::io;
using namespace irr::gui;
// Create a bunch of ChronoENGINE rigid bodies that
// represent bricks in a large wall.
void create_wall_bodies(ChSystemNSC& mphysicalSystem) {
    // Create a material that will be shared between bricks
    auto mmaterial = chrono_types::make_shared<ChMaterialSurfaceNSC>();
    mmaterial->SetFriction(0.4f);
    mmaterial->SetCompliance(0.0000005f);
    mmaterial->SetComplianceT(0.0000005f);
    mmaterial->SetDampingF(0.1f);
    // Create bricks
    for (int ai = 0; ai < 1; ai++)  // N. of walls
    {
        for (int bi = 0; bi < 10; bi++)  // N. of vert. bricks
        {
            for (int ui = 0; ui < 15; ui++)  // N. of hor. bricks
            {
                auto mrigidBody = chrono_types::make_shared<ChBodyEasyBox>(3.96, 2, 4,  // x,y,z size
                                                                  100,         // density
                                                                  true,        // collide enable?
                                                                  true);       // visualization?
                mrigidBody->SetPos(ChVector<>(-8 + ui * 4.0 + 2 * (bi % 2), 1.0 + bi * 2.0, ai * 9));
                mrigidBody->SetMaterialSurface(mmaterial);  // use shared surface properties
                mphysicalSystem.Add(mrigidBody);
                // optional, attach a texture for better visualization
                auto mtexture = chrono_types::make_shared<ChTexture>();
                mtexture->SetTextureFilename(GetChronoDataFile("cubetexture_borders.png"));
                mrigidBody->AddAsset(mtexture);
            }
        }
    }
    // Create the floor using
    // fixed rigid body of 'box' type:
    auto mrigidFloor = chrono_types::make_shared<ChBodyEasyBox>(250, 4, 250,  // x,y,z size
                                                       1000,         // density
                                                       true,         // collide enable?
                                                       true);        // visualization?
    mrigidFloor->SetPos(ChVector<>(0, -2, 0));
    mrigidFloor->SetMaterialSurface(mmaterial);
    mrigidFloor->SetBodyFixed(true);
    mphysicalSystem.Add(mrigidFloor);
    // Create a ball that will collide with wall
    auto mrigidBall = chrono_types::make_shared<ChBodyEasySphere>(4,      // radius
                                                         8000,   // density
                                                         true,   // collide enable?
                                                         true);  // visualization?
    mrigidBall->SetPos(ChVector<>(0, -2, 0));
    mrigidBall->SetMaterialSurface(mmaterial);
    mrigidBall->SetPos(ChVector<>(0, 3, -8));
    mrigidBall->SetPos_dt(ChVector<>(0, 0, 16));          // set initial speed
    mrigidBall->GetMaterialSurfaceNSC()->SetFriction(0.4f);  // use own (not shared) matrial properties
    mrigidBall->GetMaterialSurfaceNSC()->SetCompliance(0.0);
    mrigidBall->GetMaterialSurfaceNSC()->SetComplianceT(0.0);
    mrigidBall->GetMaterialSurfaceNSC()->SetDampingF(0.2f);
    mphysicalSystem.Add(mrigidBall);
    // optional, attach a texture for better visualization
    auto mtextureball = chrono_types::make_shared<ChTexture>();
    mtextureball->SetTextureFilename(GetChronoDataFile("bluwhite.png"));
    mrigidBall->AddAsset(mtextureball);
}
// Create a bunch of ChronoENGINE rigid bodies that
// represent bricks in a Jenga tower
void create_jengatower_bodies(ChSystemNSC& mphysicalSystem) {
    // Create a material that will be shared between bricks
    auto mmaterial = chrono_types::make_shared<ChMaterialSurfaceNSC>();
    mmaterial->SetFriction(0.4f);
    mmaterial->SetCompliance(0.0000005f);
    mmaterial->SetComplianceT(0.0000005f);
    mmaterial->SetDampingF(0.1f);
    // Create bricks
    for (int bi = 0; bi < 12; bi += 2) {
        auto mrigidBody1 = chrono_types::make_shared<ChBodyEasyBox>(2, 2, 14,        // x,y,z size
                                                           100,             // density
                                                           true,            // collide enable?
                                                           true);           // visualization?
        mrigidBody1->SetPos(ChVector<>(-5, 1.0 + bi * 2.0, 0));
        mrigidBody1->SetMaterialSurface(mmaterial);  // use shared surface properties
        mphysicalSystem.Add(mrigidBody1);
        auto mrigidBody2 = chrono_types::make_shared<ChBodyEasyBox>(2, 2, 14,  // x,y,z size
                                                           100,       // density
                                                           true,      // collide enable?
                                                           true);     // visualization?
        mrigidBody2->SetPos(ChVector<>(5, 1.0 + bi * 2.0, 0));
        mrigidBody2->SetMaterialSurface(mmaterial);  // use shared surface properties
        mphysicalSystem.Add(mrigidBody2);
        auto mrigidBody3 = chrono_types::make_shared<ChBodyEasyBox>(14, 2, 2,  // x,y,z size
                                                           100,       // density
                                                           true,      // collide enable?
                                                           true);     // visualization?
        mrigidBody3->SetPos(ChVector<>(0, 3.0 + bi * 2.0, 5));
        mrigidBody3->SetMaterialSurface(mmaterial);  // use shared surface properties
        mphysicalSystem.Add(mrigidBody3);
        auto mrigidBody4 = chrono_types::make_shared<ChBodyEasyBox>(14, 2, 2,  // x,y,z size
                                                           100,       // density
                                                           true,      // collide enable?
                                                           true);     // visualization?
        mrigidBody4->SetPos(ChVector<>(0, 3.0 + bi * 2.0, -5));
        mrigidBody4->SetMaterialSurface(mmaterial);  // use shared surface properties
        mphysicalSystem.Add(mrigidBody4);
    }
    // Create the floor using
    // fixed rigid body of 'box' type:
    auto mrigidFloor = chrono_types::make_shared<ChBodyEasyBox>(250, 4, 250,  // x,y,z size
                                                       1000,         // density
                                                       true,         // collide enable?
                                                       true);        // visualization?
    mrigidFloor->SetPos(ChVector<>(0, -2, 0));
    mrigidFloor->SetMaterialSurface(mmaterial);
    mrigidFloor->SetBodyFixed(true);
    mphysicalSystem.Add(mrigidFloor);
    // Create a ball that will collide with tower
    auto mrigidBall = chrono_types::make_shared<ChBodyEasySphere>(4,      // radius
                                                         1000,   // density
                                                         true,   // collide enable?
                                                         true);  // visualization?
    mrigidBall->SetMaterialSurface(mmaterial);
    mrigidBall->SetPos(ChVector<>(0, 3, -8));
    mrigidBall->SetPos_dt(ChVector<>(0, 0, 2));           // set initial speed
    mrigidBall->GetMaterialSurfaceNSC()->SetFriction(0.4f);  // use own (not shared) matrial properties
    mrigidBall->GetMaterialSurfaceNSC()->SetCompliance(0.0);
    mrigidBall->GetMaterialSurfaceNSC()->SetComplianceT(0.0);
    mrigidBall->GetMaterialSurfaceNSC()->SetDampingF(0.2f);
    mphysicalSystem.Add(mrigidBall);
    // optional, attach a texture for better visualization
    auto mtextureball = chrono_types::make_shared<ChTexture>();
    mtextureball->SetTextureFilename(GetChronoDataFile("bluwhite.png"));
    mrigidBall->AddAsset(mtextureball);
}
int main(int argc, char* argv[]) {
    // Create a ChronoENGINE physical system
    ChSystemNSC mphysicalSystem;
    // Create the Irrlicht visualization (open the Irrlicht device,
    // bind a simple user interface, etc. etc.)
    ChIrrApp application(&mphysicalSystem, L"Bricks test", core::dimension2d<u32>(800, 600), false, true);
    // Easy shortcuts to add camera, lights, logo and sky in Irrlicht scene:
    ChIrrWizard::add_typical_Logo(application.GetDevice());
    ChIrrWizard::add_typical_Sky(application.GetDevice());
    ChIrrWizard::add_typical_Lights(application.GetDevice(), core::vector3df(70.f, 120.f, -90.f),
                                    core::vector3df(30.f, 80.f, 60.f), 290, 190);
    ChIrrWizard::add_typical_Camera(application.GetDevice(), core::vector3df(-15, 14, -30), core::vector3df(0, 5, 0));
    //
    // HERE YOU POPULATE THE MECHANICAL SYSTEM OF CHRONO...
    //
    // Create all the rigid bodies.
    create_wall_bodies(mphysicalSystem);
    // create_jengatower_bodies (mphysicalSystem);
    // Use this function for adding a ChIrrNodeAsset to all items
    // If you need a finer control on which item really needs a visualization proxy in
    // Irrlicht, just use application.AssetBind(myitem); on a per-item basis.
    application.AssetBindAll();
    // Use this function for 'converting' into Irrlicht meshes the assets
    // into Irrlicht-visualizable meshes
    application.AssetUpdateAll();
    // Prepare the physical system for the simulation
    auto solver = chrono_types::make_shared<ChSolverPSOR>();
    solver->SetMaxIterations(40);
    solver->EnableWarmStart(true);
    mphysicalSystem.SetSolver(solver);
    //mphysicalSystem.SetUseSleeping(true);
    mphysicalSystem.SetMaxPenetrationRecoverySpeed(1.0);
    // Simulation loop
    application.SetStepManage(true);
    application.SetTimestep(0.02);
    while (application.GetDevice()->run()) {
        ChIrrTools::drawGrid(application.GetVideoDriver(), 5, 5, 20, 20,
                             video::SColor(50, 90, 90, 150), true);
        application.DrawAll();
        application.DoStep();
        application.EndScene();
    }
    return 0;
}
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
static void drawGrid(irr::video::IVideoDriver *driver, double ustep=0.1, double vstep=0.1, int nu=20, int nv=20, ChCoordsys<> mpos=CSYSNORM, irr::video::SColor mcol=irr::video::SColor(50, 80, 110, 110), bool use_Zbuffer=false)
Easy-to-use function to draw grids in 3D space, with given orientation, color and spacing.
Definition: ChIrrTools.cpp:695
static void add_typical_Camera(irr::IrrlichtDevice *device, irr::core::vector3df mpos=irr::core::vector3df(0, 0, -8), irr::core::vector3df mtarg=irr::core::vector3df(0, 0, 0))
A very basic and simple function which is just a shortcut to avoid lot of typing when someone wants t...
Definition: ChIrrWizard.cpp:53
void AssetUpdateAll()
For all items in a ChSystem, this function sets up the Irrlicht nodes corresponding to the geometric ...
Definition: ChIrrApp.cpp:49
ChLog & GetLog()
Global function to get the current ChLog object.
Definition: ChLog.cpp:39
void SetTimestep(double val)
Set/Get the time step for time integration.
Definition: ChIrrAppInterface.cpp:532
static void add_typical_Logo(irr::IrrlichtDevice *device, const std::string &mlogofilename=GetChronoDataFile("logo_chronoengine_alpha.png"))
A very basic and simple function which is just a shortcut to avoid lot of typing when someone wants t...
Definition: ChIrrWizard.cpp:20
static void add_typical_Sky(irr::IrrlichtDevice *device, const std::string &mtexturedir=GetChronoDataFile("skybox/"))
A very basic and simple function which is just a shortcut to avoid lot of typing when someone wants t...
Definition: ChIrrWizard.cpp:40
void SetStepManage(bool val)
If set to true, you can use DoStep() in the simulation loop to advance the simulation by one timestep...
Definition: ChIrrAppInterface.h:84
static void add_typical_Lights(irr::IrrlichtDevice *device, irr::core::vector3df pos1=irr::core::vector3df(30.f, 100.f, 30.f), irr::core::vector3df pos2=irr::core::vector3df(30.f, 80.f, -30.f), double rad1=290, double rad2=190, irr::video::SColorf col1=irr::video::SColorf(0.7f, 0.7f, 0.7f, 1.0f), irr::video::SColorf col2=irr::video::SColorf(0.7f, 0.8f, 0.8f, 1.0f))
A very basic and simple function which is just a shortcut to avoid lot of typing when someone wants t...
Definition: ChIrrWizard.cpp:25
Class to add some GUI to Irrlicht+ChronoEngine applications.
Definition: ChIrrApp.h:29
ChQuaternion< double > Q_from_AngAxis(double angle, const ChVector< double > &axis)
Get the quaternion from an angle of rotation and an axis, defined in abs coords.
Definition: ChQuaternion.cpp:100
virtual void EndScene()
Call this to end the scene draw at the end of each animation frame.
Definition: ChIrrAppInterface.cpp:578
void SetMaxPenetrationRecoverySpeed(double mval)
For the default stepper, you can limit the speed of exiting from penetration situations.
Definition: ChSystem.h:163
Definition of general purpose 3d vector variables, such as points in 3D.
Definition: ChVector.h:35
virtual void DoStep()
Call this important function inside a cycle like while(application.GetDevice()->run()) {....
Definition: ChIrrAppInterface.cpp:590
void Add(std::shared_ptr< ChPhysicsItem > item)
Attach an arbitrary ChPhysicsItem (e.g.
Definition: ChAssembly.cpp:190
virtual void SetSolver(std::shared_ptr< ChSolver > newsolver)
Attach a solver (derived from ChSolver) for use by this system.
Definition: ChSystem.cpp:205
void AssetBindAll()
Shortcut to add and bind a ChIrrNodeAsset to all items in a ChSystem.
Definition: ChIrrApp.cpp:41
virtual void BeginScene(bool backBuffer=true, bool zBuffer=true, irr::video::SColor color=irr::video::SColor(255, 0, 0, 0))
Call this to clean the canvas at the beginning of each animation frame.
Definition: ChIrrAppInterface.cpp:559
virtual void DrawAll()
Call this important function inside a loop like while(application.GetDevice()->run()) {....
Definition: ChIrrAppInterface.cpp:699
Class for a physical system in which contact is modeled using a non-smooth (complementarity-based) me...
Definition: ChSystemNSC.h:29
