Rube Goldberg Machine 1.0
This is the base code for Rube Goldberg designed for the CS296 Software Systems Lab
|
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 }