diff --git a/example-TwoWorlds/src/testApp.cpp b/example-TwoWorlds/src/testApp.cpp index 217547c..a444ef1 100644 --- a/example-TwoWorlds/src/testApp.cpp +++ b/example-TwoWorlds/src/testApp.cpp @@ -87,9 +87,9 @@ void testApp::drawGravity(ofPoint p, ofPoint gravity) { ofPushMatrix(); ofTranslate(p.x, p.y); ofRotate(angle); - ofLine(0, 0, 0, len); - ofTriangle(0, len, - -5, len-10, + ofDrawLine(0, 0, 0, len); + ofDrawTriangle(0, len, + -5, len-10, 5, len-10); ofPopMatrix(); } diff --git a/libs/Box2D/Collision/Shapes/b2PolygonShape.cpp b/libs/Box2D/Collision/Shapes/b2PolygonShape.cpp index 2ef6529..5e94e51 100644 --- a/libs/Box2D/Collision/Shapes/b2PolygonShape.cpp +++ b/libs/Box2D/Collision/Shapes/b2PolygonShape.cpp @@ -138,7 +138,7 @@ void b2PolygonShape::Set(const b2Vec2* vertices, int32 count) bool unique = true; for (int32 j = 0; j < tempCount; ++j) { - if (b2DistanceSquared(v, ps[j]) < 0.5f * b2_linearSlop) + if (b2DistanceSquared(v, ps[j]) < ((0.5f * b2_linearSlop) * (0.5f * b2_linearSlop))) { unique = false; break; diff --git a/libs/Box2D/Common/b2Math.h b/libs/Box2D/Common/b2Math.h index 70e1fbf..a9b0813 100644 --- a/libs/Box2D/Common/b2Math.h +++ b/libs/Box2D/Common/b2Math.h @@ -20,26 +20,28 @@ #define B2_MATH_H #include -#include -#include +#include /// This function is used to ensure that a floating point number is not a NaN or infinity. inline bool b2IsValid(float32 x) { - int32 ix = 0; - memcpy(&ix, &x, sizeof(x)); + int32 ix = *reinterpret_cast(&x); return (ix & 0x7f800000) != 0x7f800000; } /// This is a approximate yet fast inverse square-root. inline float32 b2InvSqrt(float32 x) { - int32 ix = 0; - memcpy(&ix, &x, sizeof(x)); - + union + { + float32 x; + int32 i; + } convert; + + convert.x = x; float32 xhalf = 0.5f * x; - ix = 0x5f3759df - (ix >> 1); - memcpy(&x, &ix, sizeof(x)); + convert.i = 0x5f3759df - (convert.i >> 1); + x = convert.x; x = x * (1.5f - xhalf * x * x); return x; } diff --git a/src/ofxBox2d.cpp b/src/ofxBox2d.cpp index 3ced805..6c0af95 100644 --- a/src/ofxBox2d.cpp +++ b/src/ofxBox2d.cpp @@ -2,17 +2,17 @@ // ------------------------------------------------------ ofxBox2d::ofxBox2d() { - enableContactEvents = false; + enableContactEvents = false; world = NULL; m_bomb = NULL; #ifdef TARGET_OPENGLES - // touch grabbing - for( int i=0; iDestroyBody(touchBodies[i]); - } - } + // destroy touch grabbing bodies + for(int i=0; iDestroyBody(touchBodies[i]); + } + } #else - // destroy mouse grabbing body - if(mouseBody) { + // destroy mouse grabbing body + if(mouseBody) { if(world) world->DestroyBody(mouseBody); } #endif - if(world) { - // Fix from: https://github.com/vanderlin/ofxBox2d/issues/62 - b2Body* f = world->GetBodyList(); - while (f) { - b2Body* next = f->GetNext(); - world->DestroyBody(f); - f = next; - } - b2Joint* j = world->GetJointList(); - while (j) { - b2Joint* next = j->GetNext(); - world->DestroyJoint(j); - j = next; - } - /* - // This is not safe... - delete world; - world = NULL;*/ - } + if(world) { + // Fix from: https://github.com/vanderlin/ofxBox2d/issues/62 + b2Body* f = world->GetBodyList(); + while (f) { + b2Body* next = f->GetNext(); + world->DestroyBody(f); + f = next; + } + b2Joint* j = world->GetJointList(); + while (j) { + b2Joint* next = j->GetNext(); + world->DestroyJoint(j); + j = next; + } + /* + // This is not safe... + delete world; + world = NULL;*/ + } } // ------------------------------------------------------ init void ofxBox2d::init() { - + // settings - bHasContactListener = false; - bCheckBounds = false; - bEnableGrabbing = true; - scale = OFX_BOX2D_SCALE; - doSleep = true; - + bHasContactListener = false; + bCheckBounds = false; + bEnableGrabbing = true; + bEnablePicking = true; + scale = OFX_BOX2D_SCALE; + doSleep = true; + // gravity gravity.set(0, 5.0f); setFPS(30.0); velocityIterations = 40; positionIterations = 20; - -#ifdef TARGET_OPENGLES - // touch grabbing - for( int i=0; iSetAllowSleeping(doSleep); + world->SetAllowSleeping(doSleep); //world->SetDebugDraw(&debugRender); - - + if(ground!=NULL) { - world->DestroyBody(ground); - ground = NULL; - } + world->DestroyBody(ground); + ground = NULL; + } ofLog(OF_LOG_NOTICE, "ofxBox2d:: - world created -"); - + } // ------------------------------------------------------ enable events void ofxBox2d::enableEvents() { - if(world!=NULL) { - world->SetContactListener(this); - } + if (world!=NULL) { + world->SetContactListener(this); + } } // ------------------------------------------------------ disable events void ofxBox2d::disableEvents() { - if(world!=NULL) { - world->SetContactListener(NULL); - } + if (world!=NULL) { + world->SetContactListener(NULL); + } } // ------------------------------------------------------ grab shapes void ofxBox2d::setContactListener(ofxBox2dContactListener * listener) { - if(world != NULL) { bHasContactListener = true; world->SetContactListener(listener); @@ -170,127 +169,132 @@ void ofxBox2d::mouseReleased(ofMouseEventArgs &e) { // ------------------------------------------------------ void ofxBox2d::grabShapeDown(float x, float y, int id) { - + if(world == NULL) { ofLog(OF_LOG_WARNING, "ofxBox2d:: - Need a world, call init first! -"); return; } - - if(bEnableGrabbing) { - b2Vec2 p(x/OFX_BOX2D_SCALE, y/OFX_BOX2D_SCALE); - -#ifdef TARGET_OPENGLES - if(id >= 0 && id < OF_MAX_TOUCH_JOINTS) - { - if(touchJoints[id] != NULL) - return; - - if( touchBodies[id] == NULL) { - b2BodyDef bd; - touchBodies[id] = world->CreateBody(&bd); - } - } - else - return; // invalid mouse / touch id. + + if(bEnableGrabbing || bEnablePicking) { + b2Vec2 p(x/OFX_BOX2D_SCALE, y/OFX_BOX2D_SCALE); + +#ifdef TARGET_OPENGLES + if(id >= 0 && id < OF_MAX_TOUCH_JOINTS) + { + if(touchJoints[id] != NULL) + return; + + if( touchBodies[id] == NULL) { + b2BodyDef bd; + touchBodies[id] = world->CreateBody(&bd); + } + } + else + return; // invalid mouse / touch id. #else - if (mouseJoint != NULL) { - return; - } - - if(mouseBody == NULL) { - b2BodyDef bd; - mouseBody = world->CreateBody(&bd); - } - + if (mouseJoint != NULL) { + return; + } + + if(mouseBody == NULL) { + b2BodyDef bd; + mouseBody = world->CreateBody(&bd); + } + #endif - // Make a small box. b2AABB aabb; b2Vec2 d; d.Set(0.001f, 0.001f); aabb.lowerBound = p - d; aabb.upperBound = p + d; - + // Query the world for overlapping shapes. QueryCallback callback(p); world->QueryAABB(&callback, aabb); - + if (callback.m_fixture) { + + //!!! + if (bEnablePicking) { + static ofxBox2dContactArgs ev_args; + ev_args.a = callback.m_fixture; + ev_args.b = NULL; + ofNotifyEvent(mousePickEvent, ev_args); + } + //!!! + b2Body* body = callback.m_fixture->GetBody(); - b2MouseJointDef md; + b2MouseJointDef md; md.bodyB = body; md.target = p; md.maxForce = 1000.0f * body->GetMass(); #ifdef TARGET_OPENGLES - md.bodyA = touchBodies[id]; - touchJoints[id] = (b2MouseJoint*)world->CreateJoint(&md); + md.bodyA = touchBodies[id]; + touchJoints[id] = (b2MouseJoint*)world->CreateJoint(&md); #else - md.bodyA = mouseBody; - mouseJoint = (b2MouseJoint*)world->CreateJoint(&md); -#endif - + md.bodyA = mouseBody; + mouseJoint = (b2MouseJoint*)world->CreateJoint(&md); +#endif + body->SetAwake(true); } - - + + } - + } -// ------------------------------------------------------ +// ------------------------------------------------------ void ofxBox2d::grabShapeUp(float x, float y, int id) { -#ifdef TARGET_OPENGLES - if(id >= 0 && id < OF_MAX_TOUCH_JOINTS) { - if(touchJoints[id] && bEnableGrabbing){ - if(world == NULL) { - ofLog(OF_LOG_WARNING, "ofxBox2d:: - Need a world, call init first! -"); - return; - } - world->DestroyJoint(touchJoints[id]); - touchJoints[id] = NULL; - } - } -#else - if(mouseJoint && bEnableGrabbing) { +#ifdef TARGET_OPENGLES + if(id >= 0 && id < OF_MAX_TOUCH_JOINTS) { + if(touchJoints[id] && bEnableGrabbing){ if(world == NULL) { ofLog(OF_LOG_WARNING, "ofxBox2d:: - Need a world, call init first! -"); return; } - world->DestroyJoint(mouseJoint); - mouseJoint = NULL; - } -#endif - - + world->DestroyJoint(touchJoints[id]); + touchJoints[id] = NULL; + } + } +#else + if(mouseJoint && (bEnableGrabbing || bEnablePicking)) { + if(world == NULL) { + ofLog(OF_LOG_WARNING, "ofxBox2d:: - Need a world, call init first! -"); + return; + } + world->DestroyJoint(mouseJoint); + mouseJoint = NULL; + } +#endif } -// ------------------------------------------------------ +// ------------------------------------------------------ void ofxBox2d::grabShapeDragged(float x, float y, int id) { b2Vec2 p(x/OFX_BOX2D_SCALE, y/OFX_BOX2D_SCALE); -#ifdef TARGET_OPENGLES - if(id >= 0 && id < OF_MAX_TOUCH_JOINTS) { - if (touchJoints[id] && bEnableGrabbing) - touchJoints[id]->SetTarget(p); - } -#else - if (mouseJoint && bEnableGrabbing) - mouseJoint->SetTarget(p); +#ifdef TARGET_OPENGLES + if(id >= 0 && id < OF_MAX_TOUCH_JOINTS) { + if (touchJoints[id] && bEnableGrabbing) + touchJoints[id]->SetTarget(p); + } +#else + if (mouseJoint && bEnableGrabbing) + mouseJoint->SetTarget(p); #endif - - } -// ------------------------------------------------------ -int ofxBox2d::getBodyCount() { +// ------------------------------------------------------ +int ofxBox2d::getBodyCount() { if(world) return world->GetBodyCount(); return 0; } // ------------------------------------------------------ -int ofxBox2d::getJointCount() { +int ofxBox2d::getJointCount() { if(world) return world->GetJointCount(); return 0; @@ -298,25 +302,24 @@ int ofxBox2d::getJointCount() { // ------------------------------------------------------ wake up void ofxBox2d::wakeupShapes() { - if(world == NULL) { + if(world == NULL) { ofLog(OF_LOG_WARNING, "ofxBox2d:: - Need a world, call init first! -"); return; } - - b2Body* bodies = world->GetBodyList(); - while(bodies) { - b2Body* b = bodies; - if(b) { - if( !b->IsAwake() ) b->SetAwake(true); - } - bodies = bodies->GetNext(); - } - + + b2Body* bodies = world->GetBodyList(); + while(bodies) { + b2Body* b = bodies; + if(b) { + if( !b->IsAwake() ) b->SetAwake(true); + } + bodies = bodies->GetNext(); + } } // ------------------------------------------------------ set gravity void ofxBox2d::setGravity(ofPoint pt) { - setGravity(pt.x, pt.y); + setGravity(pt.x, pt.y); } void ofxBox2d::setGravity(float x, float y) { if(world == NULL) { @@ -324,14 +327,14 @@ void ofxBox2d::setGravity(float x, float y) { return; } world->SetGravity(b2Vec2(x, y)); - wakeupShapes(); + wakeupShapes(); } ofPoint ofxBox2d::getGravity() { if(world == NULL) { ofLog(OF_LOG_WARNING, "ofxBox2d:: - Need a world, call init first! -"); return ofPoint(); } - return ofPoint(world->GetGravity().x, world->GetGravity().y); + return ofPoint(world->GetGravity().x, world->GetGravity().y); } @@ -342,19 +345,19 @@ void ofxBox2d::setBounds(ofPoint lowBounds, ofPoint upBounds) { // ------------------------------------------------------ create Ground void ofxBox2d::createGround(float x1, float y1, float x2, float y2) { - + if(world == NULL) { ofLog(OF_LOG_WARNING, "ofxBox2d:: - Need a world, call init first! -"); return; } - - if(ground!=NULL) world->DestroyBody(ground); - + + if(ground!=NULL) world->DestroyBody(ground); + b2BodyDef bd; ground = world->CreateBody(&bd); b2EdgeShape shape; - shape.Set(b2Vec2(x1/OFX_BOX2D_SCALE, y1/OFX_BOX2D_SCALE), b2Vec2(x2/OFX_BOX2D_SCALE, y2/OFX_BOX2D_SCALE)); + shape.Set(b2Vec2(x1/OFX_BOX2D_SCALE, y1/OFX_BOX2D_SCALE), b2Vec2(x2/OFX_BOX2D_SCALE, y2/OFX_BOX2D_SCALE)); ground->CreateFixture(&shape, 0.0f); } @@ -370,38 +373,38 @@ void ofxBox2d::createBounds(ofRectangle rec) { // ------------------------------------------------------ create bounds void ofxBox2d::createBounds(float x, float y, float w, float h) { - + if(world == NULL) { ofLog(OF_LOG_WARNING, "ofxBox2d:: - Need a world, call init first! -"); return; } if(ground!=NULL) world->DestroyBody(ground); - + b2BodyDef bd; bd.position.Set(0, 0); - ground = world->CreateBody(&bd); - + ground = world->CreateBody(&bd); + b2EdgeShape shape; - + ofRectangle rec(x/OFX_BOX2D_SCALE, y/OFX_BOX2D_SCALE, w/OFX_BOX2D_SCALE, h/OFX_BOX2D_SCALE); - - + + //right wall shape.Set(b2Vec2(rec.x+rec.width, rec.y), b2Vec2(rec.x+rec.width, rec.y+rec.height)); ground->CreateFixture(&shape, 0.0f); - + //left wall shape.Set(b2Vec2(rec.x, rec.y), b2Vec2(rec.x, rec.y+rec.height)); ground->CreateFixture(&shape, 0.0f); - + // top wall shape.Set(b2Vec2(rec.x, rec.y), b2Vec2(rec.x+rec.width, rec.y)); ground->CreateFixture(&shape, 0.0f); - + // bottom wall shape.Set(b2Vec2(rec.x, rec.y+rec.height), b2Vec2(rec.x+rec.width, rec.y+rec.height)); ground->CreateFixture(&shape, 0.0f); - + } // ------------------------------------------------------ check if shapes are out of bounds @@ -422,70 +425,69 @@ void ofxBox2d::update() { ofLog(OF_LOG_WARNING, "ofxBox2d:: - Need a world, call init first! -"); return; } - + // destroy the object if we are out of the bounds if(bCheckBounds) { /* - float top = 0; - float bottom = ofGetHeight(); - float right = ofGetWidth(); - float left = 0; - - b2Body* node = world->GetBodyList(); - while(node) { - b2Body* b = node; - node = node->GetNext(); - b2Vec2 p = b->GetPosition(); - ofxBox2dBaseShape* base = (ofxBox2dBaseShape*)b->GetUserData(); - if(base) { - //printf("dead:%i\n", base->dead); - - if(p.y*OFX_BOX2D_SCALE > bottom) { - base->dead = true; - world->DestroyBody(b); - } - if(p.y*OFX_BOX2D_SCALE < top) { - base->dead = true; - world->DestroyBody(b); - } - if(p.x*OFX_BOX2D_SCALE > right) { - base->dead = true; - world->DestroyBody(b); - } - if(p.x*OFX_BOX2D_SCALE < left) { - base->dead = true; - world->DestroyBody(b); - } - */ + float top = 0; + float bottom = ofGetHeight(); + float right = ofGetWidth(); + float left = 0; + + b2Body* node = world->GetBodyList(); + while(node) { + b2Body* b = node; + node = node->GetNext(); + b2Vec2 p = b->GetPosition(); + ofxBox2dBaseShape* base = (ofxBox2dBaseShape*)b->GetUserData(); + if(base) { + //printf("dead:%i\n", base->dead); + + if(p.y*OFX_BOX2D_SCALE > bottom) { + base->dead = true; + world->DestroyBody(b); + } + if(p.y*OFX_BOX2D_SCALE < top) { + base->dead = true; + world->DestroyBody(b); + } + if(p.x*OFX_BOX2D_SCALE > right) { + base->dead = true; + world->DestroyBody(b); + } + if(p.x*OFX_BOX2D_SCALE < left) { + base->dead = true; + world->DestroyBody(b); + } + */ } - float timeStep = (1.0f / fps); + float timeStep = (1.0f / fps); world->Step(timeStep, velocityIterations, positionIterations); - //world->Validate(); - + //world->Validate(); + } -// ------------------------------------------------------ +// ------------------------------------------------------ void ofxBox2d::drawGround() { - + if(ground == NULL) return; - -// const b2Transform& xf = ground->GetTransform(); + +// const b2Transform& xf = ground->GetTransform(); for (b2Fixture* f = ground->GetFixtureList(); f; f = f->GetNext()) { b2EdgeShape* edge = (b2EdgeShape*)f->GetShape(); if(edge) { - + ofNoFill(); ofSetColor(120, 0, 120); - ofLine(worldPtToscreenPt(edge->m_vertex0), worldPtToscreenPt(edge->m_vertex1)); + ofDrawLine(worldPtToscreenPt(edge->m_vertex0), worldPtToscreenPt(edge->m_vertex1)); } } } -// ------------------------------------------------------ +// ------------------------------------------------------ void ofxBox2d::draw() { drawGround(); } - diff --git a/src/ofxBox2d.h b/src/ofxBox2d.h index 911c5b9..99c6fae 100644 --- a/src/ofxBox2d.h +++ b/src/ofxBox2d.h @@ -10,125 +10,129 @@ #include "ofxBox2dRect.h" #include "ofxBox2dJoint.h" +#include "ofxBox2dRevoluteJoint.h" #include "ofxBox2dRender.h" #include "ofxBox2dContactListener.h" #ifdef TARGET_OPENGLES -#define OF_MAX_TOUCH_JOINTS 5 // max number of touch points on iPhone + iPad (this may change in the future though). +#define OF_MAX_TOUCH_JOINTS 5 // max number of touch points on iPhone + iPad (this may change in the future though). #endif class ofxBox2dContactArgs : public ofEventArgs { public: - + b2Fixture * a; b2Fixture * b; }; class ofxBox2d : public b2ContactListener { - + private: - - bool enableContactEvents; - float fps; - int velocityIterations; - int positionIterations; - + + bool enableContactEvents; + float fps; + int velocityIterations; + int positionIterations; + // Called when two fixtures begin to touch. - void BeginContact(b2Contact* contact) { + void BeginContact(b2Contact* contact) { static ofxBox2dContactArgs args; args.a = contact->GetFixtureA(); args.b = contact->GetFixtureB(); ofNotifyEvent( contactStartEvents, args, this); } - + // Called when two fixtures cease to touch. - void EndContact(b2Contact* contact) { + void EndContact(b2Contact* contact) { static ofxBox2dContactArgs args; args.a = contact->GetFixtureA(); args.b = contact->GetFixtureB(); ofNotifyEvent( contactEndEvents, args, this); } - - ofPoint gravity; + + ofPoint gravity; public: - - // b2AABB worldAABB; - b2World * world; - ofxBox2dRender debugRender; - - float scale; - bool doSleep; - bool bEnableGrabbing; - bool bCheckBounds; - bool bHasContactListener; - - b2BodyDef bd; - - b2Body* m_bomb; -#ifdef TARGET_OPENGLES - b2MouseJoint* touchJoints[ OF_MAX_TOUCH_JOINTS ]; - b2Body* touchBodies[ OF_MAX_TOUCH_JOINTS ]; + + // b2AABB worldAABB; + b2World * world; + ofxBox2dRender debugRender; + + float scale; + bool doSleep; + bool bEnableGrabbing; + bool bEnablePicking; + bool bCheckBounds; + bool bHasContactListener; + + b2BodyDef bd; + + b2Body* m_bomb; +#ifdef TARGET_OPENGLES + b2MouseJoint* touchJoints[ OF_MAX_TOUCH_JOINTS ]; + b2Body* touchBodies[ OF_MAX_TOUCH_JOINTS ]; #else - b2MouseJoint* mouseJoint; - b2Body* mouseBody; -#endif - b2Body* ground; - b2Body* mainBody; + b2MouseJoint* mouseJoint; + b2Body* mouseBody; +#endif + b2Body* ground; + b2Body* mainBody; // ------------------------------------------------------ - void enableEvents(); - void disableEvents(); + void enableEvents(); + void disableEvents(); + ofEvent mousePickEvent; ofEvent contactStartEvents; ofEvent contactEndEvents; - + // ------------------------------------------------------ ofxBox2d(); ~ofxBox2d(); - - void init(); - void setFPS(float theFps) { fps = theFps; } - + + void init(); + void setFPS(float theFps) { fps = theFps; } + float getFPS() { return fps; } + #ifdef TARGET_OPENGLES - void touchDown(ofTouchEventArgs &touch); - void touchMoved(ofTouchEventArgs &touch); - void touchUp(ofTouchEventArgs &touch); + void touchDown(ofTouchEventArgs &touch); + void touchMoved(ofTouchEventArgs &touch); + void touchUp(ofTouchEventArgs &touch); #else - void mousePressed(ofMouseEventArgs &e); - void mouseDragged(ofMouseEventArgs &e); - void mouseReleased(ofMouseEventArgs &e); + void mousePressed(ofMouseEventArgs &e); + void mouseDragged(ofMouseEventArgs &e); + void mouseReleased(ofMouseEventArgs &e); #endif - - void registerGrabbing(); - void grabShapeDown(float x, float y, int id = -1 ); // -1 is reserved for mouse. - void grabShapeUp(float x, float y, int id = -1 ); // -1 is reserved for mouse. - void grabShapeDragged(float x, float y, int id = -1 ); // -1 is reserved for mouse. - - b2World* getWorld() { return world; } - int getBodyCount(); - int getJointCount(); - - void enableGrabbing() { bEnableGrabbing = true; }; - void disableGrabbing() { bEnableGrabbing = false; }; - - void setContactListener(ofxBox2dContactListener * listener); - - void wakeupShapes(); - void setIterations(int velocityTimes, int positionTimes); - void setGravity(float x, float y); - void setGravity(ofPoint pt); - ofPoint getGravity(); - - void setBounds(ofPoint lowBounds, ofPoint upBounds); - void createBounds(float x=0, float y=0, float w=ofGetWidth(), float h=ofGetHeight()); - void createBounds(ofRectangle rec); - - void createGround(const ofPoint & p1, const ofPoint & p2); - void createGround(float x1=0, float y1=ofGetHeight(), float x2=ofGetWidth(), float y2=ofGetHeight()); - void checkBounds(bool b); - - void update(); - void draw(); - void drawGround(); - + + void registerGrabbing(); + void grabShapeDown(float x, float y, int id = -1 ); // -1 is reserved for mouse. + void grabShapeUp(float x, float y, int id = -1 ); // -1 is reserved for mouse. + void grabShapeDragged(float x, float y, int id = -1 ); // -1 is reserved for mouse. + + b2World* getWorld() { return world; } + int getBodyCount(); + int getJointCount(); + + void enableGrabbing() { bEnableGrabbing = true; }; + void disableGrabbing() { bEnableGrabbing = false; }; + + void setContactListener(ofxBox2dContactListener * listener); + + void wakeupShapes(); + void setIterations(int velocityTimes, int positionTimes); + void setGravity(float x, float y); + void setGravity(ofPoint pt); + ofPoint getGravity(); + + void setBounds(ofPoint lowBounds, ofPoint upBounds); + void createBounds(float x=0, float y=0, float w=ofGetWidth(), float h=ofGetHeight()); + void createBounds(ofRectangle rec); + + void createGround(const ofPoint & p1, const ofPoint & p2); + void createGround(float x1=0, float y1=ofGetHeight(), float x2=ofGetWidth(), float y2=ofGetHeight()); + void checkBounds(bool b); + + void update(); + void draw(); + void drawGround(); + }; diff --git a/src/ofxBox2dBaseShape.cpp b/src/ofxBox2dBaseShape.cpp index e239d81..99fb916 100644 --- a/src/ofxBox2dBaseShape.cpp +++ b/src/ofxBox2dBaseShape.cpp @@ -11,13 +11,13 @@ //---------------------------------------- ofxBox2dBaseShape::ofxBox2dBaseShape() { - + setMassFromShape = true; alive = false; body = NULL; - - density = 0.0; - bounce = 0.0; + + density = 0.0; + bounce = 0.0; friction = 0.0; bodyDef.allowSleep = true; } @@ -32,7 +32,7 @@ ofxBox2dBaseShape::~ofxBox2dBaseShape() { //------------------------------------------------ void ofxBox2dBaseShape::destroy() { - + if(getWorld() == NULL) { ofLog(OF_LOG_NOTICE, "ofxBox2dBaseShape:: - must have a valid world -"); return; @@ -41,7 +41,7 @@ void ofxBox2dBaseShape::destroy() { ofLog(OF_LOG_NOTICE, "ofxBox2dBaseShape:: - null body -"); return; } - + getWorld()->DestroyBody(body); body = NULL; alive = false; @@ -68,13 +68,13 @@ bool ofxBox2dBaseShape::isFixed() { } bool ofxBox2dBaseShape::isSleeping() { - if(isBody()) { - return !body->IsAwake(); - } - else { - ofLog(OF_LOG_ERROR, "ofxBox2dBaseShape:: - body is not defined -"); - return false; - } + if(isBody()) { + return !body->IsAwake(); + } + else { + ofLog(OF_LOG_ERROR, "ofxBox2dBaseShape:: - body is not defined -"); + return false; + } } // b2World* ofxBox2dBaseShape::getWorld() { @@ -87,20 +87,20 @@ b2World* ofxBox2dBaseShape::getWorld() { //---------------------------------------- void ofxBox2dBaseShape::create() {} -//------------------------------------------------ +//------------------------------------------------ void ofxBox2dBaseShape::setBounce(float val) { bounce = val; } -//------------------------------------------------ +//------------------------------------------------ void ofxBox2dBaseShape::setDensity(float val) { // -- this is not working ! -- /*b2MassData data; - data.mass = 3; - data.center = body->GetPosition(); - data.I = body->GetInertia(); - body->SetMass(&data); - */ + data.mass = 3; + data.center = body->GetPosition(); + data.I = body->GetInertia(); + body->SetMass(&data); + */ } //---------------------------------------- @@ -108,20 +108,20 @@ void ofxBox2dBaseShape::setFriction(float val) { friction = val; } -//------------------------------------------------ +//------------------------------------------------ void ofxBox2dBaseShape::setPhysics(float density, float bounce, float friction) { this->density = density; this->bounce = bounce; this->friction = friction; } -//------------------------------------------------ +//------------------------------------------------ void* ofxBox2dBaseShape::setData(void*data) { - + if(data == NULL) { ofLog(OF_LOG_NOTICE, "ofxBox2dBaseShape:: - data is NULL -"); return NULL; } - + if(isBody()) { //ofLog(OF_LOG_NOTICE, "ofxBox2dBaseShape:: - custom data set %p", data); body->SetUserData(data); @@ -130,10 +130,10 @@ void* ofxBox2dBaseShape::setData(void*data) { else { ofLog(OF_LOG_NOTICE, "ofxBox2dBaseShape:: - must have a valid body -"); } - return NULL; + return NULL; } -//------------------------------------------------ +//------------------------------------------------ void* ofxBox2dBaseShape::getData() { if(body) { return body->GetUserData(); @@ -146,12 +146,12 @@ void* ofxBox2dBaseShape::getData() { //------------------------------------------------ void ofxBox2dBaseShape::setFilterData(b2Filter filter) { - for( b2Fixture * f = body->GetFixtureList(); f; f = f->GetNext() ){ - f->SetFilterData(filter); - } + for(b2Fixture * f = body->GetFixtureList(); f; f = f->GetNext()) { + f->SetFilterData(filter); + } } -//------------------------------------------------ +//------------------------------------------------ void ofxBox2dBaseShape::enableGravity(bool b) { //bodyDef.isGravitated = b; } @@ -175,7 +175,7 @@ float ofxBox2dBaseShape::getRotation() { } void ofxBox2dBaseShape::setRotation(float angle){ - body->SetTransform(body->GetWorldCenter(), DEG_TO_RAD * angle); + body->SetTransform(body->GetWorldCenter(), DEG_TO_RAD * angle); } @@ -194,15 +194,15 @@ void ofxBox2dBaseShape::setPosition(ofVec2f p) { setPosition(p.x, p.y); } -//------------------------------------------------ +//------------------------------------------------ ofVec2f ofxBox2dBaseShape::getPosition() { ofVec2f p; if(body != NULL) { - const b2Transform& xf = body->GetTransform(); - b2Vec2 pos = body->GetLocalCenter(); - b2Vec2 b2Center = b2Mul(xf, pos); + const b2Transform& xf = body->GetTransform(); + b2Vec2 pos = body->GetLocalCenter(); + b2Vec2 b2Center = b2Mul(xf, pos); p = worldPtToscreenPt(b2Center); - } + } return p; } @@ -211,7 +211,17 @@ ofVec2f ofxBox2dBaseShape::getB2DPosition() { return getPosition() / OFX_BOX2D_SCALE; } -//------------------------------------------------ +//------------------------------------------------ +float ofxBox2dBaseShape::getMass() { + if (!isBody()) { + ofLog(OF_LOG_ERROR, "- trying to get Mass of unitialized rect -"); + return 0; + } + return (float)body->GetMass(); +} + + +//------------------------------------------------ void ofxBox2dBaseShape::setVelocity(float x, float y) { if(body != NULL) { body->SetLinearVelocity(b2Vec2(x, y)); @@ -255,19 +265,18 @@ void ofxBox2dBaseShape::addImpulseForce(ofVec2f pt, ofVec2f amt) { //------------------------------------------------ void ofxBox2dBaseShape::addRepulsionForce(ofVec2f pt, float radius, float amt) { /*if(body != NULL) { - b2Vec2 P(pt.x/OFX_BOX2D_SCALE, pt.y/OFX_BOX2D_SCALE); - b2Vec2 D = P - body->GetPosition(); - if(D.LengthSquared() < minDis) {; - P.Normalize(); - b2Vec2 F = amt * D; - body->ApplyForce(F, P); - } - }*/ - - + b2Vec2 P(pt.x/OFX_BOX2D_SCALE, pt.y/OFX_BOX2D_SCALE); + b2Vec2 D = P - body->GetPosition(); + if(D.LengthSquared() < minDis) {; + P.Normalize(); + b2Vec2 F = amt * D; + body->ApplyForce(F, P); + } + }*/ + if(body != NULL) { b2Vec2 P(pt.x/OFX_BOX2D_SCALE, pt.y/OFX_BOX2D_SCALE); - b2Vec2 D = P - body->GetPosition(); + b2Vec2 D = P - body->GetPosition(); if(D.LengthSquared() < radius) {; P.Normalize(); b2Vec2 F = amt * D; diff --git a/src/ofxBox2dBaseShape.h b/src/ofxBox2dBaseShape.h index e7da823..7002f95 100644 --- a/src/ofxBox2dBaseShape.h +++ b/src/ofxBox2dBaseShape.h @@ -5,109 +5,105 @@ #include "ofxBox2dUtils.h" class ofxBox2dBaseShape { - + public: b2FixtureDef fixture; - b2BodyDef bodyDef; - b2Body* body; - - bool alive; - bool setMassFromShape; - - float density; - float bounce; - float friction; - ofxBox2dBaseShape(); - + b2BodyDef bodyDef; + b2Body* body; + + bool alive; + bool setMassFromShape; + + float density; + float bounce; + float friction; + //---------------------------------------- + ofxBox2dBaseShape(); ~ofxBox2dBaseShape(); - + //---------------------------------------- bool isBody(); - + //---------------------------------------- - static bool shouldRemove(shared_ptr shape); - static bool shouldRemoveOffScreen(shared_ptr shape); + static bool shouldRemove(shared_ptr shape); + static bool shouldRemoveOffScreen(shared_ptr shape); bool isFixed(); bool isSleeping(); - + //---------------------------------------- b2World* getWorld(); - + //---------------------------------------- virtual void create(); - - //------------------------------------------------ + + //------------------------------------------------ virtual void setBounce(float val); - - //------------------------------------------------ + + //------------------------------------------------ virtual void setDensity(float val); - + //---------------------------------------- virtual void setFriction(float val); - - //------------------------------------------------ + + //------------------------------------------------ virtual void setPhysics(float density, float bounce, float friction); - - //------------------------------------------------ + + //------------------------------------------------ void* setData(void*data); - - //------------------------------------------------ + + //------------------------------------------------ void* getData(); - - //------------------------------------------------ + + //------------------------------------------------ virtual void setFilterData(b2Filter filter); - - //------------------------------------------------ + + //------------------------------------------------ virtual void enableGravity(bool b); - - //------------------------------------------------ + + //------------------------------------------------ virtual void setFixedRotation(bool b); virtual void setRotationFriction(float f); float getRotation(); void setRotation(float angle); - - //------------------------------------------------ + + //------------------------------------------------ virtual void setPosition(float x, float y); virtual void setPosition(ofVec2f p); - - //------------------------------------------------ + + //------------------------------------------------ ofVec2f getPosition(); ofVec2f getB2DPosition(); - - - //------------------------------------------------ + + //------------------------------------------------ + float getMass(); + + //------------------------------------------------ virtual void setVelocity(float x, float y); virtual void setVelocity(ofVec2f p); ofVec2f getVelocity(); - - //------------------------------------------------ + + //------------------------------------------------ virtual void setDamping(float f); virtual void setDamping(float fx, float fy); - - - + + + //------------------------------------------------ virtual void addForce(ofVec2f frc, float scale); - + //------------------------------------------------ virtual void addImpulseForce(ofVec2f pt, ofVec2f amt); - + //------------------------------------------------ virtual void addRepulsionForce(ofVec2f pt, float radius, float amt); - + //------------------------------------------------ virtual void destroy(); - + //------------------------------------------------ virtual void update(); virtual void draw(); - -}; - - - - - +}; diff --git a/src/ofxBox2dCircle.cpp b/src/ofxBox2dCircle.cpp index 540169a..edab63c 100644 --- a/src/ofxBox2dCircle.cpp +++ b/src/ofxBox2dCircle.cpp @@ -15,37 +15,36 @@ ofxBox2dCircle::ofxBox2dCircle() { //------------------------------------------------ void ofxBox2dCircle::setup(b2World * b2dworld, float x, float y, float radius) { - - + if(b2dworld == NULL) { ofLog(OF_LOG_NOTICE, "ofxBox2dCircle :: setup : - must have a valid world -"); return; } - + // these are used to create the shape b2CircleShape shape; - + shape.m_p.SetZero(); - shape.m_radius = radius / OFX_BOX2D_SCALE; - this->radius = radius; - - fixture.shape = &shape; - fixture.density = density; + shape.m_radius = radius / OFX_BOX2D_SCALE; + this->radius = radius; + + fixture.shape = &shape; + fixture.density = density; fixture.friction = friction; fixture.restitution = bounce; - - if(density == 0.f) bodyDef.type = b2_staticBody; - else bodyDef.type = b2_dynamicBody; - + + if(density == 0.f) bodyDef.type = b2_staticBody; + else bodyDef.type = b2_dynamicBody; + bodyDef.position.Set(x/OFX_BOX2D_SCALE, y/OFX_BOX2D_SCALE); - - body = b2dworld->CreateBody(&bodyDef); + + body = b2dworld->CreateBody(&bodyDef); body->CreateFixture(&fixture); - - alive = true; + + alive = true; } void ofxBox2dCircle::setup(b2World * b2dworld, ofVec2f &pts, float radius) { - setup(b2dworld, pts.x, pts.y, radius); + setup(b2dworld, pts.x, pts.y, radius); } //------------------------------------------------ @@ -57,22 +56,22 @@ void ofxBox2dCircle::addRepulsionForce(float x, float y, float amt) { void ofxBox2dCircle::addRepulsionForce(ofVec2f pt, float amt) { const b2Transform& xf = body->GetTransform(); b2Vec2 P(pt.x/OFX_BOX2D_SCALE, pt.y/OFX_BOX2D_SCALE); - + float cx = body->GetPosition().x / OFX_BOX2D_SCALE; float cy = body->GetPosition().y / OFX_BOX2D_SCALE; float r = getRadius() / OFX_BOX2D_SCALE; float ori = DEG_TO_RAD * getRotation(); - + b2Vec2 A(cx,cy); b2Vec2 B(cx+r*cos(ori), cy+r*sin(ori)); - + b2Vec2 qtA = b2Mul(xf, A); b2Vec2 qtB = b2Mul(xf, B); b2Vec2 DA = P - qtA; b2Vec2 DB = P - qtB; b2Vec2 FA = amt * DA; b2Vec2 FB = amt * DB; - + body->ApplyForce(-FA, P, true); body->ApplyForce(-FB, P, true); } @@ -86,28 +85,50 @@ void ofxBox2dCircle::addAttractionPoint(float x, float y, float amt) { void ofxBox2dCircle::addAttractionPoint(ofVec2f pt, float amt) { const b2Transform& xf = body->GetTransform(); b2Vec2 P(pt.x/OFX_BOX2D_SCALE, pt.y/OFX_BOX2D_SCALE); - + float cx = body->GetPosition().x / OFX_BOX2D_SCALE; float cy = body->GetPosition().y / OFX_BOX2D_SCALE; float r = getRadius() / OFX_BOX2D_SCALE; float ori = DEG_TO_RAD * getRotation(); - + b2Vec2 A(cx,cy); b2Vec2 B(cx+r*cos(ori), cy+r*sin(ori)); - + b2Vec2 qtA = b2Mul(xf, A); b2Vec2 qtB = b2Mul(xf, B); b2Vec2 DA = P - qtA; b2Vec2 DB = P - qtB; b2Vec2 FA = amt * DA; b2Vec2 FB = amt * DB; - + body->ApplyForce(FA, P, true); body->ApplyForce(FB, P, true); } +//------------------------------------------------ +float ofxBox2dCircle::getX() { + if (!isBody()) { + ofLog(OF_LOG_ERROR, "- trying to get X of unitialized circle -"); + return 0; + } + float cx = body->GetPosition().x * OFX_BOX2D_SCALE; + return cx; +} +float ofxBox2dCircle::getY() { + if (!isBody()) { + ofLog(OF_LOG_ERROR, "- trying to get X of unitialized circle -"); + return 0; + } + float cy = body->GetPosition().y * OFX_BOX2D_SCALE; + return cy; +} + //------------------------------------------------ float ofxBox2dCircle::getRadius() { + if (!isBody()) { + ofLog(OF_LOG_ERROR, "- trying to get Radius of unitialized circle -"); + return 0; + } return radius; } @@ -117,16 +138,19 @@ float ofxBox2dCircle::getRadius() { Im not sure about this it seems like a bad idea. I cant figure out another way to change the radius of a shape that we have - + -- any help here :) -- - + here is a solution for changing the radius on the fly without destroying the shape - chrispie - + */ void ofxBox2dCircle::setRadius(float r) { + + if(!isBody()) return; + this->radius = r; - + for (b2Fixture* f= body->GetFixtureList(); f; f = f->GetNext()) { f->GetShape()->m_radius=r/OFX_BOX2D_SCALE; @@ -135,38 +159,24 @@ void ofxBox2dCircle::setRadius(float r) { //------------------------------------------------ void ofxBox2dCircle::draw() { - + if(!isBody()) return; - + ofPushMatrix(); ofTranslate(getPosition().x, getPosition().y, 0); ofRotate(getRotation(), 0, 0, 1); - ofCircle(0, 0, radius); - - ofPushStyle(); - ofEnableAlphaBlending(); - ofSetColor(0); - ofLine(0, 0, radius, 0); - if(isSleeping()) { - ofSetColor(255, 100); - ofCircle(0, 0, radius); - } - ofPopStyle(); - - ofPopMatrix(); - -} - - - - - - - - - - - - + ofDrawCircle(0, 0, radius); + + ofPushStyle(); + ofEnableAlphaBlending(); + ofSetColor(0); + ofDrawLine(0, 0, radius, 0); + if (isSleeping()) { + ofSetColor(255, 100); + ofDrawCircle(0, 0, radius); + } + ofPopStyle(); + ofPopMatrix(); +} diff --git a/src/ofxBox2dCircle.h b/src/ofxBox2dCircle.h index b3ce20d..f953967 100644 --- a/src/ofxBox2dCircle.h +++ b/src/ofxBox2dCircle.h @@ -1,50 +1,37 @@ - - #pragma once + #include "ofMain.h" #include "ofxBox2dBaseShape.h" class ofxBox2dCircle : public ofxBox2dBaseShape { - + private: float radius; - + public: //------------------------------------------------ ofxBox2dCircle(); - + //------------------------------------------------ void setup(b2World * b2dworld, float x, float y, float radius); void setup(b2World * b2dworld, ofVec2f &pts, float radius); - + //------------------------------------------------ + float getX(); + float getY(); float getRadius(); void setRadius(float r); - + //------------------------------------------------ virtual void draw(); - + //------------------------------------------------ - void addAttractionPoint(float x, float y, float amt=1); - void addAttractionPoint(ofVec2f pt, float amt=1); - + void addAttractionPoint(float x, float y, float amt=1); + void addAttractionPoint(ofVec2f pt, float amt=1); + void addRepulsionForce(float x, float y, float amt); void addRepulsionForce(ofVec2f pt, float amt); }; - - - - - - - - - - - - - - diff --git a/src/ofxBox2dContactListener.h b/src/ofxBox2dContactListener.h index 3d3e664..22d74f1 100644 --- a/src/ofxBox2dContactListener.h +++ b/src/ofxBox2dContactListener.h @@ -1,5 +1,5 @@ - #pragma once + #include "ofMain.h" #include "Box2D.h" @@ -10,25 +10,20 @@ */ class ofxBox2dContactListener : public b2ContactListener { - + public: virtual void BeginContact(b2Contact* contact) { - } - + } + virtual void EndContact(b2Contact* contact) { - } + } ofxBox2dContactListener() { } - - - + virtual void contactAdd(ofPoint p) { } virtual void contactRemove(ofPoint p) { } }; - - - diff --git a/src/ofxBox2dConvexPoly.cpp b/src/ofxBox2dConvexPoly.cpp index 4486559..aeba812 100644 --- a/src/ofxBox2dConvexPoly.cpp +++ b/src/ofxBox2dConvexPoly.cpp @@ -10,37 +10,32 @@ #include "ofxBox2dConvexPoly.h" #include "ofxBox2dPolygon.h" +ofPolyline convexHull(ofPolyline & line){ + vector ptsIn; + for (int i = 0; i < line.getVertices().size(); i++) { + hPoint pt; + pt.x = line.getVertices()[i].x; + pt.y = line.getVertices()[i].y; + ptsIn.push_back(pt); + } + vector ptsOut; + ptsOut = calcConvexHull(ptsIn); -ofPolyline convexHull(ofPolyline & line){ - - vector < hPoint > ptsIn; - for (int i = 0; i < line.getVertices().size(); i++){ - hPoint pt; - pt.x = line.getVertices()[i].x; - pt.y = line.getVertices()[i].y; - - ptsIn.push_back(pt); - } - vector < hPoint > ptsOut; - - ptsOut = calcConvexHull(ptsIn); - - ofPolyline out; - - for (int i = 0; i < ptsOut.size(); i++){ - out.addVertex(ofPoint(ptsOut[i].x, ptsOut[i].y)); - } - - return out; - + ofPolyline out; + + for (int i = 0; i < ptsOut.size(); i++) { + out.addVertex(ofPoint(ptsOut[i].x, ptsOut[i].y)); + } + + return out; } ////---------------------------------------- -//ofxBox2dConvexPoly::~ofxBox2dPolygon() { +//ofxBox2dConvexPoly::~ofxBox2dPolygon() { //} // ////---------------------------------------- @@ -58,45 +53,43 @@ ofxBox2dConvexPoly::ofxBox2dConvexPoly() { //------------------------------------------------ void ofxBox2dConvexPoly::setup(b2World * b2dworld, ofPolyline & _line){ - ofPolyline line = convexHull(_line); - line.getVertices().erase(line.getVertices().end()-1); - - - b2Vec2 * vertices; - int32 vertexCount = line.getVertices().size(); - vertices = new b2Vec2[vertexCount]; - ofPoint pos; - ghettoRadius = 0; - for (int i = 0; i < vertexCount; i++){ - vertices[i].x = line.getVertices()[i].x; - vertices[i].y = line.getVertices()[i].y; - pos.x += line.getVertices()[i].x; - pos.y += line.getVertices()[i].y; - - } - pos /= (float)vertexCount; - - for (int i = 0; i < vertexCount; i++){ - float dist = (pos - line.getVertices()[i]).length(); - if (dist > ghettoRadius){ - ghettoRadius = dist; - } - } - - - for (int i = 0; i < vertexCount; i++){ - vertices[i].x /= OFX_BOX2D_SCALE; - vertices[i].y /= OFX_BOX2D_SCALE; - } - - ofPoint posCent = ofPoint(200,200) - pos; - - pos /= OFX_BOX2D_SCALE; - posCent /= OFX_BOX2D_SCALE; - ghettoRadius /= OFX_BOX2D_SCALE; + ofPolyline line = convexHull(_line); + line.getVertices().erase(line.getVertices().end()-1); + + + b2Vec2 * vertices; + int32 vertexCount = line.getVertices().size(); + vertices = new b2Vec2[vertexCount]; + ofPoint pos; + ghettoRadius = 0; + for (int i = 0; i < vertexCount; i++) { + vertices[i].x = line.getVertices()[i].x; + vertices[i].y = line.getVertices()[i].y; + pos.x += line.getVertices()[i].x; + pos.y += line.getVertices()[i].y; + } + pos /= (float)vertexCount; + + for (int i = 0; i < vertexCount; i++) { + float dist = (pos - line.getVertices()[i]).length(); + if (dist > ghettoRadius){ + ghettoRadius = dist; + } + } + + for (int i = 0; i < vertexCount; i++) { + vertices[i].x /= OFX_BOX2D_SCALE; + vertices[i].y /= OFX_BOX2D_SCALE; + } + + ofPoint posCent = ofPoint(200,200) - pos; + + pos /= OFX_BOX2D_SCALE; + posCent /= OFX_BOX2D_SCALE; + ghettoRadius /= OFX_BOX2D_SCALE; ofPath path; - for (int i = 0; i < vertexCount; i++){ + for (int i = 0; i < vertexCount; i++) { vertices[i].x -= pos.x; vertices[i].y -= pos.y; ofVec2f cur(vertices[i].x, vertices[i].y); @@ -104,85 +97,82 @@ void ofxBox2dConvexPoly::setup(b2World * b2dworld, ofPolyline & _line){ path.lineTo(cur); } gpuCachedTesselation = path.getTessellation(); - - - float x = pos.x ; - float y = pos.y ; - + + float x = pos.x; + float y = pos.y; + if(b2dworld == NULL) { ofLog(OF_LOG_NOTICE, "ofxBox2dConvexPoly :: setup : - must have a valid world -"); return; } - + // these are used to create the shape - + shape.Set(vertices, vertexCount); - - delete vertices; - - fixture.shape = &shape; - fixture.density = density; + + delete vertices; + + fixture.shape = &shape; + fixture.density = density; fixture.friction = friction; fixture.restitution = bounce; - - if(density == 0.f) bodyDef.type = b2_staticBody; - else bodyDef.type = b2_dynamicBody; - + + if(density == 0.f) bodyDef.type = b2_staticBody; + else bodyDef.type = b2_dynamicBody; + bodyDef.position.Set(x,y); - + body = b2dworld->CreateBody(&bodyDef); body->CreateFixture(&fixture); - - scale = 1; + + scale = 1; } //------------------------------------------------ -void ofxBox2dConvexPoly::setScale(float _scale){ - - - if(!isBody()) return; - - b2Fixture* fix = body->GetFixtureList(); - - scale = _scale; - - b2PolygonShape* shape = (b2PolygonShape*) fix->GetShape(); - - for (int i = 0; i < polyPts.size(); i++){ - shape->m_vertices[i].Set(polyPts[i].x*scale, polyPts[i].y*scale); - } - - +void ofxBox2dConvexPoly::setScale(float _scale) { + + if(!isBody()) return; + + b2Fixture* fix = body->GetFixtureList(); + + scale = _scale; + + b2PolygonShape* shape = (b2PolygonShape*) fix->GetShape(); + + for (int i = 0; i < polyPts.size(); i++) { + shape->m_vertices[i].Set(polyPts[i].x*scale, polyPts[i].y*scale); + } + } void ofxBox2dConvexPoly::addAttractionPoint (ofVec2f pt, float amt) { - // we apply forces at each vertex. - if(body != NULL) { - const b2Transform& xf = body->GetTransform(); - - for (b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext()) { - b2PolygonShape* poly = (b2PolygonShape*)f->GetShape(); - - if(poly) { - b2Vec2 P(pt.x/OFX_BOX2D_SCALE, pt.y/OFX_BOX2D_SCALE); - - for(int i=0; iGetVertexCount(); i++) { - b2Vec2 qt = b2Mul(xf, poly->GetVertex(i)); - b2Vec2 D = P - qt; - b2Vec2 F = amt * D; - body->ApplyForce(F, P, true); - } - } - } - } + // we apply forces at each vertex. + if (body != NULL) { + const b2Transform& xf = body->GetTransform(); + + for (b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext()) { + b2PolygonShape* poly = (b2PolygonShape*)f->GetShape(); + + if (poly) { + b2Vec2 P(pt.x/OFX_BOX2D_SCALE, pt.y/OFX_BOX2D_SCALE); + + for (int i=0; iGetVertexCount(); i++) { + b2Vec2 qt = b2Mul(xf, poly->GetVertex(i)); + b2Vec2 D = P - qt; + b2Vec2 F = amt * D; + body->ApplyForce(F, P, true); + } + } + } + } } //---------------------------------------- void ofxBox2dConvexPoly::addAttractionPoint (float x, float y, float amt) { - addAttractionPoint(ofVec2f(x, y), amt); + addAttractionPoint(ofVec2f(x, y), amt); } //---------------------------------------- @@ -190,34 +180,31 @@ void ofxBox2dConvexPoly::addRepulsionForce(float x, float y, float amt) { addRepulsionForce(ofVec2f(x, y), amt); } void ofxBox2dConvexPoly::addRepulsionForce(ofVec2f pt, float amt) { - // we apply forces at each vertex. - if(body != NULL) { - const b2Transform& xf = body->GetTransform(); - - for (b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext()) { - b2PolygonShape* poly = (b2PolygonShape*)f->GetShape(); - - if(poly) { - b2Vec2 P(pt.x/OFX_BOX2D_SCALE, pt.y/OFX_BOX2D_SCALE); - - for(int i=0; iGetVertexCount(); i++) { - b2Vec2 qt = b2Mul(xf, poly->GetVertex(i)); - b2Vec2 D = P - qt; - b2Vec2 F = amt * D; - body->ApplyForce(-F, P, true); - } - } - } - } + // we apply forces at each vertex. + if(body != NULL) { + const b2Transform& xf = body->GetTransform(); + + for (b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext()) { + b2PolygonShape* poly = (b2PolygonShape*)f->GetShape(); + + if(poly) { + b2Vec2 P(pt.x/OFX_BOX2D_SCALE, pt.y/OFX_BOX2D_SCALE); + + for (int i=0; iGetVertexCount(); i++) { + b2Vec2 qt = b2Mul(xf, poly->GetVertex(i)); + b2Vec2 D = P - qt; + b2Vec2 F = amt * D; + body->ApplyForce(-F, P, true); + } + } + } + } } - - - //------------------------------------------------ void ofxBox2dConvexPoly::draw() { if(!isBody()) return; - + ofPushMatrix(); ofTranslate(getPosition().x, getPosition().y, 0); ofRotate(getRotation(), 0, 0, 1); @@ -225,4 +212,3 @@ void ofxBox2dConvexPoly::draw() { gpuCachedTesselation.draw(); ofPopMatrix(); } - diff --git a/src/ofxBox2dConvexPoly.h b/src/ofxBox2dConvexPoly.h index af87fe5..455eabf 100644 --- a/src/ofxBox2dConvexPoly.h +++ b/src/ofxBox2dConvexPoly.h @@ -1,56 +1,40 @@ - - #pragma once #include "ofMain.h" #include "ofxBox2dBaseShape.h" class ofxBox2dConvexPoly : public ofxBox2dBaseShape { - + private: - + float radius; - + public: - - ~ofxBox2dConvexPoly(){}; + + ~ofxBox2dConvexPoly(){}; //------------------------------------------------ ofxBox2dConvexPoly(); - + //------------------------------------------------ void setup(b2World * b2dworld, ofPolyline & line); - - - void setScale(float scale); - + + + void setScale(float scale); + //------------------------------------------------ virtual void draw(); //------------------------------------------------ - void addAttractionPoint(float x, float y, float amt=1); - void addAttractionPoint(ofVec2f pt, float amt=1); - + void addAttractionPoint(float x, float y, float amt=1); + void addAttractionPoint(ofVec2f pt, float amt=1); + void addRepulsionForce(float x, float y, float amt); void addRepulsionForce(ofVec2f pt, float amt); - - float ghettoRadius; - - b2PolygonShape shape; - ofVboMesh gpuCachedTesselation; - ofPolyline polyPts; - float scale; - -}; - - - - - - - - - - - + float ghettoRadius; + b2PolygonShape shape; + ofVboMesh gpuCachedTesselation; + ofPolyline polyPts; + float scale; +}; diff --git a/src/ofxBox2dEdge.cpp b/src/ofxBox2dEdge.cpp index 63ff66b..3e760ad 100644 --- a/src/ofxBox2dEdge.cpp +++ b/src/ofxBox2dEdge.cpp @@ -10,53 +10,53 @@ //---------------------------------------- void ofxBox2dEdge::clear() { - ofPolyline::clear(); - ofxBox2dBaseShape::destroy(); - mesh.clear(); + ofPolyline::clear(); + ofxBox2dBaseShape::destroy(); + mesh.clear(); } //---------------------------------------- void ofxBox2dEdge::destroy() { - ofPolyline::clear(); - ofxBox2dBaseShape::destroy(); - mesh.clear(); + ofPolyline::clear(); + ofxBox2dBaseShape::destroy(); + mesh.clear(); } //---------------------------------------- void ofxBox2dEdge::create(b2World * b2dworld) { - - bFlagShapeUpdate = false; - - if(size() < 2) { + + bFlagShapeUpdate = false; + + if(size() < 2) { printf("need at least 3 points\n"); return; } - + if (body != NULL) { b2dworld->DestroyBody(body); body = NULL; } - + // create the body from the world (1) b2BodyDef bd; bd.type = density <= 0.0 ? b2_staticBody : b2_dynamicBody; body = b2dworld->CreateBody(&bd); - - vector&pts = ofPolyline::getVertices(); + + vector&pts = ofPolyline::getVertices(); for(int i=1; i<(int)size(); i++) { - b2EdgeShape edge; - edge.Set(screenPtToWorldPt(pts[i-1]), screenPtToWorldPt(pts[i])); - body->CreateFixture(&edge, density); - } - mesh.clear(); - mesh.setUsage(body->GetType()==b2_staticBody?GL_STATIC_DRAW:GL_DYNAMIC_DRAW); - mesh.setMode(OF_PRIMITIVE_LINE_STRIP); - for(int i=0; i<(int)size(); i++) { - mesh.addVertex(ofVec3f(pts[i].x, pts[i].y)); - } - - flagHasChanged(); - alive = true; + b2EdgeShape edge; + edge.Set(screenPtToWorldPt(pts[i-1]), screenPtToWorldPt(pts[i])); + body->CreateFixture(&edge, density); + } + mesh.clear(); + mesh.setUsage(body->GetType()==b2_staticBody?GL_STATIC_DRAW:GL_DYNAMIC_DRAW); + mesh.setMode(OF_PRIMITIVE_LINE_STRIP); + for(int i=0; i<(int)size(); i++) { + mesh.addVertex(ofVec3f(pts[i].x, pts[i].y)); + } + + flagHasChanged(); + alive = true; } /* @@ -65,9 +65,9 @@ void ofxBox2dEdge::create(b2World * b2dworld) { //---------------------------------------- void ofxBox2dEdge::addVertexes(vector &pts) { for (int i=0; iGetTransform(); - ofPolyline::clear(); - mesh.clear(); - mesh.setUsage(body->GetType()==b2_staticBody?GL_STATIC_DRAW:GL_DYNAMIC_DRAW); - mesh.setMode(OF_PRIMITIVE_LINE_STRIP); - - for (b2Fixture * f = body->GetFixtureList(); f; f = f->GetNext()) { - b2EdgeShape * edge = (b2EdgeShape*)f->GetShape(); - - if(edge) { - ofPolyline::addVertex(worldPtToscreenPt(edge->m_vertex2)); - ofPolyline::addVertex(worldPtToscreenPt(edge->m_vertex1)); - - mesh.addVertex(ofVec3f(worldPtToscreenPt(edge->m_vertex2))); - mesh.addVertex(ofVec3f(worldPtToscreenPt(edge->m_vertex1))); - } - } - - bFlagShapeUpdate = true; - flagHasChanged(); + if(body==NULL) return; + // const b2Transform& xf = body->GetTransform(); + ofPolyline::clear(); + mesh.clear(); + mesh.setUsage(body->GetType()==b2_staticBody?GL_STATIC_DRAW:GL_DYNAMIC_DRAW); + mesh.setMode(OF_PRIMITIVE_LINE_STRIP); + + for (b2Fixture * f = body->GetFixtureList(); f; f = f->GetNext()) { + b2EdgeShape * edge = (b2EdgeShape*)f->GetShape(); + + if(edge) { + ofPolyline::addVertex(worldPtToscreenPt(edge->m_vertex2)); + ofPolyline::addVertex(worldPtToscreenPt(edge->m_vertex1)); + + mesh.addVertex(ofVec3f(worldPtToscreenPt(edge->m_vertex2))); + mesh.addVertex(ofVec3f(worldPtToscreenPt(edge->m_vertex1))); + } + } + + bFlagShapeUpdate = true; + flagHasChanged(); } //---------------------------------------- void ofxBox2dEdge::draw() { - if(body==NULL) return; - + if(body==NULL) return; + if(!bFlagShapeUpdate && body->GetType() != b2_staticBody) { - printf("Need to update shape first\n"); - } - // Temporary fix until we switch to OF 0.8.0. - mesh.draw(); - //ofPolyline::draw(); - bFlagShapeUpdate = false; + printf("Need to update shape first\n"); + } + // Temporary fix until we switch to OF 0.8.0. + mesh.draw(); + //ofPolyline::draw(); + bFlagShapeUpdate = false; } - - - - - - - - - diff --git a/src/ofxBox2dEdge.h b/src/ofxBox2dEdge.h index ad6d5fc..3744704 100644 --- a/src/ofxBox2dEdge.h +++ b/src/ofxBox2dEdge.h @@ -5,28 +5,27 @@ // Created by Todd Vanderlin on 11/18/13. // // - - #pragma once + #include "ofMain.h" #include "ofxBox2dBaseShape.h" #include "ofxBox2dPolygonUtils.h" class ofxBox2dEdge : public ofxBox2dBaseShape, public ofPolyline { - + private: - bool bFlagShapeUpdate; - + bool bFlagShapeUpdate; + public: - ofVboMesh mesh; - void addVertexes(ofPolyline &polyline); - void addVertexes(vector &pts); - - void clear(); - void destroy(); - - void create(b2World * b2dworld); - void updateShape(); - void draw(); -}; \ No newline at end of file + ofVboMesh mesh; + void addVertexes(ofPolyline &polyline); + void addVertexes(vector &pts); + + void clear(); + void destroy(); + + void create(b2World * b2dworld); + void updateShape(); + void draw(); +}; diff --git a/src/ofxBox2dJoint.cpp b/src/ofxBox2dJoint.cpp index 4d90a84..d28f6aa 100644 --- a/src/ofxBox2dJoint.cpp +++ b/src/ofxBox2dJoint.cpp @@ -36,19 +36,19 @@ ofxBox2dJoint::ofxBox2dJoint(b2World* b2world, b2DistanceJointDef jointDef) { //---------------------------------------- void ofxBox2dJoint::setup(b2World* b2world, b2Body* body1, b2Body* body2, float frequencyHz, float damping, bool bCollideConnected) { - + if(body1 == NULL || body2 == NULL) { ofLog(OF_LOG_NOTICE, "ofxBox2dJoint :: setup : - box2d body is NULL -"); return; } - + b2Vec2 a1, a2; a1 = body1->GetWorldCenter(); a2 = body2->GetWorldCenter(); - + setup(b2world, body1, body2, a1, a2, frequencyHz, damping, bCollideConnected); - - alive = true; + + alive = true; } //---------------------------------------- @@ -62,26 +62,26 @@ void ofxBox2dJoint::setup(b2World* b2world, b2Body* body1, b2Body* body2, b2Vec2 b2DistanceJointDef jointDef; jointDef.Initialize(body1, body2, anchor1, anchor2); jointDef.collideConnected = bCollideConnected; - jointDef.frequencyHz = frequencyHz; - jointDef.dampingRatio = damping; - - setup(b2world, jointDef); + jointDef.frequencyHz = frequencyHz; + jointDef.dampingRatio = damping; + + setup(b2world, jointDef); } //---------------------------------------- void ofxBox2dJoint::setup(b2World* b2world, b2DistanceJointDef jointDef) { - setWorld(b2world); - - joint = (b2DistanceJoint*)world->CreateJoint(&jointDef); - + setWorld(b2world); + + joint = (b2DistanceJoint*)world->CreateJoint(&jointDef); + alive = true; } //---------------------------------------- void ofxBox2dJoint::setWorld(b2World* w) { if(w == NULL) { - ofLog(OF_LOG_NOTICE, "ofxBox2dJoint :: setWorld : - box2d world needed -"); + ofLog(OF_LOG_NOTICE, "ofxBox2dJoint :: setWorld : - box2d world needed -"); return; } world = w; @@ -104,13 +104,13 @@ bool ofxBox2dJoint::isSetup() { //---------------------------------------- void ofxBox2dJoint::draw() { if(!alive) return; - + b2Vec2 p1 = joint->GetAnchorA(); b2Vec2 p2 = joint->GetAnchorB(); - + p1 *= OFX_BOX2D_SCALE; p2 *= OFX_BOX2D_SCALE; - ofLine(p1.x, p1.y, p2.x, p2.y); + ofDrawLine(p1.x, p1.y, p2.x, p2.y); } //---------------------------------------- @@ -182,7 +182,3 @@ float ofxBox2dJoint::getReactionTorque(float inv_dt) const { } return 0; } - - - - diff --git a/src/ofxBox2dJoint.h b/src/ofxBox2dJoint.h index 299229b..b720ed2 100644 --- a/src/ofxBox2dJoint.h +++ b/src/ofxBox2dJoint.h @@ -7,56 +7,44 @@ #define BOX2D_DEFAULT_DAMPING 0.5 class ofxBox2dJoint { - + public: - - b2World * world; - b2DistanceJoint * joint; - int jointType; - bool alive; - + + b2World * world; + b2DistanceJoint * joint; + int jointType; + bool alive; + //---------------------------------------- ofxBox2dJoint(); ofxBox2dJoint(b2World* b2world, b2Body* body1, b2Body* body2, float frequencyHz=4.f, float damping=.5f, bool bCollideConnected=true); ofxBox2dJoint(b2World* b2world, b2Body* body1, b2Body* body2, b2Vec2 anchor1, b2Vec2 anchor2, float frequencyHz=4.f, float damping=.5f, bool bCollideConnected=true); - ofxBox2dJoint(b2World* b2world, b2DistanceJointDef jointDef); - + ofxBox2dJoint(b2World* b2world, b2DistanceJointDef jointDef); + //---------------------------------------- void setWorld(b2World * w); void setup(b2World* b2world, b2Body* body1, b2Body* body2, float frequencyHz=4.f, float damping=.5f, bool bCollideConnected=true); void setup(b2World* b2world, b2Body* body1, b2Body* body2, b2Vec2 anchor1, b2Vec2 anchor2, float frequencyHz=4.f, float damping=.5f, bool bCollideConnected=true); - void setup(b2World* b2world, b2DistanceJointDef jointDef); - + void setup(b2World* b2world, b2DistanceJointDef jointDef); + //---------------------------------------- bool isSetup(); void draw(); void destroy(); - + //---------------------------------------- // Manipulating the length can lead to non-physical behavior when the frequency is zero. void setLength(float len); float getLength(); - + void setFrequency(float freq); float getFrequency(); - + void setDamping(float ratio); float getDamping(); - + //---------------------------------------- ofVec2f getReactionForce(float inv_dt) const; b2Vec2 getReactionForceB2D(float inv_dt) const; float getReactionTorque(float inv_dt) const; }; - - - - - - - - - - - - diff --git a/src/ofxBox2dPolygon.cpp b/src/ofxBox2dPolygon.cpp index de3aa3b..4150e98 100644 --- a/src/ofxBox2dPolygon.cpp +++ b/src/ofxBox2dPolygon.cpp @@ -11,22 +11,21 @@ #include "ofxBox2dPolygonUtils.h" //---------------------------------------- -ofxBox2dPolygon::ofxBox2dPolygon() { +ofxBox2dPolygon::ofxBox2dPolygon() { bIsTriangulated = false; bIsSimplified = false; - ofPolyline::setClosed(true); - + ofPolyline::setClosed(true); } //---------------------------------------- -ofxBox2dPolygon::~ofxBox2dPolygon() { +ofxBox2dPolygon::~ofxBox2dPolygon() { } //---------------------------------------- void ofxBox2dPolygon::clear() { ofxBox2dBaseShape::destroy(); - ofPolyline::clear(); - mesh.clear(); + ofPolyline::clear(); + mesh.clear(); } //---------------------------------------- @@ -38,7 +37,7 @@ void ofxBox2dPolygon::destroy() { //---------------------------------------- void ofxBox2dPolygon::addTriangle(const ofVec2f &a, const ofVec2f &b, const ofVec2f &c) { addVertex(a); addVertex(b); addVertex(c); - + // dont forget to close it addVertex(a); close(); @@ -63,44 +62,44 @@ void ofxBox2dPolygon::addVertexes(ofPolyline &polyline) { //---------------------------------------- void ofxBox2dPolygon::simplify(float tolerance) { - ofPolyline::simplify(tolerance); + ofPolyline::simplify(tolerance); bIsSimplified = true; } //---------------------------------------- void ofxBox2dPolygon::simplifyToMaxVerts() { - ofPolyline p = getResampledByCount(b2_maxPolygonVertices); - if(p.size()) { - ofPolyline::clear(); - ofPolyline::addVertices(p.getVertices()); - } + ofPolyline p = getResampledByCount(b2_maxPolygonVertices); + if(p.size()) { + ofPolyline::clear(); + ofPolyline::addVertices(p.getVertices()); + } } //---------------------------------------- void ofxBox2dPolygon::triangulatePoly(float resampleAmt, int nPointsInside) { - + triangles.clear(); bool wasClosed = isClosed(); if(size() > 0) { - + // copy over the points into a polyline ofPolyline polyOutline; ofPolyline newPoly; - + // make sure to close the polyline and then // simplify and resample by spacing... setClosed(true); if(!bIsSimplified) simplify(); newPoly = getResampledBySpacing(resampleAmt); - + // save the outline... polyOutline = newPoly; - + // add some random points inside then // triangulate the polyline... if(nPointsInside!=-1) addRandomPointsInside(newPoly, nPointsInside); triangles = triangulatePolygonWithOutline(newPoly, polyOutline); - + clear(); if(wasClosed) ofPolyline::setClosed(wasClosed); @@ -109,16 +108,16 @@ void ofxBox2dPolygon::triangulatePoly(float resampleAmt, int nPointsInside) { addVertex(newPoly[i]); } } - + bIsTriangulated = true; } //---------------------------------------- void ofxBox2dPolygon::makeConvexPoly() { - ofPolyline convex = getConvexHull(ofPolyline::getVertices()); - ofPolyline::clear(); - ofPolyline::addVertices(convex.getVertices()); - bIsTriangulated = false; + ofPolyline convex = getConvexHull(ofPolyline::getVertices()); + ofPolyline::clear(); + ofPolyline::addVertices(convex.getVertices()); + bIsTriangulated = false; } //---------------------------------------- @@ -126,28 +125,28 @@ void ofxBox2dPolygon::create(b2World * b2dworld) { if(size() < 3) { ofLog(OF_LOG_NOTICE, "need at least 3 points: %i\n", (int)size()); - return; + return; } - + if (body != NULL) { b2dworld->DestroyBody(body); body = NULL; } - + // create the body from the world (1) - b2BodyDef bd; - bd.type = density <= 0.0 ? b2_staticBody : b2_dynamicBody; - body = b2dworld->CreateBody(&bd); + b2BodyDef bd; + bd.type = density <= 0.0 ? b2_staticBody : b2_dynamicBody; + body = b2dworld->CreateBody(&bd); if(bIsTriangulated) { - - b2PolygonShape shape; - b2FixtureDef fixture; - b2Vec2 verts[3]; - + + b2PolygonShape shape; + b2FixtureDef fixture; + b2Vec2 verts[3]; + ofVec2f a, b, c; for (size_t i=0; iCreateFixture(&fixture); } - + } else { - makeConvexPoly(); + makeConvexPoly(); vector pts = ofPolyline::getVertices(); - vectorverts; - for (int i=0; iCreateFixture(&fixture); - - - } - - vector pts = ofPolyline::getVertices(); - mesh.clear(); - ofPath path; - ofPoint center = getCentroid2D(); - for (size_t i=0; iverts; + for (int i=0; iCreateFixture(&fixture); + } + + vector pts = ofPolyline::getVertices(); + mesh.clear(); + ofPath path; + ofPoint center = getCentroid2D(); + for (size_t i=0; iGetTransform(); - - for (b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext()) { - b2PolygonShape* poly = (b2PolygonShape*)f->GetShape(); - - if(poly) { - b2Vec2 P(pt.x/OFX_BOX2D_SCALE, pt.y/OFX_BOX2D_SCALE); - - for(int i=0; iGetVertexCount(); i++) { - b2Vec2 qt = b2Mul(xf, poly->GetVertex(i)); - b2Vec2 D = P - qt; - b2Vec2 F = amt * D; - body->ApplyForce(F, P, true); - } - } - } - } + // we apply forces at each vertex. + if(body != NULL) { + const b2Transform& xf = body->GetTransform(); + + for (b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext()) { + b2PolygonShape* poly = (b2PolygonShape*)f->GetShape(); + + if(poly) { + b2Vec2 P(pt.x/OFX_BOX2D_SCALE, pt.y/OFX_BOX2D_SCALE); + + for(int i=0; iGetVertexCount(); i++) { + b2Vec2 qt = b2Mul(xf, poly->GetVertex(i)); + b2Vec2 D = P - qt; + b2Vec2 F = amt * D; + body->ApplyForce(F, P, true); + } + } + } + } } //---------------------------------------- void ofxBox2dPolygon::addAttractionPoint (float x, float y, float amt) { - addAttractionPoint(ofVec2f(x, y), amt); + addAttractionPoint(ofVec2f(x, y), amt); } //---------------------------------------- @@ -237,36 +234,36 @@ void ofxBox2dPolygon::addRepulsionForce(float x, float y, float amt) { } void ofxBox2dPolygon::addRepulsionForce(ofVec2f pt, float amt) { // we apply forces at each vertex. - if(body != NULL) { - const b2Transform& xf = body->GetTransform(); - - for (b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext()) { - b2PolygonShape* poly = (b2PolygonShape*)f->GetShape(); - - if(poly) { - b2Vec2 P(pt.x/OFX_BOX2D_SCALE, pt.y/OFX_BOX2D_SCALE); - - for(int i=0; iGetVertexCount(); i++) { - b2Vec2 qt = b2Mul(xf, poly->GetVertex(i)); - b2Vec2 D = P - qt; - b2Vec2 F = amt * D; - body->ApplyForce(-F, P, true); - } - } - } - } + if(body != NULL) { + const b2Transform& xf = body->GetTransform(); + + for (b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext()) { + b2PolygonShape* poly = (b2PolygonShape*)f->GetShape(); + + if(poly) { + b2Vec2 P(pt.x/OFX_BOX2D_SCALE, pt.y/OFX_BOX2D_SCALE); + + for(int i=0; iGetVertexCount(); i++) { + b2Vec2 qt = b2Mul(xf, poly->GetVertex(i)); + b2Vec2 D = P - qt; + b2Vec2 F = amt * D; + body->ApplyForce(-F, P, true); + } + } + } + } } //---------------------------------------- vector & ofxBox2dPolygon::getPoints() { - - if(body != NULL) { - + + if(body != NULL) { + const b2Transform& xf = body->GetTransform(); - + for (b2Fixture * f = body->GetFixtureList(); f; f = f->GetNext()) { b2PolygonShape * poly = (b2PolygonShape*)f->GetShape(); - + if(poly) { ofPolyline::clear(); for(int i=0; iGetVertexCount(); i++) { @@ -278,31 +275,19 @@ vector & ofxBox2dPolygon::getPoints() { } } - return ofPolyline::getVertices(); + return ofPolyline::getVertices(); } //---------------------------------------- void ofxBox2dPolygon::draw() { if(body == NULL) { - ofLog(OF_LOG_ERROR, "ofxBox2dPolygon::draw body null\n"); - return; + ofLog(OF_LOG_ERROR, "ofxBox2dPolygon::draw body null\n"); + return; } - ofPushMatrix(); - ofTranslate(getPosition()); - ofRotate(getRotation(), 0, 0, 1); - mesh.draw(); - ofPopMatrix(); + ofPushMatrix(); + ofTranslate(getPosition()); + ofRotate(getRotation(), 0, 0, 1); + mesh.draw(); + ofPopMatrix(); } - - - - - - - - - - - - diff --git a/src/ofxBox2dPolygon.h b/src/ofxBox2dPolygon.h index 1c77228..2ad8ab4 100644 --- a/src/ofxBox2dPolygon.h +++ b/src/ofxBox2dPolygon.h @@ -1,5 +1,5 @@ - #pragma once + #include "ofMain.h" #include "ofxBox2dBaseShape.h" #include "ofxBox2dPolygonUtils.h" @@ -7,27 +7,27 @@ class ofxBox2dPolygon : public ofxBox2dBaseShape, public ofPolyline { private: - - bool bIsSimplified; + + bool bIsSimplified; bool bIsTriangulated; float area; ofVec2f center; void calculateCentroid(); float calculateArea(); - void makeConvexPoly(); + void makeConvexPoly(); public: - ofVboMesh mesh; - ofRectangle bounds; + ofVboMesh mesh; + ofRectangle bounds; vector triangles; - + //---------------------------------------- ofxBox2dPolygon(); ~ofxBox2dPolygon(); void destroy(); void clear(); - + //---------------------------------------- void addTriangle(const ofVec2f &a, const ofVec2f &b, const ofVec2f &c); void addVertexes(vector &pts); @@ -37,13 +37,13 @@ class ofxBox2dPolygon : public ofxBox2dBaseShape, public ofPolyline { // Polygon helper functions //---------------------------------------- void simplify(float tolerance=0.3); - void simplifyToMaxVerts(); + void simplifyToMaxVerts(); void triangulatePoly(float resampleAmt=20, int nPointsInside=-1); - + //---------------------------------------- vector &getPoints(); - bool isGoodShape() { return calculateArea() > 15; } - + bool isGoodShape() { return calculateArea() > 15; } + //------------------------------------------------ void addAttractionPoint(ofVec2f pt, float amt=1); void addAttractionPoint(float x, float y, float amt=1); @@ -53,5 +53,5 @@ class ofxBox2dPolygon : public ofxBox2dBaseShape, public ofPolyline { //---------------------------------------- void create(b2World * b2dworld); void draw(); - -}; \ No newline at end of file + +}; diff --git a/src/ofxBox2dPolygonUtils.h b/src/ofxBox2dPolygonUtils.h index f9fe9bf..0760ec3 100644 --- a/src/ofxBox2dPolygonUtils.h +++ b/src/ofxBox2dPolygonUtils.h @@ -14,7 +14,6 @@ using namespace tpp; - //This is for polygon/contour simplification - we use it to reduce the number of points needed in //representing the letters as openGL shapes - will soon be moved to ofGraphics.cpp @@ -33,9 +32,9 @@ typedef struct{ typedef struct { ofVec2f a,b,c; - void draw() { - ofTriangle(a,b,c); - } + void draw() { + ofDrawTriangle(a,b,c); + } } TriangleShape; // dot product (3D) which allows vector operations in arguments @@ -46,53 +45,53 @@ typedef struct { // #define d(u,v) norm(u-v) // distance = norm of difference static void simplifyDP(float tol, ofVec2f* v, int j, int k, int* mk ){ - if (k <= j+1) // there is nothing to simplify - return; - - // check for adequate approximation by segment S from v[j] to v[k] - int maxi = j; // index of vertex farthest from S - float maxd2 = 0; // distance squared of farthest vertex - float tol2 = tol * tol; // tolerance squared - Segment S = {v[j], v[k]}; // segment from v[j] to v[k] - ofVec2f u; - u = S.P1 - S.P0; // segment direction vector - double cu = u.dot(u);// dot(u,u); // segment length squared - - // test each vertex v[i] for max distance from S - // compute using the Feb 2001 Algorithm's dist_ofPoint_to_Segment() - // Note: this works in any dimension (2D, 3D, ...) - ofVec2f w; - ofVec2f Pb; // base of perpendicular from v[i] to S - float b, cw, dv2; // dv2 = distance v[i] to S squared - - for (int i=j+1; i tol2) // error is worse than the tolerance - { - // split the polyline at the farthest vertex from S - mk[maxi] = 1; // mark v[maxi] for the simplified polyline - // recursively simplify the two subpolylines at v[maxi] - simplifyDP( tol, v, j, maxi, mk ); // polyline v[j] to v[maxi] - simplifyDP( tol, v, maxi, k, mk ); // polyline v[maxi] to v[k] - } - // else the approximation is OK, so ignore intermediate vertices - return; + if (k <= j+1) // there is nothing to simplify + return; + + // check for adequate approximation by segment S from v[j] to v[k] + int maxi = j; // index of vertex farthest from S + float maxd2 = 0; // distance squared of farthest vertex + float tol2 = tol * tol; // tolerance squared + Segment S = {v[j], v[k]}; // segment from v[j] to v[k] + ofVec2f u; + u = S.P1 - S.P0; // segment direction vector + double cu = u.dot(u);// dot(u,u); // segment length squared + + // test each vertex v[i] for max distance from S + // compute using the Feb 2001 Algorithm's dist_ofPoint_to_Segment() + // Note: this works in any dimension (2D, 3D, ...) + ofVec2f w; + ofVec2f Pb; // base of perpendicular from v[i] to S + float b, cw, dv2; // dv2 = distance v[i] to S squared + + for (int i=j+1; i tol2) // error is worse than the tolerance + { + // split the polyline at the farthest vertex from S + mk[maxi] = 1; // mark v[maxi] for the simplified polyline + // recursively simplify the two subpolylines at v[maxi] + simplifyDP( tol, v, j, maxi, mk ); // polyline v[j] to v[maxi] + simplifyDP( tol, v, maxi, k, mk ); // polyline v[maxi] to v[k] + } + // else the approximation is OK, so ignore intermediate vertices + return; } @@ -104,37 +103,37 @@ static vector simplifyContour(vector &V, float tol) { vector sV; if(n <= 2) { - return sV; + return sV; } sV.assign(n, ofVec2f()); - int i, k, m, pv; // misc counters - float tol2 = tol * tol; // tolerance squared - - vector vt(n); + int i, k, m, pv; // misc counters + float tol2 = tol * tol; // tolerance squared + + vector vt(n); int* mk = new int[n]; //dynamically allocate a new int array - + memset(mk, 0, n * sizeof(int)); - - // STAGE 1. Vertex Reduction within tolerance of prior vertex cluster - vt[0] = V[0]; // start at the beginning - for (i=k=1, pv=0; i & vertices) { ofRectangle bounds; bounds.x = 100000; - bounds.y = 100000; + bounds.y = 100000; bounds.width = 0; bounds.height = 0; float farRight = -100000; float bottom = -100000; - + for (size_t i=0; i & vertices, int amt=100) { //------------------------------------------------------------------- -static vector triangulatePolygonWithOutline(const ofPolyline &pts, - const ofPolyline &polyOutline) { +static vector triangulatePolygonWithOutline(const ofPolyline &pts, const ofPolyline &polyOutline) { vector triangles; @@ -322,8 +320,8 @@ static vector triangulatePolygonWithOutline(const ofPolyline &pt // now triangluate from the polyline vector delaunayPts; - Delaunay::Point tempP; - + Delaunay::Point tempP; + for(size_t i=0; i triangulatePolygonWithOutline(const ofPolyline &pt return triangles; } -static vector triangulatePolygonWithOutline(const vector &pts, - const ofPolyline &polyOutline) { - ofPolyline p; - - for (size_t i=0; i triangulatePolygonWithOutline(const vector &pts, const ofPolyline &polyOutline) { + ofPolyline p; + + for (size_t i=0; i triangulatePolygon(const vector &ptsIn, // now triangluate from the polyline (3) vector delaunayPts; - Delaunay::Point tempP; + Delaunay::Point tempP; for(size_t i=0; i triangulatePolygon(const vector &ptsIn, //------------------------------------------------------------------- static vector triangulatePolygon(const ofPolyline &poly, bool addPointsInside=false, int amt=100) { vector pts; - + for (size_t i=0; i calcConvexHull(vector P) { static ofPolyline getConvexHull(vector&linePts){ - vector < hPoint > ptsIn; - - for (size_t i = 0; i < linePts.size(); i++){ - hPoint pt; - pt.x = linePts[i].x; - pt.y = linePts[i].y; + vector ptsIn; - ptsIn.push_back(pt); - } - vector < hPoint > ptsOut; + for (size_t i = 0; i < linePts.size(); i++){ + hPoint pt; + pt.x = linePts[i].x; + pt.y = linePts[i].y; - ptsOut = calcConvexHull(ptsIn); + ptsIn.push_back(pt); + } + vector ptsOut; - ofPolyline outLine; - - for (size_t i = 0; i < ptsOut.size(); i++){ - outLine.addVertex(ofPoint(ptsOut[i].x, ptsOut[i].y)); - } + ptsOut = calcConvexHull(ptsIn); + + ofPolyline outLine; + + for (size_t i = 0; i < ptsOut.size(); i++){ + outLine.addVertex(ofPoint(ptsOut[i].x, ptsOut[i].y)); + } - return outLine; + return outLine; } static ofPolyline getConvexHull(ofPolyline &line){ - return getConvexHull(line.getVertices()); + return getConvexHull(line.getVertices()); } #undef norm2 diff --git a/src/ofxBox2dRect.cpp b/src/ofxBox2dRect.cpp index 2e408f0..938b4eb 100644 --- a/src/ofxBox2dRect.cpp +++ b/src/ofxBox2dRect.cpp @@ -9,10 +9,7 @@ #include "ofxBox2dRect.h" - - //------------------------------------------------ - ofxBox2dRect::ofxBox2dRect() { } @@ -29,17 +26,17 @@ void ofxBox2dRect::setup(b2World * b2dworld, float x, float y, float w, float h) return; } - w /= 2; - h /= 2; + w /= 2; + h /= 2; width = w; height = h; b2PolygonShape shape; shape.SetAsBox(width/OFX_BOX2D_SCALE, height/OFX_BOX2D_SCALE); - fixture.shape = &shape; - fixture.density = density; + fixture.shape = &shape; + fixture.density = density; fixture.friction = friction; - fixture.restitution = bounce; + fixture.restitution = bounce; b2BodyDef bodyDef; if(density == 0.f) bodyDef.type = b2_staticBody; @@ -50,8 +47,8 @@ void ofxBox2dRect::setup(b2World * b2dworld, float x, float y, float w, float h) body = b2dworld->CreateBody(&bodyDef); body->CreateFixture(&fixture); - updateMesh(); - alive = true; + updateMesh(); + alive = true; } // Temporary fix until OF 0.8.0 @@ -66,14 +63,14 @@ static void rectangle(ofPath & path, const ofRectangle & r){ //------------------------------------------------ void ofxBox2dRect::updateMesh() { - float w = getWidth(); - float h = getHeight(); - ofPath path; - // Temporary fix until OF 0.8.0 - rectangle(path, ofRectangle(-w/2, -h/2, w, h)); - mesh.clear(); - mesh = path.getTessellation(); - mesh.setUsage(GL_STATIC_DRAW); + float w = getWidth(); + float h = getHeight(); + ofPath path; + // Temporary fix until OF 0.8.0 + rectangle(path, ofRectangle(-w/2, -h/2, w, h)); + mesh.clear(); + mesh = path.getTessellation(); + mesh.setUsage(GL_STATIC_DRAW); } /* //------------------------------------------------ @@ -100,6 +97,38 @@ ofPolyline& ofxBox2dRect::getRectangleShape() { }*/ +float ofxBox2dRect::getX() { + if (!isBody()) { + ofLog(OF_LOG_ERROR, "- trying to get X of unitialized rect -"); + return 0; + } + float cx = body->GetPosition().x * OFX_BOX2D_SCALE; + return cx; +} +float ofxBox2dRect::getY() { + if (!isBody()) { + ofLog(OF_LOG_ERROR, "- trying to get Y of unitialized rect -"); + return 0; + } + float cy = body->GetPosition().y * OFX_BOX2D_SCALE; + return cy; +} +float ofxBox2dRect::getWidth() { + if (!isBody()) { + ofLog(OF_LOG_ERROR, "- trying to get Width of unitialized rect -"); + return 0; + } + return width * 2; +} +float ofxBox2dRect::getHeight() { + if (!isBody()) { + ofLog(OF_LOG_ERROR, "- trying to get Height of unitialized rect -"); + return 0; + } + return height * 2; +} + + //------------------------------------------------ void ofxBox2dRect::addRepulsionForce(float fx, float fy, float amt) { addRepulsionForce(ofVec2f(fx,fy), amt); @@ -162,67 +191,50 @@ void ofxBox2dRect::draw() { return; } - ofPushMatrix(); - ofTranslate(ofxBox2dBaseShape::getPosition()); - ofRotate(getRotation()); - // Temporary fix until we switch to OF 0.8.0. - mesh.draw(); - ofPopMatrix(); - - /* - const b2Transform& xf = body->GetTransform(); - ofPolyline shape; - for (b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext()) { - b2PolygonShape* poly = (b2PolygonShape*)f->GetShape(); - if(poly) { - for(int i=0; im_count; i++) { - b2Vec2 pt = b2Mul(xf, poly->m_vertices[i]); - shape.addVertex(worldPtToscreenPt(pt)); - } - } - } - shape.close(); - shape.draw();*/ - - - // update the polyline - // getRectangleShape(); - /* - ofPath path; - for (int i=0; iGetTransform(); + ofPolyline shape; + for (b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext()) { + b2PolygonShape* poly = (b2PolygonShape*)f->GetShape(); + if(poly) { + for(int i=0; im_count; i++) { + b2Vec2 pt = b2Mul(xf, poly->m_vertices[i]); + shape.addVertex(worldPtToscreenPt(pt)); + } + } + } + shape.close(); + shape.draw();*/ + + // update the polyline + // getRectangleShape(); + /* + ofPath path; + for (int i=0; iGetWorldCenter(); + a2 = body2->GetWorldCenter(); + + setup(b2world, body1, body2, a1, a2, enableLimit, lowerLimit, upperLimit, bCollideConnected); + + alive = true; +} + +//---------------------------------------- +void ofxBox2dRevoluteJoint::setup(b2World* b2world, b2Body* body1, b2Body* body2, b2Vec2 anchor0, bool enableLimit, float lowerLimit, float upperLimit, bool bCollideConnected) { + + if(body1 == NULL || body2 == NULL) { + ofLog(OF_LOG_NOTICE, "ofxBox2dRevoluteJoint :: setup : - box2d body is NULL -"); + return; + } + + b2RevoluteJointDef jointDef; + jointDef.Initialize(body1, body2, anchor0); + jointDef.enableLimit = enableLimit; + jointDef.lowerAngle = lowerLimit; + jointDef.upperAngle = upperLimit; + jointDef.collideConnected = bCollideConnected; + + setup(b2world, jointDef); +} + + +//---------------------------------------- +void ofxBox2dRevoluteJoint::setup(b2World* b2world, b2Body* body1, b2Body* body2, b2Vec2 anchor1, b2Vec2 anchor2, bool enableLimit, float lowerLimit, float upperLimit, bool bCollideConnected) { + + if (body1 == NULL || body2 == NULL) { + ofLog(OF_LOG_NOTICE, "ofxBox2dRevoluteJoint :: setup : - box2d body is NULL -"); + return; + } + + b2Vec2 anchor0; + anchor0 = body1->GetWorldCenter(); + + b2RevoluteJointDef jointDef; + jointDef.Initialize(body1, body2, anchor0); + jointDef.localAnchorA = anchor1; + jointDef.localAnchorB = anchor2; + jointDef.enableLimit = enableLimit; + jointDef.lowerAngle = lowerLimit; + jointDef.upperAngle = upperLimit; + jointDef.collideConnected = bCollideConnected; + + setup(b2world, jointDef); +} + +//---------------------------------------- +void ofxBox2dRevoluteJoint::setup(b2World* b2world, b2RevoluteJointDef jointDef) { + + setWorld(b2world); + + joint = (b2RevoluteJoint*)world->CreateJoint(&jointDef); + + alive = true; +} + +//---------------------------------------- +void ofxBox2dRevoluteJoint::setWorld(b2World* w) { + if (w == NULL) { + ofLog(OF_LOG_NOTICE, "ofxBox2dRevoluteJoint :: setWorld : - box2d world needed -"); + return; + } + world = w; +} + +//---------------------------------------- +bool ofxBox2dRevoluteJoint::isSetup() { + if (world == NULL) { + ofLog(OF_LOG_NOTICE, "ofxBox2dRevoluteJoint :: world must be set!"); + return false; + } + if (joint == NULL) { + ofLog(OF_LOG_NOTICE, "ofxBox2dRevoluteJoint :: setup function must be called!"); + return false; + } + return true; +} + + +//---------------------------------------- +void ofxBox2dRevoluteJoint::draw() { + if(!alive) return; + + b2Vec2 p1 = joint->GetAnchorA(); + b2Vec2 p2 = joint->GetAnchorB(); + + p1 *= OFX_BOX2D_SCALE; + p2 *= OFX_BOX2D_SCALE; + ofDrawLine(p1.x + 0.0001f, p1.y, p2.x, p2.y - 0.0001f); +} + +//---------------------------------------- +void ofxBox2dRevoluteJoint::destroy() { + if (!isSetup()) return; + if (joint) { + world->DestroyJoint(joint); + } + joint = NULL; + alive = false; +} + +//---------------------------------------- +float ofxBox2dRevoluteJoint::getJointAngle() { //in radians + if (joint) { + return (float)joint->GetJointAngle(); + } + return 0; +} + +//---------------------------------------- +float ofxBox2dRevoluteJoint::getJointSpeed() { //in radians per second + if (joint) { + return (float)joint->GetJointSpeed(); + } + return 0; +} + +//---------------------------------------- +void ofxBox2dRevoluteJoint::setLimitEnabled(bool toggle) { + if (joint) { + joint->EnableLimit(toggle); + } +} +bool ofxBox2dRevoluteJoint::getLimitEnabled() { + if (joint) { + return (bool)joint->IsLimitEnabled(); + } + return false; +} + +//---------------------------------------- +void ofxBox2dRevoluteJoint::setLowerLimit(float angle) { + if (joint) { + joint->SetLimits((float32)angle, joint->GetUpperLimit()); + } +} +float ofxBox2dRevoluteJoint::getLowerLimit() { + if (joint) { + return (float)joint->GetLowerLimit(); + } + return 0; +} + +//---------------------------------------- +void ofxBox2dRevoluteJoint::setUpperLimit(float angle) { + if (joint) { + joint->SetLimits(joint->GetLowerLimit(), (float32)angle); + } +} +float ofxBox2dRevoluteJoint::getUpperLimit() { + if (joint) { + return (float)joint->GetUpperLimit(); + } + return 0; +} + +//---------------------------------------- +void ofxBox2dRevoluteJoint::setLimits(float lowerAngle, float upperAngle) { + if (joint) { + joint->SetLimits((float32)lowerAngle, (float32)upperAngle); + } +} + +//---------------------------------------- +void ofxBox2dRevoluteJoint::setMotorEnabled(bool toggle) { + if (joint) { + joint->EnableMotor(toggle); + } +} +bool ofxBox2dRevoluteJoint::getMotorEnabled() { + if (joint) { + return (bool)joint->IsMotorEnabled(); + } + return false; +} + +//---------------------------------------- +void ofxBox2dRevoluteJoint::setMotorSpeed(float speed) { + if (joint) { + joint->SetMotorSpeed((float32)speed); + } +} +float ofxBox2dRevoluteJoint::getMotorSpeed() { + if (joint) { + return (float)joint->GetMotorSpeed(); + } + return 0; +} + +//---------------------------------------- +void ofxBox2dRevoluteJoint::setMaxMotorTorque(float torque) { + if (joint) { + joint->SetMaxMotorTorque((float32)torque); + } +} +float ofxBox2dRevoluteJoint::getMaxMotorTorque() { + if (joint) { + return (float)joint->GetMaxMotorTorque(); + } + return 0; +} + + +//---------------------------------------- +float ofxBox2dRevoluteJoint::getMotorTorque(float inv_dt) { + if (joint) { + return (float)joint->GetMotorTorque((float32)inv_dt); + } + return 0; +} + +//---------------------------------------- +float ofxBox2dRevoluteJoint::getReactionTorque(float inv_dt) { + if (joint) { + return (float)joint->GetReactionTorque((float32)inv_dt); + } + return 0; +} + +//---------------------------------------- +ofVec2f ofxBox2dRevoluteJoint::getReactionForce(float inv_dt) { + ofVec2f r; + if (joint) { + b2Vec2 rf = joint->GetReactionForce((float32)inv_dt); + r.x = rf.x; + r.y = rf.y; + } + return r; +} \ No newline at end of file diff --git a/src/ofxBox2dRevoluteJoint.h b/src/ofxBox2dRevoluteJoint.h new file mode 100644 index 0000000..e20473f --- /dev/null +++ b/src/ofxBox2dRevoluteJoint.h @@ -0,0 +1,63 @@ +#pragma once + +#include "ofMain.h" +#include "Box2D.h" +#include "ofxBox2dUtils.h" + +#define BOX2D_DEFAULT_FREQ 4.0 +#define BOX2D_DEFAULT_DAMPING 0.5 + +class ofxBox2dRevoluteJoint { + +public: + + b2World * world; + b2RevoluteJoint * joint; + bool alive; + + //---------------------------------------- + ofxBox2dRevoluteJoint(); + ofxBox2dRevoluteJoint(b2World* b2world, b2Body* body1, b2Body* body2, bool enableLimit = false, float lowerLimit = -0.01f, float upperLimit = 0.01f, bool bCollideConnected=true); + ofxBox2dRevoluteJoint(b2World* b2world, b2Body* body1, b2Body* body2, b2Vec2 anchor0, bool enableLimit = false, float lowerLimit = -0.01f, float upperLimit = 0.01f, bool bCollideConnected=true); + ofxBox2dRevoluteJoint(b2World* b2world, b2Body* body1, b2Body* body2, b2Vec2 anchor1, b2Vec2 anchor2, bool enableLimit = false, float lowerLimit = -0.01f, float upperLimit = 0.01f, bool bCollideConnected=true); + ofxBox2dRevoluteJoint(b2World* b2world, b2RevoluteJointDef jointDef); + + //---------------------------------------- + void setWorld(b2World * w); + void setup(b2World* b2world, b2Body* body1, b2Body* body2, bool enableLimit = false, float lowerLimit = -0.01f, float upperLimit = 0.01f, bool bCollideConnected=true); + void setup(b2World* b2world, b2Body* body1, b2Body* body2, b2Vec2 anchor0, bool enableLimit = false, float lowerLimit = -0.01f, float upperLimit = 0.01f, bool bCollideConnected=true); + void setup(b2World* b2world, b2Body* body1, b2Body* body2, b2Vec2 anchor1, b2Vec2 anchor2, bool enableLimit = false, float lowerLimit = -0.01f, float upperLimit = 0.01f, bool bCollideConnected=true); + void setup(b2World* b2world, b2RevoluteJointDef jointDef); + + //---------------------------------------- + bool isSetup(); + void draw(); + void destroy(); + + //---------------------------------------- + //read-only + float getJointAngle(); //in radians + + float getJointSpeed(); + float getMotorTorque(float inv_dt); + float getReactionTorque(float inv_dt); + ofVec2f getReactionForce(float inv_dt); + + //---------------------------------------- + //read-write + void setLimitEnabled(bool toggle); + bool getLimitEnabled(); + void setLowerLimit(float radangle); + float getLowerLimit(); + void setUpperLimit(float radangle); + float getUpperLimit(); + void setLimits(float lowerAngle, float upperAngle); + + void setMotorEnabled(bool toggle); + bool getMotorEnabled(); + void setMotorSpeed(float speed); // radians per second + float getMotorSpeed(); + void setMaxMotorTorque(float torque); + float getMaxMotorTorque(); + +}; diff --git a/src/ofxBox2dUtils.h b/src/ofxBox2dUtils.h index 839278e..62c5dcf 100644 --- a/src/ofxBox2dUtils.h +++ b/src/ofxBox2dUtils.h @@ -6,7 +6,7 @@ static float b2dNum(float f) { - return (float)f/OFX_BOX2D_SCALE; + return (float)f/OFX_BOX2D_SCALE; } @@ -19,13 +19,13 @@ static ofPoint worldPtToscreenPt(b2Vec2 p) { class QueryCallback : public b2QueryCallback { - + public: QueryCallback(const b2Vec2& point) { m_point = point; m_fixture = NULL; } - + bool ReportFixture(b2Fixture* fixture) { b2Body* body = fixture->GetBody(); if (body->GetType() == b2_dynamicBody) @@ -39,11 +39,11 @@ class QueryCallback : public b2QueryCallback { return false; } } - + // Continue the query. return true; } - + b2Vec2 m_point; b2Fixture* m_fixture; };