1 // =============================================================================
2 // PROJECT CHRONO - http://projectchrono.org
3 //
4 // Copyright (c) 2014 projectchrono.org
5 // All rights reserved.
6 //
7 // Use of this source code is governed by a BSD-style license that can be found
8 // in the LICENSE file at the top level of the distribution and at
9 // http://projectchrono.org/license-chrono.txt.
10 //
11 // =============================================================================
12 // Authors: Alessandro Tasora
13 // =============================================================================
14 //
15 // Demo code about
16 // - collisions and contacts
17 // - sharing a ChMaterialSurfaceNSC property between bodies
18 //
19 // =============================================================================
20
21 #include "chrono/physics/ChSystemNSC.h"
22 #include "chrono/physics/ChBodyEasy.h"
23 #include "chrono/solver/ChSolverPSOR.h"
24 #include "chrono/assets/ChTexture.h"
25
26 #include "chrono_irrlicht/ChIrrApp.h"
27
28 // Use the namespaces of Chrono
29 using namespace chrono;
30 using namespace chrono::irrlicht;
31
32 // Use the main namespaces of Irrlicht
33 using namespace irr;
34 using namespace irr::core;
35 using namespace irr::scene;
36 using namespace irr::video;
37 using namespace irr::io;
38 using namespace irr::gui;
39
40 // Create a bunch of ChronoENGINE rigid bodies that
41 // represent bricks in a large wall.
42
create_wall_bodies(ChSystemNSC & mphysicalSystem)43 void create_wall_bodies(ChSystemNSC& mphysicalSystem) {
44 // Create a material that will be shared among all collision shapes
45 auto mat = chrono_types::make_shared<ChMaterialSurfaceNSC>();
46 mat->SetFriction(0.4f);
47 mat->SetCompliance(0.0);
48 mat->SetComplianceT(0.0);
49 mat->SetDampingF(0.2f);
50
51 // Create bricks
52 for (int ai = 0; ai < 1; ai++) { // N. of walls
53 for (int bi = 0; bi < 10; bi++) { // N. of vert. bricks
54 for (int ui = 0; ui < 15; ui++) { // N. of hor. bricks
55
56 auto mrigidBody = chrono_types::make_shared<ChBodyEasyBox>(3.96, 2, 4, // x,y,z size
57 100, // density
58 true, // visualization?
59 true, // collision?
60 mat); // contact material
61 mrigidBody->SetPos(ChVector<>(-8 + ui * 4.0 + 2 * (bi % 2), 1.0 + bi * 2.0, ai * 9));
62
63 mphysicalSystem.Add(mrigidBody);
64
65 // optional, attach a texture for better visualization
66 auto mtexture = chrono_types::make_shared<ChTexture>();
67 mtexture->SetTextureFilename(GetChronoDataFile("textures/cubetexture_borders.png"));
68 mrigidBody->AddAsset(mtexture);
69 }
70 }
71 }
72
73 // Create the floor using
74 // fixed rigid body of 'box' type:
75
76 auto mrigidFloor = chrono_types::make_shared<ChBodyEasyBox>(250, 4, 250, // x,y,z size
77 1000, // density
78 true, // visulization?
79 true, // collision?
80 mat); // contact material
81 mrigidFloor->SetPos(ChVector<>(0, -2, 0));
82 mrigidFloor->SetBodyFixed(true);
83
84 mphysicalSystem.Add(mrigidFloor);
85
86 // Create a ball that will collide with wall
87 auto mrigidBall = chrono_types::make_shared<ChBodyEasySphere>(4, // radius
88 8000, // density
89 true, // visualization?
90 true, // collision?
91 mat); // contact material
92 mrigidBall->SetPos(ChVector<>(0, -2, 0));
93 mrigidBall->SetPos(ChVector<>(0, 3, -8));
94 mrigidBall->SetPos_dt(ChVector<>(0, 0, 16)); // set initial speed
95
96 mphysicalSystem.Add(mrigidBall);
97
98 // optional, attach a texture for better visualization
99 auto mtextureball = chrono_types::make_shared<ChTexture>();
100 mtextureball->SetTextureFilename(GetChronoDataFile("textures/bluewhite.png"));
101 mrigidBall->AddAsset(mtextureball);
102 }
103
104 // Create a bunch of ChronoENGINE rigid bodies that
105 // represent bricks in a Jenga tower
106
create_jengatower_bodies(ChSystemNSC & mphysicalSystem)107 void create_jengatower_bodies(ChSystemNSC& mphysicalSystem) {
108 // Create a material that will be shared among all collision shapes
109 auto mat = chrono_types::make_shared<ChMaterialSurfaceNSC>();
110 mat->SetFriction(0.4f);
111 mat->SetCompliance(0.0);
112 mat->SetComplianceT(0.0);
113 mat->SetDampingF(0.2f);
114
115 // Create bricks
116 for (int bi = 0; bi < 12; bi += 2) {
117 auto mrigidBody1 = chrono_types::make_shared<ChBodyEasyBox>(2, 2, 14, // x,y,z size
118 100, // density
119 true, // visualization?
120 true, // collision?
121 mat); // contact material
122 mrigidBody1->SetPos(ChVector<>(-5, 1.0 + bi * 2.0, 0));
123 mphysicalSystem.Add(mrigidBody1);
124
125 auto mrigidBody2 = chrono_types::make_shared<ChBodyEasyBox>(2, 2, 14, // x,y,z size
126 100, // density
127 true, // visualization?
128 true, // collision?
129 mat); // contact material
130 mrigidBody2->SetPos(ChVector<>(5, 1.0 + bi * 2.0, 0));
131 mphysicalSystem.Add(mrigidBody2);
132
133 auto mrigidBody3 = chrono_types::make_shared<ChBodyEasyBox>(14, 2, 2, // x,y,z size
134 100, // density
135 true, // visualization?
136 true, // collision?
137 mat); // contact material
138 mrigidBody3->SetPos(ChVector<>(0, 3.0 + bi * 2.0, 5));
139 mphysicalSystem.Add(mrigidBody3);
140
141 auto mrigidBody4 = chrono_types::make_shared<ChBodyEasyBox>(14, 2, 2, // x,y,z size
142 100, // density
143 true, // visualization?
144 true, // collision?
145 mat); // contact material
146 mrigidBody4->SetPos(ChVector<>(0, 3.0 + bi * 2.0, -5));
147 mphysicalSystem.Add(mrigidBody4);
148 }
149
150 // Create the floor using
151 // fixed rigid body of 'box' type:
152 auto mrigidFloor = chrono_types::make_shared<ChBodyEasyBox>(250, 4, 250, // x,y,z size
153 1000, // density
154 true, // visualization?
155 true, // collision?
156 mat); // contact material
157 mrigidFloor->SetPos(ChVector<>(0, -2, 0));
158 mrigidFloor->SetBodyFixed(true);
159
160 mphysicalSystem.Add(mrigidFloor);
161
162 // Create a ball that will collide with tower
163 auto mrigidBall = chrono_types::make_shared<ChBodyEasySphere>(4, // radius
164 1000, // density
165 true, // visualization?
166 true, // collision?
167 mat); // contact material
168 mrigidBall->SetPos(ChVector<>(0, 3, -8));
169 mrigidBall->SetPos_dt(ChVector<>(0, 0, 2)); // set initial speed
170
171 mphysicalSystem.Add(mrigidBall);
172
173 // optional, attach a texture for better visualization
174 auto mtextureball = chrono_types::make_shared<ChTexture>();
175 mtextureball->SetTextureFilename(GetChronoDataFile("textures/bluewhite.png"));
176 mrigidBall->AddAsset(mtextureball);
177 }
178
main(int argc,char * argv[])179 int main(int argc, char* argv[]) {
180 GetLog() << "Copyright (c) 2017 projectchrono.org\nChrono version: " << CHRONO_VERSION << "\n\n";
181
182 // Create a ChronoENGINE physical system
183 ChSystemNSC mphysicalSystem;
184
185 // Create the Irrlicht visualization (open the Irrlicht device,
186 // bind a simple user interface, etc. etc.)
187 ChIrrApp application(&mphysicalSystem, L"Bricks test", core::dimension2d<u32>(800, 600));
188 application.AddTypicalLogo();
189 application.AddTypicalSky();
190 application.AddTypicalLights(core::vector3df(70.f, 120.f, -90.f), core::vector3df(30.f, 80.f, 60.f), 290, 190);
191 application.AddTypicalCamera(core::vector3df(-15, 14, -30), core::vector3df(0, 5, 0));
192
193 //
194 // HERE YOU POPULATE THE MECHANICAL SYSTEM OF CHRONO...
195 //
196
197 // Create all the rigid bodies.
198 create_wall_bodies(mphysicalSystem);
199 // create_jengatower_bodies (mphysicalSystem);
200
201 // Use this function for adding a ChIrrNodeAsset to all items
202 // If you need a finer control on which item really needs a visualization proxy in
203 // Irrlicht, just use application.AssetBind(myitem); on a per-item basis.
204 application.AssetBindAll();
205
206 // Use this function for 'converting' into Irrlicht meshes the assets
207 // into Irrlicht-visualizable meshes
208 application.AssetUpdateAll();
209
210 // Prepare the physical system for the simulation
211
212 auto solver = chrono_types::make_shared<ChSolverPSOR>();
213 solver->SetMaxIterations(40);
214 solver->EnableWarmStart(true);
215 mphysicalSystem.SetSolver(solver);
216
217 // mphysicalSystem.SetUseSleeping(true);
218 mphysicalSystem.SetMaxPenetrationRecoverySpeed(1.0);
219
220 // Simulation loop
221
222 application.SetTimestep(0.02);
223 application.SetTryRealtime(true);
224
225 while (application.GetDevice()->run()) {
226 application.BeginScene(true, true, SColor(255, 140, 161, 192));
227
228 tools::drawGrid(application.GetVideoDriver(), 5, 5, 20, 20,
229 ChCoordsys<>(ChVector<>(0, 0.04, 0), Q_from_AngAxis(CH_C_PI / 2, VECT_X)),
230 video::SColor(50, 90, 90, 150), true);
231
232 application.DrawAll();
233
234 application.DoStep();
235
236 application.EndScene();
237 }
238
239 return 0;
240 }
241