1 /*************************************************************************
3 * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
4 * All rights reserved. Email: russ@q12.org Web: www.q12.org *
6 * This library is free software; you can redistribute it and/or *
7 * modify it under the terms of EITHER: *
8 * (1) The GNU Lesser General Public License as published by the Free *
9 * Software Foundation; either version 2.1 of the License, or (at *
10 * your option) any later version. The text of the GNU Lesser *
11 * General Public License is included with this library in the *
13 * (2) The BSD-style license that is included with this library in *
14 * the file LICENSE-BSD.TXT. *
16 * This library is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
19 * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
21 *************************************************************************/
23 // Test my Plane2D constraint.
24 // Uses ode-0.35 collision API.
30 # include <drawstuff/drawstuff.h>
31 #include "texturepath.h"
34 # define drand48() ((double) (((double) rand()) / ((double) RAND_MAX)))
37 # define STAGE_SIZE 8.0 // in m
39 # define TIME_STEP 0.01
40 # define K_SPRING 10.0
43 //using namespace ode;
48 dBody dyn_bodies
[N_BODIES
];
49 dReal bodies_sides
[N_BODIES
][3];
51 dSpaceID coll_space_id
;
52 dJointID plane2d_joint_ids
[N_BODIES
];
53 dJointGroup coll_contacts
;
56 static GlobalVars
*g_globals_ptr
= NULL
;
60 static void cb_start ()
61 /*************************/
63 dAllocateODEDataForThread(dAllocateMaskAll
);
65 static float xyz
[3] = { 0.5f
*STAGE_SIZE
, 0.5f
*STAGE_SIZE
, 0.85f
*STAGE_SIZE
};
66 static float hpr
[3] = { 90.0f
, -90.0f
, 0 };
68 dsSetViewpoint (xyz
, hpr
);
73 static void cb_near_collision (void *, dGeomID o1
, dGeomID o2
)
74 /********************************************************************/
76 dBodyID b1
= dGeomGetBody (o1
);
77 dBodyID b2
= dGeomGetBody (o2
);
81 // exit without doing anything if the two bodies are static
82 if (b1
== 0 && b2
== 0)
85 // exit without doing anything if the two bodies are connected by a joint
86 if (b1
&& b2
&& dAreConnected (b1
, b2
))
92 contact
.surface
.mode
= 0;
93 contact
.surface
.mu
= 0; // frictionless
95 if (dCollide (o1
, o2
, 1, &contact
.geom
, sizeof (dContactGeom
)))
97 dJointID c
= dJointCreateContact (g_globals_ptr
->dyn_world
.id(),
98 g_globals_ptr
->coll_contacts
.id (), &contact
);
99 dJointAttach (c
, b1
, b2
);
104 static void track_to_pos (dBody
&body
, dJointID joint_id
,
105 dReal target_x
, dReal target_y
)
106 /************************************************************************/
108 dReal curr_x
= body
.getPosition()[0];
109 dReal curr_y
= body
.getPosition()[1];
111 dJointSetPlane2DXParam (joint_id
, dParamVel
, 1 * (target_x
- curr_x
));
112 dJointSetPlane2DYParam (joint_id
, dParamVel
, 1 * (target_y
- curr_y
));
117 static void cb_sim_step (int pause
)
118 /*************************************/
122 static dReal angle
= 0;
124 angle
+= REAL( 0.01 );
126 track_to_pos (g_globals_ptr
->dyn_bodies
[0], g_globals_ptr
->plane2d_joint_ids
[0],
127 dReal( STAGE_SIZE
/2 + STAGE_SIZE
/2.0 * cos (angle
) ),
128 dReal( STAGE_SIZE
/2 + STAGE_SIZE
/2.0 * sin (angle
) ));
130 /* double f0 = 0.001; */
131 /* for (int b = 0; b < N_BODIES; b ++) */
133 /* double p = 1 + b / (double) N_BODIES; */
134 /* double q = 2 - b / (double) N_BODIES; */
135 /* g_globals_ptr->dyn_bodies[b].addForce (f0 * cos (p*angle), f0 * sin (q*angle), 0); */
137 /* g_globals_ptr->dyn_bodies[0].addTorque (0, 0, 0.1); */
140 for (int i
= 0; i
< n
; i
++)
142 dSpaceCollide (g_globals_ptr
->coll_space_id
, 0, &cb_near_collision
);
143 g_globals_ptr
->dyn_world
.step (dReal(TIME_STEP
/n
));
144 g_globals_ptr
->coll_contacts
.empty ();
150 // @@@ hack Plane2D constraint error reduction here:
151 for (int b
= 0; b
< N_BODIES
; b
++)
153 const dReal
*rot
= dBodyGetAngularVel (g_globals_ptr
->dyn_bodies
[b
].id());
154 const dReal
*quat_ptr
;
159 quat_ptr
= dBodyGetQuaternion (g_globals_ptr
->dyn_bodies
[b
].id());
160 quat
[0] = quat_ptr
[0];
163 quat
[3] = quat_ptr
[3];
164 quat_len
= sqrt (quat
[0] * quat
[0] + quat
[3] * quat
[3]);
167 dBodySetQuaternion (g_globals_ptr
->dyn_bodies
[b
].id(), quat
);
168 dBodySetAngularVel (g_globals_ptr
->dyn_bodies
[b
].id(), 0, 0, rot
[2]);
177 for (int b
= 0; b
< N_BODIES
; b
++)
179 const dReal
*vel
= dBodyGetLinearVel (g_globals_ptr
->dyn_bodies
[b
].id()),
180 *rot
= dBodyGetAngularVel (g_globals_ptr
->dyn_bodies
[b
].id());
184 dBodySetLinearVel (g_globals_ptr
->dyn_bodies
[b
].id(), s
*vel
[0],s
*vel
[1],s
*vel
[2]);
185 dBodySetAngularVel (g_globals_ptr
->dyn_bodies
[b
].id(),t
*rot
[0],t
*rot
[1],t
*rot
[2]);
194 dsSetTexture (DS_WOOD
);
195 for (int b
= 0; b
< N_BODIES
; b
++)
198 dsSetColor (1.0, 0.5, 1.0);
200 dsSetColor (0, 0.5, 1.0);
202 dsDrawBoxD (g_globals_ptr
->dyn_bodies
[b
].getPosition(), g_globals_ptr
->dyn_bodies
[b
].getRotation(), g_globals_ptr
->bodies_sides
[b
]);
204 dsDrawBox (g_globals_ptr
->dyn_bodies
[b
].getPosition(), g_globals_ptr
->dyn_bodies
[b
].getRotation(), g_globals_ptr
->bodies_sides
[b
]);
220 dsFunctions drawstuff_functions
;
225 g_globals_ptr
= new GlobalVars();
229 dReal cf_mixing
;// = 1 / TIME_STEP * K_SPRING + K_DAMP;
230 dReal err_reduct
;// = TIME_STEP * K_SPRING * cf_mixing;
231 err_reduct
= REAL( 0.5 );
232 cf_mixing
= REAL( 0.001 );
233 dWorldSetERP (g_globals_ptr
->dyn_world
.id (), err_reduct
);
234 dWorldSetCFM (g_globals_ptr
->dyn_world
.id (), cf_mixing
);
235 g_globals_ptr
->dyn_world
.setGravity (0, 0.0, -1.0);
237 g_globals_ptr
->coll_space_id
= dSimpleSpaceCreate (0);
240 for (b
= 0; b
< N_BODIES
; b
++)
242 int l
= (int) (1 + sqrt ((double) N_BODIES
));
243 dReal x
= dReal( (0.5 + (b
/ l
)) / l
* STAGE_SIZE
);
244 dReal y
= dReal( (0.5 + (b
% l
)) / l
* STAGE_SIZE
);
245 dReal z
= REAL( 1.0 ) + REAL( 0.1 ) * (dReal
)drand48();
247 g_globals_ptr
->bodies_sides
[b
][0] = dReal( 5 * (0.2 + 0.7*drand48()) / sqrt((double)N_BODIES
) );
248 g_globals_ptr
->bodies_sides
[b
][1] = dReal( 5 * (0.2 + 0.7*drand48()) / sqrt((double)N_BODIES
) );
249 g_globals_ptr
->bodies_sides
[b
][2] = z
;
251 g_globals_ptr
->dyn_bodies
[b
].create (g_globals_ptr
->dyn_world
);
252 g_globals_ptr
->dyn_bodies
[b
].setPosition (x
, y
, z
/2);
253 g_globals_ptr
->dyn_bodies
[b
].setData ((void*) (dsizeint
)b
);
254 dBodySetLinearVel (g_globals_ptr
->dyn_bodies
[b
].id (),
255 dReal( 3 * (drand48 () - 0.5) ),
256 dReal( 3 * (drand48 () - 0.5) ), 0);
259 m
.setBox (1, g_globals_ptr
->bodies_sides
[b
][0],g_globals_ptr
->bodies_sides
[b
][1],g_globals_ptr
->bodies_sides
[b
][2]);
260 m
.adjust (REAL(0.1) * g_globals_ptr
->bodies_sides
[b
][0] * g_globals_ptr
->bodies_sides
[b
][1]);
261 g_globals_ptr
->dyn_bodies
[b
].setMass (&m
);
263 g_globals_ptr
->plane2d_joint_ids
[b
] = dJointCreatePlane2D (g_globals_ptr
->dyn_world
.id (), 0);
264 dJointAttach (g_globals_ptr
->plane2d_joint_ids
[b
], g_globals_ptr
->dyn_bodies
[b
].id (), 0);
267 dJointSetPlane2DXParam (g_globals_ptr
->plane2d_joint_ids
[0], dParamFMax
, 10);
268 dJointSetPlane2DYParam (g_globals_ptr
->plane2d_joint_ids
[0], dParamFMax
, 10);
271 // collision geoms and joints
272 dCreatePlane (g_globals_ptr
->coll_space_id
, 1, 0, 0, 0);
273 dCreatePlane (g_globals_ptr
->coll_space_id
, -1, 0, 0, -STAGE_SIZE
);
274 dCreatePlane (g_globals_ptr
->coll_space_id
, 0, 1, 0, 0);
275 dCreatePlane (g_globals_ptr
->coll_space_id
, 0, -1, 0, -STAGE_SIZE
);
277 for (b
= 0; b
< N_BODIES
; b
++)
280 coll_box_id
= dCreateBox (g_globals_ptr
->coll_space_id
,
281 g_globals_ptr
->bodies_sides
[b
][0], g_globals_ptr
->bodies_sides
[b
][1], g_globals_ptr
->bodies_sides
[b
][2]);
282 dGeomSetBody (coll_box_id
, g_globals_ptr
->dyn_bodies
[b
].id ());
285 g_globals_ptr
->coll_contacts
.create ();
288 // simulation loop (by drawstuff lib)
289 drawstuff_functions
.version
= DS_VERSION
;
290 drawstuff_functions
.start
= &cb_start
;
291 drawstuff_functions
.step
= &cb_sim_step
;
292 drawstuff_functions
.command
= 0;
293 drawstuff_functions
.stop
= 0;
294 drawstuff_functions
.path_to_textures
= DRAWSTUFF_TEXTURE_PATH
;
296 dsSimulationLoop (argc
, argv
, DS_SIMULATION_DEFAULT_WIDTH
, DS_SIMULATION_DEFAULT_HEIGHT
, &drawstuff_functions
);
299 delete g_globals_ptr
;
300 g_globals_ptr
= NULL
;