Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ode/ode-0.9/contrib/TerrainAndCone/test_boxstackb.cpp @ 216

Last change on this file since 216 was 216, checked in by mathiask, 17 years ago

[Physik] add ode-0.9

File size: 13.6 KB
Line 
1/*************************************************************************
2
3
4*                                                                                                                                                *
5
6
7* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.                *
8
9
10* All rights reserved.  Email: russ@q12.org   Web: www.q12.org           *
11
12
13*                                                                                                                                                *
14
15
16* This library is free software; you can redistribute it and/or          *
17
18
19* modify it under the terms of EITHER:                                                           *
20
21
22*        (1) The GNU Lesser General Public License as published by the Free  *
23
24
25*                Software Foundation; either version 2.1 of the License, or (at  *
26
27
28*                your option) any later version. The text of the GNU Lesser      *
29
30
31*                General Public License is included with this library in the     *
32
33
34*                file LICENSE.TXT.                                                                                               *
35
36
37*        (2) The BSD-style license that is included with this library in         *
38
39
40*                the file LICENSE-BSD.TXT.                                                                               *
41
42
43*                                                                                                                                                *
44
45
46* This library is distributed in the hope that it will be useful,                *
47
48
49* but WITHOUT ANY WARRANTY; without even the implied warranty of                 *
50
51
52* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files     *
53
54
55* LICENSE.TXT and LICENSE-BSD.TXT for more details.                                      *
56
57
58*                                                                                                                                                *
59
60
61*************************************************************************/
62
63
64
65
66
67#include <ode/ode.h>
68
69
70#include <drawstuff/drawstuff.h>
71
72
73
74
75
76#ifdef _MSC_VER
77
78
79#pragma warning(disable:4244 4305)      // for VC++, no precision loss complaints
80
81
82#endif
83
84
85
86
87
88// select correct drawing functions
89
90
91
92
93
94#ifdef dDOUBLE
95
96
97#define dsDrawBox dsDrawBoxD
98
99
100#define dsDrawSphere dsDrawSphereD
101
102
103#define dsDrawCylinder dsDrawCylinderD
104
105
106#define dsDrawCappedCylinder dsDrawCappedCylinderD
107
108
109#endif
110
111
112
113
114
115
116
117
118// some constants
119
120
121
122
123
124const dReal vTerrainLength = 4.f;
125
126
127const dReal vTerrainHeight = 0.5f;
128
129
130const int TERRAINNODES = 4;
131
132
133dReal pTerrainHeights[TERRAINNODES*TERRAINNODES];
134
135
136
137
138
139dGeomID terrainZ = NULL;
140
141
142dGeomID terrainY = NULL;
143
144
145
146
147
148#define NUM 20                  // max number of objects
149
150
151#define DENSITY (5.0)           // density of all objects
152
153
154#define GPB 3                   // maximum number of geometries per body
155
156
157#define MAX_CONTACTS 4          // maximum number of contact points per body
158
159
160
161
162
163
164
165
166// dynamics and collision objects
167
168
169
170
171
172struct MyObject {
173
174
175        dBodyID body;           // the body
176
177
178        dGeomID geom[GPB];              // geometries representing this body
179
180
181};
182
183
184
185
186
187static int num=0;               // number of objects in simulation
188
189
190static int nextobj=0;           // next object to recycle if num==NUM
191
192
193static dWorldID world;
194
195
196static dSpaceID space;
197
198
199static MyObject obj[NUM];
200
201
202static dJointGroupID contactgroup;
203
204
205static int selected = -1;       // selected object
206
207
208static int show_aabb = 0;       // show geom AABBs?
209
210
211static int show_contacts = 0;   // show contact points?
212
213
214static int random_pos = 1;      // drop objects from random position?
215
216
217
218
219
220
221
222
223// this is called by dSpaceCollide when two objects in space are
224
225
226// potentially colliding.
227
228
229
230
231
232static void nearCallback (void *data, dGeomID o1, dGeomID o2)
233
234
235{
236
237
238        int i;
239
240
241        // if (o1->body && o2->body) return;
242
243
244       
245
246
247        // exit without doing anything if the two bodies are connected by a joint
248
249
250        dBodyID b1 = dGeomGetBody(o1);
251
252
253        dBodyID b2 = dGeomGetBody(o2);
254
255
256        if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact)) return;
257
258
259       
260
261
262        dContact contact[MAX_CONTACTS]; // up to MAX_CONTACTS contacts per box-box
263
264
265        for (i=0; i<MAX_CONTACTS; i++) {
266
267
268                contact[i].surface.mode = dContactBounce | dContactApprox1;     //dContactSoftCFM;
269
270
271                contact[i].surface.mu = dInfinity;
272
273
274                contact[i].surface.mu2 = 0;
275
276
277                contact[i].surface.bounce = 0.1;
278
279
280                contact[i].surface.bounce_vel = 0.1;
281
282
283                contact[i].surface.soft_cfm = 0.01;
284
285
286        }
287
288
289        if (int numc = dCollide (o1,o2,MAX_CONTACTS,&contact[0].geom,
290
291
292                sizeof(dContact))) {
293
294
295                dMatrix3 RI;
296
297
298                dRSetIdentity (RI);
299
300
301                const dReal ss[3] = {0.02,0.02,0.02};
302
303
304                for (i=0; i<numc; i++) {
305
306
307                        dJointID c = dJointCreateContact (world,contactgroup,contact+i);
308
309
310                        dJointAttach (c,b1,b2);
311
312
313                        if (show_contacts) dsDrawBox (contact[i].geom.pos,RI,ss);
314
315
316                }
317
318
319        }
320
321
322}
323
324
325
326
327
328
329
330
331// start simulation - set viewpoint
332
333
334
335
336
337static void start()
338
339
340{
341
342
343        static float xyz[3] = {2.1640f,-1.3079f,1.7600f};
344
345
346        static float hpr[3] = {125.5000f,-17.0000f,0.0000f};
347
348
349        dsSetViewpoint (xyz,hpr);
350
351
352        printf ("To drop another object, press:\n");
353
354
355        printf ("   b for box.\n");
356
357
358        printf ("   s for sphere.\n");
359
360
361        printf ("   c for cylinder.\n");
362
363
364        printf ("   x for a composite object.\n");
365
366
367        printf ("To select an object, press space.\n");
368
369
370        printf ("To disable the selected object, press d.\n");
371
372
373        printf ("To enable the selected object, press e.\n");
374
375
376        printf ("To toggle showing the geom AABBs, press a.\n");
377
378
379        printf ("To toggle showing the contact points, press t.\n");
380
381
382        printf ("To toggle dropping from random position/orientation, press r.\n");
383
384
385}
386
387
388
389
390
391
392
393
394char locase (char c)
395
396
397{
398
399
400        if (c >= 'A' && c <= 'Z') return c - ('a'-'A');
401
402
403        else return c;
404
405
406}
407
408
409
410
411
412
413
414
415// called when a key pressed
416
417
418
419
420
421static void command (int cmd)
422
423
424{
425
426
427        int i,j,k;
428
429
430        dReal sides[3];
431
432
433        dMass m;
434
435
436       
437
438
439        cmd = locase (cmd);
440
441
442        if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x'
443
444
445                /* || cmd == 'l' */) {
446
447
448                if (num < NUM) {
449
450
451                        i = num;
452
453
454                        num++;
455
456
457                }
458
459
460                else {
461
462
463                        i = nextobj;
464
465
466                        nextobj++;
467
468
469                        if (nextobj >= num) nextobj = 0;
470
471
472                       
473
474
475                        // destroy the body and geoms for slot i
476
477
478                        dBodyDestroy (obj[i].body);
479
480
481                        for (k=0; k < GPB; k++) {
482
483
484                                if (obj[i].geom[k]) dGeomDestroy (obj[i].geom[k]);
485
486
487                        }
488
489
490                        memset (&obj[i],0,sizeof(obj[i]));
491
492
493                }
494
495
496               
497
498
499                obj[i].body = dBodyCreate (world);
500
501
502                for (k=0; k<3; k++) sides[k] = dRandReal()*0.5+0.1;
503
504
505               
506
507
508                dMatrix3 R;
509
510
511                if (random_pos) {
512
513
514                        dBodySetPosition (obj[i].body,
515
516
517                                dRandReal()*2-1,dRandReal()*2+1,dRandReal()+3);
518
519
520                        dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0,
521
522
523                                dRandReal()*2.0-1.0,dRandReal()*10.0-5.0);
524
525
526                }
527
528
529                else {
530
531
532                        dReal maxheight = 0;
533
534
535                        for (k=0; k<num; k++) {
536
537
538                                const dReal *pos = dBodyGetPosition (obj[k].body);
539
540
541                                if (pos[2] > maxheight) maxheight = pos[2];
542
543
544                        }
545
546
547                        dBodySetPosition (obj[i].body, 0,maxheight+1,maxheight+3);
548
549
550                        dRFromAxisAndAngle (R,0,0,1,dRandReal()*10.0-5.0);
551
552
553                }
554
555
556                dBodySetRotation (obj[i].body,R);
557
558
559                dBodySetData (obj[i].body,(void*) i);
560
561
562               
563
564
565                if (cmd == 'b') {
566
567
568                        dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]);
569
570
571                        obj[i].geom[0] = dCreateBox (space,sides[0],sides[1],sides[2]);
572
573
574                }
575
576
577                else if (cmd == 'c') {
578
579
580                        sides[0] *= 0.5;
581
582
583                        dMassSetCappedCylinder (&m,DENSITY,3,sides[0],sides[1]);
584
585
586                        obj[i].geom[0] = dCreateCCylinder (space,sides[0],sides[1]);
587
588
589                }
590
591
592                /*
593
594
595                // cylinder option not yet implemented
596
597
598                else if (cmd == 'l') {
599
600
601                sides[1] *= 0.5;
602
603
604                dMassSetCappedCylinder (&m,DENSITY,3,sides[0],sides[1]);
605
606
607                obj[i].geom[0] = dCreateCylinder (space,sides[0],sides[1]);
608
609
610                }
611
612
613                */
614
615
616                else if (cmd == 's') {
617
618
619                        sides[0] *= 0.5;
620
621
622                        dMassSetSphere (&m,DENSITY,sides[0]);
623
624
625                        obj[i].geom[0] = dCreateSphere (space,sides[0]);
626
627
628                }
629
630
631                else if (cmd == 'x') {
632
633
634                        dGeomID g2[GPB];                // encapsulated geometries
635
636
637                        dReal dpos[GPB][3];     // delta-positions for encapsulated geometries
638
639
640                       
641
642
643                        // start accumulating masses for the encapsulated geometries
644
645
646                        dMass m2;
647
648
649                        dMassSetZero (&m);
650
651
652                       
653
654
655                        // set random delta positions
656
657
658                        for (j=0; j<GPB; j++) {
659
660
661                                for (k=0; k<3; k++) dpos[j][k] = dRandReal()*0.3-0.15;
662
663
664                        }
665
666
667                       
668
669
670                        for (k=0; k<GPB; k++) {
671
672
673                                obj[i].geom[k] = dCreateGeomTransform (space);
674
675
676                                dGeomTransformSetCleanup (obj[i].geom[k],1);
677
678
679                                if (k==0) {
680
681
682                                        dReal radius = dRandReal()*0.25+0.05;
683
684
685                                        g2[k] = dCreateSphere (0,radius);
686
687
688                                        dMassSetSphere (&m2,DENSITY,radius);
689
690
691                                }
692
693
694                                else if (k==1) {
695
696
697                                        g2[k] = dCreateBox (0,sides[0],sides[1],sides[2]);
698
699
700                                        dMassSetBox (&m2,DENSITY,sides[0],sides[1],sides[2]);
701
702
703                                }
704
705
706                                else {
707
708
709                                        dReal radius = dRandReal()*0.1+0.05;
710
711
712                                        dReal length = dRandReal()*1.0+0.1;
713
714
715                                        g2[k] = dCreateCCylinder (0,radius,length);
716
717
718                                        dMassSetCappedCylinder (&m2,DENSITY,3,radius,length);
719
720
721                                }
722
723
724                                dGeomTransformSetGeom (obj[i].geom[k],g2[k]);
725
726
727                               
728
729
730                                // set the transformation (adjust the mass too)
731
732
733                                dGeomSetPosition (g2[k],dpos[k][0],dpos[k][1],dpos[k][2]);
734
735
736                                dMassTranslate (&m2,dpos[k][0],dpos[k][1],dpos[k][2]);
737
738
739                                dMatrix3 Rtx;
740
741
742                                dRFromAxisAndAngle (Rtx,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0,
743
744
745                                        dRandReal()*2.0-1.0,dRandReal()*10.0-5.0);
746
747
748                                dGeomSetRotation (g2[k],Rtx);
749
750
751                                dMassRotate (&m2,Rtx);
752
753
754                               
755
756
757                                // add to the total mass
758
759
760                                dMassAdd (&m,&m2);
761
762
763                        }
764
765
766                       
767
768
769                        // move all encapsulated objects so that the center of mass is (0,0,0)
770
771
772                        for (k=0; k<2; k++) {
773
774
775                                dGeomSetPosition (g2[k],
776
777
778                                        dpos[k][0]-m.c[0],
779
780
781                                        dpos[k][1]-m.c[1],
782
783
784                                        dpos[k][2]-m.c[2]);
785
786
787                        }
788
789
790                        dMassTranslate (&m,-m.c[0],-m.c[1],-m.c[2]);
791
792
793                }
794
795
796               
797
798
799                for (k=0; k < GPB; k++) {
800
801
802                        if (obj[i].geom[k]) dGeomSetBody (obj[i].geom[k],obj[i].body);
803
804
805                }
806
807
808               
809
810
811                dBodySetMass (obj[i].body,&m);
812
813
814  }
815
816
817 
818
819
820  if (cmd == ' ') {
821
822
823          selected++;
824
825
826          if (selected >= num) selected = 0;
827
828
829          if (selected < 0) selected = 0;
830
831
832  }
833
834
835  else if (cmd == 'd' && selected >= 0 && selected < num) {
836
837
838          dBodyDisable (obj[selected].body);
839
840
841  }
842
843
844  else if (cmd == 'e' && selected >= 0 && selected < num) {
845
846
847          dBodyEnable (obj[selected].body);
848
849
850  }
851
852
853  else if (cmd == 'a') {
854
855
856          show_aabb ^= 1;
857
858
859  }
860
861
862  else if (cmd == 't') {
863
864
865          show_contacts ^= 1;
866
867
868  }
869
870
871  else if (cmd == 'r') {
872
873
874          random_pos ^= 1;
875
876
877  }
878
879
880}
881
882
883
884
885
886
887
888
889// draw a geom
890
891
892
893
894
895void drawGeom (dGeomID g, const dReal *pos, const dReal *R, int show_aabb)
896
897
898{
899
900
901        int i;
902
903
904       
905
906
907        if (!g) return;
908
909
910        if (!pos) pos = dGeomGetPosition (g);
911
912
913        if (!R) R = dGeomGetRotation (g);
914
915
916       
917
918
919        int type = dGeomGetClass (g);
920
921
922        if (type == dBoxClass) {
923
924
925                dVector3 sides;
926
927
928                dGeomBoxGetLengths (g,sides);
929
930
931                dsDrawBox (pos,R,sides);
932
933
934        }
935
936
937        else if (type == dSphereClass) {
938
939
940                dsDrawSphere (pos,R,dGeomSphereGetRadius (g));
941
942
943        }
944
945
946        else if (type == dCCylinderClass) {
947
948
949                dReal radius,length;
950
951
952                dGeomCCylinderGetParams (g,&radius,&length);
953
954
955                dsDrawCappedCylinder (pos,R,length,radius);
956
957
958        }
959
960
961        /*
962
963
964        // cylinder option not yet implemented
965
966
967        else if (type == dCylinderClass) {
968
969
970        dReal radius,length;
971
972
973        dGeomCylinderGetParams (g,&radius,&length);
974
975
976        dsDrawCylinder (pos,R,length,radius);
977
978
979        }
980
981
982        */
983
984
985        else if (type == dGeomTransformClass) {
986
987
988                dGeomID g2 = dGeomTransformGetGeom (g);
989
990
991                const dReal *pos2 = dGeomGetPosition (g2);
992
993
994                const dReal *R2 = dGeomGetRotation (g2);
995
996
997                dVector3 actual_pos;
998
999
1000                dMatrix3 actual_R;
1001
1002
1003                dMULTIPLY0_331 (actual_pos,R,pos2);
1004
1005
1006                actual_pos[0] += pos[0];
1007
1008
1009                actual_pos[1] += pos[1];
1010
1011
1012                actual_pos[2] += pos[2];
1013
1014
1015                dMULTIPLY0_333 (actual_R,R,R2);
1016
1017
1018                drawGeom (g2,actual_pos,actual_R,0);
1019
1020
1021        }
1022
1023
1024       
1025
1026
1027        if (show_aabb) {
1028
1029
1030                // draw the bounding box for this geom
1031
1032
1033                dReal aabb[6];
1034
1035
1036                dGeomGetAABB (g,aabb);
1037
1038
1039                dVector3 bbpos;
1040
1041
1042                for (i=0; i<3; i++) bbpos[i] = 0.5*(aabb[i*2] + aabb[i*2+1]);
1043
1044
1045                dVector3 bbsides;
1046
1047
1048                for (i=0; i<3; i++) bbsides[i] = aabb[i*2+1] - aabb[i*2];
1049
1050
1051                dMatrix3 RI;
1052
1053
1054                dRSetIdentity (RI);
1055
1056
1057                dsSetColorAlpha (1,0,0,0.5);
1058
1059
1060                dsDrawBox (bbpos,RI,bbsides);
1061
1062
1063        }
1064
1065
1066}
1067
1068
1069
1070
1071
1072
1073
1074
1075// simulation loop
1076
1077
1078
1079
1080
1081static void simLoop (int pause)
1082
1083
1084{
1085
1086
1087        dsSetColor (0,0,2);
1088
1089
1090        dSpaceCollide (space,0,&nearCallback);
1091
1092
1093        if (!pause) dWorldStep (world,0.05);
1094
1095
1096
1097
1098
1099        dAASSERT(terrainY);
1100
1101
1102        dAASSERT(terrainZ);
1103
1104
1105        dsSetColor (0,1,0);
1106
1107
1108        dsDrawTerrainY(0,0,vTerrainLength,vTerrainLength/TERRAINNODES,TERRAINNODES,pTerrainHeights,dGeomGetRotation(terrainY),dGeomGetPosition(terrainY));
1109
1110
1111        dsDrawTerrainZ(0,0,vTerrainLength,vTerrainLength/TERRAINNODES,TERRAINNODES,pTerrainHeights,dGeomGetRotation(terrainZ),dGeomGetPosition(terrainZ));
1112
1113
1114
1115
1116
1117        if (show_aabb) 
1118
1119
1120        {
1121
1122
1123                dReal aabb[6];
1124
1125
1126                dGeomGetAABB (terrainY,aabb);
1127
1128
1129                dVector3 bbpos;
1130
1131
1132                int i;
1133
1134
1135                for (i=0; i<3; i++) bbpos[i] = 0.5*(aabb[i*2] + aabb[i*2+1]);
1136
1137
1138                dVector3 bbsides;
1139
1140
1141                for (i=0; i<3; i++) bbsides[i] = aabb[i*2+1] - aabb[i*2];
1142
1143
1144                dMatrix3 RI;
1145
1146
1147                dRSetIdentity (RI);
1148
1149
1150                dsSetColorAlpha (1,0,0,0.5);
1151
1152
1153                dsDrawBox (bbpos,RI,bbsides);
1154
1155
1156
1157
1158
1159                dGeomGetAABB (terrainZ,aabb);
1160
1161
1162                for (i=0; i<3; i++) bbpos[i] = 0.5*(aabb[i*2] + aabb[i*2+1]);
1163
1164
1165                for (i=0; i<3; i++) bbsides[i] = aabb[i*2+1] - aabb[i*2];
1166
1167
1168                dsDrawBox (bbpos,RI,bbsides);
1169
1170
1171        }
1172
1173
1174
1175
1176
1177        dsSetColor (1,1,0);
1178
1179
1180       
1181
1182
1183        // remove all contact joints
1184
1185
1186        dJointGroupEmpty (contactgroup);
1187
1188
1189       
1190
1191
1192        dsSetColor (1,1,0);
1193
1194
1195        dsSetTexture (DS_WOOD);
1196
1197
1198        for (int i=0; i<num; i++) {
1199
1200
1201                for (int j=0; j < GPB; j++) {
1202
1203
1204                        if (i==selected) {
1205
1206
1207                                dsSetColor (0,0.7,1);
1208
1209
1210                        }
1211
1212
1213                        else if (! dBodyIsEnabled (obj[i].body)) {
1214
1215
1216                                dsSetColor (1,0,0);
1217
1218
1219                        }
1220
1221
1222                        else {
1223
1224
1225                                dsSetColor (1,1,0);
1226
1227
1228                        }
1229
1230
1231                        drawGeom (obj[i].geom[j],0,0,show_aabb);
1232
1233
1234                }
1235
1236
1237        }
1238
1239
1240}
1241
1242
1243
1244
1245
1246
1247
1248
1249int main (int argc, char **argv)
1250
1251
1252{
1253
1254
1255        // setup pointers to drawstuff callback functions
1256
1257
1258        dsFunctions fn;
1259
1260
1261        fn.version = DS_VERSION;
1262
1263
1264        fn.start = &start;
1265
1266
1267        fn.step = &simLoop;
1268
1269
1270        fn.command = &command;
1271
1272
1273        fn.stop = 0;
1274
1275
1276        fn.path_to_textures = "../../drawstuff/textures";
1277
1278
1279  if(argc==2)
1280    {
1281        fn.path_to_textures = argv[1];
1282    }
1283       
1284
1285
1286        // create world
1287
1288
1289       
1290
1291
1292        world = dWorldCreate();
1293
1294
1295        space = dHashSpaceCreate (0);
1296
1297
1298        contactgroup = dJointGroupCreate (0);
1299
1300
1301        dWorldSetGravity (world,0,0,-0.5); //-0.5
1302
1303
1304        dWorldSetCFM (world,1e-5);
1305
1306
1307        dCreatePlane (space,0,0,1,0);
1308
1309
1310        memset (obj,0,sizeof(obj));
1311
1312
1313
1314
1315
1316        for (int i=0;i<TERRAINNODES*TERRAINNODES;i++)   pTerrainHeights[i] = vTerrainHeight * dRandReal();
1317
1318
1319        terrainY = dCreateTerrainY(space,pTerrainHeights,vTerrainLength,TERRAINNODES,1,1);
1320
1321
1322        terrainZ = dCreateTerrainZ(space,pTerrainHeights,vTerrainLength,TERRAINNODES,1,1);
1323
1324
1325
1326
1327
1328        dMatrix3 R;
1329
1330
1331        dRFromZAxis(R, 0.2f, 0.2f, 0.2f);
1332
1333
1334        dGeomSetPosition(terrainY,0.f,0.f,0.5f);
1335
1336
1337        dGeomSetRotation(terrainY,R);
1338
1339
1340        dGeomSetPosition(terrainZ,0.f,0.f,0.5f);
1341
1342
1343        dGeomSetRotation(terrainZ,R);
1344
1345
1346
1347
1348
1349        // run simulation
1350
1351
1352        dsSimulationLoop (argc,argv,352,288,&fn);
1353
1354
1355       
1356
1357
1358        dJointGroupDestroy (contactgroup);
1359
1360
1361        dSpaceDestroy (space);
1362
1363
1364        dWorldDestroy (world);
1365
1366
1367       
1368
1369
1370        return 0;
1371
1372
1373}
1374
1375
Note: See TracBrowser for help on using the repository browser.