|
World of Rigid Bodies (WoRB)
|
Encapsulates a rigid body test-bed application. More...
#include <WoRB_TestBed.h>


Data Structures | |
| struct | TrajectoryItem |
| Represents trajectory snapshot item (position and orientation of the rigid body). More... | |
Public Member Functions | |
| WoRB_TestBed () | |
| Dummy constructor. | |
| ~WoRB_TestBed () | |
| Deallocates all objects. | |
| void | Initialize () |
| Delayed constructor; after all static members are initialized. | |
| void | Dump () const |
| Dumps all parameter values using Printf(). | |
| void | Run () |
| Runs the simulation and rendering. | |
| void | ClearTestBed () |
| Clears the current simulation data and prepares a new simulation. | |
| void | ReconfigureTestBed () |
| Initializes the test-bed with the default objects according to selected profile. | |
| void | Simulate () |
| Updates the current state of the scene. | |
| virtual void | OnProcessData () |
| Processes data calculated, solved and derived during the simulation time-step. | |
| void | DisplayEventHandler () |
| Renders the current scene. | |
| void | RenderDebugInfo () |
| Displays debugging information (like state variables) and short help. | |
| bool | IsValid () const |
| Returns whether application is properly initialized. | |
| void | SetupAnimation () |
| Creates the GLUT window and initializes the view. | |
| void | SetupProjection () |
| Sets the projection characteristics of the camera. | |
| void | CloseEventHandler () |
| Handles on-window-close event. | |
| void | ReshapeEventHandler (int width, int height) |
| Handles event when the window has changed size. | |
| void | KeyboardEventHandler (unsigned char key) |
| Called when GLUT detects a key press. | |
| void | SpecialKeyEventHandler (int key) |
| Called when GLUT detects a function key press. | |
| void | MotionEventHandler (int x, int y) |
| Called when GLUT detects a mouse drag. | |
| void | MouseEventHandler (int button, int state, int x, int y) |
| Called when GLUT detects a mouse button press. | |
| void | MouseWheelEventHandler (int, int direction, int x, int y) |
| Called when GLUT detects a mouse wheel is spun. | |
Protected Types | |
| typedef std::vector < WoRB::GLUT_Renderer * > | RBObjects |
| typedef std::vector < TrajectoryItem > | Trajectory |
| Represents a collection of trajectory snapshots. | |
Protected Attributes | |
| WoRB::WorldOfRigidBodies< 256, 1024 > | worb |
| Holds the WoRB physics simulation framework. | |
| double | FinalTime |
| Final simulation time, s. | |
| RBObjects | Objects |
| Holds the collection of all rendered rigid bodies in the system. | |
| WoRB::HalfSpace | GroundPlane |
| Holds the ground plane, with geometry of a half-space. | |
| WoRB::HalfSpace | BoxWall [4] |
| Holds the box walls, with geometry of half-spaces. | |
| double | GridTickLength |
| Holds the length of a single tick in the system grid. | |
| int | GridTicks |
| Holds the number of the ticks in the system grid (bounded by the walls). | |
| Trajectory | Trajectories |
| Holds the collection of trajectory snapshots of the rigid bodies in the system. | |
| volatile bool | IsInitialized |
| Indicates whether the instance is properly constructed. | |
| const char * | WindowTitle |
| Holds window title. | |
| int | WindowId |
| Holds GLUT window ID. | |
| volatile bool | IsRunning |
| Indicates whether the application is running. | |
| bool | IsPaused |
| Indicates whether the simulation is running (alternative to being paused). | |
| bool | AutoPause |
| Indicates whether the simulation halts after every time-step. | |
| bool | Wireframe |
| Indicates whether to display objects in wireframe. | |
| bool | ShowBodyAxes |
| Indicates whether to display axes of the rigid bodies. | |
| bool | ShowFloorMirror |
| Indicates whether to show objects mirrored in the floor. | |
| bool | ShowContacts |
| Indicates whether to display contact normals. | |
| bool | ShowTrajectories |
| Indicates whether to display trajectories. | |
| bool | ShowStateVariables |
| Indicates whether to display the system state variables. | |
| bool | ShowHelp |
| Indicates whether to display help info. | |
| unsigned | FollowObject |
| Holds the index of an object that is followed by the camera view. | |
| double | TimeStep |
| Holds integrator time-step length, in seconds. | |
| unsigned | TimeStepsPerFrame |
| Holds number of integrator time-steps solved per one video frame. | |
| unsigned | TimeStepsPerSnapshot |
| Holds number of integrator time-steps solved per one trajectory snapshot. | |
| double | CameraZoom |
| Holds the camera zoom (distance from the look-at point). | |
| WoRB::Quaternion | CameraLookAt |
| Holds the point camera looks at. | |
| double | CameraAngle |
| Holds the camera angle (phi). | |
| double | CameraElevation |
| Holds the camera elevation (theta). | |
| struct { | |
| double x | |
| double y | |
| int button | |
| int state | |
| } | LastMouse |
| Holds the position of the mouse at the last frame of a drag. | |
| double | LastDisplayTime |
| Holds time-stamp of the last screen update. | |
| volatile int | TestSuite |
| Holds next requested configuration profile. | |
Encapsulates a rigid body test-bed application.
Definition at line 23 of file WoRB_TestBed.h.
typedef std::vector<WoRB::GLUT_Renderer*> WoRB_TestBed::RBObjects [protected] |
Definition at line 39 of file WoRB_TestBed.h.
typedef std::vector<TrajectoryItem> WoRB_TestBed::Trajectory [protected] |
Represents a collection of trajectory snapshots.
Definition at line 74 of file WoRB_TestBed.h.
| WoRB_TestBed::WoRB_TestBed | ( | ) | [inline] |
Dummy constructor.
Use Initialize() to construct an instance.
Definition at line 184 of file WoRB_TestBed.h.
References IsInitialized.
{
IsInitialized = false;
}
Deallocates all objects.
Definition at line 22 of file WoRB_TestBed.cpp.
{
for ( RBObjects::iterator i = Objects.begin(); i != Objects.end(); ++i )
{
delete *i;
}
Objects.clear ();
IsInitialized = false;
}
| void WoRB_TestBed::ClearTestBed | ( | ) |
Clears the current simulation data and prepares a new simulation.
Definition at line 760 of file WoRB_TestBed.cpp.
References WoRB::Const::X, WoRB::Const::Y, and WoRB::Const::Z.
Referenced by WoRB_MexFunction::Parse().
{
// Remove rigid body references from the WoRB solver
//
worb.RemoveObjects ();
// Setup default parameters for collision detection/resolve algorithms
//
worb.Collisions.Restitution = 1; // Coefficient of restitution
worb.Collisions.Relaxation = 0.2; // Position projection relaxation coefficient
worb.Collisions.Friction = 0; // Dynamic friction coefficient
// Disable gravity
//
worb.Gravity = 0.0;
// Initialize the ground plane and the walls
//
double boxHalfSize = GridTicks * GridTickLength;
GroundPlane.Direction = Const::Y;
GroundPlane.Offset = 0.0;
BoxWall[0].Direction = Const::X; // left
BoxWall[0].Offset = -boxHalfSize;
BoxWall[1].Direction = -Const::X; // right
BoxWall[1].Offset = -boxHalfSize;
BoxWall[2].Direction = Const::Z; // rear
BoxWall[2].Offset = -boxHalfSize;
BoxWall[3].Direction = -Const::Z; // front
BoxWall[3].Offset = -boxHalfSize;
// Add the ground plane and the walls to our WoRB solver
//
worb.Add( GroundPlane );
// for ( unsigned i = 0; i < 4; ++i ) {
// worb.Add( BoxWall[i] );
// }
// Remove existing trajectories
//
Trajectories.clear ();
Trajectories.reserve( 10000 );
// Remove existing objects
//
for ( RBObjects::iterator i = Objects.begin(); i != Objects.end(); ++i ) {
delete *i;
}
Objects.clear ();
Objects.reserve( 64 );
}
| void WoRB_TestBed::CloseEventHandler | ( | ) | [inline] |
Handles on-window-close event.
Definition at line 248 of file WoRB_TestBed.h.
References IsRunning.
{
IsRunning = false;
}
| void WoRB_TestBed::DisplayEventHandler | ( | ) |
Renders the current scene.
Definition at line 315 of file WoRB_TestBed.cpp.
References WoRB::GLUT_Renderer::BodyShadow, WoRB::GLUT_Renderer::BodyShape, WoRB::GLUT_Renderer::FloorMirror, WoRB::Pause(), and WoRB::RenderAxes().
{
// Adjust camera's 'look-at' position depending on the selected object to follow
//
if ( FollowObject < Objects.size () )
{
CameraLookAt = Objects.at( FollowObject )->GetBody ().Position;
}
// Clear the viewport and setup the camera direction
//
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glLoadIdentity ();
gluLookAt( /*eye*/ CameraZoom, 0, 0, /*center*/ 0, 0, 0, /*up*/ 0, 1, 0 );
glTranslated ( -CameraZoom, 0, 0 ); // move away = zoom out
glRotated ( -CameraElevation, 0, 0, 1 ); // z-rotate = elevation
glRotated ( CameraAngle, 0, 1, 0 ); // y-rotate = angle
glTranslated ( -CameraLookAt.x, -CameraLookAt.y, -CameraLookAt.z );
if ( CameraElevation >= -8.0 )
{
// Render objects reflected in the floor (mirror)
//
if ( ShowFloorMirror )
{
glEnable( GL_DEPTH_TEST );
glEnable( GL_LIGHTING );
glEnable( GL_BLEND );
glColorMaterial( GL_FRONT_AND_BACK, GL_DIFFUSE );
glEnable( GL_COLOR_MATERIAL );
static const GLfloat lightPosition[] = { 1, -1, 0, 0 };
glLightfv( GL_LIGHT0, GL_POSITION, lightPosition );
// A transform matrix for rendering objects reflected in the floor
//
static const GLdouble floorMirrorTransform [] =
{
1, 0, 0, 0,
0, -1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
};
glPushMatrix();
glMultMatrixd( floorMirrorTransform );
for ( RBObjects::iterator i = Objects.begin(); i != Objects.end(); ++i )
{
(*i)->Render( GLUT_Renderer::FloorMirror );
}
glPopMatrix();
}
glDisable( GL_COLOR_MATERIAL );
glDisable( GL_LIGHTING );
glDisable( GL_DEPTH_TEST );
glDisable( GL_BLEND );
}
// Render a tiled ground plane i.e. the xz-grid
//
glColor3d( 0.95, 0.95, 0.85 );
glBegin( GL_LINES );
for ( int x = -GridTicks; x <= GridTicks; ++x )
{
for ( int z = -GridTicks; z <= GridTicks; ++z )
{
glVertex3d( x * GridTickLength, 0, -z * GridTickLength );
glVertex3d( x * GridTickLength, 0, z * GridTickLength );
glVertex3d( x * GridTickLength, 0, z * GridTickLength );
glVertex3d( -x * GridTickLength, 0, z * GridTickLength );
}
}
glEnd ();
// Display the main axes
//
RenderAxes( 10 * GridTickLength );
// Render ground shadows of the objects
//
glEnable( GL_BLEND );
glDisable( GL_DEPTH_TEST );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glColor4d( 0.1, 0.1, 0, 0.1 );
for ( RBObjects::iterator i = Objects.begin(); i != Objects.end(); ++i )
{
(*i)->Render( GLUT_Renderer::BodyShadow );
}
// Render the objects themselves
//
glEnable( GL_LIGHTING );
static const GLfloat lightPositionForMirror [] = { 1, 1, 0, 0 };
glLightfv( GL_LIGHT0, GL_POSITION, lightPositionForMirror );
glColorMaterial( GL_FRONT_AND_BACK, GL_DIFFUSE );
glEnable( GL_COLOR_MATERIAL );
if ( Wireframe ) {
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
}
else {
glEnable( GL_DEPTH_TEST );
}
for ( RBObjects::iterator i = Objects.begin(); i != Objects.end(); ++i )
{
(*i)->Render( GLUT_Renderer::BodyShape );
}
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
glDisable( GL_COLOR_MATERIAL );
glDisable( GL_LIGHTING );
// Render trajectories
//
if ( ShowTrajectories )
{
for ( Trajectory::iterator i = Trajectories.begin(); i != Trajectories.end(); ++i )
{
(*i).object->RenderWireframe( (*i).matrix );
}
}
glDisable( GL_DEPTH_TEST );
glDisable( GL_BLEND );
// Render any additional information
RenderDebugInfo ();
// Update the display and swap double-buffers
//
glFlush ();
glutSwapBuffers ();
// Remember the current time
//
double currentTime = glutGet( GLUT_ELAPSED_TIME );
double durationMs = TimeStep * TimeStepsPerFrame * 1e3; // in milliseconds
durationMs -= currentTime - LastDisplayTime;
if ( durationMs > 0 ) {
Pause( (unsigned long)durationMs );
}
LastDisplayTime = currentTime;
}
| void WoRB_TestBed::Dump | ( | ) | const |
Dumps all parameter values using Printf().
Definition at line 103 of file WoRB_TestBed.cpp.
References WoRB::RigidBody::AngularMomentum, WoRB::RigidBody::AngularVelocity, WoRB::Geometry::GetName(), WoRB::Cuboid::HalfExtent, WoRB::Geometry::IsCuboid(), WoRB::Geometry::IsSphere(), WoRB::RigidBody::KineticEnergy, WoRB::RigidBody::LinearMomentum, WoRB::RigidBody::Mass(), WoRB::RigidBody::Orientation, WoRB::RigidBody::Position, WoRB::Printf(), WoRB::Sphere::Radius, WoRB::RigidBody::Velocity, WoRB::Quaternion::w, WoRB::Quaternion::x, WoRB::Quaternion::y, and WoRB::Quaternion::z.
Referenced by WoRB_MexFunction::Parse().
{
Printf( "IsInitialized : %s\n", IsInitialized ? "true" : "false" );
Printf( "IsRunning : %s\n", IsRunning ? "true" : "false" );
Printf( "IsPaused : %s\n", IsPaused ? "true" : "false" );
Printf( "AutoPause : %s\n", AutoPause ? "true" : "false" );
Printf( "Wireframe : %s\n", Wireframe ? "true" : "false" );
Printf( "ShowBodyAxes : %s\n", ShowBodyAxes ? "true" : "false" );
Printf( "ShowFloorMirror : %s\n", ShowFloorMirror ? "true" : "false" );
Printf( "ShowContacts : %s\n", ShowContacts ? "true" : "false" );
Printf( "ShowTrajectories : %s\n", ShowTrajectories ? "true" : "false" );
Printf( "ShowStateVariables : %s\n", ShowStateVariables ? "true" : "false" );
Printf( "ShowHelp : %s\n", ShowHelp ? "true" : "false" );
Printf( "GridTickLength : %g m\n", GridTickLength );
Printf( "GridTicks : %d\n", GridTicks );
Printf( "TimeStep : %g s\n", TimeStep );
Printf( "TimeStepsPerFrame : %u\n", TimeStepsPerFrame );
Printf( "TimeStepsPerSnapshot : %u\n", TimeStepsPerSnapshot );
Printf( "FinalTime : %g s\n", FinalTime );
Printf( "FollowObject : %lu\n", FollowObject );
Printf( "CameraAngle : %g°\n", CameraAngle );
Printf( "CameraElevation : %g°\n", CameraElevation );
Printf( "CameraZoom : %g m\n", CameraZoom );
Printf( "CameraLookAt : [ %g, %g, %g ] m\n",
CameraLookAt.x, CameraLookAt.y, CameraLookAt.z );
// Now display objects in the system
//
for ( unsigned i = 0; i < Objects.size (); ++i )
{
const Geometry& g = Objects.at(i)->GetGeometry ();
const RigidBody& b = Objects.at(i)->GetBody ();
Printf( "\nObject %d\n", i + 1 );
Printf( "Geometry : %s\n", g.GetName () );
if ( g.IsSphere () )
{
const Sphere& s = (const Sphere&)g;
Printf( "Radius : %g m\n", s.Radius );
}
else if ( g.IsCuboid () )
{
const Cuboid& c = (const Cuboid&)g;
Printf( "Half-Extent : [ %g, %g, %g ] m\n",
c.HalfExtent.x, c.HalfExtent.y, c.HalfExtent.z );
}
Printf( "Mass : %g kg\n", b.Mass () );
Printf( "Position : [ %g, %g, %g | %g ] m\n",
b.Position.x, b.Position.y, b.Position.z, b.Position.w );
Printf( "Orientation : [ %g, %g, %g | %g ]\n",
b.Orientation.x, b.Orientation.y, b.Orientation.z, b.Orientation.w );
Printf( "Linear Momentum : [ %g, %g, %g | %g ] kg m s^-1\n",
b.LinearMomentum.x, b.LinearMomentum.y,
b.LinearMomentum.z, b.LinearMomentum.w );
Printf( "Angular Momentum : [ %g, %g, %g | %g ] kg m^2 s^-1m\n",
b.AngularMomentum.x, b.AngularMomentum.y,
b.AngularMomentum.z, b.AngularMomentum.w );
Printf( "Velocity : [ %g, %g, %g | %g ] m s^-1\n",
b.Velocity.x, b.Velocity.y, b.Velocity.z, b.Velocity.w );
Printf( "Angular Velocity : [ %g, %g, %g | %g ] s^-1\n",
b.AngularVelocity.x, b.AngularVelocity.y,
b.AngularVelocity.z, b.AngularVelocity.w );
Printf( "Kinetic Energy : %g J\n", b.KineticEnergy );
}
}
| void WoRB_TestBed::Initialize | ( | ) |
Delayed constructor; after all static members are initialized.
Definition at line 64 of file WoRB_TestBed.cpp.
References WoRB::Printf().
Referenced by main(), and WoRB_MexFunction::Parse().
{
Printf( "WoRB: WoRB_TestBed: Initialize\n" );
WindowTitle = "Lab4: World of Rigid Bodies";
// Initialize all properties to default values
//
TestSuite = 0; // Start test-suite #0
IsInitialized = false; // Not initialized yet
IsRunning = true; // Main-loop ends, when set to false
IsPaused = false; // Is simulation paused: no
AutoPause = false; // Is single-step mode: no
Wireframe = false; // Show bodies in wireframe instead of solid: no
ShowBodyAxes = true; // Show body axes: yes
ShowFloorMirror = false; // Show objects mirrored in the floor: no
ShowContacts = false; // Show contact normals: no
ShowTrajectories = false; // Show object's trajectories: no
ShowStateVariables = true; // Show system state variables: yes
ShowHelp = true; // Show short help: yes
GridTickLength = 1.0; // Tick size of the grid, in meters
GridTicks = 50; // Number of ticks in the grid
TimeStep = 0.01; // Integrator time-step, in seconds
TimeStepsPerFrame = 1; // Number of time-steps solved per one video frame
TimeStepsPerSnapshot = 20; // Number of time-steps per one trajectory snapshot
CameraZoom = 15.0; // Position in m, from the coordinate system origin
CameraLookAt.x = -2.0; // Look at x = -2 m
CameraLookAt.y = 2.0; // Look at y = 2 m (height)
CameraLookAt.z = 0.0; // Look at z = 0 m
CameraAngle = 55.0; // Angle in degrees, left/right of x-axis
CameraElevation = 25.0; // Angle in degres, up/bellow the horizon
FollowObject = 0; // Follow the first object (with camera)
LastDisplayTime = 0.0; // Force immediate update
FinalTime = 0.0; // No final (when simulation ends) time
}
| bool WoRB_TestBed::IsValid | ( | ) | const [inline] |
Returns whether application is properly initialized.
Definition at line 233 of file WoRB_TestBed.h.
References IsInitialized.
{
return IsInitialized;
}
| void WoRB_TestBed::KeyboardEventHandler | ( | unsigned char | key | ) |
Called when GLUT detects a key press.
Definition at line 658 of file WoRB_TestBed.cpp.
{
switch( key )
{
case 'A': case 'a': // Toggle displaying axes of the rigid bodies
ShowBodyAxes = ! ShowBodyAxes;
break;
case 'C': case 'c': // Toggle displaying contact info
ShowContacts = ! ShowContacts;
break;
case 'F': case 'f': // Toggle fullscreen mode
glutFullScreenToggle ();
break;
case 'H': case 'h': // Toggle help mode
ShowHelp = ! ShowHelp;
break;
case 'M': case 'm': // Toggle floor mirror
ShowFloorMirror = ! ShowFloorMirror;
break;
case 'Q': case 'q': // Quit application
IsRunning = false;
break;
case 'P': case 'p': case ' ': // Toggle running the simulation
IsPaused = ! IsPaused;
break;
case 'S': case 's': case '\r': // Advance only one time-step
AutoPause = true;
IsPaused = false;
break;
case 'T': case 't': // Toggle displaying trajectories
ShowTrajectories = ! ShowTrajectories;
// Trajectories.clear ();
break;
case 'V': case 'v': // Toggle displaying state variables
ShowStateVariables = ! ShowStateVariables;
break;
case 'W': case 'w': // Toggle wireframe mode
Wireframe = ! Wireframe;
break;
case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
TestSuite = key - '1';
break;
}
}
| void WoRB_TestBed::MotionEventHandler | ( | int | x, |
| int | y | ||
| ) |
Called when GLUT detects a mouse drag.
Definition at line 609 of file WoRB_TestBed.cpp.
References WoRB::Const::Pi.
{
int modifiers = glutGetModifiers ();
if ( modifiers == GLUT_ACTIVE_CTRL && LastMouse.state == GLUT_DOWN )
{
CameraZoom += 0.5 * ( y - LastMouse.y );
CameraZoom = std::max( 0.5, std::min( 300.0, CameraZoom ) );
}
else if ( modifiers == GLUT_ACTIVE_SHIFT && LastMouse.state == GLUT_DOWN )
{
double k = CameraZoom * 2e-3;
double dx = k * ( x - LastMouse.x );
double dy = k * ( y - LastMouse.y );
double phi = CameraAngle * Const::Pi / 180.0;
double theta = CameraElevation * Const::Pi / 180.0;
CameraLookAt.y += dy * cos( theta );
CameraLookAt.x += -dx * sin( phi ) - dy * cos( phi ) * sin( theta );
CameraLookAt.z += dx * cos( phi ) - dy * sin( phi ) * sin( theta );
if ( CameraLookAt.y < 0 ) {
CameraLookAt.y = 0;
}
}
else
{
CameraAngle += 0.25 * ( x - LastMouse.x );
while( CameraAngle < -180.0 ) {
CameraAngle += 360.0;
}
while ( CameraAngle > 180.0 ) {
CameraAngle -= 360.0;
}
CameraElevation += 0.25 * ( y - LastMouse.y );
CameraElevation = std::max( -20.0, std::min( 90.0, CameraElevation ) );
}
// Remember the current mouse position
//
LastMouse.x = x;
LastMouse.y = y;
}
| void WoRB_TestBed::MouseEventHandler | ( | int | button, |
| int | state, | ||
| int | x, | ||
| int | y | ||
| ) | [inline] |
| void WoRB_TestBed::MouseWheelEventHandler | ( | int | , |
| int | direction, | ||
| int | x, | ||
| int | y | ||
| ) | [inline] |
Called when GLUT detects a mouse wheel is spun.
Definition at line 287 of file WoRB_TestBed.h.
References CameraZoom, LastMouse, x, and y.
{
CameraZoom -= direction;
CameraZoom = std::max( 0.01, std::min( 200.0, CameraZoom ) );
// Remember the current mouse position
//
LastMouse.x = x;
LastMouse.y = y;
}
| virtual void WoRB_TestBed::OnProcessData | ( | ) | [inline, virtual] |
Processes data calculated, solved and derived during the simulation time-step.
This virtual method can be used to save simulation data in files or to return simulated data to MATLAB for example.
Reimplemented in WoRB_MexFunction.
Definition at line 221 of file WoRB_TestBed.h.
{}
| void WoRB_TestBed::ReconfigureTestBed | ( | ) |
Initializes the test-bed with the default objects according to selected profile.
Definition at line 816 of file WoRB_TestBed.cpp.
References WoRB::GLUT_Renderer::Colorf::A, WoRB::GLUT_Renderer::ActiveColor, WoRB::Geometry::Body, WoRB::RigidBody::CalculateDerivedQuantities(), WoRB::RigidBody::CanBeDeactivated, WoRB::Quaternion::FromAxisAngle(), WoRB::Const::g_n, WoRB::RigidBody::Orientation, WoRB::Const::Pi, WoRB::RigidBody::Position, WoRB::RandomQuaternion(), WoRB::Cuboid::SetMass(), WoRB::RigidBody::Velocity, WoRB::Quaternion::w, WoRB::Const::X, and WoRB::Quaternion::y.
{
/////////////////////////////////////////////////////////////////////////////////////
ClearTestBed (); // Clear existing simulation, if any.
LastDisplayTime = 0; // Force display refresh
if ( TestSuite >= 6 ) {
return;
}
/////////////////////////////////////////////////////////////////////////////////////
/* LAB4 */
ShowBodyAxes = true;
double thick = 0.01;
double v = -1;
double mass = 0.1;
double L = 5.0;
if ( TestSuite >= 1 )
{
thick = 0.7;
v = -20;
mass = 10e3;
}
/////////////////////////////////////////////////////////////////////////////////////
// Add new objects
Box* box1 = new Box(
/*x=*/ SpatialVector( -L/2, 3, 0 ),
/*q=*/ Quaternion::FromAxisAngle( Const::Pi/2, 0, 1, 0 ),
/*v=*/ 0.0, /*w=*/ 0.0,
/*extent=*/ SpatialVector( L, thick, L/2 ), /*mass=*/ mass
);
Objects.push_back( box1 );
worb.Add( box1 );
/////////////////////////////////////////////////////////////////////////////////////
Box* box2 = new Box(
/*x*/ SpatialVector( L - v, 3, L/2 ), /*q=*/ Quaternion( 0, 0, 1, 0 ),
/*v*/ v * Const::X, /*w=*/ 0.0,
/*extent=*/ SpatialVector( L, thick, L/2 ), /*mass=*/ mass
);
Objects.push_back( box2 );
worb.Add( box2 );
/////////////////////////////////////////////////////////////////////////////////////
if ( TestSuite >= 1 )
{
// box2->Orientation.w -= 1e-4;
box2->Orientation.w += 1e-4;
box1->RigidBody::Position.y += 1.0;
box2->RigidBody::Position.y += 1.01;
}
/////////////////////////////////////////////////////////////////////////////////////
if ( TestSuite >= 2 && TestSuite <= 3 )
{
for ( int i = 0; i < 30; ++i ) {
Ball* ball = new Ball(
RandomQuaternion( SpatialVector( 1, 3, 0 ), SpatialVector( 1, 20, 0 ) ),
RandomQuaternion (),
/*v=*/ 0.0, /*w=*/ 0.0, /*r=*/ 0.5, /*mass=*/ 1e1
);
Objects.push_back( ball );
worb.Add( ball );
}
}
/////////////////////////////////////////////////////////////////////////////////////
if ( TestSuite >= 2 )
{
worb.Gravity = Const::g_n; // add gravity
ShowBodyAxes = false;
box1->SetMass( 3 );
box1->Body->Position.y = 5;
box1->Body->CanBeDeactivated = true;
box2->Body->Position.y = 5;
box2->Body->CanBeDeactivated = true;
}
if ( TestSuite >= 3 )
{
worb.Collisions.Restitution = 0.2;
worb.Collisions.Friction = 0.2;
}
if ( TestSuite >= 4 )
{
ShowBodyAxes = false;
for ( int i = 0; i < 50; ++i )
{
Box* box;
if ( TestSuite >= 5 ) {
box2->Body->Velocity *= 0.8;
box2->Body->CalculateDerivedQuantities( false );
box = new Box(
/*x*/ SpatialVector( L, i * 0.4 + 0.2, L/2 ),
/*q*/ Quaternion( 1.0 ),
/*v*/ 0.0, /*w*/ 0.0,
/*extent=*/ SpatialVector( 2, 0.2, 2 ),
/*mass=*/ mass
);
}
else {
box2->Body->Velocity = 0.0;
box2->Body->CalculateDerivedQuantities( false );
worb.Collisions.Relaxation = 0.0;
box = new Box(
/*x*/ SpatialVector( L, i * 0.4 + 0.2, L/2 ),
/*q*/ RandomQuaternion (),
/*v*/ 0.0, /*w*/ 0.0,
/*extent=*/ RandomQuaternion(
SpatialVector( 0.5, 0.5, 0.5 ), SpatialVector( 1, 2, 3 ) ),
/*mass=*/ mass
);
box->ActiveColor = RandomQuaternion ();
box->ActiveColor.A = 0.8f;
}
box->Body->CanBeDeactivated = true;
Objects.push_back( box );
worb.Add( box );
}
}
/////////////////////////////////////////////////////////////////////////////////////
// Finally, initialize ODE (calculate derived quantities for recently added objects)
worb.InitializeODE ();
}
| void WoRB_TestBed::RenderDebugInfo | ( | ) |
Displays debugging information (like state variables) and short help.
Definition at line 479 of file WoRB_TestBed.cpp.
References WoRB::RigidBody::AngularMomentum, WoRB::RigidBody::AngularVelocity, WoRB::GLUT_Renderer::BodyAxes, WoRB::RigidBody::LinearMomentum, WoRB::RigidBody::Orientation, WoRB::RigidBody::Position, WoRB::RenderPrintf(), WoRB::RigidBody::Velocity, WoRB::Quaternion::w, WoRB::Quaternion::x, WoRB::Quaternion::y, and WoRB::Quaternion::z.
{
// Draw axes of the body
//
if ( ShowBodyAxes )
{
for ( RBObjects::iterator i = Objects.begin(); i != Objects.end(); ++i )
{
(*i)->Render( GLUT_Renderer::BodyAxes );
}
}
// Display the state variables of the system
//
if ( ShowStateVariables )
{
GLOrthoScreen _inScreenCoordinates; // Establish temporary transform for text
glColor3d( 0, 0, 0.7 );
const double E_k = worb.TotalKineticEnergy;
const double E_p = worb.TotalPotentialEnergy;
const Quaternion& p_tot = worb.TotalLinearMomentum;
const Quaternion& L_tot = worb.TotalAngularMomentum;
int row = glutGet( GLUT_WINDOW_HEIGHT ) - 20;
row = RenderPrintf( 10, row,
"N = %4lu, t = %6.3lf%s\n"
"E_t/k/p %12.3lf %12.3lf %12.3lf\n"
"p_tot %12.3lf %12.3lf %12.3lf\n"
"L_tot %12.3lf %12.3lf %12.3lf",
worb.TimeStepCount, worb.Time,
IsPaused || AutoPause ? " (Paused)" : "",
E_k + E_p, E_k, E_p,
p_tot.x, p_tot.y, p_tot.z,
L_tot.x, L_tot.y, L_tot.z
);
// Display the state variables of the rigid bodies
//
unsigned nShown = unsigned( Objects.size () );
nShown = std::min( IsPaused || AutoPause ? 4u : 0u, nShown );
for ( unsigned i = 0; i < nShown; ++i )
{
const RigidBody& b = Objects.at(i)->GetBody ();
const Quaternion& x = b.Position;
const Quaternion& q = b.Orientation;
const Quaternion& p = b.LinearMomentum;
const Quaternion& L = b.AngularMomentum;
const Quaternion& v = b.Velocity;
const Quaternion& w = b.AngularVelocity;
row = RenderPrintf( 10, row,
"(%d) x %12.3lf %12.3lf %12.3lf\n"
" q %12.3lf %12.3lf %12.3lf %12.3lf\n"
" p %12.3lf %12.3lf %12.3lf\n"
" L %12.3lf %12.3lf %12.3lf\n"
" v %12.3lf %12.3lf %12.3lf\n"
" w %12.3lf %12.3lf %12.3lf",
i + 1, x.x, x.y, x.z,
q.x, q.y, q.z, q.w,
p.x, p.y, p.z,
L.x, L.y, L.z,
v.x, v.y, v.z,
w.x, w.y, w.z
);
}
}
// Display short help
//
if ( ShowHelp )
{
GLOrthoScreen _inScreenCoordinates; // Establish temporary transform for text
glColor3d( 0, 0, 0 );
RenderPrintf( 10, 4 * 25,
"Shortcut keys:\n"
" 1, 2, ... for different simulation\n"
" (P)ause, (S)ingle-step, (Q)uit\n"
" (A)xes, (V)ariables, (C)ontacts, (T)rajectories\n"
" (W)ireframe, Floor (M)irror, (F)ullscreen"
);
glColor3d( 0, 0, 1 );
RenderPrintf( 10, 10,
"Camera: a= %+5.1lf, e= %+5.1lf, d= %+5.1lf, at= %+5.1lf %+5.1lf %+5.1lf",
CameraAngle, CameraElevation, CameraZoom,
CameraLookAt.x, CameraLookAt.y, CameraLookAt.z
);
}
// Display contact normals.
// Green between two objects, red between objects and scenery e.g. floor.
//
if ( ShowContacts )
{
glLineWidth( 3 );
glBegin( GL_LINES );
for ( unsigned i = 0; i < worb.Collisions.Count (); ++i )
{
Quaternion pos = worb.Collisions[i].Position;
Quaternion n = worb.Collisions[i].Normal;
Quaternion end = pos + n;
if ( worb.Collisions[i].WithScenery () ) {
glColor3d( 1, 0, 0 ); // red body
} else {
glColor3d( 0, 1, 0 ); // green body
}
glVertex3d( pos.x, pos.y, pos.z );
glVertex3d( end.x, end.y, end.z );
pos = end;
end = pos + n * 0.1;
glColor3d( 0, 0, 1 ); // blue head
glVertex3d( pos.x, pos.y, pos.z );
glVertex3d( end.x, end.y, end.z );
}
glEnd ();
glLineWidth( 1 );
}
}
| void WoRB_TestBed::ReshapeEventHandler | ( | int | width, |
| int | height | ||
| ) | [inline] |
Handles event when the window has changed size.
Definition at line 255 of file WoRB_TestBed.h.
References SetupProjection().
{
glViewport( 0, 0, width, height );
SetupProjection ();
}
| void WoRB_TestBed::Run | ( | ) |
Runs the simulation and rendering.
Definition at line 37 of file WoRB_TestBed.cpp.
References WoRB::Printf().
Referenced by main(), and mexFunction().
{
Printf( "WoRB: WoRB_TestBed: Run\n" );
OnProcessData (); // Process initial simulation data
glutPopWindow ();
while ( IsRunning )
{
Simulate ();
glutMainLoopEvent ();
}
glutDestroyWindow( WindowId );
for ( unsigned i = 0; i < 10; ++i ) {
glutMainLoopEvent ();
}
Printf( "WoRB: Destroyed GLUT window %d\n", WindowId );
IsInitialized = false;
}
| void WoRB_TestBed::SetupAnimation | ( | ) |
Creates the GLUT window and initializes the view.
Definition at line 185 of file WoRB_TestBed.cpp.
References WoRB::glutForegroundWindow(), and WoRB::Printf().
Referenced by main(), and mexFunction().
{
// Setup common execution options for GLUT: not to call exit() when finished
//
glutSetOption( GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION );
// Create GLUT window
//
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
glutInitWindowSize( 800, 600 );
WindowId = glutCreateWindow( WindowTitle );
glutForegroundWindow ();
Printf( "WoRB: Created GLUT window %d\n", WindowId );
// Initialize ambient light
//
GLfloat lightAmbient[] = { 0.5, 0.5, 0.5, 1 };
glLightfv( GL_LIGHT0, GL_AMBIENT, lightAmbient );
GLfloat lightDiffuse[] = { 1, 1, 1, 1 };
glLightfv( GL_LIGHT0, GL_DIFFUSE, lightDiffuse );
glEnable( GL_LIGHT0 );
glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
glEnable( GL_DEPTH_TEST );
glShadeModel( GL_SMOOTH );
// Finally, setup camera position
//
SetupProjection ();
// .. and mark the instance as initialized.
//
IsInitialized = true;
}
| void WoRB_TestBed::SetupProjection | ( | ) |
Sets the projection characteristics of the camera.
Definition at line 228 of file WoRB_TestBed.cpp.
Referenced by ReshapeEventHandler().
{
double aspect = double( glutGet( GLUT_WINDOW_WIDTH ) )
/ std::max( 1, glutGet( GLUT_WINDOW_HEIGHT ) );
aspect = std::min( 2e3, std::max( -2e3, aspect ) );
glMatrixMode( GL_PROJECTION );
glLoadIdentity ();
gluPerspective( 45.0, aspect, 1.0, 500.0 );
glMatrixMode( GL_MODELVIEW );
}
| void WoRB_TestBed::Simulate | ( | ) |
Updates the current state of the scene.
Definition at line 244 of file WoRB_TestBed.cpp.
References WoRB::GLUT_Renderer::GetBody(), WoRB::QTensor::GetGLTransform(), WoRB_TestBed::TrajectoryItem::matrix, WoRB_TestBed::TrajectoryItem::object, WoRB::Pause(), and WoRB::RigidBody::ToWorld.
{
// Reconfigure the test-bed, if requested
//
if ( TestSuite >= 0 )
{
ReconfigureTestBed ();
TestSuite = -1; // Set the flag to 'initialized'
}
// Just refresh display and sleep some time, when paused
//
if ( IsPaused )
{
glutPostRedisplay ();
// Just wait
double durationMs = TimeStep * TimeStepsPerFrame * 1e3; // in milliseconds
Pause( (unsigned long)durationMs );
return;
}
// If not paused, solve ODE
//
worb.SolveODE( TimeStep );
// Process data calculated during the simulation, e.g. save data.
//
OnProcessData ();
if ( FinalTime > 0 && worb.Time >= FinalTime )
{
IsRunning = false;
}
// Take a snapshot of object's positions, when snapshot time comes
//
if ( worb.TimeStepCount % TimeStepsPerSnapshot == 0 && ShowTrajectories )
{
for ( RBObjects::iterator i = Objects.begin(); i != Objects.end(); ++i )
{
if ( (*i)->ShowTrajectory ) {
TrajectoryItem ti;
ti.object = *i;
(*i)->GetBody ().ToWorld.GetGLTransform( ti.matrix );
Trajectories.push_back( ti );
}
}
}
// Animate objects, when (animation frame) time comes
//
if ( worb.TimeStepCount % TimeStepsPerFrame == 0 || AutoPause )
{
glutPostRedisplay ();
}
// Clear auto-pause flag, i.e. force user to set `IsPaused = false`
// and `AutoPause = true` for the next simulation single-step.
//
if ( AutoPause )
{
AutoPause = false;
IsPaused = true;
}
}
| void WoRB_TestBed::SpecialKeyEventHandler | ( | int | key | ) |
Called when GLUT detects a function key press.
Definition at line 718 of file WoRB_TestBed.cpp.
{
switch( key )
{
case GLUT_KEY_F1: // Follow body 1
FollowObject = 0;
break;
case GLUT_KEY_F2: // Follow body 2
FollowObject = 1;
break;
case GLUT_KEY_F3: // Follow body 3
FollowObject = 2;
break;
case GLUT_KEY_F4: // Follow body 4
FollowObject = 3;
break;
case GLUT_KEY_F11: // Look at coordinate origin, with offset of Oxyz bisectris
FollowObject = 0xFFFFu;
CameraLookAt = 0.0;
CameraAngle = 55.0;
CameraElevation = 25.0;
CameraZoom = 20;
break;
case GLUT_KEY_F12: // Look at coordinate origin, from above
FollowObject = 0xFFFFu;
CameraLookAt = 0.0;
CameraAngle = 0.0;
CameraElevation = 90.0;
CameraZoom = 30;
break;
}
}
bool WoRB_TestBed::AutoPause [protected] |
Indicates whether the simulation halts after every time-step.
Definition at line 104 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::Parse().
WoRB::HalfSpace WoRB_TestBed::BoxWall[4] [protected] |
Holds the box walls, with geometry of half-spaces.
Definition at line 51 of file WoRB_TestBed.h.
Definition at line 168 of file WoRB_TestBed.h.
Referenced by MouseEventHandler().
double WoRB_TestBed::CameraAngle [protected] |
Holds the camera angle (phi).
Definition at line 160 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::Parse().
double WoRB_TestBed::CameraElevation [protected] |
Holds the camera elevation (theta).
Definition at line 164 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::Parse().
WoRB::Quaternion WoRB_TestBed::CameraLookAt [protected] |
Holds the point camera looks at.
Definition at line 156 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::Parse().
double WoRB_TestBed::CameraZoom [protected] |
Holds the camera zoom (distance from the look-at point).
Definition at line 152 of file WoRB_TestBed.h.
Referenced by MouseWheelEventHandler(), and WoRB_MexFunction::Parse().
double WoRB_TestBed::FinalTime [protected] |
Final simulation time, s.
Definition at line 35 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::CreateResultMatrix(), and WoRB_MexFunction::Parse().
unsigned WoRB_TestBed::FollowObject [protected] |
Holds the index of an object that is followed by the camera view.
Definition at line 136 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::Parse().
double WoRB_TestBed::GridTickLength [protected] |
Holds the length of a single tick in the system grid.
Definition at line 55 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::Parse().
int WoRB_TestBed::GridTicks [protected] |
Holds the number of the ticks in the system grid (bounded by the walls).
Definition at line 59 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::Parse().
WoRB::HalfSpace WoRB_TestBed::GroundPlane [protected] |
Holds the ground plane, with geometry of a half-space.
Definition at line 47 of file WoRB_TestBed.h.
volatile bool WoRB_TestBed::IsInitialized [protected] |
Indicates whether the instance is properly constructed.
Definition at line 84 of file WoRB_TestBed.h.
Referenced by IsValid(), WoRB_MexFunction::Parse(), and WoRB_TestBed().
bool WoRB_TestBed::IsPaused [protected] |
Indicates whether the simulation is running (alternative to being paused).
Definition at line 100 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::Parse().
volatile bool WoRB_TestBed::IsRunning [protected] |
Indicates whether the application is running.
Definition at line 96 of file WoRB_TestBed.h.
Referenced by CloseEventHandler(), and WoRB_MexFunction::Parse().
double WoRB_TestBed::LastDisplayTime [protected] |
Holds time-stamp of the last screen update.
Definition at line 172 of file WoRB_TestBed.h.
struct { ... } WoRB_TestBed::LastMouse [protected] |
Holds the position of the mouse at the last frame of a drag.
Referenced by MouseEventHandler(), and MouseWheelEventHandler().
RBObjects WoRB_TestBed::Objects [protected] |
Holds the collection of all rendered rigid bodies in the system.
Definition at line 43 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::OnProcessData(), and WoRB_MexFunction::Parse().
bool WoRB_TestBed::ShowBodyAxes [protected] |
Indicates whether to display axes of the rigid bodies.
Definition at line 112 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::Parse().
bool WoRB_TestBed::ShowContacts [protected] |
Indicates whether to display contact normals.
Definition at line 120 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::Parse().
bool WoRB_TestBed::ShowFloorMirror [protected] |
Indicates whether to show objects mirrored in the floor.
Definition at line 116 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::Parse().
bool WoRB_TestBed::ShowHelp [protected] |
Indicates whether to display help info.
Definition at line 132 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::Parse().
bool WoRB_TestBed::ShowStateVariables [protected] |
Indicates whether to display the system state variables.
Definition at line 128 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::Parse().
bool WoRB_TestBed::ShowTrajectories [protected] |
Indicates whether to display trajectories.
Definition at line 124 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::Parse().
Definition at line 168 of file WoRB_TestBed.h.
Referenced by MouseEventHandler().
volatile int WoRB_TestBed::TestSuite [protected] |
Holds next requested configuration profile.
Definition at line 176 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::Parse().
double WoRB_TestBed::TimeStep [protected] |
Holds integrator time-step length, in seconds.
Definition at line 140 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::CreateResultMatrix(), and WoRB_MexFunction::Parse().
unsigned WoRB_TestBed::TimeStepsPerFrame [protected] |
Holds number of integrator time-steps solved per one video frame.
Definition at line 144 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::Parse().
unsigned WoRB_TestBed::TimeStepsPerSnapshot [protected] |
Holds number of integrator time-steps solved per one trajectory snapshot.
Definition at line 148 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::Parse().
Trajectory WoRB_TestBed::Trajectories [protected] |
Holds the collection of trajectory snapshots of the rigid bodies in the system.
Definition at line 78 of file WoRB_TestBed.h.
int WoRB_TestBed::WindowId [protected] |
Holds GLUT window ID.
Definition at line 92 of file WoRB_TestBed.h.
const char* WoRB_TestBed::WindowTitle [protected] |
Holds window title.
Definition at line 88 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::Parse().
bool WoRB_TestBed::Wireframe [protected] |
Indicates whether to display objects in wireframe.
Definition at line 108 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::Parse().
WoRB::WorldOfRigidBodies<256,1024> WoRB_TestBed::worb [protected] |
Holds the WoRB physics simulation framework.
Definition at line 31 of file WoRB_TestBed.h.
Referenced by WoRB_MexFunction::OnProcessData(), and WoRB_MexFunction::Parse().
| double WoRB_TestBed::x |
Definition at line 168 of file WoRB_TestBed.h.
Referenced by MouseEventHandler(), and MouseWheelEventHandler().
| double WoRB_TestBed::y |
Definition at line 168 of file WoRB_TestBed.h.
Referenced by MouseEventHandler(), and MouseWheelEventHandler().