From fa62113ad7fe81dea8b887bb13184948b47ec643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Thu, 20 Jun 2013 23:56:54 -0300 Subject: [PATCH] Added cShapePoint for Physics ( usefull to draw boxes or rounded points faster ). Working on the Physics example. Updated fonts example. --- .hgignore | 1 + include/eepp/physics.hpp | 1 + include/eepp/physics/cshapepoint.hpp | 35 ++ premake4.lua | 6 + projects/linux/ee.creator.user | 97 ++++- projects/linux/ee.files | 3 + src/eepp/graphics/cconsole.cpp | 6 +- src/eepp/physics/cshapepoint.cpp | 70 ++++ src/examples/empty_window/empty_window.cpp | 6 +- src/examples/fonts/fonts.cpp | 9 +- src/examples/physics/physics.cpp | 446 +++++++++++++++++++++ 11 files changed, 664 insertions(+), 16 deletions(-) create mode 100644 include/eepp/physics/cshapepoint.hpp create mode 100644 src/eepp/physics/cshapepoint.cpp create mode 100644 src/examples/physics/physics.cpp diff --git a/.hgignore b/.hgignore index 7f62533bf..466542d47 100644 --- a/.hgignore +++ b/.hgignore @@ -20,6 +20,7 @@ eesound* eesprite* eefonts* eevbo-fbo-batch* +eephysics* eeiv* ee.tag log.log diff --git a/include/eepp/physics.hpp b/include/eepp/physics.hpp index dfa2b5c4f..3e538a6a6 100644 --- a/include/eepp/physics.hpp +++ b/include/eepp/physics.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/include/eepp/physics/cshapepoint.hpp b/include/eepp/physics/cshapepoint.hpp new file mode 100644 index 000000000..550def019 --- /dev/null +++ b/include/eepp/physics/cshapepoint.hpp @@ -0,0 +1,35 @@ +#ifndef EE_PHYSICS_CSHAPEPOINT_HPP +#define EE_PHYSICS_CSHAPEPOINT_HPP + +#include + +CP_NAMESPACE_BEGIN + +class CP_API cShapePoint : public cShape { + public: + static cShapePoint * New( cBody * body, cpFloat radius, cVect offset ); + + cShapePoint( cBody * body, cpFloat radius, cVect offset ); + + cVect Offset(); + + virtual void Offset( const cVect& offset ); + + cpFloat Radius(); + + virtual void Radius( const cpFloat& radius ); + + virtual void Draw( cSpace * space ); + + #ifdef PHYSICS_RENDERER_ENABLED + cpFloat DrawRadius(); + + virtual void DrawRadius( const cpFloat& radius ); + protected: + cpFloat mDrawRadius; + #endif +}; + +CP_NAMESPACE_END + +#endif diff --git a/premake4.lua b/premake4.lua index aa8c23967..075b3b7b8 100644 --- a/premake4.lua +++ b/premake4.lua @@ -752,6 +752,12 @@ solution "eepp" files { "src/examples/vbo_fbo_batch/*.cpp" } build_link_configuration( "eevbo-fbo-batch" ) + project "eepp-physics" + kind "WindowedApp" + language "C++" + files { "src/examples/physics/*.cpp" } + build_link_configuration( "eephysics" ) + if os.isfile("external_projects.lua") then dofile("external_projects.lua") end diff --git a/projects/linux/ee.creator.user b/projects/linux/ee.creator.user index 6bbae736d..52c340969 100644 --- a/projects/linux/ee.creator.user +++ b/projects/linux/ee.creator.user @@ -1,6 +1,6 @@ - + ProjectExplorer.Project.ActiveTarget @@ -48,9 +48,9 @@ Desktop Desktop {388e5431-b31b-42b3-b9ad-9002d279d75d} - 0 + 18 0 - 0 + 10 /home/programming/eepp/make/linux @@ -469,6 +469,46 @@ debug-vbo-fbo-batch GenericProjectManager.GenericBuildConfiguration + + /home/programming/eepp/make/linux + + + + false + -j4 eepp-physics + make + true + Make + + GenericProjectManager.GenericMakeStep + + 1 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + clean + make + %{buildDir} + Custom Process Step + + ProjectExplorer.ProcessStep + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + debug-test + debug-physics + GenericProjectManager.GenericBuildConfiguration + /home/programming/eepp/make/linux @@ -789,7 +829,7 @@ release-es GenericProjectManager.GenericBuildConfiguration - 18 + 19 0 @@ -898,6 +938,53 @@ false false + + true + + false + false + false + false + true + 0.01 + 10 + true + 25 + + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + + 2 + /home/programming/eepp/eephysics-debug + false + + %{buildDir} + Run /home/programming/eepp/eephysics-debug + eephysics-debug + ProjectExplorer.CustomExecutableRunConfiguration + 3768 + true + false + false + true + true @@ -1274,7 +1361,7 @@ false true - 10 + 11 diff --git a/projects/linux/ee.files b/projects/linux/ee.files index 0f2be081b..a10f3461d 100644 --- a/projects/linux/ee.files +++ b/projects/linux/ee.files @@ -611,3 +611,6 @@ ../../src/examples/sprites/sprites.cpp ../../src/examples/fonts/fonts.cpp ../../src/examples/vbo_fbo_batch/vbo_fbo_batch.cpp +../../src/examples/physics/physics.cpp +../../src/eepp/physics/cshapepoint.cpp +../../include/eepp/physics/cshapepoint.hpp diff --git a/src/eepp/graphics/cconsole.cpp b/src/eepp/graphics/cconsole.cpp index 8499f9559..30b92e49c 100755 --- a/src/eepp/graphics/cconsole.cpp +++ b/src/eepp/graphics/cconsole.cpp @@ -83,10 +83,6 @@ cConsole::cConsole( cFont* Font, const bool& MakeDefaultCommands, const bool& At } cConsole::~cConsole() { - mCallbacks.clear(); - mCmdLog.clear(); - mLastCommands.clear(); - if ( mMyCallback && NULL != cEngine::ExistsSingleton() && cEngine::instance()->ExistsWindow( mWindow ) @@ -128,7 +124,7 @@ void cConsole::Create( cFont* Font, const bool& MakeDefaultCommands, const bool& mWidth = (eeFloat) mWindow->GetWidth(); mHeight = (eeFloat) mWindow->GetHeight(); - mHeightMin = (eeFloat) mWindow->GetHeight() * 0.5f; + mHeightMin = (eeFloat) ( mWindow->GetHeight() / 2 ); if ( NULL != cEngine::ExistsSingleton() && cEngine::instance()->ExistsWindow( mWindow ) ) diff --git a/src/eepp/physics/cshapepoint.cpp b/src/eepp/physics/cshapepoint.cpp new file mode 100644 index 000000000..f5be13d35 --- /dev/null +++ b/src/eepp/physics/cshapepoint.cpp @@ -0,0 +1,70 @@ +#include +#include +#include + +#ifdef PHYSICS_RENDERER_ENABLED +#include +#include +using namespace EE::Graphics; +#endif + +CP_NAMESPACE_BEGIN + +cShapePoint * cShapePoint::New( cBody * body, cpFloat radius, cVect offset ) { + return cpNew( cShapePoint, ( body, radius, offset ) ); +} + +cShapePoint::cShapePoint( cBody * body, cpFloat radius, cVect offset ) +#ifdef PHYSICS_RENDERER_ENABLED + : mDrawRadius( radius ) +#endif +{ + mShape = cpCircleShapeNew( body->Body(), radius, tocpv( offset ) ); + SetData(); +} + +cVect cShapePoint::Offset() { + return tovect( cpCircleShapeGetOffset( mShape ) ); +} + +void cShapePoint::Offset( const cVect &offset ) { + cpCircleShapeSetOffset( mShape, tocpv( offset ) ); +} + +cpFloat cShapePoint::Radius() { + return cpCircleShapeGetRadius( mShape ); +} + +void cShapePoint::Radius( const cpFloat& radius ) { + cpCircleShapeSetRadius( mShape, radius ); +} + +void cShapePoint::Draw( cSpace * space ) { + #ifdef PHYSICS_RENDERER_ENABLED + cBatchRenderer * BR = cGlobalBatchRenderer::instance(); + + BR->SetPointSize( mDrawRadius ); + + BR->SetTexture( NULL ); + BR->PointsBegin(); + BR->PointSetColor( ColorForShape( mShape, space->Space() ) ); + + cpCircleShape * cs = (cpCircleShape*)mShape; + + BR->BatchPoint( cs->CP_PRIVATE(tc).x, cs->CP_PRIVATE(tc).y ); + + BR->DrawOpt(); + #endif +} + +#ifdef PHYSICS_RENDERER_ENABLED +cpFloat cShapePoint::DrawRadius() { + return mDrawRadius; +} + +void cShapePoint::DrawRadius( const cpFloat& radius ) { + mDrawRadius = radius; +} +#endif + +CP_NAMESPACE_END diff --git a/src/examples/empty_window/empty_window.cpp b/src/examples/empty_window/empty_window.cpp index d0c02b18d..f8613641c 100644 --- a/src/examples/empty_window/empty_window.cpp +++ b/src/examples/empty_window/empty_window.cpp @@ -6,11 +6,11 @@ EE_MAIN_FUNC int main (int argc, char * argv []) // Create a new window cWindow * win = cEngine::instance()->CreateWindow( WindowSettings( 960, 640, "eepp - Empty Window" ) ); - // Set window background color - win->BackColor( eeColor( 50, 50, 50 ) ); - // Check if created if ( win->Created() ) { + // Set window background color + win->BackColor( eeColor( 50, 50, 50 ) ); + // Create an instance of the primitive renderer cPrimitives p; diff --git a/src/examples/fonts/fonts.cpp b/src/examples/fonts/fonts.cpp index bdcd828b8..bb948dd80 100644 --- a/src/examples/fonts/fonts.cpp +++ b/src/examples/fonts/fonts.cpp @@ -20,8 +20,8 @@ EE_MAIN_FUNC int main (int argc, char * argv []) cTextureFont * TexF2 = cTextureFont::New( "conchars" ); // Load the TTF font - TTF->Load( AppPath + "assets/fonts/DejaVuSansMono.ttf", 18, TTF_STYLE_NORMAL, false, 128, eeColor(255,255,255), 3, eeColor(0,0,0), true ); - TTF2->Load( AppPath + "assets/fonts/DejaVuSansMono.ttf", 24, TTF_STYLE_NORMAL, false, 128, eeColor(255,255,255), 0, eeColor(0,0,0), true ); + TTF->Load( AppPath + "assets/fonts/DejaVuSansMono.ttf", 18, TTF_STYLE_NORMAL, 128, eeColor(255,255,255), 3, eeColor(0,0,0), true ); + TTF2->Load( AppPath + "assets/fonts/DejaVuSansMono.ttf", 24, TTF_STYLE_NORMAL, 128, eeColor(255,255,255), 0, eeColor(0,0,0), true ); // Save the TTF font so then it can be loaded as a cTextureFont TTF->Save( AppPath + "assets/temp/DejaVuSansMono.png", AppPath + "assets/temp/DejaVuSansMono.fnt" ); @@ -57,6 +57,9 @@ EE_MAIN_FUNC int main (int argc, char * argv []) // The cached text will cTextCache TxtCache( TTF2, Txt, eeColorA(0,0,0,255) ); + // Set the text cache to be centered + TxtCache.Flags( FONT_DRAW_CENTER ); + // Set the font color to a substring of the text // To be able to set the color of the font, create the font as white // Create a gradient @@ -89,7 +92,7 @@ EE_MAIN_FUNC int main (int argc, char * argv []) TexF2->Draw( win->GetWidth() * 0.5f - TexF2->GetTextWidth() * 0.5f, ( YPos += TexF->GetTextHeight() + 24 ) ); // Draw the cached text - TxtCache.Draw( 48, ( YPos += TexF2->GetTextHeight() + 24 ), FONT_DRAW_CENTER ); + TxtCache.Draw( 48, ( YPos += TexF2->GetTextHeight() + 24 ) ); // Text rotated and scaled TTF->Draw( win->GetWidth() * 0.5f - TTF->GetTextWidth() * 0.5f, 512, FONT_DRAW_LEFT, 0.75f, 12.5f ); diff --git a/src/examples/physics/physics.cpp b/src/examples/physics/physics.cpp new file mode 100644 index 000000000..5b1cb4b1f --- /dev/null +++ b/src/examples/physics/physics.cpp @@ -0,0 +1,446 @@ +#include + +typedef cb::Callback0 SceneCb; + +struct physicDemo { + SceneCb init; + SceneCb update; + SceneCb destroy; +}; + +std::vector mDemo; +eeInt mCurDemo = eeINDEX_NOT_FOUND; +cSpace * mSpace; +cBody * mMouseBody; +cVect mMousePoint; +cVect mMousePoint_last; +cConstraint * mMouseJoint; + +#define GRABABLE_MASK_BIT (1<<31) +#define NOT_GRABABLE_MASK (~GRABABLE_MASK_BIT) + +void CreateJointAndBody() { + mMouseJoint = NULL; + mMouseBody = eeNew( cBody, ( INFINITY, INFINITY ) ); +} + +cWindow * mWindow; +cInput * KM; + +void DestroyBody() { + eeSAFE_DELETE( mMouseBody ); +} + +static const int image_width = 188; +static const int image_height = 35; +static const int image_row_length = 24; + +static const char image_bitmap[] = { + 15,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,-64,15,63,-32,-2,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,31,-64,15,127,-125,-1,-128,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,127,-64,15,127,15,-1,-64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,-64,15,-2, + 31,-1,-64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,-64,0,-4,63,-1,-32,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,1,-1,-64,15,-8,127,-1,-32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,-1,-64,0,-8,-15,-1,-32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-31,-1,-64,15,-8,-32, + -1,-32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,-15,-1,-64,9,-15,-32,-1,-32,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,31,-15,-1,-64,0,-15,-32,-1,-32,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,63,-7,-1,-64,9,-29,-32,127,-61,-16,63,15,-61,-1,-8,31,-16,15,-8,126,7,-31, + -8,31,-65,-7,-1,-64,9,-29,-32,0,7,-8,127,-97,-25,-1,-2,63,-8,31,-4,-1,15,-13, + -4,63,-1,-3,-1,-64,9,-29,-32,0,7,-8,127,-97,-25,-1,-2,63,-8,31,-4,-1,15,-13, + -2,63,-1,-3,-1,-64,9,-29,-32,0,7,-8,127,-97,-25,-1,-1,63,-4,63,-4,-1,15,-13, + -2,63,-33,-1,-1,-32,9,-25,-32,0,7,-8,127,-97,-25,-1,-1,63,-4,63,-4,-1,15,-13, + -1,63,-33,-1,-1,-16,9,-25,-32,0,7,-8,127,-97,-25,-1,-1,63,-4,63,-4,-1,15,-13, + -1,63,-49,-1,-1,-8,9,-57,-32,0,7,-8,127,-97,-25,-8,-1,63,-2,127,-4,-1,15,-13, + -1,-65,-49,-1,-1,-4,9,-57,-32,0,7,-8,127,-97,-25,-8,-1,63,-2,127,-4,-1,15,-13, + -1,-65,-57,-1,-1,-2,9,-57,-32,0,7,-8,127,-97,-25,-8,-1,63,-2,127,-4,-1,15,-13, + -1,-1,-57,-1,-1,-1,9,-57,-32,0,7,-1,-1,-97,-25,-8,-1,63,-1,-1,-4,-1,15,-13,-1, + -1,-61,-1,-1,-1,-119,-57,-32,0,7,-1,-1,-97,-25,-8,-1,63,-1,-1,-4,-1,15,-13,-1, + -1,-61,-1,-1,-1,-55,-49,-32,0,7,-1,-1,-97,-25,-8,-1,63,-1,-1,-4,-1,15,-13,-1, + -1,-63,-1,-1,-1,-23,-49,-32,127,-57,-1,-1,-97,-25,-1,-1,63,-1,-1,-4,-1,15,-13, + -1,-1,-63,-1,-1,-1,-16,-49,-32,-1,-25,-1,-1,-97,-25,-1,-1,63,-33,-5,-4,-1,15, + -13,-1,-1,-64,-1,-9,-1,-7,-49,-32,-1,-25,-8,127,-97,-25,-1,-1,63,-33,-5,-4,-1, + 15,-13,-1,-1,-64,-1,-13,-1,-32,-49,-32,-1,-25,-8,127,-97,-25,-1,-2,63,-49,-13, + -4,-1,15,-13,-1,-1,-64,127,-7,-1,-119,-17,-15,-1,-25,-8,127,-97,-25,-1,-2,63, + -49,-13,-4,-1,15,-13,-3,-1,-64,127,-8,-2,15,-17,-1,-1,-25,-8,127,-97,-25,-1, + -8,63,-49,-13,-4,-1,15,-13,-3,-1,-64,63,-4,120,0,-17,-1,-1,-25,-8,127,-97,-25, + -8,0,63,-57,-29,-4,-1,15,-13,-4,-1,-64,63,-4,0,15,-17,-1,-1,-25,-8,127,-97, + -25,-8,0,63,-57,-29,-4,-1,-1,-13,-4,-1,-64,31,-2,0,0,103,-1,-1,-57,-8,127,-97, + -25,-8,0,63,-57,-29,-4,-1,-1,-13,-4,127,-64,31,-2,0,15,103,-1,-1,-57,-8,127, + -97,-25,-8,0,63,-61,-61,-4,127,-1,-29,-4,127,-64,15,-8,0,0,55,-1,-1,-121,-8, + 127,-97,-25,-8,0,63,-61,-61,-4,127,-1,-29,-4,63,-64,15,-32,0,0,23,-1,-2,3,-16, + 63,15,-61,-16,0,31,-127,-127,-8,31,-1,-127,-8,31,-128,7,-128,0,0 +}; + +int get_pixel(int x, int y) { + return (image_bitmap[(x>>3) + y*image_row_length]>>(~x&0x7)) & 1; +} + +cShape * make_ball( cpFloat x, cpFloat y ) { + cBody * body = cBody::New( 1.0, INFINITY ); + + body->Pos( cVectNew( x, y ) ); + + cShapePoint * shape = cShapePoint::New( body, 0.95, cVectZero ); + + shape->DrawRadius( 4 ); + shape->Elasticity( 0.0 ); + shape->Friction( 0.0 ); + + return shape; +} + +static int bodyCount = 0; + +void Demo1Create() { + CreateJointAndBody(); + + mSpace = Physics::cSpace::New(); + mSpace->Iterations( 1 ); + + // The space will contain a very large number of similary sized objects. + // This is the perfect candidate for using the spatial hash. + // Generally you will never need to do this. + mSpace->UseSpatialHash( 2.0, 10000 ); + + bodyCount = 0; + + cBody * body; + cShape * shape; + + eeFloat pX = mWindow->GetWidth() / 2 - ( image_width * 4 ) / 2; + eeFloat pY = mWindow->GetHeight() / 2 - ( image_height * 4 ) / 2; + + for(int y=0; yAddBody( shape->Body() ); + mSpace->AddShape( shape ); + + bodyCount++; + } + } + + body = mSpace->AddBody( cBody::New( INFINITY, INFINITY ) ); + body->Pos( cVectNew( 0, mWindow->GetHeight() / 2 + 16 ) ); + body->Vel( cVectNew( 400, 0 ) ); + + shape = mSpace->AddShape( cShapeCircle::New( body, 8.0f, cVectZero ) ); + shape->Elasticity( 0.0 ); + shape->Friction( 0.0 ); + shape->Layers( NOT_GRABABLE_MASK ); + + bodyCount++; +} + +void Demo1Update(){ +} + +void Demo1Destroy() { + DestroyBody(); + eeSAFE_DELETE( mSpace ); +} + +void Demo2Create() { + CreateJointAndBody(); + + cShape::ResetShapeIdCounter(); + + mSpace = Physics::cSpace::New(); + mSpace->Gravity( cVectNew( 0, 100 ) ); + mSpace->SleepTimeThreshold( 0.5f ); + + cBody *body, *staticBody = mSpace->StaticBody(); + cShape * shape; + + shape = mSpace->AddShape( cShapeSegment::New( staticBody, cVectNew( 0, mWindow->GetHeight() ), cVectNew( mWindow->GetWidth(), mWindow->GetHeight() ), 0.0f ) ); + shape->e( 1.0f ); + shape->u( 1.0f ); + shape->Layers( NOT_GRABABLE_MASK ); + + shape = mSpace->AddShape( cShapeSegment::New( staticBody, cVectNew( mWindow->GetWidth(), 0 ), cVectNew( mWindow->GetWidth(), mWindow->GetHeight() ), 0.0f ) ); + shape->e( 1.0f ); + shape->u( 1.0f ); + shape->Layers( NOT_GRABABLE_MASK ); + + shape = mSpace->AddShape( cShapeSegment::New( staticBody, cVectNew( 0, 0 ), cVectNew( 0, mWindow->GetHeight() ), 0.0f ) ); + shape->e( 1.0f ); + shape->u( 1.0f ); + shape->Layers( NOT_GRABABLE_MASK ); + + shape = mSpace->AddShape( cShapeSegment::New( staticBody, cVectNew( 0, 0 ), cVectNew( mWindow->GetWidth(), 0 ), 0.0f ) ); + shape->e( 1.0f ); + shape->u( 1.0f ); + shape->Layers( NOT_GRABABLE_MASK ); + + eeFloat hw = mWindow->GetWidth() / 2; + + for(int i=0; i<14; i++){ + for(int j=0; j<=i; j++){ + body = mSpace->AddBody( cBody::New( 1.0f, Moment::ForBox( 1.0f, 30.0f, 30.0f ) ) ); + body->Pos( cVectNew( hw + j * 32 - i * 16, 100 + i * 32 ) ); + + shape = mSpace->AddShape( cShapePoly::New( body, 30.f, 30.f ) ); + shape->e( 0.0f ); + shape->u( 0.8f ); + } + } + + cpFloat radius = 15.0f; + + body = mSpace->AddBody( cBody::New( 10.0f, Moment::ForCircle( 10.0f, 0.0f, radius, cVectZero ) ) ); + body->Pos( cVectNew( hw, mWindow->GetHeight() - radius - 5 ) ); + + //shape = mSpace->AddShape( cShapeCircleSprite::New( body, radius, cVectZero, mCircleSprite ) ); + shape = mSpace->AddShape( cShapeCircle::New( body, radius, cVectZero ) ); + shape->e( 0.0f ); + shape->u( 0.9f ); +} + +void Demo2Update() { +} + +void Demo2Destroy() { + DestroyBody(); + eeSAFE_DELETE( mSpace ); +} + +enum CollisionTypes { + BALL_TYPE, + BLOCKING_SENSOR_TYPE, + CATCH_SENSOR_TYPE +}; + +struct Emitter { + int queue; + int blocked; + cVect position; +}; +Emitter emitterInstance; + +cpBool blockerBegin( cArbiter *arb, cSpace *space, void *unused ) { + cShape * a, * b; + arb->GetShapes( &a, &b ); + + Emitter *emitter = (Emitter *) a->Data(); + + emitter->blocked++; + + return cpFalse; // Return values from sensors callbacks are ignored, +} + +void blockerSeparate( cArbiter *arb, cSpace * space, void *unused ) { + cShape * a, * b; + arb->GetShapes( &a, &b ); + + Emitter *emitter = (Emitter *) a->Data(); + + emitter->blocked--; +} + +void postStepRemove( cSpace *space, void * tshape, void * unused ) { + cShape * shape = reinterpret_cast( tshape ); + + if ( NULL != mMouseJoint && ( mMouseJoint->A() == shape->Body() || mMouseJoint->B() == shape->Body() ) ) { + mSpace->RemoveConstraint( mMouseJoint ); + eeSAFE_DELETE( mMouseJoint ); + } + + mSpace->RemoveBody( shape->Body() ); + mSpace->RemoveShape( shape ); + + cShape::Free( shape, true ); +} + +cpBool catcherBarBegin(cArbiter *arb, Physics::cSpace *space, void *unused) { + cShape * a, * b; + arb->GetShapes( &a, &b ); + + Emitter *emitter = (Emitter *) a->Data(); + + emitter->queue++; + + mSpace->AddPostStepCallback( cb::Make3( &postStepRemove ), b, NULL ); + + return cpFalse; +} + +void Demo3Create() { + CreateJointAndBody(); + + cShape::ResetShapeIdCounter(); + + mSpace = Physics::cSpace::New(); + mSpace->Iterations( 10 ); + mSpace->Gravity( cVectNew( 0, 100 ) ); + + cBody * staticBody = mSpace->StaticBody(); + cShape * shape; + + emitterInstance.queue = 5; + emitterInstance.blocked = 0; + emitterInstance.position = cVectNew( mWindow->GetWidth() / 2 , 150); + + shape = mSpace->AddShape( cShapeCircle::New( staticBody, 15.0f, emitterInstance.position ) ); + shape->Sensor( 1 ); + shape->CollisionType( BLOCKING_SENSOR_TYPE ); + shape->Data( &emitterInstance ); + + // Create our catch sensor to requeue the balls when they reach the bottom of the screen + shape = mSpace->AddShape( cShapeSegment::New( staticBody, cVectNew(-4000, 600), cVectNew(4000, 600), 15.0f ) ); + shape->Sensor( 1 ); + shape->CollisionType( CATCH_SENSOR_TYPE ); + shape->Data( &emitterInstance ); + + cSpace::cCollisionHandler handler; + handler.a = BLOCKING_SENSOR_TYPE; + handler.b = BALL_TYPE; + handler.begin = cb::Make3( &blockerBegin ); + handler.separate = cb::Make3( &blockerSeparate ); + mSpace->AddCollisionHandler( handler ); + + handler.Reset(); // Reset all the values and the callbacks ( set the callbacks as !IsSet() + + handler.a = CATCH_SENSOR_TYPE; + handler.b = BALL_TYPE; + handler.begin = cb::Make3( &catcherBarBegin ); + mSpace->AddCollisionHandler( handler ); +} + +void Demo3Update() { + if( !emitterInstance.blocked && emitterInstance.queue ){ + emitterInstance.queue--; + + cBody * body = mSpace->AddBody( cBody::New( 1.0f, Moment::ForCircle(1.0f, 15.0f, 0.0f, cVectZero ) ) ); + body->Pos( emitterInstance.position ); + body->Vel( cVectNew( Math::Randf(-1,1), Math::Randf(-1,1) ) * (cpFloat)100 ); + + cShape *shape = mSpace->AddShape( cShapeCircle::New( body, 15.0f, cVectZero ) ); + shape->CollisionType( BALL_TYPE ); + } +} + +void Demo3Destroy() { + DestroyBody(); + eeSAFE_DELETE( mSpace ); +} + +void ChangeDemo( eeInt num ) { + if ( num >= 0 && num < (eeInt)mDemo.size() && num != mCurDemo ) { + if ( (eeInt)eeINDEX_NOT_FOUND != mCurDemo ) + mDemo[ mCurDemo ].destroy(); + + mCurDemo = num; + + mDemo[ mCurDemo ].init(); + } +} + +void PhysicsCreate() { + cPhysicsManager::CreateSingleton(); + cPhysicsManager * PM = cPhysicsManager::instance(); + cPhysicsManager::cDrawSpaceOptions * DSO = PM->GetDrawOptions(); + + DSO->DrawBBs = false; + DSO->DrawShapes = true; + DSO->DrawShapesBorders = true; + DSO->CollisionPointSize = 4; + DSO->BodyPointSize = 0; + DSO->LineThickness = 1; + + mDemo.clear(); + + physicDemo demo; + + demo.init = cb::Make0( &Demo1Create ); + demo.update = cb::Make0( &Demo1Update ); + demo.destroy = cb::Make0( &Demo1Destroy ); + mDemo.push_back( demo ); + + demo.init = cb::Make0( &Demo2Create ); + demo.update = cb::Make0( &Demo2Update ); + demo.destroy = cb::Make0( &Demo2Destroy ); + mDemo.push_back( demo ); + + demo.init = cb::Make0( &Demo3Create ); + demo.update = cb::Make0( &Demo3Update ); + demo.destroy = cb::Make0( &Demo3Destroy ); + mDemo.push_back( demo ); + + ChangeDemo( 0 ); +} + +void PhysicsUpdate() { + mMousePoint = cVectNew( KM->GetMousePosf().x, KM->GetMousePosf().y ); + cVect newPoint = tovect( cpvlerp( tocpv( mMousePoint_last ), tocpv( mMousePoint ), 0.25 ) ); + mMouseBody->Pos( newPoint ); + mMouseBody->Vel( ( newPoint - mMousePoint_last ) * (cpFloat)mWindow->FPS() ); + mMousePoint_last = newPoint; + + if ( KM->MouseLeftPressed() ) { + if ( NULL == mMouseJoint ) { + cVect point = cVectNew( KM->GetMousePosf().x, KM->GetMousePosf().y ); + + cShape * shape = mSpace->PointQueryFirst( point, GRABABLE_MASK_BIT, CP_NO_GROUP ); + + if( NULL != shape ){ + mMouseJoint = eeNew( cPivotJoint, ( mMouseBody, shape->Body(), cVectZero, shape->Body()->World2Local( point ) ) ); + + mMouseJoint->MaxForce( 50000.0f ); + mSpace->AddConstraint( mMouseJoint ); + } + } + } else if ( NULL != mMouseJoint ) { + mSpace->RemoveConstraint( mMouseJoint ); + eeSAFE_DELETE( mMouseJoint ); + } + + mDemo[ mCurDemo ].update(); + mSpace->Update(); + mSpace->Draw(); +} + +void PhysicsDestroy() { + mDemo[ mCurDemo ].destroy(); +} + +EE_MAIN_FUNC int main (int argc, char * argv []) +{ + mWindow = cEngine::instance()->CreateWindow( WindowSettings( 1024, 768, "eepp - Physics" ), ContextSettings( true ) ); + + if ( mWindow->Created() ) { + KM = mWindow->GetInput(); + + mWindow->BackColor( eeColor( 255, 255, 255 ) ); + + PhysicsCreate(); + + while ( mWindow->Running() ) { + KM->Update(); + + if ( KM->IsKeyDown( KEY_ESCAPE ) ) { + mWindow->Close(); + } + + PhysicsUpdate(); + + if ( KM->IsKeyUp( KEY_LEFT ) ) { + ChangeDemo( mCurDemo - 1 ); + } else if ( KM->IsKeyUp( KEY_RIGHT ) ) { + ChangeDemo( mCurDemo + 1 ); + } + + mWindow->Display(); + } + + PhysicsDestroy(); + } + + cEngine::DestroySingleton(); + + EE::MemoryManager::ShowResults(); + + return EXIT_SUCCESS; +}