Rube Goldberg Machine 1.0
This is the base code for Rube Goldberg designed for the CS296 Software Systems Lab
src/cs296_base.cpp
Go to the documentation of this file.
00001 /*
00002 * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
00003 *
00004 * This software is provided 'as-is', without any express or implied
00005 * warranty.  In no event will the authors be held liable for any damages
00006 * arising from the use of this software.
00007 * Permission is granted to anyone to use this software for any purpose,
00008 * including commercial applications, and to alter it and redistribute it
00009 * freely, subject to the following restrictions:
00010 * 1. The origin of this software must not be misrepresented; you must not
00011 * claim that you wrote the original software. If you use this software
00012 * in a product, an acknowledgment in the product documentation would be
00013 * appreciated but is not required.
00014 * 2. Altered source versions must be plainly marked as such, and must not be
00015 * misrepresented as being the original software.
00016 * 3. This notice may not be removed or altered from any source distribution.
00017 */
00018 
00019 #include "cs296_base.hpp"
00020 #include <cstdio>
00021 using namespace std;
00022 using namespace cs296;
00023 
00024 
00025 base_sim_t::base_sim_t()
00026 {
00027     b2Vec2 gravity;
00028     gravity.Set(0.0f, -10.0f);
00029     m_world = new b2World(gravity);
00030 
00031     m_text_line = 30;
00032 
00033     m_point_count = 0;
00034     
00035     m_world->SetDebugDraw(&m_debug_draw);
00036     
00037     m_step_count = 0;
00038 
00039     b2BodyDef body_def;
00040     m_ground_body = m_world->CreateBody(&body_def);
00041 
00042     memset(&m_max_profile, 0, sizeof(b2Profile));
00043     memset(&m_total_profile, 0, sizeof(b2Profile));
00044 }
00045 
00046 base_sim_t::~base_sim_t()
00047 {
00048     // By deleting the world, we delete the bomb, mouse joint, etc.
00049     delete m_world;
00050     m_world = NULL;
00051 }
00052 
00053 void base_sim_t::pre_solve(b2Contact* contact, const b2Manifold* oldManifold)
00054 {
00055   const b2Manifold* manifold = contact->GetManifold();
00056   
00057   if (manifold->pointCount == 0)
00058     {
00059       return;
00060     }
00061   
00062   b2Fixture* fixtureA = contact->GetFixtureA();
00063   b2Fixture* fixtureB = contact->GetFixtureB();
00064   
00065   b2PointState state1[b2_maxManifoldPoints], state2[b2_maxManifoldPoints];
00066   b2GetPointStates(state1, state2, oldManifold, manifold);
00067   
00068   b2WorldManifold world_manifold;
00069   contact->GetWorldManifold(&world_manifold);
00070   
00071   for (int32 i = 0; i < manifold->pointCount && m_point_count < k_max_contact_points; ++i)
00072     {
00073       contact_point_t* cp = m_points + m_point_count;
00074       cp->fixtureA = fixtureA;
00075       cp->fixtureB = fixtureB;
00076       cp->position = world_manifold.points[i];
00077       cp->normal = world_manifold.normal;
00078       cp->state = state2[i];
00079       ++m_point_count;
00080     }
00081 }
00082 
00083 void base_sim_t::draw_title(int x, int y, const char *string)
00084 {
00085     m_debug_draw.DrawString(x, y, string);
00086 }
00087 
00088 void base_sim_t::step(settings_t* settings)
00089 {
00090   float32 time_step = settings->hz > 0.0f ? 1.0f / settings->hz : float32(0.0f);
00091 
00092   if (settings->pause)
00093     {
00094       if (settings->single_step)
00095     {
00096       settings->single_step = 0;
00097     }
00098       else
00099     {
00100       time_step = 0.0f;
00101     }
00102       
00103       m_debug_draw.DrawString(5, m_text_line, "****PAUSED****");
00104       m_text_line += 15;
00105     }
00106   
00107   uint32 flags = 0;
00108   flags += settings->draw_shapes            * b2Draw::e_shapeBit;
00109   flags += settings->draw_joints            * b2Draw::e_jointBit;
00110   flags += settings->draw_AABBs         * b2Draw::e_aabbBit;
00111   flags += settings->draw_pairs         * b2Draw::e_pairBit;
00112   flags += settings->draw_COMs              * b2Draw::e_centerOfMassBit;
00113   m_debug_draw.SetFlags(flags);
00114   
00115   m_world->SetWarmStarting(settings->enable_warm_starting > 0);
00116   m_world->SetContinuousPhysics(settings->enable_continuous > 0);
00117   m_world->SetSubStepping(settings->enable_sub_stepping > 0);
00118   
00119   m_point_count = 0;
00120   
00121   m_world->Step(time_step, settings->velocity_iterations, settings->position_iterations);
00122   
00123   m_world->DrawDebugData();
00124   
00125   if (time_step > 0.0f)
00126     {
00127       ++m_step_count;
00128     }
00129   
00130   if (settings->draw_stats)
00131     {
00132       int32 body_count = m_world->GetBodyCount();
00133       int32 contact_count = m_world->GetContactCount();
00134       int32 joint_count = m_world->GetJointCount();
00135       m_debug_draw.DrawString(5, m_text_line, "bodies/contacts/joints = %d/%d/%d", body_count, contact_count, joint_count);
00136       m_text_line += 15;
00137       
00138       int32 proxy_count = m_world->GetProxyCount();
00139       int32 height = m_world->GetTreeHeight();
00140       int32 balance = m_world->GetTreeBalance();
00141       float32 quality = m_world->GetTreeQuality();
00142       m_debug_draw.DrawString(5, m_text_line, "proxies/height/balance/quality = %d/%d/%d/%g", proxy_count, height, balance, quality);
00143       m_text_line += 15;
00144     }
00145   
00146   // Track maximum profile times
00147   {
00148     const b2Profile& p = m_world->GetProfile();
00149     m_max_profile.step = b2Max(m_max_profile.step, p.step);
00150     m_max_profile.collide = b2Max(m_max_profile.collide, p.collide);
00151     m_max_profile.solve = b2Max(m_max_profile.solve, p.solve);
00152     m_max_profile.solveInit = b2Max(m_max_profile.solveInit, p.solveInit);
00153     m_max_profile.solveVelocity = b2Max(m_max_profile.solveVelocity, p.solveVelocity);
00154     m_max_profile.solvePosition = b2Max(m_max_profile.solvePosition, p.solvePosition);
00155     m_max_profile.solveTOI = b2Max(m_max_profile.solveTOI, p.solveTOI);
00156     m_max_profile.broadphase = b2Max(m_max_profile.broadphase, p.broadphase);
00157     
00158     m_total_profile.step += p.step;
00159     m_total_profile.collide += p.collide;
00160     m_total_profile.solve += p.solve;
00161     m_total_profile.solveInit += p.solveInit;
00162     m_total_profile.solveVelocity += p.solveVelocity;
00163     m_total_profile.solvePosition += p.solvePosition;
00164     m_total_profile.solveTOI += p.solveTOI;
00165     m_total_profile.broadphase += p.broadphase;
00166   }
00167   
00168   if (settings->draw_profile)
00169     {
00170       const b2Profile& p = m_world->GetProfile();
00171       
00172       b2Profile ave_profile;
00173       memset(&ave_profile, 0, sizeof(b2Profile));
00174       if (m_step_count > 0)
00175     {
00176       float32 scale = 1.0f / m_step_count;
00177       ave_profile.step = scale * m_total_profile.step;
00178       ave_profile.collide = scale * m_total_profile.collide;
00179       ave_profile.solve = scale * m_total_profile.solve;
00180       ave_profile.solveInit = scale * m_total_profile.solveInit;
00181       ave_profile.solveVelocity = scale * m_total_profile.solveVelocity;
00182       ave_profile.solvePosition = scale * m_total_profile.solvePosition;
00183       ave_profile.solveTOI = scale * m_total_profile.solveTOI;
00184       ave_profile.broadphase = scale * m_total_profile.broadphase;
00185     }
00186       
00187       m_debug_draw.DrawString(5, m_text_line, "step [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.step, ave_profile.step, m_max_profile.step);
00188       m_text_line += 15;
00189       m_debug_draw.DrawString(5, m_text_line, "collide [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.collide, ave_profile.collide, m_max_profile.collide);
00190       m_text_line += 15;
00191       m_debug_draw.DrawString(5, m_text_line, "solve [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solve, ave_profile.solve, m_max_profile.solve);
00192       m_text_line += 15;
00193       m_debug_draw.DrawString(5, m_text_line, "solve init [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solveInit, ave_profile.solveInit, m_max_profile.solveInit);
00194       m_text_line += 15;
00195       m_debug_draw.DrawString(5, m_text_line, "solve velocity [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solveVelocity, ave_profile.solveVelocity, m_max_profile.solveVelocity);
00196       m_text_line += 15;
00197       m_debug_draw.DrawString(5, m_text_line, "solve position [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solvePosition, ave_profile.solvePosition, m_max_profile.solvePosition);
00198       m_text_line += 15;
00199       m_debug_draw.DrawString(5, m_text_line, "solveTOI [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.solveTOI, ave_profile.solveTOI, m_max_profile.solveTOI);
00200       m_text_line += 15;
00201       m_debug_draw.DrawString(5, m_text_line, "broad-phase [ave] (max) = %5.2f [%6.2f] (%6.2f)", p.broadphase, ave_profile.broadphase, m_max_profile.broadphase);
00202       m_text_line += 15;
00203     }
00204     
00205   if (settings->draw_contact_points)
00206     {
00207       //const float32 k_impulseScale = 0.1f;
00208       const float32 k_axis_scale = 0.3f;
00209       
00210       for (int32 i = 0; i < m_point_count; ++i)
00211     {
00212       contact_point_t* point = m_points + i;
00213       
00214       if (point->state == b2_addState)
00215         {
00216           // Add
00217           m_debug_draw.DrawPoint(point->position, 10.0f, b2Color(0.3f, 0.95f, 0.3f));
00218         }
00219       else if (point->state == b2_persistState)
00220         {
00221           // Persist
00222           m_debug_draw.DrawPoint(point->position, 5.0f, b2Color(0.3f, 0.3f, 0.95f));
00223         }
00224       
00225       if (settings->draw_contact_normals == 1)
00226         {
00227           b2Vec2 p1 = point->position;
00228           b2Vec2 p2 = p1 + k_axis_scale * point->normal;
00229           m_debug_draw.DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.9f));
00230         }
00231       else if (settings->draw_contact_forces == 1)
00232         {
00233           //b2Vec2 p1 = point->position;
00234           //b2Vec2 p2 = p1 + k_forceScale * point->normalForce * point->normal;
00235           //DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
00236         }
00237       
00238       if (settings->draw_friction_forces == 1)
00239         {
00240           //b2Vec2 tangent = b2Cross(point->normal, 1.0f);
00241           //b2Vec2 p1 = point->position;
00242           //b2Vec2 p2 = p1 + k_forceScale * point->tangentForce * tangent;
00243           //DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
00244         }
00245     }
00246     }
00247 }
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines